summaryrefslogtreecommitdiff
path: root/gabble
diff options
context:
space:
mode:
authorWill Thompson <will.thompson@collabora.co.uk>2011-06-22 14:33:52 +0100
committerWill Thompson <will.thompson@collabora.co.uk>2011-11-18 10:43:05 +0000
commit33f739934f7a8f01aaec71400afd584be24d4e72 (patch)
tree46c7a49165d599e1fd4b9093bdd816743f79b75c /gabble
parentc48ab1e75a698bda268a4331ed4d793af98ae3b8 (diff)
Add an XMPP console sidecar
It currently only supports sending an arbitrary IQ and getting the reply. Obviously this is for developer use only.
Diffstat (limited to 'gabble')
-rw-r--r--gabble/extensions/Gabble_Plugin_Console.xml66
-rw-r--r--gabble/extensions/Makefile.am1
-rw-r--r--gabble/extensions/all.xml1
-rw-r--r--gabble/plugins/Makefile.am5
-rw-r--r--gabble/plugins/console.c430
-rw-r--r--gabble/plugins/console.h85
6 files changed, 588 insertions, 0 deletions
diff --git a/gabble/extensions/Gabble_Plugin_Console.xml b/gabble/extensions/Gabble_Plugin_Console.xml
new file mode 100644
index 000000000..f00a24ad3
--- /dev/null
+++ b/gabble/extensions/Gabble_Plugin_Console.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" ?>
+<node name="/Gabble_Plugin_Console"
+ xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright © 2011 Collabora Ltd.</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.</p>
+
+ <p>This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.</p>
+
+ <p>You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.</p>
+ </tp:license>
+
+ <interface name="org.freedesktop.Telepathy.Gabble.Plugin.Console">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>A sidecar interface providing an XMPP console.</p>
+ </tp:docstring>
+
+ <method name="SendIQ" tp:name-for-bindings="Send_IQ">
+ <arg direction="in" name="Type" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The type of IQ request to send; either <code>"get"</code> or
+ <code>"set"</code>.
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="To" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The recipient for the IQ; or the empty string to send an IQ to the
+ server (with no recipient specified).
+ </tp:docstring>
+ </arg>
+ <arg direction="in" name="Body" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ An XML fragment for the body of the IQ, which MUST have exactly one
+ top-level element.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" name="Reply_Type" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ The type of IQ reply; either <code>"result"</code> or
+ <code>"error"</code>.
+ </tp:docstring>
+ </arg>
+ <arg direction="out" name="Body" type="s">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ An XML fragment for the body of the response, which MUST have between
+ zero and two top-level elements (the query element, an error element,
+ both, or neither).
+ </tp:docstring>
+ </arg>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ Hai.
+ </tp:docstring>
+ </method>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/gabble/extensions/Makefile.am b/gabble/extensions/Makefile.am
index feee4e790..10cab4308 100644
--- a/gabble/extensions/Makefile.am
+++ b/gabble/extensions/Makefile.am
@@ -5,6 +5,7 @@ EXTRA_DIST = \
Channel_Type_FileTransfer_Future.xml \
Connection_Future.xml \
Connection_Interface_Gabble_Decloak.xml \
+ Gabble_Plugin_Console.xml \
Gabble_Plugin_Gateways.xml \
Gabble_Plugin_Test.xml \
OLPC_Activity_Properties.xml \
diff --git a/gabble/extensions/all.xml b/gabble/extensions/all.xml
index cb368ef9e..90f52a89b 100644
--- a/gabble/extensions/all.xml
+++ b/gabble/extensions/all.xml
@@ -40,6 +40,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA</p>
<xi:include href="Connection_Interface_Gabble_Decloak.xml"/>
<xi:include href="Connection_Future.xml"/>
+<xi:include href="Gabble_Plugin_Console.xml"/>
<xi:include href="Gabble_Plugin_Gateways.xml"/>
<xi:include href="Gabble_Plugin_Test.xml"/>
diff --git a/gabble/plugins/Makefile.am b/gabble/plugins/Makefile.am
index 97f87a4c5..5d4715be1 100644
--- a/gabble/plugins/Makefile.am
+++ b/gabble/plugins/Makefile.am
@@ -1,6 +1,7 @@
plugindir = $(libdir)/telepathy/gabble-0
installable_plugins = \
+ console.la \
gateways.la
test_only_plugins = \
@@ -45,6 +46,10 @@ gateways_la_SOURCES = \
gateways.c \
gateways.h
+console_la_SOURCES = \
+ console.c \
+ console.h
+
AM_CFLAGS = $(ERROR_CFLAGS) \
-I $(top_srcdir) -I $(top_builddir) \
@DBUS_CFLAGS@ @GLIB_CFLAGS@ @WOCKY_CFLAGS@ @TP_GLIB_CFLAGS@ \
diff --git a/gabble/plugins/console.c b/gabble/plugins/console.c
new file mode 100644
index 000000000..47375f774
--- /dev/null
+++ b/gabble/plugins/console.c
@@ -0,0 +1,430 @@
+/* XML console plugin
+ *
+ * Copyright © 2011 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "console.h"
+
+#include "config.h"
+
+#include <string.h>
+
+#include <telepathy-glib/telepathy-glib.h>
+
+#include <wocky/wocky-xmpp-error.h>
+#include <wocky/wocky-utils.h>
+#include <wocky/wocky-xmpp-reader.h>
+#include <wocky/wocky-xmpp-writer.h>
+
+#include "extensions/extensions.h"
+
+#include <gabble/gabble.h>
+
+/*************************
+ * Plugin implementation *
+ *************************/
+
+static guint debug = 0;
+
+#define DEBUG(format, ...) \
+G_STMT_START { \
+ if (debug != 0) \
+ g_debug ("%s: " format, G_STRFUNC, ## __VA_ARGS__); \
+} G_STMT_END
+
+static const GDebugKey debug_keys[] = {
+ { "console", 1 },
+ { NULL, 0 }
+};
+
+static void plugin_iface_init (
+ gpointer g_iface,
+ gpointer data);
+
+static const gchar * const sidecar_interfaces[] = {
+ GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE,
+ NULL
+};
+
+G_DEFINE_TYPE_WITH_CODE (GabbleConsolePlugin, gabble_console_plugin,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GABBLE_TYPE_PLUGIN, plugin_iface_init);
+ )
+
+static void
+gabble_console_plugin_init (GabbleConsolePlugin *self)
+{
+}
+
+static void
+gabble_console_plugin_class_init (GabbleConsolePluginClass *klass)
+{
+}
+
+static void
+gabble_console_plugin_create_sidecar (
+ GabblePlugin *plugin,
+ const gchar *sidecar_interface,
+ GabbleConnection *connection,
+ WockySession *session,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result = g_simple_async_result_new (G_OBJECT (plugin),
+ callback, user_data,
+ /* sic: all plugins share gabble_plugin_create_sidecar_finish() so we
+ * need to use the same source tag.
+ */
+ gabble_plugin_create_sidecar);
+ 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_ERRORS,
+ 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 void
+plugin_iface_init (
+ gpointer g_iface,
+ gpointer data G_GNUC_UNUSED)
+{
+ GabblePluginInterface *iface = g_iface;
+
+ iface->name = "XMPP console";
+ iface->version = PACKAGE_VERSION;
+ iface->sidecar_interfaces = sidecar_interfaces;
+ iface->create_sidecar = gabble_console_plugin_create_sidecar;
+}
+
+GabblePlugin *
+gabble_plugin_create (void)
+{
+ debug = g_parse_debug_string (g_getenv ("GABBLE_DEBUG"), debug_keys,
+ G_N_ELEMENTS (debug_keys) - 1);
+ DEBUG ("loaded");
+
+ return g_object_new (GABBLE_TYPE_CONSOLE_PLUGIN,
+ NULL);
+}
+
+/**************************
+ * Sidecar implementation *
+ **************************/
+
+enum {
+ PROP_0,
+ PROP_CONNECTION,
+ PROP_SESSION
+};
+
+struct _GabbleConsoleSidecarPrivate
+{
+ WockySession *session;
+ TpBaseConnection *connection;
+ WockyXmppReader *reader;
+ WockyXmppWriter *writer;
+};
+
+static void sidecar_iface_init (
+ gpointer g_iface,
+ gpointer data);
+
+static void console_iface_init (
+ gpointer g_iface,
+ gpointer data);
+
+G_DEFINE_TYPE_WITH_CODE (GabbleConsoleSidecar, gabble_console_sidecar,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GABBLE_TYPE_SIDECAR, sidecar_iface_init);
+ G_IMPLEMENT_INTERFACE (GABBLE_TYPE_SVC_GABBLE_PLUGIN_CONSOLE,
+ console_iface_init);
+ )
+
+static void
+gabble_console_sidecar_init (GabbleConsoleSidecar *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GABBLE_TYPE_CONSOLE_SIDECAR,
+ GabbleConsoleSidecarPrivate);
+ self->priv->reader = wocky_xmpp_reader_new_no_stream ();
+ self->priv->writer = wocky_xmpp_writer_new_no_stream ();
+}
+
+static void
+gabble_console_sidecar_set_property (
+ GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (object);
+
+ switch (property_id)
+ {
+ case PROP_CONNECTION:
+ g_assert (self->priv->connection == NULL); /* construct-only */
+ self->priv->connection = g_value_dup_object (value);
+ break;
+
+ case PROP_SESSION:
+ g_assert (self->priv->session == NULL); /* construct-only */
+ self->priv->session = g_value_dup_object (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ }
+}
+
+static void
+gabble_console_sidecar_dispose (GObject *object)
+{
+ void (*chain_up) (GObject *) =
+ G_OBJECT_CLASS (gabble_console_sidecar_parent_class)->dispose;
+ GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (object);
+
+ tp_clear_object (&self->priv->connection);
+ tp_clear_object (&self->priv->reader);
+ tp_clear_object (&self->priv->writer);
+ tp_clear_object (&self->priv->session);
+
+ if (chain_up != NULL)
+ chain_up (object);
+}
+
+static void
+gabble_console_sidecar_class_init (GabbleConsoleSidecarClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->set_property = gabble_console_sidecar_set_property;
+ object_class->dispose = gabble_console_sidecar_dispose;
+
+ g_type_class_add_private (klass, sizeof (GabbleConsoleSidecarPrivate));
+
+ g_object_class_install_property (object_class, PROP_CONNECTION,
+ g_param_spec_object ("connection", "Connection",
+ "Gabble connection",
+ GABBLE_TYPE_CONNECTION,
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ 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));
+}
+
+static void sidecar_iface_init (
+ gpointer g_iface,
+ gpointer data)
+{
+ GabbleSidecarInterface *iface = g_iface;
+
+ iface->interface = GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE;
+ iface->get_immutable_properties = NULL;
+}
+
+static void
+return_from_send_iq (
+ GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (source);
+ DBusGMethodInvocation *context = user_data;
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+ GError *error = NULL;
+
+ if (g_simple_async_result_propagate_error (simple, &error))
+ {
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ }
+ else
+ {
+ WockyStanza *reply = g_simple_async_result_get_op_res_gpointer (simple);
+ WockyStanzaSubType sub_type;
+ const guint8 *body;
+ gsize length;
+
+ wocky_stanza_get_type_info (reply, NULL, &sub_type);
+ wocky_xmpp_writer_write_stanza (self->priv->writer, reply, &body, &length);
+
+ /* woop woop */
+ gabble_svc_gabble_plugin_console_return_from_send_iq (context,
+ sub_type == WOCKY_STANZA_SUB_TYPE_RESULT ? "result" : "error",
+ (const gchar *) body);
+ }
+}
+
+static void
+console_iq_reply_cb (
+ GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ WockyPorter *porter = WOCKY_PORTER (source);
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+ GError *error = NULL;
+ WockyStanza *reply = wocky_porter_send_iq_finish (porter, result, &error);
+
+ if (reply != NULL)
+ {
+ g_simple_async_result_set_op_res_gpointer (simple, reply, g_object_unref);
+ }
+ else
+ {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+}
+
+static gboolean
+get_iq_type (const gchar *type_str,
+ WockyStanzaSubType *sub_type_out,
+ GError **error)
+{
+ if (!wocky_strdiff (type_str, "get"))
+ {
+ *sub_type_out = WOCKY_STANZA_SUB_TYPE_GET;
+ return TRUE;
+ }
+
+ if (!wocky_strdiff (type_str, "set"))
+ {
+ *sub_type_out = WOCKY_STANZA_SUB_TYPE_SET;
+ return TRUE;
+ }
+
+ g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
+ "Type must be 'get' or 'set', not '%s'", type_str);
+ return FALSE;
+}
+
+static gboolean
+validate_jid (const gchar **to,
+ GError **error)
+{
+ if (tp_str_empty (*to))
+ {
+ *to = NULL;
+ return TRUE;
+ }
+
+ if (wocky_decode_jid (*to, NULL, NULL, NULL))
+ return TRUE;
+
+ g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
+ "'%s' is not a valid (or empty) JID", *to);
+ return FALSE;
+}
+
+static gboolean
+parse_body_fragment (
+ GabbleConsoleSidecar *self,
+ const gchar *body,
+ WockyNodeTree **fragment_out,
+ GError **error)
+{
+ GabbleConsoleSidecarPrivate *priv = self->priv;
+ WockyStanza *stanza;
+
+ wocky_xmpp_reader_reset (priv->reader);
+ wocky_xmpp_reader_push (priv->reader, (const guint8 *) body, strlen (body));
+
+ *error = wocky_xmpp_reader_get_error (priv->reader);
+
+ if (*error != NULL)
+ return FALSE;
+
+ stanza = wocky_xmpp_reader_pop_stanza (priv->reader);
+
+ if (stanza == NULL)
+ {
+ g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
+ "Incomplete stanza! Bad person.");
+ return FALSE;
+ }
+
+ *fragment_out = (WockyNodeTree *) stanza;
+ return TRUE;
+}
+
+static void
+console_send_iq (
+ GabbleSvcGabblePluginConsole *sidecar,
+ const gchar *type_str,
+ const gchar *to,
+ const gchar *body,
+ DBusGMethodInvocation *context)
+{
+ GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (sidecar);
+ WockyPorter *porter = wocky_session_get_porter (self->priv->session);
+ WockyStanzaSubType sub_type;
+ WockyNodeTree *fragment;
+ GError *error = NULL;
+
+ if (get_iq_type (type_str, &sub_type, &error) &&
+ validate_jid (&to, &error) &&
+ parse_body_fragment (self, body, &fragment, &error))
+ {
+ GSimpleAsyncResult *simple = g_simple_async_result_new (G_OBJECT (self),
+ return_from_send_iq, context, console_send_iq);
+ WockyStanza *stanza = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, sub_type,
+ NULL, to, NULL);
+
+ wocky_node_add_node_tree (wocky_stanza_get_top_node (stanza), fragment);
+ wocky_porter_send_iq_async (porter, stanza, NULL, console_iq_reply_cb, simple);
+ g_object_unref (fragment);
+ }
+ else
+ {
+ DEBUG ("%s", error->message);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ }
+}
+
+static void
+console_iface_init (
+ gpointer klass,
+ gpointer data G_GNUC_UNUSED)
+{
+#define IMPLEMENT(x) gabble_svc_gabble_plugin_console_implement_##x (\
+ klass, console_##x)
+ IMPLEMENT (send_iq);
+#undef IMPLEMENT
+}
diff --git a/gabble/plugins/console.h b/gabble/plugins/console.h
new file mode 100644
index 000000000..e3e2c0304
--- /dev/null
+++ b/gabble/plugins/console.h
@@ -0,0 +1,85 @@
+/* XML console plugin
+ *
+ * Copyright © 2011 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <glib-object.h>
+
+#include <gio/gio.h>
+#include <wocky/wocky-session.h>
+
+typedef struct _GabbleConsolePlugin GabbleConsolePlugin;
+typedef struct _GabbleConsolePluginClass GabbleConsolePluginClass;
+typedef struct _GabbleConsolePluginPrivate GabbleConsolePluginPrivate;
+
+struct _GabbleConsolePlugin {
+ GObject parent;
+ GabbleConsolePluginPrivate *priv;
+};
+
+struct _GabbleConsolePluginClass {
+ GObjectClass parent;
+};
+
+GType gabble_console_plugin_get_type (void);
+
+#define GABBLE_TYPE_CONSOLE_PLUGIN \
+ (gabble_console_plugin_get_type ())
+#define GABBLE_CONSOLE_PLUGIN(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GABBLE_TYPE_CONSOLE_PLUGIN, \
+ GabbleConsolePlugin))
+#define GABBLE_CONSOLE_PLUGIN_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GABBLE_TYPE_CONSOLE_PLUGIN, \
+ GabbleConsolePluginClass))
+#define GABBLE_IS_CONSOLE_PLUGIN(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GABBLE_TYPE_CONSOLE_PLUGIN))
+#define GABBLE_IS_CONSOLE_PLUGIN_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GABBLE_TYPE_CONSOLE_PLUGIN))
+#define GABBLE_CONSOLE_PLUGIN_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), GABBLE_TYPE_CONSOLE_PLUGIN, \
+ GabbleConsolePluginClass))
+
+typedef struct _GabbleConsoleSidecar GabbleConsoleSidecar;
+typedef struct _GabbleConsoleSidecarClass GabbleConsoleSidecarClass;
+typedef struct _GabbleConsoleSidecarPrivate GabbleConsoleSidecarPrivate;
+
+struct _GabbleConsoleSidecar {
+ GObject parent;
+ GabbleConsoleSidecarPrivate *priv;
+};
+
+struct _GabbleConsoleSidecarClass {
+ GObjectClass parent;
+};
+
+GType gabble_console_sidecar_get_type (void);
+
+#define GABBLE_TYPE_CONSOLE_SIDECAR \
+ (gabble_console_sidecar_get_type ())
+#define GABBLE_CONSOLE_SIDECAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GABBLE_TYPE_CONSOLE_SIDECAR, \
+ GabbleConsoleSidecar))
+#define GABBLE_CONSOLE_SIDECAR_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GABBLE_TYPE_CONSOLE_SIDECAR, \
+ GabbleConsoleSidecarClass))
+#define GABBLE_IS_CONSOLE_SIDECAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GABBLE_TYPE_CONSOLE_SIDECAR))
+#define GABBLE_IS_CONSOLE_SIDECAR_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GABBLE_TYPE_CONSOLE_SIDECAR))
+#define GABBLE_CONSOLE_SIDECAR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), GABBLE_TYPE_CONSOLE_SIDECAR, \
+ GabbleConsoleSidecarClass))