/srv/mercurial-server/detachablepurple: 938b036143ac: Added a ne...

Gilles Bedel gillux at cpw.pidgin.im
Fri Jun 15 22:01:32 EDT 2012


Changeset: 938b036143accf38b2f6bd33b6a7dc82fcc6199a
Author:	 Gilles Bedel <gillux at cpw.pidgin.im>
Date:	 2012-05-12 17:35 +0000
Branch:	 cpw.gillux.detachablepurple
URL: http://hg.pidgin.im/srv/mercurial-server/detachablepurple/rev/938b036143ac

Description:

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).

diffstat:

 libpurple/pobject.c |  71 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 libpurple/pobject.h |  11 ++++++++
 2 files changed, 82 insertions(+), 0 deletions(-)

diffs (109 lines):

diff --git a/libpurple/pobject.c b/libpurple/pobject.c
--- a/libpurple/pobject.c
+++ b/libpurple/pobject.c
@@ -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 @@
 	}
 }
 
+/* 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)
 {
diff --git a/libpurple/pobject.h b/libpurple/pobject.h
--- a/libpurple/pobject.h
+++ b/libpurple/pobject.h
@@ -350,6 +350,17 @@
  */
 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