soc.2010.detachablepurple: bc886588: Added the new GetBuddyList dbus method -...
gillux at soc.pidgin.im
gillux at soc.pidgin.im
Mon Aug 9 23:58:42 EDT 2010
----------------------------------------------------------------------
Revision: bc886588a0be43d28804bf9bb9cc3259691f7aac
Parent: e071748c3c086a743a68ced010f2c62758c0219d
Author: gillux at soc.pidgin.im
Date: 08/08/10 12:40:04
Branch: im.pidgin.soc.2010.detachablepurple
URL: http://d.pidgin.im/viewmtn/revision/info/bc886588a0be43d28804bf9bb9cc3259691f7aac
Changelog:
Added the new GetBuddyList dbus method - server side only. It will be used by
clients to load their buddy list from the daemon.
Changes against parent e071748c3c086a743a68ced010f2c62758c0219d
patched libpurple/dbus/blist.c
patched libpurple/dbus/blist.xml
-------------- next part --------------
============================================================
--- libpurple/dbus/blist.c 9b375eb3b2dabe6cc0d5c2d05be24f1bd780ae9f
+++ libpurple/dbus/blist.c 17d1b295884f98ed97b75e8c79e13097e28a0728
@@ -23,9 +23,9 @@
#include "internal.h"
#include "blist.h"
+#include "blist-node.h"
#include "core.h"
#include "dbus/blist.h"
-#include "dbus/blist-server.h"
#include "dbus-purple.h"
/**
@@ -58,6 +58,51 @@ G_DEFINE_TYPE(PurpleBListDBus, purple_bl
G_DEFINE_TYPE(PurpleBListDBus, purple_blist_dbus, PURPLE_TYPE_OBJECT)
+/* Server side dbus methods.
+ * Theses functions needs PurpleBListDBus declared, and must go before the
+ * inclusion of blist-server.h, in which they are defined. */
+gboolean DBUS_purple_blist_get_buddy_list(PurpleBListDBus *blist, GPtrArray **groups, GPtrArray **contacts, GPtrArray **buddies, GPtrArray **chats, GError** error);
+#include "dbus/blist-server.h"
+
+/* DBus transfered data formats */
+#define DBUS_PURPLE_BLIST_SETTING \
+( \
+ dbus_g_type_get_struct("GValueArray", \
+ G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID) \
+)
+#define DBUS_PURPLE_BLIST_SETTINGS \
+( \
+ dbus_g_type_get_collection("GPtrArray", \
+ DBUS_PURPLE_BLIST_SETTING) \
+)
+#define DBUS_PURPLE_GROUP_PACK \
+( \
+ dbus_g_type_get_struct("GValueArray", \
+ G_TYPE_STRING, DBUS_PURPLE_BLIST_SETTINGS, G_TYPE_INVALID) \
+)
+#define DBUS_PURPLE_CONTACT_PACK \
+( \
+ dbus_g_type_get_struct("GValueArray", \
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, \
+ DBUS_PURPLE_BLIST_SETTINGS, G_TYPE_INVALID) \
+)
+#define DBUS_PURPLE_BUDDY_PACK \
+( \
+ dbus_g_type_get_struct("GValueArray", \
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, \
+ G_TYPE_STRING, DBUS_PURPLE_BLIST_SETTINGS, G_TYPE_INVALID) \
+)
+#define DBUS_PURPLE_CHAT_PACK \
+( \
+ dbus_g_type_get_struct("GValueArray", \
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, \
+ DBUS_TYPE_G_STRING_STRING_HASHTABLE, G_TYPE_STRING, \
+ DBUS_PURPLE_BLIST_SETTINGS, G_TYPE_INVALID) \
+)
+
+/* A convenience macro. */
+#define parent_node_dbus_path(node) purple_object_get_dbus_path(PURPLE_OBJECT(purple_blist_node_parent(node)))
+
static void
purple_blist_dbus_init(PurpleBListDBus *self)
{
@@ -110,3 +155,240 @@ purple_blist_uninit_dbus(void)
g_return_if_fail(klass->instance != NULL);
g_object_unref(klass->instance);
}
+
+/**
+ * Callback used by settings_to_ptr_array().
+ * Builds a DBUS_PURPLE_BLIST_SETTING struct, to export a setting on dbus.
+ */
+static void
+blist_setting_to_array(const char *name, GValue *value, GPtrArray *settings)
+{
+ GValue setting = {0, };
+ gboolean ok;
+
+ g_value_init(&setting, DBUS_PURPLE_BLIST_SETTING);
+ g_value_take_boxed(&setting,
+ dbus_g_type_specialized_construct(DBUS_PURPLE_BLIST_SETTING));
+ ok = dbus_g_type_struct_set(&setting, 0, name, 1, value, G_MAXUINT);
+
+ g_return_if_fail(ok == TRUE);
+ g_ptr_array_add(settings, g_value_get_boxed(&setting));
+}
+
+/**
+ * Converts the settings of the provided PurpleBlistNode into a
+ * DBUS_PURPLE_BLIST_SETTINGS GPtrArray (array of GValues), to export them on
+ * dbus. Caller is responsible for freeing the array and the GValues in it.
+ * Used to pack data in DBUS_purple_blist_get_buddy_list().
+ */
+static GPtrArray *
+settings_to_ptr_array(PurpleBlistNode *node)
+{
+ GPtrArray *array;
+ GHashTable *settings_hash;
+
+ array = g_ptr_array_new();
+ settings_hash = purple_blist_node_get_settings(PURPLE_BLIST_NODE(node));
+ g_hash_table_foreach(settings_hash,
+ (GHFunc)blist_setting_to_array, array);
+ return array;
+}
+
+/**
+ * Packs a PurpleGroup in a DBUS_PURPLE_GROUP_PACK struct,
+ * to export it on dbus, and append it in the provided groups array.
+ * Used to pack data in DBUS_purple_blist_get_buddy_list().
+ */
+static void
+pack_group(GPtrArray *groups, PurpleGroup *group)
+{
+ GValue group_pack = {0, };
+ gboolean ok;
+ const char *group_name;
+ GPtrArray *settings_pack;
+
+ g_value_init(&group_pack, DBUS_PURPLE_GROUP_PACK);
+ g_value_set_boxed(&group_pack,
+ dbus_g_type_specialized_construct(DBUS_PURPLE_GROUP_PACK));
+
+ group_name = purple_group_get_name(group);
+ settings_pack = settings_to_ptr_array(PURPLE_BLIST_NODE(group));
+ ok = dbus_g_type_struct_set(&group_pack,
+ 0, group_name,
+ 1, settings_pack, G_MAXUINT);
+
+ g_ptr_array_foreach(settings_pack, (GFunc)g_value_array_free, NULL);
+ g_ptr_array_free(settings_pack, TRUE);
+
+ g_return_if_fail(ok == TRUE);
+ g_ptr_array_add(groups, g_value_get_boxed(&group_pack));
+}
+
+/**
+ * Packs a PurpleContact in a DBUS_PURPLE_CONTACT_PACK struct,
+ * to export it on dbus, and append it in the provided contacts array.
+ * Used to pack data in DBUS_purple_blist_get_buddy_list().
+ */
+static void
+pack_contact(GPtrArray *contacts, PurpleContact *contact)
+{
+ GValue contact_pack = {0, };
+ gboolean ok;
+ char* contact_path;
+ const char *alias;
+ char *parent_path;
+ GPtrArray *settings_pack;
+
+ g_value_init(&contact_pack, DBUS_PURPLE_CONTACT_PACK);
+ g_value_set_boxed(&contact_pack,
+ dbus_g_type_specialized_construct(DBUS_PURPLE_CONTACT_PACK));
+
+ contact_path = purple_object_get_dbus_path(PURPLE_OBJECT(contact));
+ alias = purple_contact_get_alias(contact);
+ parent_path = parent_node_dbus_path(PURPLE_BLIST_NODE(contact));
+ settings_pack = settings_to_ptr_array(PURPLE_BLIST_NODE(contact));
+ ok = dbus_g_type_struct_set(&contact_pack,
+ 0, contact_path,
+ 1, alias,
+ 2, parent_path,
+ 3, settings_pack, G_MAXUINT);
+
+ g_ptr_array_foreach(settings_pack, (GFunc)g_value_array_free, NULL);
+ g_ptr_array_free(settings_pack, TRUE);
+
+ g_return_if_fail(ok == TRUE);
+ g_ptr_array_add(contacts, g_value_get_boxed(&contact_pack));
+}
+
+/**
+ * Packs a PurpleBuddy in a DBUS_PURPLE_BUDDY_PACK struct,
+ * to export it on dbus, and append it in the provided buddies array.
+ * Used to pack data in DBUS_purple_blist_get_buddy_list().
+ */
+static void
+pack_buddy(GPtrArray *buddies, PurpleBuddy *buddy)
+{
+ GValue buddy_pack = {0, };
+ gboolean ok;
+ char *buddy_path;
+ char *account_path;
+ const char *name;
+ const char *alias;
+ char *parent_path;
+ GPtrArray *settings_pack;
+
+ g_value_init(&buddy_pack, DBUS_PURPLE_BUDDY_PACK);
+ g_value_set_boxed(&buddy_pack,
+ dbus_g_type_specialized_construct(DBUS_PURPLE_BUDDY_PACK));
+
+ buddy_path = purple_object_get_dbus_path(PURPLE_OBJECT(buddy));
+ account_path = purple_object_get_dbus_path(
+ PURPLE_OBJECT(purple_buddy_get_account(buddy)));
+ name = purple_buddy_get_name(buddy);
+ alias = purple_buddy_get_alias_only(buddy);
+ parent_path = parent_node_dbus_path(PURPLE_BLIST_NODE(buddy));
+ settings_pack = settings_to_ptr_array(PURPLE_BLIST_NODE(buddy));
+ ok = dbus_g_type_struct_set(&buddy_pack,
+ 0, buddy_path,
+ 1, account_path,
+ 2, name,
+ 3, alias,
+ 4, parent_path,
+ 5, settings_pack, G_MAXUINT);
+
+ g_ptr_array_foreach(settings_pack, (GFunc)g_value_array_free, NULL);
+ g_ptr_array_free(settings_pack, TRUE);
+
+ g_return_if_fail(ok == TRUE);
+ g_ptr_array_add(buddies, g_value_get_boxed(&buddy_pack));
+}
+
+/**
+ * Packs a PurpleChat in a DBUS_PURPLE_CHAT_PACK struct,
+ * to export it on dbus, and append it in the provided chats array.
+ * Used to pack data in DBUS_purple_blist_get_buddy_list().
+ */
+static void
+pack_chat(GPtrArray *chats, PurpleChat *chat)
+{
+ GValue chat_pack = {0, };
+ gboolean ok;
+ char *chat_path;
+ char *account_path;
+ const char *alias;
+ GHashTable *components;
+ char *parent_path;
+ GPtrArray *settings_pack;
+
+ g_value_init(&chat_pack, DBUS_PURPLE_CHAT_PACK);
+ g_value_set_boxed(&chat_pack,
+ dbus_g_type_specialized_construct(DBUS_PURPLE_CHAT_PACK));
+
+ chat_path = purple_object_get_dbus_path(PURPLE_OBJECT(chat));
+ account_path = purple_object_get_dbus_path(
+ PURPLE_OBJECT(purple_chat_get_account(chat)));
+ alias = purple_chat_get_alias(chat);
+ components = purple_chat_get_components(chat);
+ parent_path = parent_node_dbus_path(PURPLE_BLIST_NODE(chat));
+ settings_pack = settings_to_ptr_array(PURPLE_BLIST_NODE(chat));
+ ok = dbus_g_type_struct_set(&chat_pack,
+ 0, chat_path,
+ 1, account_path,
+ 2, alias,
+ 3, components,
+ 4, parent_path,
+ 5, settings_pack, G_MAXUINT);
+
+ g_ptr_array_foreach(settings_pack, (GFunc)g_value_array_free, NULL);
+ g_ptr_array_free(settings_pack, TRUE);
+
+ g_return_if_fail(ok == TRUE);
+ g_ptr_array_add(chats, g_value_get_boxed(&chat_pack));
+}
+
+/**
+ * Recursive function. Goes through the buddy list and fills the GPtrArrays
+ * from what it encounter.
+ * Used to pack data in purple_blist_get_buddy_list_RPC().
+ */
+static void
+pack_node(PurpleBlistNode *node, GPtrArray *groups, GPtrArray *contacts,
+ GPtrArray *buddies, GPtrArray *chats)
+{
+ PurpleBlistNode *child;
+
+ while (node) {
+ if (PURPLE_IS_GROUP(node)) {
+ pack_group(groups, PURPLE_GROUP(node));
+ } else if(PURPLE_IS_CONTACT(node)) {
+ pack_contact(contacts, PURPLE_CONTACT(node));
+ } else if(PURPLE_IS_BUDDY(node)) {
+ pack_buddy(buddies, PURPLE_BUDDY(node));
+ } else if(PURPLE_IS_CHAT(node)) {
+ pack_chat(chats, PURPLE_CHAT(node));
+ }
+
+ child = purple_blist_node_first_child(node);
+ if (child)
+ pack_node(child, groups, contacts, buddies, chats);
+
+ node = purple_blist_node_next(node);
+ }
+}
+
+gboolean
+DBUS_purple_blist_get_buddy_list(PurpleBListDBus *blist, GPtrArray **groups,
+ GPtrArray **contacts, GPtrArray **buddies,
+ GPtrArray **chats, GError** error)
+{
+ PurpleBlistNode *node;
+
+ *groups = g_ptr_array_new();
+ *contacts = g_ptr_array_new();
+ *buddies = g_ptr_array_new();
+ *chats = g_ptr_array_new();
+ node = purple_blist_get_root();
+ pack_node(purple_blist_get_root(),
+ *groups, *contacts, *buddies, *chats);
+ return TRUE;
+}
============================================================
--- libpurple/dbus/blist.xml 56900a2b6fe7f5483ad9d40112b3e034bc82cbb4
+++ libpurple/dbus/blist.xml 0096598a98100c297b0759050c79abe190d03e18
@@ -1,5 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<node name="/im/pidgin/purple/blist">
<interface name="im.pidgin.purple.blist">
+ <method name="GetBuddyList">
+ <!-- group: s = group name; a(sv) = settings -->
+ <arg type="a(sa(sv))" name="groups" direction="out" />
+ <!-- contact: s = contact path name; s = alias;
+ s = parent path name; a(sv) = settings -->
+ <arg type="a(sssa(sv))" name="contacts"
+ direction="out" />
+ <!-- buddy: s = buddy path name; s = account; s = name;
+ s = alias; s = parent path name;
+ a(sv) = settings -->
+ <arg type="a(sssssa(sv))" name="buddies"
+ direction="out" />
+ <!-- chat: s = chat path name; s = account; s = alias;
+ a{ss} = components; s = parent path name;
+ a(sv) = settings -->
+ <arg type="a(sssa{ss}sa(sv))" name="chats"
+ direction="out" />
+ </method>
</interface>
</node>
More information about the Commits
mailing list