static void add_to_members (EmpathyTpContactList *list, GArray *handles) { EmpathyTpContactListPriv *priv = GET_PRIV (list); GArray *request; guint i; if (handles->len == 0) return; request = g_array_new (FALSE, FALSE, sizeof (TpHandle)); for (i = 0; i < handles->len; i++) { TpHandle handle = g_array_index (handles, TpHandle, i); if (g_hash_table_lookup (priv->members, GUINT_TO_POINTER (handle))) continue; g_array_append_val (request, handle); } if (request->len > 0) { empathy_tp_contact_factory_get_from_handles (priv->connection, request->len, (TpHandle *) request->data, got_added_members_cb, NULL, NULL, G_OBJECT (list)); } g_array_unref (request); }
static void tp_chat_group_members_changed_cb (TpChannel *self, gchar *message, GArray *added, GArray *removed, GArray *local_pending, GArray *remote_pending, guint actor, guint reason, EmpathyTpChat *chat) { EmpathyTpChatPriv *priv = GET_PRIV (chat); EmpathyContact *contact; EmpathyContact *actor_contact = NULL; guint i; if (actor != 0) { actor_contact = chat_lookup_contact (chat, actor, FALSE); if (actor_contact == NULL) { /* FIXME: handle this a tad more gracefully: perhaps * the actor was a server op. We could use the * contact-ids detail of MembersChangedDetailed. */ DEBUG ("actor %u not a channel member", actor); } } /* Remove contacts that are not members anymore */ for (i = 0; i < removed->len; i++) { contact = chat_lookup_contact (chat, g_array_index (removed, TpHandle, i), TRUE); if (contact != NULL) { g_signal_emit_by_name (chat, "members-changed", contact, actor_contact, reason, message, FALSE); g_object_unref (contact); } } /* Request added contacts */ if (added->len > 0) { empathy_tp_contact_factory_get_from_handles (priv->factory, added->len, (TpHandle *) added->data, tp_chat_got_added_contacts_cb, NULL, NULL, G_OBJECT (chat)); } tp_chat_update_remote_contact (chat); if (actor_contact != NULL) { g_object_unref (actor_contact); } }
GList * empathy_contact_factory_get_from_handles (EmpathyContactFactory *factory, McAccount *account, const GArray *handles) { EmpathyTpContactFactory *tp_factory; tp_factory = empathy_contact_factory_get_tp_factory (factory, account); return empathy_tp_contact_factory_get_from_handles (tp_factory, handles); }
static void tp_contact_list_publish_group_members_changed_cb (TpChannel *channel, gchar *message, GArray *added, GArray *removed, GArray *local_pending, GArray *remote_pending, TpHandle actor, TpChannelGroupChangeReason reason, EmpathyTpContactList *list) { EmpathyTpContactListPriv *priv = GET_PRIV (list); guint i; /* We now send our presence to those contacts, remove them from pendings */ add_to_members (list, added); for (i = 0; i < added->len; i++) { tp_contact_list_remove_handle (list, priv->pendings, g_array_index (added, TpHandle, i)); } /* We refuse to send our presence to those contacts, remove from pendings */ for (i = 0; i < removed->len; i++) { TpHandle handle = g_array_index (removed, TpHandle, i); tp_contact_list_remove_handle (list, priv->pendings, handle); remove_from_member_if_needed (list, handle); } /* Those contacts want our presence, auto accept those that are already * member, otherwise add in pendings. */ if (local_pending->len > 0) { empathy_tp_contact_factory_get_from_handles (priv->connection, local_pending->len, (TpHandle *) local_pending->data, tp_contact_list_got_local_pending_cb, NULL, NULL, G_OBJECT (list)); } }
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; }