Merge branch 'gdbus-merge'
[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_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   { "auto-start", 'a', 0, G_OPTION_ARG_NONE, &opt_auto_start, "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 void
22 print_properties (GDBusProxy *proxy)
23 {
24   gchar **property_names;
25   guint n;
26
27   g_print ("    properties:\n");
28
29   property_names = g_dbus_proxy_get_cached_property_names (proxy);
30   for (n = 0; property_names != NULL && property_names[n] != NULL; n++)
31     {
32       const gchar *key = property_names[n];
33       GVariant *value;
34       gchar *value_str;
35       value = g_dbus_proxy_get_cached_property (proxy, key);
36       value_str = g_variant_print (value, TRUE);
37       g_print ("      %s -> %s\n", key, value_str);
38       g_variant_unref (value);
39       g_free (value_str);
40     }
41   g_strfreev (property_names);
42 }
43
44 static void
45 on_properties_changed (GDBusProxy          *proxy,
46                        GVariant            *changed_properties,
47                        const gchar* const  *invalidated_properties,
48                        gpointer             user_data)
49 {
50   /* Note that we are guaranteed that changed_properties and
51    * invalidated_properties are never NULL
52    */
53
54   if (g_variant_n_children (changed_properties) > 0)
55     {
56       GVariantIter *iter;
57       GVariant *item;
58
59       g_print (" *** Properties Changed:\n");
60       g_variant_get (changed_properties,
61                      "a{sv}",
62                      &iter);
63       while ((item = g_variant_iter_next_value (iter)))
64         {
65           const gchar *key;
66           GVariant *value;
67           gchar *value_str;
68           g_variant_get (item,
69                          "{sv}",
70                          &key,
71                          &value);
72           value_str = g_variant_print (value, TRUE);
73           g_print ("      %s -> %s\n", key, value_str);
74           g_free (value_str);
75         }
76     }
77
78   if (g_strv_length ((GStrv) invalidated_properties) > 0)
79     {
80       guint n;
81       g_print (" *** Properties Invalidated:\n");
82       for (n = 0; invalidated_properties[n] != NULL; n++)
83         {
84           const gchar *key = invalidated_properties[n];
85           g_print ("      %s\n", key);
86         }
87     }
88 }
89
90 static void
91 on_signal (GDBusProxy *proxy,
92            gchar      *sender_name,
93            gchar      *signal_name,
94            GVariant   *parameters,
95            gpointer    user_data)
96 {
97   gchar *parameters_str;
98
99   parameters_str = g_variant_print (parameters, TRUE);
100   g_print (" *** Received Signal: %s: %s\n",
101            signal_name,
102            parameters_str);
103   g_free (parameters_str);
104 }
105
106 static void
107 on_proxy_appeared (GDBusConnection *connection,
108                    const gchar     *name,
109                    const gchar     *name_owner,
110                    GDBusProxy      *proxy,
111                    gpointer         user_data)
112 {
113   g_print ("+++ Acquired proxy object for remote object owned by %s\n"
114            "    bus:          %s\n"
115            "    name:         %s\n"
116            "    object path:  %s\n"
117            "    interface:    %s\n",
118            name_owner,
119            opt_system_bus ? "System Bus" : "Session Bus",
120            opt_name,
121            opt_object_path,
122            opt_interface);
123
124   print_properties (proxy);
125
126   g_signal_connect (proxy,
127                     "g-properties-changed",
128                     G_CALLBACK (on_properties_changed),
129                     NULL);
130
131   g_signal_connect (proxy,
132                     "g-signal",
133                     G_CALLBACK (on_signal),
134                     NULL);
135 }
136
137 static void
138 on_proxy_vanished (GDBusConnection *connection,
139                    const gchar     *name,
140                    gpointer         user_data)
141 {
142   g_print ("--- Cannot create proxy object for\n"
143            "    bus:          %s\n"
144            "    name:         %s\n"
145            "    object path:  %s\n"
146            "    interface:    %s\n",
147            opt_system_bus ? "System Bus" : "Session Bus",
148            opt_name,
149            opt_object_path,
150            opt_interface);
151 }
152
153 int
154 main (int argc, char *argv[])
155 {
156   guint watcher_id;
157   GMainLoop *loop;
158   GOptionContext *opt_context;
159   GError *error;
160   GBusNameWatcherFlags flags;
161   GDBusProxyFlags proxy_flags;
162
163   g_type_init ();
164
165   opt_context = g_option_context_new ("g_bus_watch_proxy() example");
166   g_option_context_set_summary (opt_context,
167                                 "Example: to watch the object of gdbus-example-server, use:\n"
168                                 "\n"
169                                 "  ./gdbus-example-watch-proxy -n org.gtk.GDBus.TestServer  \\\n"
170                                 "                              -o /org/gtk/GDBus/TestObject \\\n"
171                                 "                              -i org.gtk.GDBus.TestInterface");
172   g_option_context_add_main_entries (opt_context, opt_entries, NULL);
173   error = NULL;
174   if (!g_option_context_parse (opt_context, &argc, &argv, &error))
175     {
176       g_printerr ("Error parsing options: %s", error->message);
177       goto out;
178     }
179   if (opt_name == NULL || opt_object_path == NULL || opt_interface == NULL)
180     {
181       g_printerr ("Incorrect usage, try --help.\n");
182       goto out;
183     }
184
185   flags = G_BUS_NAME_WATCHER_FLAGS_NONE;
186   if (opt_auto_start)
187     flags |= G_BUS_NAME_WATCHER_FLAGS_AUTO_START;
188
189   proxy_flags = G_DBUS_PROXY_FLAGS_NONE;
190   if (opt_no_properties)
191     proxy_flags |= G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES;
192
193   watcher_id = g_bus_watch_proxy (opt_system_bus ? G_BUS_TYPE_SYSTEM : G_BUS_TYPE_SESSION,
194                                   opt_name,
195                                   flags,
196                                   opt_object_path,
197                                   opt_interface,
198                                   G_TYPE_DBUS_PROXY,
199                                   proxy_flags,
200                                   on_proxy_appeared,
201                                   on_proxy_vanished,
202                                   NULL,
203                                   NULL);
204
205   loop = g_main_loop_new (NULL, FALSE);
206   g_main_loop_run (loop);
207
208   g_bus_unwatch_proxy (watcher_id);
209
210  out:
211   g_option_context_free (opt_context);
212   g_free (opt_name);
213   g_free (opt_object_path);
214   g_free (opt_interface);
215
216   return 0;
217 }