diff options
Diffstat (limited to 'plugins/console/channel-manager.c')
-rw-r--r-- | plugins/console/channel-manager.c | 103 |
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; } |