| #include <gio/gio.h> | |
| static gchar *opt_name = NULL; | |
| static gchar *opt_object_path = NULL; | |
| static gchar *opt_interface = NULL; | |
| static gboolean opt_system_bus = FALSE; | |
| static gboolean opt_no_auto_start = FALSE; | |
| static gboolean opt_no_properties = FALSE; | |
| static GOptionEntry opt_entries[] = | |
| { | |
| { "name", 'n', 0, G_OPTION_ARG_STRING, &opt_name, "Name of the remote object to watch", NULL }, | |
| { "object-path", 'o', 0, G_OPTION_ARG_STRING, &opt_object_path, "Object path of the remote object", NULL }, | |
| { "interface", 'i', 0, G_OPTION_ARG_STRING, &opt_interface, "D-Bus interface of remote object", NULL }, | |
| { "system-bus", 's', 0, G_OPTION_ARG_NONE, &opt_system_bus, "Use the system-bus instead of the session-bus", NULL }, | |
| { "no-auto-start", 'a', 0, G_OPTION_ARG_NONE, &opt_no_auto_start, "Don't instruct the bus to launch an owner for the name", NULL}, | |
| { "no-properties", 'p', 0, G_OPTION_ARG_NONE, &opt_no_properties, "Do not load properties", NULL}, | |
| G_OPTION_ENTRY_NULL | |
| }; | |
| static GMainLoop *loop = NULL; | |
| static void | |
| print_properties (GDBusProxy *proxy) | |
| { | |
| gchar **property_names; | |
| guint n; | |
| g_print (" properties:\n"); | |
| property_names = g_dbus_proxy_get_cached_property_names (proxy); | |
| for (n = 0; property_names != NULL && property_names[n] != NULL; n++) | |
| { | |
| const gchar *key = property_names[n]; | |
| GVariant *value; | |
| gchar *value_str; | |
| value = g_dbus_proxy_get_cached_property (proxy, key); | |
| value_str = g_variant_print (value, TRUE); | |
| g_print (" %s -> %s\n", key, value_str); | |
| g_variant_unref (value); | |
| g_free (value_str); | |
| } | |
| g_strfreev (property_names); | |
| } | |
| static void | |
| on_properties_changed (GDBusProxy *proxy, | |
| GVariant *changed_properties, | |
| const gchar* const *invalidated_properties, | |
| gpointer user_data) | |
| { | |
| /* Note that we are guaranteed that changed_properties and | |
| * invalidated_properties are never NULL | |
| */ | |
| if (g_variant_n_children (changed_properties) > 0) | |
| { | |
| GVariantIter *iter; | |
| const gchar *key; | |
| GVariant *value; | |
| g_print (" *** Properties Changed:\n"); | |
| g_variant_get (changed_properties, | |
| "a{sv}", | |
| &iter); | |
| while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) | |
| { | |
| gchar *value_str; | |
| value_str = g_variant_print (value, TRUE); | |
| g_print (" %s -> %s\n", key, value_str); | |
| g_free (value_str); | |
| } | |
| g_variant_iter_free (iter); | |
| } | |
| if (g_strv_length ((GStrv) invalidated_properties) > 0) | |
| { | |
| guint n; | |
| g_print (" *** Properties Invalidated:\n"); | |
| for (n = 0; invalidated_properties[n] != NULL; n++) | |
| { | |
| const gchar *key = invalidated_properties[n]; | |
| g_print (" %s\n", key); | |
| } | |
| } | |
| } | |
| static void | |
| on_signal (GDBusProxy *proxy, | |
| gchar *sender_name, | |
| gchar *signal_name, | |
| GVariant *parameters, | |
| gpointer user_data) | |
| { | |
| gchar *parameters_str; | |
| parameters_str = g_variant_print (parameters, TRUE); | |
| g_print (" *** Received Signal: %s: %s\n", | |
| signal_name, | |
| parameters_str); | |
| g_free (parameters_str); | |
| } | |
| static void | |
| print_proxy (GDBusProxy *proxy) | |
| { | |
| gchar *name_owner; | |
| name_owner = g_dbus_proxy_get_name_owner (proxy); | |
| if (name_owner != NULL) | |
| { | |
| g_print ("+++ Proxy object points to remote object owned by %s\n" | |
| " bus: %s\n" | |
| " name: %s\n" | |
| " object path: %s\n" | |
| " interface: %s\n", | |
| name_owner, | |
| opt_system_bus ? "System Bus" : "Session Bus", | |
| opt_name, | |
| opt_object_path, | |
| opt_interface); | |
| print_properties (proxy); | |
| } | |
| else | |
| { | |
| g_print ("--- Proxy object is inert - there is no name owner for the name\n" | |
| " bus: %s\n" | |
| " name: %s\n" | |
| " object path: %s\n" | |
| " interface: %s\n", | |
| opt_system_bus ? "System Bus" : "Session Bus", | |
| opt_name, | |
| opt_object_path, | |
| opt_interface); | |
| } | |
| g_free (name_owner); | |
| } | |
| static void | |
| on_name_owner_notify (GObject *object, | |
| GParamSpec *pspec, | |
| gpointer user_data) | |
| { | |
| GDBusProxy *proxy = G_DBUS_PROXY (object); | |
| print_proxy (proxy); | |
| } | |
| int | |
| main (int argc, char *argv[]) | |
| { | |
| GOptionContext *opt_context; | |
| GError *error; | |
| GDBusProxyFlags flags; | |
| GDBusProxy *proxy; | |
| loop = NULL; | |
| proxy = NULL; | |
| opt_context = g_option_context_new ("g_bus_watch_proxy() example"); | |
| g_option_context_set_summary (opt_context, | |
| "Example: to watch the object of gdbus-example-server, use:\n" | |
| "\n" | |
| " ./gdbus-example-watch-proxy -n org.gtk.GDBus.TestServer \\\n" | |
| " -o /org/gtk/GDBus/TestObject \\\n" | |
| " -i org.gtk.GDBus.TestInterface"); | |
| g_option_context_add_main_entries (opt_context, opt_entries, NULL); | |
| error = NULL; | |
| if (!g_option_context_parse (opt_context, &argc, &argv, &error)) | |
| { | |
| g_printerr ("Error parsing options: %s\n", error->message); | |
| goto out; | |
| } | |
| if (opt_name == NULL || opt_object_path == NULL || opt_interface == NULL) | |
| { | |
| g_printerr ("Incorrect usage, try --help.\n"); | |
| goto out; | |
| } | |
| flags = G_DBUS_PROXY_FLAGS_NONE; | |
| if (opt_no_properties) | |
| flags |= G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES; | |
| if (opt_no_auto_start) | |
| flags |= G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START; | |
| loop = g_main_loop_new (NULL, FALSE); | |
| error = NULL; | |
| proxy = g_dbus_proxy_new_for_bus_sync (opt_system_bus ? G_BUS_TYPE_SYSTEM : G_BUS_TYPE_SESSION, | |
| flags, | |
| NULL, /* GDBusInterfaceInfo */ | |
| opt_name, | |
| opt_object_path, | |
| opt_interface, | |
| NULL, /* GCancellable */ | |
| &error); | |
| if (proxy == NULL) | |
| { | |
| g_printerr ("Error creating proxy: %s\n", error->message); | |
| g_error_free (error); | |
| goto out; | |
| } | |
| g_signal_connect (proxy, | |
| "g-properties-changed", | |
| G_CALLBACK (on_properties_changed), | |
| NULL); | |
| g_signal_connect (proxy, | |
| "g-signal", | |
| G_CALLBACK (on_signal), | |
| NULL); | |
| g_signal_connect (proxy, | |
| "notify::g-name-owner", | |
| G_CALLBACK (on_name_owner_notify), | |
| NULL); | |
| print_proxy (proxy); | |
| g_main_loop_run (loop); | |
| out: | |
| if (proxy != NULL) | |
| g_object_unref (proxy); | |
| if (loop != NULL) | |
| g_main_loop_unref (loop); | |
| g_option_context_free (opt_context); | |
| g_free (opt_name); | |
| g_free (opt_object_path); | |
| g_free (opt_interface); | |
| return 0; | |
| } |