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); } }
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); }
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); }
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); } }
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); }
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); } }
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); }
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); } } }
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); } }
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); }