static void tp_contact_factory_capabilities_changed_cb (TpConnection *connection, const GPtrArray *capabilities, gpointer user_data, GObject *weak_object) { EmpathyTpContactFactory *tp_factory = EMPATHY_TP_CONTACT_FACTORY (weak_object); guint i; for (i = 0; i < capabilities->len; i++) { GValueArray *values; guint handle; const gchar *channel_type; guint generic; guint specific; values = g_ptr_array_index (capabilities, i); handle = g_value_get_uint (g_value_array_get_nth (values, 0)); channel_type = g_value_get_string (g_value_array_get_nth (values, 1)); generic = g_value_get_uint (g_value_array_get_nth (values, 3)); specific = g_value_get_uint (g_value_array_get_nth (values, 5)); tp_contact_factory_update_capabilities (tp_factory, handle, channel_type, generic, specific); } }
static void tp_contact_factory_avatar_updated_cb (TpConnection *connection, guint handle, const gchar *new_token, gpointer user_data, GObject *tp_factory) { GArray *handles; if (tp_contact_factory_avatar_maybe_update (EMPATHY_TP_CONTACT_FACTORY (tp_factory), handle, new_token)) { /* Avatar was cached, nothing to do */ return; } DEBUG ("Need to request avatar for token %s", new_token); handles = g_array_new (FALSE, FALSE, sizeof (guint)); g_array_append_val (handles, handle); tp_cli_connection_interface_avatars_call_request_avatars (connection, -1, handles, tp_contact_factory_request_avatars_cb, NULL, NULL, tp_factory); g_array_free (handles, TRUE); }
static void tp_contact_factory_avatar_retrieved_cb (TpConnection *connection, guint handle, const gchar *token, const GArray *avatar_data, const gchar *mime_type, gpointer user_data, GObject *tp_factory) { EmpathyContact *contact; contact = tp_contact_factory_find_by_handle (EMPATHY_TP_CONTACT_FACTORY (tp_factory), handle); if (!contact) { return; } DEBUG ("Avatar retrieved for contact %s (%d)", empathy_contact_get_id (contact), handle); empathy_contact_load_avatar_data (contact, (guchar *) avatar_data->data, avatar_data->len, mime_type, token); }
static void tp_contact_factory_got_locations (TpConnection *tp_conn, GHashTable *locations, const GError *error, gpointer user_data, GObject *weak_object) { GHashTableIter iter; gpointer key, value; EmpathyTpContactFactory *tp_factory; tp_factory = EMPATHY_TP_CONTACT_FACTORY (user_data); if (error != NULL) { DEBUG ("Error: %s", error->message); return; } g_hash_table_iter_init (&iter, locations); while (g_hash_table_iter_next (&iter, &key, &value)) { guint handle = GPOINTER_TO_INT (key); GHashTable *location = value; tp_contact_factory_update_location (tp_factory, handle, location); } }
static void connection_ready_cb (TpConnection *connection, const GError *error, gpointer user_data) { EmpathyTpContactFactory *tp_factory = EMPATHY_TP_CONTACT_FACTORY (user_data); EmpathyTpContactFactoryPriv *priv = GET_PRIV (tp_factory); if (error != NULL) goto out; /* FIXME: This should be moved to TpContact */ tp_cli_connection_interface_avatars_connect_to_avatar_updated (priv->connection, tp_contact_factory_avatar_updated_cb, NULL, NULL, G_OBJECT (tp_factory), NULL); tp_cli_connection_interface_avatars_connect_to_avatar_retrieved (priv->connection, tp_contact_factory_avatar_retrieved_cb, NULL, NULL, G_OBJECT (tp_factory), NULL); if (tp_proxy_has_interface_by_id (connection, TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACT_CAPABILITIES)) { priv->contact_caps_supported = TRUE; tp_cli_connection_interface_contact_capabilities_connect_to_contact_capabilities_changed ( priv->connection, tp_contact_factory_contact_capabilities_changed_cb, NULL, NULL, G_OBJECT (tp_factory), NULL); } else { tp_cli_connection_interface_capabilities_connect_to_capabilities_changed (priv->connection, tp_contact_factory_capabilities_changed_cb, NULL, NULL, G_OBJECT (tp_factory), NULL); } tp_cli_connection_interface_avatars_call_get_avatar_requirements (priv->connection, -1, tp_contact_factory_got_avatar_requirements_cb, NULL, NULL, G_OBJECT (tp_factory)); if (!priv->contact_caps_supported) { tp_cli_dbus_properties_call_get (priv->connection, -1, TP_IFACE_CONNECTION_INTERFACE_REQUESTS, "RequestableChannelClasses", get_requestable_channel_classes_cb, NULL, NULL, G_OBJECT (tp_factory)); } out: g_object_unref (tp_factory); }
static void tp_contact_factory_contact_capabilities_changed_cb (TpConnection *connection, GHashTable *caps, gpointer user_data, GObject *weak_object) { EmpathyTpContactFactory *self = EMPATHY_TP_CONTACT_FACTORY (weak_object); update_contact_capabilities (self, caps); }
static void tp_contact_factory_location_updated_cb (TpConnection *tp_conn, guint handle, GHashTable *location, gpointer user_data, GObject *weak_object) { EmpathyTpContactFactory *tp_factory = EMPATHY_TP_CONTACT_FACTORY (weak_object); tp_contact_factory_update_location (tp_factory, handle, location); }
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_got_contact_capabilities (TpConnection *connection, GHashTable *caps, const GError *error, gpointer user_data, GObject *weak_object) { EmpathyTpContactFactory *self = EMPATHY_TP_CONTACT_FACTORY (weak_object); if (error != NULL) { DEBUG ("Error: %s", error->message); return; } update_contact_capabilities (self, caps); }
static void tp_contact_factory_got_known_avatar_tokens (TpConnection *connection, GHashTable *tokens, const GError *error, gpointer user_data, GObject *weak_object) { EmpathyTpContactFactory *tp_factory = EMPATHY_TP_CONTACT_FACTORY (weak_object); EmpathyTpContactFactoryPriv *priv = GET_PRIV (tp_factory); GArray *handles; GHashTableIter iter; gpointer key, value; if (error) { DEBUG ("Error: %s", error->message); return; } handles = g_array_new (FALSE, FALSE, sizeof (guint)); g_hash_table_iter_init (&iter, tokens); while (g_hash_table_iter_next (&iter, &key, &value)) { guint handle = GPOINTER_TO_UINT (key); const gchar *token = value; if (!tp_contact_factory_avatar_maybe_update (tp_factory, handle, token)) { g_array_append_val (handles, handle); } } DEBUG ("Got %d tokens, need to request %d avatars", g_hash_table_size (tokens), handles->len); /* Request needed avatars */ if (handles->len > 0) { tp_cli_connection_interface_avatars_call_request_avatars (priv->connection, -1, handles, tp_contact_factory_request_avatars_cb, NULL, NULL, G_OBJECT (tp_factory)); } g_array_free (handles, TRUE); }
static void tp_contact_factory_got_capabilities (TpConnection *connection, const GPtrArray *capabilities, const GError *error, gpointer user_data, GObject *weak_object) { EmpathyTpContactFactory *tp_factory; guint i; tp_factory = EMPATHY_TP_CONTACT_FACTORY (weak_object); if (error) { DEBUG ("Error: %s", error->message); /* FIXME Should set the capabilities of the contacts for which this request * originated to NONE */ return; } for (i = 0; i < capabilities->len; i++) { GValueArray *values; guint handle; const gchar *channel_type; guint generic; guint specific; values = g_ptr_array_index (capabilities, i); handle = g_value_get_uint (g_value_array_get_nth (values, 0)); channel_type = g_value_get_string (g_value_array_get_nth (values, 1)); generic = g_value_get_uint (g_value_array_get_nth (values, 2)); specific = g_value_get_uint (g_value_array_get_nth (values, 3)); tp_contact_factory_update_capabilities (tp_factory, handle, channel_type, generic, specific); } }
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); } }