1#include <gio/gio.h>
2
3static gchar *opt_name = NULL;
4static gchar *opt_object_path = NULL;
5static gchar *opt_interface = NULL;
6static gboolean opt_system_bus = FALSE;
7static gboolean opt_no_auto_start = FALSE;
8static gboolean opt_no_properties = FALSE;
9
10static GOptionEntry opt_entries[] =
11{
12 { "name", 'n', 0, G_OPTION_ARG_STRING, &opt_name, "Name of the remote object to watch", NULL },
13 { "object-path", 'o', 0, G_OPTION_ARG_STRING, &opt_object_path, "Object path of the remote object", NULL },
14 { "interface", 'i', 0, G_OPTION_ARG_STRING, &opt_interface, "D-Bus interface of remote object", NULL },
15 { "system-bus", 's', 0, G_OPTION_ARG_NONE, &opt_system_bus, "Use the system-bus instead of the session-bus", NULL },
16 { "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},
17 { "no-properties", 'p', 0, G_OPTION_ARG_NONE, &opt_no_properties, "Do not load properties", NULL},
18 { NULL}
19};
20
21static GMainLoop *loop = NULL;
22
23static void
24print_properties (GDBusProxy *proxy)
25{
26 gchar **property_names;
27 guint n;
28
29 g_print (format: " properties:\n");
30
31 property_names = g_dbus_proxy_get_cached_property_names (proxy);
32 for (n = 0; property_names != NULL && property_names[n] != NULL; n++)
33 {
34 const gchar *key = property_names[n];
35 GVariant *value;
36 gchar *value_str;
37 value = g_dbus_proxy_get_cached_property (proxy, property_name: key);
38 value_str = g_variant_print (value, TRUE);
39 g_print (format: " %s -> %s\n", key, value_str);
40 g_variant_unref (value);
41 g_free (mem: value_str);
42 }
43 g_strfreev (str_array: property_names);
44}
45
46static void
47on_properties_changed (GDBusProxy *proxy,
48 GVariant *changed_properties,
49 const gchar* const *invalidated_properties,
50 gpointer user_data)
51{
52 /* Note that we are guaranteed that changed_properties and
53 * invalidated_properties are never NULL
54 */
55
56 if (g_variant_n_children (value: changed_properties) > 0)
57 {
58 GVariantIter *iter;
59 const gchar *key;
60 GVariant *value;
61
62 g_print (format: " *** Properties Changed:\n");
63 g_variant_get (value: changed_properties,
64 format_string: "a{sv}",
65 &iter);
66 while (g_variant_iter_loop (iter, format_string: "{&sv}", &key, &value))
67 {
68 gchar *value_str;
69 value_str = g_variant_print (value, TRUE);
70 g_print (format: " %s -> %s\n", key, value_str);
71 g_free (mem: value_str);
72 }
73 g_variant_iter_free (iter);
74 }
75
76 if (g_strv_length (str_array: (GStrv) invalidated_properties) > 0)
77 {
78 guint n;
79 g_print (format: " *** Properties Invalidated:\n");
80 for (n = 0; invalidated_properties[n] != NULL; n++)
81 {
82 const gchar *key = invalidated_properties[n];
83 g_print (format: " %s\n", key);
84 }
85 }
86}
87
88static void
89on_signal (GDBusProxy *proxy,
90 gchar *sender_name,
91 gchar *signal_name,
92 GVariant *parameters,
93 gpointer user_data)
94{
95 gchar *parameters_str;
96
97 parameters_str = g_variant_print (value: parameters, TRUE);
98 g_print (format: " *** Received Signal: %s: %s\n",
99 signal_name,
100 parameters_str);
101 g_free (mem: parameters_str);
102}
103
104static void
105print_proxy (GDBusProxy *proxy)
106{
107 gchar *name_owner;
108
109 name_owner = g_dbus_proxy_get_name_owner (proxy);
110 if (name_owner != NULL)
111 {
112 g_print (format: "+++ Proxy object points to remote object owned by %s\n"
113 " bus: %s\n"
114 " name: %s\n"
115 " object path: %s\n"
116 " interface: %s\n",
117 name_owner,
118 opt_system_bus ? "System Bus" : "Session Bus",
119 opt_name,
120 opt_object_path,
121 opt_interface);
122 print_properties (proxy);
123 }
124 else
125 {
126 g_print (format: "--- Proxy object is inert - there is no name owner for the name\n"
127 " bus: %s\n"
128 " name: %s\n"
129 " object path: %s\n"
130 " interface: %s\n",
131 opt_system_bus ? "System Bus" : "Session Bus",
132 opt_name,
133 opt_object_path,
134 opt_interface);
135 }
136 g_free (mem: name_owner);
137}
138
139static void
140on_name_owner_notify (GObject *object,
141 GParamSpec *pspec,
142 gpointer user_data)
143{
144 GDBusProxy *proxy = G_DBUS_PROXY (object);
145 print_proxy (proxy);
146}
147
148int
149main (int argc, char *argv[])
150{
151 GOptionContext *opt_context;
152 GError *error;
153 GDBusProxyFlags flags;
154 GDBusProxy *proxy;
155
156 loop = NULL;
157 proxy = NULL;
158
159 opt_context = g_option_context_new (parameter_string: "g_bus_watch_proxy() example");
160 g_option_context_set_summary (context: opt_context,
161 summary: "Example: to watch the object of gdbus-example-server, use:\n"
162 "\n"
163 " ./gdbus-example-watch-proxy -n org.gtk.GDBus.TestServer \\\n"
164 " -o /org/gtk/GDBus/TestObject \\\n"
165 " -i org.gtk.GDBus.TestInterface");
166 g_option_context_add_main_entries (context: opt_context, entries: opt_entries, NULL);
167 error = NULL;
168 if (!g_option_context_parse (context: opt_context, argc: &argc, argv: &argv, error: &error))
169 {
170 g_printerr (format: "Error parsing options: %s\n", error->message);
171 goto out;
172 }
173 if (opt_name == NULL || opt_object_path == NULL || opt_interface == NULL)
174 {
175 g_printerr (format: "Incorrect usage, try --help.\n");
176 goto out;
177 }
178
179 flags = G_DBUS_PROXY_FLAGS_NONE;
180 if (opt_no_properties)
181 flags |= G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES;
182 if (opt_no_auto_start)
183 flags |= G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
184
185 loop = g_main_loop_new (NULL, FALSE);
186
187 error = NULL;
188 proxy = g_dbus_proxy_new_for_bus_sync (bus_type: opt_system_bus ? G_BUS_TYPE_SYSTEM : G_BUS_TYPE_SESSION,
189 flags,
190 NULL, /* GDBusInterfaceInfo */
191 name: opt_name,
192 object_path: opt_object_path,
193 interface_name: opt_interface,
194 NULL, /* GCancellable */
195 error: &error);
196 if (proxy == NULL)
197 {
198 g_printerr (format: "Error creating proxy: %s\n", error->message);
199 g_error_free (error);
200 goto out;
201 }
202
203 g_signal_connect (proxy,
204 "g-properties-changed",
205 G_CALLBACK (on_properties_changed),
206 NULL);
207 g_signal_connect (proxy,
208 "g-signal",
209 G_CALLBACK (on_signal),
210 NULL);
211 g_signal_connect (proxy,
212 "notify::g-name-owner",
213 G_CALLBACK (on_name_owner_notify),
214 NULL);
215 print_proxy (proxy);
216
217 g_main_loop_run (loop);
218
219 out:
220 if (proxy != NULL)
221 g_object_unref (object: proxy);
222 if (loop != NULL)
223 g_main_loop_unref (loop);
224 g_option_context_free (context: opt_context);
225 g_free (mem: opt_name);
226 g_free (mem: opt_object_path);
227 g_free (mem: opt_interface);
228
229 return 0;
230}
231

source code of gtk/subprojects/glib/gio/tests/gdbus-example-watch-proxy.c