static gboolean add_member (GObject *object, TpHandle member, const gchar *message, GError **error) { ExampleCallableMediaChannel *self = EXAMPLE_CALLABLE_MEDIA_CHANNEL (object); TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (self->priv->conn, TP_HANDLE_TYPE_CONTACT); /* In connection managers that supported the RequestChannel method for * streamed media channels, it would be necessary to support adding the * called contact to the members of an outgoing call. However, in this * legacy-free example, we don't support that usage, so the only use for * AddMembers is to accept an incoming call. */ if (member == self->group.self_handle && tp_handle_set_is_member (self->group.local_pending, member)) { /* We're in local-pending, move to members to accept. */ TpIntSet *set = tp_intset_new_containing (member); GHashTableIter iter; gpointer v; g_assert (self->priv->progress == PROGRESS_CALLING); g_message ("SIGNALLING: send: Accepting incoming call from %s", tp_handle_inspect (contact_repo, self->priv->handle)); self->priv->progress = PROGRESS_ACTIVE; tp_group_mixin_change_members (object, "", set /* added */, NULL /* nobody removed */, NULL /* nobody added to local pending */, NULL /* nobody added to remote pending */, member /* actor */, TP_CHANNEL_GROUP_CHANGE_REASON_NONE); tp_intset_destroy (set); g_hash_table_iter_init (&iter, self->priv->streams); while (g_hash_table_iter_next (&iter, NULL, &v)) { /* we accept the proposed stream direction... */ example_callable_media_stream_accept_proposed_direction (v); /* ... and the stream tries to connect */ example_callable_media_stream_connect (v); } return TRUE; } /* Otherwise it's a meaningless request, so reject it. */ g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, "Cannot add handle %u to channel", member); return FALSE; }
static void fetion_contact_list_set_group_members_async (TpBaseContactList *contact_list, const gchar *group, TpHandleSet *contacts, GAsyncReadyCallback callback, gpointer user_data) { FetionContactList *self = FETION_CONTACT_LIST (contact_list); FetionConnection *conn = FETION_CONNECTION (self->priv->conn); HybridAccount *account = conn->priv->account; HybridGroup *dest_group = hybrid_blist_find_group_by_name(account, group); if (dest_group == NULL) return ; // the group must existed TpHandleSet *added = tp_handle_set_new (account->contact_repo); TpHandleSet *removed = tp_handle_set_new (account->contact_repo); TpIntsetFastIter iter; TpHandle member; tp_intset_fast_iter_init (&iter, tp_handle_set_peek (contacts)); while (tp_intset_fast_iter_next (&iter, &member)) { HybridBuddy* buddy = hybrid_blist_find_buddy_by_handle(account,member); if (buddy == NULL) continue; // must existed HybridGroup *origin_group = buddy->parent; if (origin_group == dest_group) continue; if(!account->proto->info->im_ops->buddy_move(account,buddy,dest_group)) continue; tp_handle_set_add (added, member); } tp_intset_fast_iter_init (&iter, tp_handle_set_peek (account->contacts)); HybridGroup *default_group = hybrid_blist_find_group(account, "0"); g_assert (default_group != NULL); while (tp_intset_fast_iter_next (&iter, &member)) { if (tp_handle_set_is_member (contacts, member)) continue; HybridBuddy* buddy = hybrid_blist_find_buddy_by_handle(account,member); if (buddy == NULL) continue; // must existed HybridGroup *origin_group = buddy->parent; if (origin_group != dest_group) continue; if(!account->proto->info->im_ops->buddy_move(account,buddy,default_group)) continue; tp_handle_set_add (removed, member); } if (!tp_handle_set_is_empty (added)) tp_base_contact_list_groups_changed (contact_list, added, &group, 1, NULL, 0); if (!tp_handle_set_is_empty (removed)) tp_base_contact_list_groups_changed (contact_list, removed, NULL, 0, &group, 1); tp_handle_set_destroy (added); tp_handle_set_destroy (removed); tp_simple_async_report_success_in_idle ((GObject *) self, callback, user_data, fetion_contact_list_set_group_members_async); }