cpw.gillux.detachablepurple: a09cbed7: Added a new generic function to call a D...

gillux at soc.pidgin.im gillux at soc.pidgin.im
Sat May 12 16:56:40 EDT 2012


----------------------------------------------------------------------
Revision: a09cbed718d0fad0b27e4203c2c4c97a822e3ef4
Parent:   66d1b27b5e99ca08cf225977b29ec72e0dc878b2
Author:   gillux at soc.pidgin.im
Date:     05/12/12 13:35:10
Branch:   im.pidgin.cpw.gillux.detachablepurple
URL: http://d.pidgin.im/viewmtn/revision/info/a09cbed718d0fad0b27e4203c2c4c97a822e3ef4

Changelog: 

Added a new generic function to call a D-Bus remote method
on a given PurpleObject. Prototypes are assumed to be what's
in the the D-Bus introspection stuff (in the XML files).

Changes against parent 66d1b27b5e99ca08cf225977b29ec72e0dc878b2

  patched  libpurple/pobject.c
  patched  libpurple/pobject.h

-------------- next part --------------
============================================================
--- libpurple/pobject.c	3574249bcdf57f7b38c5b5c45916470719df0bf3
+++ libpurple/pobject.c	556742176928e158eabd0c6fad27faa5de3d6a35
@@ -19,6 +19,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
 
+#include <stdarg.h>
+
 #include "internal.h"
 #include "core.h"
 #include "dbus-maybe.h"
@@ -845,6 +847,75 @@ purple_object_dbus_connect(gpointer obje
 	}
 }
 
+/* Merges all the args signatures in a tuple and create a GVariantType from
+ * that. Code shamely copied from glib's gdbusprivate.c. */
+static GVariantType *
+purple_object_tuplize_signatures(GDBusArgInfo **args)
+{
+	const GVariantType *arg_types[256];
+	guint n;
+
+	if (args)
+		for (n = 0; args[n] != NULL; n++) {
+			/* DBus places a hard limit of 255 on signature length.
+			 * therefore number of args must be less than 256.
+			 */
+			g_assert (n < 256);
+			arg_types[n] = G_VARIANT_TYPE (args[n]->signature);
+			if G_UNLIKELY (arg_types[n] == NULL)
+				return NULL;
+		}
+	else
+		n = 0;
+
+	return g_variant_type_new_tuple (arg_types, n);
+}
+
+GVariant *
+purple_object_dbus_call(PurpleObject *pobj, const char *method_name, ...)
+{
+	va_list ap;
+	GDBusInterfaceInfo *iface;
+	GDBusMethodInfo *method_info;
+	GDBusConnection *connection;
+	GVariantType *type_in, *type_out;
+	GVariant *in_args, *out_args;
+	gchar *sig_in;
+	GError *error = NULL;
+
+	connection = purple_gdbus_get_connection();
+	if (!connection) /* TODO: handle this properly. */
+		return NULL;
+
+	iface = PURPLE_OBJECT_GET_CLASS(pobj)->dbus_ifaceinfo;
+	method_info = g_dbus_interface_info_lookup_method(iface, method_name);
+	g_return_val_if_fail(method_info != NULL, NULL);
+
+	type_in = purple_object_tuplize_signatures(method_info->in_args);
+	sig_in = g_variant_type_dup_string(type_in);
+	va_start(ap, method_name);
+	in_args = g_variant_new_va(sig_in, NULL, &ap);
+	va_end(ap);
+	g_free(sig_in);
+
+	type_out = purple_object_tuplize_signatures(method_info->out_args);
+	out_args = g_dbus_connection_call_sync(connection, DBUS_PURPLE_SERVICE,
+	                                       purple_object_get_dbus_path(pobj),
+	                                       iface->name, method_name,
+	                                       in_args, type_out,
+	                                       G_DBUS_CALL_FLAGS_NONE,
+	                                       -1, NULL, &error);
+	if (!out_args) {
+		purple_debug_error("dbus", "Error while remotely calling %s.%s: %s",
+		                   iface->name, method_name, error->message);
+		g_error_free(error);
+	}
+
+	g_variant_type_free(type_in);
+	g_variant_type_free(type_out);
+	return out_args;
+}
+
 static GQuark
 purple_object_type_dbus_metadata_quark(void)
 {
============================================================
--- libpurple/pobject.h	ce5b77fd2f5d8838c20db0df47efcf31289ff95f
+++ libpurple/pobject.h	c42d85c7dcc4af5edbaf65ec6b61e33bb3f6e58a
@@ -350,6 +350,17 @@ void purple_object_dbus_connect(gpointer
  */
 void purple_object_dbus_connect(gpointer object, GDBusConnection *dbus_conn);
 
+/**
+ * Remotely calls method_name on pobj over D-Bus. Actually, it's not called
+ * on this pojb object but on the remote associated one. The input parameters
+ * are all the variable parameters, and must follow the method input parameters
+ * signature described in the XML file.
+ *
+ * @param pobj The PurpleObject on which the method is called.
+ * @param method_name The name of the method.
+ * @returns The output parameters of the method, as described in the XML file. They must be freed using g_variant_unref().
+ */
+GVariant* purple_object_dbus_call(PurpleObject *pobj, const char *method_name, ...);
 
 #endif /* HAVE_DBUS */
 


More information about the Commits mailing list