comparison HACKING @ 6797:053b577e08f2

[gaim-migrate @ 7337] Okay, our text files are REALLY OLD. they need massively updated, HACKING especially is like 2/3rds wrong. but there is more wrong than i care to deal with right now. over the next few days you will hopefully see some updates, BUT IT WON'T BE ENOUGH. someone had better decide to help out :-) committer: Tailor Script <tailor@pidgin.im>
author Luke Schierer <lschiere@pidgin.im>
date Tue, 09 Sep 2003 14:35:07 +0000
parents c7986b4d182a
children 754afaa07386
comparison
equal deleted inserted replaced
6796:f5f2669970a0 6797:053b577e08f2
1 The majority of the below was written by Eric Warmenhoven way back in
2 antiquity. I have taken the liberty of attempting to PARTIALLY update
3 it. I still think its helpful, but use it at your own risk.
4 --Luke
5
6
1 A lot of people have tried to hack gaim, but haven't been able to because 7 A lot of people have tried to hack gaim, but haven't been able to because
2 the code is just so horrid. Well, the code isn't getting better anytime 8 the code is just so horrid. Well, the code isn't getting better anytime
3 soon (I hate GNU indent), so to help all you would-be hackers help out 9 soon (I hate GNU indent), so to help all you would-be hackers help out
4 gaim, here's a brief tutorial on how gaim works. I'll quickly describe 10 gaim, here's a brief tutorial on how gaim works. I'll quickly describe
5 the logical flow of things, then what you'll find in each of the source 11 the logical flow of things, then what you'll find in each of the source
36 two trees, or even two copies of the same file). Then when you're ready to 42 two trees, or even two copies of the same file). Then when you're ready to
37 make your patch, simply run 'cvs diff -u >my.patch' and send it off; 43 make your patch, simply run 'cvs diff -u >my.patch' and send it off;
38 either post it on sf.net/projects/gaim in the patches section, or email it 44 either post it on sf.net/projects/gaim in the patches section, or email it
39 to gaim@marko.net. 45 to gaim@marko.net.
40 46
41 This file was last modified by $Author: lschiere $ on 47 Some Documentation is available on the Gaim api if you run the command
42 $Date: 2003-02-18 09:36:15 -0500 (Tue, 18 Feb 2003) $. Do not expect any information contained 48 $make docs
43 within to be current or correct. 49 after running ./configure (or ./autogen.sh). You will need doxygen and
44 50 graphiz dot to generate these docs.
45 Here's something new. Someone requested that I comment the code. No. I'm a
46 lazy bastard, and I understand most of the code, so I don't need the
47 comments. I understand that some of you do though. So give me the names of
48 specific functions that you'd like commented and I'll see what I can do.
49 It's more likely that those comments will be updated with the code than
50 this file is, though even that is still unlikely.
51
52 51
53 CODING STYLE 52 CODING STYLE
54 ============ 53 ============
55 54
56 Coding styles are like assholes, everyone has one and no one likes anyone 55 Coding styles are like assholes, everyone has one and no one likes anyone
77 76
78 NO goto. I'm very likely to refuse a patch if it makes use of goto. If you 77 NO goto. I'm very likely to refuse a patch if it makes use of goto. If you
79 feel the need to use goto, you need to rethink your design and flow. 78 feel the need to use goto, you need to rethink your design and flow.
80 79
81 80
82 PROGRAM FLOW 81 PROGRAM FLOW (just about every function name from here on down is wrong.
83 ============ 82 ============ but many of the ideas still apply under different names.)
84 83
85 Before gaim does anything you can see, it initializes itself, which is 84 Before gaim does anything you can see, it initializes itself, which is
86 mostly just reading .gaimrc (handled by the functions in gaimrc.c) and 85 mostly just reading ~/.gaim/*.xml (handled by the functions in prefs.[ch])
87 parsing command-line options. It then draws the login window by calling 86 and parsing command-line options. It then draws the login window by
88 show_login, and waits for input. 87 calling show_login, and waits for input.
89 88
90 At the login window, when "Accounts" is clicked, account_editor() is 89 At the login window, when "Accounts" is clicked, account_editor() is
91 called. This then displays all of the users and various information 90 called. This then displays all of the users and various information
92 about them. (Don't ask about what happens when "Sign On" is called. It's 91 about them. (Don't ask about what happens when "Sign On" is called. It's
93 quite hackish. The only reason the login window is there anymore is to 92 quite hackish. The only reason the login window is there anymore is to
135 That's pretty much it for the quick tutorial. I know it wasn't much but 134 That's pretty much it for the quick tutorial. I know it wasn't much but
136 it's enough to get you started. Make sure you know GTK before you get too 135 it's enough to get you started. Make sure you know GTK before you get too
137 involved. Most of the back-end stuff is pretty basic; most of gaim is GTK. 136 involved. Most of the back-end stuff is pretty basic; most of gaim is GTK.
138 137
139 138
140 SOURCE FILES 139 SOURCE FILES (this should probly be utterly removed)
141 ============ 140 ============
142 141
143 about.c: 142 about.c:
144 Not much to say here, just a few basic functions. 143 Not much to say here, just a few basic functions.
145 144
153 152
154 browser.c: 153 browser.c:
155 Code for opening a browser window. Most of the code is trying to deal 154 Code for opening a browser window. Most of the code is trying to deal
156 with Netscape. The most important function here is open_url. Have fun. 155 with Netscape. The most important function here is open_url. Have fun.
157 156
158 buddy.c: 157 blist.c:
159 This takes care of the buddy list window and most things related to it. 158 This takes care of the buddy list backend, the blist.xml file,
160 It still has some functions that manage the list, but not many. 159 importing old buddy list files, and related things like
161 160 finding buddies and groups.
161
162 buddy_chat.c: 162 buddy_chat.c:
163 This takes care of the buddy chat stuff. This used to be a lot bigger 163 This takes care of the buddy chat stuff. This used to be a lot bigger
164 until the chat and IM windows got merged in the code. Now it mostly 164 until the chat and IM windows got merged in the code. Now it mostly
165 just takes care of chat-specific stuff, like ignoring people and 165 just takes care of chat-specific stuff, like ignoring people and
166 keeping track of who's in the room. This is also where the chat window 166 keeping track of who's in the room. This is also where the chat window
187 187
188 gaimrc.c: 188 gaimrc.c:
189 This controls everything about the .gaimrc file. There's not really much 189 This controls everything about the .gaimrc file. There's not really much
190 to say about it; this is probably one of the better designed and easier 190 to say about it; this is probably one of the better designed and easier
191 to follow files in gaim. The important functions are towards the bottom. 191 to follow files in gaim. The important functions are towards the bottom.
192 This file is also utterly deprecated. It is used only for importing
193 on upgrade. the prefs.c and prefs.h files replace the control,
194 and gtkprefs.c replaces the gui component.
192 195
193 gtkimhtml.c: 196 gtkimhtml.c:
194 This is gaim's HTML widget. It replaced the old widget, GtkHtml (which 197 This is gaim's HTML widget. It replaced the old widget, GtkHtml (which
195 was different than GNOME's GtkHTML). It's self-contained (it doesn't 198 was different than GNOME's GtkHTML). It's self-contained (it doesn't
196 use any of gaim's code) and is actually a separate project from gaim 199 use any of gaim's code) and is actually a separate project from gaim
204 idle.c: 207 idle.c:
205 This file used to be entirely #if 0'd out of existance. However, thanks 208 This file used to be entirely #if 0'd out of existance. However, thanks
206 to some very generous people who submitted patches, this takes care of 209 to some very generous people who submitted patches, this takes care of
207 reporting idle time (imagine that). It's a pretty straight-forward file. 210 reporting idle time (imagine that). It's a pretty straight-forward file.
208 This also takes care of the auto-away stuff. 211 This also takes care of the auto-away stuff.
209
210 list.c:
211 This file contains all of the routines for managing buddy lists,
212 including importing them from a file, saving them, adding and removing
213 buddies and groups, etc.
214 212
215 main.c: 213 main.c:
216 This is where the main() function is. It takes care of a lot of the 214 This is where the main() function is. It takes care of a lot of the
217 initialization stuff, and showing the login window. It's pretty tiny 215 initialization stuff, and showing the login window. It's pretty tiny
218 and there's not really much to edit in it. This has some of the most 216 and there's not really much to edit in it. This has some of the most
234 with multiple connections. The best function in here by far is the 232 with multiple connections. The best function in here by far is the
235 account_editor(). auto_login() is also in here (I'm just reading multi.h 233 account_editor(). auto_login() is also in here (I'm just reading multi.h
236 now...). account_editor is really the only function that the UI needs 234 now...). account_editor is really the only function that the UI needs
237 to be concerned with. 235 to be concerned with.
238 236
239 perl.c:
240 This was basically copied straight from X-Chat through the power of
241 the GPL. Perl is the biggest, most confusing piece of C code I've ever
242 seen in my life (and keep in mind I'm a gaim hacker). I have a basic
243 idea of what's going on in it, but I couldn't tell you exactly. The
244 top half sets up perl and tells it what's going on and the bottom half
245 implements the AIM module.
246
247 prefs.c: 237 prefs.c:
248 The important function in here is build_prefs, but the most useful 238 Read the documentation on this file. This handles the backend
249 function is gaim_button. build_prefs draws the window, and calls 239 side of prefs.
250 gaim_button probably 30 or 40 times. (I don't really wanna run grep
251 | wc to count.) This is where you add the toggle button for gaim
252 preferences. It's very simple, and if you look at a couple of the
253 calls to gaim_button you'll figure it out right away. The new prefs
254 window uses a CList instead of a Notebook, and there's a pretty bad
255 hack to get it to work. I won't tell you what though.
256 240
257 proxy.c: 241 proxy.c:
258 Adam (of libfaim glory) got bored one day and rewrote this file, so 242 Adam (of libfaim glory) got bored one day and rewrote this file, so
259 now everything actually works. The main function is proxy_connect, 243 now everything actually works. The main function is proxy_connect,
260 which figures out which proxy you want to use (if you want to use one 244 which figures out which proxy you want to use (if you want to use one
261 at all) and passes off the data to the appropriate function. This file 245 at all) and passes off the data to the appropriate function. This file
262 should be pretty straight-forward. 246 should be pretty straight-forward.
247 Except I STRONGLY suspect that time has broken this file.
263 248
264 prpl.c: 249 prpl.c:
265 This file is what lets gaim dynamically load protocols, sort of. All 250 This file is what lets gaim dynamically load protocols, sort of. All
266 of the actual dlopen(), dlsym() stuff is in module.c. But this contains 251 of the actual dlopen(), dlsym() stuff is in module.c. But this contains
267 all of the functions that the protocol plugin needs to call, and manages 252 all of the functions that the protocol plugin needs to call, and manages
301 286
302 For the PRPLs, the only protocol whose "main" gaim file isn't the same as 287 For the PRPLs, the only protocol whose "main" gaim file isn't the same as
303 the name of the protocol is ICQ; for that it's gaim_icq.c. But ICQ is 288 the name of the protocol is ICQ; for that it's gaim_icq.c. But ICQ is
304 deprecated and you should be using Oscar for ICQ anyway. 289 deprecated and you should be using Oscar for ICQ anyway.
305 290
306 HOW BUDDY LISTS WORK 291 PLUGINS (read the plugins howto, this is really out of date)
307 ====================
308
309 The buddy list is a pain in the ass. Let me start off by saying that. The
310 most difficult part about getting gaim to do multiple connections was
311 the buddy list. In its current state it's very much like the UI for
312 0.10.x and earlier, which is what I was aiming for. However, the code
313 is completely different. And not much better.
314
315 There are two parts to the buddy list: the lists for the connections and
316 the Buddy List window. list.c contains code to manage the lists themselves
317 and buddy.c contains the code for the Buddy List window.
318
319 Each buddy needs to belong to a connection, it cannot belong to a
320 "protocol" like in EveryBuddy. The reason is because when you are adding
321 buddies, you tell the server who is on your buddy list so it can tell you
322 about them; in order to tell the server, it needs to go out over a
323 connection. Going out over all connections would not be good, so you need
324 to specify which connection they go out on.
325
326 Managing lists is therefore fairly easy, each group and buddy has an
327 associated connection. Management functions like add_buddy/remove_buddy
328 and add_group/remove_group all take a gaim_connection. These are all in
329 list.c. They're boring.
330
331 The window is a lot more fun. There's really only one function that
332 does anything interesting, and that's set_buddy. (There's also things
333 like build_edit_tree, but that's boring.) set_buddy is called by
334 serv_got_update (and should only be called by that function) any time
335 a user signs on, signs off, goes away, comes back, goes idle, etc, etc,
336 etc. Various things happen depending on the new state of the buddy.
337
338 struct buddy has a member, present, which is set to either 0, 1, or
339 2. You can check if the buddy is online with "if (b->present)". This
340 becomes important. present is set to either 0 or 1 by serv_got_update,
341 or is not set at all. When the buddy is passed to set_buddy, if present
342 is 1 then set_buddy plays the BUDDY_ARRIVE sound, and sets present to 2,
343 to indicate it has already received notification of arrival. It then
344 does other signin-related stuff: setting the pixmap to the login icon;
345 updating the conversation windows; etc.
346
347 The most important thing it does though, if a buddy is present, is it
348 checks for the existance of the appropriate group_show and buddy_show for
349 that buddy. Each buddy must belong to a group. group_shows are based on
350 name; there can only be one group_show for each group name. buddy_shows
351 are based both on name and on group_show; there can only be one buddy_show
352 in a group_show for each name. However, there can be two buddy_shows
353 with the same name as long as they have different group_shows.
354
355 Each buddy_show has a GList of connections that has registered its related
356 buddy as being online. set_buddy makes sure that the connection that it's
357 being passed is part of the connlist for the buddy_show associated with
358 the struct buddy that it's passed (it helps to know your data structures).
359
360 If a buddy logs off (b->present == 0), and a buddy_show exists for
361 that buddy, then set_buddy will play the logoff sound, change the icon,
362 remove the connection from the connlist for the buddy_show, etc.
363
364 And that's how that works. For the buddy lists, connections own buddies;
365 for the window, the buddies own the connections. When the buddy_show
366 connlist count drops to zero it disappears from existance.
367
368
369 PLUGINS
370 ======= 292 =======
371 293
372 OK, so you want to load a plugin. You go through whatever UI (you 294 OK, so you want to load a plugin. You go through whatever UI (you
373 can read all about the UI in plugins.c or whereever). You finally get 295 can read all about the UI in plugins.c or whereever). You finally get
374 to load_plugin, the meat of the plugins stuff (plugins can actually 296 to load_plugin, the meat of the plugins stuff (plugins can actually