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);
}
Ejemplo n.º 2
0
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));
	}
}
Ejemplo n.º 5
0
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;
}