Mercurial > pidgin
changeset 17718:63a09098b0e8
propagate from branch 'im.pidgin.pidgin' (head faebb5b94eeb15c49559aa2b3c3ce87c9a38a763)
to branch 'org.maemo.garage.pidgin.pidgin.dbus_uniq' (head 6771ea465fa274728502a0e7e5d7295deef57e28)
author | Gabriel Schulhof <nix@go-nix.ca> |
---|---|
date | Fri, 18 May 2007 22:31:37 +0000 |
parents | 150980c9d79d (diff) 9c8172ddc72d (current diff) |
children | a217e9b9ebc2 |
files | pidgin/gtkconv.c |
diffstat | 5 files changed, 112 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/core.c Fri May 18 15:18:32 2007 +0000 +++ b/libpurple/core.c Fri May 18 22:31:37 2007 +0000 @@ -48,7 +48,11 @@ #include "util.h" #ifdef HAVE_DBUS +# define DBUS_API_SUBJECT_TO_CHANGE +# include <dbus/dbus.h> +# include "dbus-purple.h" # include "dbus-server.h" +# include "dbus-bindings.h" #endif struct PurpleCore @@ -276,6 +280,85 @@ return _ops; } +#ifdef HAVE_DBUS +static char *purple_dbus_owner_user_dir(void) +{ + DBusMessage *msg = NULL, *reply = NULL; + DBusConnection *dbus_connection = NULL; + DBusError dbus_error; + char *remote_user_dir = NULL; + + if ((dbus_connection = purple_dbus_get_connection()) == NULL) + return NULL; + + if ((msg = dbus_message_new_method_call(DBUS_SERVICE_PURPLE, DBUS_PATH_PURPLE, DBUS_INTERFACE_PURPLE, "PurpleUserDir")) == NULL) + return NULL; + + dbus_error_init(&dbus_error); + reply = dbus_connection_send_with_reply_and_block(dbus_connection, msg, 5000, &dbus_error); + dbus_message_unref(msg); + dbus_error_free(&dbus_error); + + if (reply) { + 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); + } + + return remote_user_dir; +} + +static void purple_dbus_owner_show_buddy_list(void) +{ + DBusError dbus_error; + DBusMessage *msg = NULL, *reply = NULL; + DBusConnection *dbus_connection = NULL; + + if ((dbus_connection = purple_dbus_get_connection()) == NULL) + return; + + if ((msg = dbus_message_new_method_call(DBUS_SERVICE_PURPLE, DBUS_PATH_PURPLE, DBUS_INTERFACE_PURPLE, "PurpleBlistShow")) == NULL) + return ; + + dbus_error_init(&dbus_error); + if ((reply = dbus_connection_send_with_reply_and_block(dbus_connection, msg, 5000, &dbus_error)) != NULL) { + dbus_message_unref(msg); + } + dbus_error_free(&dbus_error); +} +#endif /* HAVE_DBUS */ + +gboolean purple_core_ensure_single_instance() +{ +gboolean is_single_instance = TRUE; +#ifdef HAVE_DBUS + /* in the future, other mechanisms might have already set this to FALSE */ + if (is_single_instance) { + if (!purple_dbus_is_owner()) { + const char *user_dir = purple_user_dir(); + char *dbus_owner_user_dir = purple_dbus_owner_user_dir(); + + if (NULL == user_dir && NULL != dbus_owner_user_dir) + is_single_instance = TRUE; + else if (NULL != user_dir && NULL == dbus_owner_user_dir) + is_single_instance = TRUE; + else if (NULL == user_dir && NULL == dbus_owner_user_dir) + is_single_instance = FALSE; + else + is_single_instance = strcmp(dbus_owner_user_dir, user_dir); + + if (!is_single_instance) + purple_dbus_owner_show_buddy_list(); + + g_free(dbus_owner_user_dir); + } + } +#endif /* HAVE_DBUS */ + return is_single_instance; +} + static gboolean move_and_symlink_dir(const char *path, const char *basename, const char *old_base, const char *new_base, const char *relative) {
--- a/libpurple/core.h Fri May 18 15:18:32 2007 +0000 +++ b/libpurple/core.h Fri May 18 22:31:37 2007 +0000 @@ -121,6 +121,14 @@ */ gboolean purple_core_migrate(void); +/** + * Ensures that only one instance is running. + * + * @return A boolean such that @c TRUE indicates that this is the first instance, + * whereas @c FALSE indicates that there is another instance running. + */ +gboolean purple_core_ensure_single_instance(void); + #ifdef __cplusplus } #endif
--- a/libpurple/dbus-server.c Fri May 18 15:18:32 2007 +0000 +++ b/libpurple/dbus-server.c Fri May 18 22:31:37 2007 +0000 @@ -65,6 +65,12 @@ static GHashTable *map_id_type; static gchar *init_error; +static int dbus_request_name_reply = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER; + +gboolean purple_dbus_is_owner(void) +{ + return(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER == dbus_request_name_reply); +} /** * This function initializes the pointer-id traslation system. It @@ -592,6 +598,7 @@ return; } + dbus_request_name_reply = result = dbus_bus_request_name(purple_dbus_connection, DBUS_SERVICE_PURPLE, 0, &error);
--- a/libpurple/dbus-server.h Fri May 18 15:18:32 2007 +0000 +++ b/libpurple/dbus-server.h Fri May 18 22:31:37 2007 +0000 @@ -169,6 +169,11 @@ void *purple_dbus_get_handle(void); /** + * Determines whether this instance owns the DBus service name + */ +gboolean purple_dbus_is_owner(); + +/** * Starts Purple's D-BUS server. It is responsible for handling DBUS * requests from other applications. */
--- a/pidgin/gtkmain.c Fri May 18 15:18:32 2007 +0000 +++ b/pidgin/gtkmain.c Fri May 18 22:31:37 2007 +0000 @@ -730,6 +730,15 @@ abort(); } + if (!purple_core_ensure_single_instance()) { + purple_core_quit(); +#ifdef HAVE_SIGNAL_H + g_free(segfault_message); +#endif + return 0 ; + } + + /* TODO: Move blist loading into purple_blist_init() */ purple_set_blist(purple_blist_new()); purple_blist_load();