mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-26 15:36:14 +01:00
GDBus: add 'monitor' verb to gdbus(1)
This uncovered a bug in name watching if the name wasn't activatable. Also provoked the need for on_connection variants of g_bus_watch_name (added g_bus_watch_proxy's variant as well).
This commit is contained in:
parent
9695c23d4c
commit
ea1e0496b0
@ -23,6 +23,19 @@
|
|||||||
<arg choice="plain">--dest <replaceable>bus_name</replaceable></arg>
|
<arg choice="plain">--dest <replaceable>bus_name</replaceable></arg>
|
||||||
<arg choice="plain">--object-path <replaceable>/path/to/object</replaceable></arg>
|
<arg choice="plain">--object-path <replaceable>/path/to/object</replaceable></arg>
|
||||||
</cmdsynopsis>
|
</cmdsynopsis>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>gdbus</command>
|
||||||
|
<arg choice="plain">monitor</arg>
|
||||||
|
<group>
|
||||||
|
<arg choice="plain">--system</arg>
|
||||||
|
<arg choice="plain">--session</arg>
|
||||||
|
<arg choice="plain">--address <replaceable>address</replaceable></arg>
|
||||||
|
</group>
|
||||||
|
<arg choice="plain">--dest <replaceable>bus_name</replaceable></arg>
|
||||||
|
<group>
|
||||||
|
<arg choice="plain">--object-path <replaceable>/path/to/object</replaceable></arg>
|
||||||
|
</group>
|
||||||
|
</cmdsynopsis>
|
||||||
<cmdsynopsis>
|
<cmdsynopsis>
|
||||||
<command>gdbus</command>
|
<command>gdbus</command>
|
||||||
<arg choice="plain">call</arg>
|
<arg choice="plain">call</arg>
|
||||||
@ -60,6 +73,13 @@
|
|||||||
<literal>org.freedesktop.DBus.Introspectable</literal> interface.
|
<literal>org.freedesktop.DBus.Introspectable</literal> interface.
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>monitor</option></term>
|
||||||
|
<listitem><para>
|
||||||
|
Monitors one or all objects owned by the owned of
|
||||||
|
<replaceable>bus_name</replaceable>.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>call</option></term>
|
<term><option>call</option></term>
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
@ -189,6 +209,29 @@ $ gdbus call --session \
|
|||||||
5000
|
5000
|
||||||
(uint32 12,)
|
(uint32 12,)
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
Monitoring all objects on a service:
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
$ gdbus monitor --system --dest org.freedesktop.ConsoleKit
|
||||||
|
Monitoring signals from all objects owned by org.freedesktop.ConsoleKit
|
||||||
|
The name org.freedesktop.ConsoleKit is owned by :1.15
|
||||||
|
/org/freedesktop/ConsoleKit/Session2: org.freedesktop.ConsoleKit.Session.ActiveChanged (false,)
|
||||||
|
/org/freedesktop/ConsoleKit/Seat1: org.freedesktop.ConsoleKit.Seat.ActiveSessionChanged ('',)
|
||||||
|
/org/freedesktop/ConsoleKit/Session2: org.freedesktop.ConsoleKit.Session.ActiveChanged (true,)
|
||||||
|
/org/freedesktop/ConsoleKit/Seat1: org.freedesktop.ConsoleKit.Seat.ActiveSessionChanged ('/org/freedesktop/ConsoleKit/Session2',)
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
Monitoring a single object on a service:
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
$ gdbus monitor --system --dest org.freedesktop.ConsoleKit --object-path /org/freedesktop/ConsoleKit/Session2
|
||||||
|
Monitoring signals on object /org/freedesktop/ConsoleKit/Session2 owned by org.freedesktop.ConsoleKit
|
||||||
|
The name org.freedesktop.ConsoleKit is owned by :1.15
|
||||||
|
/org/freedesktop/ConsoleKit/Session2: org.freedesktop.ConsoleKit.Session.ActiveChanged (false,)
|
||||||
|
/org/freedesktop/ConsoleKit/Session2: org.freedesktop.ConsoleKit.Session.ActiveChanged (true,)
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
|
@ -2446,6 +2446,7 @@ GBusNameAppearedCallback
|
|||||||
GBusNameVanishedCallback
|
GBusNameVanishedCallback
|
||||||
GBusNameWatcherFlags
|
GBusNameWatcherFlags
|
||||||
g_bus_watch_name
|
g_bus_watch_name
|
||||||
|
g_bus_watch_name_on_connection
|
||||||
g_bus_unwatch_name
|
g_bus_unwatch_name
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
@ -2454,6 +2455,7 @@ g_bus_unwatch_name
|
|||||||
GBusProxyAppearedCallback
|
GBusProxyAppearedCallback
|
||||||
GBusProxyVanishedCallback
|
GBusProxyVanishedCallback
|
||||||
g_bus_watch_proxy
|
g_bus_watch_proxy
|
||||||
|
g_bus_watch_proxy_on_connection
|
||||||
g_bus_unwatch_proxy
|
g_bus_unwatch_proxy
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
|
253
gio/gdbus-tool.c
253
gio/gdbus-tool.c
@ -92,6 +92,7 @@ usage (gint *argc, gchar **argv[], gboolean use_stdout)
|
|||||||
s = g_strdup_printf (_("Commands:\n"
|
s = g_strdup_printf (_("Commands:\n"
|
||||||
" help Shows this information\n"
|
" help Shows this information\n"
|
||||||
" introspect Introspect a remote object\n"
|
" introspect Introspect a remote object\n"
|
||||||
|
" monitor Monitor a remote object\n"
|
||||||
" call Invoke a method on a remote object\n"
|
" call Invoke a method on a remote object\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Use \"%s COMMAND --help\" to get help on each command.\n"),
|
"Use \"%s COMMAND --help\" to get help on each command.\n"),
|
||||||
@ -1380,6 +1381,246 @@ handle_introspect (gint *argc,
|
|||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static gchar *opt_monitor_dest = NULL;
|
||||||
|
static gchar *opt_monitor_object_path = NULL;
|
||||||
|
|
||||||
|
static guint monitor_filter_id = 0;
|
||||||
|
|
||||||
|
static void
|
||||||
|
monitor_signal_cb (GDBusConnection *connection,
|
||||||
|
const gchar *sender_name,
|
||||||
|
const gchar *object_path,
|
||||||
|
const gchar *interface_name,
|
||||||
|
const gchar *signal_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
gchar *s;
|
||||||
|
s = g_variant_print (parameters, TRUE);
|
||||||
|
g_print ("%s: %s.%s %s\n",
|
||||||
|
object_path,
|
||||||
|
interface_name,
|
||||||
|
signal_name,
|
||||||
|
s);
|
||||||
|
g_free (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
monitor_on_name_appeared (GDBusConnection *connection,
|
||||||
|
const gchar *name,
|
||||||
|
const gchar *name_owner,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
g_print ("The name %s is owned by %s\n", name, name_owner);
|
||||||
|
g_assert (monitor_filter_id == 0);
|
||||||
|
monitor_filter_id = g_dbus_connection_signal_subscribe (connection,
|
||||||
|
name_owner,
|
||||||
|
NULL, /* any interface */
|
||||||
|
NULL, /* any member */
|
||||||
|
opt_monitor_object_path,
|
||||||
|
NULL, /* arg0 */
|
||||||
|
monitor_signal_cb,
|
||||||
|
NULL, /* user_data */
|
||||||
|
NULL); /* user_data destroy notify */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
monitor_on_name_vanished (GDBusConnection *connection,
|
||||||
|
const gchar *name,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
g_print ("The name %s does not have an owner\n", name);
|
||||||
|
|
||||||
|
if (monitor_filter_id != 0)
|
||||||
|
{
|
||||||
|
g_dbus_connection_signal_unsubscribe (connection, monitor_filter_id);
|
||||||
|
monitor_filter_id = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const GOptionEntry monitor_entries[] =
|
||||||
|
{
|
||||||
|
{ "dest", 'd', 0, G_OPTION_ARG_STRING, &opt_monitor_dest, N_("Destination name to monitor"), NULL},
|
||||||
|
{ "object-path", 'o', 0, G_OPTION_ARG_STRING, &opt_monitor_object_path, N_("Object path to monitor"), NULL},
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
handle_monitor (gint *argc,
|
||||||
|
gchar **argv[],
|
||||||
|
gboolean request_completion,
|
||||||
|
const gchar *completion_cur,
|
||||||
|
const gchar *completion_prev)
|
||||||
|
{
|
||||||
|
gint ret;
|
||||||
|
GOptionContext *o;
|
||||||
|
gchar *s;
|
||||||
|
GError *error;
|
||||||
|
GDBusConnection *c;
|
||||||
|
GVariant *result;
|
||||||
|
GDBusNodeInfo *node;
|
||||||
|
gboolean complete_names;
|
||||||
|
gboolean complete_paths;
|
||||||
|
GMainLoop *loop;
|
||||||
|
|
||||||
|
ret = FALSE;
|
||||||
|
c = NULL;
|
||||||
|
node = NULL;
|
||||||
|
result = NULL;
|
||||||
|
|
||||||
|
modify_argv0_for_command (argc, argv, "monitor");
|
||||||
|
|
||||||
|
o = g_option_context_new (NULL);
|
||||||
|
if (request_completion)
|
||||||
|
g_option_context_set_ignore_unknown_options (o, TRUE);
|
||||||
|
g_option_context_set_help_enabled (o, FALSE);
|
||||||
|
g_option_context_set_summary (o, _("Monitor a remote object."));
|
||||||
|
g_option_context_add_main_entries (o, monitor_entries, NULL /* GETTEXT_PACKAGE*/);
|
||||||
|
g_option_context_add_group (o, connection_get_group ());
|
||||||
|
|
||||||
|
complete_names = FALSE;
|
||||||
|
if (request_completion && *argc > 1 && g_strcmp0 ((*argv)[(*argc)-1], "--dest") == 0)
|
||||||
|
{
|
||||||
|
complete_names = TRUE;
|
||||||
|
remove_arg ((*argc) - 1, argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_paths = FALSE;
|
||||||
|
if (request_completion && *argc > 1 && g_strcmp0 ((*argv)[(*argc)-1], "--object-path") == 0)
|
||||||
|
{
|
||||||
|
complete_paths = TRUE;
|
||||||
|
remove_arg ((*argc) - 1, argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_option_context_parse (o, argc, argv, NULL))
|
||||||
|
{
|
||||||
|
if (!request_completion)
|
||||||
|
{
|
||||||
|
s = g_option_context_get_help (o, FALSE, NULL);
|
||||||
|
g_printerr ("%s", s);
|
||||||
|
g_free (s);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
error = NULL;
|
||||||
|
c = connection_get_dbus_connection (&error);
|
||||||
|
if (c == NULL)
|
||||||
|
{
|
||||||
|
if (request_completion)
|
||||||
|
{
|
||||||
|
if (g_strcmp0 (completion_prev, "--address") == 0)
|
||||||
|
{
|
||||||
|
g_print ("unix:\n"
|
||||||
|
"tcp:\n"
|
||||||
|
"nonce-tcp:\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_print ("--system \n--session \n--address \n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_printerr (_("Error connecting: %s\n"), error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_dbus_connection_get_unique_name (c) != NULL)
|
||||||
|
{
|
||||||
|
if (complete_names)
|
||||||
|
{
|
||||||
|
print_names (c, FALSE);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
/* this only makes sense on message bus connections */
|
||||||
|
if (opt_monitor_dest == NULL)
|
||||||
|
{
|
||||||
|
if (request_completion)
|
||||||
|
g_print ("--dest \n");
|
||||||
|
else
|
||||||
|
g_printerr (_("Error: Destination is not specified\n"));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (request_completion && g_strcmp0 ("--dest", completion_prev) == 0)
|
||||||
|
{
|
||||||
|
print_names (c, g_str_has_prefix (opt_monitor_dest, ":"));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (complete_paths)
|
||||||
|
{
|
||||||
|
print_paths (c, opt_monitor_dest, "/");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (opt_monitor_object_path == NULL)
|
||||||
|
{
|
||||||
|
if (request_completion)
|
||||||
|
{
|
||||||
|
g_print ("--object-path \n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
/* it's fine to not have an object path */
|
||||||
|
}
|
||||||
|
if (request_completion && g_strcmp0 ("--object-path", completion_prev) == 0)
|
||||||
|
{
|
||||||
|
gchar *p;
|
||||||
|
s = g_strdup (opt_monitor_object_path);
|
||||||
|
p = strrchr (s, '/');
|
||||||
|
if (p != NULL)
|
||||||
|
{
|
||||||
|
if (p == s)
|
||||||
|
p++;
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
|
print_paths (c, opt_monitor_dest, s);
|
||||||
|
g_free (s);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (!request_completion && (opt_monitor_object_path != NULL && !g_variant_is_object_path (opt_monitor_object_path)))
|
||||||
|
{
|
||||||
|
g_printerr (_("Error: %s is not a valid object path\n"), opt_monitor_object_path);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All done with completion now */
|
||||||
|
if (request_completion)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (opt_monitor_object_path != NULL)
|
||||||
|
g_print ("Monitoring signals on object %s owned by %s\n", opt_monitor_object_path, opt_monitor_dest);
|
||||||
|
else
|
||||||
|
g_print ("Monitoring signals from all objects owned by %s\n", opt_monitor_dest);
|
||||||
|
|
||||||
|
loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
g_bus_watch_name_on_connection (c,
|
||||||
|
opt_monitor_dest,
|
||||||
|
G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
|
||||||
|
monitor_on_name_appeared,
|
||||||
|
monitor_on_name_vanished,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
g_main_loop_run (loop);
|
||||||
|
g_main_loop_unref (loop);
|
||||||
|
|
||||||
|
ret = TRUE;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (node != NULL)
|
||||||
|
g_dbus_node_info_unref (node);
|
||||||
|
if (result != NULL)
|
||||||
|
g_variant_unref (result);
|
||||||
|
if (c != NULL)
|
||||||
|
g_object_unref (c);
|
||||||
|
g_option_context_free (o);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
pick_word_at (const gchar *s,
|
pick_word_at (const gchar *s,
|
||||||
gint cursor,
|
gint cursor,
|
||||||
@ -1476,6 +1717,16 @@ main (gint argc, gchar *argv[])
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
else if (g_strcmp0 (command, "monitor") == 0)
|
||||||
|
{
|
||||||
|
if (handle_monitor (&argc,
|
||||||
|
&argv,
|
||||||
|
request_completion,
|
||||||
|
completion_cur,
|
||||||
|
completion_prev))
|
||||||
|
ret = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
else if (g_strcmp0 (command, "complete") == 0 && argc == 4 && !request_completion)
|
else if (g_strcmp0 (command, "complete") == 0 && argc == 4 && !request_completion)
|
||||||
{
|
{
|
||||||
const gchar *completion_line;
|
const gchar *completion_line;
|
||||||
@ -1545,7 +1796,7 @@ main (gint argc, gchar *argv[])
|
|||||||
{
|
{
|
||||||
if (request_completion)
|
if (request_completion)
|
||||||
{
|
{
|
||||||
g_print ("help \ncall \nintrospect \n");
|
g_print ("help \ncall \nintrospect \nmonitor \n");
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -417,10 +417,11 @@ start_service_by_name_cb (GObject *source_object,
|
|||||||
* org.freedesktop.DBus.Error.ServiceUnknown: The name org.gnome.Epiphany2
|
* org.freedesktop.DBus.Error.ServiceUnknown: The name org.gnome.Epiphany2
|
||||||
* was not provided by any .service files
|
* was not provided by any .service files
|
||||||
*
|
*
|
||||||
* so just report vanished.
|
* This doesn't mean that the name doesn't have an owner, just
|
||||||
|
* that it's not provided by a .service file. So proceed to
|
||||||
|
* invoke GetNameOwner().
|
||||||
*/
|
*/
|
||||||
call_vanished_handler (client, FALSE);
|
invoke_get_name_owner (client);
|
||||||
client->initialized = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != NULL)
|
if (result != NULL)
|
||||||
@ -586,6 +587,68 @@ g_bus_watch_name (GBusType bus_type,
|
|||||||
return client->id;
|
return client->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_bus_watch_name_on_connection:
|
||||||
|
* @connection: A #GDBusConnection that is not closed.
|
||||||
|
* @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 or %NULL.
|
||||||
|
* @name_vanished_handler: Handler to invoke when @name is known to not exist or %NULL.
|
||||||
|
* @user_data: User data to pass to handlers.
|
||||||
|
* @user_data_free_func: Function for freeing @user_data or %NULL.
|
||||||
|
*
|
||||||
|
* Like g_bus_watch_name() but takes a #GDBusConnection instead of a
|
||||||
|
* #GBusType.
|
||||||
|
*
|
||||||
|
* Returns: An identifier (never 0) that an be used with
|
||||||
|
* g_bus_unwatch_name() to stop watching the name.
|
||||||
|
*
|
||||||
|
* Since: 2.26
|
||||||
|
*/
|
||||||
|
guint g_bus_watch_name_on_connection (GDBusConnection *connection,
|
||||||
|
const gchar *name,
|
||||||
|
GBusNameWatcherFlags flags,
|
||||||
|
GBusNameAppearedCallback name_appeared_handler,
|
||||||
|
GBusNameVanishedCallback name_vanished_handler,
|
||||||
|
gpointer user_data,
|
||||||
|
GDestroyNotify user_data_free_func)
|
||||||
|
{
|
||||||
|
Client *client;
|
||||||
|
|
||||||
|
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), 0);
|
||||||
|
g_return_val_if_fail (g_dbus_is_name (name), 0);
|
||||||
|
|
||||||
|
G_LOCK (lock);
|
||||||
|
|
||||||
|
client = g_new0 (Client, 1);
|
||||||
|
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;
|
||||||
|
client->user_data_free_func = user_data_free_func;
|
||||||
|
client->main_context = g_main_context_get_thread_default ();
|
||||||
|
if (client->main_context != NULL)
|
||||||
|
g_main_context_ref (client->main_context);
|
||||||
|
|
||||||
|
if (map_id_to_client == NULL)
|
||||||
|
{
|
||||||
|
map_id_to_client = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||||
|
}
|
||||||
|
g_hash_table_insert (map_id_to_client,
|
||||||
|
GUINT_TO_POINTER (client->id),
|
||||||
|
client);
|
||||||
|
|
||||||
|
client->connection = g_object_ref (connection);
|
||||||
|
G_UNLOCK (lock);
|
||||||
|
|
||||||
|
has_connection (client);
|
||||||
|
|
||||||
|
return client->id;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_bus_unwatch_name:
|
* g_bus_unwatch_name:
|
||||||
* @watcher_id: An identifier obtained from g_bus_watch_name()
|
* @watcher_id: An identifier obtained from g_bus_watch_name()
|
||||||
|
@ -65,6 +65,13 @@ guint g_bus_watch_name (GBusType bus_type,
|
|||||||
GBusNameVanishedCallback name_vanished_handler,
|
GBusNameVanishedCallback name_vanished_handler,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify user_data_free_func);
|
GDestroyNotify user_data_free_func);
|
||||||
|
guint g_bus_watch_name_on_connection (GDBusConnection *connection,
|
||||||
|
const gchar *name,
|
||||||
|
GBusNameWatcherFlags flags,
|
||||||
|
GBusNameAppearedCallback name_appeared_handler,
|
||||||
|
GBusNameVanishedCallback name_vanished_handler,
|
||||||
|
gpointer user_data,
|
||||||
|
GDestroyNotify user_data_free_func);
|
||||||
void g_bus_unwatch_name (guint watcher_id);
|
void g_bus_unwatch_name (guint watcher_id);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "gdbusutils.h"
|
#include "gdbusutils.h"
|
||||||
|
#include "gdbusconnection.h"
|
||||||
#include "gdbusnamewatching.h"
|
#include "gdbusnamewatching.h"
|
||||||
#include "gdbusproxywatching.h"
|
#include "gdbusproxywatching.h"
|
||||||
#include "gdbuserror.h"
|
#include "gdbuserror.h"
|
||||||
@ -362,6 +363,91 @@ g_bus_watch_proxy (GBusType bus_type,
|
|||||||
return client->id;
|
return client->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_bus_watch_proxy_on_connection:
|
||||||
|
* @connection: A #GDBusConnection that is not closed.
|
||||||
|
* @name: The name (well-known or unique) to watch.
|
||||||
|
* @flags: Flags from the #GBusNameWatcherFlags enumeration.
|
||||||
|
* @object_path: The object path of the remote object to watch.
|
||||||
|
* @interface_name: The D-Bus interface name for the proxy.
|
||||||
|
* @interface_type: The #GType for the kind of proxy to create. This must be a #GDBusProxy derived type.
|
||||||
|
* @proxy_flags: Flags from #GDBusProxyFlags to use when constructing the proxy.
|
||||||
|
* @proxy_appeared_handler: Handler to invoke when @name is known to exist and the
|
||||||
|
* requested proxy is available.
|
||||||
|
* @proxy_vanished_handler: Handler to invoke when @name is known to not exist
|
||||||
|
* and the previously created proxy is no longer available.
|
||||||
|
* @user_data: User data to pass to handlers.
|
||||||
|
* @user_data_free_func: Function for freeing @user_data or %NULL.
|
||||||
|
*
|
||||||
|
* Like g_bus_watch_proxy() but takes a #GDBusConnection instead of a
|
||||||
|
* #GBusType.
|
||||||
|
*
|
||||||
|
* Returns: An identifier (never 0) that can be used with
|
||||||
|
* g_bus_unwatch_proxy() to stop watching the remote object.
|
||||||
|
*
|
||||||
|
* Since: 2.26
|
||||||
|
*/
|
||||||
|
guint
|
||||||
|
g_bus_watch_proxy_on_connection (GDBusConnection *connection,
|
||||||
|
const gchar *name,
|
||||||
|
GBusNameWatcherFlags flags,
|
||||||
|
const gchar *object_path,
|
||||||
|
const gchar *interface_name,
|
||||||
|
GType interface_type,
|
||||||
|
GDBusProxyFlags proxy_flags,
|
||||||
|
GBusProxyAppearedCallback proxy_appeared_handler,
|
||||||
|
GBusProxyVanishedCallback proxy_vanished_handler,
|
||||||
|
gpointer user_data,
|
||||||
|
GDestroyNotify user_data_free_func)
|
||||||
|
{
|
||||||
|
Client *client;
|
||||||
|
|
||||||
|
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), 0);
|
||||||
|
g_return_val_if_fail (g_dbus_is_name (name), 0);
|
||||||
|
g_return_val_if_fail (g_variant_is_object_path (object_path), 0);
|
||||||
|
g_return_val_if_fail (g_dbus_is_interface_name (interface_name), 0);
|
||||||
|
g_return_val_if_fail (g_type_is_a (interface_type, G_TYPE_DBUS_PROXY), 0);
|
||||||
|
|
||||||
|
G_LOCK (lock);
|
||||||
|
|
||||||
|
client = g_new0 (Client, 1);
|
||||||
|
client->id = next_global_id++; /* TODO: uh oh, handle overflow */
|
||||||
|
client->name = g_strdup (name);
|
||||||
|
client->proxy_appeared_handler = proxy_appeared_handler;
|
||||||
|
client->proxy_vanished_handler = proxy_vanished_handler;
|
||||||
|
client->user_data = user_data;
|
||||||
|
client->user_data_free_func = user_data_free_func;
|
||||||
|
client->main_context = g_main_context_get_thread_default ();
|
||||||
|
if (client->main_context != NULL)
|
||||||
|
g_main_context_ref (client->main_context);
|
||||||
|
client->name_watcher_id = g_bus_watch_name_on_connection (connection,
|
||||||
|
name,
|
||||||
|
flags,
|
||||||
|
on_name_appeared,
|
||||||
|
on_name_vanished,
|
||||||
|
client,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
client->object_path = g_strdup (object_path);
|
||||||
|
client->interface_name = g_strdup (interface_name);
|
||||||
|
client->interface_type = interface_type;
|
||||||
|
client->proxy_flags = proxy_flags;
|
||||||
|
client->initial_construction = TRUE;
|
||||||
|
|
||||||
|
if (map_id_to_client == NULL)
|
||||||
|
{
|
||||||
|
map_id_to_client = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||||
|
}
|
||||||
|
g_hash_table_insert (map_id_to_client,
|
||||||
|
GUINT_TO_POINTER (client->id),
|
||||||
|
client);
|
||||||
|
|
||||||
|
G_UNLOCK (lock);
|
||||||
|
|
||||||
|
return client->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_bus_unwatch_proxy:
|
* g_bus_unwatch_proxy:
|
||||||
* @watcher_id: An identifier obtained from g_bus_watch_proxy()
|
* @watcher_id: An identifier obtained from g_bus_watch_proxy()
|
||||||
|
@ -74,6 +74,17 @@ guint g_bus_watch_proxy (GBusType bus_type,
|
|||||||
GBusProxyVanishedCallback proxy_vanished_handler,
|
GBusProxyVanishedCallback proxy_vanished_handler,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify user_data_free_func);
|
GDestroyNotify user_data_free_func);
|
||||||
|
guint g_bus_watch_proxy_on_connection (GDBusConnection *connection,
|
||||||
|
const gchar *name,
|
||||||
|
GBusNameWatcherFlags flags,
|
||||||
|
const gchar *object_path,
|
||||||
|
const gchar *interface_name,
|
||||||
|
GType interface_type,
|
||||||
|
GDBusProxyFlags proxy_flags,
|
||||||
|
GBusProxyAppearedCallback proxy_appeared_handler,
|
||||||
|
GBusProxyVanishedCallback proxy_vanished_handler,
|
||||||
|
gpointer user_data,
|
||||||
|
GDestroyNotify user_data_free_func);
|
||||||
void g_bus_unwatch_proxy (guint watcher_id);
|
void g_bus_unwatch_proxy (guint watcher_id);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
@ -1652,6 +1652,7 @@ g_bus_unown_name
|
|||||||
#if IN_HEADER(__G_DBUS_NAME_WATCHING_H__)
|
#if IN_HEADER(__G_DBUS_NAME_WATCHING_H__)
|
||||||
#if IN_FILE(__G_DBUS_NAME_WATCHING_C__)
|
#if IN_FILE(__G_DBUS_NAME_WATCHING_C__)
|
||||||
g_bus_watch_name
|
g_bus_watch_name
|
||||||
|
g_bus_watch_name_on_connection
|
||||||
g_bus_unwatch_name
|
g_bus_unwatch_name
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@ -1683,6 +1684,7 @@ g_dbus_proxy_call_sync
|
|||||||
#if IN_HEADER(__G_DBUS_PROXY_WATCHING_H__)
|
#if IN_HEADER(__G_DBUS_PROXY_WATCHING_H__)
|
||||||
#if IN_FILE(__G_DBUS_PROXY_WATCHING_C__)
|
#if IN_FILE(__G_DBUS_PROXY_WATCHING_C__)
|
||||||
g_bus_watch_proxy
|
g_bus_watch_proxy
|
||||||
|
g_bus_watch_proxy_on_connection
|
||||||
g_bus_unwatch_proxy
|
g_bus_unwatch_proxy
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user