summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonny Lamb <jonny.lamb@collabora.co.uk>2012-05-01 11:06:42 +0100
committerJonny Lamb <jonny.lamb@collabora.co.uk>2012-05-01 11:06:42 +0100
commit04909550618339a33f6a5b40ac5e6176ca280972 (patch)
tree099f51361df05a1bd48d701d7acbbc8b6558536b
parent9379255451b6a4d805d070ee2eb4bca80f9a7993 (diff)
capabilities: implement ContactCapabilities
Signed-off-by: Jonny Lamb <jonny.lamb@collabora.co.uk>
-rw-r--r--src/connection-capabilities.c150
-rw-r--r--src/connection-capabilities.h2
-rw-r--r--src/connection.c3
3 files changed, 155 insertions, 0 deletions
diff --git a/src/connection-capabilities.c b/src/connection-capabilities.c
index 951dc02..f082d53 100644
--- a/src/connection-capabilities.c
+++ b/src/connection-capabilities.c
@@ -267,6 +267,61 @@ haze_connection_get_handle_capabilities (HazeConnection *self,
}
}
+static GPtrArray *
+haze_connection_get_handle_contact_capabilities (HazeConnection *self,
+ TpHandle handle)
+{
+ GPtrArray *arr = g_ptr_array_new ();
+ GValue monster = {0, };
+ GHashTable *fixed_properties;
+ GValue *channel_type_value;
+ GValue *target_handle_type_value;
+ gchar *text_allowed_properties[] =
+ {
+ TP_IFACE_CHANNEL ".TargetHandle",
+ NULL
+ };
+
+ if (0 == handle)
+ {
+ /* obsolete request for the connection's capabilities, do nothing */
+ return arr;
+ }
+
+ /* TODO: Check for presence */
+
+ /* TODO: do media */
+
+ g_value_init (&monster, TP_STRUCT_TYPE_REQUESTABLE_CHANNEL_CLASS);
+ g_value_take_boxed (&monster,
+ dbus_g_type_specialized_construct (
+ TP_STRUCT_TYPE_REQUESTABLE_CHANNEL_CLASS));
+
+ fixed_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify) tp_g_value_slice_free);
+
+ channel_type_value = tp_g_value_slice_new (G_TYPE_STRING);
+ g_value_set_static_string (channel_type_value, TP_IFACE_CHANNEL_TYPE_TEXT);
+ g_hash_table_insert (fixed_properties, TP_IFACE_CHANNEL ".ChannelType",
+ channel_type_value);
+
+ target_handle_type_value = tp_g_value_slice_new (G_TYPE_UINT);
+ g_value_set_uint (target_handle_type_value, TP_HANDLE_TYPE_CONTACT);
+ g_hash_table_insert (fixed_properties, TP_IFACE_CHANNEL ".TargetHandleType",
+ target_handle_type_value);
+
+ dbus_g_type_struct_set (&monster,
+ 0, fixed_properties,
+ 1, text_allowed_properties,
+ G_MAXUINT);
+
+ g_hash_table_unref (fixed_properties);
+
+ g_ptr_array_add (arr, g_value_get_boxed (&monster));
+
+ return arr;
+}
+
/**
* haze_connection_get_capabilities
*
@@ -351,6 +406,37 @@ conn_capabilities_fill_contact_attributes (GObject *obj,
g_ptr_array_free (array, TRUE);
}
+static void
+conn_capabilities_fill_contact_attributes_contact_caps (
+ GObject *obj,
+ const GArray *contacts,
+ GHashTable *attributes_hash)
+{
+ HazeConnection *self = HAZE_CONNECTION (obj);
+ guint i;
+
+ for (i = 0; i < contacts->len; i++)
+ {
+ TpHandle handle = g_array_index (contacts, TpHandle, i);
+ GPtrArray *array;
+
+ array = haze_connection_get_handle_contact_capabilities (self, handle);
+
+ if (array->len > 0)
+ {
+ GValue *val = tp_g_value_slice_new (
+ TP_ARRAY_TYPE_REQUESTABLE_CHANNEL_CLASS_LIST);
+
+ g_value_take_boxed (val, array);
+ tp_contacts_mixin_set_contact_attribute (attributes_hash,
+ handle, TP_IFACE_CONNECTION_INTERFACE_CONTACT_CAPABILITIES "/capabilities",
+ val);
+ }
+ else
+ g_ptr_array_free (array, TRUE);
+ }
+}
+
void
haze_connection_capabilities_iface_init (gpointer g_iface,
gpointer iface_data)
@@ -365,6 +451,67 @@ haze_connection_capabilities_iface_init (gpointer g_iface,
#undef IMPLEMENT
}
+static void
+free_rcc_list (GPtrArray *rccs)
+{
+ g_boxed_free (TP_ARRAY_TYPE_REQUESTABLE_CHANNEL_CLASS_LIST, rccs);
+}
+
+static void
+haze_connection_get_contact_capabilities (
+ TpSvcConnectionInterfaceContactCapabilities *svc,
+ const GArray *handles,
+ DBusGMethodInvocation *context)
+{
+ HazeConnection *self = HAZE_CONNECTION (svc);
+ TpBaseConnection *base = (TpBaseConnection *) self;
+ TpHandleRepoIface *contact_handles = tp_base_connection_get_handles (base,
+ TP_HANDLE_TYPE_CONTACT);
+ guint i;
+ GHashTable *ret;
+ GError *error = NULL;
+
+ TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
+
+ if (!tp_handles_are_valid (contact_handles, handles, FALSE, &error))
+ {
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+
+ ret = g_hash_table_new_full (NULL, NULL, NULL,
+ (GDestroyNotify) free_rcc_list);
+
+ for (i = 0; i < handles->len; i++)
+ {
+ TpHandle handle = g_array_index (handles, TpHandle, i);
+ GPtrArray *arr;
+
+ arr = haze_connection_get_handle_contact_capabilities (self, handle);
+ g_hash_table_insert (ret, GUINT_TO_POINTER (handle), arr);
+ }
+
+ tp_svc_connection_interface_contact_capabilities_return_from_get_contact_capabilities
+ (context, ret);
+
+ g_hash_table_unref (ret);
+}
+
+void
+haze_connection_contact_capabilities_iface_init (gpointer g_iface,
+ gpointer iface_data)
+{
+ TpSvcConnectionInterfaceContactCapabilitiesClass *klass = g_iface;
+
+#define IMPLEMENT(x) \
+ tp_svc_connection_interface_contact_capabilities_implement_##x (\
+ klass, haze_connection_##x)
+ /*IMPLEMENT(update_capabilities);*/
+ IMPLEMENT(get_contact_capabilities);
+#undef IMPLEMENT
+}
+
#ifdef ENABLE_MEDIA
static void
caps_changed_cb (PurpleBuddy *buddy,
@@ -400,4 +547,7 @@ haze_connection_capabilities_init (GObject *object)
tp_contacts_mixin_add_contact_attributes_iface (G_OBJECT (object),
TP_IFACE_CONNECTION_INTERFACE_CAPABILITIES,
conn_capabilities_fill_contact_attributes);
+ tp_contacts_mixin_add_contact_attributes_iface (G_OBJECT (object),
+ TP_IFACE_CONNECTION_INTERFACE_CONTACT_CAPABILITIES,
+ conn_capabilities_fill_contact_attributes_contact_caps);
}
diff --git a/src/connection-capabilities.h b/src/connection-capabilities.h
index b8bb4fd..2d2e866 100644
--- a/src/connection-capabilities.h
+++ b/src/connection-capabilities.h
@@ -25,6 +25,8 @@
void haze_connection_capabilities_iface_init (gpointer g_iface,
gpointer iface_data);
+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);
diff --git a/src/connection.c b/src/connection.c
index 3ec4c8e..c903249 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -75,6 +75,8 @@ G_DEFINE_TYPE_WITH_CODE(HazeConnection,
haze_connection_aliasing_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_AVATARS,
haze_connection_avatars_iface_init);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_CAPABILITIES,
+ haze_connection_contact_capabilities_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CAPABILITIES,
haze_connection_capabilities_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACTS,
@@ -105,6 +107,7 @@ static const gchar * implemented_interfaces[] = {
TP_IFACE_CONNECTION_INTERFACE_PRESENCE,
TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
TP_IFACE_CONNECTION_INTERFACE_CAPABILITIES,
+ TP_IFACE_CONNECTION_INTERFACE_CONTACT_CAPABILITIES,
TP_IFACE_CONNECTION_INTERFACE_CONTACTS,
/* TODO: This is a lie. Not all protocols supported by libpurple
* actually have the concept of a user-settable alias, but