/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