3 * Purple is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
23 #include "connection.h"
24 #include "conversation.h"
28 #include "glibcompat.h"
31 #include "image-store.h"
40 #include "savedstatuses.h"
42 #include "smiley-custom.h"
43 #include "smiley-parser.h"
44 #include "smiley-theme.h"
46 #include "sound-theme-loader.h"
50 #include "theme-manager.h"
54 # ifndef DBUS_API_SUBJECT_TO_CHANGE
55 # define DBUS_API_SUBJECT_TO_CHANGE
57 # include <dbus/dbus.h>
58 # include "dbus-purple.h"
59 # include "dbus-server.h"
60 # include "dbus-bindings.h"
70 static PurpleCoreUiOps
*_ops
= NULL
;
71 static PurpleCore
*_core
= NULL
;
77 purple_core_print_version(void)
79 GHashTable
*ui_info
= purple_core_get_ui_info();
81 const gchar
*ui_version
;
82 gchar
*ui_full_name
= NULL
;
84 ui_name
= ui_info
? g_hash_table_lookup(ui_info
, "name") : NULL
;
85 ui_version
= ui_info
? g_hash_table_lookup(ui_info
, "version") : NULL
;
88 ui_full_name
= g_strdup_printf("%s%s%s", ui_name
,
89 ui_version
? " " : "", ui_version
);
92 purple_debug_info("main", "Launching %s%slibpurple %s",
93 ui_full_name
? ui_full_name
: "",
94 ui_full_name
? " with " : "",
95 purple_core_get_version());
100 purple_core_init(const char *ui
)
102 PurpleCoreUiOps
*ops
;
105 g_return_val_if_fail(ui
!= NULL
, FALSE
);
106 g_return_val_if_fail(purple_get_core() == NULL
, FALSE
);
109 bindtextdomain(PACKAGE
, PURPLE_LOCALEDIR
);
115 _core
= core
= g_new0(PurpleCore
, 1);
116 core
->ui
= g_strdup(ui
);
117 core
->reserved
= NULL
;
119 ops
= purple_core_get_ui_ops();
121 /* The signals subsystem is important and should be first. */
122 purple_signals_init();
126 purple_signal_register(core
, "uri-handler",
127 purple_marshal_BOOLEAN__POINTER_POINTER_POINTER
,
129 G_TYPE_STRING
, /* Protocol */
130 G_TYPE_STRING
, /* Command */
131 G_TYPE_POINTER
); /* Parameters (GHashTable *) */
133 purple_signal_register(core
, "quitting", purple_marshal_VOID
, G_TYPE_NONE
,
135 purple_signal_register(core
, "core-initialized", purple_marshal_VOID
,
138 purple_core_print_version();
140 /* The prefs subsystem needs to be initialized before static protocols
141 * for protocol prefs to work. */
148 if (ops
->ui_prefs_init
!= NULL
)
149 ops
->ui_prefs_init();
151 if (ops
->debug_ui_init
!= NULL
)
152 ops
->debug_ui_init();
160 purple_protocols_init();
162 /* Load all static protocols. */
165 /* Since plugins get probed so early we should probably initialize their
166 * subsystem right away too.
168 purple_plugins_init();
170 purple_keyring_init(); /* before accounts */
171 purple_theme_manager_init();
173 /* The buddy icon code uses the image store, so init it early. */
174 _purple_image_store_init();
176 /* Accounts use status, buddy icons and connection signals, so
177 * initialize these before accounts
179 purple_statuses_init();
180 purple_buddy_icons_init();
181 purple_connections_init();
183 purple_accounts_init();
184 purple_savedstatuses_init();
185 purple_notify_init();
186 _purple_message_init();
187 purple_conversations_init();
190 purple_network_init();
191 purple_pounces_init();
198 _purple_smiley_custom_init();
199 _purple_smiley_parser_init();
202 * Call this early on to try to auto-detect our IP address and
203 * hopefully save some time later.
205 purple_network_get_my_ip(-1);
207 if (ops
!= NULL
&& ops
->ui_init
!= NULL
)
210 /* The UI may have registered some theme types, so refresh them */
211 purple_theme_manager_refresh();
213 /* Load the buddy list after UI init */
216 purple_signal_emit(purple_get_core(), "core-initialized");
222 purple_core_quit(void)
224 PurpleCoreUiOps
*ops
;
225 PurpleCore
*core
= purple_get_core();
227 g_return_if_fail(core
!= NULL
);
229 /* The self destruct sequence has been initiated */
230 purple_signal_emit(purple_get_core(), "quitting");
232 /* Transmission ends */
233 purple_connections_disconnect_all();
235 /* Save .xml files, remove signals, etc. */
236 _purple_smiley_theme_uninit();
237 _purple_smiley_custom_uninit();
238 _purple_smiley_parser_uninit();
239 purple_http_uninit();
240 purple_idle_uninit();
241 purple_pounces_uninit();
242 purple_conversations_uninit();
243 purple_blist_uninit();
244 purple_notify_uninit();
245 purple_connections_uninit();
246 purple_buddy_icons_uninit();
247 purple_savedstatuses_uninit();
248 purple_statuses_uninit();
249 purple_accounts_uninit();
250 purple_keyring_uninit(); /* after accounts */
251 purple_sound_uninit();
252 purple_theme_manager_uninit();
253 purple_xfers_uninit();
254 purple_proxy_uninit();
255 _purple_image_store_uninit();
256 purple_network_uninit();
258 ops
= purple_core_get_ui_ops();
259 if (ops
!= NULL
&& ops
->quit
!= NULL
)
262 /* Everything after prefs_uninit must not try to read any prefs */
263 purple_prefs_uninit();
264 purple_plugins_uninit();
266 static_proto_unload();
267 purple_protocols_uninit();
270 purple_dbus_uninit();
273 purple_cmds_uninit();
275 _purple_message_uninit();
276 /* Everything after util_uninit cannot try to write things to the
277 * confdir nor use purple_escape_js
279 purple_util_uninit();
281 purple_signals_uninit();
294 purple_core_quit_cb(gpointer unused
)
302 purple_core_get_version(void)
308 purple_core_get_ui(void)
310 PurpleCore
*core
= purple_get_core();
312 g_return_val_if_fail(core
!= NULL
, NULL
);
318 purple_get_core(void)
323 static PurpleCoreUiOps
*
324 purple_core_ui_ops_copy(PurpleCoreUiOps
*ops
)
326 PurpleCoreUiOps
*ops_new
;
328 g_return_val_if_fail(ops
!= NULL
, NULL
);
330 ops_new
= g_new(PurpleCoreUiOps
, 1);
337 purple_core_ui_ops_get_type(void)
339 static GType type
= 0;
342 type
= g_boxed_type_register_static("PurpleCoreUiOps",
343 (GBoxedCopyFunc
)purple_core_ui_ops_copy
,
344 (GBoxedFreeFunc
)g_free
);
351 purple_core_set_ui_ops(PurpleCoreUiOps
*ops
)
357 purple_core_get_ui_ops(void)
363 static char *purple_dbus_owner_user_dir(void)
365 DBusMessage
*msg
= NULL
, *reply
= NULL
;
366 DBusConnection
*dbus_connection
= NULL
;
367 DBusError dbus_error
;
368 char *remote_user_dir
= NULL
;
370 if ((dbus_connection
= purple_dbus_get_connection()) == NULL
)
373 if ((msg
= dbus_message_new_method_call(PURPLE_DBUS_SERVICE
, PURPLE_DBUS_PATH
, PURPLE_DBUS_INTERFACE
, "PurpleUserDir")) == NULL
)
376 dbus_error_init(&dbus_error
);
377 reply
= dbus_connection_send_with_reply_and_block(dbus_connection
, msg
, 5000, &dbus_error
);
378 dbus_message_unref(msg
);
379 dbus_error_free(&dbus_error
);
383 dbus_error_init(&dbus_error
);
384 dbus_message_get_args(reply
, &dbus_error
, DBUS_TYPE_STRING
, &remote_user_dir
, DBUS_TYPE_INVALID
);
385 remote_user_dir
= g_strdup(remote_user_dir
);
386 dbus_error_free(&dbus_error
);
387 dbus_message_unref(reply
);
390 return remote_user_dir
;
393 #endif /* HAVE_DBUS */
396 purple_core_ensure_single_instance()
398 gboolean is_single_instance
= TRUE
;
400 /* in the future, other mechanisms might have already set this to FALSE */
401 if (is_single_instance
)
403 if (!purple_dbus_is_owner())
405 const char *user_dir
= purple_user_dir();
406 char *dbus_owner_user_dir
= purple_dbus_owner_user_dir();
408 is_single_instance
= !purple_strequal(dbus_owner_user_dir
, user_dir
);
409 g_free(dbus_owner_user_dir
);
412 #endif /* HAVE_DBUS */
414 return is_single_instance
;
417 GHashTable
* purple_core_get_ui_info() {
418 PurpleCoreUiOps
*ops
= purple_core_get_ui_ops();
420 if(NULL
== ops
|| NULL
== ops
->get_ui_info
)
423 return ops
->get_ui_info();