Mercurial > pidgin.yaz
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 |