Mercurial > pidgin.yaz
annotate src/main.c @ 4889:f7150929332b
[gaim-migrate @ 5219]
Fix a lil ko.po problem some people with weird gettexts had.
Swap the "Open Mail" and "Close" buttons on the mail
notification dialog. Is this more HIGgish? If not, lemme know
and I'll burninate.
I took out lots of aim_conn_t's from ssi.c in favor of looking up
the connection from the session when it is needed. I like this way
better, and I've been slowly moving towards it.
Added some code used for uploading icons. I haven't gotten it to work
yet. I'm still not exactly sure what I'm supposed to be doing.
'twould be nice if Windows AIM still did this correctly. 'twould be
nice to have that kind of job security.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Tue, 25 Mar 2003 05:01:00 +0000 |
parents | 9b51c090236a |
children | ec3830b344f2 |
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 GList *buddy_pounces = NULL; | |
69 GSList *away_messages = NULL; | |
70 GSList *message_queue = NULL; | |
71 GSList *unread_message_queue = NULL; | |
72 GSList *away_time_queue = NULL; | |
73 | |
74 GtkWidget *mainwindow = NULL; | |
75 | |
4561 | 76 |
4489 | 77 int opt_away = 0; |
4687 | 78 int docklet_count = 0; |
4489 | 79 char *opt_away_arg = NULL; |
80 char *opt_rcfile_arg = NULL; | |
81 int opt_debug = 0; | |
82 #ifdef _WIN32 | |
83 int opt_gdebug = 0; | |
84 #endif | |
85 | |
86 #if HAVE_SIGNAL_H | |
87 /* | |
88 * Lists of signals we wish to catch and those we wish to ignore. | |
89 * Each list terminated with -1 | |
90 */ | |
91 static int catch_sig_list[] = { | |
92 SIGSEGV, | |
93 SIGHUP, | |
94 SIGINT, | |
95 SIGTERM, | |
96 SIGQUIT, | |
97 SIGCHLD, | |
98 -1 | |
99 }; | |
100 | |
101 static int ignore_sig_list[] = { | |
102 SIGPIPE, | |
103 -1 | |
104 }; | |
105 #endif | |
106 | |
107 void do_quit() | |
108 { | |
109 /* captain's log, stardate... */ | |
110 system_log(log_quit, NULL, NULL, OPT_LOG_BUDDY_SIGNON | OPT_LOG_MY_SIGNON); | |
111 | |
112 /* the self destruct sequence has been initiated */ | |
113 plugin_event(event_quit); | |
114 | |
115 /* transmission ends */ | |
116 signoff_all(); | |
117 | |
118 /* record what we have before we blow it away... */ | |
119 save_prefs(); | |
120 | |
121 #ifdef GAIM_PLUGINS | |
122 /* jettison cargo */ | |
123 remove_all_plugins(); | |
124 #endif | |
125 | |
126 #ifdef USE_PERL | |
127 /* yup, perl too */ | |
128 perl_end(); | |
129 #endif | |
130 | |
131 #ifdef USE_SM | |
132 /* unplug */ | |
133 session_end(); | |
134 #endif | |
135 | |
136 /* and end it all... */ | |
137 gtk_main_quit(); | |
138 } | |
139 | |
4561 | 140 static guint snd_tmout = 0; |
4489 | 141 static gboolean sound_timeout(gpointer data) |
142 { | |
4561 | 143 gaim_sound_set_login_mute(FALSE); |
144 snd_tmout = 0; | |
4489 | 145 return FALSE; |
146 } | |
147 | |
148 /* we need to do this for Oscar because serv_login only starts the login | |
149 * process, it doesn't end there. gaim_setup will be called later from | |
150 * oscar.c, after the buddy list is made and serv_finish_login is called */ | |
151 void gaim_setup(struct gaim_connection *gc) | |
152 { | |
153 if ((sound_options & OPT_SOUND_LOGIN) && (sound_options & OPT_SOUND_SILENT_SIGNON)) { | |
4561 | 154 if(snd_tmout) { |
155 g_source_remove(snd_tmout); | |
156 } | |
157 gaim_sound_set_login_mute(TRUE); | |
4489 | 158 snd_tmout = g_timeout_add(10000, sound_timeout, NULL); |
159 } | |
160 } | |
161 | |
162 static gboolean domiddleclick(GtkWidget *w, GdkEventButton *event, gpointer null) | |
163 { | |
164 if (event->button != 2) | |
165 return FALSE; | |
166 | |
167 auto_login(); | |
168 return TRUE; | |
169 } | |
170 | |
171 static void dologin(GtkWidget *widget, GtkWidget *w) | |
172 { | |
4491 | 173 struct gaim_account *account; |
4489 | 174 const char *username = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(name)->entry)); |
175 const char *password = gtk_entry_get_text(GTK_ENTRY(pass)); | |
176 | |
177 if (!strlen(username)) { | |
178 do_error_dialog(_("Please enter your login."), NULL, GAIM_ERROR); | |
179 return; | |
180 } | |
181 | |
182 /* if there is more than one user of the same name, then fuck | |
183 * them, they just have to use the account editor to sign in | |
184 * the second one */ | |
185 | |
4491 | 186 account = gaim_account_find(username, -1); |
187 if (!account) | |
188 account = gaim_account_new(username, DEFAULT_PROTO, OPT_ACCT_REM_PASS); | |
189 g_snprintf(account->password, sizeof account->password, "%s", password); | |
4489 | 190 save_prefs(); |
4491 | 191 serv_login(account); |
4489 | 192 } |
193 | |
194 /* <name> is a comma-separated list of names, or NULL | |
195 if NULL and there is at least one user defined in .gaimrc, try to login. | |
196 if not NULL, parse <name> into separate strings, look up each one in | |
197 .gaimrc and, if it's there, try to login. | |
198 returns: 0 if successful | |
199 -1 if no user was found that had a saved password | |
200 */ | |
201 static int dologin_named(char *name) | |
202 { | |
4491 | 203 struct gaim_account *account; |
4489 | 204 char **names, **n; |
205 int retval = -1; | |
206 | |
207 if (name !=NULL) { /* list of names given */ | |
208 names = g_strsplit(name, ",", 32); | |
209 for (n = names; *n != NULL; n++) { | |
4491 | 210 account = gaim_account_find(*n, -1); |
211 if (account) { /* found a user */ | |
212 if (account->options & OPT_ACCT_REM_PASS) { | |
4489 | 213 retval = 0; |
4491 | 214 serv_login(account); |
4489 | 215 } |
216 } | |
217 } | |
218 g_strfreev(names); | |
219 } else { /* no name given, use default */ | |
4491 | 220 account = (struct gaim_account *)gaim_accounts->data; |
221 if (account->options & OPT_ACCT_REM_PASS) { | |
4489 | 222 retval = 0; |
4491 | 223 serv_login(account); |
4489 | 224 } |
225 } | |
226 | |
227 return retval; | |
228 } | |
229 | |
230 | |
231 static void doenter(GtkWidget *widget, GtkWidget *w) | |
232 { | |
233 if (widget == name) { | |
234 gtk_entry_set_text(GTK_ENTRY(pass), ""); | |
4635 | 235 gtk_editable_select_region(GTK_EDITABLE(GTK_COMBO(name)->entry), 0, 0); |
4489 | 236 gtk_widget_grab_focus(pass); |
237 } else if (widget == pass) { | |
238 dologin(widget, w); | |
239 } | |
240 } | |
241 | |
242 | |
243 static void combo_changed(GtkWidget *w, GtkWidget *combo) | |
244 { | |
245 const char *txt = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo)->entry)); | |
4491 | 246 struct gaim_account *account; |
4489 | 247 |
4491 | 248 account = gaim_account_find(txt, -1); |
4489 | 249 |
4491 | 250 if (account && account->options & OPT_ACCT_REM_PASS) { |
251 gtk_entry_set_text(GTK_ENTRY(pass), account->password); | |
4489 | 252 } else { |
253 gtk_entry_set_text(GTK_ENTRY(pass), ""); | |
254 } | |
255 } | |
256 | |
257 | |
258 static GList *combo_user_names() | |
259 { | |
4491 | 260 GSList *accts = gaim_accounts; |
4489 | 261 GList *tmp = NULL; |
4491 | 262 struct gaim_account *account; |
4489 | 263 |
4491 | 264 if (!accts) |
4489 | 265 return g_list_append(NULL, _("<New User>")); |
266 | |
4491 | 267 while (accts) { |
268 account = (struct gaim_account *)accts->data; | |
269 tmp = g_list_append(tmp, account->username); | |
270 accts = accts->next; | |
4489 | 271 } |
272 | |
273 return tmp; | |
274 } | |
275 | |
276 static void login_window_closed(GtkWidget *w, GdkEvent *ev, gpointer d) | |
277 { | |
278 if(docklet_count) { | |
4880
9b51c090236a
[gaim-migrate @ 5210]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4800
diff
changeset
|
279 #ifdef _WIN32 |
4489 | 280 wgaim_systray_minimize(mainwindow); |
281 #endif | |
282 gtk_widget_hide(mainwindow); | |
283 } else | |
284 do_quit(); | |
285 } | |
286 | |
287 void show_login() | |
288 { | |
289 GdkPixbuf *icon; | |
290 GtkWidget *image; | |
291 GtkWidget *vbox; | |
292 GtkWidget *button; | |
293 GtkWidget *hbox; | |
294 GtkWidget *label; | |
295 GtkWidget *vbox2; | |
296 GList *tmp; | |
297 | |
298 /* Do we already have a main window opened? If so, bring it back, baby... ribs... yeah */ | |
299 if (mainwindow) { | |
300 gtk_window_present(GTK_WINDOW(mainwindow)); | |
301 return; | |
302 } | |
303 | |
304 mainwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
305 | |
306 gtk_window_set_role(GTK_WINDOW(mainwindow), "login"); | |
4635 | 307 gtk_window_set_resizable(GTK_WINDOW(mainwindow), FALSE); |
4703 | 308 gtk_window_set_title(GTK_WINDOW(mainwindow), _("Login")); |
4489 | 309 gtk_widget_realize(mainwindow); |
310 gdk_window_set_group(mainwindow->window, mainwindow->window); | |
311 gtk_container_set_border_width(GTK_CONTAINER(mainwindow), 5); | |
312 g_signal_connect(G_OBJECT(mainwindow), "delete_event", | |
313 G_CALLBACK(login_window_closed), mainwindow); | |
314 | |
315 | |
316 icon = gaim_pixbuf(NULL, "gaim.png"); | |
317 if (icon) { | |
318 gtk_window_set_icon(GTK_WINDOW(mainwindow), icon); | |
4793 | 319 g_object_unref(G_OBJECT(icon)); |
4489 | 320 } |
321 | |
322 vbox = gtk_vbox_new(FALSE, 0); | |
323 gtk_container_add(GTK_CONTAINER(mainwindow), vbox); | |
324 | |
325 image = gaim_pixmap(NULL, "logo.png"); | |
326 gtk_box_pack_start(GTK_BOX(vbox), image, FALSE, FALSE, 0); | |
327 | |
328 vbox2 = gtk_vbox_new(FALSE, 0); | |
329 gtk_container_set_border_width(GTK_CONTAINER(vbox2), 5); | |
330 | |
331 label = gtk_label_new(_("Screen Name:")); | |
332 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
333 gtk_box_pack_start(GTK_BOX(vbox2), label, FALSE, FALSE, 0); | |
334 | |
335 name = gtk_combo_new(); | |
336 tmp = combo_user_names(); | |
337 gtk_combo_set_popdown_strings(GTK_COMBO(name), tmp); | |
338 g_list_free(tmp); | |
339 g_signal_connect(G_OBJECT(GTK_COMBO(name)->entry), "activate", | |
340 G_CALLBACK(doenter), mainwindow); | |
341 g_signal_connect(G_OBJECT(GTK_COMBO(name)->entry), "changed", | |
342 G_CALLBACK(combo_changed), name); | |
343 gtk_box_pack_start(GTK_BOX(vbox2), name, FALSE, TRUE, 0); | |
344 gtk_box_pack_start(GTK_BOX(vbox), vbox2, FALSE, TRUE, 0); | |
345 | |
346 vbox2 = gtk_vbox_new(FALSE, 0); | |
347 gtk_container_set_border_width(GTK_CONTAINER(vbox2), 5); | |
348 | |
349 label = gtk_label_new(_("Password:")); | |
350 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
351 gtk_box_pack_start(GTK_BOX(vbox2), label, FALSE, FALSE, 0); | |
352 | |
353 pass = gtk_entry_new(); | |
354 gtk_entry_set_visibility(GTK_ENTRY(pass), FALSE); | |
355 g_signal_connect(G_OBJECT(pass), "activate", | |
356 G_CALLBACK(doenter), mainwindow); | |
357 gtk_box_pack_start(GTK_BOX(vbox2), pass, FALSE, TRUE, 0); | |
358 gtk_box_pack_start(GTK_BOX(vbox), vbox2, FALSE, TRUE, 0); | |
359 | |
360 /* Now for the button box */ | |
361 hbox = gtk_hbox_new(TRUE, 0); | |
362 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 5); | |
363 | |
364 /* And now for the buttons */ | |
4589 | 365 button = gaim_pixbuf_button(_("Accounts"), "accounts.png", GAIM_BUTTON_VERTICAL); |
4489 | 366 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); |
367 g_signal_connect(G_OBJECT(button), "clicked", | |
368 G_CALLBACK(account_editor), mainwindow); | |
369 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
370 | |
371 #ifdef NO_MULTI | |
372 gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE); | |
373 #endif | |
374 | |
4589 | 375 button = gaim_pixbuf_button(_("Settings"), "preferences.png", GAIM_BUTTON_VERTICAL); |
4489 | 376 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); |
377 g_signal_connect(G_OBJECT(button), "clicked", | |
378 G_CALLBACK(show_prefs), mainwindow); | |
379 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
380 | |
4589 | 381 button = gaim_pixbuf_button(_("Sign On"), "signon.png", GAIM_BUTTON_VERTICAL); |
4489 | 382 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); |
383 g_signal_connect(G_OBJECT(button), "clicked", | |
384 G_CALLBACK(dologin), mainwindow); | |
385 g_signal_connect(G_OBJECT(button), "button-press-event", G_CALLBACK(domiddleclick), NULL); | |
386 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
387 | |
388 /* Now grab the focus that we need */ | |
4491 | 389 if (gaim_accounts) { |
390 struct gaim_account *account = gaim_accounts->data; | |
391 if (account->options & OPT_ACCT_REM_PASS) { | |
4489 | 392 combo_changed(NULL, name); |
393 gtk_widget_grab_focus(button); | |
394 } else { | |
395 gtk_widget_grab_focus(pass); | |
396 } | |
397 } else { | |
398 gtk_widget_grab_focus(name); | |
399 } | |
400 | |
401 /* And raise the curtain! */ | |
402 gtk_widget_show_all(mainwindow); | |
403 | |
404 } | |
405 | |
406 #if HAVE_SIGNAL_H | |
407 void sighandler(int sig) | |
408 { | |
409 switch (sig) { | |
410 case SIGHUP: | |
411 debug_printf("caught signal %d\n", sig); | |
412 signoff_all(NULL, NULL); | |
413 break; | |
414 case SIGSEGV: | |
415 core_quit(); | |
416 #ifndef DEBUG | |
417 fprintf(stderr, "Gaim has segfaulted and attempted to dump a core file.\n" | |
418 "This is a bug in the software and has happened through\n" | |
419 "no fault of your own.\n\n" | |
420 "It is possible that this bug is already fixed in CVS.\n" | |
421 "You can get a tarball of CVS from the Gaim website, at\n" | |
422 WEBSITE "gaim-CVS.tar.gz.\n\n" | |
423 "If you are already using CVS, or can reproduce the crash\n" | |
424 "using the CVS version, please notify the gaim maintainers\n" | |
425 "by reporting a bug at\n" | |
426 WEBSITE "bug.php\n\n" | |
427 "Please make sure to specify what you were doing at the time,\n" | |
428 "and post the backtrace from the core file. If you do not know\n" | |
429 "how to get the backtrace, please get instructions at\n" | |
430 WEBSITE "gdb.php. If you need further\n" | |
431 "assistance, please IM either RobFlynn or SeanEgn and\n" | |
432 "they can help you.\n"); | |
433 #else | |
434 fprintf(stderr, "Oh no! Segmentation fault!\n"); | |
4703 | 435 /*g_on_error_query (g_get_prgname());*/ |
4489 | 436 exit(1); |
437 #endif | |
438 abort(); | |
439 break; | |
440 case SIGCHLD: | |
441 clean_pid(); | |
442 #if HAVE_SIGNAL_H | |
443 signal(SIGCHLD, sighandler); /* restore signal catching on this one! */ | |
444 #endif | |
445 break; | |
446 default: | |
447 debug_printf("caught signal %d\n", sig); | |
448 signoff_all(NULL, NULL); | |
449 #ifdef GAIM_PLUGINS | |
450 remove_all_plugins(); | |
451 #endif | |
452 if (gtk_main_level()) | |
453 gtk_main_quit(); | |
454 core_quit(); | |
455 exit(0); | |
456 } | |
457 } | |
458 #endif | |
459 | |
460 #ifndef _WIN32 | |
461 static gboolean socket_readable(GIOChannel *source, GIOCondition cond, gpointer ud) | |
462 { | |
463 guchar type; | |
464 guchar subtype; | |
465 guint32 len; | |
466 guchar *data; | |
467 guint32 x; | |
4793 | 468 GError *error; |
4489 | 469 |
470 debug_printf("Core says: "); | |
4793 | 471 g_io_channel_read_chars(source, &type, sizeof(type), &x, &error); |
472 if(error) | |
4800 | 473 g_error_free(error); |
4489 | 474 if (x == 0) { |
475 debug_printf("CORE IS GONE!\n"); | |
4793 | 476 g_io_channel_shutdown(source, TRUE, &error); |
477 if(error) | |
478 g_free(error); | |
4489 | 479 return FALSE; |
480 } | |
481 debug_printf("%d ", type); | |
4793 | 482 g_io_channel_read_chars(source, &subtype, sizeof(subtype), &x, &error); |
483 if(error) | |
4800 | 484 g_error_free(error); |
4489 | 485 if (x == 0) { |
486 debug_printf("CORE IS GONE!\n"); | |
4793 | 487 g_io_channel_shutdown(source, TRUE, &error); |
488 if(error) | |
4800 | 489 g_error_free(error); |
4489 | 490 return FALSE; |
491 } | |
492 debug_printf("%d ", subtype); | |
4793 | 493 g_io_channel_read_chars(source, (guchar *)&len, sizeof(len), &x, &error); |
494 if(error) | |
4800 | 495 g_error_free(error); |
4489 | 496 if (x == 0) { |
497 debug_printf("CORE IS GONE!\n"); | |
4793 | 498 g_io_channel_shutdown(source, TRUE, &error); |
499 if(error) | |
4800 | 500 g_error_free(error); |
4489 | 501 return FALSE; |
502 } | |
503 debug_printf("(%d bytes)\n", len); | |
504 | |
505 data = g_malloc(len); | |
4793 | 506 g_io_channel_read_chars(source, data, len, &x, &error); |
507 if(error) | |
4800 | 508 g_error_free(error); |
4489 | 509 if (x != len) { |
510 debug_printf("CORE IS GONE! (read %d/%d bytes)\n", x, len); | |
511 g_free(data); | |
4793 | 512 g_io_channel_shutdown(source, TRUE, &error); |
513 if(error) | |
4800 | 514 g_error_free(error); |
4489 | 515 return FALSE; |
516 } | |
517 | |
518 g_free(data); | |
519 return TRUE; | |
520 } | |
521 #endif /* _WIN32 */ | |
522 | |
523 static int ui_main() | |
524 { | |
525 #ifndef _WIN32 | |
526 GIOChannel *channel; | |
527 int UI_fd; | |
528 char name[256]; | |
529 GList *icons = NULL; | |
530 GdkPixbuf *icon = NULL; | |
531 char *icon_path; | |
532 #endif | |
533 if (current_smiley_theme == NULL) { | |
534 smiley_theme_probe(); | |
535 if (smiley_themes) { | |
536 struct smiley_theme *smile = smiley_themes->data; | |
537 load_smiley_theme(smile->path, TRUE); | |
538 } | |
539 } | |
540 | |
541 setup_stock(); | |
542 | |
543 #ifndef _WIN32 | |
544 /* use the nice PNG icon for all the windows */ | |
545 icon_path = g_build_filename(DATADIR, "pixmaps", "gaim.png", NULL); | |
546 icon = gdk_pixbuf_new_from_file(icon_path, NULL); | |
547 g_free(icon_path); | |
548 if (icon) { | |
549 icons = g_list_append(icons,icon); | |
550 gtk_window_set_default_icon_list(icons); | |
551 g_object_unref(G_OBJECT(icon)); | |
552 } else { | |
553 debug_printf("Failed to load icon from %s" G_DIR_SEPARATOR_S "pixmaps" G_DIR_SEPARATOR_S "gaim.png\n",DATADIR); | |
554 } | |
555 | |
556 g_snprintf(name, sizeof(name), "%s" G_DIR_SEPARATOR_S "gaim_%s.%d", g_get_tmp_dir(), g_get_user_name(), gaim_session); | |
557 UI_fd = gaim_connect_to_session(0); | |
558 if (UI_fd < 0) | |
559 return 1; | |
560 | |
561 channel = g_io_channel_unix_new(UI_fd); | |
562 g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_ERR, socket_readable, NULL); | |
563 #endif | |
564 return 0; | |
565 } | |
566 | |
567 static void set_first_user(char *name) | |
568 { | |
4491 | 569 struct gaim_account *account; |
4489 | 570 |
4491 | 571 account = gaim_account_find(name, -1); |
4489 | 572 |
4491 | 573 if (!account) { /* new user */ |
574 account = g_new0(struct gaim_account, 1); | |
575 g_snprintf(account->username, sizeof(account->username), "%s", name); | |
576 account->protocol = DEFAULT_PROTO; | |
577 gaim_accounts = g_slist_prepend(gaim_accounts, account); | |
4489 | 578 } else { /* user already exists */ |
4491 | 579 gaim_accounts = g_slist_remove(gaim_accounts, account); |
580 gaim_accounts = g_slist_prepend(gaim_accounts, account); | |
4489 | 581 } |
582 save_prefs(); | |
583 } | |
584 | |
585 #ifdef _WIN32 | |
586 /* WIN32 print and log handlers */ | |
587 | |
588 static void gaim_dummy_print( const gchar* string ) { | |
589 return; | |
590 } | |
591 | |
592 static void gaim_dummy_log_handler (const gchar *domain, | |
593 GLogLevelFlags flags, | |
594 const gchar *msg, | |
595 gpointer user_data) { | |
596 return; | |
597 } | |
598 | |
599 static void gaim_log_handler (const gchar *domain, | |
600 GLogLevelFlags flags, | |
601 const gchar *msg, | |
602 gpointer user_data) { | |
603 debug_printf("%s - %s\n", domain, msg); | |
604 g_log_default_handler(domain, flags, msg, user_data); | |
605 } | |
606 #endif /* _WIN32 */ | |
607 | |
608 /* FUCKING GET ME A TOWEL! */ | |
609 #ifdef _WIN32 | |
610 int gaim_main(int argc, char *argv[]) | |
611 #else | |
612 int main(int argc, char *argv[]) | |
613 #endif | |
614 { | |
615 int opt_acct = 0, opt_help = 0, opt_version = 0, opt_login = 0, opt_nologin = 0, dologin_ret = -1; | |
616 char *opt_user_arg = NULL, *opt_login_arg = NULL; | |
617 char *opt_session_arg = NULL; | |
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 } | |
863 | |
864 #if GAIM_PLUGINS || USE_PERL | |
865 gaim_probe_plugins(); | |
866 #endif | |
867 | |
868 #ifdef _WIN32 | |
869 /* Various win32 initializations */ | |
870 wgaim_init(); | |
871 #endif | |
872 | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4687
diff
changeset
|
873 /* Set the UI operation structures. */ |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4687
diff
changeset
|
874 gaim_set_win_ui_ops(gaim_get_gtk_window_ui_ops()); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4687
diff
changeset
|
875 gaim_set_xfer_ui_ops(gaim_get_gtk_xfer_ui_ops()); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4687
diff
changeset
|
876 gaim_set_blist_ui_ops(gaim_get_gtk_blist_ui_ops()); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4687
diff
changeset
|
877 |
4489 | 878 load_prefs(); |
879 core_main(); | |
880 ui_main(); | |
881 | |
882 #ifdef USE_SM | |
883 session_init(argv[0], opt_session_arg); | |
884 #endif | |
885 if (opt_session_arg != NULL) { | |
886 g_free(opt_session_arg); | |
887 opt_session_arg = NULL; | |
888 }; | |
889 | |
890 /* set the default username */ | |
891 if (opt_user_arg != NULL) { | |
892 set_first_user(opt_user_arg); | |
893 g_free(opt_user_arg); | |
894 opt_user_arg = NULL; | |
895 } | |
896 | |
897 if (misc_options & OPT_MISC_DEBUG) | |
898 show_debug(); | |
899 | |
900 static_proto_init(); | |
901 | |
902 /* deal with --login */ | |
903 if (opt_login) { | |
904 dologin_ret = dologin_named(opt_login_arg); | |
905 if (opt_login_arg != NULL) { | |
906 g_free(opt_login_arg); | |
907 opt_login_arg = NULL; | |
908 } | |
909 } | |
910 | |
911 if (!opt_acct && !opt_nologin && gaim_session == 0) | |
912 auto_login(); | |
913 | |
914 if (opt_acct) { | |
915 account_editor(NULL, NULL); | |
916 } else if ((dologin_ret == -1) && !connections) | |
917 show_login(); | |
918 | |
919 gtk_main(); | |
920 core_quit(); | |
4561 | 921 gaim_sound_quit(); |
4489 | 922 #ifdef _WIN32 |
923 wgaim_cleanup(); | |
924 #endif | |
925 return 0; | |
926 | |
927 } |