static void update_contact_capabilities (EmpathyTpContactFactory *self, GHashTable *caps) { GHashTableIter iter; gpointer key, value; g_hash_table_iter_init (&iter, caps); while (g_hash_table_iter_next (&iter, &key, &value)) { TpHandle handle = GPOINTER_TO_UINT (key); GPtrArray *classes = value; EmpathyContact *contact; EmpathyCapabilities capabilities; contact = tp_contact_factory_find_by_handle (self, handle); if (contact == NULL) continue; capabilities = empathy_contact_get_capabilities (contact); capabilities &= ~EMPATHY_CAPABILITIES_UNKNOWN; capabilities |= channel_classes_to_capabilities (classes, TRUE); DEBUG ("Changing capabilities for contact %s (%d) to %d", empathy_contact_get_id (contact), empathy_contact_get_handle (contact), capabilities); empathy_contact_set_capabilities (contact, capabilities); } }
static void get_requestable_channel_classes_cb (TpProxy *connection, const GValue *value, const GError *error, gpointer user_data, GObject *weak_object) { EmpathyTpContactFactory *self = EMPATHY_TP_CONTACT_FACTORY (weak_object); EmpathyTpContactFactoryPriv *priv = GET_PRIV (self); GPtrArray *classes; GList *l; EmpathyCapabilities capabilities; if (error != NULL) { DEBUG ("Error: %s", error->message); return; } classes = g_value_get_boxed (value); DEBUG ("ContactCapabilities is not implemented; use RCC"); capabilities = channel_classes_to_capabilities (classes, FALSE); if ((capabilities & EMPATHY_CAPABILITIES_FT) != 0) { DEBUG ("Assume all contacts support FT as CM implements it"); priv->can_request_ft = TRUE; } if ((capabilities & EMPATHY_CAPABILITIES_STREAM_TUBE) != 0) { DEBUG ("Assume all contacts support stream tubes as CM implements them"); priv->can_request_st = TRUE; } if (!priv->can_request_ft && !priv->can_request_st) return ; /* Update the capabilities of all contacts */ for (l = priv->contacts; l != NULL; l = g_list_next (l)) { EmpathyContact *contact = l->data; EmpathyCapabilities caps; caps = empathy_contact_get_capabilities (contact); /* ContactCapabilities is not supported; assume all contacts can do file * transfer if it's implemented in the CM */ if (priv->can_request_ft) caps |= EMPATHY_CAPABILITIES_FT; if (priv->can_request_st) caps |= EMPATHY_CAPABILITIES_STREAM_TUBE; empathy_contact_set_capabilities (contact, caps); } }
static void tp_contact_factory_update_capabilities (EmpathyTpContactFactory *tp_factory, guint handle, const gchar *channel_type, guint generic, guint specific) { EmpathyContact *contact; EmpathyCapabilities capabilities; contact = tp_contact_factory_find_by_handle (tp_factory, handle); if (!contact) { return; } capabilities = empathy_contact_get_capabilities (contact); capabilities &= ~EMPATHY_CAPABILITIES_UNKNOWN; if (strcmp (channel_type, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA) == 0) { capabilities &= ~EMPATHY_CAPABILITIES_AUDIO; capabilities &= ~EMPATHY_CAPABILITIES_VIDEO; if (specific & TP_CHANNEL_MEDIA_CAPABILITY_AUDIO) { capabilities |= EMPATHY_CAPABILITIES_AUDIO; } if (specific & TP_CHANNEL_MEDIA_CAPABILITY_VIDEO) { capabilities |= EMPATHY_CAPABILITIES_VIDEO; } } DEBUG ("Changing capabilities for contact %s (%d) to %d", empathy_contact_get_id (contact), empathy_contact_get_handle (contact), capabilities); empathy_contact_set_capabilities (contact, capabilities); }
static void tp_contact_factory_add_contact (EmpathyTpContactFactory *tp_factory, EmpathyContact *contact) { EmpathyTpContactFactoryPriv *priv = GET_PRIV (tp_factory); TpHandle self_handle; TpHandle handle; GArray handles = {(gchar *) &handle, 1}; EmpathyCapabilities caps; /* Keep a weak ref to that contact */ g_object_weak_ref (G_OBJECT (contact), tp_contact_factory_weak_notify, tp_factory); priv->contacts = g_list_prepend (priv->contacts, contact); /* The contact keeps a ref to its factory */ g_object_set_data_full (G_OBJECT (contact), "empathy-factory", g_object_ref (tp_factory), g_object_unref); caps = empathy_contact_get_capabilities (contact); /* Set the FT capability */ if (!priv->contact_caps_supported) { /* ContactCapabilities is not supported; assume all contacts can do file * transfer if it's implemented in the CM */ if (priv->can_request_ft) { caps |= EMPATHY_CAPABILITIES_FT; } /* Set the Stream Tube capability */ if (priv->can_request_st) { caps |= EMPATHY_CAPABILITIES_STREAM_TUBE; } } empathy_contact_set_capabilities (contact, caps); /* Set is-user property. Note that it could still be the handle is * different from the connection's self handle, in the case the handle * comes from a group interface. */ self_handle = tp_connection_get_self_handle (priv->connection); handle = empathy_contact_get_handle (contact); empathy_contact_set_is_user (contact, self_handle == handle); /* FIXME: This should be done by TpContact */ if (tp_proxy_has_interface_by_id (priv->connection, TP_IFACE_QUARK_CONNECTION_INTERFACE_AVATARS)) { tp_cli_connection_interface_avatars_call_get_known_avatar_tokens ( priv->connection, -1, &handles, tp_contact_factory_got_known_avatar_tokens, NULL, NULL, G_OBJECT (tp_factory)); } if (priv->contact_caps_supported) { tp_cli_connection_interface_contact_capabilities_call_get_contact_capabilities ( priv->connection, -1, &handles, tp_contact_factory_got_contact_capabilities, NULL, NULL, G_OBJECT (tp_factory)); } else if (tp_proxy_has_interface_by_id (priv->connection, TP_IFACE_QUARK_CONNECTION_INTERFACE_CAPABILITIES)) { tp_cli_connection_interface_capabilities_call_get_capabilities ( priv->connection, -1, &handles, tp_contact_factory_got_capabilities, NULL, NULL, G_OBJECT (tp_factory)); } DEBUG ("Contact added: %s (%d)", empathy_contact_get_id (contact), empathy_contact_get_handle (contact)); }
static void get_requestable_channel_classes_cb (TpProxy *connection, const GValue *value, const GError *error, gpointer user_data, GObject *weak_object) { EmpathyTpContactFactory *self = EMPATHY_TP_CONTACT_FACTORY (weak_object); EmpathyTpContactFactoryPriv *priv = GET_PRIV (self); GPtrArray *classes; guint i; GList *l; if (error != NULL) { DEBUG ("Error: %s", error->message); return; } classes = g_value_get_boxed (value); for (i = 0; i < classes->len; i++) { GValueArray *class_struct; GHashTable *fixed_prop; GValue *chan_type, *handle_type; class_struct = g_ptr_array_index (classes, i); fixed_prop = g_value_get_boxed (g_value_array_get_nth (class_struct, 0)); handle_type = g_hash_table_lookup (fixed_prop, TP_IFACE_CHANNEL ".TargetHandleType"); if (handle_type == NULL || g_value_get_uint (handle_type) != TP_HANDLE_TYPE_CONTACT) continue; chan_type = g_hash_table_lookup (fixed_prop, TP_IFACE_CHANNEL ".ChannelType"); if (chan_type == NULL) continue; if (!tp_strdiff (g_value_get_string (chan_type), TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER)) priv->can_request_ft = TRUE; else if (!tp_strdiff (g_value_get_string (chan_type), TP_IFACE_CHANNEL_TYPE_STREAM_TUBE)) priv->can_request_st = TRUE; } if (!priv->can_request_ft && !priv->can_request_st) return ; /* Update the capabilities of all contacts */ for (l = priv->contacts; l != NULL; l = g_list_next (l)) { EmpathyContact *contact = l->data; EmpathyCapabilities caps; caps = empathy_contact_get_capabilities (contact); if (priv->can_request_ft) caps |= EMPATHY_CAPABILITIES_FT; if (priv->can_request_st) caps |= EMPATHY_CAPABILITIES_STREAM_TUBE; empathy_contact_set_capabilities (contact, caps); } }