diff options
author | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2012-05-01 11:06:42 +0100 |
---|---|---|
committer | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2012-05-01 11:06:42 +0100 |
commit | 04909550618339a33f6a5b40ac5e6176ca280972 (patch) | |
tree | 099f51361df05a1bd48d701d7acbbc8b6558536b | |
parent | 9379255451b6a4d805d070ee2eb4bca80f9a7993 (diff) |
capabilities: implement ContactCapabilities
Signed-off-by: Jonny Lamb <jonny.lamb@collabora.co.uk>
-rw-r--r-- | src/connection-capabilities.c | 150 | ||||
-rw-r--r-- | src/connection-capabilities.h | 2 | ||||
-rw-r--r-- | src/connection.c | 3 |
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 |