summaryrefslogtreecommitdiff
path: root/plugins/console/channel-manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/console/channel-manager.c')
-rw-r--r--plugins/console/channel-manager.c103
1 files changed, 98 insertions, 5 deletions
diff --git a/plugins/console/channel-manager.c b/plugins/console/channel-manager.c
index 44f4a8b6d..b2a17902d 100644
--- a/plugins/console/channel-manager.c
+++ b/plugins/console/channel-manager.c
@@ -21,6 +21,7 @@
#include "console/channel-manager.h"
#include "extensions/extensions.h"
+#include "console/sidecar.h"
static void channel_manager_iface_init (gpointer, gpointer);
@@ -80,6 +81,23 @@ gabble_console_channel_manager_get_property (
}
}
+
+static void
+gabble_console_channel_manager_dispose (
+ GObject *object)
+{
+ GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (object);
+ TpBaseChannel *channel;
+
+ while ((channel = g_queue_peek_head (&self->console_channels)) != NULL)
+ {
+ tp_base_channel_close (channel);
+ }
+
+ G_OBJECT_CLASS (gabble_console_channel_manager_parent_class)->dispose (object);
+}
+
+
static void
gabble_console_channel_manager_class_init (GabbleConsoleChannelManagerClass *klass)
{
@@ -87,6 +105,7 @@ gabble_console_channel_manager_class_init (GabbleConsoleChannelManagerClass *kla
oclass->set_property = gabble_console_channel_manager_set_property;
oclass->get_property = gabble_console_channel_manager_get_property;
+ oclass->dispose = gabble_console_channel_manager_dispose;
g_object_class_install_property (oclass, PROP_CONNECTION,
g_param_spec_object ("plugin-connection", "Gabble Plugin Connection",
@@ -95,6 +114,13 @@ gabble_console_channel_manager_class_init (GabbleConsoleChannelManagerClass *kla
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
}
+
+static const gchar * const allowed[] = {
+ TP_PROP_CHANNEL_CHANNEL_TYPE,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
+ NULL
+};
+
static void
gabble_console_channel_manager_type_foreach_channel_class (GType type,
TpChannelManagerTypeChannelClassFunc func,
@@ -110,6 +136,77 @@ gabble_console_channel_manager_type_foreach_channel_class (GType type,
g_hash_table_unref (table);
}
+
+static void
+console_channel_closed_cb (
+ GabbleConsoleSidecar *channel,
+ gpointer user_data)
+{
+ GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (user_data);
+
+ tp_channel_manager_emit_channel_closed_for_object (self,
+ TP_EXPORTABLE_CHANNEL (channel));
+
+ if (g_queue_remove (&self->console_channels, channel))
+ {
+ g_object_unref (channel);
+ }
+}
+
+
+static gboolean
+gabble_console_channel_manager_create_channel (
+ TpChannelManager *manager,
+ gpointer request_token,
+ GHashTable *request_properties)
+{
+ GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (manager);
+ TpBaseChannel *channel = NULL;
+ GError *error = NULL;
+ GSList *request_tokens;
+
+ if (tp_strdiff (tp_asv_get_string (request_properties,
+ TP_IFACE_CHANNEL ".ChannelType"),
+ GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE))
+ return FALSE;
+
+ if (tp_asv_get_uint32 (request_properties,
+ TP_IFACE_CHANNEL ".TargetHandleType", NULL) != 0)
+ {
+ g_set_error (&error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED,
+ "Console channels can't have a target handle");
+ goto error;
+ }
+
+ if (tp_channel_manager_asv_has_unknown_properties (request_properties,
+ allowed,
+ allowed,
+ &error))
+ goto error;
+
+ channel = g_object_new (GABBLE_TYPE_CONSOLE_SIDECAR,
+ "connection", self->plugin_connection,
+ NULL);
+ tp_base_channel_register (channel);
+ g_signal_connect (channel, "closed", (GCallback) console_channel_closed_cb,
+ self);
+ g_queue_push_tail (&self->console_channels, channel);
+
+ request_tokens = g_slist_prepend (NULL, request_token);
+ tp_channel_manager_emit_new_channel (self,
+ TP_EXPORTABLE_CHANNEL (channel), request_tokens);
+ g_slist_free (request_tokens);
+
+ return TRUE;
+
+error:
+ tp_channel_manager_emit_request_failed (self, request_token,
+ error->domain, error->code, error->message);
+ g_error_free (error);
+ return TRUE;
+}
+
+
static void
channel_manager_iface_init (gpointer g_iface,
gpointer iface_data)
@@ -117,9 +214,5 @@ channel_manager_iface_init (gpointer g_iface,
TpChannelManagerIface *iface = g_iface;
iface->type_foreach_channel_class = gabble_console_channel_manager_type_foreach_channel_class;
-
- /* not requestable. */
- iface->ensure_channel = NULL;
- iface->create_channel = NULL;
- iface->request_channel = NULL;
+ iface->create_channel = gabble_console_channel_manager_create_channel;
}