summaryrefslogtreecommitdiff
path: root/gdbus/gdbusnamewatching.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdbus/gdbusnamewatching.c')
-rw-r--r--gdbus/gdbusnamewatching.c106
1 files changed, 94 insertions, 12 deletions
diff --git a/gdbus/gdbusnamewatching.c b/gdbus/gdbusnamewatching.c
index ef030f2..fe6cc41 100644
--- a/gdbus/gdbusnamewatching.c
+++ b/gdbus/gdbusnamewatching.c
@@ -58,6 +58,7 @@ typedef struct
volatile gint ref_count;
guint id;
gchar *name;
+ GBusNameWatcherFlags flags;
gchar *name_owner;
GBusNameAppearedCallback name_appeared_handler;
GBusNameVanishedCallback name_vanished_handler;
@@ -356,6 +357,77 @@ get_name_owner_cb (GObject *source_object,
/* ---------------------------------------------------------------------------------------------------- */
static void
+invoke_get_name_owner (Client *client)
+{
+ g_dbus_connection_invoke_method (client->connection,
+ "org.freedesktop.DBus", /* bus name */
+ "/org/freedesktop/DBus", /* object path */
+ "org.freedesktop.DBus", /* interface name */
+ "GetNameOwner", /* method name */
+ g_variant_new ("(s)", client->name),
+ G_DBUS_INVOKE_METHOD_FLAGS_NONE,
+ -1,
+ NULL,
+ (GAsyncReadyCallback) get_name_owner_cb,
+ client_ref (client));
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+start_service_by_name_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ Client *client = user_data;
+ GVariant *result;
+
+ result = NULL;
+
+ result = g_dbus_connection_invoke_method_finish (client->connection,
+ res,
+ NULL);
+ if (result != NULL)
+ {
+ guint32 start_service_result;
+ g_variant_get (result, "(u)", &start_service_result);
+
+ if (start_service_result == 1) /* DBUS_START_REPLY_SUCCESS */
+ {
+ invoke_get_name_owner (client);
+ }
+ else if (start_service_result == 2) /* DBUS_START_REPLY_ALREADY_RUNNING */
+ {
+ invoke_get_name_owner (client);
+ }
+ else
+ {
+ g_warning ("Unexpected reply %d from StartServiceByName() method", start_service_result);
+ call_vanished_handler (client, FALSE);
+ client->initialized = TRUE;
+ }
+ }
+ else
+ {
+ /* Errors are not unexpected; the bus will reply e.g.
+ *
+ * org.freedesktop.DBus.Error.ServiceUnknown: The name org.gnome.Epiphany2
+ * was not provided by any .service files
+ *
+ * so just report vanished.
+ */
+ call_vanished_handler (client, FALSE);
+ client->initialized = TRUE;
+ }
+
+ if (result != NULL)
+ g_variant_unref (result);
+ client_unref (client);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
has_connection (Client *client)
{
/* listen for disconnection */
@@ -375,18 +447,25 @@ has_connection (Client *client)
client,
NULL);
- /* check owner */
- g_dbus_connection_invoke_method (client->connection,
- "org.freedesktop.DBus", /* bus name */
- "/org/freedesktop/DBus", /* object path */
- "org.freedesktop.DBus", /* interface name */
- "GetNameOwner", /* method name */
- g_variant_new ("(s)", client->name),
- G_DBUS_INVOKE_METHOD_FLAGS_NONE,
- -1,
- NULL,
- (GAsyncReadyCallback) get_name_owner_cb,
- client_ref (client));
+ if (client->flags & G_BUS_NAME_WATCHER_FLAGS_AUTO_START)
+ {
+ g_dbus_connection_invoke_method (client->connection,
+ "org.freedesktop.DBus", /* bus name */
+ "/org/freedesktop/DBus", /* object path */
+ "org.freedesktop.DBus", /* interface name */
+ "StartServiceByName", /* method name */
+ g_variant_new ("(su)", client->name, 0),
+ G_DBUS_INVOKE_METHOD_FLAGS_NONE,
+ -1,
+ NULL,
+ (GAsyncReadyCallback) start_service_by_name_cb,
+ client_ref (client));
+ }
+ else
+ {
+ /* check owner */
+ invoke_get_name_owner (client);
+ }
}
@@ -416,6 +495,7 @@ connection_get_cb (GObject *source_object,
* g_bus_watch_name:
* @bus_type: The type of bus to watch a name on (can't be #G_BUS_TYPE_NONE).
* @name: The name (well-known or unique) to watch.
+ * @flags: Flags from the #GBusNameWatcherFlags enumeration.
* @name_appeared_handler: Handler to invoke when @name is known to exist.
* @name_vanished_handler: Handler to invoke when @name is known to not exist.
* @user_data: User data to pass to handlers.
@@ -457,6 +537,7 @@ connection_get_cb (GObject *source_object,
guint
g_bus_watch_name (GBusType bus_type,
const gchar *name,
+ GBusNameWatcherFlags flags,
GBusNameAppearedCallback name_appeared_handler,
GBusNameVanishedCallback name_vanished_handler,
gpointer user_data,
@@ -475,6 +556,7 @@ g_bus_watch_name (GBusType bus_type,
client->ref_count = 1;
client->id = next_global_id++; /* TODO: uh oh, handle overflow */
client->name = g_strdup (name);
+ client->flags = flags;
client->name_appeared_handler = name_appeared_handler;
client->name_vanished_handler = name_vanished_handler;
client->user_data = user_data;