Mercurial > pidgin.yaz
annotate finch/finch.c @ 17593:759cd72bd2ff
Replaced a clean and simple API with a very weird hack due to vivid request on #pidgin by multiple devs. This avoids the change in PurplePluginProtocolInfo, but requires complicated change tracking in every prpl. The others prpl should add this change tracking, too (since otherwise the status gets changed even though nothing they care about changed), but that's not up to me.
author | Andreas Monitzer <pidgin@monitzer.com> |
---|---|
date | Mon, 18 Jun 2007 12:37:29 +0000 |
parents | c3b2a44484e1 |
children | 9ffa9af32854 |
rev | line source |
---|---|
15823 | 1 /** |
15871
66dff3dfdea6
Re-sed the copyright notices so they don't all talk about Purple.
Richard Laager <rlaager@wiktel.com>
parents:
15823
diff
changeset
|
2 * finch |
15823 | 3 * |
15871
66dff3dfdea6
Re-sed the copyright notices so they don't all talk about Purple.
Richard Laager <rlaager@wiktel.com>
parents:
15823
diff
changeset
|
4 * Finch is the legal property of its developers, whose names are too numerous |
15823 | 5 * to list here. Please refer to the COPYRIGHT file distributed with this |
6 * source distribution. | |
7 * | |
8 * This program is free software; you can redistribute it and/or modify | |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program; if not, write to the Free Software | |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 */ | |
22 #include "account.h" | |
23 #include "conversation.h" | |
24 #include "core.h" | |
25 #include "debug.h" | |
26 #include "eventloop.h" | |
27 #include "ft.h" | |
28 #include "log.h" | |
29 #include "notify.h" | |
30 #include "prefs.h" | |
31 #include "prpl.h" | |
32 #include "pounce.h" | |
33 #include "savedstatuses.h" | |
34 #include "sound.h" | |
35 #include "status.h" | |
36 #include "util.h" | |
37 #include "whiteboard.h" | |
38 | |
39 #include "gntdebug.h" | |
40 #include "finch.h" | |
41 #include "gntprefs.h" | |
42 #include "gntui.h" | |
43 #include "gntidle.h" | |
44 | |
45 #define _GNU_SOURCE | |
46 #include <getopt.h> | |
47 | |
48 #include "config.h" | |
49 | |
50 static void | |
51 debug_init() | |
52 { | |
53 finch_debug_init(); | |
54 purple_debug_set_ui_ops(finch_debug_get_ui_ops()); | |
55 } | |
56 | |
57 static PurpleCoreUiOps core_ops = | |
58 { | |
59 finch_prefs_init, | |
60 debug_init, | |
61 gnt_ui_init, | |
16677
30829e806dae
And finch is up to date
Gary Kramlich <grim@reaperworld.com>
parents:
16573
diff
changeset
|
62 gnt_ui_uninit, |
30829e806dae
And finch is up to date
Gary Kramlich <grim@reaperworld.com>
parents:
16573
diff
changeset
|
63 |
30829e806dae
And finch is up to date
Gary Kramlich <grim@reaperworld.com>
parents:
16573
diff
changeset
|
64 /* padding */ |
30829e806dae
And finch is up to date
Gary Kramlich <grim@reaperworld.com>
parents:
16573
diff
changeset
|
65 NULL, |
30829e806dae
And finch is up to date
Gary Kramlich <grim@reaperworld.com>
parents:
16573
diff
changeset
|
66 NULL, |
30829e806dae
And finch is up to date
Gary Kramlich <grim@reaperworld.com>
parents:
16573
diff
changeset
|
67 NULL, |
30829e806dae
And finch is up to date
Gary Kramlich <grim@reaperworld.com>
parents:
16573
diff
changeset
|
68 NULL |
15823 | 69 }; |
70 | |
71 static PurpleCoreUiOps * | |
72 gnt_core_get_ui_ops() | |
73 { | |
74 return &core_ops; | |
75 } | |
76 | |
77 /* Anything IO-related is directly copied from gtkpurple's source tree */ | |
78 | |
79 #define FINCH_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR) | |
80 #define FINCH_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL) | |
81 | |
82 typedef struct _PurpleGntIOClosure { | |
83 PurpleInputFunction function; | |
84 guint result; | |
85 gpointer data; | |
86 | |
87 } PurpleGntIOClosure; | |
88 | |
89 static void purple_gnt_io_destroy(gpointer data) | |
90 { | |
91 g_free(data); | |
92 } | |
93 | |
94 static gboolean purple_gnt_io_invoke(GIOChannel *source, GIOCondition condition, gpointer data) | |
95 { | |
96 PurpleGntIOClosure *closure = data; | |
97 PurpleInputCondition purple_cond = 0; | |
98 | |
99 if (condition & FINCH_READ_COND) | |
100 purple_cond |= PURPLE_INPUT_READ; | |
101 if (condition & FINCH_WRITE_COND) | |
102 purple_cond |= PURPLE_INPUT_WRITE; | |
103 | |
104 #if 0 | |
105 purple_debug(PURPLE_DEBUG_MISC, "gtk_eventloop", | |
106 "CLOSURE: callback for %d, fd is %d\n", | |
107 closure->result, g_io_channel_unix_get_fd(source)); | |
108 #endif | |
109 | |
110 #ifdef _WIN32 | |
111 if(! purple_cond) { | |
112 #if DEBUG | |
113 purple_debug_misc("gnt_eventloop", | |
114 "CLOSURE received GIOCondition of 0x%x, which does not" | |
115 " match 0x%x (READ) or 0x%x (WRITE)\n", | |
116 condition, FINCH_READ_COND, FINCH_WRITE_COND); | |
117 #endif /* DEBUG */ | |
118 | |
119 return TRUE; | |
120 } | |
121 #endif /* _WIN32 */ | |
122 | |
123 closure->function(closure->data, g_io_channel_unix_get_fd(source), | |
124 purple_cond); | |
125 | |
126 return TRUE; | |
127 } | |
128 | |
129 static guint gnt_input_add(gint fd, PurpleInputCondition condition, PurpleInputFunction function, | |
130 gpointer data) | |
131 { | |
132 PurpleGntIOClosure *closure = g_new0(PurpleGntIOClosure, 1); | |
133 GIOChannel *channel; | |
134 GIOCondition cond = 0; | |
135 | |
136 closure->function = function; | |
137 closure->data = data; | |
138 | |
139 if (condition & PURPLE_INPUT_READ) | |
140 cond |= FINCH_READ_COND; | |
141 if (condition & PURPLE_INPUT_WRITE) | |
142 cond |= FINCH_WRITE_COND; | |
143 | |
144 channel = g_io_channel_unix_new(fd); | |
145 closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond, | |
146 purple_gnt_io_invoke, closure, purple_gnt_io_destroy); | |
147 | |
148 g_io_channel_unref(channel); | |
149 return closure->result; | |
150 } | |
151 | |
152 static PurpleEventLoopUiOps eventloop_ops = | |
153 { | |
154 g_timeout_add, | |
155 g_source_remove, | |
156 gnt_input_add, | |
157 g_source_remove, | |
16677
30829e806dae
And finch is up to date
Gary Kramlich <grim@reaperworld.com>
parents:
16573
diff
changeset
|
158 NULL, /* input_get_error */ |
30829e806dae
And finch is up to date
Gary Kramlich <grim@reaperworld.com>
parents:
16573
diff
changeset
|
159 |
30829e806dae
And finch is up to date
Gary Kramlich <grim@reaperworld.com>
parents:
16573
diff
changeset
|
160 /* padding */ |
30829e806dae
And finch is up to date
Gary Kramlich <grim@reaperworld.com>
parents:
16573
diff
changeset
|
161 NULL, |
30829e806dae
And finch is up to date
Gary Kramlich <grim@reaperworld.com>
parents:
16573
diff
changeset
|
162 NULL, |
30829e806dae
And finch is up to date
Gary Kramlich <grim@reaperworld.com>
parents:
16573
diff
changeset
|
163 NULL, |
30829e806dae
And finch is up to date
Gary Kramlich <grim@reaperworld.com>
parents:
16573
diff
changeset
|
164 NULL |
15823 | 165 }; |
166 | |
167 static PurpleEventLoopUiOps * | |
168 gnt_eventloop_get_ui_ops(void) | |
169 { | |
170 return &eventloop_ops; | |
171 } | |
172 | |
173 /* This is mostly copied from gtkpurple's source tree */ | |
174 static void | |
175 show_usage(const char *name, gboolean terse) | |
176 { | |
177 char *text; | |
178 | |
179 if (terse) { | |
180 text = g_strdup_printf(_("%s. Try `%s -h' for more information.\n"), VERSION, name); | |
181 } else { | |
182 text = g_strdup_printf(_("%s\n" | |
183 "Usage: %s [OPTION]...\n\n" | |
184 " -c, --config=DIR use DIR for config files\n" | |
185 " -d, --debug print debugging messages to stdout\n" | |
186 " -h, --help display this help and exit\n" | |
187 " -n, --nologin don't automatically login\n" | |
188 " -v, --version display the current version and exit\n"), VERSION, name); | |
189 } | |
190 | |
191 purple_print_utf8_to_console(stdout, text); | |
192 g_free(text); | |
193 } | |
194 | |
195 static int | |
196 init_libpurple(int argc, char **argv) | |
197 { | |
198 char *path; | |
199 int opt; | |
200 gboolean opt_help = FALSE; | |
201 gboolean opt_nologin = FALSE; | |
202 gboolean opt_version = FALSE; | |
203 char *opt_config_dir_arg = NULL; | |
204 char *opt_session_arg = NULL; | |
205 gboolean debug_enabled = FALSE; | |
206 | |
207 struct option long_options[] = { | |
208 {"config", required_argument, NULL, 'c'}, | |
209 {"debug", no_argument, NULL, 'd'}, | |
210 {"help", no_argument, NULL, 'h'}, | |
211 {"nologin", no_argument, NULL, 'n'}, | |
212 {"session", required_argument, NULL, 's'}, | |
213 {"version", no_argument, NULL, 'v'}, | |
214 {0, 0, 0, 0} | |
215 }; | |
216 | |
217 #ifdef ENABLE_NLS | |
218 bindtextdomain(PACKAGE, LOCALEDIR); | |
219 bind_textdomain_codeset(PACKAGE, "UTF-8"); | |
220 textdomain(PACKAGE); | |
221 #endif | |
222 | |
223 #ifdef HAVE_SETLOCALE | |
224 setlocale(LC_ALL, ""); | |
225 #endif | |
226 | |
227 /* scan command-line options */ | |
228 opterr = 1; | |
229 while ((opt = getopt_long(argc, argv, | |
230 #ifndef _WIN32 | |
231 "c:dhn::s:v", | |
232 #else | |
233 "c:dhn::v", | |
234 #endif | |
235 long_options, NULL)) != -1) { | |
236 switch (opt) { | |
237 case 'c': /* config dir */ | |
238 g_free(opt_config_dir_arg); | |
239 opt_config_dir_arg = g_strdup(optarg); | |
240 break; | |
241 case 'd': /* debug */ | |
242 debug_enabled = TRUE; | |
243 break; | |
244 case 'h': /* help */ | |
245 opt_help = TRUE; | |
246 break; | |
247 case 'n': /* no autologin */ | |
248 opt_nologin = TRUE; | |
249 break; | |
250 case 's': /* use existing session ID */ | |
251 g_free(opt_session_arg); | |
252 opt_session_arg = g_strdup(optarg); | |
253 break; | |
254 case 'v': /* version */ | |
255 opt_version = TRUE; | |
256 break; | |
257 case '?': /* show terse help */ | |
258 default: | |
259 show_usage(argv[0], TRUE); | |
260 return 0; | |
261 break; | |
262 } | |
263 } | |
264 | |
265 /* show help message */ | |
266 if (opt_help) { | |
267 show_usage(argv[0], FALSE); | |
268 return 0; | |
269 } | |
270 /* show version message */ | |
271 if (opt_version) { | |
16954
816759ae9644
Clarify the comments on the names for translators.
Richard Laager <rlaager@wiktel.com>
parents:
16942
diff
changeset
|
272 /* Translators may want to transliterate the name. |
816759ae9644
Clarify the comments on the names for translators.
Richard Laager <rlaager@wiktel.com>
parents:
16942
diff
changeset
|
273 It is not to be translated. */ |
16942
dd768c576ab2
disapproval of revision 'e9933d653551beb8b5f477dcf2c6bd1f3d239c55'
Richard Laager <rlaager@wiktel.com>
parents:
16940
diff
changeset
|
274 printf("%s %s\n", _("Finch"), VERSION); |
15823 | 275 return 0; |
276 } | |
277 | |
278 /* set a user-specified config directory */ | |
279 if (opt_config_dir_arg != NULL) { | |
280 purple_util_set_user_dir(opt_config_dir_arg); | |
281 g_free(opt_config_dir_arg); | |
282 } | |
283 | |
284 /* | |
285 * We're done piddling around with command line arguments. | |
286 * Fire up this baby. | |
287 */ | |
288 | |
16380
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
289 /* We don't want debug-messages to show up and corrupt the display */ |
15823 | 290 purple_debug_set_enabled(debug_enabled); |
291 | |
16380
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
292 /* If we're using a custom configuration directory, we |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
293 * do NOT want to migrate, or weird things will happen. */ |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
294 if (opt_config_dir_arg == NULL) |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
295 { |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
296 if (!purple_core_migrate()) |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
297 { |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
298 char *old = g_strconcat(purple_home_dir(), |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
299 G_DIR_SEPARATOR_S ".gaim", NULL); |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
300 char *text = g_strdup_printf(_( |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
301 "%s encountered errors migrating your settings " |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
302 "from %s to %s. Please investigate and complete the " |
16942
dd768c576ab2
disapproval of revision 'e9933d653551beb8b5f477dcf2c6bd1f3d239c55'
Richard Laager <rlaager@wiktel.com>
parents:
16940
diff
changeset
|
303 "migration by hand. Please report this error at http://developer.pidgin.im"), _("Finch"), |
16380
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
304 old, purple_user_dir()); |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
305 |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
306 g_free(old); |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
307 |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
308 purple_print_utf8_to_console(stderr, text); |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
309 g_free(text); |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
310 |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
311 return 0; |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
312 } |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
313 } |
6c97924af83b
Call the migrate code from Finch.
Richard Laager <rlaager@wiktel.com>
parents:
16098
diff
changeset
|
314 |
15823 | 315 purple_core_set_ui_ops(gnt_core_get_ui_ops()); |
316 purple_eventloop_set_ui_ops(gnt_eventloop_get_ui_ops()); | |
317 purple_idle_set_ui_ops(finch_idle_get_ui_ops()); | |
318 | |
319 path = g_build_filename(purple_user_dir(), "plugins", NULL); | |
320 purple_plugins_add_search_path(path); | |
321 g_free(path); | |
322 | |
323 purple_plugins_add_search_path(LIBDIR); | |
324 | |
325 if (!purple_core_init(FINCH_UI)) | |
326 { | |
327 fprintf(stderr, | |
328 "Initialization of the Purple core failed. Dumping core.\n" | |
329 "Please report this!\n"); | |
330 abort(); | |
331 } | |
332 | |
333 /* TODO: Move blist loading into purple_blist_init() */ | |
334 purple_set_blist(purple_blist_new()); | |
335 purple_blist_load(); | |
336 | |
337 /* TODO: Move prefs loading into purple_prefs_init() */ | |
338 purple_prefs_load(); | |
339 purple_prefs_update_old(); | |
16573
ac0d07c7fd90
Pref migration for finch.
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
16533
diff
changeset
|
340 finch_prefs_update_old(); |
15823 | 341 |
342 /* load plugins we had when we quit */ | |
16427
4999bbc52881
Works for me! Renames prefs: /core to /purple, /gaim/gtk to /pidgin, /gaim/gnt to /finch
Sean Egan <seanegan@gmail.com>
parents:
16098
diff
changeset
|
343 purple_plugins_load_saved("/finch/plugins/loaded"); |
15823 | 344 |
345 /* TODO: Move pounces loading into purple_pounces_init() */ | |
346 purple_pounces_load(); | |
347 | |
348 if (opt_nologin) | |
349 { | |
350 /* Set all accounts to "offline" */ | |
351 PurpleSavedStatus *saved_status; | |
352 | |
353 /* If we've used this type+message before, lookup the transient status */ | |
354 saved_status = purple_savedstatus_find_transient_by_type_and_message( | |
355 PURPLE_STATUS_OFFLINE, NULL); | |
356 | |
357 /* If this type+message is unique then create a new transient saved status */ | |
358 if (saved_status == NULL) | |
359 saved_status = purple_savedstatus_new(NULL, PURPLE_STATUS_OFFLINE); | |
360 | |
361 /* Set the status for each account */ | |
362 purple_savedstatus_activate(saved_status); | |
363 } | |
364 else | |
365 { | |
366 /* Everything is good to go--sign on already */ | |
16427
4999bbc52881
Works for me! Renames prefs: /core to /purple, /gaim/gtk to /pidgin, /gaim/gnt to /finch
Sean Egan <seanegan@gmail.com>
parents:
16098
diff
changeset
|
367 if (!purple_prefs_get_bool("/purple/savedstatus/startup_current_status")) |
15823 | 368 purple_savedstatus_activate(purple_savedstatus_get_startup()); |
369 purple_accounts_restore_current_statuses(); | |
370 } | |
371 | |
372 return 1; | |
373 } | |
374 | |
375 int main(int argc, char **argv) | |
376 { | |
377 signal(SIGPIPE, SIG_IGN); | |
378 | |
379 /* Initialize the libpurple stuff */ | |
380 if (!init_libpurple(argc, argv)) | |
381 return 0; | |
382 | |
383 purple_blist_show(); | |
384 gnt_main(); | |
385 | |
386 #ifdef STANDALONE | |
387 purple_core_quit(); | |
388 #endif | |
389 | |
390 return 0; | |
391 } | |
392 |