summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2005-01-30 05:18:44 +0000
committerHavoc Pennington <hp@redhat.com>2005-01-30 05:18:44 +0000
commit41f52c96d651003b3d0a266a582d401228a8368e (patch)
tree3b217cef0c0b9db03aa580cb541b7d686732055a
parent2922b0e88ba00b0067c23633075629108ad8a496 (diff)
2005-01-30 Havoc Pennington <hp@redhat.com>
dbus-viewer introspected and displayed the bus driver * dbus/dbus-object-tree.c (object_tree_test_iteration): add tests for a handler registered on "/" * dbus/dbus-object-tree.c (_dbus_decompose_path): fix to handle path "/" properly (run_decompose_tests): add tests for path decomposition * glib/dbus-gutils.c (_dbus_gutils_split_path): fix to handle "/" properly * glib/dbus-gobject.c (handle_introspect): fix quotes * test/glib/run-test.sh: support launching the bus, then running dbus-viewer * test/glib/test-service-glib.c (main): put in a trivial gobject subclass and register it on the connection * bus/driver.c (bus_driver_handle_introspect): implement introspection of the bus driver service * dbus/dbus-protocol.h: add #defines for the XML namespace, identifiers, doctype decl * bus/driver.c (bus_driver_handle_get_service_owner): handle attempts to get owner of DBUS_SERVICE_ORG_FREEDESKTOP_DBUS by returning the service unchanged. (bus_driver_handle_message): remove old check for reply_serial in method calls, now the message type deals with that (bus_driver_handle_message): handle NULL interface * glib/dbus-gproxy.c (dbus_g_proxy_get_bus_name): new function * glib/dbus-gloader-expat.c (description_load_from_string): allow -1 for len * tools/dbus-viewer.c: add support for introspecting a service on a bus * glib/dbus-gproxy.c (dbus_g_pending_call_ref): add (dbus_g_pending_call_unref): add
-rw-r--r--ChangeLog48
-rw-r--r--bus/driver.c134
-rw-r--r--dbus/dbus-glib.h3
-rw-r--r--dbus/dbus-marshal-validate.c2
-rw-r--r--dbus/dbus-object-tree.c266
-rw-r--r--dbus/dbus-protocol.h6
-rw-r--r--glib/dbus-gidl.c14
-rw-r--r--glib/dbus-gidl.h3
-rw-r--r--glib/dbus-gloader-expat.c4
-rw-r--r--glib/dbus-gobject.c16
-rw-r--r--glib/dbus-gproxy.c62
-rw-r--r--glib/dbus-gutils.c20
-rwxr-xr-xtest/glib/run-test.sh9
-rw-r--r--test/glib/test-service-glib.c46
-rw-r--r--tools/dbus-viewer.c145
15 files changed, 666 insertions, 112 deletions
diff --git a/ChangeLog b/ChangeLog
index d964d45a..dcb3a6de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,49 @@
+2005-01-30 Havoc Pennington <hp@redhat.com>
+
+ dbus-viewer introspected and displayed the bus driver
+
+ * dbus/dbus-object-tree.c
+ (object_tree_test_iteration): add tests for a handler registered on "/"
+
+ * dbus/dbus-object-tree.c
+ (_dbus_decompose_path): fix to handle path "/" properly
+ (run_decompose_tests): add tests for path decomposition
+
+ * glib/dbus-gutils.c (_dbus_gutils_split_path): fix to handle "/"
+ properly
+
+ * glib/dbus-gobject.c (handle_introspect): fix quotes
+
+ * test/glib/run-test.sh: support launching the bus, then running
+ dbus-viewer
+
+ * test/glib/test-service-glib.c (main): put in a trivial gobject
+ subclass and register it on the connection
+
+ * bus/driver.c (bus_driver_handle_introspect): implement
+ introspection of the bus driver service
+
+ * dbus/dbus-protocol.h: add #defines for the XML namespace,
+ identifiers, doctype decl
+
+ * bus/driver.c (bus_driver_handle_get_service_owner): handle
+ attempts to get owner of DBUS_SERVICE_ORG_FREEDESKTOP_DBUS by
+ returning the service unchanged.
+ (bus_driver_handle_message): remove old check for reply_serial in
+ method calls, now the message type deals with that
+ (bus_driver_handle_message): handle NULL interface
+
+ * glib/dbus-gproxy.c (dbus_g_proxy_get_bus_name): new function
+
+ * glib/dbus-gloader-expat.c (description_load_from_string): allow
+ -1 for len
+
+ * tools/dbus-viewer.c: add support for introspecting a service on
+ a bus
+
+ * glib/dbus-gproxy.c (dbus_g_pending_call_ref): add
+ (dbus_g_pending_call_unref): add
+
2005-01-29 Havoc Pennington <hp@redhat.com>
* tools/dbus-tree-view.c: add support for displaying properties.
@@ -6,7 +52,7 @@
* glib/dbus-gobject.c (handle_introspect): return
org.freedesktop.Properties and org.freedesktop.Introspectable
- interfaces when we are introspected.
+ interfaces when we are introspected.
* doc/dbus-specification.xml: allow empty interface name when
Get/Set a property
diff --git a/bus/driver.c b/bus/driver.c
index 3a9e555d..58b8fcbf 100644
--- a/bus/driver.c
+++ b/bus/driver.c
@@ -792,24 +792,34 @@ bus_driver_handle_get_service_owner (DBusConnection *connection,
_dbus_string_init_const (&str, text);
service = bus_registry_lookup (registry, &str);
- if (service == NULL)
+ if (service == NULL &&
+ _dbus_string_equal_c_str (&str, DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
+ {
+ /* ORG_FREEDESKTOP_DBUS owns itself */
+ base_name = DBUS_SERVICE_ORG_FREEDESKTOP_DBUS;
+ }
+ else if (service == NULL)
{
dbus_set_error (error,
- DBUS_ERROR_NAME_HAS_NO_OWNER,
- "Could not get owner of name '%s': no such name", text);
+ DBUS_ERROR_NAME_HAS_NO_OWNER,
+ "Could not get owner of name '%s': no such name", text);
goto failed;
}
-
- base_name = bus_connection_get_name (bus_service_get_primary_owner (service));
- if (base_name == NULL)
+ else
{
- /* FIXME - how is this error possible? */
- dbus_set_error (error,
- DBUS_ERROR_FAILED,
- "Could not determine unique name for '%s'", text);
- goto failed;
+ base_name = bus_connection_get_name (bus_service_get_primary_owner (service));
+ if (base_name == NULL)
+ {
+ /* FIXME - how is this error possible? */
+ dbus_set_error (error,
+ DBUS_ERROR_FAILED,
+ "Could not determine unique name for '%s'", text);
+ goto failed;
+ }
+ _dbus_assert (*base_name == ':');
}
- _dbus_assert (*base_name == ':');
+
+ _dbus_assert (base_name != NULL);
reply = dbus_message_new_method_return (message);
if (reply == NULL)
@@ -1040,13 +1050,89 @@ struct
{ "ReloadConfig", bus_driver_handle_reload_config }
};
+static dbus_bool_t
+bus_driver_handle_introspect (DBusConnection *connection,
+ BusTransaction *transaction,
+ DBusMessage *message,
+ DBusError *error)
+{
+ DBusString xml;
+ DBusMessage *reply;
+ const char *v_STRING;
+
+ _dbus_verbose ("Introspect() on bus driver\n");
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ reply = NULL;
+
+ if (! dbus_message_get_args (message, error,
+ DBUS_TYPE_INVALID))
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ return FALSE;
+ }
+
+ if (!_dbus_string_init (&xml))
+ {
+ BUS_SET_OOM (error);
+ return FALSE;
+ }
+
+ if (!_dbus_string_append (&xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE))
+ goto oom;
+ if (!_dbus_string_append (&xml, "<node>\n"))
+ goto oom;
+ if (!_dbus_string_append (&xml, " <interface name=\"org.freedesktop.Introspectable\">\n"))
+ goto oom;
+ if (!_dbus_string_append (&xml, " <method name=\"Introspect\">\n"))
+ goto oom;
+ if (!_dbus_string_append (&xml, " <arg name=\"data\" direction=\"out\" type=\"string\"/>\n"))
+ goto oom;
+ if (!_dbus_string_append (&xml, " </method>\n"))
+ goto oom;
+ if (!_dbus_string_append (&xml, " </interface>\n"))
+ goto oom;
+
+ if (!_dbus_string_append (&xml, "</node>\n"))
+ goto oom;
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ goto oom;
+
+ v_STRING = _dbus_string_get_const_data (&xml);
+ if (! dbus_message_append_args (reply,
+ DBUS_TYPE_STRING, &v_STRING,
+ DBUS_TYPE_INVALID))
+ goto oom;
+
+ if (! bus_transaction_send_from_driver (transaction, connection, reply))
+ goto oom;
+
+ dbus_message_unref (reply);
+ _dbus_string_free (&xml);
+
+ return TRUE;
+
+ oom:
+ BUS_SET_OOM (error);
+
+ if (reply)
+ dbus_message_unref (reply);
+
+ _dbus_string_free (&xml);
+
+ return FALSE;
+}
+
dbus_bool_t
bus_driver_handle_message (DBusConnection *connection,
BusTransaction *transaction,
DBusMessage *message,
DBusError *error)
{
- const char *name, *sender;
+ const char *name, *sender, *interface;
int i;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
@@ -1057,17 +1143,25 @@ bus_driver_handle_message (DBusConnection *connection,
return TRUE; /* we just ignore this */
}
- _dbus_assert (dbus_message_get_interface (message) != NULL);
+ if (dbus_message_is_method_call (message,
+ DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE,
+ "Introspect"))
+ return bus_driver_handle_introspect (connection, transaction, message, error);
+
+ interface = dbus_message_get_interface (message);
+ if (interface == NULL)
+ interface = DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS;
+
_dbus_assert (dbus_message_get_member (message) != NULL);
-
+
name = dbus_message_get_member (message);
sender = dbus_message_get_sender (message);
- if (strcmp (dbus_message_get_interface (message),
+ if (strcmp (interface,
DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS) != 0)
{
_dbus_verbose ("Driver got message to unknown interface \"%s\"\n",
- dbus_message_get_interface (message));
+ interface);
goto unknown;
}
@@ -1076,12 +1170,6 @@ bus_driver_handle_message (DBusConnection *connection,
/* security checks should have kept this from getting here */
_dbus_assert (sender != NULL || strcmp (name, "Hello") == 0);
-
- if (dbus_message_get_reply_serial (message) != 0)
- {
- _dbus_verbose ("Client sent a reply to the bus driver, ignoring it\n");
- return TRUE;
- }
i = 0;
while (i < _DBUS_N_ELEMENTS (message_handlers))
diff --git a/dbus/dbus-glib.h b/dbus/dbus-glib.h
index de53d14a..3e73b98f 100644
--- a/dbus/dbus-glib.h
+++ b/dbus/dbus-glib.h
@@ -145,7 +145,10 @@ void dbus_g_proxy_call_no_reply (DBusGProxy *proxy,
const char *method,
int first_arg_type,
...);
+const char* dbus_g_proxy_get_bus_name (DBusGProxy *proxy);
+DBusGPendingCall* dbus_g_pending_call_ref (DBusGPendingCall *call);
+void dbus_g_pending_call_unref (DBusGPendingCall *call);
#undef DBUS_INSIDE_DBUS_GLIB_H
diff --git a/dbus/dbus-marshal-validate.c b/dbus/dbus-marshal-validate.c
index e57be5c7..d9b85cb7 100644
--- a/dbus/dbus-marshal-validate.c
+++ b/dbus/dbus-marshal-validate.c
@@ -573,7 +573,7 @@ _dbus_validate_path (const DBusString *str,
_dbus_assert (start >= 0);
_dbus_assert (len >= 0);
_dbus_assert (start <= _dbus_string_get_length (str));
-
+
if (len > _dbus_string_get_length (str) - start)
return FALSE;
diff --git a/dbus/dbus-object-tree.c b/dbus/dbus-object-tree.c
index 694185fb..f8797595 100644
--- a/dbus/dbus-object-tree.c
+++ b/dbus/dbus-object-tree.c
@@ -630,6 +630,9 @@ handle_default_introspect_unlocked (DBusObjectTree *tree,
if (!_dbus_object_tree_list_registered_unlocked (tree, path, &children))
goto out;
+ if (!_dbus_string_append (&xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE))
+ goto out;
+
if (!_dbus_string_append (&xml, "<node>\n"))
goto out;
@@ -945,6 +948,7 @@ _dbus_object_tree_list_registered_and_unlock (DBusObjectTree *tree,
/**
* Decompose an object path. A path of just "/" is
* represented as an empty vector of strings.
+ * The path need not be nul terminated.
*
* @param data the path data
* @param len the length of the path string
@@ -962,19 +966,22 @@ _dbus_decompose_path (const char* data,
int i, j, comp;
_dbus_assert (data != NULL);
-
+
#if VERBOSE_DECOMPOSE
_dbus_verbose ("Decomposing path \"%s\"\n",
data);
#endif
n_components = 0;
- i = 0;
- while (i < len)
+ if (len > 1) /* if path is not just "/" */
{
- if (data[i] == '/')
- n_components += 1;
- ++i;
+ i = 0;
+ while (i < len)
+ {
+ if (data[i] == '/')
+ n_components += 1;
+ ++i;
+ }
}
retval = dbus_new0 (char*, n_components + 1);
@@ -983,9 +990,14 @@ _dbus_decompose_path (const char* data,
return FALSE;
comp = 0;
- i = 0;
- while (i < len)
+ if (n_components == 0)
+ i = 1;
+ else
+ i = 0;
+ while (comp < n_components)
{
+ _dbus_assert (i < len);
+
if (data[i] == '/')
++i;
j = i;
@@ -1037,22 +1049,31 @@ static char*
flatten_path (const char **path)
{
DBusString str;
- int i;
char *s;
if (!_dbus_string_init (&str))
return NULL;
- i = 0;
- while (path[i])
+ if (path[0] == NULL)
{
if (!_dbus_string_append_byte (&str, '/'))
goto nomem;
-
- if (!_dbus_string_append (&str, path[i]))
- goto nomem;
-
- ++i;
+ }
+ else
+ {
+ int i;
+
+ i = 0;
+ while (path[i])
+ {
+ if (!_dbus_string_append_byte (&str, '/'))
+ goto nomem;
+
+ if (!_dbus_string_append (&str, path[i]))
+ goto nomem;
+
+ ++i;
+ }
}
if (!_dbus_string_steal_data (&str, &s))
@@ -1191,7 +1212,7 @@ do_register (DBusObjectTree *tree,
{
DBusObjectPathVTable vtable = { test_unregister_function,
test_message_function, NULL };
-
+
tree_test_data[i].message_handled = FALSE;
tree_test_data[i].handler_unregistered = FALSE;
tree_test_data[i].handler_fallback = fallback;
@@ -1278,17 +1299,82 @@ do_test_dispatch (DBusObjectTree *tree,
}
static size_t
-string_array_length (char **array)
+string_array_length (const char **array)
{
size_t i;
for (i = 0; array[i]; i++) ;
return i;
}
+typedef struct
+{
+ const char *path;
+ const char *result[20];
+} DecomposePathTest;
+
+static DecomposePathTest decompose_tests[] = {
+ { "/foo", { "foo", NULL } },
+ { "/foo/bar", { "foo", "bar", NULL } },
+ { "/", { NULL } },
+ { "/a/b", { "a", "b", NULL } },
+ { "/a/b/c", { "a", "b", "c", NULL } },
+ { "/a/b/c/d", { "a", "b", "c", "d", NULL } },
+ { "/foo/bar/q", { "foo", "bar", "q", NULL } },
+ { "/foo/bar/this/is/longer", { "foo", "bar", "this", "is", "longer", NULL } }
+};
+
+static dbus_bool_t
+run_decompose_tests (void)
+{
+ int i;
+
+ i = 0;
+ while (i < _DBUS_N_ELEMENTS (decompose_tests))
+ {
+ char **result;
+ int result_len;
+ int expected_len;
+
+ if (!_dbus_decompose_path (decompose_tests[i].path,
+ strlen (decompose_tests[i].path),
+ &result, &result_len))
+ return FALSE;
+
+ expected_len = string_array_length (decompose_tests[i].result);
+
+ if (result_len != (int) string_array_length ((const char**)result) ||
+ expected_len != result_len ||
+ path_contains (decompose_tests[i].result,
+ (const char**) result) != STR_EQUAL)
+ {
+ int real_len = string_array_length ((const char**)result);
+ _dbus_warn ("Expected decompose of %s to have len %d, returned %d, appears to have %d\n",
+ decompose_tests[i].path, expected_len, result_len,
+ real_len);
+ _dbus_warn ("Decompose resulted in elements: { ");
+ i = 0;
+ while (i < real_len)
+ {
+ _dbus_warn ("\"%s\"%s", result[i],
+ (i + 1) == real_len ? "" : ", ");
+ ++i;
+ }
+ _dbus_warn ("}\n");
+ _dbus_assert_not_reached ("path decompose failed\n");
+ }
+
+ dbus_free_string_array (result);
+
+ ++i;
+ }
+
+ return TRUE;
+}
static dbus_bool_t
object_tree_test_iteration (void *data)
{
+ const char *path0[] = { NULL };
const char *path1[] = { "foo", NULL };
const char *path2[] = { "foo", "bar", NULL };
const char *path3[] = { "foo", "bar", "baz", NULL };
@@ -1298,19 +1384,46 @@ object_tree_test_iteration (void *data)
const char *path7[] = { "blah", "boof", "this", "is", "really", "long", NULL };
const char *path8[] = { "childless", NULL };
DBusObjectTree *tree;
- TreeTestData tree_test_data[8];
+ TreeTestData tree_test_data[9];
int i;
dbus_bool_t exact_match;
+ if (!run_decompose_tests ())
+ return FALSE;
+
tree = NULL;
tree = _dbus_object_tree_new (NULL);
if (tree == NULL)
goto out;
- if (!do_register (tree, path1, TRUE, 0, tree_test_data))
+ if (!do_register (tree, path0, TRUE, 0, tree_test_data))
+ goto out;
+
+ _dbus_assert (find_subtree (tree, path0, NULL));
+ _dbus_assert (!find_subtree (tree, path1, NULL));
+ _dbus_assert (!find_subtree (tree, path2, NULL));
+ _dbus_assert (!find_subtree (tree, path3, NULL));
+ _dbus_assert (!find_subtree (tree, path4, NULL));
+ _dbus_assert (!find_subtree (tree, path5, NULL));
+ _dbus_assert (!find_subtree (tree, path6, NULL));
+ _dbus_assert (!find_subtree (tree, path7, NULL));
+ _dbus_assert (!find_subtree (tree, path8, NULL));
+
+ _dbus_assert (find_handler (tree, path0, &exact_match) && exact_match);
+ _dbus_assert (find_handler (tree, path1, &exact_match) == tree->root && !exact_match);
+ _dbus_assert (find_handler (tree, path2, &exact_match) == tree->root && !exact_match);
+ _dbus_assert (find_handler (tree, path3, &exact_match) == tree->root && !exact_match);
+ _dbus_assert (find_handler (tree, path4, &exact_match) == tree->root && !exact_match);
+ _dbus_assert (find_handler (tree, path5, &exact_match) == tree->root && !exact_match);
+ _dbus_assert (find_handler (tree, path6, &exact_match) == tree->root && !exact_match);
+ _dbus_assert (find_handler (tree, path7, &exact_match) == tree->root && !exact_match);
+ _dbus_assert (find_handler (tree, path8, &exact_match) == tree->root && !exact_match);
+
+ if (!do_register (tree, path1, TRUE, 1, tree_test_data))
goto out;
+ _dbus_assert (find_subtree (tree, path0, NULL));
_dbus_assert (find_subtree (tree, path1, NULL));
_dbus_assert (!find_subtree (tree, path2, NULL));
_dbus_assert (!find_subtree (tree, path3, NULL));
@@ -1320,6 +1433,7 @@ object_tree_test_iteration (void *data)
_dbus_assert (!find_subtree (tree, path7, NULL));
_dbus_assert (!find_subtree (tree, path8, NULL));
+ _dbus_assert (find_handler (tree, path0, &exact_match) && exact_match);
_dbus_assert (find_handler (tree, path1, &exact_match) && exact_match);
_dbus_assert (find_handler (tree, path2, &exact_match) && !exact_match);
_dbus_assert (find_handler (tree, path3, &exact_match) && !exact_match);
@@ -1329,7 +1443,7 @@ object_tree_test_iteration (void *data)
_dbus_assert (find_handler (tree, path7, &exact_match) == tree->root && !exact_match);
_dbus_assert (find_handler (tree, path8, &exact_match) == tree->root && !exact_match);
- if (!do_register (tree, path2, TRUE, 1, tree_test_data))
+ if (!do_register (tree, path2, TRUE, 2, tree_test_data))
goto out;
_dbus_assert (find_subtree (tree, path1, NULL));
@@ -1341,9 +1455,10 @@ object_tree_test_iteration (void *data)
_dbus_assert (!find_subtree (tree, path7, NULL));
_dbus_assert (!find_subtree (tree, path8, NULL));
- if (!do_register (tree, path3, TRUE, 2, tree_test_data))
+ if (!do_register (tree, path3, TRUE, 3, tree_test_data))
goto out;
+ _dbus_assert (find_subtree (tree, path0, NULL));
_dbus_assert (find_subtree (tree, path1, NULL));
_dbus_assert (find_subtree (tree, path2, NULL));
_dbus_assert (find_subtree (tree, path3, NULL));
@@ -1353,9 +1468,10 @@ object_tree_test_iteration (void *data)
_dbus_assert (!find_subtree (tree, path7, NULL));
_dbus_assert (!find_subtree (tree, path8, NULL));
- if (!do_register (tree, path4, TRUE, 3, tree_test_data))
+ if (!do_register (tree, path4, TRUE, 4, tree_test_data))
goto out;
+ _dbus_assert (find_subtree (tree, path0, NULL));
_dbus_assert (find_subtree (tree, path1, NULL));
_dbus_assert (find_subtree (tree, path2, NULL));
_dbus_assert (find_subtree (tree, path3, NULL));
@@ -1365,9 +1481,10 @@ object_tree_test_iteration (void *data)
_dbus_assert (!find_subtree (tree, path7, NULL));
_dbus_assert (!find_subtree (tree, path8, NULL));
- if (!do_register (tree, path5, TRUE, 4, tree_test_data))
+ if (!do_register (tree, path5, TRUE, 5, tree_test_data))
goto out;
+ _dbus_assert (find_subtree (tree, path0, NULL));
_dbus_assert (find_subtree (tree, path1, NULL));
_dbus_assert (find_subtree (tree, path2, NULL));
_dbus_assert (find_subtree (tree, path3, NULL));
@@ -1376,7 +1493,8 @@ object_tree_test_iteration (void *data)
_dbus_assert (!find_subtree (tree, path6, NULL));
_dbus_assert (!find_subtree (tree, path7, NULL));
_dbus_assert (!find_subtree (tree, path8, NULL));
-
+
+ _dbus_assert (find_handler (tree, path0, &exact_match) == tree->root && exact_match);
_dbus_assert (find_handler (tree, path1, &exact_match) != tree->root && exact_match);
_dbus_assert (find_handler (tree, path2, &exact_match) != tree->root && exact_match);
_dbus_assert (find_handler (tree, path3, &exact_match) != tree->root && exact_match);
@@ -1386,9 +1504,10 @@ object_tree_test_iteration (void *data)
_dbus_assert (find_handler (tree, path7, &exact_match) != tree->root && !exact_match);
_dbus_assert (find_handler (tree, path8, &exact_match) == tree->root && !exact_match);
- if (!do_register (tree, path6, TRUE, 5, tree_test_data))
+ if (!do_register (tree, path6, TRUE, 6, tree_test_data))
goto out;
+ _dbus_assert (find_subtree (tree, path0, NULL));
_dbus_assert (find_subtree (tree, path1, NULL));
_dbus_assert (find_subtree (tree, path2, NULL));
_dbus_assert (find_subtree (tree, path3, NULL));
@@ -1398,9 +1517,10 @@ object_tree_test_iteration (void *data)
_dbus_assert (!find_subtree (tree, path7, NULL));
_dbus_assert (!find_subtree (tree, path8, NULL));
- if (!do_register (tree, path7, TRUE, 6, tree_test_data))
+ if (!do_register (tree, path7, TRUE, 7, tree_test_data))
goto out;
+ _dbus_assert (find_subtree (tree, path0, NULL));
_dbus_assert (find_subtree (tree, path1, NULL));
_dbus_assert (find_subtree (tree, path2, NULL));
_dbus_assert (find_subtree (tree, path3, NULL));
@@ -1410,9 +1530,10 @@ object_tree_test_iteration (void *data)
_dbus_assert (find_subtree (tree, path7, NULL));
_dbus_assert (!find_subtree (tree, path8, NULL));
- if (!do_register (tree, path8, TRUE, 7, tree_test_data))
+ if (!do_register (tree, path8, TRUE, 8, tree_test_data))
goto out;
+ _dbus_assert (find_subtree (tree, path0, NULL));
_dbus_assert (find_subtree (tree, path1, NULL));
_dbus_assert (find_subtree (tree, path2, NULL));
_dbus_assert (find_subtree (tree, path3, NULL));
@@ -1421,7 +1542,8 @@ object_tree_test_iteration (void *data)
_dbus_assert (find_subtree (tree, path6, NULL));
_dbus_assert (find_subtree (tree, path7, NULL));
_dbus_assert (find_subtree (tree, path8, NULL));
-
+
+ _dbus_assert (find_handler (tree, path0, &exact_match) == tree->root && exact_match);
_dbus_assert (find_handler (tree, path1, &exact_match) != tree->root && exact_match);
_dbus_assert (find_handler (tree, path2, &exact_match) != tree->root && exact_match);
_dbus_assert (find_handler (tree, path3, &exact_match) != tree->root && exact_match);
@@ -1441,7 +1563,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_list_registered_unlocked (tree, path1, &child_entries);
if (child_entries != NULL)
{
- nb = string_array_length (child_entries);
+ nb = string_array_length ((const char**)child_entries);
_dbus_assert (nb == 1);
dbus_free_string_array (child_entries);
}
@@ -1449,7 +1571,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_list_registered_unlocked (tree, path2, &child_entries);
if (child_entries != NULL)
{
- nb = string_array_length (child_entries);
+ nb = string_array_length ((const char**)child_entries);
_dbus_assert (nb == 2);
dbus_free_string_array (child_entries);
}
@@ -1457,7 +1579,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_list_registered_unlocked (tree, path8, &child_entries);
if (child_entries != NULL)
{
- nb = string_array_length (child_entries);
+ nb = string_array_length ((const char**)child_entries);
_dbus_assert (nb == 0);
dbus_free_string_array (child_entries);
}
@@ -1465,7 +1587,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_list_registered_unlocked (tree, root, &child_entries);
if (child_entries != NULL)
{
- nb = string_array_length (child_entries);
+ nb = string_array_length ((const char**)child_entries);
_dbus_assert (nb == 3);
dbus_free_string_array (child_entries);
}
@@ -1487,25 +1609,40 @@ object_tree_test_iteration (void *data)
if (tree == NULL)
goto out;
- if (!do_register (tree, path1, TRUE, 0, tree_test_data))
+ if (!do_register (tree, path0, TRUE, 0, tree_test_data))
+ goto out;
+ if (!do_register (tree, path1, TRUE, 1, tree_test_data))
goto out;
- if (!do_register (tree, path2, TRUE, 1, tree_test_data))
+ if (!do_register (tree, path2, TRUE, 2, tree_test_data))
goto out;
- if (!do_register (tree, path3, TRUE, 2, tree_test_data))
+ if (!do_register (tree, path3, TRUE, 3, tree_test_data))
goto out;
- if (!do_register (tree, path4, TRUE, 3, tree_test_data))
+ if (!do_register (tree, path4, TRUE, 4, tree_test_data))
goto out;
- if (!do_register (tree, path5, TRUE, 4, tree_test_data))
+ if (!do_register (tree, path5, TRUE, 5, tree_test_data))
goto out;
- if (!do_register (tree, path6, TRUE, 5, tree_test_data))
+ if (!do_register (tree, path6, TRUE, 6, tree_test_data))
goto out;
- if (!do_register (tree, path7, TRUE, 6, tree_test_data))
+ if (!do_register (tree, path7, TRUE, 7, tree_test_data))
goto out;
- if (!do_register (tree, path8, TRUE, 7, tree_test_data))
+ if (!do_register (tree, path8, TRUE, 8, tree_test_data))
goto out;
+
+ _dbus_object_tree_unregister_and_unlock (tree, path0);
+
+ _dbus_assert (!find_subtree (tree, path0, NULL));
+ _dbus_assert (find_subtree (tree, path1, NULL));
+ _dbus_assert (find_subtree (tree, path2, NULL));
+ _dbus_assert (find_subtree (tree, path3, NULL));
+ _dbus_assert (find_subtree (tree, path4, NULL));
+ _dbus_assert (find_subtree (tree, path5, NULL));
+ _dbus_assert (find_subtree (tree, path6, NULL));
+ _dbus_assert (find_subtree (tree, path7, NULL));
+ _dbus_assert (find_subtree (tree, path8, NULL));
_dbus_object_tree_unregister_and_unlock (tree, path1);
+ _dbus_assert (!find_subtree (tree, path0, NULL));
_dbus_assert (!find_subtree (tree, path1, NULL));
_dbus_assert (find_subtree (tree, path2, NULL));
_dbus_assert (find_subtree (tree, path3, NULL));
@@ -1517,6 +1654,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_unregister_and_unlock (tree, path2);
+ _dbus_assert (!find_subtree (tree, path0, NULL));
_dbus_assert (!find_subtree (tree, path1, NULL));
_dbus_assert (!find_subtree (tree, path2, NULL));
_dbus_assert (find_subtree (tree, path3, NULL));
@@ -1528,6 +1666,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_unregister_and_unlock (tree, path3);
+ _dbus_assert (!find_subtree (tree, path0, NULL));
_dbus_assert (!find_subtree (tree, path1, NULL));
_dbus_assert (!find_subtree (tree, path2, NULL));
_dbus_assert (!find_subtree (tree, path3, NULL));
@@ -1539,6 +1678,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_unregister_and_unlock (tree, path4);
+ _dbus_assert (!find_subtree (tree, path0, NULL));
_dbus_assert (!find_subtree (tree, path1, NULL));
_dbus_assert (!find_subtree (tree, path2, NULL));
_dbus_assert (!find_subtree (tree, path3, NULL));
@@ -1550,6 +1690,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_unregister_and_unlock (tree, path5);
+ _dbus_assert (!find_subtree (tree, path0, NULL));
_dbus_assert (!find_subtree (tree, path1, NULL));
_dbus_assert (!find_subtree (tree, path2, NULL));
_dbus_assert (!find_subtree (tree, path3, NULL));
@@ -1561,6 +1702,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_unregister_and_unlock (tree, path6);
+ _dbus_assert (!find_subtree (tree, path0, NULL));
_dbus_assert (!find_subtree (tree, path1, NULL));
_dbus_assert (!find_subtree (tree, path2, NULL));
_dbus_assert (!find_subtree (tree, path3, NULL));
@@ -1572,6 +1714,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_unregister_and_unlock (tree, path7);
+ _dbus_assert (!find_subtree (tree, path0, NULL));
_dbus_assert (!find_subtree (tree, path1, NULL));
_dbus_assert (!find_subtree (tree, path2, NULL));
_dbus_assert (!find_subtree (tree, path3, NULL));
@@ -1583,6 +1726,7 @@ object_tree_test_iteration (void *data)
_dbus_object_tree_unregister_and_unlock (tree, path8);
+ _dbus_assert (!find_subtree (tree, path0, NULL));
_dbus_assert (!find_subtree (tree, path1, NULL));
_dbus_assert (!find_subtree (tree, path2, NULL));
_dbus_assert (!find_subtree (tree, path3, NULL));
@@ -1601,43 +1745,47 @@ object_tree_test_iteration (void *data)
}
/* Register it all again, and test dispatch */
-
- if (!do_register (tree, path1, FALSE, 0, tree_test_data))
+
+ if (!do_register (tree, path0, TRUE, 0, tree_test_data))
+ goto out;
+ if (!do_register (tree, path1, FALSE, 1, tree_test_data))
goto out;
- if (!do_register (tree, path2, TRUE, 1, tree_test_data))
+ if (!do_register (tree, path2, TRUE, 2, tree_test_data))
goto out;
- if (!do_register (tree, path3, TRUE, 2, tree_test_data))
+ if (!do_register (tree, path3, TRUE, 3, tree_test_data))
goto out;
- if (!do_register (tree, path4, TRUE, 3, tree_test_data))
+ if (!do_register (tree, path4, TRUE, 4, tree_test_data))
goto out;
- if (!do_register (tree, path5, TRUE, 4, tree_test_data))
+ if (!do_register (tree, path5, TRUE, 5, tree_test_data))
goto out;
- if (!do_register (tree, path6, FALSE, 5, tree_test_data))
+ if (!do_register (tree, path6, FALSE, 6, tree_test_data))
goto out;
- if (!do_register (tree, path7, TRUE, 6, tree_test_data))
+ if (!do_register (tree, path7, TRUE, 7, tree_test_data))
goto out;
- if (!do_register (tree, path8, TRUE, 7, tree_test_data))
+ if (!do_register (tree, path8, TRUE, 8, tree_test_data))
goto out;
#if 0
spew_tree (tree);
#endif
-
- if (!do_test_dispatch (tree, path1, 0, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
+
+ if (!do_test_dispatch (tree, path0, 0, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
+ goto out;
+ if (!do_test_dispatch (tree, path1, 1, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
goto out;
- if (!do_test_dispatch (tree, path2, 1, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
+ if (!do_test_dispatch (tree, path2, 2, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
goto out;
- if (!do_test_dispatch (tree, path3, 2, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
+ if (!do_test_dispatch (tree, path3, 3, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
goto out;
- if (!do_test_dispatch (tree, path4, 3, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
+ if (!do_test_dispatch (tree, path4, 4, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
goto out;
- if (!do_test_dispatch (tree, path5, 4, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
+ if (!do_test_dispatch (tree, path5, 5, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
goto out;
- if (!do_test_dispatch (tree, path6, 5, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
+ if (!do_test_dispatch (tree, path6, 6, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
goto out;
- if (!do_test_dispatch (tree, path7, 6, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
+ if (!do_test_dispatch (tree, path7, 7, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
goto out;
- if (!do_test_dispatch (tree, path8, 7, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
+ if (!do_test_dispatch (tree, path8, 8, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data)))
goto out;
out:
diff --git a/dbus/dbus-protocol.h b/dbus/dbus-protocol.h
index f72efb60..c662d721 100644
--- a/dbus/dbus-protocol.h
+++ b/dbus/dbus-protocol.h
@@ -272,6 +272,12 @@ extern "C" {
#define DBUS_ERROR_SPAWN_FAILED "org.freedesktop.DBus.Error.Spawn.Failed"
#define DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN "org.freedesktop.DBus.Error.UnixProcessIdUnknown"
+#define DBUS_INTROSPECT_1_0_XML_NAMESPACE "http://www.freedesktop.org/standards/dbus"
+#define DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+#define DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"
+#define DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "<!DOCTYPE node PUBLIC \""DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER"\"\n\""DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER"\">\n"
+
+
#ifdef __cplusplus
}
#endif
diff --git a/glib/dbus-gidl.c b/glib/dbus-gidl.c
index cabc406b..8e0dc0da 100644
--- a/glib/dbus-gidl.c
+++ b/glib/dbus-gidl.c
@@ -303,6 +303,20 @@ node_info_add_node (NodeInfo *info,
info->nodes = g_slist_append (info->nodes, node);
}
+void
+node_info_replace_node (NodeInfo *info,
+ NodeInfo *old_child,
+ NodeInfo *new_child)
+{
+ GSList *link;
+
+ node_info_ref (new_child); /* before unref old_child in case they are the same */
+ link = g_slist_find (info->nodes, old_child);
+ g_assert (link != NULL);
+ node_info_unref (old_child);
+ link->data = new_child;
+}
+
InterfaceInfo*
interface_info_new (const char *name)
{
diff --git a/glib/dbus-gidl.h b/glib/dbus-gidl.h
index fffbddfc..88d5c6e7 100644
--- a/glib/dbus-gidl.h
+++ b/glib/dbus-gidl.h
@@ -83,6 +83,9 @@ void node_info_add_interface (NodeInfo *info,
InterfaceInfo *interface);
void node_info_add_node (NodeInfo *info,
NodeInfo *child);
+void node_info_replace_node (NodeInfo *info,
+ NodeInfo *old_child,
+ NodeInfo *new_child);
InterfaceInfo* interface_info_new (const char *name);
InterfaceInfo* interface_info_ref (InterfaceInfo *info);
void interface_info_unref (InterfaceInfo *info);
diff --git a/glib/dbus-gloader-expat.c b/glib/dbus-gloader-expat.c
index fa7e3692..609f3164 100644
--- a/glib/dbus-gloader-expat.c
+++ b/glib/dbus-gloader-expat.c
@@ -23,6 +23,7 @@
#include "dbus-gparser.h"
#include <expat.h>
+#include <string.h>
static void*
expat_g_malloc (size_t sz)
@@ -192,6 +193,9 @@ description_load_from_string (const char *str,
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ if (len < 0)
+ len = strlen (str);
+
expat = NULL;
context.parser = NULL;
context.error = error;
diff --git a/glib/dbus-gobject.c b/glib/dbus-gobject.c
index f08bf39e..245ebf1e 100644
--- a/glib/dbus-gobject.c
+++ b/glib/dbus-gobject.c
@@ -289,26 +289,28 @@ handle_introspect (DBusConnection *connection,
xml = g_string_new (NULL);
+ g_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE);
+
g_string_append (xml, "<node>\n");
/* We are introspectable, though I guess that was pretty obvious */
g_string_append (xml, " <interface name=\"org.freedesktop.Introspectable\">\n");
g_string_append (xml, " <method name=\"Introspect\">\n");
- g_string_append (xml, " <arg name=\"data\" direction=\"out\" type=\"string\"\"/>\n");
+ g_string_append (xml, " <arg name=\"data\" direction=\"out\" type=\"string\"/>\n");
g_string_append (xml, " </method>\n");
g_string_append (xml, " </interface>\n");
/* We support get/set properties */
g_string_append (xml, " <interface name=\"org.freedesktop.Properties\">\n");
g_string_append (xml, " <method name=\"Get\">\n");
- g_string_append (xml, " <arg name=\"interface\" direction=\"in\" type=\"string\"\"/>\n");
- g_string_append (xml, " <arg name=\"propname\" direction=\"in\" type=\"string\"\"/>\n");
- g_string_append (xml, " <arg name=\"value\" direction=\"out\" type=\"variant\"\"/>\n");
+ g_string_append (xml, " <arg name=\"interface\" direction=\"in\" type=\"string\"/>\n");
+ g_string_append (xml, " <arg name=\"propname\" direction=\"in\" type=\"string\"/>\n");
+ g_string_append (xml, " <arg name=\"value\" direction=\"out\" type=\"variant\"/>\n");
g_string_append (xml, " </method>\n");
g_string_append (xml, " <method name=\"Set\">\n");
- g_string_append (xml, " <arg name=\"interface\" direction=\"in\" type=\"string\"\"/>\n");
- g_string_append (xml, " <arg name=\"propname\" direction=\"in\" type=\"string\"\"/>\n");
- g_string_append (xml, " <arg name=\"value\" direction=\"in\" type=\"variant\"\"/>\n");
+ g_string_append (xml, " <arg name=\"interface\" direction=\"in\" type=\"string\"/>\n");
+ g_string_append (xml, " <arg name=\"propname\" direction=\"in\" type=\"string\"/>\n");
+ g_string_append (xml, " <arg name=\"value\" direction=\"in\" type=\"variant\"/>\n");
g_string_append (xml, " </method>\n");
g_string_append (xml, " </interface>\n");
diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c
index 624a95ca..39f8ba86 100644
--- a/glib/dbus-gproxy.c
+++ b/glib/dbus-gproxy.c
@@ -1032,12 +1032,31 @@ dbus_g_proxy_new_for_peer (DBusGConnection *connection,
g_return_val_if_fail (interface_name != NULL, NULL);
proxy = dbus_g_proxy_new (connection, NULL,
- path_name, interface_name);
+ path_name, interface_name);
return proxy;
}
/**
+ * Gets the bus name a proxy is bound to (may be #NULL in some cases).
+ * If you created the proxy with dbus_g_proxy_new_for_name(), then
+ * the name you passed to that will be returned.
+ * If you created it with dbus_g_proxy_new_for_name_owner(), then the
+ * unique connection name will be returned. If you created it
+ * with dbus_g_proxy_new_for_peer() then #NULL will be returned.
+ *
+ * @param proxy the proxy
+ * @returns the bus name the proxy sends messages to
+ */
+const char*
+dbus_g_proxy_get_bus_name (DBusGProxy *proxy)
+{
+ g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), NULL);
+
+ return proxy->name;
+}
+
+/**
* Invokes a method on a remote interface. This function does not
* block; instead it returns an opaque #DBusPendingCall object that
* tracks the pending call. The method call will not be sent over the
@@ -1113,23 +1132,28 @@ dbus_g_proxy_begin_call (DBusGProxy *proxy,
*
* Otherwise, the "out" parameters and return value of the
* method are stored in the provided varargs list.
- * The list should be terminated with DBUS_TYPE_INVALID.
+ * The list should be terminated with #DBUS_TYPE_INVALID.
*
* This function doesn't affect the reference count of the
* #DBusPendingCall, the caller of dbus_g_proxy_begin_call() still owns
* a reference.
*
+ * @todo this should be changed to make a g_malloc() copy of the
+ * data returned probably; right now the data vanishes
+ * when you free the PendingCall which is sort of strange.
+ *
* @param proxy a proxy for a remote interface
* @param pending the pending call from dbus_g_proxy_begin_call()
* @param error return location for an error
* @param first_arg_type type of first "out" argument
- * @returns #FALSE if an error is set */
+ * @returns #FALSE if an error is set
+ */
gboolean
dbus_g_proxy_end_call (DBusGProxy *proxy,
- DBusGPendingCall *pending,
- GError **error,
- int first_arg_type,
- ...)
+ DBusGPendingCall *pending,
+ GError **error,
+ int first_arg_type,
+ ...)
{
DBusMessage *message;
va_list args;
@@ -1223,6 +1247,30 @@ dbus_g_proxy_call_no_reply (DBusGProxy *proxy,
}
/**
+ * Increments refcount on a pending call.
+ *
+ * @param call the call
+ * @returns the same call
+ */
+DBusGPendingCall*
+dbus_g_pending_call_ref (DBusGPendingCall *call)
+{
+ dbus_pending_call_ref (DBUS_PENDING_CALL_FROM_G_PENDING_CALL (call));
+ return call;
+}
+
+/**
+ * Decrements refcount on a pending call.
+ *
+ * @param call the call
+ */
+void
+dbus_g_pending_call_unref (DBusGPendingCall *call)
+{
+ dbus_pending_call_unref (DBUS_PENDING_CALL_FROM_G_PENDING_CALL (call));
+}
+
+/**
* Sends a message to the interface we're proxying for. Does not
* block or wait for a reply. The message is only actually written out
* when you return to the main loop or block in
diff --git a/glib/dbus-gutils.c b/glib/dbus-gutils.c
index ff48e7f1..cf12245c 100644
--- a/glib/dbus-gutils.c
+++ b/glib/dbus-gutils.c
@@ -39,19 +39,25 @@ _dbus_gutils_split_path (const char *path)
len = strlen (path);
n_components = 0;
- i = 0;
- while (i < len)
+ if (path[1] != '\0') /* if not "/" */
{
- if (path[i] == '/')
- n_components += 1;
- ++i;
+ i = 0;
+ while (i < len)
+ {
+ if (path[i] == '/')
+ n_components += 1;
+ ++i;
+ }
}
split = g_new0 (char*, n_components + 1);
comp = 0;
- i = 0;
- while (i < len)
+ if (n_components == 0)
+ i = 1;
+ else
+ i = 0;
+ while (comp < n_components)
{
if (path[i] == '/')
++i;
diff --git a/test/glib/run-test.sh b/test/glib/run-test.sh
index eddea5f8..0a5e3f65 100755
--- a/test/glib/run-test.sh
+++ b/test/glib/run-test.sh
@@ -57,12 +57,21 @@ echo "Started test bus pid $DBUS_SESSION_BUS_PID at $DBUS_SESSION_BUS_ADDRESS"
export DBUS_TEST_GLIB_RUN_TEST_SCRIPT=1
if test x$MODE = xprofile ; then
+ echo "profiling type $PROFILE_TYPE"
sleep 2 ## this lets the bus get started so its startup time doesn't affect the profile too much
if test x$PROFILE_TYPE = x ; then
PROFILE_TYPE=all
fi
libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/test/glib/test-profile $PROFILE_TYPE || die "test-profile failed"
+elif test x$MODE = xviewer ; then
+ echo "Launching dbus-viewer"
+ ARGS=
+ if test x$DEBUG = x ; then
+ ARGS="--services org.freedesktop.DBus"
+ fi
+ libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/tools/dbus-viewer $ARGS || die "could not run dbus-viewer"
else
+ echo "running test-dbus-glib"
libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/test/glib/test-dbus-glib || die "test-dbus-glib failed"
fi
diff --git a/test/glib/test-service-glib.c b/test/glib/test-service-glib.c
index cad6f168..9b1be0ad 100644
--- a/test/glib/test-service-glib.c
+++ b/test/glib/test-service-glib.c
@@ -4,6 +4,43 @@
#include <stdlib.h>
#include <string.h>
+typedef struct MyObject MyObject;
+typedef struct MyObjectClass MyObjectClass;
+
+GType my_object_get_type (void);
+
+struct MyObject
+{
+ GObject parent;
+};
+
+struct MyObjectClass
+{
+ GObjectClass parent;
+};
+
+#define MY_TYPE_OBJECT (my_object_get_type ())
+#define MY_OBJECT_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MY_TYPE_OBJECT, MyObject))
+#define MY_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MY_TYPE_OBJECT, MyObjectClass))
+#define MY_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MY_TYPE_OBJECT))
+#define MY_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MY_TYPE_OBJECT))
+#define MY_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MY_TYPE_OBJECT, MyObjectClass))
+
+G_DEFINE_TYPE(MyObject, my_object, G_TYPE_OBJECT)
+
+
+static void
+my_object_init (MyObject *obj)
+{
+
+}
+
+static void
+my_object_class_init (MyObjectClass *obj_class)
+{
+
+}
+
static GMainLoop *loop;
int
@@ -11,6 +48,7 @@ main (int argc, char **argv)
{
DBusGConnection *connection;
GError *error;
+ GObject *obj;
g_type_init ();
@@ -27,7 +65,15 @@ main (int argc, char **argv)
exit (1);
}
+ obj = g_object_new (MY_TYPE_OBJECT, NULL);
+
+ dbus_g_connection_register_g_object (connection,
+ "/org/freedesktop/my_test_object",
+ obj);
+ g_print ("GLib test service entering main loop\n");
+
+ g_main_loop_run (loop);
g_print ("Successfully completed %s\n", argv[0]);
diff --git a/tools/dbus-viewer.c b/tools/dbus-viewer.c
index 9c57b229..c32e6fd9 100644
--- a/tools/dbus-viewer.c
+++ b/tools/dbus-viewer.c
@@ -29,6 +29,7 @@
#include "dbus-tree-view.h"
#include <glib/dbus-gparser.h>
#include <glib/dbus-gutils.h>
+#include <dbus/dbus-glib.h>
#include <libintl.h>
#define _(x) dgettext (GETTEXT_PACKAGE, x)
@@ -188,6 +189,133 @@ show_error_dialog (GtkWindow *transient_parent,
}
}
+static gboolean
+load_child_nodes (const char *service_name,
+ NodeInfo *parent,
+ GError **error)
+{
+ DBusGConnection *connection;
+ GSList *tmp;
+
+ connection = dbus_g_bus_get (DBUS_BUS_SESSION, error);
+ if (connection == NULL)
+ return FALSE;
+
+ tmp = node_info_get_nodes (parent);
+ while (tmp != NULL)
+ {
+ DBusGProxy *proxy;
+ DBusGPendingCall *call;
+ const char *data;
+ NodeInfo *child;
+ NodeInfo *complete_child;
+
+ complete_child = NULL;
+
+ child = tmp->data;
+
+ g_assert (*service_name == ':'); /* so we don't need new_for_name_owner */
+ proxy = dbus_g_proxy_new_for_name (connection,
+ service_name,
+ "/",
+ DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE);
+ g_assert (proxy != NULL);
+
+ call = dbus_g_proxy_begin_call (proxy, "Introspect",
+ DBUS_TYPE_INVALID);
+
+ data = NULL;
+ if (!dbus_g_proxy_end_call (proxy, call, error, DBUS_TYPE_STRING, &data,
+ DBUS_TYPE_INVALID))
+ goto done;
+
+ complete_child = description_load_from_string (data, -1, error);
+ if (complete_child == NULL)
+ goto done;
+
+ done:
+ dbus_g_pending_call_unref (call);
+ g_object_unref (proxy);
+
+ if (complete_child == NULL)
+ return FALSE;
+
+ /* change complete_child's name to relative */
+ base_info_set_name ((BaseInfo*)complete_child,
+ base_info_get_name ((BaseInfo*)child));
+
+ /* Stitch in complete_child rather than child */
+ node_info_replace_node (parent, child, complete_child);
+ node_info_unref (complete_child); /* ref still held by parent */
+
+ /* Now recurse */
+ if (!load_child_nodes (service_name, complete_child, error))
+ return FALSE;
+
+ tmp = tmp->next;
+ }
+
+ return TRUE;
+}
+
+static NodeInfo*
+load_from_service (const char *service_name,
+ GError **error)
+{
+ DBusGConnection *connection;
+ DBusGProxy *root_proxy;
+ DBusGPendingCall *call;
+ const char *data;
+ NodeInfo *node;
+
+ node = NULL;
+ call = NULL;
+
+ connection = dbus_g_bus_get (DBUS_BUS_SESSION, error);
+ if (connection == NULL)
+ return NULL;
+
+ root_proxy = dbus_g_proxy_new_for_name_owner (connection,
+ service_name,
+ "/",
+ DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE,
+ error);
+ if (root_proxy == NULL)
+ return NULL;
+
+ call = dbus_g_proxy_begin_call (root_proxy, "Introspect",
+ DBUS_TYPE_INVALID);
+
+ data = NULL;
+ if (!dbus_g_proxy_end_call (root_proxy, call, error, DBUS_TYPE_STRING, &data,
+ DBUS_TYPE_INVALID))
+ goto out;
+
+ node = description_load_from_string (data, -1, error);
+
+ /* g_print ("%s\n", data); */
+
+ if (node == NULL)
+ goto out;
+
+ base_info_set_name ((BaseInfo*)node, "/");
+
+ if (!load_child_nodes (dbus_g_proxy_get_bus_name (root_proxy),
+ node, error))
+ {
+ node_info_unref (node);
+ node = NULL;
+ goto out;
+ }
+
+ out:
+ if (call)
+ dbus_g_pending_call_unref (call);
+
+ g_object_unref (root_proxy);
+ return node;
+}
+
static void
usage (int ecode)
{
@@ -214,6 +342,7 @@ main (int argc, char **argv)
GSList *files;
gboolean end_of_args;
GSList *tmp;
+ gboolean services;
bindtextdomain (GETTEXT_PACKAGE, DBUS_LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
@@ -221,6 +350,7 @@ main (int argc, char **argv)
gtk_init (&argc, &argv);
+ services = FALSE;
end_of_args = FALSE;
files = NULL;
prev_arg = NULL;
@@ -237,6 +367,8 @@ main (int argc, char **argv)
usage (0);
else if (strcmp (arg, "--version") == 0)
version ();
+ else if (strcmp (arg, "--services") == 0)
+ services = TRUE;
else if (arg[0] == '-' &&
arg[1] == '-' &&
arg[2] == '\0')
@@ -270,8 +402,12 @@ main (int argc, char **argv)
filename = tmp->data;
error = NULL;
- node = description_load_from_file (filename,
- &error);
+ if (services)
+ node = load_from_service (filename, &error);
+ else
+ node = description_load_from_file (filename,
+ &error);
+
if (node == NULL)
{
g_assert (error != NULL);
@@ -313,8 +449,3 @@ main (int argc, char **argv)
return 0;
}
-
-
-
-
-