summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonny Lamb <jonny.lamb@collabora.co.uk>2012-05-02 11:36:36 +0100
committerJonny Lamb <jonny.lamb@collabora.co.uk>2012-05-02 12:14:32 +0100
commit41b053cdcc220687506d8922e129ef759d70fddb (patch)
tree45a89c51086a9e7b94c6dc6367645ae890152dde
parent1fafed8d0efac5075e7d681a9f80962ae0a8b3a3 (diff)
capabilities: implement UpdateCapabilities
I didn't bother touching AdvertiseCapabilities as old style caps are only going to be removed soon. Signed-off-by: Jonny Lamb <jonny.lamb@collabora.co.uk>
-rw-r--r--src/connection-capabilities.c106
-rw-r--r--src/connection-capabilities.h1
-rw-r--r--src/connection.c2
-rw-r--r--src/connection.h2
4 files changed, 108 insertions, 3 deletions
diff --git a/src/connection-capabilities.c b/src/connection-capabilities.c
index f2a557f..04cecfc 100644
--- a/src/connection-capabilities.c
+++ b/src/connection-capabilities.c
@@ -28,6 +28,7 @@
#include <telepathy-glib/gtypes.h>
#include <telepathy-glib/handle.h>
#include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/dbus.h>
#include "connection.h"
#include "debug.h"
@@ -208,6 +209,92 @@ haze_connection_advertise_capabilities (TpSvcConnectionInterfaceCapabilities *if
g_ptr_array_free (ret, TRUE);
}
+typedef enum {
+ CAPS_FLAGS_AUDIO = 1 << 0,
+ CAPS_FLAGS_VIDEO = 1 << 1,
+} CapsFlags;
+
+static void
+haze_connection_update_capabilities (TpSvcConnectionInterfaceContactCapabilities *iface,
+ const GPtrArray *clients,
+ DBusGMethodInvocation *context)
+{
+ HazeConnection *self = HAZE_CONNECTION (iface);
+ TpBaseConnection *base = (TpBaseConnection *) self;
+#ifdef ENABLE_MEDIA
+ guint i;
+ PurpleMediaCaps old_caps, caps;
+ GHashTableIter iter;
+ gpointer value;
+#endif
+
+ TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
+
+#ifdef ENABLE_MEDIA
+ caps = PURPLE_MEDIA_CAPS_NONE;
+ old_caps = purple_media_manager_get_ui_caps (
+ purple_media_manager_get ());
+
+ DEBUG ("enter");
+
+ /* go through all the clients and if they can do audio or video save
+ * it in the client_caps hash table */
+ for (i = 0; i < clients->len; i++)
+ {
+ GValueArray *va = g_ptr_array_index (clients, i);
+ const gchar *client_name = g_value_get_string (va->values + 0);
+ const GPtrArray *rccs = g_value_get_boxed (va->values + 1);
+ guint j;
+ CapsFlags flags = 0;
+
+ g_hash_table_remove (self->client_caps, client_name);
+
+ for (j = 0; j < rccs->len; j++)
+ {
+ GHashTable *class = g_ptr_array_index (rccs, i);
+
+ if (tp_strdiff (tp_asv_get_string (class, TP_PROP_CHANNEL_CHANNEL_TYPE),
+ TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA))
+ continue;
+
+ if (tp_asv_get_boolean (class,
+ TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_AUDIO, NULL))
+ flags |= CAPS_FLAGS_AUDIO;
+
+ if (tp_asv_get_boolean (class,
+ TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_VIDEO, NULL))
+ flags |= CAPS_FLAGS_VIDEO;
+ }
+
+ if (flags != 0)
+ {
+ g_hash_table_insert (self->client_caps, g_strdup (client_name),
+ GUINT_TO_POINTER (flags));
+ }
+ }
+
+ /* now we have an updated client_caps hash table, go through it and
+ * let libpurple know */
+ g_hash_table_iter_init (&iter, self->client_caps);
+ while (g_hash_table_iter_next (&iter, NULL, &value))
+ {
+ CapsFlags flags = GPOINTER_TO_UINT (value);
+
+ if (flags & CAPS_FLAGS_AUDIO)
+ caps |= PURPLE_MEDIA_CAPS_AUDIO;
+ if (flags & CAPS_FLAGS_VIDEO)
+ caps |= PURPLE_MEDIA_CAPS_VIDEO;
+ }
+
+ purple_media_manager_set_ui_caps (purple_media_manager_get(), caps);
+
+ _emit_capabilities_changed (self, base->self_handle, old_caps, caps);
+#endif
+
+ tp_svc_connection_interface_contact_capabilities_return_from_update_capabilities (
+ context);
+}
+
static const gchar *assumed_caps[] =
{
TP_IFACE_CHANNEL_TYPE_TEXT,
@@ -589,7 +676,7 @@ haze_connection_contact_capabilities_iface_init (gpointer g_iface,
#define IMPLEMENT(x) \
tp_svc_connection_interface_contact_capabilities_implement_##x (\
klass, haze_connection_##x)
- /*IMPLEMENT(update_capabilities);*/
+ IMPLEMENT(update_capabilities);
IMPLEMENT(get_contact_capabilities);
#undef IMPLEMENT
}
@@ -626,10 +713,23 @@ haze_connection_capabilities_class_init (GObjectClass *object_class)
void
haze_connection_capabilities_init (GObject *object)
{
- tp_contacts_mixin_add_contact_attributes_iface (G_OBJECT (object),
+ HazeConnection *self = HAZE_CONNECTION (object);
+
+ tp_contacts_mixin_add_contact_attributes_iface (object,
TP_IFACE_CONNECTION_INTERFACE_CAPABILITIES,
conn_capabilities_fill_contact_attributes);
- tp_contacts_mixin_add_contact_attributes_iface (G_OBJECT (object),
+ tp_contacts_mixin_add_contact_attributes_iface (object,
TP_IFACE_CONNECTION_INTERFACE_CONTACT_CAPABILITIES,
conn_capabilities_fill_contact_attributes_contact_caps);
+
+ self->client_caps = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free, NULL);
+}
+
+void
+haze_connection_capabilities_finalize (GObject *object)
+{
+ HazeConnection *self = HAZE_CONNECTION (object);
+
+ tp_clear_pointer (&self->client_caps, g_hash_table_unref);
}
diff --git a/src/connection-capabilities.h b/src/connection-capabilities.h
index 2d2e866..7764a31 100644
--- a/src/connection-capabilities.h
+++ b/src/connection-capabilities.h
@@ -29,5 +29,6 @@ void haze_connection_contact_capabilities_iface_init (gpointer g_iface,
gpointer iface_data);
void haze_connection_capabilities_class_init (GObjectClass *object_class);
void haze_connection_capabilities_init (GObject *object);
+void haze_connection_capabilities_finalize (GObject *object);
#endif
diff --git a/src/connection.c b/src/connection.c
index c903249..28eed06 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -721,6 +721,8 @@ haze_connection_finalize (GObject *object)
tp_contacts_mixin_finalize (object);
tp_presence_mixin_finalize (object);
+ haze_connection_capabilities_finalize (object);
+
g_strfreev (self->acceptable_avatar_mime_types);
g_free (priv->username);
g_free (priv->password);
diff --git a/src/connection.h b/src/connection.h
index a75732a..c69a7c1 100644
--- a/src/connection.h
+++ b/src/connection.h
@@ -62,6 +62,8 @@ struct _HazeConnection {
gchar **acceptable_avatar_mime_types;
+ GHashTable *client_caps;
+
/* Part of the hack for Jabber media caps */
gulong status_changed_id;