cpw.gillux.detachablepurple: 3e65e884: Introduced the switch from dbus-glib to ...
gillux at soc.pidgin.im
gillux at soc.pidgin.im
Thu May 19 16:21:15 EDT 2011
----------------------------------------------------------------------
Revision: 3e65e88487d511bac639b768dd5a4d68b11f8027
Parent: a82660ab5e31dbe1d7e86014eaafa25264b0d438
Author: gillux at soc.pidgin.im
Date: 05/19/11 15:45:55
Branch: im.pidgin.cpw.gillux.detachablepurple
URL: http://d.pidgin.im/viewmtn/revision/info/3e65e88487d511bac639b768dd5a4d68b11f8027
Changelog:
Introduced the switch from dbus-glib to gdbus, with:
- the code needed to acquire the bus
- a "virtual function", (*dbus_register), aimed to be set by
all the PurpleObjects to register themselves on DBus.
Changes against parent a82660ab5e31dbe1d7e86014eaafa25264b0d438
patched configure.ac
patched libpurple/dbus/account.c
patched libpurple/dbus-bindings.h
patched libpurple/dbus-server.c
patched libpurple/dbus-server.h
patched libpurple/pobject.c
patched libpurple/pobject.h
-------------- next part --------------
============================================================
--- configure.ac e04a5fae688b0ff25e902a3ffa611b0d820372e3
+++ configure.ac 1b779d19c273f81ffc2340729ce4e24450bc8e1b
@@ -328,7 +328,7 @@ dnl ####################################
dnl #######################################################################
dnl # Check for GLib 2.16 (required)
dnl #######################################################################
-PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.16.0 gobject-2.0 gmodule-2.0 gthread-2.0], , [
+PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.16.0 gobject-2.0 gmodule-2.0 gthread-2.0 gio-2.0], , [
AC_MSG_RESULT(no)
AC_MSG_ERROR([
============================================================
--- libpurple/dbus-server.c d24f9f54bd9dd42ff4d6c1589232a460d8bc0137
+++ libpurple/dbus-server.c e0bf81855f0987841f234719a7474ba1f17a32bb
@@ -35,6 +35,7 @@
#include <stdlib.h>
#include <string.h>
#include <dbus/dbus-glib-bindings.h>
+#include <gio/gio.h>
#include "account.h"
#include "accountlist.h"
@@ -87,6 +88,14 @@ static GHashTable *map_id_type;
static GHashTable *map_id_node;
static GHashTable *map_id_type;
+/* The bus acquiring process is asynchronous. We first ask to get it,
+ * then the other parts of purple are initialized, and then when we
+ * reach the program main loop, the on_bus_acquired callback is called.
+ * Therefore we need something to remember the objects created during
+ * the initialization that we will need to register on DBus when we get
+ * the bus. We temporary hold a reference to such objects in this list. */
+static GSList *dbus_obj_to_register = NULL;
+
static gchar *init_error;
static int dbus_request_name_reply = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
@@ -524,14 +533,14 @@ purple_dbus_get_gobject_by_path(const gc
/* DBus bindings ... */
/**************************************************************/
-static DBusGConnection *purple_dbus_g_connection;
+static GDBusConnection *purple_gdbus_connection;
static DBusConnection *purple_dbus_connection;
-DBusGConnection *
-purple_dbus_get_g_connection(void)
+GDBusConnection *
+purple_gdbus_get_connection(void)
{
- return purple_dbus_g_connection;
+ return purple_gdbus_connection;
}
DBusConnection *
@@ -721,8 +730,8 @@ purple_dbus_dispatch_init(void)
GError *gerror = NULL;
dbus_error_init(&error);
- purple_dbus_g_connection = dbus_g_bus_get(DBUS_BUS_STARTER, &gerror);
- purple_dbus_connection = dbus_g_connection_get_connection(purple_dbus_g_connection);
+ //purple_gdbus_connection = g_bus_get_sync(G_BUS_TYPE_STARTER, NULL, &gerror);
+ purple_dbus_connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
if (purple_dbus_connection == NULL)
{
@@ -772,54 +781,80 @@ purple_dbus_dispatch_init(void)
PURPLE_DBUS_REGISTER_BINDINGS(purple_dbus_get_handle());
}
+void
+purple_dbus_register_object(gpointer object)
+{
+ if (purple_gdbus_connection)
+ purple_object_register_on_dbus(object, purple_gdbus_connection);
+ else
+ dbus_obj_to_register = g_slist_append(dbus_obj_to_register,
+ g_object_ref(object));
+}
+
+/* Note that this callback will not be called until we reach the event loop,
+ * after everything is initialized. That's why we need to put our objects
+ * in the dbus_obj_to_register GSList, to register them later, when we have
+ * acquired the bus.
+ */
static void
-purple_dbus_g_init(void)
+on_bus_acquired(GDBusConnection *connection, const gchar *name,
+ gpointer user_data)
{
- DBusGProxy* dbus_proxy;
+ GObject *obj;
+ GSList* obj_list;
+
+ purple_gdbus_connection = connection;
+ for (obj_list = dbus_obj_to_register; obj_list; obj_list = obj_list->next) {
+ obj = G_OBJECT(obj_list->data);
+ /* If we are owning the last a reference, it means we are going
+ * to destroy it, so don't bother registering it on DBus. */
+ if (obj->ref_count > 1)
+ purple_object_register_on_dbus(obj_list->data, connection);
+ g_object_unref(obj);
+ }
+
+ g_slist_free(dbus_obj_to_register);
+}
+
+static void
+on_name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data)
+{
+ /* TODO: Handle this properly. */
+ purple_debug_error("dbus", "Name %s lost!", name);
+}
+
+static void
+purple_gdbus_init(void)
+{
+ guint owner_id;
GError *error = NULL;
- guint request_ret;
- /* In remote mode we need to register the marshallers
- * we will use to receive the signals sent by the daemon */
if (purple_core_is_remote_mode()) {
/* Initialize the "dbus path name -> gobject" hash table */
dbus_path_gobjects = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, NULL);
}
- /* In daemon mode create a proxy for the purple service, so we can
- * publish our gobjects on DBus.
+ /* In daemon mode we need to own our name on the bus,
+ * so we can publish our gobjects on DBus.
*/
if (purple_core_is_daemon_mode()) {
- dbus_proxy = dbus_g_proxy_new_for_name(purple_dbus_get_g_connection(),
- DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
- DBUS_INTERFACE_DBUS);
- if (!dbus_proxy) {
- purple_debug_error("dbus", "Unable to create proxy\n");
- return;
- }
-
- if (!org_freedesktop_DBus_request_name(dbus_proxy,
- DBUS_PURPLE_SERVICE, 0,
- &request_ret, &error)) {
- purple_debug_error("dbus",
- "Unable to request the name of service "
- DBUS_PURPLE_SERVICE ": %s\n",
- error->message);
- g_object_unref(dbus_proxy);
- g_error_free(error);
- return;
- }
- g_object_unref(dbus_proxy);
- /* We should also care about request_ret */
+ owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, DBUS_PURPLE_SERVICE,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_bus_acquired,
+ NULL, /* on_name_acquired */
+ on_name_lost, /* on_name_lost */
+ NULL, NULL);
+ /* TODO: handle fail of owning the name. */
}
/* In remote and daemon mode, we create our singleton objects */
+
+ /* Instantiate the PurpleConstructor */
+ purple_constructor_do_init();
+
/* Instantiate the PurpleDBusCallback. */
purple_dbus_callback_do_init();
-
- /* Instantiate and publish the PurpleConstructor */
- purple_constructor_do_init();
}
@@ -1007,11 +1042,11 @@ purple_dbus_init(void)
if (init_error != NULL)
purple_debug_error("dbus", "%s\n", init_error);
- purple_dbus_g_init();
+ purple_gdbus_init();
}
static void
-purple_dbus_g_uninit(void)
+purple_gdbus_uninit(void)
{
if (purple_core_is_remote_mode())
g_hash_table_destroy(dbus_path_gobjects);
@@ -1038,5 +1073,5 @@ purple_dbus_uninit(void)
g_free(init_error);
init_error = NULL;
- purple_dbus_g_uninit();
+ purple_gdbus_uninit();
}
============================================================
--- libpurple/dbus-server.h 0acd9de4c5ab4abeb23e019ae0d2b11de7a3fa41
+++ libpurple/dbus-server.h fdc85e47a83c0d3688979bee43480d04f33c2e9b
@@ -179,6 +179,15 @@ gboolean purple_dbus_is_owner(void);
gboolean purple_dbus_is_owner(void);
/**
+ * "Busless" function to register a PurpleObject on DBus.
+ * If the bus is acquired, it calls the ->dbus_register() operation.
+ * Otherwise, it will do it when the bus is acquired.
+ *
+ * @param obj The object to register. Must be a subclass of PurpleObject.
+ */
+void purple_dbus_register_object(gpointer object);
+
+/**
* Starts Purple's D-BUS server. It is responsible for handling DBUS
* requests from other applications.
*/
============================================================
--- libpurple/dbus-bindings.h cf9bc137c80c8a1d14cd0a38d74fc9d6ef839238
+++ libpurple/dbus-bindings.h 16b39a8348552a1490a0fa8815261ab92ec89e1f
@@ -107,7 +107,7 @@ DBusConnection *purple_dbus_get_connecti
DBusConnection *purple_dbus_get_connection(void);
-DBusGConnection *purple_dbus_get_g_connection(void);
+GDBusConnection *purple_gdbus_get_connection(void);
#ifdef __cplusplus
}
============================================================
--- libpurple/pobject.c 38302660f3991b981d0a1a0475af2d9fa688f8c7
+++ libpurple/pobject.c f4b3c3a9683bd5f1cc581fabcb0900b5715b6319
@@ -459,14 +459,14 @@ purple_object_install_dbus_infos(PurpleO
if (purple_core_is_remote_mode() || purple_core_is_mirror_mode()) {
/* One for the org.freedesktop.DBus.Properties interface */
dbus_proxy = dbus_g_proxy_new_for_name(
- purple_dbus_get_g_connection(),
+ purple_gdbus_get_connection(),
DBUS_PURPLE_SERVICE, dbus_path,
DBUS_INTERFACE_PROPERTIES);
priv->dbus_props_proxy = dbus_proxy;
/* One for the provided interface */
dbus_proxy = dbus_g_proxy_new_for_name(
- purple_dbus_get_g_connection(),
+ purple_gdbus_get_connection(),
DBUS_PURPLE_SERVICE, dbus_path,
dbus_interface);
priv->dbus_obj_proxy = dbus_proxy;
@@ -487,7 +487,7 @@ purple_object_install_dbus_infos(PurpleO
else if (purple_core_is_daemon_mode()) {
/* Register our object as at dbus_path */
dbus_g_connection_register_g_object(
- purple_dbus_get_g_connection(),
+ purple_gdbus_get_connection(),
dbus_path, G_OBJECT(pobj));
/* Remember the purple interface */
============================================================
--- libpurple/pobject.h fac160f0d1097e0f16383286a3e36118290499b3
+++ libpurple/pobject.h 18476ab80af15bff6acdd5cc7232c60c63ab01e4
@@ -26,6 +26,7 @@
#ifdef HAVE_DBUS
# include <dbus/dbus-glib-bindings.h>
+# include <gio/gio.h>
#endif
#define PURPLE_TYPE_OBJECT (purple_object_get_type())
@@ -47,8 +48,13 @@ struct _PurpleObjectClass
struct _PurpleObjectClass
{
GObjectClass gparent;
-
+#ifdef HAVE_DBUS
+ /* A function that should register the object on DBus. */
+ guint (*dbus_register)(gpointer object, GDBusConnection *connection);
+ void (*_purple_reserved[3])(void);
+#else
void (*_purple_reserved[4])(void);
+#endif
};
G_BEGIN_DECLS
@@ -155,6 +161,16 @@ void purple_object_set_dbus_path(PurpleO
* @param path The path name.
*/
void purple_object_set_dbus_path(PurpleObject *pobj, char* path);
+/**
+ * Calls the dbus_register function pointer on the class of object, and keeps
+ * the registration id.
+ *
+ * @param object An object derived from PurpleObject.
+ * @param dbus_conn The GDBus handle.
+ */
+void purple_object_register_on_dbus(gpointer object, GDBusConnection *dbus_conn);
+
+
#endif /* HAVE_DBUS */
int purple_object_get_int(PurpleObject *pobj, const char *prop);
============================================================
--- libpurple/dbus/account.c 4090faba625cb3299307578a53cb1ddf4e4093d5
+++ libpurple/dbus/account.c 767afc902247a45b355a5f64435e00d0b002447c
@@ -245,7 +245,7 @@ purple_account_new_RPC(const char *usern
PurpleRunningMode mode;
/* First, remotely create a new account */
- dbus_proxy = dbus_g_proxy_new_for_name(purple_dbus_get_g_connection(),
+ dbus_proxy = dbus_g_proxy_new_for_name(purple_gdbus_get_connection(),
DBUS_PURPLE_SERVICE,
DBUS_CONSTRUCTOR_PATH,
DBUS_CONSTRUCTOR_INTERFACE);
More information about the Commits
mailing list