* @file core.c Purple Core API * Purple is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA #include "conversation.h" #include "savedstatuses.h" #include "sound-theme-loader.h" #include "theme-manager.h" # ifndef DBUS_API_SUBJECT_TO_CHANGE # define DBUS_API_SUBJECT_TO_CHANGE # include "dbus-purple.h" # include "dbus-server.h" # include "dbus-bindings.h" static PurpleCoreUiOps *_ops = NULL; static PurpleCore *_core = NULL; purple_core_init(const char *ui) g_return_val_if_fail(ui != NULL, FALSE); g_return_val_if_fail(purple_get_core() == NULL, FALSE); bindtextdomain(PACKAGE, LOCALEDIR); _core = core = g_new0(PurpleCore, 1); ops = purple_core_get_ui_ops(); /* The signals subsystem is important and should be first. */ purple_signal_register(core, "uri-handler", purple_marshal_BOOLEAN__POINTER_POINTER_POINTER, purple_value_new(PURPLE_TYPE_BOOLEAN), 3, purple_value_new(PURPLE_TYPE_STRING), /* Protocol */ purple_value_new(PURPLE_TYPE_STRING), /* Command */ purple_value_new(PURPLE_TYPE_BOXED, "GHashTable *")); /* Parameters */ purple_signal_register(core, "quitting", purple_marshal_VOID, NULL, 0); /* The prefs subsystem needs to be initialized before static protocols * for protocol prefs to work. */ if (ops->ui_prefs_init != NULL) if (ops->debug_ui_init != NULL) /* Since plugins get probed so early we should probably initialize their * subsystem right away too. /* Initialize all static protocols. */ purple_plugins_probe(G_MODULE_SUFFIX); purple_theme_manager_init(); /* The buddy icon code uses the imgstore, so init it early. */ /* Accounts use status, buddy icons and connection signals, so * initialize these before accounts purple_buddy_icons_init(); purple_connections_init(); purple_savedstatuses_init(); purple_certificate_init(); purple_conversations_init(); * Call this early on to try to auto-detect our IP address and * hopefully save some time later. purple_network_get_my_ip(-1); if (ops != NULL && ops->ui_init != NULL) /* The UI may have registered some theme types, so refresh them */ purple_theme_manager_refresh(); PurpleCore *core = purple_get_core(); g_return_if_fail(core != NULL); /* The self destruct sequence has been initiated */ purple_signal_emit(purple_get_core(), "quitting"); purple_connections_disconnect_all(); * Certificates must be destroyed before the SSL plugins, because * PurpleCertificates contain pointers to PurpleCertificateSchemes, * and the PurpleCertificateSchemes will be unregistered when the purple_certificate_uninit(); /* The SSL plugins must be uninit before they're unloaded */ /* Unload all non-loader, non-prpl plugins before shutting down purple_debug_info("main", "Unloading normal plugins\n"); purple_plugins_unload(PURPLE_PLUGIN_STANDARD); /* Save .xml files, remove signals, etc. */ purple_conversations_uninit(); purple_connections_uninit(); purple_buddy_icons_uninit(); purple_savedstatuses_uninit(); purple_accounts_uninit(); purple_theme_manager_uninit(); purple_dnsquery_uninit(); purple_imgstore_uninit(); /* Everything after unloading all plugins must not fail if prpls aren't purple_debug_info("main", "Unloading all plugins\n"); purple_plugins_destroy_all(); ops = purple_core_get_ui_ops(); if (ops != NULL && ops->quit != NULL) /* Everything after prefs_uninit must not try to read any prefs */ /* Everything after util_uninit cannot try to write things to the confdir */ purple_core_quit_cb(gpointer unused) purple_core_get_version(void) PurpleCore *core = purple_get_core(); g_return_val_if_fail(core != NULL, NULL); purple_core_set_ui_ops(PurpleCoreUiOps *ops) purple_core_get_ui_ops(void) static char *purple_dbus_owner_user_dir(void) DBusMessage *msg = NULL, *reply = NULL; DBusConnection *dbus_connection = NULL; char *remote_user_dir = NULL; if ((dbus_connection = purple_dbus_get_connection()) == NULL) if ((msg = dbus_message_new_method_call(DBUS_SERVICE_PURPLE, DBUS_PATH_PURPLE, DBUS_INTERFACE_PURPLE, "PurpleUserDir")) == NULL) dbus_error_init(&dbus_error); reply = dbus_connection_send_with_reply_and_block(dbus_connection, msg, 5000, &dbus_error); dbus_error_free(&dbus_error); dbus_error_init(&dbus_error); dbus_message_get_args(reply, &dbus_error, DBUS_TYPE_STRING, &remote_user_dir, DBUS_TYPE_INVALID); remote_user_dir = g_strdup(remote_user_dir); dbus_error_free(&dbus_error); dbus_message_unref(reply); purple_core_ensure_single_instance() gboolean is_single_instance = TRUE; /* in the future, other mechanisms might have already set this to FALSE */ if (!purple_dbus_is_owner()) const char *user_dir = purple_user_dir(); char *dbus_owner_user_dir = purple_dbus_owner_user_dir(); is_single_instance = !purple_strequal(dbus_owner_user_dir, user_dir); g_free(dbus_owner_user_dir); return is_single_instance; GHashTable* purple_core_get_ui_info() { PurpleCoreUiOps *ops = purple_core_get_ui_ops(); if(NULL == ops || NULL == ops->get_ui_info) return ops->get_ui_info();