Mercurial > pidgin
annotate src/main.c @ 5205:fefad67de2c7
[gaim-migrate @ 5573]
I had a damn good commit message, but it was eaten. Let's try it again.
Announcing, Gaim Plugin API version 2.0, or GPAPIV2.0 for short.
There are lots'a cool thingies here.
Okay now, this isn't as cool as the previous message, but:
1) There's now a single entry function for all plugin types. It returns a
detailed information structure on the plugin. This removes a lot of the
ugliness from old plugins. Oh yeah, libicq wasn't converted to this, so
if you use it, well, you shouldn't have used it anyway, but now you
can't! bwahahaha. Use AIM/ICQ.
2) There are now 3 types of plugins: Standard, Loader, and Protocol
plugins.
Standard plugins are, well, standard, compiled plugins.
Loader plugins load other plugins. For example, the perl support is now
a loader plugin. It loads perl scripts. In the future, we'll have
Ruby and Python loader plugins.
Protocol plugins are, well, protocol plugins... yeah...
3) Plugins have unique IDs, so they can be referred to or automatically
updated from a plugin database in the future. Neat, huh?
4) Plugins will have dependency support in the future, and can be hidden,
so if you have, say, a logging core plugin, it won't have to show up,
but then you load the GTK+ logging plugin and it'll auto-load the core
plugin. Core/UI split plugins!
5) There will eventually be custom plugin signals and RPC of some sort, for
the core/ui split plugins.
So, okay, back up .gaimrc.
I'd like to thank my parents for their support, javabsp for helping convert
a bunch of protocol plugins, and Etan for helping convert a bunch of
standard plugins.
Have fun. If you have any problems, please let me know, but you probably
won't have anything major happen. You will have to convert your plugins,
though, and I'm not guaranteeing that all perl scripts will still work.
I'll end up changing the perl script API eventually, so I know they won't
down the road. Don't worry, though. It'll be mass cool.
faceprint wants me to just commit the damn code already. So, here we go!!!
..
..
I need a massage. From a young, cute girl. Are there any young, cute girls
in the audience? IM me plz k thx.
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Fri, 25 Apr 2003 06:47:33 +0000 |
parents | cb700c07ee07 |
children | 0241d6b6702d |
rev | line source |
---|---|
4489 | 1 /* |
2 * gaim | |
3 * | |
4 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 * | |
20 */ | |
21 | |
22 #ifdef HAVE_CONFIG_H | |
23 #include <config.h> | |
24 #endif | |
25 #ifdef GAIM_PLUGINS | |
26 #ifndef _WIN32 | |
27 #include <dlfcn.h> | |
28 #endif | |
29 #endif /* GAIM_PLUGINS */ | |
30 #include <gtk/gtk.h> | |
31 #ifndef _WIN32 | |
32 #include <gdk/gdkx.h> | |
33 #include <unistd.h> | |
34 #include <sys/socket.h> | |
35 #include <netinet/in.h> | |
36 #include <arpa/inet.h> | |
37 #include <sys/un.h> | |
38 #include <sys/wait.h> | |
39 #endif /* !_WIN32 */ | |
40 #include <gdk/gdk.h> | |
41 #include <sys/types.h> | |
42 #include <sys/stat.h> | |
43 #include <errno.h> | |
44 #include <stdio.h> | |
45 #include <string.h> | |
46 #include <stdarg.h> | |
47 #include <stdlib.h> | |
48 #include <ctype.h> | |
49 #include "prpl.h" | |
4561 | 50 #include "sound.h" |
4489 | 51 #include "gaim.h" |
52 #include "gaim-socket.h" | |
4687 | 53 #include "gtklist.h" |
4489 | 54 #if HAVE_SIGNAL_H |
55 #include <signal.h> | |
56 #endif | |
57 #include "locale.h" | |
58 #include <getopt.h> | |
59 | |
60 #ifdef _WIN32 | |
61 #include "win32dep.h" | |
62 #endif | |
63 | |
64 static GtkWidget *name; | |
65 static GtkWidget *pass; | |
66 | |
67 GList *log_conversations = NULL; | |
68 GSList *away_messages = NULL; | |
69 GSList *message_queue = NULL; | |
70 GSList *unread_message_queue = NULL; | |
71 GSList *away_time_queue = NULL; | |
72 | |
73 GtkWidget *mainwindow = NULL; | |
74 | |
4561 | 75 |
4489 | 76 int opt_away = 0; |
4687 | 77 int docklet_count = 0; |
4489 | 78 char *opt_away_arg = NULL; |
79 char *opt_rcfile_arg = NULL; | |
80 int opt_debug = 0; | |
81 #ifdef _WIN32 | |
82 int opt_gdebug = 0; | |
83 #endif | |
84 | |
85 #if HAVE_SIGNAL_H | |
86 /* | |
87 * Lists of signals we wish to catch and those we wish to ignore. | |
88 * Each list terminated with -1 | |
89 */ | |
90 static int catch_sig_list[] = { | |
91 SIGSEGV, | |
92 SIGHUP, | |
93 SIGINT, | |
94 SIGTERM, | |
95 SIGQUIT, | |
96 SIGCHLD, | |
97 -1 | |
98 }; | |
99 | |
100 static int ignore_sig_list[] = { | |
101 SIGPIPE, | |
102 -1 | |
103 }; | |
104 #endif | |
105 | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
106 STATIC_PROTO_INIT |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
107 |
4489 | 108 void do_quit() |
109 { | |
110 /* captain's log, stardate... */ | |
111 system_log(log_quit, NULL, NULL, OPT_LOG_BUDDY_SIGNON | OPT_LOG_MY_SIGNON); | |
112 | |
113 /* the self destruct sequence has been initiated */ | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
114 gaim_event_broadcast(event_quit); |
4489 | 115 |
116 /* transmission ends */ | |
117 signoff_all(); | |
118 | |
119 /* record what we have before we blow it away... */ | |
120 save_prefs(); | |
121 | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
122 debug_printf("Unloading all plugins\n"); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
123 gaim_plugins_unload_all(); |
4489 | 124 |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
125 /* XXX */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
126 #if 0 |
4489 | 127 #ifdef USE_PERL |
128 /* yup, perl too */ | |
129 perl_end(); | |
130 #endif | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
131 #endif |
4489 | 132 |
133 #ifdef USE_SM | |
134 /* unplug */ | |
135 session_end(); | |
136 #endif | |
137 | |
138 /* and end it all... */ | |
139 gtk_main_quit(); | |
140 } | |
141 | |
4561 | 142 static guint snd_tmout = 0; |
4489 | 143 static gboolean sound_timeout(gpointer data) |
144 { | |
4561 | 145 gaim_sound_set_login_mute(FALSE); |
146 snd_tmout = 0; | |
4489 | 147 return FALSE; |
148 } | |
149 | |
150 /* we need to do this for Oscar because serv_login only starts the login | |
151 * process, it doesn't end there. gaim_setup will be called later from | |
152 * oscar.c, after the buddy list is made and serv_finish_login is called */ | |
153 void gaim_setup(struct gaim_connection *gc) | |
154 { | |
155 if ((sound_options & OPT_SOUND_LOGIN) && (sound_options & OPT_SOUND_SILENT_SIGNON)) { | |
4561 | 156 if(snd_tmout) { |
157 g_source_remove(snd_tmout); | |
158 } | |
159 gaim_sound_set_login_mute(TRUE); | |
4489 | 160 snd_tmout = g_timeout_add(10000, sound_timeout, NULL); |
161 } | |
162 } | |
163 | |
164 static gboolean domiddleclick(GtkWidget *w, GdkEventButton *event, gpointer null) | |
165 { | |
166 if (event->button != 2) | |
167 return FALSE; | |
168 | |
169 auto_login(); | |
170 return TRUE; | |
171 } | |
172 | |
173 static void dologin(GtkWidget *widget, GtkWidget *w) | |
174 { | |
4491 | 175 struct gaim_account *account; |
4489 | 176 const char *username = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(name)->entry)); |
177 const char *password = gtk_entry_get_text(GTK_ENTRY(pass)); | |
178 | |
179 if (!strlen(username)) { | |
180 do_error_dialog(_("Please enter your login."), NULL, GAIM_ERROR); | |
181 return; | |
182 } | |
183 | |
184 /* if there is more than one user of the same name, then fuck | |
185 * them, they just have to use the account editor to sign in | |
186 * the second one */ | |
187 | |
4491 | 188 account = gaim_account_find(username, -1); |
189 if (!account) | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
190 account = gaim_account_new(username, GAIM_PROTO_DEFAULT, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
191 OPT_ACCT_REM_PASS); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
192 |
4491 | 193 g_snprintf(account->password, sizeof account->password, "%s", password); |
4489 | 194 save_prefs(); |
4491 | 195 serv_login(account); |
4489 | 196 } |
197 | |
198 /* <name> is a comma-separated list of names, or NULL | |
199 if NULL and there is at least one user defined in .gaimrc, try to login. | |
200 if not NULL, parse <name> into separate strings, look up each one in | |
201 .gaimrc and, if it's there, try to login. | |
202 returns: 0 if successful | |
203 -1 if no user was found that had a saved password | |
204 */ | |
205 static int dologin_named(char *name) | |
206 { | |
4491 | 207 struct gaim_account *account; |
4489 | 208 char **names, **n; |
209 int retval = -1; | |
210 | |
211 if (name !=NULL) { /* list of names given */ | |
212 names = g_strsplit(name, ",", 32); | |
213 for (n = names; *n != NULL; n++) { | |
4491 | 214 account = gaim_account_find(*n, -1); |
215 if (account) { /* found a user */ | |
216 if (account->options & OPT_ACCT_REM_PASS) { | |
4489 | 217 retval = 0; |
4491 | 218 serv_login(account); |
4489 | 219 } |
220 } | |
221 } | |
222 g_strfreev(names); | |
223 } else { /* no name given, use default */ | |
4491 | 224 account = (struct gaim_account *)gaim_accounts->data; |
225 if (account->options & OPT_ACCT_REM_PASS) { | |
4489 | 226 retval = 0; |
4491 | 227 serv_login(account); |
4489 | 228 } |
229 } | |
230 | |
231 return retval; | |
232 } | |
233 | |
234 | |
235 static void doenter(GtkWidget *widget, GtkWidget *w) | |
236 { | |
237 if (widget == name) { | |
238 gtk_entry_set_text(GTK_ENTRY(pass), ""); | |
4635 | 239 gtk_editable_select_region(GTK_EDITABLE(GTK_COMBO(name)->entry), 0, 0); |
4489 | 240 gtk_widget_grab_focus(pass); |
241 } else if (widget == pass) { | |
242 dologin(widget, w); | |
243 } | |
244 } | |
245 | |
246 | |
247 static void combo_changed(GtkWidget *w, GtkWidget *combo) | |
248 { | |
249 const char *txt = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo)->entry)); | |
4491 | 250 struct gaim_account *account; |
4489 | 251 |
4491 | 252 account = gaim_account_find(txt, -1); |
4489 | 253 |
4491 | 254 if (account && account->options & OPT_ACCT_REM_PASS) { |
255 gtk_entry_set_text(GTK_ENTRY(pass), account->password); | |
4489 | 256 } else { |
257 gtk_entry_set_text(GTK_ENTRY(pass), ""); | |
258 } | |
259 } | |
260 | |
261 | |
262 static GList *combo_user_names() | |
263 { | |
4491 | 264 GSList *accts = gaim_accounts; |
4489 | 265 GList *tmp = NULL; |
4491 | 266 struct gaim_account *account; |
4489 | 267 |
4491 | 268 if (!accts) |
4489 | 269 return g_list_append(NULL, _("<New User>")); |
270 | |
4491 | 271 while (accts) { |
272 account = (struct gaim_account *)accts->data; | |
273 tmp = g_list_append(tmp, account->username); | |
274 accts = accts->next; | |
4489 | 275 } |
276 | |
277 return tmp; | |
278 } | |
279 | |
280 static void login_window_closed(GtkWidget *w, GdkEvent *ev, gpointer d) | |
281 { | |
282 if(docklet_count) { | |
4880
9b51c090236a
[gaim-migrate @ 5210]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4800
diff
changeset
|
283 #ifdef _WIN32 |
4489 | 284 wgaim_systray_minimize(mainwindow); |
285 #endif | |
286 gtk_widget_hide(mainwindow); | |
287 } else | |
288 do_quit(); | |
289 } | |
290 | |
291 void show_login() | |
292 { | |
293 GtkWidget *image; | |
294 GtkWidget *vbox; | |
295 GtkWidget *button; | |
296 GtkWidget *hbox; | |
297 GtkWidget *label; | |
298 GtkWidget *vbox2; | |
299 GList *tmp; | |
300 | |
301 /* Do we already have a main window opened? If so, bring it back, baby... ribs... yeah */ | |
302 if (mainwindow) { | |
303 gtk_window_present(GTK_WINDOW(mainwindow)); | |
304 return; | |
305 } | |
306 | |
307 mainwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
308 | |
309 gtk_window_set_role(GTK_WINDOW(mainwindow), "login"); | |
4635 | 310 gtk_window_set_resizable(GTK_WINDOW(mainwindow), FALSE); |
4703 | 311 gtk_window_set_title(GTK_WINDOW(mainwindow), _("Login")); |
4489 | 312 gtk_widget_realize(mainwindow); |
313 gdk_window_set_group(mainwindow->window, mainwindow->window); | |
314 gtk_container_set_border_width(GTK_CONTAINER(mainwindow), 5); | |
315 g_signal_connect(G_OBJECT(mainwindow), "delete_event", | |
316 G_CALLBACK(login_window_closed), mainwindow); | |
317 | |
318 vbox = gtk_vbox_new(FALSE, 0); | |
319 gtk_container_add(GTK_CONTAINER(mainwindow), vbox); | |
320 | |
5024 | 321 image = gtk_image_new_from_stock(GAIM_STOCK_LOGO, gtk_icon_size_from_name(GAIM_ICON_SIZE_LOGO)); |
4489 | 322 gtk_box_pack_start(GTK_BOX(vbox), image, FALSE, FALSE, 0); |
323 | |
324 vbox2 = gtk_vbox_new(FALSE, 0); | |
325 gtk_container_set_border_width(GTK_CONTAINER(vbox2), 5); | |
326 | |
327 label = gtk_label_new(_("Screen Name:")); | |
328 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
329 gtk_box_pack_start(GTK_BOX(vbox2), label, FALSE, FALSE, 0); | |
330 | |
331 name = gtk_combo_new(); | |
332 tmp = combo_user_names(); | |
333 gtk_combo_set_popdown_strings(GTK_COMBO(name), tmp); | |
334 g_list_free(tmp); | |
335 g_signal_connect(G_OBJECT(GTK_COMBO(name)->entry), "activate", | |
336 G_CALLBACK(doenter), mainwindow); | |
337 g_signal_connect(G_OBJECT(GTK_COMBO(name)->entry), "changed", | |
338 G_CALLBACK(combo_changed), name); | |
339 gtk_box_pack_start(GTK_BOX(vbox2), name, FALSE, TRUE, 0); | |
340 gtk_box_pack_start(GTK_BOX(vbox), vbox2, FALSE, TRUE, 0); | |
341 | |
342 vbox2 = gtk_vbox_new(FALSE, 0); | |
343 gtk_container_set_border_width(GTK_CONTAINER(vbox2), 5); | |
344 | |
345 label = gtk_label_new(_("Password:")); | |
346 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
347 gtk_box_pack_start(GTK_BOX(vbox2), label, FALSE, FALSE, 0); | |
348 | |
349 pass = gtk_entry_new(); | |
350 gtk_entry_set_visibility(GTK_ENTRY(pass), FALSE); | |
351 g_signal_connect(G_OBJECT(pass), "activate", | |
352 G_CALLBACK(doenter), mainwindow); | |
353 gtk_box_pack_start(GTK_BOX(vbox2), pass, FALSE, TRUE, 0); | |
354 gtk_box_pack_start(GTK_BOX(vbox), vbox2, FALSE, TRUE, 0); | |
355 | |
356 /* Now for the button box */ | |
357 hbox = gtk_hbox_new(TRUE, 0); | |
358 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 5); | |
359 | |
360 /* And now for the buttons */ | |
5024 | 361 button = gaim_pixbuf_button_from_stock(_("Accounts"), GAIM_STOCK_ACCOUNTS, GAIM_BUTTON_VERTICAL); |
4489 | 362 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); |
363 g_signal_connect(G_OBJECT(button), "clicked", | |
364 G_CALLBACK(account_editor), mainwindow); | |
365 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
366 | |
367 #ifdef NO_MULTI | |
368 gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE); | |
369 #endif | |
370 | |
5024 | 371 button = gaim_pixbuf_button_from_stock(_("Preferences"), GTK_STOCK_PREFERENCES, GAIM_BUTTON_VERTICAL); |
4489 | 372 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); |
373 g_signal_connect(G_OBJECT(button), "clicked", | |
374 G_CALLBACK(show_prefs), mainwindow); | |
375 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
376 | |
5024 | 377 button = gaim_pixbuf_button_from_stock(_("Sign On"), GAIM_STOCK_SIGN_ON, GAIM_BUTTON_VERTICAL); |
4489 | 378 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); |
379 g_signal_connect(G_OBJECT(button), "clicked", | |
380 G_CALLBACK(dologin), mainwindow); | |
381 g_signal_connect(G_OBJECT(button), "button-press-event", G_CALLBACK(domiddleclick), NULL); | |
382 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
383 | |
384 /* Now grab the focus that we need */ | |
4491 | 385 if (gaim_accounts) { |
386 struct gaim_account *account = gaim_accounts->data; | |
387 if (account->options & OPT_ACCT_REM_PASS) { | |
4489 | 388 combo_changed(NULL, name); |
389 gtk_widget_grab_focus(button); | |
390 } else { | |
391 gtk_widget_grab_focus(pass); | |
392 } | |
393 } else { | |
394 gtk_widget_grab_focus(name); | |
395 } | |
396 | |
397 /* And raise the curtain! */ | |
398 gtk_widget_show_all(mainwindow); | |
399 | |
400 } | |
401 | |
402 #if HAVE_SIGNAL_H | |
403 void sighandler(int sig) | |
404 { | |
405 switch (sig) { | |
406 case SIGHUP: | |
407 debug_printf("caught signal %d\n", sig); | |
408 signoff_all(NULL, NULL); | |
409 break; | |
410 case SIGSEGV: | |
411 core_quit(); | |
412 #ifndef DEBUG | |
413 fprintf(stderr, "Gaim has segfaulted and attempted to dump a core file.\n" | |
414 "This is a bug in the software and has happened through\n" | |
415 "no fault of your own.\n\n" | |
416 "It is possible that this bug is already fixed in CVS.\n" | |
417 "You can get a tarball of CVS from the Gaim website, at\n" | |
418 WEBSITE "gaim-CVS.tar.gz.\n\n" | |
419 "If you are already using CVS, or can reproduce the crash\n" | |
420 "using the CVS version, please notify the gaim maintainers\n" | |
421 "by reporting a bug at\n" | |
422 WEBSITE "bug.php\n\n" | |
423 "Please make sure to specify what you were doing at the time,\n" | |
424 "and post the backtrace from the core file. If you do not know\n" | |
425 "how to get the backtrace, please get instructions at\n" | |
426 WEBSITE "gdb.php. If you need further\n" | |
427 "assistance, please IM either RobFlynn or SeanEgn and\n" | |
428 "they can help you.\n"); | |
429 #else | |
430 fprintf(stderr, "Oh no! Segmentation fault!\n"); | |
4703 | 431 /*g_on_error_query (g_get_prgname());*/ |
4489 | 432 exit(1); |
433 #endif | |
434 abort(); | |
435 break; | |
436 case SIGCHLD: | |
437 clean_pid(); | |
438 #if HAVE_SIGNAL_H | |
439 signal(SIGCHLD, sighandler); /* restore signal catching on this one! */ | |
440 #endif | |
441 break; | |
442 default: | |
443 debug_printf("caught signal %d\n", sig); | |
444 signoff_all(NULL, NULL); | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
445 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
446 gaim_plugins_unload_all(); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
447 |
4489 | 448 if (gtk_main_level()) |
449 gtk_main_quit(); | |
450 core_quit(); | |
451 exit(0); | |
452 } | |
453 } | |
454 #endif | |
455 | |
456 #ifndef _WIN32 | |
457 static gboolean socket_readable(GIOChannel *source, GIOCondition cond, gpointer ud) | |
458 { | |
459 guchar type; | |
460 guchar subtype; | |
461 guint32 len; | |
462 guchar *data; | |
463 guint32 x; | |
4793 | 464 GError *error; |
4489 | 465 |
466 debug_printf("Core says: "); | |
4793 | 467 g_io_channel_read_chars(source, &type, sizeof(type), &x, &error); |
468 if(error) | |
4800 | 469 g_error_free(error); |
4489 | 470 if (x == 0) { |
471 debug_printf("CORE IS GONE!\n"); | |
4793 | 472 g_io_channel_shutdown(source, TRUE, &error); |
473 if(error) | |
474 g_free(error); | |
4489 | 475 return FALSE; |
476 } | |
477 debug_printf("%d ", type); | |
4793 | 478 g_io_channel_read_chars(source, &subtype, sizeof(subtype), &x, &error); |
479 if(error) | |
4800 | 480 g_error_free(error); |
4489 | 481 if (x == 0) { |
482 debug_printf("CORE IS GONE!\n"); | |
4793 | 483 g_io_channel_shutdown(source, TRUE, &error); |
484 if(error) | |
4800 | 485 g_error_free(error); |
4489 | 486 return FALSE; |
487 } | |
488 debug_printf("%d ", subtype); | |
4793 | 489 g_io_channel_read_chars(source, (guchar *)&len, sizeof(len), &x, &error); |
490 if(error) | |
4800 | 491 g_error_free(error); |
4489 | 492 if (x == 0) { |
493 debug_printf("CORE IS GONE!\n"); | |
4793 | 494 g_io_channel_shutdown(source, TRUE, &error); |
495 if(error) | |
4800 | 496 g_error_free(error); |
4489 | 497 return FALSE; |
498 } | |
499 debug_printf("(%d bytes)\n", len); | |
500 | |
501 data = g_malloc(len); | |
4793 | 502 g_io_channel_read_chars(source, data, len, &x, &error); |
503 if(error) | |
4800 | 504 g_error_free(error); |
4489 | 505 if (x != len) { |
506 debug_printf("CORE IS GONE! (read %d/%d bytes)\n", x, len); | |
507 g_free(data); | |
4793 | 508 g_io_channel_shutdown(source, TRUE, &error); |
509 if(error) | |
4800 | 510 g_error_free(error); |
4489 | 511 return FALSE; |
512 } | |
513 | |
514 g_free(data); | |
515 return TRUE; | |
516 } | |
517 #endif /* _WIN32 */ | |
518 | |
519 static int ui_main() | |
520 { | |
521 #ifndef _WIN32 | |
522 GIOChannel *channel; | |
523 int UI_fd; | |
524 char name[256]; | |
525 GList *icons = NULL; | |
526 GdkPixbuf *icon = NULL; | |
527 char *icon_path; | |
528 #endif | |
4978 | 529 |
4489 | 530 if (current_smiley_theme == NULL) { |
531 smiley_theme_probe(); | |
532 if (smiley_themes) { | |
533 struct smiley_theme *smile = smiley_themes->data; | |
534 load_smiley_theme(smile->path, TRUE); | |
535 } | |
536 } | |
537 | |
538 setup_stock(); | |
539 | |
540 #ifndef _WIN32 | |
541 /* use the nice PNG icon for all the windows */ | |
5024 | 542 icon_path = g_build_filename(DATADIR, "pixmaps", "gaim", "icons", "online.png", NULL); |
4489 | 543 icon = gdk_pixbuf_new_from_file(icon_path, NULL); |
544 g_free(icon_path); | |
545 if (icon) { | |
546 icons = g_list_append(icons,icon); | |
547 gtk_window_set_default_icon_list(icons); | |
548 g_object_unref(G_OBJECT(icon)); | |
4978 | 549 g_list_free(icons); |
4489 | 550 } else { |
4978 | 551 debug_printf("Failed to load default window icon!\n"); |
4489 | 552 } |
553 | |
554 g_snprintf(name, sizeof(name), "%s" G_DIR_SEPARATOR_S "gaim_%s.%d", g_get_tmp_dir(), g_get_user_name(), gaim_session); | |
555 UI_fd = gaim_connect_to_session(0); | |
556 if (UI_fd < 0) | |
557 return 1; | |
558 | |
559 channel = g_io_channel_unix_new(UI_fd); | |
560 g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_ERR, socket_readable, NULL); | |
561 #endif | |
4978 | 562 |
4489 | 563 return 0; |
564 } | |
565 | |
566 static void set_first_user(char *name) | |
567 { | |
4491 | 568 struct gaim_account *account; |
4489 | 569 |
4491 | 570 account = gaim_account_find(name, -1); |
4489 | 571 |
4491 | 572 if (!account) { /* new user */ |
573 account = g_new0(struct gaim_account, 1); | |
574 g_snprintf(account->username, sizeof(account->username), "%s", name); | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
575 account->protocol = GAIM_PROTO_DEFAULT; |
4491 | 576 gaim_accounts = g_slist_prepend(gaim_accounts, account); |
4489 | 577 } else { /* user already exists */ |
4491 | 578 gaim_accounts = g_slist_remove(gaim_accounts, account); |
579 gaim_accounts = g_slist_prepend(gaim_accounts, account); | |
4489 | 580 } |
581 save_prefs(); | |
582 } | |
583 | |
584 #ifdef _WIN32 | |
585 /* WIN32 print and log handlers */ | |
586 | |
587 static void gaim_dummy_print( const gchar* string ) { | |
588 return; | |
589 } | |
590 | |
591 static void gaim_dummy_log_handler (const gchar *domain, | |
592 GLogLevelFlags flags, | |
593 const gchar *msg, | |
594 gpointer user_data) { | |
595 return; | |
596 } | |
597 | |
598 static void gaim_log_handler (const gchar *domain, | |
599 GLogLevelFlags flags, | |
600 const gchar *msg, | |
601 gpointer user_data) { | |
602 debug_printf("%s - %s\n", domain, msg); | |
603 g_log_default_handler(domain, flags, msg, user_data); | |
604 } | |
605 #endif /* _WIN32 */ | |
606 | |
607 /* FUCKING GET ME A TOWEL! */ | |
608 #ifdef _WIN32 | |
609 int gaim_main(int argc, char *argv[]) | |
610 #else | |
611 int main(int argc, char *argv[]) | |
612 #endif | |
613 { | |
614 int opt_acct = 0, opt_help = 0, opt_version = 0, opt_login = 0, opt_nologin = 0, dologin_ret = -1; | |
615 char *opt_user_arg = NULL, *opt_login_arg = NULL; | |
616 char *opt_session_arg = NULL; | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
617 char *plugin_search_paths[3]; |
4489 | 618 #if HAVE_SIGNAL_H |
619 int sig_indx; /* for setting up signal catching */ | |
620 sigset_t sigset; | |
621 void (*prev_sig_disp)(); | |
622 #endif | |
623 int opt, opt_user = 0; | |
624 int i; | |
625 | |
626 struct option long_options[] = { | |
627 {"acct", no_argument, NULL, 'a'}, | |
628 /*{"away", optional_argument, NULL, 'w'}, */ | |
629 {"help", no_argument, NULL, 'h'}, | |
630 /*{"login", optional_argument, NULL, 'l'}, */ | |
631 {"loginwin", no_argument, NULL, 'n'}, | |
632 {"user", required_argument, NULL, 'u'}, | |
633 {"file", required_argument, NULL, 'f'}, | |
634 {"debug", no_argument, NULL, 'd'}, | |
635 {"version", no_argument, NULL, 'v'}, | |
636 {"session", required_argument, NULL, 's'}, | |
637 {0, 0, 0, 0} | |
638 }; | |
639 | |
640 #ifdef DEBUG | |
641 opt_debug = 1; | |
642 #endif | |
643 | |
644 #ifdef ENABLE_NLS | |
645 bindtextdomain(PACKAGE, LOCALEDIR); | |
646 bind_textdomain_codeset(PACKAGE, "UTF-8"); | |
647 textdomain(PACKAGE); | |
648 #endif | |
649 | |
650 #if HAVE_SIGNAL_H | |
651 /* Let's not violate any PLA's!!!! */ | |
652 /* jseymour: whatever the fsck that means */ | |
653 /* Robot101: for some reason things like gdm like to block * | |
654 * useful signals like SIGCHLD, so we unblock all the ones we * | |
655 * declare a handler for. thanks JSeymour and Vann. */ | |
656 if (sigemptyset(&sigset)) { | |
657 char errmsg[BUFSIZ]; | |
658 sprintf(errmsg, "Warning: couldn't initialise empty signal set"); | |
659 perror(errmsg); | |
660 } | |
661 for(sig_indx = 0; catch_sig_list[sig_indx] != -1; ++sig_indx) { | |
662 if((prev_sig_disp = signal(catch_sig_list[sig_indx], sighandler)) == SIG_ERR) { | |
663 char errmsg[BUFSIZ]; | |
664 sprintf(errmsg, "Warning: couldn't set signal %d for catching", | |
665 catch_sig_list[sig_indx]); | |
666 perror(errmsg); | |
667 } | |
668 if(sigaddset(&sigset, catch_sig_list[sig_indx])) { | |
669 char errmsg[BUFSIZ]; | |
670 sprintf(errmsg, "Warning: couldn't include signal %d for unblocking", | |
671 catch_sig_list[sig_indx]); | |
672 perror(errmsg); | |
673 } | |
674 } | |
675 for(sig_indx = 0; ignore_sig_list[sig_indx] != -1; ++sig_indx) { | |
676 if((prev_sig_disp = signal(ignore_sig_list[sig_indx], SIG_IGN)) == SIG_ERR) { | |
677 char errmsg[BUFSIZ]; | |
678 sprintf(errmsg, "Warning: couldn't set signal %d to ignore", | |
679 ignore_sig_list[sig_indx]); | |
680 perror(errmsg); | |
681 } | |
682 } | |
683 | |
684 if (sigprocmask(SIG_UNBLOCK, &sigset, NULL)) { | |
685 char errmsg[BUFSIZ]; | |
686 sprintf(errmsg, "Warning: couldn't unblock signals"); | |
687 perror(errmsg); | |
688 } | |
689 #endif | |
690 | |
691 for (i = 0; i < argc; i++) { | |
692 /* --login option */ | |
693 if (strstr(argv[i], "--l") == argv[i]) { | |
694 char *equals; | |
695 opt_login = 1; | |
696 if ((equals = strchr(argv[i], '=')) != NULL) { | |
697 /* --login=NAME */ | |
698 opt_login_arg = g_strdup(equals + 1); | |
699 if (strlen(opt_login_arg) == 0) { | |
700 g_free(opt_login_arg); | |
701 opt_login_arg = NULL; | |
702 } | |
703 } else if (i + 1 < argc && argv[i + 1][0] != '-') { | |
704 /* --login NAME */ | |
705 opt_login_arg = g_strdup(argv[i + 1]); | |
706 strcpy(argv[i + 1], " "); | |
707 } | |
708 strcpy(argv[i], " "); | |
709 } | |
710 /* -l option */ | |
711 else if (strstr(argv[i], "-l") == argv[i]) { | |
712 opt_login = 1; | |
713 if (strlen(argv[i]) > 2) { | |
714 /* -lNAME */ | |
715 opt_login_arg = g_strdup(argv[i] + 2); | |
716 } else if (i + 1 < argc && argv[i + 1][0] != '-') { | |
717 /* -l NAME */ | |
718 opt_login_arg = g_strdup(argv[i + 1]); | |
719 strcpy(argv[i + 1], " "); | |
720 } | |
721 strcpy(argv[i], " "); | |
722 } | |
723 /* --away option */ | |
724 else if (strstr(argv[i], "--aw") == argv[i]) { | |
725 char *equals; | |
726 opt_away = 1; | |
727 if ((equals = strchr(argv[i], '=')) != NULL) { | |
728 /* --away=MESG */ | |
729 opt_away_arg = g_strdup(equals + 1); | |
730 if (strlen(opt_away_arg) == 0) { | |
731 g_free(opt_away_arg); | |
732 opt_away_arg = NULL; | |
733 } | |
734 } else if (i + 1 < argc && argv[i + 1][0] != '-') { | |
735 /* --away MESG */ | |
736 opt_away_arg = g_strdup(argv[i + 1]); | |
737 strcpy(argv[i + 1], " "); | |
738 } | |
739 strcpy(argv[i], " "); | |
740 } | |
741 /* -w option */ | |
742 else if (strstr(argv[i], "-w") == argv[i]) { | |
743 opt_away = 1; | |
744 if (strlen(argv[i]) > 2) { | |
745 /* -wMESG */ | |
746 opt_away_arg = g_strdup(argv[i] + 2); | |
747 } else if (i + 1 < argc && argv[i + 1][0] != '-') { | |
748 /* -w MESG */ | |
749 opt_away_arg = g_strdup(argv[i + 1]); | |
750 strcpy(argv[i + 1], " "); | |
751 } | |
752 strcpy(argv[i], " "); | |
753 } | |
754 } | |
755 /* | |
756 if (opt_login) { | |
757 printf ("--login given with arg %s\n", | |
758 opt_login_arg ? opt_login_arg : "NULL"); | |
759 exit(0); | |
760 } | |
761 */ | |
762 | |
763 gtk_set_locale(); | |
764 gtk_init(&argc, &argv); | |
765 | |
766 /* scan command-line options */ | |
767 opterr = 1; | |
768 while ((opt = getopt_long(argc, argv, | |
769 #ifndef _WIN32 | |
770 "adhu:f:vns:", | |
771 #else | |
772 "adghu:f:vn", | |
773 #endif | |
774 long_options, NULL)) != -1) { | |
775 switch (opt) { | |
776 case 'u': /* set user */ | |
777 opt_user = 1; | |
778 opt_user_arg = g_strdup(optarg); | |
779 break; | |
780 case 'a': /* account editor */ | |
781 opt_acct = 1; | |
782 break; | |
783 case 'd': /* debug */ | |
784 opt_debug = 1; | |
785 break; | |
786 case 'f': | |
787 opt_rcfile_arg = g_strdup(optarg); | |
788 break; | |
789 case 's': /* use existing session ID */ | |
790 opt_session_arg = g_strdup(optarg); | |
791 break; | |
792 case 'v': /* version */ | |
793 opt_version = 1; | |
794 break; | |
795 case 'h': /* help */ | |
796 opt_help = 1; | |
797 break; | |
798 case 'n': /* don't autologin */ | |
799 opt_nologin = 1; | |
800 break; | |
801 #ifdef _WIN32 | |
802 case 'g': /* debug GTK and GLIB */ | |
803 opt_gdebug = 1; | |
804 break; | |
805 #endif | |
806 case '?': | |
807 default: | |
808 show_usage(1, argv[0]); | |
809 return 0; | |
810 break; | |
811 } | |
812 } | |
813 | |
814 #ifdef _WIN32 | |
815 /* We don't want a console window.. */ | |
816 /* | |
817 * Any calls to the glib logging functions, result in a call to AllocConsole(). | |
818 * ME and 98 will in such cases produce a console window (2000 not), despite | |
819 * being built as a windows app rather than a console app. So we should either | |
820 * ignore messages by setting dummy log handlers, or redirect messages. | |
821 * This requires setting handlers for all domains (any lib which uses g_logging). | |
822 */ | |
823 | |
824 g_log_set_handler (NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, | |
825 (opt_gdebug ? gaim_log_handler : gaim_dummy_log_handler), | |
826 NULL); | |
827 g_log_set_handler ("Gdk", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, | |
828 (opt_gdebug ? gaim_log_handler : gaim_dummy_log_handler), | |
829 NULL); | |
830 g_log_set_handler ("Gtk", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, | |
831 (opt_gdebug ? gaim_log_handler : gaim_dummy_log_handler), | |
832 NULL); | |
833 g_log_set_handler ("GLib", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, | |
834 (opt_gdebug ? gaim_log_handler : gaim_dummy_log_handler), | |
835 NULL); | |
836 g_log_set_handler ("GModule", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, | |
837 (opt_gdebug ? gaim_log_handler : gaim_dummy_log_handler), | |
838 NULL); | |
839 g_log_set_handler ("GLib-GObject", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, | |
840 (opt_gdebug ? gaim_log_handler : gaim_dummy_log_handler), | |
841 NULL); | |
842 g_log_set_handler ("GThread", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, | |
843 (opt_gdebug ? gaim_log_handler : gaim_dummy_log_handler), | |
844 NULL); | |
845 | |
846 /* g_print also makes a call to AllocConsole(), therefore a handler needs to be | |
847 set here aswell */ | |
848 if(!opt_debug) | |
849 g_set_print_handler( gaim_dummy_print ); | |
850 | |
851 #endif | |
852 | |
853 /* show help message */ | |
854 if (opt_help) { | |
855 show_usage(0, argv[0]); | |
856 return 0; | |
857 } | |
858 /* show version message */ | |
859 if (opt_version) { | |
860 printf("Gaim %s\n",VERSION); | |
861 return 0; | |
862 } | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
863 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
864 plugin_search_paths[0] = LIBDIR; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
865 plugin_search_paths[1] = gaim_user_dir(); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
866 plugin_search_paths[2] = g_strdup_printf("%s/plugins", gaim_user_dir()); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
867 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
868 gaim_plugins_set_search_paths(sizeof(plugin_search_paths) / |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
869 sizeof(*plugin_search_paths), |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
870 plugin_search_paths); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
871 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
872 g_free(plugin_search_paths[2]); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
873 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
874 gaim_plugins_probe(NULL); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5032
diff
changeset
|
875 |
4489 | 876 #ifdef _WIN32 |
877 /* Various win32 initializations */ | |
878 wgaim_init(); | |
879 #endif | |
880 | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4687
diff
changeset
|
881 /* Set the UI operation structures. */ |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4687
diff
changeset
|
882 gaim_set_win_ui_ops(gaim_get_gtk_window_ui_ops()); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4687
diff
changeset
|
883 gaim_set_xfer_ui_ops(gaim_get_gtk_xfer_ui_ops()); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4687
diff
changeset
|
884 gaim_set_blist_ui_ops(gaim_get_gtk_blist_ui_ops()); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4687
diff
changeset
|
885 |
4489 | 886 load_prefs(); |
887 core_main(); | |
5032
cb700c07ee07
[gaim-migrate @ 5375]
Christian Hammond <chipx86@chipx86.com>
parents:
5024
diff
changeset
|
888 load_pounces(); |
4489 | 889 ui_main(); |
890 | |
891 #ifdef USE_SM | |
892 session_init(argv[0], opt_session_arg); | |
893 #endif | |
894 if (opt_session_arg != NULL) { | |
895 g_free(opt_session_arg); | |
896 opt_session_arg = NULL; | |
897 }; | |
898 | |
899 /* set the default username */ | |
900 if (opt_user_arg != NULL) { | |
901 set_first_user(opt_user_arg); | |
902 g_free(opt_user_arg); | |
903 opt_user_arg = NULL; | |
904 } | |
905 | |
906 if (misc_options & OPT_MISC_DEBUG) | |
907 show_debug(); | |
908 | |
909 static_proto_init(); | |
910 | |
911 /* deal with --login */ | |
912 if (opt_login) { | |
913 dologin_ret = dologin_named(opt_login_arg); | |
914 if (opt_login_arg != NULL) { | |
915 g_free(opt_login_arg); | |
916 opt_login_arg = NULL; | |
917 } | |
918 } | |
919 | |
920 if (!opt_acct && !opt_nologin && gaim_session == 0) | |
921 auto_login(); | |
922 | |
923 if (opt_acct) { | |
924 account_editor(NULL, NULL); | |
925 } else if ((dologin_ret == -1) && !connections) | |
926 show_login(); | |
927 | |
928 gtk_main(); | |
929 core_quit(); | |
4561 | 930 gaim_sound_quit(); |
4489 | 931 #ifdef _WIN32 |
932 wgaim_cleanup(); | |
933 #endif | |
934 return 0; | |
935 | |
936 } |