2 * Copyright © 2010 Red Hat, Inc.
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2 of the licence or (at
7 * your option) any later version.
9 * See the included COPYING file for more information.
11 * Author: David Zeuthen <davidz@redhat.com>
18 /* ---------------------------------------------------------------------------------------------------- */
20 static GDBusNodeInfo *introspection_data = NULL;
21 static const GDBusInterfaceInfo *manager_interface_info = NULL;
22 static const GDBusInterfaceInfo *block_interface_info = NULL;
23 static const GDBusInterfaceInfo *partition_interface_info = NULL;
25 /* Introspection data for the service we are exporting */
26 static const gchar introspection_xml[] =
28 " <interface name='org.gtk.GDBus.Example.Manager'>"
29 " <method name='Hello'>"
30 " <arg type='s' name='greeting' direction='in'/>"
31 " <arg type='s' name='response' direction='out'/>"
34 " <interface name='org.gtk.GDBus.Example.Block'>"
35 " <method name='Hello'>"
36 " <arg type='s' name='greeting' direction='in'/>"
37 " <arg type='s' name='response' direction='out'/>"
39 " <property type='i' name='Major' access='read'/>"
40 " <property type='i' name='Minor' access='read'/>"
41 " <property type='s' name='Notes' access='readwrite'/>"
43 " <interface name='org.gtk.GDBus.Example.Partition'>"
44 " <method name='Hello'>"
45 " <arg type='s' name='greeting' direction='in'/>"
46 " <arg type='s' name='response' direction='out'/>"
48 " <property type='i' name='PartitionNumber' access='read'/>"
49 " <property type='s' name='Notes' access='readwrite'/>"
53 /* ---------------------------------------------------------------------------------------------------- */
56 manager_method_call (GDBusConnection *connection,
58 const gchar *object_path,
59 const gchar *interface_name,
60 const gchar *method_name,
62 GDBusMethodInvocation *invocation,
65 const gchar *greeting;
68 g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.Example.Manager");
69 g_assert_cmpstr (method_name, ==, "Hello");
71 g_variant_get (parameters, "(s)", &greeting);
73 response = g_strdup_printf ("Method %s.%s with user_data `%s' on object path %s called with arg '%s'",
76 (const gchar *) user_data,
79 g_dbus_method_invocation_return_value (invocation,
80 g_variant_new ("(s)", response));
84 const GDBusInterfaceVTable manager_vtable =
87 NULL, /* get_property */
88 NULL /* set_property */
91 /* ---------------------------------------------------------------------------------------------------- */
94 block_method_call (GDBusConnection *connection,
96 const gchar *object_path,
97 const gchar *interface_name,
98 const gchar *method_name,
100 GDBusMethodInvocation *invocation,
103 g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.Example.Block");
105 if (g_strcmp0 (method_name, "Hello") == 0)
107 const gchar *greeting;
110 g_variant_get (parameters, "(s)", &greeting);
112 response = g_strdup_printf ("Method %s.%s with user_data `%s' on object path %s called with arg '%s'",
115 (const gchar *) user_data,
118 g_dbus_method_invocation_return_value (invocation,
119 g_variant_new ("(s)", response));
122 else if (g_strcmp0 (method_name, "DoStuff") == 0)
124 g_dbus_method_invocation_return_dbus_error (invocation,
125 "org.gtk.GDBus.TestSubtree.Error.Failed",
126 "This method intentionally always fails");
130 g_assert_not_reached ();
135 block_get_property (GDBusConnection *connection,
137 const gchar *object_path,
138 const gchar *interface_name,
139 const gchar *property_name,
148 node = strrchr (object_path, '/') + 1;
149 if (g_str_has_prefix (node, "sda"))
153 if (strlen (node) == 4)
154 minor = node[3] - '0';
159 if (g_strcmp0 (property_name, "Major") == 0)
161 ret = g_variant_new_int32 (major);
163 else if (g_strcmp0 (property_name, "Minor") == 0)
165 ret = g_variant_new_int32 (minor);
167 else if (g_strcmp0 (property_name, "Notes") == 0)
172 "Hello %s. I thought I said reading this property "
173 "always results in an error. kthxbye",
178 g_assert_not_reached ();
185 block_set_property (GDBusConnection *connection,
187 const gchar *object_path,
188 const gchar *interface_name,
189 const gchar *property_name,
195 g_assert_not_reached ();
198 const GDBusInterfaceVTable block_vtable =
205 /* ---------------------------------------------------------------------------------------------------- */
208 partition_method_call (GDBusConnection *connection,
210 const gchar *object_path,
211 const gchar *interface_name,
212 const gchar *method_name,
213 GVariant *parameters,
214 GDBusMethodInvocation *invocation,
217 const gchar *greeting;
220 g_assert_cmpstr (interface_name, ==, "org.gtk.GDBus.Example.Partition");
221 g_assert_cmpstr (method_name, ==, "Hello");
223 g_variant_get (parameters, "(s)", &greeting);
225 response = g_strdup_printf ("Method %s.%s with user_data `%s' on object path %s called with arg '%s'",
228 (const gchar *) user_data,
231 g_dbus_method_invocation_return_value (invocation,
232 g_variant_new ("(s)", response));
236 const GDBusInterfaceVTable partition_vtable =
238 partition_method_call,
239 //partition_get_property,
240 //partition_set_property
243 /* ---------------------------------------------------------------------------------------------------- */
246 subtree_enumerate (GDBusConnection *connection,
248 const gchar *object_path,
254 p = g_ptr_array_new ();
255 g_ptr_array_add (p, g_strdup ("sda"));
256 g_ptr_array_add (p, g_strdup ("sda1"));
257 g_ptr_array_add (p, g_strdup ("sda2"));
258 g_ptr_array_add (p, g_strdup ("sda3"));
259 g_ptr_array_add (p, g_strdup ("sdb"));
260 g_ptr_array_add (p, g_strdup ("sdb1"));
261 g_ptr_array_add (p, g_strdup ("sdc"));
262 g_ptr_array_add (p, g_strdup ("sdc1"));
263 g_ptr_array_add (p, NULL);
264 nodes = (gchar **) g_ptr_array_free (p, FALSE);
270 subtree_introspect (GDBusConnection *connection,
272 const gchar *object_path,
278 p = g_ptr_array_new ();
279 if (g_strcmp0 (node, "/") == 0)
281 g_ptr_array_add (p, (gpointer) manager_interface_info);
285 g_ptr_array_add (p, (gpointer) block_interface_info);
286 if (strlen (node) == 4)
287 g_ptr_array_add (p, (gpointer) partition_interface_info);
293 static const GDBusInterfaceVTable *
294 subtree_dispatch (GDBusConnection *connection,
296 const gchar *object_path,
297 const gchar *interface_name,
299 gpointer *out_user_data,
302 const GDBusInterfaceVTable *vtable_to_return;
303 gpointer user_data_to_return;
305 if (g_strcmp0 (interface_name, "org.gtk.GDBus.Example.Manager") == 0)
307 user_data_to_return = "The Root";
308 vtable_to_return = &manager_vtable;
312 if (strlen (node) == 4)
313 user_data_to_return = "A partition";
315 user_data_to_return = "A block device";
317 if (g_strcmp0 (interface_name, "org.gtk.GDBus.Example.Block") == 0)
318 vtable_to_return = &block_vtable;
319 else if (g_strcmp0 (interface_name, "org.gtk.GDBus.Example.Partition") == 0)
320 vtable_to_return = &partition_vtable;
322 g_assert_not_reached ();
325 *out_user_data = user_data_to_return;
327 return vtable_to_return;
330 const GDBusSubtreeVTable subtree_vtable =
337 /* ---------------------------------------------------------------------------------------------------- */
340 on_bus_acquired (GDBusConnection *connection,
344 guint registration_id;
346 registration_id = g_dbus_connection_register_subtree (connection,
347 "/org/gtk/GDBus/TestSubtree/Devices",
349 G_DBUS_SUBTREE_FLAGS_NONE,
350 NULL, /* user_data */
351 NULL, /* user_data_free_func */
352 NULL); /* GError** */
353 g_assert (registration_id > 0);
357 on_name_acquired (GDBusConnection *connection,
364 on_name_lost (GDBusConnection *connection,
372 main (int argc, char *argv[])
379 /* We are lazy here - we don't want to manually provide
380 * the introspection data structures - so we just build
383 introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
384 g_assert (introspection_data != NULL);
386 manager_interface_info = g_dbus_node_info_lookup_interface (introspection_data, "org.gtk.GDBus.Example.Manager");
387 block_interface_info = g_dbus_node_info_lookup_interface (introspection_data, "org.gtk.GDBus.Example.Block");
388 partition_interface_info = g_dbus_node_info_lookup_interface (introspection_data, "org.gtk.GDBus.Example.Partition");
389 g_assert (manager_interface_info != NULL);
390 g_assert (block_interface_info != NULL);
391 g_assert (partition_interface_info != NULL);
393 owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
394 "org.gtk.GDBus.TestSubtree",
395 G_BUS_NAME_OWNER_FLAGS_NONE,
402 loop = g_main_loop_new (NULL, FALSE);
403 g_main_loop_run (loop);
405 g_bus_unown_name (owner_id);
407 g_dbus_node_info_unref (introspection_data);