static void
got_list_channel (EmpathyTpContactList *list,
		  TpChannel *channel)
{
	EmpathyTpContactListPriv *priv = GET_PRIV (list);
	const gchar *id;

	/* We requested that channel by providing TargetID property, so it's
	 * guaranteed that tp_channel_get_identifier will return it. */
	id = tp_channel_get_identifier (channel);

	/* TpChannel emits initial set of members just before being ready */
	if (!tp_strdiff (id, "stored")) {
		if (priv->stored != NULL)
			return;
		priv->stored = g_object_ref (channel);
		g_signal_connect (priv->stored, "group-members-changed",
				  G_CALLBACK (tp_contact_list_store_group_members_changed_cb),
				  list);
	} else if (!tp_strdiff (id, "publish")) {
		if (priv->publish != NULL)
			return;
		priv->publish = g_object_ref (channel);
		g_signal_connect (priv->publish, "group-members-changed",
				  G_CALLBACK (tp_contact_list_publish_group_members_changed_cb),
				  list);
	} else if (!tp_strdiff (id, "subscribe")) {
		if (priv->subscribe != NULL)
			return;
		priv->subscribe = g_object_ref (channel);
		g_signal_connect (priv->subscribe, "group-members-changed",
				  G_CALLBACK (tp_contact_list_subscribe_group_members_changed_cb),
				  list);
	}
}
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
contacts_added_to_group (EmpathyTpContactList *list,
			 TpChannel *channel,
			 GArray *added)
{
	EmpathyTpContactListPriv *priv = GET_PRIV (list);
	const gchar *group_name;
	guint i;

	group_name = tp_channel_get_identifier (channel);

	for (i = 0; i < added->len; i++) {
		EmpathyContact *contact;
		TpHandle handle;

		handle = g_array_index (added, TpHandle, i);
		contact = g_hash_table_lookup (priv->members,
					       GUINT_TO_POINTER (handle));
		if (contact == NULL) {
			continue;
		}

		DEBUG ("Contact %s (%d) added to group %s",
			empathy_contact_get_id (contact), handle, group_name);
		g_signal_emit_by_name (list, "groups-changed", contact,
				       group_name,
				       TRUE);
	}
}
コード例 #4
0
static void
handle_dbus_channel(TpSimpleHandler* /*handler*/,
	TpAccount* /*account*/,
	TpConnection* /*connection*/,
	GList* channels,
	GList* /*requests*/,
	gint64 /*user_action_time*/,
	TpHandleChannelsContext* context,
	gpointer user_data)
{
	UT_DEBUGMSG(("handle_dbus_channel()\n"));

	TelepathyAccountHandler* pHandler = reinterpret_cast<TelepathyAccountHandler*>(user_data);
	UT_return_if_fail(pHandler);

	for (GList* chan = channels; chan; chan = chan->next)
	{
		TpChannel* channel = TP_CHANNEL(chan->data);
		UT_continue_if_fail(channel);
		UT_DEBUGMSG((">>>>> incoming dbus channel: %s\n", tp_channel_get_identifier(channel)));

		if (tp_channel_get_channel_type_id(channel) != TP_IFACE_QUARK_CHANNEL_TYPE_DBUS_TUBE)
			continue;

		/* accept the channel */
		tp_cli_channel_type_dbus_tube_call_accept(channel, -1,
					TP_SOCKET_ACCESS_CONTROL_LOCALHOST,
					tube_accept_cb, user_data, NULL, NULL);
	}

	tp_handle_channels_context_accept(context);
}
コード例 #5
0
ファイル: empathy-tp-chat.c プロジェクト: james-w/empathy
const gchar *
empathy_tp_chat_get_id (EmpathyTpChat *chat)
{
	EmpathyTpChatPriv *priv = GET_PRIV (chat);

	g_return_val_if_fail (EMPATHY_IS_TP_CHAT (chat), NULL);

	return tp_channel_get_identifier (priv->channel);
}
コード例 #6
0
static void
file_transfer_channel_ready (TpChannel		*channel,
                             const GError	*in_error,
			     gpointer		 user_data)
{
	GError *error = NULL;

	handle_error (in_error);

	GHashTable *map = tp_channel_borrow_immutable_properties (channel);

	const char *filename = tp_asv_get_string (map,
			TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_FILENAME);
	guint64 size = tp_asv_get_uint64 (map,
			TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_SIZE, NULL);

	g_print ("New file transfer to %s -- `%s' (%llu bytes)\n",
			tp_channel_get_identifier (channel),
			filename, size);

	/* File transfers in Telepathy work by opening a socket to the
	 * Connection Manager and streaming the file over that socket.
	 * Let's find out what manner of sockets are supported by this CM */
	GHashTable *sockets = tp_asv_get_boxed (map,
		TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_AVAILABLE_SOCKET_TYPES,
		TP_HASH_TYPE_SUPPORTED_SOCKET_MAP);

	/* let's try for IPv4 */
	if (g_hash_table_lookup (sockets,
				GINT_TO_POINTER (TP_SOCKET_ADDRESS_TYPE_IPV4)))
	{
		g_print ("ipv4 supported\n");
	}
	else if (g_hash_table_lookup (sockets,
				GINT_TO_POINTER (TP_SOCKET_ADDRESS_TYPE_UNIX)))
	{
		struct ft_state *state = g_slice_new0 (struct ft_state);
		state->sa.sun_family = AF_UNIX;

		tp_cli_channel_type_file_transfer_connect_to_file_transfer_state_changed (
				channel, file_transfer_unix_state_changed_cb,
				state, NULL, NULL, &error);
		handle_error (error);

		GValue *value = tp_g_value_slice_new_static_string ("");

		/* set up the socket for providing the file */
		tp_cli_channel_type_file_transfer_call_provide_file (
				channel, -1, TP_SOCKET_ADDRESS_TYPE_UNIX,
				TP_SOCKET_ACCESS_CONTROL_LOCALHOST,
				value, file_transfer_unix_cb,
				state, NULL, NULL);

		tp_g_value_slice_free (value);
	}
}
コード例 #7
0
static void
_observer_new_channel_cb (AnerleyTpObserver *observer,
                          const gchar       *account_name,
                          TpChannel         *channel,
                          gpointer           userdata)
{
  g_debug (G_STRLOC ": New channel for %s on %s",
           tp_channel_get_identifier (channel),
           account_name);
}
コード例 #8
0
static void
join_cb (GObject *source,
    GAsyncResult *result,
    gpointer user_data)
{
  TpChannel *channel = TP_CHANNEL (source);
  GError *error = NULL;

  if (!tp_channel_join_finish (channel, result, &error))
    {
      DEBUG ("Failed to join chat (%s): %s",
          tp_channel_get_identifier (channel), error->message);
      g_error_free (error);
    }
}
コード例 #9
0
ファイル: polari-room.c プロジェクト: jwendell/polari
static void
update_identifier (PolariRoom *room)
{
  PolariRoomPrivate *priv = room->priv;
  const char *id = NULL;

  if (priv->channel)
    id = tp_channel_get_identifier (priv->channel);

  g_clear_pointer (&priv->display_name, g_free);
  if (id)
    priv->display_name = g_strdup (id + (id[0] == '#' ? 1 : 0));

  g_object_notify_by_pspec (G_OBJECT (room), props[PROP_DISPLAY_NAME]);
}
static void
tp_contact_list_group_invalidated_cb (TpChannel *channel,
				      guint      domain,
				      gint       code,
				      gchar     *message,
				      EmpathyTpContactList *list)
{
	EmpathyTpContactListPriv *priv = GET_PRIV (list);
	const gchar *group_name;

	group_name = tp_channel_get_identifier (channel);
	DEBUG ("Group %s invalidated. Message: %s", group_name, message);

	tp_contact_list_forget_group (list, channel);

	g_hash_table_remove (priv->groups, group_name);
}
コード例 #11
0
ファイル: msg.c プロジェクト: keis/charlatan
static void
channel_cb (ChVisitor *visitor,
            TpChannel *channel)
{
    const char *type = tp_channel_get_channel_type (channel);
    const char *ident = tp_channel_get_identifier (channel);
    char **userlist;

    // if this is a text channel probe it for pending messages
    if (!strcmp (type, TP_IFACE_CHANNEL_TYPE_TEXT))
    {
        // filter to only include given channels
        if ((userlist = users)) {
            for (; *userlist; userlist += 1) {
                if (!strcmp (ident, *userlist)) {
                    break;
                }
            }
            if (!*userlist) {
                return;
            }
        }

        if (list_messages) {
            ch_visitor_visit_channel_target (visitor, channel);
            return;
        }

        GQuark features[] = { TP_TEXT_CHANNEL_FEATURE_INCOMING_MESSAGES, 0};

        ch_visitor_incref (visitor);
        tp_proxy_prepare_async (channel,
                                features,
                                channel_ready,
                                visitor);
    } else {
        if (verbose > 0) {
            g_printerr ("ignored channel %s %s\n", ident, type);
        }
    }
}
コード例 #12
0
ファイル: visitor.c プロジェクト: keis/charlatan
static void
visit_contact_channel (GObject      *source,
                       GAsyncResult *result,
                       gpointer      user_data)
{
    ChChannelRequest *chreq = (ChChannelRequest*) user_data;
    ChVisitor *self = chreq->self;
    TpContact *contact = chreq->contact;
    g_free (chreq);

    const char *ident, *contact_ident;
    GError *error = NULL;
    GPtrArray *channels;

    if (!list_channels_finish (source, result, &channels, &error)) {
        g_printerr ("error listing channels: %s\n", error->message);
        return;
    }

    contact_ident = tp_contact_get_identifier (contact);

    // Try to find a matching channel among the already established channels
    for (unsigned int i = 0; i < channels->len; i++) {
        TpChannel *channel = g_ptr_array_index (channels, i);
        ident = tp_channel_get_identifier (channel);

        if (!strcmp (ident, contact_ident)) {
            self->visit_channel (self, channel);
            goto done;
        }
    }

    // Request a new channel
    request_channel (self, contact);

done:
    g_ptr_array_free (channels, TRUE);
    ch_visitor_decref (self);
}
static void
tp_contact_list_group_members_changed_cb (TpChannel     *channel,
					  gchar         *message,
					  GArray        *added,
					  GArray        *removed,
					  GArray        *local_pending,
					  GArray        *remote_pending,
					  guint          actor,
					  guint          reason,
					  EmpathyTpContactList *list)
{
	EmpathyTpContactListPriv  *priv = GET_PRIV (list);
	const gchar *group_name;
	guint i;

	contacts_added_to_group (list, channel, added);

	group_name = tp_channel_get_identifier (channel);

	for (i = 0; i < removed->len; i++) {
		EmpathyContact *contact;
		TpHandle handle;

		handle = g_array_index (removed, TpHandle, i);
		contact = g_hash_table_lookup (priv->members,
					       GUINT_TO_POINTER (handle));
		if (contact == NULL) {
			continue;
		}

		DEBUG ("Contact %s (%d) removed from group %s",
			empathy_contact_get_id (contact), handle, group_name);

		g_signal_emit_by_name (list, "groups-changed", contact,
				       group_name,
				       FALSE);
	}
}
コード例 #14
0
ファイル: msg.c プロジェクト: keis/charlatan
static void
channel_ready (GObject      *source,
               GAsyncResult *result,
               gpointer      user_data)
{
    ChVisitor *visitor = (ChVisitor*) user_data;
    TpChannel *channel;
    const gchar *ident;
    TpMessage *message;

    GError *error = NULL;
    if (!tp_proxy_prepare_finish (source, result, &error)) {
        g_printerr ("error loading channel: %s\n", error->message);
        return;
    }

    channel = TP_CHANNEL (source);
    ident = tp_channel_get_identifier (channel);

    if (verbose > 0) {
        g_printerr ("channel ready \"%s\" (type %s)\n",
                    ident,
                    tp_channel_get_channel_type (channel));
    }

    GList *messages, *iter;
    if (TP_IS_TEXT_CHANNEL (channel)) {
        messages = tp_text_channel_dup_pending_messages (
             TP_TEXT_CHANNEL (channel));

        for (iter = messages; iter; iter = iter->next) {
            TpMessage *message = TP_MESSAGE (iter->data);
            message_cb (message);
        }

        if (acknowledge) {
            tp_text_channel_ack_messages_async (TP_TEXT_CHANNEL (channel),
                                                messages,
                                                ack_messages_cb,
                                                NULL);
        }

        g_list_free_full (messages, g_object_unref);

        if (send_message && !has_sent_message_to (ident)) {
            message = tp_client_message_new_text(0, msg_buffer);
            g_ptr_array_add (messages_sent, g_strdup (ident));
            ch_visitor_incref (visitor);
            tp_text_channel_send_message_async (TP_TEXT_CHANNEL (channel),
                                                message,
                                                0,
                                                send_message_cb,
                                                visitor);
        }
    } else {
        g_printerr ("error loading channel: %s is not a text channel\n",
                    tp_channel_get_identifier (channel));
    }

    ch_visitor_decref (visitor);
}
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);
}