# HG changeset patch # User Eric Warmenhoven # Date 973307334 0 # Node ID e1408fb04c362cc8a0df3fe02ce340bf31626634 # Parent 9446ac58745e135658113bd03475119fb6a5ee50 [gaim-migrate @ 1073] updated HACKING to describe gaim_connection/aim_user/prpl. updated FAQ to answer some questions about multiple connections. made it so you're not able to send a message in a chat room that you're no longer in (i.e. when you were in the room but sign off) free'd the buddy list when the connection is destroyed tried to prevent set_buddy from being called before the buddy list is drawn i think there was something else committer: Tailor Script diff -r 9446ac58745e -r e1408fb04c36 HACKING --- a/HACKING Sat Nov 04 00:21:33 2000 +0000 +++ b/HACKING Sat Nov 04 03:08:54 2000 +0000 @@ -2,8 +2,9 @@ the code is just so horrid. Well, the code isn't getting better anytime soon, so to help all you would-be hackers help out gaim, here's a brief tutorial on how gaim works. I'll quickly describe the logical flow of -things, then what you'll find in each of the source files. Hopefully -that's enough to get most of you going. +things, then what you'll find in each of the source files. As an added +bonus, I'll try and describe as best I can how multiple connections and +multiple protocols work. Hopefully that's enough to get most of you going. If you're going to hack gaim, PLEASE, PLEASE PLEASE PLEASE send patches against the absolute latest CVS. I get really annoyed when I get patches @@ -34,7 +35,7 @@ of the information that's printed is useless anyway though; so the --enable-debug option really doesn't do a whole lot. -This file was last modified by $Author: warmenhoven $ on $Date: 2000-10-31 05:49:53 -0500 (Tue, 31 Oct 2000) $. +This file was last modified by $Author: warmenhoven $ on $Date: 2000-11-03 22:08:54 -0500 (Fri, 03 Nov 2000) $. PROGRAM FLOW @@ -268,6 +269,56 @@ like the name says. -So that's our little tour of the internals of Gaim. It's really not -difficult to figure out if you've spent any time with GTK. I'm looking -forward to getting all of your patches :) +MULTIPLE CONNECTIONS AND PRPLS +============================== + +OK, let's start with the basics. There are users. Each user is contained +in an aim_user struct, and kept track of in the aim_users GList (GSList?). +Each aim_user has certain features: a username, a password, and user_info. +It also has certain options, and the protocol it uses to sign on (kept as +an int which is #define'd in prpl.h). The way the management of the users +works is, there will (hopefully) only be one user for a given screenname/ +protocol pair (i.e. you may have two user warmenhoven's, but they'll both +have a different protocol number). + +Now then, there are protocols that gaim knows about. Each protocol is in +a prpl struct and kept track of in the protocols GSList. The way the +management of the protocols is, there will only ever be one prpl per numeric +protocol. Each prpl defines a basic set of functions: login, logout, send_im, +etc. The prpl is responsible not only for handling these functions, but also +for calling the appropriate serv_got functions (e.g. serv_got_update when a +buddy comes online/goes offline/goes idle/etc). It handles each of these on +a per-connection basis. + +So why's it called a PRPL? It stands for PRotocol PLugin. That means that +it's possible to dynamically add new protocols to gaim. However, all protocols +must be implemented the same way: by using a prpl struct and being loaded, +regardless of whether they are static or dynamic. + +Here's how struct gaim_connection fits into all of this. At some point the +User (capitalized to indicate a person and not a name) will try to sign on +one of Their users. serv_login is then called for that user. It searches for +the prpl that is assigned to that user, and calls that prpl's login function, +passing it the aim_user struct that is attempting to sign on. The prpl is then +responsible for seeing that the gaim_connection is created (by calling +new_gaim_connection), and registering it as being online (by calling +account_online and passing it the aim_user and gaim_connection structs). At +that point, the aim_user and gaim_connection structs have pointers to each +other, and the gaim_connection struct has a pointer to the prpl struct that +it is using. The gaim_connections are stored in the connections GSList. +The way connection management works is, there will always only be one +gaim_connection per user, and the prpl that the gaim_connection uses will be +constant for the gaim_connection's life. + +So at certain points the User is going to want to do certain things, like +send a message. They must send the message on a connection. So the UI figures +out which gaim_connection the User want to send a message on (for our example), +and calls serv_send_im, telling it which gaim_connection to use, and the +necessary information (who to send it to, etc). The serv_ function then +calls the handler of the prpl of the connection for that event (that was way +too many prepositions). OK, each prpl has a send_im function. Each connection +has a prpl. so you call gc->prpl->send_im and pass it the connection and all +the necessary info. And that's how things get done. + +I hope some of that made sense. Looking back at it it makes absolutely no +sense to me. Thank god I wrote the code; otherwise I'm sure I'd be lost. diff -r 9446ac58745e -r e1408fb04c36 doc/FAQ --- a/doc/FAQ Sat Nov 04 00:21:33 2000 +0000 +++ b/doc/FAQ Sat Nov 04 03:08:54 2000 +0000 @@ -30,7 +30,14 @@ version of gaim. 8. I've got a proxy, and I'd like to use GAIM. -III. Problems +III. Multiple Connections + 1. What do you mean by "multiple connections"? + 2. What's a PRPL? + 3. What happens when I load a new protocol? + 4. So how do I add accounts? + 5. This sucks. I want my old gaim back. + +IV. Problems 1. WAAAAAH! My sound doesn't work! 2. My buddy list disappeared! 3. I click on URLs, but Netscape doesn't popup! @@ -39,12 +46,12 @@ 6. I have a bug not described here. 7. I have Mandrake 6.0 and GAIM doesnt work! -IV. Programming +V. Programming 1. I have a patch for gaim! 2. I have a plugin for gaim! 3. Can you teach me how to program GTK? -V. Miscellaneous +VI. Miscellaneous 1. Can I talk to you on IM? 2. I want to write an IM client. Will you help me? 3. I have money. I need some software written. Can you help? @@ -135,7 +142,45 @@ None of them support authentication yet though. -III. Problems +III. Multiple Connections + 1. What do you mean by "multiple connections"? + Multiple Connections means that it's possible to connect to +the AOL servers using more than one screenname at a time. When you connect +using more than one screenname, each name will have their own buddy list. Each +will be able to send messages and do all the normal things. It's just a way of +not having to run 3 copies of gaim for each of your screennames. + + 2. What's a PRPL? + PRPL stands for PRotocol PLugin. It's a way to dynamically add +new protocols to gaim. This allows you to use gaim as your AIM client, ICQ +client, Yahoo, client, and even IRC client, all at the same time. Loading a +PRPL is like loading any other plugin - simply load the file from the plugins +dialog. Then simply add an account using the Account Editor and have it use +that protocol. + + 3. What happens when I load a new protocol? + Gaim keeps track of all the protocols that it knows about. +When you load a new protocol, it lets you add a new account that uses that +protocol. If you loaded the protocol as a plugin, and remove that plugin, gaim +then signs off any connections that were using that protocol, and forgets +about it. If you load a protocol that has already been loaded, it will unload +the original one and load the new one. + + 4. So how do I add accounts? + There is an Account Editor that is accessible from the main +signon window, and also from the Buddy List Tools menu. This brings up a +window that lets you add and remove accounts, modify them, and sign them on +independently of each other. + + 5. This sucks. I want my old gaim back. + Relax, there's a configure option, --disable-multi, that will +remove any way of having multiple connections from the UI. This gives gaim the +old familiar UI, and allow only one connection at a time. It will also benefit +from all of the features added that are not related to multiple connections +(like reporting idle times based on X usage). + + +IV. Problems 1. WAAAAAH! My sound doesn't work! ./configure should autodetect whether or not you have ESD libraries. If you have them it _WILL_ compile with them, if not it won't. @@ -185,7 +230,7 @@ Mandrake 6.1, with its newer libraries, appears to fix this problem. -IV. Programming +V. Programming 1. I have a patch for gaim! Nice. Think about your patch though. First, does it have to do with AIM? I won't apply patches for stock tickers, search engines, @@ -224,7 +269,7 @@ C and read the damn GTK tutorial, I'm a busy person. -V. Miscellaneous +VI. Miscellaneous 1. Can I talk to you on IM? Sure. My IM name is RobFlynn. The rest of the crew's IM names can be found in various places. Keep in mind though, I'm a very busy person. diff -r 9446ac58745e -r e1408fb04c36 src/buddy.c --- a/src/buddy.c Sat Nov 04 00:21:33 2000 +0000 +++ b/src/buddy.c Sat Nov 04 03:08:54 2000 +0000 @@ -1481,6 +1481,8 @@ GdkBitmap *bm; char **xpm = NULL; + if (!blist) return; + if (b->present) { if ((gs = find_group_show(g->name)) == NULL) gs = new_group_show(g->name); diff -r 9446ac58745e -r e1408fb04c36 src/conversation.c --- a/src/conversation.c Sat Nov 04 00:21:33 2000 +0000 +++ b/src/conversation.c Sat Nov 04 03:08:54 2000 +0000 @@ -369,7 +369,17 @@ c->log_dialog = NULL; if (c->is_chat) { - serv_chat_leave(c->gc, c->id); + if (c->gc) + serv_chat_leave(c->gc, c->id); + else { + /* bah */ + while (c->in_room) { + char *tmp = c->in_room->data; + c->in_room = g_list_remove(c->in_room, tmp); + g_free(tmp); + } + g_free(c); + } } else { delete_conversation(c); } diff -r 9446ac58745e -r e1408fb04c36 src/multi.c --- a/src/multi.c Sat Nov 04 00:21:33 2000 +0000 +++ b/src/multi.c Sat Nov 04 03:08:54 2000 +0000 @@ -66,7 +66,22 @@ void destroy_gaim_conn(struct gaim_connection *gc) { + GSList *g = gc->groups; + GSList *h; + struct group *m; + struct buddy *n; connections = g_slist_remove(connections, gc); + while (g) { + m = (struct group *)g->data; + g = g_slist_remove(g, m); + h = m->members; + while (h) { + n = (struct buddy *)h->data; + h = g_slist_remove(h, n); + g_free(n); + } + g_free(m); + } g_free(gc); redo_convo_menus(); if (!connections && mainwindow) diff -r 9446ac58745e -r e1408fb04c36 src/server.c --- a/src/server.c Sat Nov 04 00:21:33 2000 +0000 +++ b/src/server.c Sat Nov 04 03:08:54 2000 +0000 @@ -57,6 +57,15 @@ void serv_close(struct gaim_connection *gc) { + GSList *bcs = gc->buddy_chats; + struct conversation *b; + while (bcs) { + b = (struct conversation *)bcs->data; + gc->buddy_chats = g_slist_remove(gc->buddy_chats, b); + b->gc = NULL; + bcs = gc->buddy_chats; + } + if (gc->idle_timer > 0) gtk_timeout_remove(gc->idle_timer); gc->idle_timer = -1;