# HG changeset patch # User Richard Laager # Date 1179672821 0 # Node ID f8fc41570bf1a69518ebffb2f951c3f531f893ae # Parent 52c49142bbed358f3a4f41f0e83994e9c32f5196# Parent b328eb5ccde48b12b46e114f7ac538dcd4fef800 propagate from branch 'org.maemo.garage.pidgin.pidgin.pidgin-create-window' (head aa14d4a155af76ab7e3be4b5a92082e3bb2daa21) to branch 'im.pidgin.rlaager.merging.for_2_1_0' (head c8c2bc1f0dd3a0a30b7be8b90114f176ab8c7943) diff -r 52c49142bbed -r f8fc41570bf1 ChangeLog --- a/ChangeLog Sun May 20 14:53:34 2007 +0000 +++ b/ChangeLog Sun May 20 14:53:41 2007 +0000 @@ -1,5 +1,18 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul +version 2.1.0 (??/??/????): + libpurple: + * Core changes to allow UIs to use second-granularity for scheduling. + Pidgin and Finch, which use the glib event loop, were changed to use + g_timeout_add_seconds() on glib >= 2.14 when possible. This allows + glib to properly group our longer timers to increase power efficiency. + (Arjan van de Ven with Intel Corporation) + + Pidgin: + * Ensure only one copy of Pidgin is running with a given configuration + directory. The net effect of this is that trying to start Pidgin a + second time will raise the buddy list. (Gabriel Schulhof) + version 2.0.1 (??/??/????): * Buddy list update speedups when buddy icons are not being displayed. (Scott Wolchok) diff -r 52c49142bbed -r f8fc41570bf1 ChangeLog.API --- a/ChangeLog.API Sun May 20 14:53:34 2007 +0000 +++ b/ChangeLog.API Sun May 20 14:53:41 2007 +0000 @@ -1,5 +1,19 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul +version 2.1.0 (??/??/????): + Added: + * PurpleEventLoopUiOps.timeout_add_seconds + UIs can now use better scheduling for whole-second timers. For + example, clients based on the glib event loop can now use + g_timeout_add_seconds(). + * pidgin_create_window() + * purple_core_ensure_single_instance() + This is for UIs to use to ensure only one copy is running. + * purple_dbus_is_owner() + * purple_timeout_add_seconds() + Callers should prefer this to purple_timeout_add() for timers + longer than 1 second away. Be aware of the rounding, though. + version 2.0.0 (5/3/2007): Please note all functions, defines, and data structures have been re-namespaced to match the new names of Pidgin, Finch, and libpurple. diff -r 52c49142bbed -r f8fc41570bf1 configure.ac --- a/configure.ac Sun May 20 14:53:34 2007 +0000 +++ b/configure.ac Sun May 20 14:53:41 2007 +0000 @@ -43,10 +43,10 @@ # # Make sure to update finch/libgnt/configure.ac with libgnt version changes. # -m4_define([purple_lt_current], [0]) +m4_define([purple_lt_current], [1]) m4_define([purple_major_version], [2]) -m4_define([purple_minor_version], [0]) -m4_define([purple_micro_version], [1]) +m4_define([purple_minor_version], [1]) +m4_define([purple_micro_version], [0]) m4_define([purple_version_suffix], [devel]) m4_define([purple_version], [purple_major_version.purple_minor_version.purple_micro_version]) diff -r 52c49142bbed -r f8fc41570bf1 finch/finch.c --- a/finch/finch.c Sun May 20 14:53:34 2007 +0000 +++ b/finch/finch.c Sun May 20 14:53:41 2007 +0000 @@ -156,11 +156,15 @@ gnt_input_add, g_source_remove, NULL, /* input_get_error */ +#if GLIB_CHECK_VERSION(2,14,0) + g_timeout_add_seconds, +#else + NULL, +#endif /* padding */ NULL, NULL, - NULL, NULL }; diff -r 52c49142bbed -r f8fc41570bf1 libpurple/account.c --- a/libpurple/account.c Sun May 20 14:53:34 2007 +0000 +++ b/libpurple/account.c Sun May 20 14:53:41 2007 +0000 @@ -417,7 +417,7 @@ schedule_accounts_save() { if (save_timer == 0) - save_timer = purple_timeout_add(5000, save_cb, NULL); + save_timer = purple_timeout_add_seconds(5, save_cb, NULL); } diff -r 52c49142bbed -r f8fc41570bf1 libpurple/blist.c --- a/libpurple/blist.c Sun May 20 14:53:34 2007 +0000 +++ b/libpurple/blist.c Sun May 20 14:53:41 2007 +0000 @@ -365,7 +365,7 @@ purple_blist_schedule_save() { if (save_timer == 0) - save_timer = purple_timeout_add(5000, save_cb, NULL); + save_timer = purple_timeout_add_seconds(5, save_cb, NULL); } diff -r 52c49142bbed -r f8fc41570bf1 libpurple/connection.c --- a/libpurple/connection.c Sun May 20 14:53:34 2007 +0000 +++ b/libpurple/connection.c Sun May 20 14:53:41 2007 +0000 @@ -72,7 +72,7 @@ if (on && !gc->keepalive) { purple_debug_info("connection", "Activating keepalive.\n"); - gc->keepalive = purple_timeout_add(30000, send_keepalive, gc); + gc->keepalive = purple_timeout_add_seconds(30, send_keepalive, gc); } else if (!on && gc->keepalive > 0) { diff -r 52c49142bbed -r f8fc41570bf1 libpurple/conversation.c --- a/libpurple/conversation.c Sun May 20 14:53:34 2007 +0000 +++ b/libpurple/conversation.c Sun May 20 14:53:41 2007 +0000 @@ -1010,7 +1010,7 @@ conv = purple_conv_im_get_conversation(im); name = purple_conversation_get_name(conv); - im->typing_timeout = purple_timeout_add(timeout * 1000, reset_typing_cb, conv); + im->typing_timeout = purple_timeout_add_seconds(timeout, reset_typing_cb, conv); } void diff -r 52c49142bbed -r f8fc41570bf1 libpurple/core.c --- a/libpurple/core.c Sun May 20 14:53:34 2007 +0000 +++ b/libpurple/core.c Sun May 20 14:53:41 2007 +0000 @@ -48,7 +48,11 @@ #include "util.h" #ifdef HAVE_DBUS +# define DBUS_API_SUBJECT_TO_CHANGE +# include +# include "dbus-purple.h" # include "dbus-server.h" +# include "dbus-bindings.h" #endif struct PurpleCore @@ -276,6 +280,91 @@ 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) { diff -r 52c49142bbed -r f8fc41570bf1 libpurple/core.h --- a/libpurple/core.h Sun May 20 14:53:34 2007 +0000 +++ b/libpurple/core.h Sun May 20 14:53:41 2007 +0000 @@ -121,6 +121,16 @@ */ 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. + * + * @since 2.1.0 + */ +gboolean purple_core_ensure_single_instance(void); + #ifdef __cplusplus } #endif diff -r 52c49142bbed -r f8fc41570bf1 libpurple/dbus-server.c --- a/libpurple/dbus-server.c Sun May 20 14:53:34 2007 +0000 +++ b/libpurple/dbus-server.c Sun May 20 14:53:41 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); diff -r 52c49142bbed -r f8fc41570bf1 libpurple/dbus-server.h --- a/libpurple/dbus-server.h Sun May 20 14:53:34 2007 +0000 +++ b/libpurple/dbus-server.h Sun May 20 14:53:41 2007 +0000 @@ -169,6 +169,13 @@ void *purple_dbus_get_handle(void); /** + * Determines whether this instance owns the DBus service name + * + * @since 2.1.0 + */ +gboolean purple_dbus_is_owner(); + +/** * Starts Purple's D-BUS server. It is responsible for handling DBUS * requests from other applications. */ diff -r 52c49142bbed -r f8fc41570bf1 libpurple/eventloop.c --- a/libpurple/eventloop.c Sun May 20 14:53:34 2007 +0000 +++ b/libpurple/eventloop.c Sun May 20 14:53:41 2007 +0000 @@ -35,6 +35,17 @@ return ops->timeout_add(interval, function, data); } +guint +purple_timeout_add_seconds(guint interval, GSourceFunc function, gpointer data) +{ + PurpleEventLoopUiOps *ops = purple_eventloop_get_ui_ops(); + + if (ops->timeout_add_seconds) + return ops->timeout_add_seconds(interval, function, data); + else + return ops->timeout_add(1000 * interval, function, data); +} + gboolean purple_timeout_remove(guint tag) { diff -r 52c49142bbed -r f8fc41570bf1 libpurple/eventloop.h --- a/libpurple/eventloop.h Sun May 20 14:53:34 2007 +0000 +++ b/libpurple/eventloop.h Sun May 20 14:53:41 2007 +0000 @@ -48,7 +48,7 @@ struct _PurpleEventLoopUiOps { /** - * Creates a callback timer. + * Creates a callback timer with an interval measured in milliseconds. * @see g_timeout_add, purple_timeout_add **/ guint (*timeout_add)(guint interval, GSourceFunc function, gpointer data); @@ -81,7 +81,20 @@ */ int (*input_get_error)(int fd, int *error); - void (*_purple_reserved1)(void); + /** + * Creates a callback timer with an interval measured in seconds. + * + * This allows UIs to group timers for better power efficiency. For + * this reason, @a interval may be rounded by up to a second. + * + * Implementation of this UI op is optional. If it's not implemented, + * calls to purple_timeout_add_seconds() will be serviced by the + * timeout_add UI op. + * + * @see g_timeout_add_seconds, purple_timeout_add_seconds() + **/ + guint (*timeout_add_seconds)(guint interval, GSourceFunc function, gpointer data); + void (*_purple_reserved2)(void); void (*_purple_reserved3)(void); void (*_purple_reserved4)(void); @@ -93,10 +106,15 @@ /*@{*/ /** * Creates a callback timer. + * * The timer will repeat until the function returns @c FALSE. The * first call will be at the end of the first interval. + * + * If the timer is in a multiple of seconds, use purple_timeout_add_seconds() + * instead as it allows UIs to group timers for power efficiency. + * * @param interval The time between calls of the function, in - * milliseconds. + * milliseconds. * @param function The function to call. * @param data data to pass to @a function. * @return A handle to the timer which can be passed to @@ -105,6 +123,24 @@ guint purple_timeout_add(guint interval, GSourceFunc function, gpointer data); /** + * Creates a callback timer. + * + * The timer will repeat until the function returns @c FALSE. The + * first call will be at the end of the first interval. + * + * This function allows UIs to group timers for better power efficiency. For + * this reason, @a interval may be rounded by up to a second. + * + * @param interval The time between calls of the function, in + * seconds. + * @param function The function to call. + * @param data data to pass to @a function. + * @return A handle to the timer which can be passed to + * purple_timeout_remove to remove the timer. + */ +guint purple_timeout_add_seconds(guint interval, GSourceFunc function, gpointer data); + +/** * Removes a timeout handler. * * @param handle The handle, as returned by purple_timeout_add. diff -r 52c49142bbed -r f8fc41570bf1 libpurple/example/nullclient.c --- a/libpurple/example/nullclient.c Sun May 20 14:53:34 2007 +0000 +++ b/libpurple/example/nullclient.c Sun May 20 14:53:41 2007 +0000 @@ -108,11 +108,15 @@ glib_input_add, g_source_remove, NULL, +#if GLIB_CHECK_VERSION(2,14,0) + g_timeout_add_seconds, +#else + NULL, +#endif /* padding */ NULL, NULL, - NULL, NULL }; /*** End of the eventloop functions. ***/ diff -r 52c49142bbed -r f8fc41570bf1 libpurple/idle.c --- a/libpurple/idle.c Sun May 20 14:53:34 2007 +0000 +++ b/libpurple/idle.c Sun May 20 14:53:41 2007 +0000 @@ -230,7 +230,11 @@ if (time_until_next_idle_event == 0) idle_timer = 0; else - idle_timer = purple_timeout_add(1000 * (time_until_next_idle_event + 1), check_idleness_timer, NULL); + { + /* +1 for the boundary, + * +1 more for g_timeout_add_seconds rounding. */ + idle_timer = purple_timeout_add_seconds(time_until_next_idle_event + 2, check_idleness_timer, NULL); + } return FALSE; } @@ -309,8 +313,10 @@ void purple_idle_init() { - /* Add the timer to check if we're idle */ - idle_timer = purple_timeout_add(1000 * (IDLEMARK + 1), check_idleness_timer, NULL); + /* Add the timer to check if we're idle. + * IDLEMARK + 1 as the boundary, + * +1 more for g_timeout_add_seconds rounding. */ + idle_timer = purple_timeout_add_seconds((IDLEMARK + 2), check_idleness_timer, NULL); purple_signal_connect(purple_conversations_get_handle(), "sent-im-msg", purple_idle_get_handle(), diff -r 52c49142bbed -r f8fc41570bf1 libpurple/pounce.c --- a/libpurple/pounce.c Sun May 20 14:53:34 2007 +0000 +++ b/libpurple/pounce.c Sun May 20 14:53:41 2007 +0000 @@ -273,7 +273,7 @@ schedule_pounces_save(void) { if (save_timer == 0) - save_timer = purple_timeout_add(5000, save_cb, NULL); + save_timer = purple_timeout_add_seconds(5, save_cb, NULL); } diff -r 52c49142bbed -r f8fc41570bf1 libpurple/prefs.c --- a/libpurple/prefs.c Sun May 20 14:53:34 2007 +0000 +++ b/libpurple/prefs.c Sun May 20 14:53:41 2007 +0000 @@ -226,7 +226,7 @@ schedule_prefs_save(void) { if (save_timer == 0) - save_timer = purple_timeout_add(5000, save_cb, NULL); + save_timer = purple_timeout_add_seconds(5, save_cb, NULL); } diff -r 52c49142bbed -r f8fc41570bf1 libpurple/savedstatuses.c --- a/libpurple/savedstatuses.c Sun May 20 14:53:34 2007 +0000 +++ b/libpurple/savedstatuses.c Sun May 20 14:53:41 2007 +0000 @@ -357,7 +357,7 @@ schedule_save(void) { if (save_timer == 0) - save_timer = purple_timeout_add(5000, save_cb, NULL); + save_timer = purple_timeout_add_seconds(5, save_cb, NULL); } diff -r 52c49142bbed -r f8fc41570bf1 libpurple/server.c --- a/libpurple/server.c Sun May 20 14:53:34 2007 +0000 +++ b/libpurple/server.c Sun May 20 14:53:41 2007 +0000 @@ -92,7 +92,7 @@ /* because we're modifying or creating a lar, schedule the * function to expire them as the pref dictates */ - purple_timeout_add((SECS_BEFORE_RESENDING_AUTORESPONSE + 1) * 1000, expire_last_auto_responses, NULL); + purple_timeout_add_seconds((SECS_BEFORE_RESENDING_AUTORESPONSE + 1), expire_last_auto_responses, NULL); tmp = last_auto_responses; diff -r 52c49142bbed -r f8fc41570bf1 pidgin/gtkblist.c --- a/pidgin/gtkblist.c Sun May 20 14:53:34 2007 +0000 +++ b/pidgin/gtkblist.c Sun May 20 14:53:41 2007 +0000 @@ -4195,7 +4195,7 @@ {"application/x-im-contact", 0, DRAG_BUDDY}, {"text/x-vcard", 0, DRAG_VCARD }}; if (gtkblist && gtkblist->window) { - purple_blist_set_visible(purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/list_visible")); + purple_blist_set_visible(TRUE); return; } diff -r 52c49142bbed -r f8fc41570bf1 pidgin/gtkeventloop.c --- a/pidgin/gtkeventloop.c Sun May 20 14:53:34 2007 +0000 +++ b/pidgin/gtkeventloop.c Sun May 20 14:53:41 2007 +0000 @@ -120,7 +120,11 @@ pidgin_input_add, g_source_remove, NULL, /* input_get_error */ +#if GLIB_CHECK_VERSION(2,14,0) + g_timeout_add_seconds, +#else NULL, +#endif NULL, NULL, NULL diff -r 52c49142bbed -r f8fc41570bf1 pidgin/gtkmain.c --- a/pidgin/gtkmain.c Sun May 20 14:53:34 2007 +0000 +++ b/pidgin/gtkmain.c Sun May 20 14:53:41 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();