diff options
author | Will Thompson <will.thompson@collabora.co.uk> | 2013-06-22 19:10:10 +0100 |
---|---|---|
committer | Will Thompson <will.thompson@collabora.co.uk> | 2013-06-23 16:06:05 +0100 |
commit | ddb451a71569bdd6b7d9a673d12e8e83eddb818e (patch) | |
tree | d98448bcb4322f7323ff12cf3ac72696c08ceacc /plugins | |
parent | e996dd8b1f69eb1367582916b92e702426dfdf25 (diff) |
console: turn it into an actual channel
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/console/channel-manager.c | 103 | ||||
-rw-r--r-- | plugins/console/channel-manager.h | 1 | ||||
-rw-r--r-- | plugins/console/plugin.c | 59 | ||||
-rw-r--r-- | plugins/console/sidecar.c | 61 |
4 files changed, 129 insertions, 95 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; } diff --git a/plugins/console/channel-manager.h b/plugins/console/channel-manager.h index a876a7b14..8ec4adc0a 100644 --- a/plugins/console/channel-manager.h +++ b/plugins/console/channel-manager.h @@ -31,6 +31,7 @@ struct _GabbleConsoleChannelManager { GObject parent; GabblePluginConnection *plugin_connection; + GQueue console_channels; }; GType gabble_console_channel_manager_get_type (void); diff --git a/plugins/console/plugin.c b/plugins/console/plugin.c index 222c58378..52386016d 100644 --- a/plugins/console/plugin.c +++ b/plugins/console/plugin.c @@ -53,62 +53,6 @@ gabble_console_plugin_class_init (GabbleConsolePluginClass *klass) { } -static void -gabble_console_plugin_create_sidecar_async ( - GabblePlugin *plugin, - const gchar *sidecar_interface, - GabblePluginConnection *connection, - WockySession *session, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *result = g_simple_async_result_new (G_OBJECT (plugin), - callback, user_data, - gabble_console_plugin_create_sidecar_async); - GabbleSidecar *sidecar = NULL; - - if (!tp_strdiff (sidecar_interface, GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE)) - { - sidecar = g_object_new (GABBLE_TYPE_CONSOLE_SIDECAR, - "connection", connection, - "session", session, - NULL); - } - else - { - g_simple_async_result_set_error (result, TP_ERROR, - TP_ERROR_NOT_IMPLEMENTED, "'%s' not implemented", sidecar_interface); - } - - if (sidecar != NULL) - g_simple_async_result_set_op_res_gpointer (result, sidecar, - g_object_unref); - - g_simple_async_result_complete_in_idle (result); - g_object_unref (result); -} - -static GabbleSidecar * -gabble_console_plugin_create_sidecar_finish ( - GabblePlugin *plugin, - GAsyncResult *result, - GError **error) -{ - GabbleSidecar *sidecar; - - if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), - error)) - return NULL; - - g_return_val_if_fail (g_simple_async_result_is_valid (result, - G_OBJECT (plugin), gabble_console_plugin_create_sidecar_async), NULL); - - sidecar = GABBLE_SIDECAR (g_simple_async_result_get_op_res_gpointer ( - G_SIMPLE_ASYNC_RESULT (result))); - - return g_object_ref (sidecar); -} - static GPtrArray * gabble_console_plugin_create_channel_managers (GabblePlugin *plugin, GabblePluginConnection *plugin_connection) @@ -132,9 +76,6 @@ plugin_iface_init ( iface->name = "XMPP console"; iface->version = PACKAGE_VERSION; - iface->sidecar_interfaces = sidecar_interfaces; - iface->create_sidecar_async = gabble_console_plugin_create_sidecar_async; - iface->create_sidecar_finish = gabble_console_plugin_create_sidecar_finish; iface->create_channel_managers = gabble_console_plugin_create_channel_managers; } diff --git a/plugins/console/sidecar.c b/plugins/console/sidecar.c index 5484a3ca0..b224b7f48 100644 --- a/plugins/console/sidecar.c +++ b/plugins/console/sidecar.c @@ -29,7 +29,6 @@ enum { PROP_0, - PROP_SESSION, PROP_SPEW }; @@ -50,23 +49,18 @@ struct _GabbleConsoleSidecarPrivate gulong sending_id; }; -static void sidecar_iface_init ( - gpointer g_iface, - gpointer data); static void console_iface_init ( gpointer g_iface, gpointer data); static void gabble_console_sidecar_set_spew ( GabbleConsoleSidecar *self, gboolean spew); +static void gabble_console_sidecar_close (TpBaseChannel *chan); G_DEFINE_TYPE_WITH_CODE (GabbleConsoleSidecar, gabble_console_sidecar, TP_TYPE_BASE_CHANNEL, - G_IMPLEMENT_INTERFACE (GABBLE_TYPE_SIDECAR, sidecar_iface_init); G_IMPLEMENT_INTERFACE (GABBLE_TYPE_SVC_GABBLE_PLUGIN_CONSOLE, console_iface_init); - G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES, - tp_dbus_properties_mixin_iface_init); ) static void @@ -79,6 +73,25 @@ gabble_console_sidecar_init (GabbleConsoleSidecar *self) self->priv->writer = wocky_xmpp_writer_new_no_stream (); } + +static void +gabble_console_sidecar_constructed (GObject *object) +{ + GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (object); + void (*chain_up)(GObject *) = + G_OBJECT_CLASS (gabble_console_sidecar_parent_class)->constructed; + + if (chain_up != NULL) + chain_up (object); + + self->priv->session = g_object_ref ( + gabble_plugin_connection_get_session ( + GABBLE_PLUGIN_CONNECTION ( + tp_base_channel_get_connection ( + TP_BASE_CHANNEL (self))))); + g_return_if_fail (self->priv->session != NULL); +} + static void gabble_console_sidecar_get_property ( GObject *object, @@ -110,11 +123,6 @@ gabble_console_sidecar_set_property ( switch (property_id) { - case PROP_SESSION: - g_assert (self->priv->session == NULL); /* construct-only */ - self->priv->session = g_value_dup_object (value); - break; - case PROP_SPEW: gabble_console_sidecar_set_spew (self, g_value_get_boolean (value)); break; @@ -145,22 +153,21 @@ static void gabble_console_sidecar_class_init (GabbleConsoleSidecarClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + TpBaseChannelClass *channel_class = TP_BASE_CHANNEL_CLASS (klass); static TpDBusPropertiesMixinPropImpl console_props[] = { { "SpewStanzas", "spew-stanzas", "spew-stanzas" }, { NULL }, }; + object_class->constructed = gabble_console_sidecar_constructed; object_class->get_property = gabble_console_sidecar_get_property; object_class->set_property = gabble_console_sidecar_set_property; object_class->dispose = gabble_console_sidecar_dispose; - g_type_class_add_private (klass, sizeof (GabbleConsoleSidecarPrivate)); + channel_class->channel_type = GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE; + channel_class->close = gabble_console_sidecar_close; - g_object_class_install_property (object_class, PROP_SESSION, - g_param_spec_object ("session", "Session", - "Wocky session", - WOCKY_TYPE_SESSION, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + g_type_class_add_private (klass, sizeof (GabbleConsoleSidecarPrivate)); g_object_class_install_property (object_class, PROP_SPEW, g_param_spec_boolean ("spew-stanzas", "SpewStanzas", @@ -171,25 +178,17 @@ gabble_console_sidecar_class_init (GabbleConsoleSidecarClass *klass) tp_dbus_properties_mixin_implement_interface (object_class, GABBLE_IFACE_QUARK_GABBLE_PLUGIN_CONSOLE, tp_dbus_properties_mixin_getter_gobject_properties, - /* FIXME: if we were feeling clever, we'd override the setter so that - * we can monitor the bus name of any application which sets - * SpewStanzas to TRUE and flip it back to false when that application - * dies. - * - * Alternatively, we could just replace this sidecar with a channel. - */ tp_dbus_properties_mixin_setter_gobject_properties, console_props); } -static void sidecar_iface_init ( - gpointer g_iface, - gpointer data) +static void +gabble_console_sidecar_close (TpBaseChannel *chan) { - GabbleSidecarInterface *iface = g_iface; + GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (chan); - iface->interface = GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE; - iface->get_immutable_properties = NULL; + gabble_console_sidecar_set_spew (self, FALSE); + tp_base_channel_destroyed (chan); } static gboolean |