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 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_stream_tube_channel_constructed (GObject *obj) { TpStreamTubeChannel *self = (TpStreamTubeChannel *) obj; void (*chain_up) (GObject *) = ((GObjectClass *) tp_stream_tube_channel_parent_class)->constructed; TpChannel *chan = (TpChannel *) obj; GHashTable *props; GError *err = NULL; if (chain_up != NULL) chain_up (obj); if (tp_channel_get_channel_type_id (chan) != TP_IFACE_QUARK_CHANNEL_TYPE_STREAM_TUBE) { GError error = { TP_DBUS_ERRORS, TP_DBUS_ERROR_INCONSISTENT, "Channel is not a stream tube" }; DEBUG ("Channel is not a stream tube: %s", tp_channel_get_channel_type ( chan)); tp_proxy_invalidate (TP_PROXY (self), &error); return; } props = _tp_channel_get_immutable_properties (TP_CHANNEL (self)); if (tp_asv_get_string (props, TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE) == NULL) { GError error = { TP_DBUS_ERRORS, TP_DBUS_ERROR_INCONSISTENT, "Tube doesn't have StreamTube.Service property" }; DEBUG ("%s", error.message); tp_proxy_invalidate (TP_PROXY (self), &error); return; } /* Tube.Parameters is immutable for incoming tubes. For outgoing ones, * it's defined when offering the tube. */ if (!tp_channel_get_requested (TP_CHANNEL (self))) { GHashTable *params; params = tp_asv_get_boxed (props, TP_PROP_CHANNEL_INTERFACE_TUBE_PARAMETERS, TP_HASH_TYPE_STRING_VARIANT_MAP); if (params == NULL) { DEBUG ("Incoming tube doesn't have Tube.Parameters property"); self->priv->parameters = tp_asv_new (NULL, NULL); } else { self->priv->parameters = g_boxed_copy ( TP_HASH_TYPE_STRING_VARIANT_MAP, params); } } tp_cli_channel_type_stream_tube_connect_to_connection_closed ( TP_CHANNEL (self), connection_closed_cb, NULL, NULL, G_OBJECT (self), &err); if (err != NULL) { DEBUG ("Failed to connect to ConnectionClosed signal: %s", err->message); g_error_free (err); } }