[glib] application: Add dbus register/unregister hooks
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] application: Add dbus register/unregister hooks
- Date: Tue, 29 May 2012 17:11:45 +0000 (UTC)
commit 4979c1d075e08bcdc7a6569afae2052dac5eea81
Author: Christian Persch <chpe gnome org>
Date: Sat May 5 16:52:28 2012 +0200
application: Add dbus register/unregister hooks
When the application is using its D-Bus backend, it is useful to be able
to export extra D-Bus objects at the right time, i.e. *before* the application
tries to own the bus name. This is accomplished here by adding a hook
in GApplicationClass for this; and a corresponding hook that will be called
on unregistration to undo whatever the register hook did.
Bug #675509.
gio/gapplication.c | 36 ++++++++++
gio/gapplication.h | 10 +++-
gio/gapplicationimpl-dbus.c | 15 ++++-
gio/tests/Makefile.am | 4 +
gio/tests/gapplication-example-dbushooks.c | 99 ++++++++++++++++++++++++++++
5 files changed, 162 insertions(+), 2 deletions(-)
---
diff --git a/gio/gapplication.c b/gio/gapplication.c
index 32341cf..1172a59 100644
--- a/gio/gapplication.c
+++ b/gio/gapplication.c
@@ -159,6 +159,14 @@
* </xi:include>
* </programlisting>
* </example>
+ *
+ * <example id="gapplication-example-dbushooks"><title>Using extra D-Bus hooks with a GApplication</title>
+ * <programlisting>
+ * <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gapplication-example-dbushooks.c">
+ * <xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback>
+ * </xi:include>
+ * </programlisting>
+ * </example>
*/
/**
@@ -190,6 +198,16 @@
* g_application_run() if the use-count is non-zero. Since 2.32,
* GApplication is iterating the main context directly and is not
* using @run_mainloop anymore
+ * @dbus_register: invoked locally during registration, if the application is
+ * using its D-Bus backend. You can use this to export extra objects on the
+ * bus, that need to exist before the application tries to own the bus name.
+ * The function is passed the #GDBusConnection to to session bus, and the
+ * object path that #GApplication will use to export is D-Bus API.
+ * If this function returns %TRUE, registration will proceed; otherwise
+ * registration will abort. Since: 2.34
+ * @dbus_unregister: invoked locally during unregistration, if the application
+ * is using its D-Bus backend. Use this to undo anything done by the
+ * @dbus_register vfunc. Since: 2.34
*
* Virtual function table for #GApplication.
*
@@ -506,6 +524,22 @@ g_application_real_add_platform_data (GApplication *application,
{
}
+static gboolean
+g_application_real_dbus_register (GApplication *application,
+ GDBusConnection *connection,
+ const gchar *object_path,
+ GError **error)
+{
+ return TRUE;
+}
+
+static void
+g_application_real_dbus_unregister (GApplication *application,
+ GDBusConnection *connection,
+ const gchar *object_path)
+{
+}
+
/* GObject implementation stuff {{{1 */
static void
g_application_set_property (GObject *object,
@@ -682,6 +716,8 @@ g_application_class_init (GApplicationClass *class)
class->command_line = g_application_real_command_line;
class->local_command_line = g_application_real_local_command_line;
class->add_platform_data = g_application_real_add_platform_data;
+ class->dbus_register = g_application_real_dbus_register;
+ class->dbus_unregister = g_application_real_dbus_unregister;
g_object_class_install_property (object_class, PROP_APPLICATION_ID,
g_param_spec_string ("application-id",
diff --git a/gio/gapplication.h b/gio/gapplication.h
index f5d912f..087682e 100644
--- a/gio/gapplication.h
+++ b/gio/gapplication.h
@@ -90,8 +90,16 @@ struct _GApplicationClass
void (* run_mainloop) (GApplication *application);
void (* shutdown) (GApplication *application);
+ gboolean (* dbus_register) (GApplication *application,
+ GDBusConnection *connection,
+ const gchar *object_path,
+ GError **error);
+ void (* dbus_unregister) (GApplication *application,
+ GDBusConnection *connection,
+ const gchar *object_path);
+
/*< private >*/
- gpointer padding[11];
+ gpointer padding[9];
};
GType g_application_get_type (void) G_GNUC_CONST;
diff --git a/gio/gapplicationimpl-dbus.c b/gio/gapplicationimpl-dbus.c
index df3f103..1248d0f 100644
--- a/gio/gapplicationimpl-dbus.c
+++ b/gio/gapplicationimpl-dbus.c
@@ -97,7 +97,7 @@ struct _GApplicationImpl
gboolean properties_live;
gboolean primary;
- gpointer app;
+ GApplication *app;
};
@@ -228,6 +228,7 @@ g_application_impl_attempt_primary (GApplicationImpl *impl,
const static GDBusInterfaceVTable vtable = {
g_application_impl_method_call,
};
+ GApplicationClass *app_class = G_APPLICATION_GET_CLASS (impl->app);
GVariant *reply;
guint32 rval;
@@ -271,6 +272,12 @@ g_application_impl_attempt_primary (GApplicationImpl *impl,
if (impl->actions_id == 0)
return FALSE;
+ if (!app_class->dbus_register (impl->app,
+ impl->session_bus,
+ impl->object_path,
+ error))
+ return FALSE;
+
if (impl->bus_name == NULL)
{
/* If this is a non-unique application then it is sufficient to
@@ -315,6 +322,12 @@ g_application_impl_attempt_primary (GApplicationImpl *impl,
static void
g_application_impl_stop_primary (GApplicationImpl *impl)
{
+ GApplicationClass *app_class = G_APPLICATION_GET_CLASS (impl->app);
+
+ app_class->dbus_unregister (impl->app,
+ impl->session_bus,
+ impl->object_path);
+
if (impl->object_id)
{
g_dbus_connection_unregister_object (impl->session_bus, impl->object_id);
diff --git a/gio/tests/Makefile.am b/gio/tests/Makefile.am
index c5cf59d..14411e2 100644
--- a/gio/tests/Makefile.am
+++ b/gio/tests/Makefile.am
@@ -120,6 +120,7 @@ SAMPLE_PROGS = \
gapplication-example-cmdline2 \
gapplication-example-cmdline3 \
gapplication-example-actions \
+ gapplication-example-dbushooks \
gdbus-daemon \
$(NULL)
@@ -451,6 +452,9 @@ gapplication_example_cmdline3_LDADD = $(progs_ldadd)
gapplication_example_actions_SOURCES = gapplication-example-actions.c
gapplication_example_actions_LDADD = $(progs_ldadd)
+gapplication_example_dbushooks_SOURCES = gapplication-example-dbushooks.c
+gapplication_example_dbushooks_LDADD = $(progs_ldadd)
+
gmenumodel_SOURCES = gmenumodel.c gdbus-sessionbus.h gdbus-sessionbus.c
gmenumodel_LDADD = $(progs_ldadd)
diff --git a/gio/tests/gapplication-example-dbushooks.c b/gio/tests/gapplication-example-dbushooks.c
new file mode 100644
index 0000000..ab33f46
--- /dev/null
+++ b/gio/tests/gapplication-example-dbushooks.c
@@ -0,0 +1,99 @@
+#include <gio/gio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void
+activate (GApplication *application)
+{
+ g_print ("activated\n");
+
+ /* Note: when doing a longer-lasting action here that returns
+ * to the mainloop, you should use g_application_hold() and
+ * g_application_release() to keep the application alive until
+ * the action is completed.
+ */
+}
+
+typedef GApplication TestApplication;
+typedef GApplicationClass TestApplicationClass;
+
+static GType test_application_get_type (void);
+G_DEFINE_TYPE (TestApplication, test_application, G_TYPE_APPLICATION)
+
+static gboolean
+test_application_dbus_register (GApplication *application,
+ GDBusConnection *connection,
+ const gchar *object_path,
+ GError **error)
+{
+ /* We must chain up to the parent class */
+ if (!G_APPLICATION_CLASS (test_application_parent_class)->dbus_register (application,
+ connection,
+ object_path,
+ error))
+ return FALSE;
+
+ /* Now we can do our own stuff here. For example, we could export some D-Bus objects */
+ return TRUE;
+}
+
+static void
+test_application_dbus_unregister (GApplication *application,
+ GDBusConnection *connection,
+ const gchar *object_path)
+{
+ /* Do our own stuff here, e.g. unexport any D-Bus objects we exported in the dbus_register
+ * hook above. Be sure to check that we actually did export them, since the hook
+ * above might have returned early due to the parent class' hook returning FALSE!
+ */
+
+ /* Lastly, we must chain up to the parent class */
+ G_APPLICATION_CLASS (test_application_parent_class)->dbus_unregister (application,
+ connection,
+ object_path);
+}
+
+static void
+test_application_init (TestApplication *app)
+{
+}
+
+static void
+test_application_class_init (TestApplicationClass *class)
+{
+ GApplicationClass *g_application_class = G_APPLICATION_CLASS (class);
+
+ g_application_class->dbus_register = test_application_dbus_register;
+ g_application_class->dbus_unregister = test_application_dbus_unregister;
+}
+
+static GApplication *
+test_application_new (const gchar *application_id,
+ GApplicationFlags flags)
+{
+ g_return_val_if_fail (g_application_id_is_valid (application_id), NULL);
+
+ g_type_init ();
+
+ return g_object_new (test_application_get_type (),
+ "application-id", application_id,
+ "flags", flags,
+ NULL);
+}
+
+int
+main (int argc, char **argv)
+{
+ GApplication *app;
+ int status;
+
+ app = test_application_new ("org.gtk.TestApplication", 0);
+ g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
+ g_application_set_inactivity_timeout (app, 10000);
+
+ status = g_application_run (app, argc, argv);
+
+ g_object_unref (app);
+
+ return status;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]