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