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);
		}
	}
}
コード例 #6
0
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);
}
コード例 #7
0
ファイル: empathy-tp-chat.c プロジェクト: james-w/empathy
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;
}
コード例 #10
0
ファイル: empathy-tp-chat.c プロジェクト: james-w/empathy
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);
}