[Telepathy-commits] [telepathy-salut/master] Start the implementation of D-Bus method call set_self_capabilities()
Alban Crequy
alban.crequy at collabora.co.uk
Thu Feb 26 11:20:04 PST 2009
---
src/Makefile.am | 2 +
src/salut-connection.c | 224 +++++++++++++++++++++++++++++++++++++++----
src/salut-presence-cache.c | 105 +++++++++++++++++++++
src/salut-presence-cache.h | 46 +++++++++
4 files changed, 356 insertions(+), 21 deletions(-)
create mode 100644 src/salut-presence-cache.c
create mode 100644 src/salut-presence-cache.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 3b6d3ab..26747ab 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -41,6 +41,8 @@ CORE_SOURCES = \
salut-file-transfer-channel.c \
salut-file-transfer-channel.h \
salut-muc-channel.h \
+ salut-presence-cache.c \
+ salut-presence-cache.h \
salut-tubes-manager.c \
salut-tubes-manager.h \
salut-contact.h \
diff --git a/src/salut-connection.c b/src/salut-connection.c
index 14b69ed..fa49b60 100644
--- a/src/salut-connection.c
+++ b/src/salut-connection.c
@@ -30,43 +30,45 @@
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
-#include "salut-connection.h"
+#include <telepathy-glib/channel-manager.h>
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/handle-repo-dynamic.h>
+#include <telepathy-glib/handle-repo.h>
+#include <telepathy-glib/handle-repo-static.h>
+#include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/svc-generic.h>
+#include <telepathy-glib/util.h>
-#include "salut-util.h"
-#include "salut-contact-manager.h"
+#include <gibber/gibber-namespaces.h>
+
+#include "salut-avahi-discovery-client.h"
+#include "salut-caps-channel-manager.h"
+#include "salut-caps-hash.h"
+#include "salut-connection.h"
#include "salut-contact-channel.h"
+#include "salut-contact.h"
+#include "salut-contact-manager.h"
+#include "salut-direct-bytestream-manager.h"
+#include "salut-discovery-client.h"
#include "salut-im-manager.h"
#include "salut-muc-manager.h"
#include "salut-ft-manager.h"
#include "salut-contact.h"
#include "salut-roomlist-manager.h"
+#include "salut-presence.h"
+#include "salut-presence-cache.h"
#include "salut-self.h"
-#include "salut-xmpp-connection-manager.h"
#include "salut-si-bytestream-manager.h"
+#include "salut-tubes-manager.h"
+#include "salut-util.h"
+#include "salut-xmpp-connection-manager.h"
#ifdef ENABLE_OLPC
#include "salut-olpc-activity-manager.h"
#endif
-#include "salut-tubes-manager.h"
-
-#include "salut-presence.h"
-#include "salut-discovery-client.h"
-#include "salut-avahi-discovery-client.h"
-
#include <extensions/extensions.h>
-#include <telepathy-glib/channel-manager.h>
-#include <telepathy-glib/util.h>
-#include <telepathy-glib/dbus.h>
-#include <telepathy-glib/handle-repo-dynamic.h>
-#include <telepathy-glib/handle-repo-static.h>
-#include <telepathy-glib/handle-repo.h>
-#include <telepathy-glib/interfaces.h>
-#include <telepathy-glib/svc-generic.h>
-
-#include <gibber/gibber-namespaces.h>
-
#define DEBUG_FLAG DEBUG_CONNECTION
#include "debug.h"
@@ -97,6 +99,9 @@ static void
salut_connection_avatar_service_iface_init (gpointer g_iface,
gpointer iface_data);
+static void
+salut_conn_contact_caps_iface_init (gpointer, gpointer);
+
G_DEFINE_TYPE_WITH_CODE(SalutConnection,
salut_connection,
TP_TYPE_BASE_CONNECTION,
@@ -112,6 +117,9 @@ G_DEFINE_TYPE_WITH_CODE(SalutConnection,
tp_presence_mixin_simple_presence_iface_init);
G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CONNECTION_INTERFACE_AVATARS,
salut_connection_avatar_service_iface_init);
+ G_IMPLEMENT_INTERFACE
+ (SALUT_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_CAPABILITIES,
+ salut_conn_contact_caps_iface_init);
#ifdef ENABLE_OLPC
G_IMPLEMENT_INTERFACE (SALUT_TYPE_SVC_OLPC_BUDDY_INFO,
salut_connection_olpc_buddy_info_iface_init);
@@ -1654,6 +1662,180 @@ salut_connection_avatar_service_iface_init (gpointer g_iface,
#undef IMPLEMENT
}
+static void
+salut_free_enhanced_contact_capabilities (GPtrArray *caps)
+{
+ guint i;
+
+ for (i = 0; i < caps->len; i++)
+ {
+ GValue monster = {0, };
+
+ g_value_init (&monster, SALUT_STRUCT_TYPE_ENHANCED_CONTACT_CAPABILITY);
+ g_value_take_boxed (&monster, g_ptr_array_index (caps, i));
+ g_value_unset (&monster);
+ }
+
+ g_ptr_array_free (caps, TRUE);
+}
+
+/**
+ * salut_connection_get_handle_contact_capabilities
+ *
+ * Add capabilities of handle to the given GPtrArray
+ */
+static void
+salut_connection_get_handle_contact_capabilities (SalutConnection *self,
+ TpHandle handle, GPtrArray *arr)
+{
+ TpBaseConnection *base_conn = TP_BASE_CONNECTION (self);
+ TpChannelManagerIter iter;
+ TpChannelManager *manager;
+
+ tp_base_connection_channel_manager_iter_init (&iter, base_conn);
+ while (tp_base_connection_channel_manager_iter_next (&iter, &manager))
+ {
+ /* all channel managers must implement the capability interface */
+ g_assert (SALUT_IS_CAPS_CHANNEL_MANAGER (manager));
+
+ salut_caps_channel_manager_get_contact_capabilities (
+ SALUT_CAPS_CHANNEL_MANAGER (manager), self, handle, arr);
+ }
+}
+
+
+static void
+_emit_contact_capabilities_changed (SalutConnection *conn,
+ TpHandle handle,
+ GHashTable *old_caps,
+ GHashTable *new_caps)
+{
+ TpBaseConnection *base_conn = TP_BASE_CONNECTION (conn);
+ TpChannelManagerIter iter;
+ TpChannelManager *manager;
+ GPtrArray *ret;
+ gboolean diff = FALSE;
+
+ tp_base_connection_channel_manager_iter_init (&iter, base_conn);
+ while (tp_base_connection_channel_manager_iter_next (&iter, &manager))
+ {
+ gpointer per_channel_manager_caps_old = NULL;
+ gpointer per_channel_manager_caps_new = NULL;
+
+ /* all channel managers must implement the capability interface */
+ g_assert (SALUT_IS_CAPS_CHANNEL_MANAGER (manager));
+
+ if (old_caps != NULL)
+ per_channel_manager_caps_old = g_hash_table_lookup (old_caps, manager);
+ if (new_caps != NULL)
+ per_channel_manager_caps_new = g_hash_table_lookup (new_caps, manager);
+
+ if (salut_caps_channel_manager_capabilities_diff (
+ SALUT_CAPS_CHANNEL_MANAGER (manager), handle,
+ per_channel_manager_caps_old, per_channel_manager_caps_new))
+ {
+ diff = TRUE;
+ break;
+ }
+ }
+
+ /* Don't emit the D-Bus signal if there is no change */
+ if (! diff)
+ return;
+
+ ret = g_ptr_array_new ();
+
+ salut_connection_get_handle_contact_capabilities (conn, handle, ret);
+ salut_svc_connection_interface_contact_capabilities_emit_contact_capabilities_changed (
+ conn, ret);
+
+ salut_free_enhanced_contact_capabilities (ret);
+}
+
+/**
+ * salut_connection_set_self_capabilities
+ *
+ * Implements D-Bus method SetSelfCapabilities
+ * on interface
+ * org.freedesktop.Telepathy.Connection.Interface.ContactCapabilities
+ *
+ * @error: Used to return a pointer to a GError detailing any error
+ * that occurred, D-Bus will throw the error only if this
+ * function returns FALSE.
+ *
+ * Returns: TRUE if successful, FALSE if an error was thrown.
+ */
+static void
+salut_connection_set_self_capabilities (
+ SalutSvcConnectionInterfaceContactCapabilities *iface,
+ const GPtrArray *caps,
+ DBusGMethodInvocation *context)
+{
+ SalutConnection *self = SALUT_CONNECTION (iface);
+ TpBaseConnection *base = (TpBaseConnection *) self;
+ SalutConnectionPrivate *priv = SALUT_CONNECTION_GET_PRIVATE (self);
+ guint i;
+ GHashTable *save_caps;
+ GError *error = NULL;
+
+ TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
+
+ /* reset the caps, and fill with the given parameter but keep a backup for
+ * diffing: we don't want to emit a signal if nothing has changed */
+ save_caps = priv->self->per_channel_manager_caps;
+ priv->self->per_channel_manager_caps = NULL;
+
+ for (i = 0; i < caps->len; i++)
+ {
+ GHashTable *cap_to_add = g_ptr_array_index (caps, i);
+ TpChannelManagerIter iter;
+ TpChannelManager *manager;
+
+ tp_base_connection_channel_manager_iter_init (&iter, base);
+ while (tp_base_connection_channel_manager_iter_next (&iter, &manager))
+ {
+ /* all channel managers must implement the capability interface */
+ g_assert (SALUT_IS_CAPS_CHANNEL_MANAGER (manager));
+
+ salut_caps_channel_manager_add_capability (
+ SALUT_CAPS_CHANNEL_MANAGER (manager), self,
+ base->self_handle, cap_to_add);
+ }
+ }
+
+ if (!salut_self_set_caps (priv->self, "NODE", "HASH", "VER", &error))
+ {
+ salut_presence_cache_free_cache_entry (save_caps);
+ dbus_g_method_return_error (context, error);
+ return;
+ }
+
+ _emit_contact_capabilities_changed (self, base->self_handle,
+ save_caps,
+ priv->self->per_channel_manager_caps);
+ salut_presence_cache_free_cache_entry (save_caps);
+
+
+ salut_svc_connection_interface_contact_capabilities_return_from_set_self_capabilities
+ (context);
+}
+
+
+static void
+salut_conn_contact_caps_iface_init (gpointer g_iface, gpointer iface_data)
+{
+ SalutSvcConnectionInterfaceContactCapabilitiesClass *klass =
+ (SalutSvcConnectionInterfaceContactCapabilitiesClass *) g_iface;
+
+#define IMPLEMENT(x) \
+ salut_svc_connection_interface_contact_capabilities_implement_##x (\
+ klass, salut_connection_##x)
+ //IMPLEMENT(get_contact_capabilities);
+ IMPLEMENT(set_self_capabilities);
+#undef IMPLEMENT
+}
+
+
#ifdef ENABLE_OLPC
static GValue *
new_gvalue (GType type)
diff --git a/src/salut-presence-cache.c b/src/salut-presence-cache.c
new file mode 100644
index 0000000..c00b269
--- /dev/null
+++ b/src/salut-presence-cache.c
@@ -0,0 +1,105 @@
+/*
+ * salut-presence-cache.c - Salut's contact presence cache
+ * Copyright (C) 2005 Collabora Ltd.
+ * Copyright (C) 2005 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "salut-presence-cache.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#define DEBUG_FLAG SALUT_DEBUG_PRESENCE
+
+#include <gibber/gibber-namespaces.h>
+#include <telepathy-glib/channel-manager.h>
+#include <telepathy-glib/intset.h>
+
+#define DEBUG_FLAG SALUT_DEBUG_PRESENCE
+
+#include "salut-caps-channel-manager.h"
+#include "salut-caps-hash.h"
+#include "debug.h"
+
+static void
+free_caps_helper (gpointer key, gpointer value, gpointer user_data)
+{
+ SalutCapsChannelManager *manager = SALUT_CAPS_CHANNEL_MANAGER (key);
+ salut_caps_channel_manager_free_capabilities (manager, value);
+}
+
+void
+salut_presence_cache_free_cache_entry (
+ GHashTable *per_channel_manager_caps)
+{
+ if (per_channel_manager_caps == NULL)
+ return;
+
+ g_hash_table_foreach (per_channel_manager_caps, free_caps_helper,
+ NULL);
+ g_hash_table_destroy (per_channel_manager_caps);
+}
+
+static void
+copy_caps_helper (gpointer key, gpointer value, gpointer user_data)
+{
+ GHashTable *table_out = user_data;
+ SalutCapsChannelManager *manager = SALUT_CAPS_CHANNEL_MANAGER (key);
+ gpointer out;
+ salut_caps_channel_manager_copy_capabilities (manager, &out, value);
+ g_hash_table_insert (table_out, key, out);
+}
+
+void
+salut_presence_cache_copy_cache_entry (
+ GHashTable **out, GHashTable *in)
+{
+ *out = g_hash_table_new (NULL, NULL);
+ if (in != NULL)
+ g_hash_table_foreach (in, copy_caps_helper,
+ *out);
+}
+
+static void
+update_caps_helper (gpointer key, gpointer value, gpointer user_data)
+{
+ GHashTable *table_out = user_data;
+ SalutCapsChannelManager *manager = SALUT_CAPS_CHANNEL_MANAGER (key);
+ gpointer out;
+
+ out = g_hash_table_lookup (table_out, key);
+ if (out == NULL)
+ {
+ salut_caps_channel_manager_copy_capabilities (manager, &out, value);
+ g_hash_table_insert (table_out, key, out);
+ }
+ else
+ {
+ salut_caps_channel_manager_update_capabilities (manager, out, value);
+ }
+}
+
+void
+salut_presence_cache_update_cache_entry (
+ GHashTable *out, GHashTable *in)
+{
+ g_hash_table_foreach (in, update_caps_helper,
+ out);
+}
+
diff --git a/src/salut-presence-cache.h b/src/salut-presence-cache.h
new file mode 100644
index 0000000..40de8cc
--- /dev/null
+++ b/src/salut-presence-cache.h
@@ -0,0 +1,46 @@
+/*
+ * salut-presence-cache.h - Headers for Salut's contact presence cache
+ * Copyright (C) 2005-2008 Collabora Ltd.
+ * Copyright (C) 2005-2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __SALUT_PRESENCE_CACHE_H__
+#define __SALUT_PRESENCE_CACHE_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+/* loop on CapabilityInfo::per_channel_manager_caps and call
+ * salut_caps_channel_manager_free_capabilities */
+void salut_presence_cache_free_cache_entry (
+ GHashTable *per_channel_manager_caps);
+
+/* loop on CapabilityInfo::per_channel_manager_caps and call
+ * salut_caps_channel_manager_copy_capabilities */
+void salut_presence_cache_copy_cache_entry (GHashTable **out,
+ GHashTable *in);
+
+/* loop on CapabilityInfo::per_channel_manager_caps and call
+ * salut_caps_channel_manager_update_capabilities */
+void salut_presence_cache_update_cache_entry (GHashTable *out,
+ GHashTable *in);
+
+G_END_DECLS
+
+#endif /* __SALUT_PRESENCE_CACHE_H__ */
+
--
1.5.6.5
More information about the telepathy-commits
mailing list