Mercurial > pidgin.yaz
annotate src/main.c @ 5032:cb700c07ee07
[gaim-migrate @ 5375]
Rewrote the buddy pounce code. It's now core/UI split, and may allow for
more advanced stuff later. Pounce actions are now a UI thing, and the
backend logic for registering, unregistering, and activating pouncs is now
in core. Also, the buddy pounce dialog was redesigned.
Oh, and there are new pounce types. You can now choose from:
* Sign on
* Sign off
* Away
* Return from away
* Idle
* Return from idle
* Buddy starts typing
* Buddy stops typing
Should work. I've been using it for some time. If you find a bug, though,
let me know.
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Sat, 05 Apr 2003 10:14:21 +0000 |
parents | 8e55a4d362a3 |
children | fefad67de2c7 |
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 | |
106 void do_quit() | |
107 { | |
108 /* captain's log, stardate... */ | |
109 system_log(log_quit, NULL, NULL, OPT_LOG_BUDDY_SIGNON | OPT_LOG_MY_SIGNON); | |
110 | |
111 /* the self destruct sequence has been initiated */ | |
112 plugin_event(event_quit); | |
113 | |
114 /* transmission ends */ | |
115 signoff_all(); | |
116 | |
117 /* record what we have before we blow it away... */ | |
118 save_prefs(); | |
119 | |
120 #ifdef GAIM_PLUGINS | |
121 /* jettison cargo */ | |
122 remove_all_plugins(); | |
123 #endif | |
124 | |
125 #ifdef USE_PERL | |
126 /* yup, perl too */ | |
127 perl_end(); | |
128 #endif | |
129 | |
130 #ifdef USE_SM | |
131 /* unplug */ | |
132 session_end(); | |
133 #endif | |
134 | |
135 /* and end it all... */ | |
136 gtk_main_quit(); | |
137 } | |
138 | |
4561 | 139 static guint snd_tmout = 0; |
4489 | 140 static gboolean sound_timeout(gpointer data) |
141 { | |
4561 | 142 gaim_sound_set_login_mute(FALSE); |
143 snd_tmout = 0; | |
4489 | 144 return FALSE; |
145 } | |
146 | |
147 /* we need to do this for Oscar because serv_login only starts the login | |
148 * process, it doesn't end there. gaim_setup will be called later from | |
149 * oscar.c, after the buddy list is made and serv_finish_login is called */ | |
150 void gaim_setup(struct gaim_connection *gc) | |
151 { | |
152 if ((sound_options & OPT_SOUND_LOGIN) && (sound_options & OPT_SOUND_SILENT_SIGNON)) { | |
4561 | 153 if(snd_tmout) { |
154 g_source_remove(snd_tmout); | |
155 } | |
156 gaim_sound_set_login_mute(TRUE); | |
4489 | 157 snd_tmout = g_timeout_add(10000, sound_timeout, NULL); |
158 } | |
159 } | |
160 | |
161 static gboolean domiddleclick(GtkWidget *w, GdkEventButton *event, gpointer null) | |
162 { | |
163 if (event->button != 2) | |
164 return FALSE; | |
165 | |
166 auto_login(); | |
167 return TRUE; | |
168 } | |
169 | |
170 static void dologin(GtkWidget *widget, GtkWidget *w) | |
171 { | |
4491 | 172 struct gaim_account *account; |
4489 | 173 const char *username = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(name)->entry)); |
174 const char *password = gtk_entry_get_text(GTK_ENTRY(pass)); | |
175 | |
176 if (!strlen(username)) { | |
177 do_error_dialog(_("Please enter your login."), NULL, GAIM_ERROR); | |
178 return; | |
179 } | |
180 | |
181 /* if there is more than one user of the same name, then fuck | |
182 * them, they just have to use the account editor to sign in | |
183 * the second one */ | |
184 | |
4491 | 185 account = gaim_account_find(username, -1); |
186 if (!account) | |
187 account = gaim_account_new(username, DEFAULT_PROTO, OPT_ACCT_REM_PASS); | |
188 g_snprintf(account->password, sizeof account->password, "%s", password); | |
4489 | 189 save_prefs(); |
4491 | 190 serv_login(account); |
4489 | 191 } |
192 | |
193 /* <name> is a comma-separated list of names, or NULL | |
194 if NULL and there is at least one user defined in .gaimrc, try to login. | |
195 if not NULL, parse <name> into separate strings, look up each one in | |
196 .gaimrc and, if it's there, try to login. | |
197 returns: 0 if successful | |
198 -1 if no user was found that had a saved password | |
199 */ | |
200 static int dologin_named(char *name) | |
201 { | |
4491 | 202 struct gaim_account *account; |
4489 | 203 char **names, **n; |
204 int retval = -1; | |
205 | |
206 if (name !=NULL) { /* list of names given */ | |
207 names = g_strsplit(name, ",", 32); | |
208 for (n = names; *n != NULL; n++) { | |
4491 | 209 account = gaim_account_find(*n, -1); |
210 if (account) { /* found a user */ | |
211 if (account->options & OPT_ACCT_REM_PASS) { | |
4489 | 212 retval = 0; |
4491 | 213 serv_login(account); |
4489 | 214 } |
215 } | |
216 } | |
217 g_strfreev(names); | |
218 } else { /* no name given, use default */ | |
4491 | 219 account = (struct gaim_account *)gaim_accounts->data; |
220 if (account->options & OPT_ACCT_REM_PASS) { | |
4489 | 221 retval = 0; |
4491 | 222 serv_login(account); |
4489 | 223 } |
224 } | |
225 | |
226 return retval; | |
227 } | |
228 | |
229 | |
230 static void doenter(GtkWidget *widget, GtkWidget *w) | |
231 { | |
232 if (widget == name) { | |
233 gtk_entry_set_text(GTK_ENTRY(pass), ""); | |
4635 | 234 gtk_editable_select_region(GTK_EDITABLE(GTK_COMBO(name)->entry), 0, 0); |
4489 | 235 gtk_widget_grab_focus(pass); |
236 } else if (widget == pass) { | |
237 dologin(widget, w); | |
238 } | |
239 } | |
240 | |
241 | |
242 static void combo_changed(GtkWidget *w, GtkWidget *combo) | |
243 { | |
244 const char *txt = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo)->entry)); | |
4491 | 245 struct gaim_account *account; |
4489 | 246 |
4491 | 247 account = gaim_account_find(txt, -1); |
4489 | 248 |
4491 | 249 if (account && account->options & OPT_ACCT_REM_PASS) { |
250 gtk_entry_set_text(GTK_ENTRY(pass), account->password); | |
4489 | 251 } else { |
252 gtk_entry_set_text(GTK_ENTRY(pass), ""); | |
253 } | |
254 } | |
255 | |
256 | |
257 static GList *combo_user_names() | |
258 { | |
4491 | 259 GSList *accts = gaim_accounts; |
4489 | 260 GList *tmp = NULL; |
4491 | 261 struct gaim_account *account; |
4489 | 262 |
4491 | 263 if (!accts) |
4489 | 264 return g_list_append(NULL, _("<New User>")); |
265 | |
4491 | 266 while (accts) { |
267 account = (struct gaim_account *)accts->data; | |
268 tmp = g_list_append(tmp, account->username); | |
269 accts = accts->next; | |
4489 | 270 } |
271 | |
272 return tmp; | |
273 } | |
274 | |
275 static void login_window_closed(GtkWidget *w, GdkEvent *ev, gpointer d) | |
276 { | |
277 if(docklet_count) { | |
4880
9b51c090236a
[gaim-migrate @ 5210]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4800
diff
changeset
|
278 #ifdef _WIN32 |
4489 | 279 wgaim_systray_minimize(mainwindow); |
280 #endif | |
281 gtk_widget_hide(mainwindow); | |
282 } else | |
283 do_quit(); | |
284 } | |
285 | |
286 void show_login() | |
287 { | |
288 GtkWidget *image; | |
289 GtkWidget *vbox; | |
290 GtkWidget *button; | |
291 GtkWidget *hbox; | |
292 GtkWidget *label; | |
293 GtkWidget *vbox2; | |
294 GList *tmp; | |
295 | |
296 /* Do we already have a main window opened? If so, bring it back, baby... ribs... yeah */ | |
297 if (mainwindow) { | |
298 gtk_window_present(GTK_WINDOW(mainwindow)); | |
299 return; | |
300 } | |
301 | |
302 mainwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
303 | |
304 gtk_window_set_role(GTK_WINDOW(mainwindow), "login"); | |
4635 | 305 gtk_window_set_resizable(GTK_WINDOW(mainwindow), FALSE); |
4703 | 306 gtk_window_set_title(GTK_WINDOW(mainwindow), _("Login")); |
4489 | 307 gtk_widget_realize(mainwindow); |
308 gdk_window_set_group(mainwindow->window, mainwindow->window); | |
309 gtk_container_set_border_width(GTK_CONTAINER(mainwindow), 5); | |
310 g_signal_connect(G_OBJECT(mainwindow), "delete_event", | |
311 G_CALLBACK(login_window_closed), mainwindow); | |
312 | |
313 vbox = gtk_vbox_new(FALSE, 0); | |
314 gtk_container_add(GTK_CONTAINER(mainwindow), vbox); | |
315 | |
5024 | 316 image = gtk_image_new_from_stock(GAIM_STOCK_LOGO, gtk_icon_size_from_name(GAIM_ICON_SIZE_LOGO)); |
4489 | 317 gtk_box_pack_start(GTK_BOX(vbox), image, FALSE, FALSE, 0); |
318 | |
319 vbox2 = gtk_vbox_new(FALSE, 0); | |
320 gtk_container_set_border_width(GTK_CONTAINER(vbox2), 5); | |
321 | |
322 label = gtk_label_new(_("Screen Name:")); | |
323 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
324 gtk_box_pack_start(GTK_BOX(vbox2), label, FALSE, FALSE, 0); | |
325 | |
326 name = gtk_combo_new(); | |
327 tmp = combo_user_names(); | |
328 gtk_combo_set_popdown_strings(GTK_COMBO(name), tmp); | |
329 g_list_free(tmp); | |
330 g_signal_connect(G_OBJECT(GTK_COMBO(name)->entry), "activate", | |
331 G_CALLBACK(doenter), mainwindow); | |
332 g_signal_connect(G_OBJECT(GTK_COMBO(name)->entry), "changed", | |
333 G_CALLBACK(combo_changed), name); | |
334 gtk_box_pack_start(GTK_BOX(vbox2), name, FALSE, TRUE, 0); | |
335 gtk_box_pack_start(GTK_BOX(vbox), vbox2, FALSE, TRUE, 0); | |
336 | |
337 vbox2 = gtk_vbox_new(FALSE, 0); | |
338 gtk_container_set_border_width(GTK_CONTAINER(vbox2), 5); | |
339 | |
340 label = gtk_label_new(_("Password:")); | |
341 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
342 gtk_box_pack_start(GTK_BOX(vbox2), label, FALSE, FALSE, 0); | |
343 | |
344 pass = gtk_entry_new(); | |
345 gtk_entry_set_visibility(GTK_ENTRY(pass), FALSE); | |
346 g_signal_connect(G_OBJECT(pass), "activate", | |
347 G_CALLBACK(doenter), mainwindow); | |
348 gtk_box_pack_start(GTK_BOX(vbox2), pass, FALSE, TRUE, 0); | |
349 gtk_box_pack_start(GTK_BOX(vbox), vbox2, FALSE, TRUE, 0); | |
350 | |
351 /* Now for the button box */ | |
352 hbox = gtk_hbox_new(TRUE, 0); | |
353 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 5); | |
354 | |
355 /* And now for the buttons */ | |
5024 | 356 button = gaim_pixbuf_button_from_stock(_("Accounts"), GAIM_STOCK_ACCOUNTS, GAIM_BUTTON_VERTICAL); |
4489 | 357 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); |
358 g_signal_connect(G_OBJECT(button), "clicked", | |
359 G_CALLBACK(account_editor), mainwindow); | |
360 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
361 | |
362 #ifdef NO_MULTI | |
363 gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE); | |
364 #endif | |
365 | |
5024 | 366 button = gaim_pixbuf_button_from_stock(_("Preferences"), GTK_STOCK_PREFERENCES, GAIM_BUTTON_VERTICAL); |
4489 | 367 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); |
368 g_signal_connect(G_OBJECT(button), "clicked", | |
369 G_CALLBACK(show_prefs), mainwindow); | |
370 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
371 | |
5024 | 372 button = gaim_pixbuf_button_from_stock(_("Sign On"), GAIM_STOCK_SIGN_ON, GAIM_BUTTON_VERTICAL); |
4489 | 373 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); |
374 g_signal_connect(G_OBJECT(button), "clicked", | |
375 G_CALLBACK(dologin), mainwindow); | |
376 g_signal_connect(G_OBJECT(button), "button-press-event", G_CALLBACK(domiddleclick), NULL); | |
377 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
378 | |
379 /* Now grab the focus that we need */ | |
4491 | 380 if (gaim_accounts) { |
381 struct gaim_account *account = gaim_accounts->data; | |
382 if (account->options & OPT_ACCT_REM_PASS) { | |
4489 | 383 combo_changed(NULL, name); |
384 gtk_widget_grab_focus(button); | |
385 } else { | |
386 gtk_widget_grab_focus(pass); | |
387 } | |
388 } else { | |
389 gtk_widget_grab_focus(name); | |
390 } | |
391 | |
392 /* And raise the curtain! */ | |
393 gtk_widget_show_all(mainwindow); | |
394 | |
395 } | |
396 | |
397 #if HAVE_SIGNAL_H | |
398 void sighandler(int sig) | |
399 { | |
400 switch (sig) { | |
401 case SIGHUP: | |
402 debug_printf("caught signal %d\n", sig); | |
403 signoff_all(NULL, NULL); | |
404 break; | |
405 case SIGSEGV: | |
406 core_quit(); | |
407 #ifndef DEBUG | |
408 fprintf(stderr, "Gaim has segfaulted and attempted to dump a core file.\n" | |
409 "This is a bug in the software and has happened through\n" | |
410 "no fault of your own.\n\n" | |
411 "It is possible that this bug is already fixed in CVS.\n" | |
412 "You can get a tarball of CVS from the Gaim website, at\n" | |
413 WEBSITE "gaim-CVS.tar.gz.\n\n" | |
414 "If you are already using CVS, or can reproduce the crash\n" | |
415 "using the CVS version, please notify the gaim maintainers\n" | |
416 "by reporting a bug at\n" | |
417 WEBSITE "bug.php\n\n" | |
418 "Please make sure to specify what you were doing at the time,\n" | |
419 "and post the backtrace from the core file. If you do not know\n" | |
420 "how to get the backtrace, please get instructions at\n" | |
421 WEBSITE "gdb.php. If you need further\n" | |
422 "assistance, please IM either RobFlynn or SeanEgn and\n" | |
423 "they can help you.\n"); | |
424 #else | |
425 fprintf(stderr, "Oh no! Segmentation fault!\n"); | |
4703 | 426 /*g_on_error_query (g_get_prgname());*/ |
4489 | 427 exit(1); |
428 #endif | |
429 abort(); | |
430 break; | |
431 case SIGCHLD: | |
432 clean_pid(); | |
433 #if HAVE_SIGNAL_H | |
434 signal(SIGCHLD, sighandler); /* restore signal catching on this one! */ | |
435 #endif | |
436 break; | |
437 default: | |
438 debug_printf("caught signal %d\n", sig); | |
439 signoff_all(NULL, NULL); | |
440 #ifdef GAIM_PLUGINS | |
441 remove_all_plugins(); | |
442 #endif | |
443 if (gtk_main_level()) | |
444 gtk_main_quit(); | |
445 core_quit(); | |
446 exit(0); | |
447 } | |
448 } | |
449 #endif | |
450 | |
451 #ifndef _WIN32 | |
452 static gboolean socket_readable(GIOChannel *source, GIOCondition cond, gpointer ud) | |
453 { | |
454 guchar type; | |
455 guchar subtype; | |
456 guint32 len; | |
457 guchar *data; | |
458 guint32 x; | |
4793 | 459 GError *error; |
4489 | 460 |
461 debug_printf("Core says: "); | |
4793 | 462 g_io_channel_read_chars(source, &type, sizeof(type), &x, &error); |
463 if(error) | |
4800 | 464 g_error_free(error); |
4489 | 465 if (x == 0) { |
466 debug_printf("CORE IS GONE!\n"); | |
4793 | 467 g_io_channel_shutdown(source, TRUE, &error); |
468 if(error) | |
469 g_free(error); | |
4489 | 470 return FALSE; |
471 } | |
472 debug_printf("%d ", type); | |
4793 | 473 g_io_channel_read_chars(source, &subtype, sizeof(subtype), &x, &error); |
474 if(error) | |
4800 | 475 g_error_free(error); |
4489 | 476 if (x == 0) { |
477 debug_printf("CORE IS GONE!\n"); | |
4793 | 478 g_io_channel_shutdown(source, TRUE, &error); |
479 if(error) | |
4800 | 480 g_error_free(error); |
4489 | 481 return FALSE; |
482 } | |
483 debug_printf("%d ", subtype); | |
4793 | 484 g_io_channel_read_chars(source, (guchar *)&len, sizeof(len), &x, &error); |
485 if(error) | |
4800 | 486 g_error_free(error); |
4489 | 487 if (x == 0) { |
488 debug_printf("CORE IS GONE!\n"); | |
4793 | 489 g_io_channel_shutdown(source, TRUE, &error); |
490 if(error) | |
4800 | 491 g_error_free(error); |
4489 | 492 return FALSE; |
493 } | |
494 debug_printf("(%d bytes)\n", len); | |
495 | |
496 data = g_malloc(len); | |
4793 | 497 g_io_channel_read_chars(source, data, len, &x, &error); |
498 if(error) | |
4800 | 499 g_error_free(error); |
4489 | 500 if (x != len) { |
501 debug_printf("CORE IS GONE! (read %d/%d bytes)\n", x, len); | |
502 g_free(data); | |
4793 | 503 g_io_channel_shutdown(source, TRUE, &error); |
504 if(error) | |
4800 | 505 g_error_free(error); |
4489 | 506 return FALSE; |
507 } | |
508 | |
509 g_free(data); | |
510 return TRUE; | |
511 } | |
512 #endif /* _WIN32 */ | |
513 | |
514 static int ui_main() | |
515 { | |
516 #ifndef _WIN32 | |
517 GIOChannel *channel; | |
518 int UI_fd; | |
519 char name[256]; | |
520 GList *icons = NULL; | |
521 GdkPixbuf *icon = NULL; | |
522 char *icon_path; | |
523 #endif | |
4978 | 524 |
4489 | 525 if (current_smiley_theme == NULL) { |
526 smiley_theme_probe(); | |
527 if (smiley_themes) { | |
528 struct smiley_theme *smile = smiley_themes->data; | |
529 load_smiley_theme(smile->path, TRUE); | |
530 } | |
531 } | |
532 | |
533 setup_stock(); | |
534 | |
535 #ifndef _WIN32 | |
536 /* use the nice PNG icon for all the windows */ | |
5024 | 537 icon_path = g_build_filename(DATADIR, "pixmaps", "gaim", "icons", "online.png", NULL); |
4489 | 538 icon = gdk_pixbuf_new_from_file(icon_path, NULL); |
539 g_free(icon_path); | |
540 if (icon) { | |
541 icons = g_list_append(icons,icon); | |
542 gtk_window_set_default_icon_list(icons); | |
543 g_object_unref(G_OBJECT(icon)); | |
4978 | 544 g_list_free(icons); |
4489 | 545 } else { |
4978 | 546 debug_printf("Failed to load default window icon!\n"); |
4489 | 547 } |
548 | |
549 g_snprintf(name, sizeof(name), "%s" G_DIR_SEPARATOR_S "gaim_%s.%d", g_get_tmp_dir(), g_get_user_name(), gaim_session); | |
550 UI_fd = gaim_connect_to_session(0); | |
551 if (UI_fd < 0) | |
552 return 1; | |
553 | |
554 channel = g_io_channel_unix_new(UI_fd); | |
555 g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_ERR, socket_readable, NULL); | |
556 #endif | |
4978 | 557 |
4489 | 558 return 0; |
559 } | |
560 | |
561 static void set_first_user(char *name) | |
562 { | |
4491 | 563 struct gaim_account *account; |
4489 | 564 |
4491 | 565 account = gaim_account_find(name, -1); |
4489 | 566 |
4491 | 567 if (!account) { /* new user */ |
568 account = g_new0(struct gaim_account, 1); | |
569 g_snprintf(account->username, sizeof(account->username), "%s", name); | |
570 account->protocol = DEFAULT_PROTO; | |
571 gaim_accounts = g_slist_prepend(gaim_accounts, account); | |
4489 | 572 } else { /* user already exists */ |
4491 | 573 gaim_accounts = g_slist_remove(gaim_accounts, account); |
574 gaim_accounts = g_slist_prepend(gaim_accounts, account); | |
4489 | 575 } |
576 save_prefs(); | |
577 } | |
578 | |
579 #ifdef _WIN32 | |
580 /* WIN32 print and log handlers */ | |
581 | |
582 static void gaim_dummy_print( const gchar* string ) { | |
583 return; | |
584 } | |
585 | |
586 static void gaim_dummy_log_handler (const gchar *domain, | |
587 GLogLevelFlags flags, | |
588 const gchar *msg, | |
589 gpointer user_data) { | |
590 return; | |
591 } | |
592 | |
593 static void gaim_log_handler (const gchar *domain, | |
594 GLogLevelFlags flags, | |
595 const gchar *msg, | |
596 gpointer user_data) { | |
597 debug_printf("%s - %s\n", domain, msg); | |
598 g_log_default_handler(domain, flags, msg, user_data); | |
599 } | |
600 #endif /* _WIN32 */ | |
601 | |
602 /* FUCKING GET ME A TOWEL! */ | |
603 #ifdef _WIN32 | |
604 int gaim_main(int argc, char *argv[]) | |
605 #else | |
606 int main(int argc, char *argv[]) | |
607 #endif | |
608 { | |
609 int opt_acct = 0, opt_help = 0, opt_version = 0, opt_login = 0, opt_nologin = 0, dologin_ret = -1; | |
610 char *opt_user_arg = NULL, *opt_login_arg = NULL; | |
611 char *opt_session_arg = NULL; | |
612 #if HAVE_SIGNAL_H | |
613 int sig_indx; /* for setting up signal catching */ | |
614 sigset_t sigset; | |
615 void (*prev_sig_disp)(); | |
616 #endif | |
617 int opt, opt_user = 0; | |
618 int i; | |
619 | |
620 struct option long_options[] = { | |
621 {"acct", no_argument, NULL, 'a'}, | |
622 /*{"away", optional_argument, NULL, 'w'}, */ | |
623 {"help", no_argument, NULL, 'h'}, | |
624 /*{"login", optional_argument, NULL, 'l'}, */ | |
625 {"loginwin", no_argument, NULL, 'n'}, | |
626 {"user", required_argument, NULL, 'u'}, | |
627 {"file", required_argument, NULL, 'f'}, | |
628 {"debug", no_argument, NULL, 'd'}, | |
629 {"version", no_argument, NULL, 'v'}, | |
630 {"session", required_argument, NULL, 's'}, | |
631 {0, 0, 0, 0} | |
632 }; | |
633 | |
634 #ifdef DEBUG | |
635 opt_debug = 1; | |
636 #endif | |
637 | |
638 #ifdef ENABLE_NLS | |
639 bindtextdomain(PACKAGE, LOCALEDIR); | |
640 bind_textdomain_codeset(PACKAGE, "UTF-8"); | |
641 textdomain(PACKAGE); | |
642 #endif | |
643 | |
644 #if HAVE_SIGNAL_H | |
645 /* Let's not violate any PLA's!!!! */ | |
646 /* jseymour: whatever the fsck that means */ | |
647 /* Robot101: for some reason things like gdm like to block * | |
648 * useful signals like SIGCHLD, so we unblock all the ones we * | |
649 * declare a handler for. thanks JSeymour and Vann. */ | |
650 if (sigemptyset(&sigset)) { | |
651 char errmsg[BUFSIZ]; | |
652 sprintf(errmsg, "Warning: couldn't initialise empty signal set"); | |
653 perror(errmsg); | |
654 } | |
655 for(sig_indx = 0; catch_sig_list[sig_indx] != -1; ++sig_indx) { | |
656 if((prev_sig_disp = signal(catch_sig_list[sig_indx], sighandler)) == SIG_ERR) { | |
657 char errmsg[BUFSIZ]; | |
658 sprintf(errmsg, "Warning: couldn't set signal %d for catching", | |
659 catch_sig_list[sig_indx]); | |
660 perror(errmsg); | |
661 } | |
662 if(sigaddset(&sigset, catch_sig_list[sig_indx])) { | |
663 char errmsg[BUFSIZ]; | |
664 sprintf(errmsg, "Warning: couldn't include signal %d for unblocking", | |
665 catch_sig_list[sig_indx]); | |
666 perror(errmsg); | |
667 } | |
668 } | |
669 for(sig_indx = 0; ignore_sig_list[sig_indx] != -1; ++sig_indx) { | |
670 if((prev_sig_disp = signal(ignore_sig_list[sig_indx], SIG_IGN)) == SIG_ERR) { | |
671 char errmsg[BUFSIZ]; | |
672 sprintf(errmsg, "Warning: couldn't set signal %d to ignore", | |
673 ignore_sig_list[sig_indx]); | |
674 perror(errmsg); | |
675 } | |
676 } | |
677 | |
678 if (sigprocmask(SIG_UNBLOCK, &sigset, NULL)) { | |
679 char errmsg[BUFSIZ]; | |
680 sprintf(errmsg, "Warning: couldn't unblock signals"); | |
681 perror(errmsg); | |
682 } | |
683 #endif | |
684 | |
685 for (i = 0; i < argc; i++) { | |
686 /* --login option */ | |
687 if (strstr(argv[i], "--l") == argv[i]) { | |
688 char *equals; | |
689 opt_login = 1; | |
690 if ((equals = strchr(argv[i], '=')) != NULL) { | |
691 /* --login=NAME */ | |
692 opt_login_arg = g_strdup(equals + 1); | |
693 if (strlen(opt_login_arg) == 0) { | |
694 g_free(opt_login_arg); | |
695 opt_login_arg = NULL; | |
696 } | |
697 } else if (i + 1 < argc && argv[i + 1][0] != '-') { | |
698 /* --login NAME */ | |
699 opt_login_arg = g_strdup(argv[i + 1]); | |
700 strcpy(argv[i + 1], " "); | |
701 } | |
702 strcpy(argv[i], " "); | |
703 } | |
704 /* -l option */ | |
705 else if (strstr(argv[i], "-l") == argv[i]) { | |
706 opt_login = 1; | |
707 if (strlen(argv[i]) > 2) { | |
708 /* -lNAME */ | |
709 opt_login_arg = g_strdup(argv[i] + 2); | |
710 } else if (i + 1 < argc && argv[i + 1][0] != '-') { | |
711 /* -l NAME */ | |
712 opt_login_arg = g_strdup(argv[i + 1]); | |
713 strcpy(argv[i + 1], " "); | |
714 } | |
715 strcpy(argv[i], " "); | |
716 } | |
717 /* --away option */ | |
718 else if (strstr(argv[i], "--aw") == argv[i]) { | |
719 char *equals; | |
720 opt_away = 1; | |
721 if ((equals = strchr(argv[i], '=')) != NULL) { | |
722 /* --away=MESG */ | |
723 opt_away_arg = g_strdup(equals + 1); | |
724 if (strlen(opt_away_arg) == 0) { | |
725 g_free(opt_away_arg); | |
726 opt_away_arg = NULL; | |
727 } | |
728 } else if (i + 1 < argc && argv[i + 1][0] != '-') { | |
729 /* --away MESG */ | |
730 opt_away_arg = g_strdup(argv[i + 1]); | |
731 strcpy(argv[i + 1], " "); | |
732 } | |
733 strcpy(argv[i], " "); | |
734 } | |
735 /* -w option */ | |
736 else if (strstr(argv[i], "-w") == argv[i]) { | |
737 opt_away = 1; | |
738 if (strlen(argv[i]) > 2) { | |
739 /* -wMESG */ | |
740 opt_away_arg = g_strdup(argv[i] + 2); | |
741 } else if (i + 1 < argc && argv[i + 1][0] != '-') { | |
742 /* -w MESG */ | |
743 opt_away_arg = g_strdup(argv[i + 1]); | |
744 strcpy(argv[i + 1], " "); | |
745 } | |
746 strcpy(argv[i], " "); | |
747 } | |
748 } | |
749 /* | |
750 if (opt_login) { | |
751 printf ("--login given with arg %s\n", | |
752 opt_login_arg ? opt_login_arg : "NULL"); | |
753 exit(0); | |
754 } | |
755 */ | |
756 | |
757 gtk_set_locale(); | |
758 gtk_init(&argc, &argv); | |
759 | |
760 /* scan command-line options */ | |
761 opterr = 1; | |
762 while ((opt = getopt_long(argc, argv, | |
763 #ifndef _WIN32 | |
764 "adhu:f:vns:", | |
765 #else | |
766 "adghu:f:vn", | |
767 #endif | |
768 long_options, NULL)) != -1) { | |
769 switch (opt) { | |
770 case 'u': /* set user */ | |
771 opt_user = 1; | |
772 opt_user_arg = g_strdup(optarg); | |
773 break; | |
774 case 'a': /* account editor */ | |
775 opt_acct = 1; | |
776 break; | |
777 case 'd': /* debug */ | |
778 opt_debug = 1; | |
779 break; | |
780 case 'f': | |
781 opt_rcfile_arg = g_strdup(optarg); | |
782 break; | |
783 case 's': /* use existing session ID */ | |
784 opt_session_arg = g_strdup(optarg); | |
785 break; | |
786 case 'v': /* version */ | |
787 opt_version = 1; | |
788 break; | |
789 case 'h': /* help */ | |
790 opt_help = 1; | |
791 break; | |
792 case 'n': /* don't autologin */ | |
793 opt_nologin = 1; | |
794 break; | |
795 #ifdef _WIN32 | |
796 case 'g': /* debug GTK and GLIB */ | |
797 opt_gdebug = 1; | |
798 break; | |
799 #endif | |
800 case '?': | |
801 default: | |
802 show_usage(1, argv[0]); | |
803 return 0; | |
804 break; | |
805 } | |
806 } | |
807 | |
808 #ifdef _WIN32 | |
809 /* We don't want a console window.. */ | |
810 /* | |
811 * Any calls to the glib logging functions, result in a call to AllocConsole(). | |
812 * ME and 98 will in such cases produce a console window (2000 not), despite | |
813 * being built as a windows app rather than a console app. So we should either | |
814 * ignore messages by setting dummy log handlers, or redirect messages. | |
815 * This requires setting handlers for all domains (any lib which uses g_logging). | |
816 */ | |
817 | |
818 g_log_set_handler (NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, | |
819 (opt_gdebug ? gaim_log_handler : gaim_dummy_log_handler), | |
820 NULL); | |
821 g_log_set_handler ("Gdk", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, | |
822 (opt_gdebug ? gaim_log_handler : gaim_dummy_log_handler), | |
823 NULL); | |
824 g_log_set_handler ("Gtk", 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 ("GLib", 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 ("GModule", 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-GObject", 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 ("GThread", 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 | |
840 /* g_print also makes a call to AllocConsole(), therefore a handler needs to be | |
841 set here aswell */ | |
842 if(!opt_debug) | |
843 g_set_print_handler( gaim_dummy_print ); | |
844 | |
845 #endif | |
846 | |
847 /* show help message */ | |
848 if (opt_help) { | |
849 show_usage(0, argv[0]); | |
850 return 0; | |
851 } | |
852 /* show version message */ | |
853 if (opt_version) { | |
854 printf("Gaim %s\n",VERSION); | |
855 return 0; | |
856 } | |
857 | |
858 #if GAIM_PLUGINS || USE_PERL | |
859 gaim_probe_plugins(); | |
860 #endif | |
861 | |
862 #ifdef _WIN32 | |
863 /* Various win32 initializations */ | |
864 wgaim_init(); | |
865 #endif | |
866 | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4687
diff
changeset
|
867 /* Set the UI operation structures. */ |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4687
diff
changeset
|
868 gaim_set_win_ui_ops(gaim_get_gtk_window_ui_ops()); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4687
diff
changeset
|
869 gaim_set_xfer_ui_ops(gaim_get_gtk_xfer_ui_ops()); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4687
diff
changeset
|
870 gaim_set_blist_ui_ops(gaim_get_gtk_blist_ui_ops()); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4687
diff
changeset
|
871 |
4489 | 872 load_prefs(); |
873 core_main(); | |
5032
cb700c07ee07
[gaim-migrate @ 5375]
Christian Hammond <chipx86@chipx86.com>
parents:
5024
diff
changeset
|
874 load_pounces(); |
4489 | 875 ui_main(); |
876 | |
877 #ifdef USE_SM | |
878 session_init(argv[0], opt_session_arg); | |
879 #endif | |
880 if (opt_session_arg != NULL) { | |
881 g_free(opt_session_arg); | |
882 opt_session_arg = NULL; | |
883 }; | |
884 | |
885 /* set the default username */ | |
886 if (opt_user_arg != NULL) { | |
887 set_first_user(opt_user_arg); | |
888 g_free(opt_user_arg); | |
889 opt_user_arg = NULL; | |
890 } | |
891 | |
892 if (misc_options & OPT_MISC_DEBUG) | |
893 show_debug(); | |
894 | |
895 static_proto_init(); | |
896 | |
897 /* deal with --login */ | |
898 if (opt_login) { | |
899 dologin_ret = dologin_named(opt_login_arg); | |
900 if (opt_login_arg != NULL) { | |
901 g_free(opt_login_arg); | |
902 opt_login_arg = NULL; | |
903 } | |
904 } | |
905 | |
906 if (!opt_acct && !opt_nologin && gaim_session == 0) | |
907 auto_login(); | |
908 | |
909 if (opt_acct) { | |
910 account_editor(NULL, NULL); | |
911 } else if ((dologin_ret == -1) && !connections) | |
912 show_login(); | |
913 | |
914 gtk_main(); | |
915 core_quit(); | |
4561 | 916 gaim_sound_quit(); |
4489 | 917 #ifdef _WIN32 |
918 wgaim_cleanup(); | |
919 #endif | |
920 return 0; | |
921 | |
922 } |