cpw.gillux.detachablepurple: c412b925: Finally added the D-Bus sighandlers code...

gillux at soc.pidgin.im gillux at soc.pidgin.im
Tue Mar 27 17:25:57 EDT 2012


----------------------------------------------------------------------
Revision: c412b9258c64846d33a3884684310a9c4a63e10d
Parent:   1cdfd83748e5f04659af4117aec8cb0e661d8aaf
Author:   gillux at soc.pidgin.im
Date:     03/27/12 17:07:41
Branch:   im.pidgin.cpw.gillux.detachablepurple
URL: http://d.pidgin.im/viewmtn/revision/info/c412b9258c64846d33a3884684310a9c4a63e10d

Changelog: 

Finally added the D-Bus sighandlers code. Hopefully, clients will
be able to simply bind their sighandlers upon connection to D-Bus,
using the same mechanisms as the daemon with its methods handlers.
Clients shall first bind every sighandler with
purple_object_bind_dbus_callback() on their class initialization
function, and then call purple_dbus_connect_object() on their
object initialization function.

Changes against parent 1cdfd83748e5f04659af4117aec8cb0e661d8aaf

  patched  libpurple/pobject.c

-------------- next part --------------
============================================================
--- libpurple/pobject.c	0520469e129ff67d45635f3a7c29a2c61c0cdef7
+++ libpurple/pobject.c	ff4c2ec108882cc688ab8596665158333fb2ef0d
@@ -208,14 +208,8 @@ purple_object_class_init(PurpleObjectCla
 #ifdef HAVE_DBUS
 	if (purple_core_is_daemon_mode())
 		klass->on_dbus_connected = purple_object_generic_dbus_register_object;
-	/* 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()) {
-		/* Marshaller for the DBusNotify dbus signal */
-		dbus_g_object_register_marshaller(
-			purple_smarshal_VOID__STRING_BOXED,
-			G_TYPE_NONE, G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID);
-	}
+	else if (purple_core_is_remote_mode())
+		klass->on_dbus_connected = purple_object_generic_dbus_signal_subscribe;
 #endif
 }
 
@@ -775,6 +769,60 @@ purple_object_generic_dbus_register_obje
 	return reg_id;
 }
 
+static void
+purple_object_generic_dbus_sighandler(GDBusConnection *connection,
+                                      const gchar *sender_name,
+                                      const gchar *object_path,
+                                      const gchar *interface_name,
+                                      const gchar *signal_name,
+                                      GVariant *params,
+                                      gpointer object)
+{
+	GClosure *closure;
+	GValue *paramv;
+	guint i, num_params;
+
+	/* Get the sighandler back. */
+	closure = purple_object_get_dbus_closure(PURPLE_OBJECT_GET_CLASS(object),
+	                                         signal_name);
+	if (!closure) {
+		purple_debug_warning("dbus", "Signal %s received on interface %s lacks a sighandler.", signal_name, interface_name);
+		return;
+	}
+
+	/* Prepare the closure parameters. */
+	gvariant_to_gvalue_closure_args(object, params, &paramv, &num_params);
+
+	/* Execute the sighandler. */
+	g_closure_invoke(closure, NULL, num_params, paramv, NULL);
+
+	for (i = 0; i < num_params; i++)
+		g_value_unset (&paramv[i]);
+	g_free (paramv);
+}
+
+guint
+purple_object_generic_dbus_signal_subscribe(gpointer object, GDBusConnection *dbus_conn)
+{
+	PurpleObject *pobj = PURPLE_OBJECT(object);
+	guint reg_id;
+
+	reg_id = g_dbus_connection_signal_subscribe
+	          (dbus_conn, NULL, /* TODO: is NULL for 'sender' what we want? */
+	           PURPLE_OBJECT_GET_CLASS(pobj)->dbus_ifaceinfo->name,
+	           NULL, /* any signal name */
+	           purple_object_get_dbus_path(pobj),
+	           NULL, /* any first arg */
+	           G_DBUS_SIGNAL_FLAGS_NONE,
+	           purple_object_generic_dbus_sighandler, object, NULL);
+	
+	if (reg_id == 0) {
+		purple_debug_error("dbus", "Failed to subscribe %s to D-Bus signals\n",
+                                   G_OBJECT_TYPE_NAME(object));
+	}
+	return reg_id;
+}
+
 void
 purple_object_dbus_connect(gpointer object, GDBusConnection *dbus_conn)
 {


More information about the Commits mailing list