static void tp_contact_list_rename_group (EmpathyContactList *list, const gchar *old_group_name, const gchar *new_group_name) { EmpathyTpContactListPriv *priv = GET_PRIV (list); TpChannel *channel; const TpIntSet *members; GArray *handles; channel = g_hash_table_lookup (priv->groups, old_group_name); if (channel == NULL) { return; } DEBUG ("rename group %s to %s", old_group_name, new_group_name); /* Remove all members and close the old channel */ members = tp_channel_group_get_members (channel); handles = tp_intset_to_array (members); tp_cli_channel_interface_group_call_remove_members (channel, -1, handles, NULL, NULL, NULL, NULL, NULL); tp_cli_channel_call_close (channel, -1, NULL, NULL, NULL, NULL); tp_contact_list_group_add (EMPATHY_TP_CONTACT_LIST (list), new_group_name, handles); }
static void tp_streamed_media_update_status (EmpathyTpStreamedMedia *call) { EmpathyTpStreamedMediaPriv *priv = GET_PRIV (call); TpHandle self_handle; const TpIntSet *set; TpIntSetIter iter; g_object_ref (call); self_handle = tp_channel_group_get_self_handle (priv->channel); set = tp_channel_group_get_members (priv->channel); tp_intset_iter_init (&iter, set); while (tp_intset_iter_next (&iter)) { if (priv->status == EMPATHY_TP_STREAMED_MEDIA_STATUS_PENDING && ((priv->is_incoming && iter.element == self_handle) || (!priv->is_incoming && iter.element != self_handle))) { priv->status = EMPATHY_TP_STREAMED_MEDIA_STATUS_ACCEPTED; g_object_notify (G_OBJECT (call), "status"); } } g_object_unref (call); }
static void tp_contact_list_forget_group (EmpathyTpContactList *list, TpChannel *channel) { EmpathyTpContactListPriv *priv = GET_PRIV (list); const TpIntSet *members; TpIntSetIter iter; const gchar *group_name; group_name = tp_channel_get_identifier (channel); /* Signal that all members are not in that group anymore */ members = tp_channel_group_get_members (channel); tp_intset_iter_init (&iter, members); while (tp_intset_iter_next (&iter)) { EmpathyContact *contact; contact = g_hash_table_lookup (priv->members, GUINT_TO_POINTER (iter.element)); if (contact == NULL) { continue; } DEBUG ("Contact %s (%d) removed from group %s", empathy_contact_get_id (contact), iter.element, group_name); g_signal_emit_by_name (list, "groups-changed", contact, group_name, FALSE); } }
static void remove_from_member_if_needed (EmpathyTpContactList *list, TpHandle handle) { /* remove contact from members if it's not in publish and subscribe */ EmpathyTpContactListPriv *priv = GET_PRIV (list); const TpIntSet *members; members = tp_channel_group_get_members (priv->subscribe); if (tp_intset_is_member (members, handle)) return; members = tp_channel_group_get_remote_pending (priv->subscribe); if (tp_intset_is_member (members, handle)) return; members = tp_channel_group_get_members (priv->publish); if (tp_intset_is_member (members, handle)) return; tp_contact_list_remove_handle (list, priv->members, handle); }
static void tp_contact_list_got_local_pending_cb (TpConnection *connection, guint n_contacts, EmpathyContact * const * contacts, guint n_failed, const TpHandle *failed, const GError *error, gpointer user_data, GObject *list) { EmpathyTpContactListPriv *priv = GET_PRIV (list); guint i; if (error) { DEBUG ("Error: %s", error->message); return; } for (i = 0; i < n_contacts; i++) { EmpathyContact *contact = contacts[i]; TpHandle handle; const gchar *message; TpChannelGroupChangeReason reason; const TpIntSet *members, *remote_pending; handle = empathy_contact_get_handle (contact); members = tp_channel_group_get_members (priv->subscribe); remote_pending = tp_channel_group_get_remote_pending (priv->subscribe); if (tp_intset_is_member (members, handle) || tp_intset_is_member (remote_pending, handle)) { GArray handles = {(gchar *) &handle, 1}; /* This contact is already subscribed, or user requested * to subscribe, auto accept. */ tp_cli_channel_interface_group_call_add_members (priv->publish, -1, &handles, NULL, NULL, NULL, NULL, NULL); } else if (tp_channel_group_get_local_pending_info (priv->publish, handle, NULL, &reason, &message)) { /* Add contact to pendings */ g_hash_table_insert (priv->pendings, GUINT_TO_POINTER (handle), g_object_ref (contact)); g_signal_emit_by_name (list, "pendings-changed", contact, contact, reason, message, TRUE); } } }
static void contact_list_channel_ready (TpChannel *channel, const GError *in_error, gpointer user_data) { char **argv = (char **) user_data; GError *error = NULL; handle_error (in_error); g_print (" > contact_list_channel_ready\n"); g_signal_connect (channel, "group-members-changed", G_CALLBACK (group_members_changed_cb), argv); const TpIntSet *members = tp_channel_group_get_members (channel); GArray *handles = tp_intset_to_array (members); g_print (" channel contains %i members\n", handles->len); iterate_contacts (channel, handles, argv); g_array_free (handles, TRUE); }
static void tp_chat_got_added_contacts_cb (EmpathyTpContactFactory *factory, guint n_contacts, EmpathyContact * const * contacts, guint n_failed, const TpHandle *failed, const GError *error, gpointer user_data, GObject *chat) { EmpathyTpChatPriv *priv = GET_PRIV (chat); guint i; const TpIntSet *members; TpHandle handle; EmpathyContact *contact; if (error) { DEBUG ("Error: %s", error->message); return; } members = tp_channel_group_get_members (priv->channel); for (i = 0; i < n_contacts; i++) { contact = contacts[i]; handle = empathy_contact_get_handle (contact); /* Make sure the contact is still member */ if (tp_intset_is_member (members, handle)) { priv->members = g_list_prepend (priv->members, g_object_ref (contact)); g_signal_emit_by_name (chat, "members-changed", contact, NULL, 0, NULL, TRUE); } } tp_chat_update_remote_contact (EMPATHY_TP_CHAT (chat)); tp_chat_check_if_ready (EMPATHY_TP_CHAT (chat)); }
static void tp_contact_list_remove_group (EmpathyContactList *list, const gchar *group_name) { EmpathyTpContactListPriv *priv = GET_PRIV (list); TpChannel *channel; const TpIntSet *members; GArray *handles; channel = g_hash_table_lookup (priv->groups, group_name); if (channel == NULL) { return; } DEBUG ("remove group %s", group_name); /* Remove all members and close the channel */ members = tp_channel_group_get_members (channel); handles = tp_intset_to_array (members); tp_cli_channel_interface_group_call_remove_members (channel, -1, handles, NULL, NULL, NULL, NULL, NULL); tp_cli_channel_call_close (channel, -1, NULL, NULL, NULL, NULL); g_array_unref (handles); }
static GList * tp_contact_list_get_groups (EmpathyContactList *list, EmpathyContact *contact) { EmpathyTpContactListPriv *priv = GET_PRIV (list); GList *ret = NULL; GHashTableIter iter; gpointer group_name; gpointer channel; TpHandle handle; handle = empathy_contact_get_handle (contact); g_hash_table_iter_init (&iter, priv->groups); while (g_hash_table_iter_next (&iter, &group_name, &channel)) { const TpIntSet *members; members = tp_channel_group_get_members (channel); if (tp_intset_is_member (members, handle)) { ret = g_list_prepend (ret, g_strdup (group_name)); } } return ret; }
static GObject * tp_chat_constructor (GType type, guint n_props, GObjectConstructParam *props) { GObject *chat; EmpathyTpChatPriv *priv; TpConnection *connection; TpHandle handle; chat = G_OBJECT_CLASS (empathy_tp_chat_parent_class)->constructor (type, n_props, props); priv = GET_PRIV (chat); connection = tp_channel_borrow_connection (priv->channel); priv->factory = empathy_tp_contact_factory_dup_singleton (connection); g_signal_connect (priv->channel, "invalidated", G_CALLBACK (tp_chat_invalidated_cb), chat); if (tp_proxy_has_interface_by_id (priv->channel, TP_IFACE_QUARK_CHANNEL_INTERFACE_GROUP)) { const TpIntSet *members; GArray *handles; /* Get self contact from the group's self handle */ handle = tp_channel_group_get_self_handle (priv->channel); empathy_tp_contact_factory_get_from_handle (priv->factory, handle, tp_chat_got_self_contact_cb, NULL, NULL, chat); /* Get initial member contacts */ members = tp_channel_group_get_members (priv->channel); handles = tp_intset_to_array (members); empathy_tp_contact_factory_get_from_handles (priv->factory, handles->len, (TpHandle *) handles->data, tp_chat_got_added_contacts_cb, NULL, NULL, chat); g_signal_connect (priv->channel, "group-members-changed", G_CALLBACK (tp_chat_group_members_changed_cb), chat); } else { /* Get the self contact from the connection's self handle */ handle = tp_connection_get_self_handle (connection); empathy_tp_contact_factory_get_from_handle (priv->factory, handle, tp_chat_got_self_contact_cb, NULL, NULL, chat); /* Get the remote contact */ handle = tp_channel_get_handle (priv->channel, NULL); empathy_tp_contact_factory_get_from_handle (priv->factory, handle, tp_chat_got_remote_contact_cb, NULL, NULL, chat); } if (tp_proxy_has_interface_by_id (priv->channel, TP_IFACE_QUARK_PROPERTIES_INTERFACE)) { tp_cli_properties_interface_call_list_properties (priv->channel, -1, tp_chat_list_properties_cb, NULL, NULL, G_OBJECT (chat)); tp_cli_properties_interface_connect_to_properties_changed (priv->channel, tp_chat_properties_changed_cb, NULL, NULL, G_OBJECT (chat), NULL); tp_cli_properties_interface_connect_to_property_flags_changed (priv->channel, tp_chat_property_flags_changed_cb, NULL, NULL, G_OBJECT (chat), NULL); } return chat; }
static void tp_contact_list_group_ready_cb (TpChannel *channel, const GError *error, gpointer list) { EmpathyTpContactListPriv *priv = GET_PRIV (list); TpChannel *old_group; const gchar *group_name; const TpIntSet *members; GArray *arr; if (error) { DEBUG ("Error: %s", error->message); g_object_unref (channel); return; } group_name = tp_channel_get_identifier (channel); /* If there's already a group with this name in the table, we can't * just let it be replaced. Replacing it causes it to be unreffed, * which causes it to be invalidated (see * <https://bugs.freedesktop.org/show_bug.cgi?id=22119>), which causes * it to be removed from the hash table again, which causes it to be * unreffed again. */ old_group = g_hash_table_lookup (priv->groups, group_name); if (old_group != NULL) { DEBUG ("Discarding old group %s (%p)", group_name, old_group); g_hash_table_steal (priv->groups, group_name); tp_contact_list_forget_group (list, old_group); g_object_unref (old_group); } /* Pass the reference on the TpChannel to priv->groups */ g_hash_table_insert (priv->groups, (gpointer) group_name, channel); DEBUG ("Group %s added", group_name); g_signal_connect (channel, "group-members-changed", G_CALLBACK (tp_contact_list_group_members_changed_cb), list); g_signal_connect (channel, "invalidated", G_CALLBACK (tp_contact_list_group_invalidated_cb), list); if (priv->add_to_group) { GArray *handles; handles = g_hash_table_lookup (priv->add_to_group, group_name); if (handles) { DEBUG ("Adding initial members to group %s", group_name); tp_cli_channel_interface_group_call_add_members (channel, -1, handles, NULL, NULL, NULL, NULL, NULL); g_hash_table_remove (priv->add_to_group, group_name); } } /* Get initial members of the group */ members = tp_channel_group_get_members (channel); g_assert (members != NULL); arr = tp_intset_to_array (members); contacts_added_to_group (list, channel, arr); g_array_unref (arr); }