Merge remote branch 'gvdb/master'
[platform/upstream/glib.git] / gio / tests / gdbus-example-watch-proxy.c
1 #include <gio/gio.h>
2
3 static gchar *opt_name         = NULL;
4 static gchar *opt_object_path  = NULL;
5 static gchar *opt_interface    = NULL;
6 static gboolean opt_system_bus = FALSE;
7 static gboolean opt_no_auto_start = FALSE;
8 static gboolean opt_no_properties = FALSE;
9
10 static 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
21 static GMainLoop *loop = NULL;
22
23 static void
24 print_properties (GDBusProxy *proxy)
25 {
26   gchar **property_names;
27   guint n;
28
29   g_print ("    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, key);
38       value_str = g_variant_print (value, TRUE);
39       g_print ("      %s -> %s\n", key, value_str);
40       g_variant_unref (value);
41       g_free (value_str);
42     }
43   g_strfreev (property_names);
44 }
45
46 static void
47 on_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 (changed_properties) > 0)
57     {
58       GVariantIter *iter;
59       const gchar *key;
60       GVariant *value;
61
62       g_print (" *** Properties Changed:\n");
63       g_variant_get (changed_properties,
64                      "a{sv}",
65                      &iter);
66       while (g_variant_iter_loop (iter, "{&sv}", &key, &value))
67         {
68           gchar *value_str;
69           value_str = g_variant_print (value, TRUE);
70           g_print ("      %s -> %s\n", key, value_str);
71           g_free (value_str);
72         }
73       g_variant_iter_free (iter);
74     }
75
76   if (g_strv_length ((GStrv) invalidated_properties) > 0)
77     {
78       guint n;
79       g_print (" *** Properties Invalidated:\n");
80       for (n = 0; invalidated_properties[n] != NULL; n++)
81         {
82           const gchar *key = invalidated_properties[n];
83           g_print ("      %s\n", key);
84         }
85     }
86 }
87
88 static void
89 on_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 (parameters, TRUE);
98   g_print (" *** Received Signal: %s: %s\n",
99            signal_name,
100            parameters_str);
101   g_free (parameters_str);
102 }
103
104 static void
105 print_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 ("+++ 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 ("--- 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 (name_owner);
137 }
138
139 static void
140 on_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
148 int
149 main (int argc, char *argv[])
150 {
151   GOptionContext *opt_context;
152   GError *error;
153   GDBusProxyFlags flags;
154   GDBusProxy *proxy;
155
156   g_type_init ();
157
158   loop = NULL;
159   proxy = NULL;
160
161   opt_context = g_option_context_new ("g_bus_watch_proxy() example");
162   g_option_context_set_summary (opt_context,
163                                 "Example: to watch the object of gdbus-example-server, use:\n"
164                                 "\n"
165                                 "  ./gdbus-example-watch-proxy -n org.gtk.GDBus.TestServer  \\\n"
166                                 "                              -o /org/gtk/GDBus/TestObject \\\n"
167                                 "                              -i org.gtk.GDBus.TestInterface");
168   g_option_context_add_main_entries (opt_context, opt_entries, NULL);
169   error = NULL;
170   if (!g_option_context_parse (opt_context, &argc, &argv, &error))
171     {
172       g_printerr ("Error parsing options: %s\n", error->message);
173       goto out;
174     }
175   if (opt_name == NULL || opt_object_path == NULL || opt_interface == NULL)
176     {
177       g_printerr ("Incorrect usage, try --help.\n");
178       goto out;
179     }
180
181   flags = G_DBUS_PROXY_FLAGS_NONE;
182   if (opt_no_properties)
183     flags |= G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES;
184   if (opt_no_auto_start)
185     flags |= G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
186
187   loop = g_main_loop_new (NULL, FALSE);
188
189   error = NULL;
190   proxy = g_dbus_proxy_new_for_bus_sync (opt_system_bus ? G_BUS_TYPE_SYSTEM : G_BUS_TYPE_SESSION,
191                                          flags,
192                                          NULL, /* GDBusInterfaceInfo */
193                                          opt_name,
194                                          opt_object_path,
195                                          opt_interface,
196                                          NULL, /* GCancellable */
197                                          &error);
198   if (proxy == NULL)
199     {
200       g_printerr ("Error creating proxy: %s\n", error->message);
201       g_error_free (error);
202       goto out;
203     }
204
205   g_signal_connect (proxy,
206                     "g-properties-changed",
207                     G_CALLBACK (on_properties_changed),
208                     NULL);
209   g_signal_connect (proxy,
210                     "g-signal",
211                     G_CALLBACK (on_signal),
212                     NULL);
213   g_signal_connect (proxy,
214                     "notify::g-name-owner",
215                     G_CALLBACK (on_name_owner_notify),
216                     NULL);
217   print_proxy (proxy);
218
219   g_main_loop_run (loop);
220
221  out:
222   if (proxy != NULL)
223     g_object_unref (proxy);
224   if (loop != NULL)
225     g_main_loop_unref (loop);
226   g_option_context_free (opt_context);
227   g_free (opt_name);
228   g_free (opt_object_path);
229   g_free (opt_interface);
230
231   return 0;
232 }