diff options
author | David Zeuthen <davidz@redhat.com> | 2011-03-16 14:45:13 -0400 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2011-03-16 15:29:15 -0400 |
commit | bea5ff9e3a753cbbee0b12246bce79206049f0b4 (patch) | |
tree | 7c4471270f42e48751246d904542b69e94d48133 | |
parent | b2b3375586152985c1d3bf49178419546f55c2af (diff) |
Rework object model significantly
Signed-off-by: David Zeuthen <davidz@redhat.com>
-rw-r--r-- | doc/Makefile.am | 2 | ||||
-rw-r--r-- | doc/gen-docs.xml | 10 | ||||
-rw-r--r-- | doc/gen-sections.txt (renamed from doc/gen-sections.txt.in) | 172 | ||||
-rw-r--r-- | doc/gen.types (renamed from doc/gen.types.in) | 5 | ||||
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/codegen.py | 91 | ||||
-rw-r--r-- | src/gdbus-example-objectmanager.c | 8 | ||||
-rw-r--r-- | src/gdbus-example-proxymanager.c | 8 | ||||
-rw-r--r-- | src/gdbusinterface.c | 111 | ||||
-rw-r--r-- | src/gdbusinterface.h | 50 | ||||
-rw-r--r-- | src/gdbusinterfacestub.c | 188 | ||||
-rw-r--r-- | src/gdbusinterfacestub.h | 92 | ||||
-rw-r--r-- | src/gdbusobject.c | 442 | ||||
-rw-r--r-- | src/gdbusobject.h | 93 | ||||
-rw-r--r-- | src/gdbusobjectmanager.c | 97 | ||||
-rw-r--r-- | src/gdbusobjectmanager.h | 6 | ||||
-rw-r--r-- | src/gdbusobjectproxy.c | 214 | ||||
-rw-r--r-- | src/gdbusobjectproxy.h | 16 | ||||
-rw-r--r-- | src/gdbusobjectstub.c | 403 | ||||
-rw-r--r-- | src/gdbusobjectstub.h | 82 | ||||
-rw-r--r-- | src/gdbusproxymanager.c | 131 | ||||
-rw-r--r-- | src/gdbusproxymanager.h | 13 | ||||
-rw-r--r-- | src/test.c | 211 |
23 files changed, 1215 insertions, 1236 deletions
diff --git a/doc/Makefile.am b/doc/Makefile.am index fbb1b73..76de7c6 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -74,7 +74,6 @@ CLEANFILES += \ $(DOC_MODULE)-decl-list.txt \ $(DOC_MODULE)-decl.txt \ $(DOC_MODULE)-overrides.txt \ - $(DOC_MODULE)-sections.txt \ $(DOC_MODULE)-undeclared.txt \ $(DOC_MODULE)-undocumented.txt \ $(DOC_MODULE)-unused.txt \ @@ -83,7 +82,6 @@ CLEANFILES += \ $(DOC_MODULE).interfaces \ $(DOC_MODULE).prerequisites \ $(DOC_MODULE).signals \ - $(DOC_MODULE).types \ *.stamp \ -rf xml html tmpl \ gdbus-codegen.1 \ diff --git a/doc/gen-docs.xml b/doc/gen-docs.xml index d7d9924..fad502d 100644 --- a/doc/gen-docs.xml +++ b/doc/gen-docs.xml @@ -13,9 +13,11 @@ <part> <title>Temporary Library (will be merged into libgio)</title> <xi:include href="xml/gdbusinterface.xml"/> + <xi:include href="xml/gdbusinterfacestub.xml"/> <xi:include href="xml/gdbusobject.xml"/> - <xi:include href="xml/gdbusobjectmanager.xml"/> + <xi:include href="xml/gdbusobjectstub.xml"/> <xi:include href="xml/gdbusobjectproxy.xml"/> + <xi:include href="xml/gdbusobjectmanager.xml"/> <xi:include href="xml/gdbusproxymanager.xml"/> </part> @@ -33,12 +35,6 @@ </part> <part> - <title>Supporting API Reference</title> - <xi:include href="xml/mytestpair.xml"/> - <xi:include href="xml/mytestpoint.xml"/> - </part> - - <part> <title>Tools Reference</title> <xi:include href="gdbus-codegen.xml"/> </part> diff --git a/doc/gen-sections.txt.in b/doc/gen-sections.txt index 2b41097..186e5d6 100644 --- a/doc/gen-sections.txt.in +++ b/doc/gen-sections.txt @@ -3,47 +3,88 @@ <TITLE>GDBusInterface</TITLE> GDBusInterface GDBusInterfaceIface -GDBusInterfaceFlags g_dbus_interface_get_info -g_dbus_interface_get_properties -g_dbus_interface_flush -g_dbus_interface_register_object g_dbus_interface_get_object g_dbus_interface_set_object -g_dbus_interface_get_flags -g_dbus_interface_set_flags <SUBSECTION Standard> G_DBUS_INTERFACE -G_DBUS_INTERFACE_GET_IFACE G_IS_DBUS_INTERFACE G_TYPE_DBUS_INTERFACE -<SUBSECTION Private> g_dbus_interface_get_type +G_DBUS_INTERFACE_GET_IFACE +</SECTION> + + +<SECTION> +<FILE>gdbusinterfacestub</FILE> +<TITLE>GDBusInterfaceStub</TITLE> +GDBusInterfaceStub +GDBusInterfaceStubClass +g_dbus_interface_stub_flush +g_dbus_interface_stub_get_info +g_dbus_interface_stub_get_properties +g_dbus_interface_stub_export +<SUBSECTION Standard> +G_DBUS_INTERFACE_STUB +G_IS_DBUS_INTERFACE_STUB +G_TYPE_DBUS_INTERFACE_STUB +g_dbus_interface_stub_get_type +G_DBUS_INTERFACE_STUB_CLASS +G_IS_DBUS_INTERFACE_STUB_CLASS +G_DBUS_INTERFACE_STUB_GET_CLASS </SECTION> <SECTION> <FILE>gdbusobject</FILE> <TITLE>GDBusObject</TITLE> GDBusObject -GDBusObjectClass -g_dbus_object_new +GDBusObjectIface g_dbus_object_get_object_path -g_dbus_object_flush -g_dbus_object_add_interface -g_dbus_object_remove_interface -g_dbus_object_remove_interface_by_name -g_dbus_object_lookup_interface g_dbus_object_get_interfaces +g_dbus_object_get_interface <SUBSECTION Standard> -G_TYPE_DBUS_OBJECT G_DBUS_OBJECT -G_DBUS_OBJECT_CLASS -G_DBUS_OBJECT_GET_CLASS G_IS_DBUS_OBJECT -G_IS_DBUS_OBJECT_CLASS -<SUBSECTION Private> -GDBusObjectPrivate +G_TYPE_DBUS_OBJECT g_dbus_object_get_type +G_DBUS_OBJECT_GET_IFACE +</SECTION> + +<SECTION> +<FILE>gdbusobjectproxy</FILE> +<TITLE>GDBusObjectProxy</TITLE> +GDBusObjectProxy +GDBusObjectProxyClass +g_dbus_object_proxy_get_connection +<SUBSECTION Standard> +G_DBUS_OBJECT_PROXY +G_IS_DBUS_OBJECT_PROXY +G_TYPE_DBUS_OBJECT_PROXY +g_dbus_object_proxy_get_type +G_DBUS_OBJECT_PROXY_CLASS +G_IS_DBUS_OBJECT_PROXY_CLASS +G_DBUS_OBJECT_PROXY_GET_CLASS +</SECTION> + +<SECTION> +<FILE>gdbusobjectstub</FILE> +<TITLE>GDBusObjectStub</TITLE> +GDBusObjectStub +GDBusObjectStubClass +g_dbus_object_stub_new +g_dbus_object_stub_flush +g_dbus_object_stub_add_interface +g_dbus_object_stub_remove_interface +g_dbus_object_stub_remove_interface_by_name +g_dbus_object_stub_set_object_path +<SUBSECTION Standard> +G_DBUS_OBJECT_STUB +G_IS_DBUS_OBJECT_STUB +G_TYPE_DBUS_OBJECT_STUB +g_dbus_object_stub_get_type +G_DBUS_OBJECT_STUB_CLASS +G_IS_DBUS_OBJECT_STUB_CLASS +G_DBUS_OBJECT_STUB_GET_CLASS </SECTION> <SECTION> @@ -59,38 +100,13 @@ g_dbus_object_manager_export_and_uniquify g_dbus_object_manager_unexport g_dbus_object_manager_get_all <SUBSECTION Standard> -G_TYPE_DBUS_OBJECT_MANAGER G_DBUS_OBJECT_MANAGER -G_DBUS_OBJECT_MANAGER_CLASS -G_DBUS_OBJECT_MANAGER_GET_CLASS G_IS_DBUS_OBJECT_MANAGER -G_IS_DBUS_OBJECT_MANAGER_CLASS -<SUBSECTION Private> -GDBusObjectManagerPrivate +G_TYPE_DBUS_OBJECT_MANAGER g_dbus_object_manager_get_type -</SECTION> - -<SECTION> -<FILE>gdbusobjectproxy</FILE> -<TITLE>GDBusObjectProxy</TITLE> -GDBusObjectProxy -GDBusObjectProxyClass -g_dbus_object_proxy_get_object_path -g_dbus_object_proxy_get_connection -g_dbus_object_proxy_lookup -g_dbus_object_proxy_get_all -<SUBSECTION Standard> -G_TYPE_DBUS_OBJECT_PROXY -G_DBUS_OBJECT_PROXY -G_DBUS_OBJECT_PROXY_CLASS -G_DBUS_OBJECT_PROXY_GET_CLASS -G_IS_DBUS_OBJECT_PROXY -G_IS_DBUS_OBJECT_PROXY_CLASS -<SUBSECTION Private> -GDBusObjectProxyPrivate -g_dbus_object_proxy_get_type -g_dbus_object_proxy_peek_with_typecheck -g_dbus_object_proxy_lookup_with_typecheck +G_DBUS_OBJECT_MANAGER_CLASS +G_IS_DBUS_OBJECT_MANAGER_CLASS +G_DBUS_OBJECT_MANAGER_GET_CLASS </SECTION> <SECTION> @@ -98,8 +114,8 @@ g_dbus_object_proxy_lookup_with_typecheck <TITLE>GDBusProxyManager</TITLE> GDBusProxyManager GDBusProxyManagerClass -GDBusProxyManagerFlags GDBusProxyTypeFunc +GDBusProxyManagerFlags g_dbus_proxy_manager_new g_dbus_proxy_manager_new_finish g_dbus_proxy_manager_new_sync @@ -111,55 +127,15 @@ g_dbus_proxy_manager_get_flags g_dbus_proxy_manager_get_name g_dbus_proxy_manager_get_name_owner g_dbus_proxy_manager_get_object_path -g_dbus_proxy_manager_get_all -g_dbus_proxy_manager_lookup -g_dbus_proxy_manager_lookup_interface +g_dbus_proxy_manager_get_objects +g_dbus_proxy_manager_get_object +g_dbus_proxy_manager_get_interface <SUBSECTION Standard> -G_TYPE_DBUS_PROXY_MANAGER G_DBUS_PROXY_MANAGER -G_DBUS_PROXY_MANAGER_CLASS -G_DBUS_PROXY_MANAGER_GET_CLASS G_IS_DBUS_PROXY_MANAGER -G_IS_DBUS_PROXY_MANAGER_CLASS -G_TYPE_DBUS_PROXY_MANAGER_FLAGS -<SUBSECTION Private> -GDBusProxyManagerPrivate +G_TYPE_DBUS_PROXY_MANAGER g_dbus_proxy_manager_get_type -g_dbus_proxy_manager_flags_get_type -</SECTION> - -<SECTION> -<FILE>mytestpoint</FILE> -<TITLE>MyTestPoint</TITLE> -MyTestPoint -my_test_point_new -my_test_point_get_x -my_test_point_set_x -my_test_point_get_y -my_test_point_set_y -my_test_point_get_meta -my_test_point_set_meta -my_test_point_to_gvariant -my_test_point_from_gvariant -<SUBSECTION Standard> -MY_TEST_TYPE_POINT -MY_TEST_POINT -MY_TEST_IS_POINT -<SUBSECTION Private> -my_test_point_get_type -</SECTION> - -<SECTION> -<FILE>mytestpair</FILE> -<TITLE>MyTestPair</TITLE> -MyTestPair -MY_TEST_TYPE_PAIR -my_test_pair_new -my_test_pair_free -my_test_pair_copy -my_test_pair_to_gvariant -my_test_pair_from_gvariant -<SUBSECTION Standard> -<SUBSECTION Private> -my_test_pair_get_type +G_DBUS_PROXY_MANAGER_CLASS +G_IS_DBUS_PROXY_MANAGER_CLASS +G_DBUS_PROXY_MANAGER_GET_CLASS </SECTION> diff --git a/doc/gen.types.in b/doc/gen.types index 372d2e3..3ddb0c1 100644 --- a/doc/gen.types.in +++ b/doc/gen.types @@ -1,6 +1,7 @@ g_dbus_interface_get_type +g_dbus_interface_stub_get_type g_dbus_object_get_type -g_dbus_object_manager_get_type +g_dbus_object_stub_get_type g_dbus_object_proxy_get_type +g_dbus_object_manager_get_type g_dbus_proxy_manager_get_type -my_test_point_get_type diff --git a/src/Makefile.am b/src/Makefile.am index 48fda06..8a176c1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -58,18 +58,22 @@ libgdbus_codegenincludedir = $(includedir)/gdbus-codegen libgdbus_codegeninclude_HEADERS = \ gdbusinterface.h \ + gdbusinterfacestub.h \ gdbusobject.h \ - gdbusobjectmanager.h \ gdbusobjectproxy.h \ + gdbusobjectstub.h \ + gdbusobjectmanager.h \ gdbusproxymanager.h \ gdbuscodegen-enumtypes.h \ $(NULL) libgdbus_codegen_la_SOURCES = \ gdbusinterface.h gdbusinterface.c \ + gdbusinterfacestub.h gdbusinterfacestub.c \ gdbusobject.h gdbusobject.c \ gdbusobjectmanager.h gdbusobjectmanager.c \ gdbusobjectproxy.h gdbusobjectproxy.c \ + gdbusobjectstub.h gdbusobjectstub.c \ gdbusproxymanager.h gdbusproxymanager.c \ gdbuscodegen-marshal.h gdbuscodegen-marshal.c \ gdbuscodegen-enumtypes.h gdbuscodegen-enumtypes.c \ diff --git a/src/codegen.py b/src/codegen.py index 354526c..6d932d8 100644 --- a/src/codegen.py +++ b/src/codegen.py @@ -177,9 +177,11 @@ class CodeGenerator: # TODO: reduce to just gio/gio.h when client-side code has been merged self.h.write('#include <gio/gio.h>\n' '#include <gdbusinterface.h>\n' + '#include <gdbusinterfacestub.h>\n' + '#include <gdbusobject.h>\n' '#include <gdbusobjectproxy.h>\n' + '#include <gdbusobjectstub.h>\n' '#include <gdbusproxymanager.h>\n' - '#include <gdbusobject.h>\n' '#include <gdbusobjectmanager.h>\n' '#include <gdbuscodegen-enumtypes.h>\n' '\n' @@ -388,8 +390,8 @@ class CodeGenerator: self.h.write('\n') # Interface proxy accessors - self.h.write('#define %sGET_%s(object_proxy) (g_dbus_object_proxy_lookup_with_typecheck (object_proxy, "%s", %sTYPE_%s))\n'%(i.ns_upper, i.name_upper, i.name, i.ns_upper, i.name_upper)) - self.h.write('#define %sPEEK_%s(object_proxy) (g_dbus_object_proxy_peek_with_typecheck (object_proxy, "%s", %sTYPE_%s))\n'%(i.ns_upper, i.name_upper, i.name, i.ns_upper, i.name_upper)) + self.h.write('#define %sGET_%s(object) (g_dbus_object_lookup_with_typecheck (G_DBUS_OBJECT (object), "%s", %sTYPE_%s))\n'%(i.ns_upper, i.name_upper, i.name, i.ns_upper, i.name_upper)) + self.h.write('#define %sPEEK_%s(object) (g_dbus_object_peek_with_typecheck (G_DBUS_OBJECT (object), "%s", %sTYPE_%s))\n'%(i.ns_upper, i.name_upper, i.name, i.ns_upper, i.name_upper)) self.h.write('\n') # Then the stub @@ -409,13 +411,13 @@ class CodeGenerator: self.h.write('\n') self.h.write('struct _%sStub\n'%(i.camel_name)) self.h.write('{\n') - self.h.write(' GObject parent_instance;\n') + self.h.write(' GDBusInterfaceStub parent_instance;\n') self.h.write(' %sStubPrivate *priv;\n'%(i.camel_name)) self.h.write('};\n') self.h.write('\n') self.h.write('struct _%sStubClass\n'%(i.camel_name)) self.h.write('{\n') - self.h.write(' GObjectClass parent_class;\n') + self.h.write(' GDBusInterfaceStubClass parent_class;\n') self.h.write('};\n') self.h.write('\n') self.h.write('GType %s_stub_get_gtype (void) G_GNUC_CONST;\n'%(i.name_lower)) @@ -1290,8 +1292,6 @@ class CodeGenerator: self.c.write('struct _%sStubPrivate\n' '{\n' ' GValueArray *properties;\n' - ' GDBusObject *object;\n' - ' GDBusInterfaceFlags flags;\n' ' GList *changed_properties;\n' ' GSource *changed_properties_idle_source;\n' ' GDBusConnection *connection;\n' @@ -1450,7 +1450,7 @@ class CodeGenerator: '\n'%(i.name_lower, i.name_lower, i.name_lower, i.name_lower)) self.c.write('static GDBusInterfaceInfo *\n' - '%s_stub_dbus_interface_get_info (GDBusInterface *interface)\n' + '%s_stub_dbus_interface_get_info (GDBusInterfaceStub *stub)\n' '{\n' ' return %s_interface_info ();\n' %(i.name_lower, i.name_lower)) @@ -1458,9 +1458,9 @@ class CodeGenerator: '\n') self.c.write('static GVariant *\n' - '%s_stub_dbus_interface_get_properties (GDBusInterface *interface)\n' + '%s_stub_dbus_interface_get_properties (GDBusInterfaceStub *_stub)\n' '{\n' - ' %sStub *stub = %s%s_STUB (interface);\n' + ' %sStub *stub = %s%s_STUB (_stub);\n' %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper)) self.c.write('\n' ' GVariantBuilder builder;\n' @@ -1496,11 +1496,11 @@ class CodeGenerator: %(i.name_lower)) self.c.write('static void\n' - '%s_stub_dbus_interface_flush (GDBusInterface *interface)\n' + '%s_stub_dbus_interface_flush (GDBusInterfaceStub *_stub)\n' '{\n' %(i.name_lower)) if len(i.properties) > 0: - self.c.write(' %sStub *stub = %s%s_STUB (interface);\n' + self.c.write(' %sStub *stub = %s%s_STUB (_stub);\n' ' if (stub->priv->changed_properties_idle_source != NULL)\n' ' {\n' ' g_source_destroy (stub->priv->changed_properties_idle_source);\n' @@ -1522,12 +1522,12 @@ class CodeGenerator: %(i.name_lower, i.camel_name)) self.c.write('static guint\n' - '%s_stub_dbus_interface_register_object (GDBusInterface *interface,' + '%s_stub_dbus_interface_export (GDBusInterfaceStub *_stub,' ' GDBusConnection *connection,\n' ' const gchar *object_path,\n' ' GError **error)\n' '{\n' - ' %sStub *stub = %s%s_STUB (interface);\n' + ' %sStub *stub = %s%s_STUB (_stub);\n' %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper)) self.c.write(' stub->priv->connection = connection;\n') self.c.write(' stub->priv->object_path = g_strdup (object_path);\n') @@ -1538,44 +1538,6 @@ class CodeGenerator: self.c.write('}\n' '\n') - self.c.write('static GDBusObject *\n' - '%s_stub_dbus_interface_get_object (GDBusInterface *interface)\n' - '{\n' - ' %sStub *stub = %s%s_STUB (interface);\n' - %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper)) - self.c.write(' return stub->priv->object != NULL ? g_object_ref (stub->priv->object) : NULL;\n') - self.c.write('}\n' - '\n') - - self.c.write('static void\n' - '%s_stub_dbus_interface_set_object (GDBusInterface *interface,' - ' GDBusObject *object)\n' - '{\n' - ' %sStub *stub = %s%s_STUB (interface);\n' - %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper)) - self.c.write(' stub->priv->object = object;\n') - self.c.write('}\n' - '\n') - - self.c.write('static GDBusInterfaceFlags\n' - '%s_stub_dbus_interface_get_flags (GDBusInterface *interface)\n' - '{\n' - ' %sStub *stub = %s%s_STUB (interface);\n' - %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper)) - self.c.write(' return stub->priv->flags;\n') - self.c.write('}\n' - '\n') - - self.c.write('static void\n' - '%s_stub_dbus_interface_set_flags (GDBusInterface *interface,' - ' GDBusInterfaceFlags flags)\n' - '{\n' - ' %sStub *stub = %s%s_STUB (interface);\n' - %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper)) - self.c.write(' stub->priv->flags = flags;\n') - self.c.write('}\n' - '\n') - for s in i.signals: self.c.write('static void\n' '_%s_on_signal_%s (\n' @@ -1610,23 +1572,9 @@ class CodeGenerator: %(s.name_lower, i.name_lower, s.name_lower)) self.c.write('}\n' '\n') - self.c.write('static void\n' - '%s_stub_dbus_iface_init (GDBusInterfaceIface *iface)\n' - '{\n'%(i.name_lower)) - self.c.write(' iface->get_info = %s_stub_dbus_interface_get_info;\n'%(i.name_lower)) - self.c.write(' iface->get_properties = %s_stub_dbus_interface_get_properties;\n'%(i.name_lower)) - self.c.write(' iface->flush = %s_stub_dbus_interface_flush;\n'%(i.name_lower)) - self.c.write(' iface->register_object = %s_stub_dbus_interface_register_object;\n'%(i.name_lower)) - self.c.write(' iface->get_object = %s_stub_dbus_interface_get_object;\n'%(i.name_lower)) - self.c.write(' iface->set_object = %s_stub_dbus_interface_set_object;\n'%(i.name_lower)) - self.c.write(' iface->get_flags = %s_stub_dbus_interface_get_flags;\n'%(i.name_lower)) - self.c.write(' iface->set_flags = %s_stub_dbus_interface_set_flags;\n'%(i.name_lower)) - self.c.write('}\n' - '\n') self.c.write('#define %s_stub_get_type %s_stub_get_gtype\n'%(i.name_lower, i.name_lower)) - self.c.write('G_DEFINE_TYPE_WITH_CODE (%sStub, %s_stub, G_TYPE_OBJECT,\n'%(i.camel_name, i.name_lower)) - self.c.write(' G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_stub_iface_init)\n'%(i.ns_upper, i.name_upper, i.name_lower)) - self.c.write(' G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_INTERFACE, %s_stub_dbus_iface_init));\n'%(i.name_lower)) + self.c.write('G_DEFINE_TYPE_WITH_CODE (%sStub, %s_stub, G_TYPE_DBUS_INTERFACE_STUB,\n'%(i.camel_name, i.name_lower)) + self.c.write(' G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_stub_iface_init));\n'%(i.ns_upper, i.name_upper, i.name_lower)) self.c.write('#undef %s_stub_get_type\n' '\n'%(i.name_lower)) @@ -1770,6 +1718,7 @@ class CodeGenerator: '%s_stub_class_init (%sStubClass *klass)\n' '{\n' ' GObjectClass *gobject_class;\n' + ' GDBusInterfaceStubClass *stub_class;\n' '\n' ' g_type_class_add_private (klass, sizeof (%sStubPrivate));\n' '\n' @@ -1781,6 +1730,12 @@ class CodeGenerator: if len(i.properties) > 0: self.c.write('\n' ' %s_override_properties (gobject_class, 1);\n'%(i.name_lower)) + self.c.write('\n' + ' stub_class = G_DBUS_INTERFACE_STUB_CLASS (klass);\n'); + self.c.write(' stub_class->get_info = %s_stub_dbus_interface_get_info;\n'%(i.name_lower)) + self.c.write(' stub_class->get_properties = %s_stub_dbus_interface_get_properties;\n'%(i.name_lower)) + self.c.write(' stub_class->flush = %s_stub_dbus_interface_flush;\n'%(i.name_lower)) + self.c.write(' stub_class->export = %s_stub_dbus_interface_export;\n'%(i.name_lower)) self.c.write('}\n' '\n') diff --git a/src/gdbus-example-objectmanager.c b/src/gdbus-example-objectmanager.c index 9c54329..704b509 100644 --- a/src/gdbus-example-objectmanager.c +++ b/src/gdbus-example-objectmanager.c @@ -34,7 +34,7 @@ on_bus_acquired (GDBusConnection *connection, const gchar *name, gpointer user_data) { - GDBusObject *object; + GDBusObjectStub *object; guint n; g_debug ("bus acquired"); @@ -47,19 +47,19 @@ on_bus_acquired (GDBusConnection *connection, FooComAcmeCoyote *coyote; s = g_strdup_printf ("/org/gtk/GDBus/TestObjectManager/Object%03d", n); - object = g_dbus_object_new (s); + object = g_dbus_object_stub_new (s); g_free (s); bar = foo_bar_stub_new (); foo_bar_set_i (bar, n); - g_dbus_object_add_interface (object, G_DBUS_INTERFACE (bar)); + g_dbus_object_stub_add_interface (object, G_DBUS_INTERFACE_STUB (bar)); g_object_unref (bar); coyote = foo_com_acme_coyote_stub_new (); s = g_strdup_printf ("Anger %d", n); foo_com_acme_coyote_set_mood (coyote, s); g_free (s); - g_dbus_object_add_interface (object, G_DBUS_INTERFACE (coyote)); + g_dbus_object_stub_add_interface (object, G_DBUS_INTERFACE_STUB (coyote)); g_object_unref (coyote); g_dbus_object_manager_export (manager, object); diff --git a/src/gdbus-example-proxymanager.c b/src/gdbus-example-proxymanager.c index c6c7f6c..f598dcb 100644 --- a/src/gdbus-example-proxymanager.c +++ b/src/gdbus-example-proxymanager.c @@ -49,7 +49,7 @@ on_object_proxy_added (GDBusProxyManager *manager, { gchar *owner; owner = g_dbus_proxy_manager_get_name_owner (manager); - g_debug ("added object at %s (owner %s)", g_dbus_object_proxy_get_object_path (object_proxy), owner); + g_debug ("added object at %s (owner %s)", g_dbus_object_get_object_path (G_DBUS_OBJECT (object_proxy)), owner); g_free (owner); } @@ -60,7 +60,7 @@ on_object_proxy_removed (GDBusProxyManager *manager, { gchar *owner; owner = g_dbus_proxy_manager_get_name_owner (manager); - g_debug ("removed object at %s (owner %s)", g_dbus_object_proxy_get_object_path (object_proxy), owner); + g_debug ("removed object at %s (owner %s)", g_dbus_object_get_object_path (G_DBUS_OBJECT (object_proxy)), owner); g_free (owner); } @@ -114,11 +114,11 @@ main (gint argc, gchar *argv[]) g_debug ("name-owner: %s", name_owner); g_free (name_owner); - object_proxies = g_dbus_proxy_manager_get_all (manager); + object_proxies = g_dbus_proxy_manager_get_objects (manager); for (l = object_proxies; l != NULL; l = l->next) { GDBusObjectProxy *object_proxy = G_DBUS_OBJECT_PROXY (l->data); - g_debug ("proxy has object at %s", g_dbus_object_proxy_get_object_path (object_proxy)); + g_debug ("proxy has object at %s", g_dbus_object_get_object_path (G_DBUS_OBJECT (object_proxy))); } g_list_foreach (object_proxies, (GFunc) g_object_unref, NULL); g_list_free (object_proxies); diff --git a/src/gdbusinterface.c b/src/gdbusinterface.c index 0f040d9..4dc413d 100644 --- a/src/gdbusinterface.c +++ b/src/gdbusinterface.c @@ -28,13 +28,12 @@ /** * SECTION:gdbusinterface - * @short_description: Base type for exported D-Bus interfaces + * @short_description: Base type for D-Bus interfaces * @include: gio/gio.h * - * The #GDBusInterface type is the base type for D-Bus interfaces that - * can be exported on a #GDBusConnection. These objects are typically - * grouped together in a #GDBusObject object and then exported on a - * #GDBusConnection using a #GDBusObjectManager object. + * The #GDBusInterface type is the base type for D-Bus interfaces both + * on the service side (see #GDBusInterfaceStub) and client side (see + * #GDBusProxy). */ typedef GDBusInterfaceIface GDBusInterfaceInterface; @@ -54,7 +53,7 @@ g_dbus_interface_default_init (GDBusInterfaceIface *iface) * Gets D-Bus introspection information for the D-Bus interface * implemented by @interface. * - * Returns: A #GDBusInterfaceInfo. Do not free. + * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free. */ GDBusInterfaceInfo * g_dbus_interface_get_info (GDBusInterface *interface) @@ -64,69 +63,13 @@ g_dbus_interface_get_info (GDBusInterface *interface) } /** - * g_dbus_interface_get_properties: - * @interface: An exported D-Bus interface. - * - * Gets all properties for @interface. - * - * Returns: A new, floating, #GVariant. Free with g_variant_unref(). - */ -GVariant * -g_dbus_interface_get_properties (GDBusInterface *interface) -{ - GVariant *ret; - g_return_val_if_fail (G_IS_DBUS_INTERFACE (interface), NULL); - ret = G_DBUS_INTERFACE_GET_IFACE (interface)->get_properties (interface); - g_warn_if_fail (g_variant_is_floating (ret)); - return ret; -} - -/** - * g_dbus_interface_flush: - * @interface: An exported D-Bus interface. - * - * If @interface has outstanding changes, make sure they are emitted. For - * example, if an interface has queued property notifications, this will - * empty the queue forcing the - * <literal>org.freedesktop.DBus.Properties::PropertiesChanged</literal> - * signal to be emitted. - */ -void -g_dbus_interface_flush (GDBusInterface *interface) -{ - g_return_if_fail (G_IS_DBUS_INTERFACE (interface)); - G_DBUS_INTERFACE_GET_IFACE (interface)->flush (interface); -} - -/** - * g_dbus_interface_register_interface: - * @interface: An exported D-Bus interface. - * @connection: A #GDBusConnection. - * @object_path: The path to register the interface at. - * @error: Return location for error or %NULL. - * - * Registers @interface at @object_path on connection. - * - * Returns: 0 if @error is set, otherwise a registration id (never 0) - * that can be used with g_dbus_connection_unregister_object(). - */ -guint -g_dbus_interface_register_object (GDBusInterface *interface, - GDBusConnection *connection, - const gchar *object_path, - GError **error) -{ - g_return_val_if_fail (G_IS_DBUS_INTERFACE (interface), 0); - return G_DBUS_INTERFACE_GET_IFACE (interface)->register_object (interface, connection, object_path, error); -} - -/** * g_dbus_interface_get_object: * @interface: An exported D-Bus interface. * * Gets the #GDBusObject that @interface belongs to, if any. * - * Returns: A #GDBusObject or %NULL. Free the returned reference with g_object_unref(). + * Returns: (transfer none): A #GDBusObject or %NULL. The returned + * reference belongs to @interface and should not be freed. */ GDBusObject * g_dbus_interface_get_object (GDBusInterface *interface) @@ -140,12 +83,9 @@ g_dbus_interface_get_object (GDBusInterface *interface) * @interface: An exported D-Bus interface. * @object: A #GDBusObject or %NULL. * - * Sets the #GDBusObject for @interface to @object. Implementations must not take a reference to @object. + * Sets the #GDBusObject for @interface to @object. * - * <note><para>Applications never need to use this method as the - * #GDBusObject type already calls it in the - * g_dbus_object_add_interface() and g_dbus_object_remove_interface() - * methods.</para></note> + * Note that @interface will hold a weak reference to @object. */ void g_dbus_interface_set_object (GDBusInterface *interface, @@ -156,39 +96,6 @@ g_dbus_interface_set_object (GDBusInterface *interface, G_DBUS_INTERFACE_GET_IFACE (interface)->set_object (interface, object); } -/** - * g_dbus_interface_get_flags: - * @interface: An exported D-Bus interface. - * - * Gets the #GDBusInterfaceFlags for @interface. - * - * Note that the type implementing this interface may default to its - * own set of flags. - * - * Returns: A set of flags from the #GDBusInterfaceFlags enumeration. - */ -GDBusInterfaceFlags -g_dbus_interface_get_flags (GDBusInterface *interface) -{ - g_return_val_if_fail (G_IS_DBUS_INTERFACE (interface), G_DBUS_INTERFACE_FLAGS_NONE); - return G_DBUS_INTERFACE_GET_IFACE (interface)->get_flags (interface); -} - -/** - * g_dbus_interface_set_flags: - * @interface: An exported D-Bus interface. - * @flags: A set of flags from the #GDBusInterfaceFlags enumeration. - * - * Sets the flags on @interface. - */ -void -g_dbus_interface_set_flags (GDBusInterface *interface, - GDBusInterfaceFlags flags) -{ - g_return_if_fail (G_IS_DBUS_INTERFACE (interface)); - G_DBUS_INTERFACE_GET_IFACE (interface)->set_flags (interface, flags); -} - /* Keep it here for now. TODO: move */ #include <string.h> diff --git a/src/gdbusinterface.h b/src/gdbusinterface.h index 50bb2e6..43c3c55 100644 --- a/src/gdbusinterface.h +++ b/src/gdbusinterface.h @@ -28,6 +28,7 @@ G_BEGIN_DECLS typedef struct _GDBusObject GDBusObject; +typedef struct _GDBusObjectStub GDBusObjectStub; #define G_TYPE_DBUS_INTERFACE (g_dbus_interface_get_type()) #define G_DBUS_INTERFACE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_INTERFACE, GDBusInterface)) @@ -37,74 +38,37 @@ typedef struct _GDBusObject GDBusObject; /** * GDBusInterface: * - * A D-Bus interface. + * Base type for D-Bus interfaces. */ typedef struct _GDBusInterface GDBusInterface; /* Dummy typedef */ typedef struct _GDBusInterfaceIface GDBusInterfaceIface; /** - * GDBusInterfaceFlags: - * @G_DBUS_INTERFACE_FLAGS_NONE: No flags set. - * @G_DBUS_INTERFACE_FLAGS_RUN_IN_THREAD: All method invocations will - * run in a dedicated #GThread with a dedicated #GMainContext. - * - * Flags used for describing how a #GDBusInterface should work. - */ -typedef enum -{ - G_DBUS_INTERFACE_FLAGS_NONE = 0, - G_DBUS_INTERFACE_FLAGS_RUN_IN_THREAD = (1<<0) -} GDBusInterfaceFlags; - -/** * GDBusInterfaceIface: * @parent_iface: The parent interface. * @get_info: Returns a #GDBusInterfaceInfo. See g_dbus_interface_get_info(). - * @get_properties: Returns a new, floating, #GVariant with all properties. See g_dbus_interface_get_properties(). - * @flush: Emits outstanding changes, if any. See g_dbus_interface_flush(). - * @register_object: Exports the instance on a #GDBusConnection. See g_dbus_interface_register_object(). * @get_object: Gets the enclosing #GDBusObject. See g_dbus_interface_get_object(). * @set_object: Sets the enclosing #GDBusObject. See g_dbus_interface_set_object(). - * @get_flags: Gets the #GDBusInterfaceFlags flags. See g_dbus_interface_get_flags(). - * @set_flags: Sets the #GDBusInterfaceFlags flags. See g_dbus_interface_set_flags(). * - * Base interface type for D-Bus interfaces. + * Base type for D-Bus interfaces. */ struct _GDBusInterfaceIface { GTypeInterface parent_iface; /* Virtual Functions */ - GDBusInterfaceInfo *(*get_info) (GDBusInterface *interface); - GVariant *(*get_properties) (GDBusInterface *interface); - void (*flush) (GDBusInterface *interface); - guint (*register_object) (GDBusInterface *interface, - GDBusConnection *connection, - const gchar *object_path, - GError **error); - GDBusObject *(*get_object) (GDBusInterface *interface); - void (*set_object) (GDBusInterface *interface, - GDBusObject *object); - GDBusInterfaceFlags (*get_flags) (GDBusInterface *interface); - void (*set_flags) (GDBusInterface *interface, - GDBusInterfaceFlags flags); + GDBusInterfaceInfo *(*get_info) (GDBusInterface *interface); + GDBusObject *(*get_object) (GDBusInterface *interface); + void (*set_object) (GDBusInterface *interface, + GDBusObject *object); }; GType g_dbus_interface_get_type (void) G_GNUC_CONST; GDBusInterfaceInfo *g_dbus_interface_get_info (GDBusInterface *interface); -GVariant *g_dbus_interface_get_properties (GDBusInterface *interface); -void g_dbus_interface_flush (GDBusInterface *interface); -guint g_dbus_interface_register_object (GDBusInterface *interface, - GDBusConnection *connection, - const gchar *object_path, - GError **error); GDBusObject *g_dbus_interface_get_object (GDBusInterface *interface); void g_dbus_interface_set_object (GDBusInterface *interface, GDBusObject *object); -GDBusInterfaceFlags g_dbus_interface_get_flags (GDBusInterface *interface); -void g_dbus_interface_set_flags (GDBusInterface *interface, - GDBusInterfaceFlags flags); /* Keep it here for now. TODO: move */ diff --git a/src/gdbusinterfacestub.c b/src/gdbusinterfacestub.c new file mode 100644 index 0000000..32f2d20 --- /dev/null +++ b/src/gdbusinterfacestub.c @@ -0,0 +1,188 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#include "config.h" + +#include "gdbusinterfacestub.h" + +/** + * SECTION:gdbusinterfacestub + * @short_description: Service-side D-Bus interface + * @include: gio/gio.h + * + * Abstract base class for D-Bus interfaces on the service side. + */ + +struct _GDBusInterfaceStubPrivate +{ + GDBusObject *object; +}; + +static void dbus_interface_interface_init (GDBusInterfaceIface *iface); + +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GDBusInterfaceStub, g_dbus_interface_stub, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_INTERFACE, dbus_interface_interface_init)); + +static void +g_dbus_interface_stub_finalize (GObject *object) +{ + GDBusInterfaceStub *stub = G_DBUS_INTERFACE_STUB (object); + if (stub->priv->object != NULL) + g_object_remove_weak_pointer (G_OBJECT (stub->priv->object), (gpointer *) &stub->priv->object); + G_OBJECT_CLASS (g_dbus_interface_stub_parent_class)->finalize (object); +} + +static void +g_dbus_interface_stub_class_init (GDBusInterfaceStubClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_dbus_interface_stub_finalize; + + g_type_class_add_private (klass, sizeof (GDBusInterfaceStubPrivate)); +} + +static void +g_dbus_interface_stub_init (GDBusInterfaceStub *stub) +{ + stub->priv = G_TYPE_INSTANCE_GET_PRIVATE (stub, G_TYPE_DBUS_INTERFACE_STUB, GDBusInterfaceStubPrivate); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * g_dbus_interface_stub_get_info: + * @stub: A #GDBusInterfaceStub. + * + * Gets D-Bus introspection information for the D-Bus interface + * implemented by @interface. + * + * Returns: (transfer none): A #GDBusInterfaceInfo (never %NULL). Do not free. + */ +GDBusInterfaceInfo * +g_dbus_interface_stub_get_info (GDBusInterfaceStub *stub) +{ + GDBusInterfaceInfo *ret; + g_return_val_if_fail (G_IS_DBUS_INTERFACE_STUB (stub), NULL); + ret = G_DBUS_INTERFACE_STUB_GET_CLASS (stub)->get_info (stub); + g_warn_if_fail (ret != NULL); + return ret; +} + +/** + * g_dbus_interface_stub_get_properties: + * @stub: A #GDBusInterfaceStub. + * + * Gets all D-Bus properties for @stub. + * + * Returns: A new, floating, #GVariant. Free with g_variant_unref(). + */ +GVariant * +g_dbus_interface_stub_get_properties (GDBusInterfaceStub *stub) +{ + GVariant *ret; + g_return_val_if_fail (G_IS_DBUS_INTERFACE_STUB (stub), NULL); + ret = G_DBUS_INTERFACE_STUB_GET_CLASS (stub)->get_properties (stub); + g_warn_if_fail (g_variant_is_floating (ret)); + return ret; +} + +/** + * g_dbus_interface_stub_flush: + * @stub: A #GDBusInterfaceStub. + * + * If @stub has outstanding changes, request for these changes to be + * emitted immediately. + * + * For example, an exported D-Bus interface may queue up property + * changes and emit the + * <literal>org.freedesktop.DBus.Properties::PropertiesChanged</literal> + * signal later (e.g. in an idle handler). This technique is useful + * for collapsing multiple property changes into one. + */ +void +g_dbus_interface_stub_flush (GDBusInterfaceStub *stub) +{ + g_return_if_fail (G_IS_DBUS_INTERFACE_STUB (stub)); + G_DBUS_INTERFACE_STUB_GET_CLASS (stub)->flush (stub); +} + +/** + * g_dbus_interface_stub_export: + * @stub: The D-Bus interface to export. + * @connection: A #GDBusConnection to export @stub on. + * @object_path: The path to export the interface at. + * @error: Return location for error or %NULL. + * + * Exports @stubs at @object_path on @connection. + * + * Returns: 0 if @error is set, otherwise a registration id (never 0) + * that can be used with g_dbus_connection_unregister_object(). + */ +guint +g_dbus_interface_stub_export (GDBusInterfaceStub *stub, + GDBusConnection *connection, + const gchar *object_path, + GError **error) +{ + g_return_val_if_fail (G_IS_DBUS_INTERFACE_STUB (stub), 0); + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), 0); + g_return_val_if_fail (g_variant_is_object_path (object_path), 0); + g_return_val_if_fail (error == NULL || *error == NULL, 0); + return G_DBUS_INTERFACE_STUB_GET_CLASS (stub)->export (stub, connection, object_path, error); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusInterfaceInfo * +_g_dbus_interface_stub_get_info (GDBusInterface *interface) +{ + GDBusInterfaceStub *stub = G_DBUS_INTERFACE_STUB (interface); + return g_dbus_interface_stub_get_info (stub); +} + +static GDBusObject * +g_dbus_interface_stub_get_object (GDBusInterface *interface) +{ + GDBusInterfaceStub *stub = G_DBUS_INTERFACE_STUB (interface); + return stub->priv->object; +} + +static void +g_dbus_interface_stub_set_object (GDBusInterface *interface, + GDBusObject *object) +{ + GDBusInterfaceStub *stub = G_DBUS_INTERFACE_STUB (interface); + if (stub->priv->object != NULL) + g_object_remove_weak_pointer (G_OBJECT (stub->priv->object), (gpointer *) &stub->priv->object); + stub->priv->object = object; + if (object != NULL) + g_object_add_weak_pointer (G_OBJECT (stub->priv->object), (gpointer *) &stub->priv->object); +} + +static void +dbus_interface_interface_init (GDBusInterfaceIface *iface) +{ + iface->get_info = _g_dbus_interface_stub_get_info; + iface->get_object = g_dbus_interface_stub_get_object; + iface->set_object = g_dbus_interface_stub_set_object; +} diff --git a/src/gdbusinterfacestub.h b/src/gdbusinterfacestub.h new file mode 100644 index 0000000..aac0e05 --- /dev/null +++ b/src/gdbusinterfacestub.h @@ -0,0 +1,92 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#ifndef __G_DBUS_INTERFACE_STUB_H__ +#define __G_DBUS_INTERFACE_STUB_H__ + +#include <gio/gio.h> +#include <gdbusinterface.h> + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_INTERFACE_STUB (g_dbus_interface_stub_get_type ()) +#define G_DBUS_INTERFACE_STUB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_INTERFACE_STUB, GDBusInterfaceStub)) +#define G_DBUS_INTERFACE_STUB_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_INTERFACE_STUB, GDBusInterfaceStubClass)) +#define G_DBUS_INTERFACE_STUB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_INTERFACE_STUB, GDBusInterfaceStubClass)) +#define G_IS_DBUS_INTERFACE_STUB(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_INTERFACE_STUB)) +#define G_IS_DBUS_INTERFACE_STUB_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_INTERFACE_STUB)) + +typedef struct _GDBusInterfaceStub GDBusInterfaceStub; +typedef struct _GDBusInterfaceStubClass GDBusInterfaceStubClass; +typedef struct _GDBusInterfaceStubPrivate GDBusInterfaceStubPrivate; + +/** + * GDBusInterfaceStub: + * + * The #GDBusInterfaceStub structure contains private data and should + * only be accessed using the provided API. + */ +struct _GDBusInterfaceStub +{ + /*< private >*/ + GObject parent_instance; + GDBusInterfaceStubPrivate *priv; +}; + +/** + * GDBusInterfaceStubClass: + * @parent_class: The parent class. + * @get_info: Returns a #GDBusInterfaceInfo. See g_dbus_interface_stub_get_info(). + * @get_properties: Returns a new, floating, #GVariant with all properties. See g_dbus_interface_stub_get_properties(). + * @flush: Emits outstanding changes, if any. See g_dbus_interface_stub_flush(). + * @export: Exports the instance on a #GDBusConnection. See g_dbus_interface_stub_export(). + * + * Class structure for #GDBusInterfaceStub. + */ +struct _GDBusInterfaceStubClass +{ + GObjectClass parent_class; + + /* Virtual Functions */ + GDBusInterfaceInfo *(*get_info) (GDBusInterfaceStub *stub); + GVariant *(*get_properties) (GDBusInterfaceStub *stub); + void (*flush) (GDBusInterfaceStub *stub); + guint (*export) (GDBusInterfaceStub *stub, + GDBusConnection *connection, + const gchar *object_path, + GError **error); + + /*< private >*/ + gpointer padding[8]; +}; + +GType g_dbus_interface_stub_get_type (void) G_GNUC_CONST; +GDBusInterfaceInfo *g_dbus_interface_stub_get_info (GDBusInterfaceStub *stub); +GVariant *g_dbus_interface_stub_get_properties (GDBusInterfaceStub *stub); +void g_dbus_interface_stub_flush (GDBusInterfaceStub *stub); +guint g_dbus_interface_stub_export (GDBusInterfaceStub *stub, + GDBusConnection *connection, + const gchar *object_path, + GError **error); +G_END_DECLS + +#endif /* __G_DBUS_INTERFACE_STUB_H */ diff --git a/src/gdbusobject.c b/src/gdbusobject.c deleted file mode 100644 index 6e1ee02..0000000 --- a/src/gdbusobject.c +++ /dev/null @@ -1,442 +0,0 @@ -/* GDBus - GLib D-Bus Library - * - * Copyright (C) 2008-2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: David Zeuthen <davidz@redhat.com> - */ - -#include "config.h" - -#include "gdbusobject.h" - -/** - * SECTION:gdbusobject - * @short_description: A group of D-Bus interfaces - * @include: gio/gio.h - * - * #GDBusObject represents a group of D-Bus interfaces. The set is - * dynamic and may change at runtime. The type is intended to be used - * with #GDBusObjectManager. - */ - -struct _GDBusObjectPrivate -{ - gchar *object_path; - GHashTable *map_name_to_iface; -}; - -enum -{ - PROP_0, - PROP_OBJECT_PATH -}; - -enum -{ - INTERFACE_ADDED_SIGNAL, - INTERFACE_REMOVED_SIGNAL, - LAST_SIGNAL, -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE (GDBusObject, g_dbus_object, G_TYPE_OBJECT); - -static void -g_dbus_object_finalize (GObject *_object) -{ - GDBusObject *object = G_DBUS_OBJECT (_object); - - g_free (object->priv->object_path); - g_hash_table_unref (object->priv->map_name_to_iface); - - if (G_OBJECT_CLASS (g_dbus_object_parent_class)->finalize != NULL) - G_OBJECT_CLASS (g_dbus_object_parent_class)->finalize (_object); -} - -static void -g_dbus_object_get_property (GObject *_object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GDBusObject *object = G_DBUS_OBJECT (_object); - - switch (prop_id) - { - case PROP_OBJECT_PATH: - g_value_take_string (value, g_dbus_object_get_object_path (object)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec); - break; - } -} - -static void -g_dbus_object_set_property (GObject *_object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GDBusObject *object = G_DBUS_OBJECT (_object); - gchar *object_path; - - switch (prop_id) - { - case PROP_OBJECT_PATH: - object_path = g_value_dup_string (value); - g_assert (object_path == NULL || g_variant_is_object_path (object_path)); - g_free (object->priv->object_path); - object->priv->object_path = object_path; - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec); - break; - } -} - -static void -g_dbus_object_class_init (GDBusObjectClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->finalize = g_dbus_object_finalize; - gobject_class->set_property = g_dbus_object_set_property; - gobject_class->get_property = g_dbus_object_get_property; - - /** - * GDBusObject:object-path: - * - * The object path where the object is exported. - */ - g_object_class_install_property (gobject_class, - PROP_OBJECT_PATH, - g_param_spec_string ("object-path", - "Object Path", - "The object path where the object is exported", - NULL, - G_PARAM_READABLE | - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS)); - - /** - * GDBusObject::interface-added: - * @object: The #GDBusObject emitting the signal. - * @interface: The #GDBusInterface that was added. - * - * Emitted when @interface is added to @object. - */ - signals[INTERFACE_ADDED_SIGNAL] = g_signal_new ("interface-added", - G_TYPE_DBUS_OBJECT, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GDBusObjectClass, interface_added), - NULL, - NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - G_TYPE_DBUS_INTERFACE); - - /** - * GDBusObject::interface-removed: - * @object: The #GDBusObject emitting the signal. - * @interface: The #GDBusInterface that was removed. - * - * Emitted when @interface is removed from @object. - */ - signals[INTERFACE_REMOVED_SIGNAL] = g_signal_new ("interface-removed", - G_TYPE_DBUS_OBJECT, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GDBusObjectClass, interface_removed), - NULL, - NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - G_TYPE_DBUS_INTERFACE); - - g_type_class_add_private (klass, sizeof (GDBusObjectPrivate)); -} - -static void -g_dbus_object_init (GDBusObject *object) -{ - object->priv = G_TYPE_INSTANCE_GET_PRIVATE (object, G_TYPE_DBUS_OBJECT, GDBusObjectPrivate); - object->priv->map_name_to_iface = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - (GDestroyNotify) g_object_unref); -} - -/** - * g_dbus_object_new: - * @object_path: An object path. - * - * Creates a new #GDBusObject. - * - * Returns: A #GDBusObject. Free with g_object_unref(). - */ -GDBusObject * -g_dbus_object_new (const gchar *object_path) -{ - g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); - return G_DBUS_OBJECT (g_object_new (G_TYPE_DBUS_OBJECT, - "object-path", object_path, - NULL)); -} - -/** - * g_dbus_object_get_object_path: - * @object: A #GDBusObject. - * - * Gets the object path for @object. - * - * Returns: An object path. The returned string should be freed with g_free(). - */ -gchar * -g_dbus_object_get_object_path (GDBusObject *object) -{ - g_return_val_if_fail (G_IS_DBUS_OBJECT (object), NULL); - return g_strdup (object->priv->object_path); -} - -/** - * g_dbus_object_set_object_path: - * @object: A #GDBusObject. - * @object_path: A valid D-Bus object path. - * - * Sets the object path for @object. - */ -void -g_dbus_object_set_object_path (GDBusObject *object, - const gchar *object_path) -{ - g_return_if_fail (G_IS_DBUS_OBJECT (object)); - g_return_if_fail (g_variant_is_object_path (object_path)); - /* TODO: fail if object is currently exported */ - if (g_strcmp0 (object->priv->object_path, object_path) != 0) - { - g_free (object->priv->object_path); - object->priv->object_path = g_strdup (object_path); - g_object_notify (G_OBJECT (object), "object-path"); - } -} - -/** - * g_dbus_object_add_interface: - * @object: A #GDBusObject. - * @interface: A #GDBusInterface. - * - * Adds @interface to @object. - * - * If @object already contains a #GDBusInterface with the same - * interface name, the old interface is dropped. - * - * Note that @object takes its own reference on @interface and holds - * it until removed. - */ -void -g_dbus_object_add_interface (GDBusObject *object, - GDBusInterface *interface) -{ - GDBusInterfaceInfo *info; - - g_return_if_fail (G_IS_DBUS_OBJECT (object)); - g_return_if_fail (G_IS_DBUS_INTERFACE (interface)); - - info = g_dbus_interface_get_info (interface); - g_object_ref (interface); - g_dbus_object_remove_interface_by_name (object, info->name); - g_hash_table_insert (object->priv->map_name_to_iface, - g_strdup (info->name), - interface); - g_dbus_interface_set_object (interface, object); - g_signal_emit (object, - signals[INTERFACE_ADDED_SIGNAL], - 0, - interface); -} - -/** - * g_dbus_object_remove_interface: - * @object: A #GDBusObject. - * @interface: A #GDBusInterface. - * - * Removes @interface from @object. - */ -void -g_dbus_object_remove_interface (GDBusObject *object, - GDBusInterface *interface) -{ - GDBusInterface *other_interface; - GDBusInterfaceInfo *info; - - g_return_if_fail (G_IS_DBUS_OBJECT (object)); - g_return_if_fail (G_IS_DBUS_INTERFACE (interface)); - - info = g_dbus_interface_get_info (interface); - - other_interface = g_hash_table_lookup (object->priv->map_name_to_iface, info->name); - if (other_interface == NULL) - { - g_warning ("Tried to remove interface with name %s from object " - "at path %s but no such interface exists", - info->name, - object->priv->object_path); - } - else if (other_interface != interface) - { - g_warning ("Tried to remove interface %p with name %s from object " - "at path %s but the object has the interface %p", - interface, - info->name, - object->priv->object_path, - other_interface); - } - else - { - g_object_ref (interface); - g_warn_if_fail (g_hash_table_remove (object->priv->map_name_to_iface, info->name)); - g_dbus_interface_set_object (interface, NULL); - g_signal_emit (object, - signals[INTERFACE_REMOVED_SIGNAL], - 0, - interface); - g_object_unref (interface); - } -} - - -/** - * g_dbus_object_remove_interface_by_name: - * @object: A #GDBusObject. - * @interface_name: A D-Bus interface name. - * - * Removes the #GDBusInterface with @interface_name from @object. - * - * If no D-Bus interface of the given interface exists, this function - * does nothing. - */ -void -g_dbus_object_remove_interface_by_name (GDBusObject *object, - const gchar *interface_name) -{ - GDBusInterface *interface; - - g_return_if_fail (G_IS_DBUS_OBJECT (object)); - g_return_if_fail (g_dbus_is_interface_name (interface_name)); - - interface = g_hash_table_lookup (object->priv->map_name_to_iface, interface_name); - if (interface != NULL) - { - g_object_ref (interface); - g_warn_if_fail (g_hash_table_remove (object->priv->map_name_to_iface, interface_name)); - g_dbus_interface_set_object (interface, NULL); - g_signal_emit (object, - signals[INTERFACE_REMOVED_SIGNAL], - 0, - interface); - g_object_unref (interface); - } -} - -/** - * g_dbus_object_lookup_interface: - * @object: A #GDBusObject. - * @interface_name: A D-Bus interface name. - * - * Looks up the #GDBusInterface on @object for @interface_name. If no - * such interface exists, %NULL is returned. - * - * Returns: A #GDBusInterface or %NULL if not found. Free with - * g_object_unref(). - */ -GDBusInterface * -g_dbus_object_lookup_interface (GDBusObject *object, - const gchar *interface_name) -{ - GDBusInterface *ret; - - g_return_val_if_fail (G_IS_DBUS_OBJECT (object), NULL); - g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL); - - ret = g_hash_table_lookup (object->priv->map_name_to_iface, interface_name); - if (ret != NULL) - g_object_ref (ret); - return ret; -} - -/** - * g_dbus_object_get_interfaces: - * @object: A #GDBusObject. - * - * Gets the #GDBusInterface objects that are associated with #object, if any. - * - * Returns: A list of #GDBusInterface objects. The returned list - * should be freed with g_list_free() after each element has been - * freed with g_object_unref(). - */ -GList * -g_dbus_object_get_interfaces (GDBusObject *object) -{ - GList *ret; - GHashTableIter iter; - GDBusInterface *interface; - - g_return_val_if_fail (G_IS_DBUS_OBJECT (object), NULL); - - ret = NULL; - - g_hash_table_iter_init (&iter, object->priv->map_name_to_iface); - while (g_hash_table_iter_next (&iter, NULL, (gpointer) &interface)) - ret = g_list_prepend (ret, g_object_ref (interface)); - - return ret; -} - -/** - * g_dbus_object_flush: - * @object: A #GDBusObject. - * - * If interfaces belonging to @object have outstanding changes, make - * sure they are emitted. For example, if an interface has queued - * property notifications, this will empty the queue forcing - * <literal>org.freedesktop.DBus.Properties::PropertiesChanged</literal> - * signals to be emitted. - * - * This method simply calls g_dbus_interface_flush() on all interfaces - * belonging to @object. - */ -void -g_dbus_object_flush (GDBusObject *object) -{ - GHashTableIter iter; - GDBusInterface *interface; - - g_hash_table_iter_init (&iter, object->priv->map_name_to_iface); - while (g_hash_table_iter_next (&iter, NULL, (gpointer) &interface)) - { - g_dbus_interface_flush (interface); - } -} - - diff --git a/src/gdbusobject.h b/src/gdbusobject.h deleted file mode 100644 index 593c074..0000000 --- a/src/gdbusobject.h +++ /dev/null @@ -1,93 +0,0 @@ -/* GDBus - GLib D-Bus Library - * - * Copyright (C) 2008-2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: David Zeuthen <davidz@redhat.com> - */ - -#ifndef __G_DBUS_OBJECT_H__ -#define __G_DBUS_OBJECT_H__ - -#include <gio/gio.h> -#include <gdbusinterface.h> - -G_BEGIN_DECLS - -#define G_TYPE_DBUS_OBJECT (g_dbus_object_get_type ()) -#define G_DBUS_OBJECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_OBJECT, GDBusObject)) -#define G_DBUS_OBJECT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_OBJECT, GDBusObjectClass)) -#define G_DBUS_OBJECT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_OBJECT, GDBusObjectClass)) -#define G_IS_DBUS_OBJECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_OBJECT)) -#define G_IS_DBUS_OBJECT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_OBJECT)) - -typedef struct _GDBusObjectClass GDBusObjectClass; -typedef struct _GDBusObjectPrivate GDBusObjectPrivate; - -/** - * GDBusObject: - * - * The #GDBusObject structure contains private data and should only be - * accessed using the provided API. - */ -struct _GDBusObject -{ - /*< private >*/ - GObject parent_instance; - GDBusObjectPrivate *priv; -}; - -/** - * GDBusObjectClass: - * @parent_class: The parent class. - * @interface_added: Signal class handler for the #GDBusObject::interface-added signal. - * @interface_removed: Signal class handler for the #GDBusObject::interface-removed signal. - * - * Class structure for #GDBusObject. - */ -struct _GDBusObjectClass -{ - GObjectClass parent_class; - - void (*interface_added) (GDBusObject *object, - GDBusInterface *interface); - void (*interface_removed) (GDBusObject *object, - GDBusInterface *interface); - - /*< private >*/ - gpointer padding[8]; -}; - -GType g_dbus_object_get_type (void) G_GNUC_CONST; -GDBusObject *g_dbus_object_new (const gchar *object_path); -gchar *g_dbus_object_get_object_path (GDBusObject *object); -void g_dbus_object_set_object_path (GDBusObject *object, - const gchar *object_path); -void g_dbus_object_flush (GDBusObject *object); -void g_dbus_object_add_interface (GDBusObject *object, - GDBusInterface *interface); -void g_dbus_object_remove_interface (GDBusObject *object, - GDBusInterface *interface); -void g_dbus_object_remove_interface_by_name (GDBusObject *object, - const gchar *interface_name); -GDBusInterface *g_dbus_object_lookup_interface (GDBusObject *object, - const gchar *interface_name); -GList *g_dbus_object_get_interfaces (GDBusObject *object); - -G_END_DECLS - -#endif /* __G_DBUS_OBJECT_H */ diff --git a/src/gdbusobjectmanager.c b/src/gdbusobjectmanager.c index 4cf655f..c972165 100644 --- a/src/gdbusobjectmanager.c +++ b/src/gdbusobjectmanager.c @@ -25,6 +25,9 @@ #include "config.h" #include "gdbusobjectmanager.h" +#include "gdbusobject.h" +#include "gdbusobjectstub.h" +#include "gdbusinterfacestub.h" /** * SECTION:gdbusobjectmanager @@ -47,7 +50,7 @@ typedef struct { - GDBusInterface *interface; + GDBusInterfaceStub *interface_stub; guint reg_id; } IfaceData; @@ -55,7 +58,7 @@ static void iface_data_free (IfaceData *data); typedef struct { - GDBusObject *object; + GDBusObjectStub *object; GDBusObjectManager *manager; GHashTable *map_iface_name_to_iface_data; gboolean exported; @@ -276,23 +279,23 @@ g_dbus_object_manager_get_object_path (GDBusObjectManager *manager) /* ---------------------------------------------------------------------------------------------------- */ static void -registration_data_export_interface (RegistrationData *data, - GDBusInterface *interface) +registration_data_export_interface (RegistrationData *data, + GDBusInterfaceStub *interface_stub) { GDBusInterfaceInfo *info; guint registration_id; GError *error; IfaceData *iface_data; - gchar *object_path; + const gchar *object_path; - object_path = g_dbus_object_get_object_path (data->object); + object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object)); - info = g_dbus_interface_get_info (interface); + info = g_dbus_interface_stub_get_info (interface_stub); error = NULL; - registration_id = g_dbus_interface_register_object (interface, - data->manager->priv->connection, - object_path, - &error); + registration_id = g_dbus_interface_stub_export (interface_stub, + data->manager->priv->connection, + object_path, + &error); if (registration_id == 0) { /* TODO: probably wrong to complain on stderr */ @@ -307,7 +310,7 @@ registration_data_export_interface (RegistrationData *data, iface_data = g_new0 (IfaceData, 1); iface_data->reg_id = registration_id; - iface_data->interface = g_object_ref (interface); + iface_data->interface_stub = g_object_ref (interface_stub); g_assert (g_hash_table_lookup (data->map_iface_name_to_iface_data, info->name) == NULL); g_hash_table_insert (data->map_iface_name_to_iface_data, @@ -325,17 +328,18 @@ registration_data_export_interface (RegistrationData *data, } out: - g_free (object_path); + ; + //g_free (object_path); } static void -registration_data_unexport_interface (RegistrationData *data, - GDBusInterface *interface) +registration_data_unexport_interface (RegistrationData *data, + GDBusInterfaceStub *interface_stub) { GDBusInterfaceInfo *info; IfaceData *iface_data; - info = g_dbus_interface_get_info (interface); + info = g_dbus_interface_stub_get_info (interface_stub); iface_data = g_hash_table_lookup (data->map_iface_name_to_iface_data, info->name); g_assert (iface_data != NULL); g_assert (iface_data->reg_id > 0); @@ -363,7 +367,7 @@ on_interface_added (GDBusObject *object, gpointer user_data) { RegistrationData *data = user_data; - registration_data_export_interface (data, interface); + registration_data_export_interface (data, G_DBUS_INTERFACE_STUB (interface)); } static void @@ -372,7 +376,7 @@ on_interface_removed (GDBusObject *object, gpointer user_data) { RegistrationData *data = user_data; - registration_data_unexport_interface (data, interface); + registration_data_unexport_interface (data, G_DBUS_INTERFACE_STUB (interface)); } /* ---------------------------------------------------------------------------------------------------- */ @@ -380,7 +384,7 @@ on_interface_removed (GDBusObject *object, static void iface_data_free (IfaceData *data) { - g_object_unref (data->interface); + g_object_unref (data->interface_stub); g_free (data); } @@ -411,7 +415,7 @@ registration_data_free (RegistrationData *data) /** * g_dbus_object_manager_export: * @manager: A #GDBusObjectManager. - * @object: A #GDBusObject. + * @object: A #GDBusObjectStub. * * Exports @object on @manager. * @@ -426,15 +430,15 @@ registration_data_free (RegistrationData *data) */ void g_dbus_object_manager_export (GDBusObjectManager *manager, - GDBusObject *object) + GDBusObjectStub *object) { RegistrationData *data; GList *existing_interfaces; GList *l; GPtrArray *interface_names; - gchar *object_path; + const gchar *object_path; - object_path = g_dbus_object_get_object_path (object); + object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object)); g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER (manager)); g_return_if_fail (G_IS_DBUS_OBJECT (object)); @@ -466,12 +470,12 @@ g_dbus_object_manager_export (GDBusObjectManager *manager, /* Register all known interfaces - note that data->exported is FALSE so * we don't emit any InterfacesAdded signals. */ - existing_interfaces = g_dbus_object_get_interfaces (object); + existing_interfaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (object)); for (l = existing_interfaces; l != NULL; l = l->next) { - GDBusInterface *interface = G_DBUS_INTERFACE (l->data); - registration_data_export_interface (data, interface); - g_ptr_array_add (interface_names, g_dbus_interface_get_info (interface)->name); + GDBusInterfaceStub *interface_stub = G_DBUS_INTERFACE_STUB (l->data); + registration_data_export_interface (data, interface_stub); + g_ptr_array_add (interface_names, g_dbus_interface_stub_get_info (interface_stub)->name); } g_list_foreach (existing_interfaces, (GFunc) g_object_unref, NULL); g_list_free (existing_interfaces); @@ -484,7 +488,7 @@ g_dbus_object_manager_export (GDBusObjectManager *manager, g_ptr_array_unref (interface_names); g_hash_table_insert (manager->priv->map_object_path_to_data, - object_path, /* takes ownership of object_path */ + g_strdup (object_path), data); } @@ -501,14 +505,14 @@ g_dbus_object_manager_export (GDBusObjectManager *manager, */ void g_dbus_object_manager_export_and_uniquify (GDBusObjectManager *manager, - GDBusObject *object) + GDBusObjectStub *object) { gchar *orig_object_path; gchar *object_path; guint count; gboolean modified; - orig_object_path = g_dbus_object_get_object_path (object); + orig_object_path = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (object))); g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER (manager)); g_return_if_fail (G_IS_DBUS_OBJECT (object)); @@ -531,7 +535,7 @@ g_dbus_object_manager_export_and_uniquify (GDBusObjectManager *manager, } if (modified) - g_dbus_object_set_object_path (object, object_path); + g_dbus_object_stub_set_object_path (G_DBUS_OBJECT_STUB (object), object_path); g_dbus_object_manager_export (manager, object); @@ -723,7 +727,7 @@ manager_method_call (GDBusConnection *connection, GVariantBuilder interfaces_builder; GHashTableIter interface_iter; IfaceData *iface_data; - gchar *object_path; + const gchar *iter_object_path; g_variant_builder_init (&interfaces_builder, G_VARIANT_TYPE ("a{sa{sv}}")); g_hash_table_iter_init (&interface_iter, data->map_iface_name_to_iface_data); @@ -731,15 +735,14 @@ manager_method_call (GDBusConnection *connection, { g_variant_builder_add_value (&interfaces_builder, g_variant_new ("{s@a{sv}}", - g_dbus_interface_get_info (iface_data->interface)->name, - g_dbus_interface_get_properties (iface_data->interface))); + g_dbus_interface_stub_get_info (iface_data->interface_stub)->name, + g_dbus_interface_stub_get_properties (iface_data->interface_stub))); } - object_path = g_dbus_object_get_object_path (data->object); + iter_object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object)); g_variant_builder_add (&array_builder, "{oa{sa{sv}}}", - object_path, + iter_object_path, &interfaces_builder); - g_free (object_path); } g_dbus_method_invocation_return_value (invocation, @@ -801,7 +804,7 @@ g_dbus_object_manager_emit_interfaces_added (GDBusObjectManager *manager, GVariantBuilder array_builder; GError *error; guint n; - gchar *object_path; + const gchar *object_path; g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("a{sa{sv}}")); for (n = 0; interfaces[n] != NULL; n++) @@ -812,11 +815,11 @@ g_dbus_object_manager_emit_interfaces_added (GDBusObjectManager *manager, g_variant_builder_add_value (&array_builder, g_variant_new ("{s@a{sv}}", interfaces[n], - g_dbus_interface_get_properties (iface_data->interface))); + g_dbus_interface_stub_get_properties (iface_data->interface_stub))); } error = NULL; - object_path = g_dbus_object_get_object_path (data->object); + object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object)); g_dbus_connection_emit_signal (data->manager->priv->connection, NULL, /* destination_bus_name */ manager->priv->object_path, @@ -826,7 +829,6 @@ g_dbus_object_manager_emit_interfaces_added (GDBusObjectManager *manager, object_path, &array_builder), &error); - g_free (object_path); g_assert_no_error (error); } @@ -838,14 +840,14 @@ g_dbus_object_manager_emit_interfaces_removed (GDBusObjectManager *manager, GVariantBuilder array_builder; GError *error; guint n; - gchar *object_path; + const gchar *object_path; g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("as")); for (n = 0; interfaces[n] != NULL; n++) g_variant_builder_add (&array_builder, "s", interfaces[n]); error = NULL; - object_path = g_dbus_object_get_object_path (data->object); + object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object)); g_dbus_connection_emit_signal (data->manager->priv->connection, NULL, /* destination_bus_name */ manager->priv->object_path, @@ -855,7 +857,6 @@ g_dbus_object_manager_emit_interfaces_removed (GDBusObjectManager *manager, object_path, &array_builder), &error); - g_free (object_path); g_assert_no_error (error); } @@ -863,11 +864,11 @@ g_dbus_object_manager_emit_interfaces_removed (GDBusObjectManager *manager, * g_dbus_object_manager_get_all: * @manager: A #GDBusObjectManager. * - * Gets all #GDBusObject<!-- -->s currently being exported. + * Gets all #GDBusObjectStub<!-- -->s currently being exported. * - * Returns: A #GList of #GDBusObject objects. The returned list must - * be freed with g_list_free() after each element has been freed with - * g_object_unref(). + * Returns: A #GList of #GDBusObjectStub objects. The returned list + * must be freed with g_list_free() after each element has been freed + * with g_object_unref(). */ GList * g_dbus_object_manager_get_all (GDBusObjectManager *manager) diff --git a/src/gdbusobjectmanager.h b/src/gdbusobjectmanager.h index 38d287c..192cad7 100644 --- a/src/gdbusobjectmanager.h +++ b/src/gdbusobjectmanager.h @@ -24,7 +24,7 @@ #define __G_DBUS_OBJECT_MANAGER_H__ #include <gio/gio.h> -#include <gdbusobject.h> +#include <gdbusobjectstub.h> G_BEGIN_DECLS @@ -72,9 +72,9 @@ GDBusObjectManager *g_dbus_object_manager_new (GDBusConnecti GDBusConnection *g_dbus_object_manager_get_connection (GDBusObjectManager *manager); const gchar *g_dbus_object_manager_get_object_path (GDBusObjectManager *manager); void g_dbus_object_manager_export (GDBusObjectManager *manager, - GDBusObject *object); + GDBusObjectStub *object); void g_dbus_object_manager_export_and_uniquify (GDBusObjectManager *manager, - GDBusObject *object); + GDBusObjectStub *object); void g_dbus_object_manager_unexport (GDBusObjectManager *manager, const gchar *object_path); GList *g_dbus_object_manager_get_all (GDBusObjectManager *manager); diff --git a/src/gdbusobjectproxy.c b/src/gdbusobjectproxy.c index 5339c63..a3ea2ea 100644 --- a/src/gdbusobjectproxy.c +++ b/src/gdbusobjectproxy.c @@ -22,17 +22,18 @@ #include "config.h" +#include "gdbusobject.h" #include "gdbusobjectproxy.h" /** * SECTION:gdbusobjectproxy - * @short_description: A group of D-Bus interface proxies + * @short_description: Client-side D-Bus object * @include: gio/gio.h * - * A #GDBusObjectProxy is an object used client-side to represent a - * remote object with one or more D-Bus interfaces. You cannot - * instantiate a #GDBusObjectProxy yourself - you need to use a - * #GDBusProxyManager. + * A #GDBusObjectProxy is an object used to represent a remote object + * with one or more D-Bus interfaces. You cannot instantiate a + * #GDBusObjectProxy yourself - you need to use a #GDBusProxyManager + * to get one. */ struct _GDBusObjectProxyPrivate @@ -49,16 +50,10 @@ enum PROP_CONNECTION }; -enum -{ - INTERFACE_PROXY_ADDED_SIGNAL, - INTERFACE_PROXY_REMOVED_SIGNAL, - LAST_SIGNAL, -}; +static void dbus_object_interface_init (GDBusObjectIface *iface); -static guint signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE (GDBusObjectProxy, g_dbus_object_proxy, G_TYPE_OBJECT); +G_DEFINE_TYPE_WITH_CODE (GDBusObjectProxy, g_dbus_object_proxy, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, dbus_object_interface_init)); static void g_dbus_object_proxy_finalize (GObject *object) @@ -82,7 +77,7 @@ g_dbus_object_proxy_get_property (GObject *object, switch (prop_id) { case PROP_OBJECT_PATH: - g_value_set_string (value, g_dbus_object_proxy_get_object_path (proxy)); + g_value_set_string (value, proxy->priv->object_path); break; case PROP_CONNECTION: @@ -146,53 +141,6 @@ g_dbus_object_proxy_class_init (GDBusObjectProxyClass *klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - /** - * GDBusObjectProxy::interface-proxy-added: - * @proxy: The #GDBusObjectProxy emitting the signal. - * @interface_proxy: The #GDBusProxy that was added. - * - * Emitted when @interface_proxy is added to @proxy. - * - * This signal is emitted in the - * <link linkend="g-main-context-push-thread-default">thread-default main loop</link> - * that the #GDBusProxyManager owning @proxy was constructed in. - */ - signals[INTERFACE_PROXY_ADDED_SIGNAL] = - g_signal_new ("interface-proxy-added", - G_TYPE_DBUS_OBJECT_PROXY, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GDBusObjectProxyClass, interface_proxy_added), - NULL, - NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - G_TYPE_DBUS_PROXY); - - /** - * GDBusObjectProxy::interface-proxy-removed: - * @proxy: The #GDBusObjectProxy emitting the signal. - * @interface_proxy: The #GDBusProxy that was removed. - * - * Emitted when @interface_proxy is removed from @proxy. - * - * This signal is emitted in the - * <link linkend="g-main-context-push-thread-default">thread-default main loop</link> - * that the #GDBusProxyManager owning @proxy was constructed in. - */ - signals[INTERFACE_PROXY_REMOVED_SIGNAL] = - g_signal_new ("interface-proxy-removed", - G_TYPE_DBUS_OBJECT_PROXY, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GDBusObjectProxyClass, interface_proxy_removed), - NULL, - NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - G_TYPE_DBUS_PROXY); - g_type_class_add_private (klass, sizeof (GDBusObjectProxyPrivate)); } @@ -208,18 +156,10 @@ g_dbus_object_proxy_init (GDBusObjectProxy *proxy) (GDestroyNotify) g_object_unref); } -/** - * g_dbus_object_proxy_get_object_path: - * @proxy: A #GDBusObjectProxy. - * - * Gets the object path that @proxy is for. - * - * Returns: An object path. Do not free, the string is owned by @proxy. - */ -const gchar * -g_dbus_object_proxy_get_object_path (GDBusObjectProxy *proxy) +static const gchar * +g_dbus_object_proxy_get_object_path (GDBusObject *object) { - g_return_val_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy), NULL); + GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object); return proxy->priv->object_path; } @@ -238,26 +178,11 @@ g_dbus_object_proxy_get_connection (GDBusObjectProxy *proxy) return proxy->priv->connection; } - -/** - * g_dbus_object_proxy_lookup: - * @proxy: A #GDBusObjectProxy. - * @interface_name: A D-Bus interface name. - * - * Looks up the interface proxy (A #GDBusProxy object) on @proxy for - * @interface_name. If no such interface exists, %NULL is returned. - * - * The type of returned interface proxy may be a subtype of - * #GDBusProxy - it is determined by the #GDBusProxyTypeFunc that the - * #GDBusProxyManager object for @proxy was constructed with. - * - * Returns: A #GDBusProxy or %NULL if not found. Free with - * g_object_unref(). - */ -GDBusProxy * -g_dbus_object_proxy_lookup (GDBusObjectProxy *proxy, - const gchar *interface_name) +static GDBusInterface * +g_dbus_object_proxy_get_interface (GDBusObject *object, + const gchar *interface_name) { + GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object); GDBusProxy *ret; g_return_val_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy), NULL); @@ -266,22 +191,13 @@ g_dbus_object_proxy_lookup (GDBusObjectProxy *proxy, ret = g_hash_table_lookup (proxy->priv->map_name_to_iface, interface_name); if (ret != NULL) g_object_ref (ret); - return ret; + return (GDBusInterface *) ret; /* TODO: proper cast */ } -/** - * g_dbus_object_proxy_get_all: - * @proxy: A #GDBusObjectProxy. - * - * Gets all interface proxies (#GDBusProxy objects) that are associated with #proxy, if any. - * - * Returns: A list of #GDBusProxy objects. The returned list should be - * freed with g_list_free() after each element has been freed with - * g_object_unref(). - */ -GList * -g_dbus_object_proxy_get_all (GDBusObjectProxy *proxy) +static GList * +g_dbus_object_proxy_get_interfaces (GDBusObject *object) { + GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object); GList *ret; GHashTableIter iter; GDBusProxy *interface_proxy; @@ -335,10 +251,7 @@ _g_dbus_object_proxy_add_interface (GDBusObjectProxy *proxy, g_hash_table_insert (proxy->priv->map_name_to_iface, g_strdup (interface_name), g_object_ref (interface_proxy)); - g_signal_emit (proxy, - signals[INTERFACE_PROXY_ADDED_SIGNAL], - 0, - interface_proxy); + g_signal_emit_by_name (proxy, "interface-added", interface_proxy); } void @@ -355,66 +268,17 @@ _g_dbus_object_proxy_remove_interface (GDBusObjectProxy *proxy, { g_object_ref (interface_proxy); g_warn_if_fail (g_hash_table_remove (proxy->priv->map_name_to_iface, interface_name)); - g_signal_emit (proxy, - signals[INTERFACE_PROXY_REMOVED_SIGNAL], - 0, - interface_proxy); + g_signal_emit_by_name (proxy, "interface-removed", interface_proxy); g_object_unref (interface_proxy); } } -/** - * g_dbus_object_proxy_peek_with_typecheck: - * @proxy: A #GDBusObjectProxy. - * @interface_name: A D-Bus interface name. - * @type: The #GType that the returned object must conform to. - * - * Like g_dbus_object_proxy_lookup_with_typecheck() except that the - * caller does not own a reference to the returned object. - * - * <note><para>This function is not safe to use outside the thread - * where the #GDBusProxyManager for @object_proxy was constructed - * in.</para></note> - * - * <note><para>This function is intended to only be used in type - * implementations.</para></note> - * - * Returns: A #GDBusProxy implementing @type or %NULL if - * not found. Do not free the returned object, it is owned by - * @object_proxy. - */ -gpointer -g_dbus_object_proxy_peek_with_typecheck (GDBusObjectProxy *proxy, - const gchar *interface_name, - GType type) -{ - GDBusProxy *ret; - ret = g_dbus_object_proxy_lookup_with_typecheck (proxy, interface_name, type); - if (ret != NULL) - g_object_unref (ret); - return ret; -} - -/** - * g_dbus_object_proxy_lookup_with_typecheck: - * @proxy: A #GDBusObjectProxy. - * @interface_name: A D-Bus interface name. - * @type: The #GType that the returned object must conform to. - * - * Like g_dbus_object_proxy_lookup() but warns on stderr if the - * returned object, if any, does not conform to @type. - * - * <note><para>This function is intended to only be used in type - * implementations.</para></note> - * - * Returns: A #GDBusProxy implementing @type or %NULL if - * not found. Free with g_object_unref(). - */ -gpointer -g_dbus_object_proxy_lookup_with_typecheck (GDBusObjectProxy *proxy, - const gchar *interface_name, - GType type) +static gpointer +g_dbus_object_proxy_lookup_with_typecheck (GDBusObject *object, + const gchar *interface_name, + GType type) { + GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object); GDBusProxy *ret; g_return_val_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy), NULL); @@ -428,3 +292,25 @@ g_dbus_object_proxy_lookup_with_typecheck (GDBusObjectProxy *proxy, } return ret; } + +static gpointer +g_dbus_object_proxy_peek_with_typecheck (GDBusObject *object, + const gchar *interface_name, + GType type) +{ + GDBusProxy *ret; + ret = g_dbus_object_proxy_lookup_with_typecheck (object, interface_name, type); + if (ret != NULL) + g_object_unref (ret); + return ret; +} + +static void +dbus_object_interface_init (GDBusObjectIface *iface) +{ + iface->get_object_path = g_dbus_object_proxy_get_object_path; + iface->get_interfaces = g_dbus_object_proxy_get_interfaces; + iface->get_interface = g_dbus_object_proxy_get_interface; + iface->peek_with_typecheck = g_dbus_object_proxy_peek_with_typecheck; + iface->lookup_with_typecheck = g_dbus_object_proxy_lookup_with_typecheck; +} diff --git a/src/gdbusobjectproxy.h b/src/gdbusobjectproxy.h index 4f98939..7edf836 100644 --- a/src/gdbusobjectproxy.h +++ b/src/gdbusobjectproxy.h @@ -63,28 +63,12 @@ struct _GDBusObjectProxyClass { GObjectClass parent_class; - void (*interface_proxy_added) (GDBusObjectProxy *proxy, - GDBusProxy *interface_proxy); - void (*interface_proxy_removed) (GDBusObjectProxy *proxy, - GDBusProxy *interface_proxy); - /*< private >*/ gpointer padding[8]; }; GType g_dbus_object_proxy_get_type (void) G_GNUC_CONST; -const gchar *g_dbus_object_proxy_get_object_path (GDBusObjectProxy *proxy); GDBusConnection *g_dbus_object_proxy_get_connection (GDBusObjectProxy *proxy); -GDBusProxy *g_dbus_object_proxy_lookup (GDBusObjectProxy *proxy, - const gchar *interface_name); -GList *g_dbus_object_proxy_get_all (GDBusObjectProxy *proxy); - -gpointer g_dbus_object_proxy_peek_with_typecheck (GDBusObjectProxy *proxy, - const gchar *interface_name, - GType type); -gpointer g_dbus_object_proxy_lookup_with_typecheck (GDBusObjectProxy *proxy, - const gchar *interface_name, - GType type); G_END_DECLS diff --git a/src/gdbusobjectstub.c b/src/gdbusobjectstub.c new file mode 100644 index 0000000..1f7c629 --- /dev/null +++ b/src/gdbusobjectstub.c @@ -0,0 +1,403 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#include "config.h" + +#include "gdbusobject.h" +#include "gdbusobjectstub.h" +#include "gdbusinterfacestub.h" + +/** + * SECTION:gdbusobjectstub + * @short_description: Service-side D-Bus object + * @include: gio/gio.h + * + * A #GDBusObjectStub instance is essentially a group of D-Bus + * interfaces. The set of exported interfaces on the object may be + * dynamic and change at runtime. + * + * This type is intended to be used with #GDBusObjectManager. + */ + +struct _GDBusObjectStubPrivate +{ + gchar *object_path; + GHashTable *map_name_to_iface; +}; + +enum +{ + PROP_0, + PROP_OBJECT_PATH +}; + +static void dbus_object_interface_init (GDBusObjectIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GDBusObjectStub, g_dbus_object_stub, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, dbus_object_interface_init)); + + +static void +g_dbus_object_stub_finalize (GObject *_object) +{ + GDBusObjectStub *object = G_DBUS_OBJECT_STUB (_object); + + g_free (object->priv->object_path); + g_hash_table_unref (object->priv->map_name_to_iface); + + if (G_OBJECT_CLASS (g_dbus_object_stub_parent_class)->finalize != NULL) + G_OBJECT_CLASS (g_dbus_object_stub_parent_class)->finalize (_object); +} + +static void +g_dbus_object_stub_get_property (GObject *_object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GDBusObjectStub *object = G_DBUS_OBJECT_STUB (_object); + + switch (prop_id) + { + case PROP_OBJECT_PATH: + g_value_take_string (value, object->priv->object_path); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec); + break; + } +} + +static void +g_dbus_object_stub_set_property (GObject *_object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GDBusObjectStub *object = G_DBUS_OBJECT_STUB (_object); + + switch (prop_id) + { + case PROP_OBJECT_PATH: + g_dbus_object_stub_set_object_path (object, g_value_get_string (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec); + break; + } +} + +static void +g_dbus_object_stub_class_init (GDBusObjectStubClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = g_dbus_object_stub_finalize; + gobject_class->set_property = g_dbus_object_stub_set_property; + gobject_class->get_property = g_dbus_object_stub_get_property; + + /** + * GDBusObjectStub:object-path: + * + * The object path where the object is exported. + */ + g_object_class_install_property (gobject_class, + PROP_OBJECT_PATH, + g_param_spec_string ("object-path", + "Object Path", + "The object path where the object is exported", + NULL, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + g_type_class_add_private (klass, sizeof (GDBusObjectStubPrivate)); +} + +static void +g_dbus_object_stub_init (GDBusObjectStub *object) +{ + object->priv = G_TYPE_INSTANCE_GET_PRIVATE (object, G_TYPE_DBUS_OBJECT_STUB, GDBusObjectStubPrivate); + object->priv->map_name_to_iface = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) g_object_unref); +} + +/** + * g_dbus_object_stub_new: + * @object_path: An object path. + * + * Creates a new #GDBusObjectStub. + * + * Returns: A #GDBusObjectStub. Free with g_object_unref(). + */ +GDBusObjectStub * +g_dbus_object_stub_new (const gchar *object_path) +{ + g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); + return G_DBUS_OBJECT_STUB (g_object_new (G_TYPE_DBUS_OBJECT_STUB, + "object-path", object_path, + NULL)); +} + +/** + * g_dbus_object_stub_set_object_path: + * @object: A #GDBusObjectStub. + * @object_path: A valid D-Bus object path. + * + * Sets the object path for @object. + */ +void +g_dbus_object_stub_set_object_path (GDBusObjectStub *object, + const gchar *object_path) +{ + g_return_if_fail (G_IS_DBUS_OBJECT_STUB (object)); + g_return_if_fail (object_path == NULL || g_variant_is_object_path (object_path)); + /* TODO: fail if object is currently exported */ + if (g_strcmp0 (object->priv->object_path, object_path) != 0) + { + g_free (object->priv->object_path); + object->priv->object_path = g_strdup (object_path); + g_object_notify (G_OBJECT (object), "object-path"); + } +} + +static const gchar * +g_dbus_object_stub_get_object_path (GDBusObject *_object) +{ + GDBusObjectStub *object = G_DBUS_OBJECT_STUB (_object); + return object->priv->object_path; +} + +/** + * g_dbus_object_stub_add_interface: + * @object: A #GDBusObjectStub. + * @interface: A #GDBusInterfaceStub. + * + * Adds @interface to @object. + * + * If @object already contains a #GDBusInterfaceStub with the same + * interface name, it is removed before @interface is added. + * + * Note that @object takes its own reference on @interface and holds + * it until removed. + */ +void +g_dbus_object_stub_add_interface (GDBusObjectStub *object, + GDBusInterfaceStub *interface) +{ + GDBusInterfaceInfo *info; + + g_return_if_fail (G_IS_DBUS_OBJECT_STUB (object)); + g_return_if_fail (G_IS_DBUS_INTERFACE_STUB (interface)); + + info = g_dbus_interface_stub_get_info (interface); + g_object_ref (interface); + g_dbus_object_stub_remove_interface_by_name (object, info->name); + g_hash_table_insert (object->priv->map_name_to_iface, + g_strdup (info->name), + interface); + g_dbus_interface_set_object (G_DBUS_INTERFACE (interface), G_DBUS_OBJECT (object)); + g_signal_emit_by_name (object, + "interface-added", + interface); +} + +/** + * g_dbus_object_stub_remove_interface: + * @object: A #GDBusObjectStub. + * @interface: A #GDBusInterfaceStub. + * + * Removes @interface from @object. + */ +void +g_dbus_object_stub_remove_interface (GDBusObjectStub *object, + GDBusInterfaceStub *interface) +{ + GDBusInterfaceStub *other_interface; + GDBusInterfaceInfo *info; + + g_return_if_fail (G_IS_DBUS_OBJECT_STUB (object)); + g_return_if_fail (G_IS_DBUS_INTERFACE (interface)); + + info = g_dbus_interface_stub_get_info (interface); + + other_interface = g_hash_table_lookup (object->priv->map_name_to_iface, info->name); + if (other_interface == NULL) + { + g_warning ("Tried to remove interface with name %s from object " + "at path %s but no such interface exists", + info->name, + object->priv->object_path); + } + else if (other_interface != interface) + { + g_warning ("Tried to remove interface %p with name %s from object " + "at path %s but the object has the interface %p", + interface, + info->name, + object->priv->object_path, + other_interface); + } + else + { + g_object_ref (interface); + g_warn_if_fail (g_hash_table_remove (object->priv->map_name_to_iface, info->name)); + g_dbus_interface_set_object (G_DBUS_INTERFACE (interface), NULL); + g_signal_emit_by_name (object, + "interface-removed", + interface); + g_object_unref (interface); + } +} + + +/** + * g_dbus_object_stub_remove_interface_by_name: + * @object: A #GDBusObjectStub. + * @interface_name: A D-Bus interface name. + * + * Removes the #GDBusInterface with @interface_name from @object. + * + * If no D-Bus interface of the given interface exists, this function + * does nothing. + */ +void +g_dbus_object_stub_remove_interface_by_name (GDBusObjectStub *object, + const gchar *interface_name) +{ + GDBusInterface *interface; + + g_return_if_fail (G_IS_DBUS_OBJECT_STUB (object)); + g_return_if_fail (g_dbus_is_interface_name (interface_name)); + + interface = g_hash_table_lookup (object->priv->map_name_to_iface, interface_name); + if (interface != NULL) + { + g_object_ref (interface); + g_warn_if_fail (g_hash_table_remove (object->priv->map_name_to_iface, interface_name)); + g_dbus_interface_set_object (interface, NULL); + g_signal_emit_by_name (object, + "interface-removed", + interface); + g_object_unref (interface); + } +} + +static GDBusInterface * +g_dbus_object_stub_get_interface (GDBusObject *_object, + const gchar *interface_name) +{ + GDBusObjectStub *object = G_DBUS_OBJECT_STUB (_object); + GDBusInterface *ret; + + g_return_val_if_fail (G_IS_DBUS_OBJECT_STUB (object), NULL); + g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL); + + ret = g_hash_table_lookup (object->priv->map_name_to_iface, interface_name); + if (ret != NULL) + g_object_ref (ret); + return ret; +} + +static GList * +g_dbus_object_stub_get_interfaces (GDBusObject *_object) +{ + GDBusObjectStub *object = G_DBUS_OBJECT_STUB (_object); + GList *ret; + GHashTableIter iter; + GDBusInterface *interface; + + g_return_val_if_fail (G_IS_DBUS_OBJECT_STUB (object), NULL); + + ret = NULL; + + g_hash_table_iter_init (&iter, object->priv->map_name_to_iface); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &interface)) + ret = g_list_prepend (ret, g_object_ref (interface)); + + return ret; +} + +/** + * g_dbus_object_stub_flush: + * @object: A #GDBusObjectStub. + * + * This method simply calls g_dbus_interface_stub_flush() on all + * interfaces stubs belonging to @object. See that method for when + * flushing is useful. + */ +void +g_dbus_object_stub_flush (GDBusObjectStub *object) +{ + GHashTableIter iter; + GDBusInterfaceStub *interface_stub; + + g_hash_table_iter_init (&iter, object->priv->map_name_to_iface); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &interface_stub)) + { + g_dbus_interface_stub_flush (interface_stub); + } +} + +static gpointer +g_dbus_object_stub_lookup_with_typecheck (GDBusObject *object, + const gchar *interface_name, + GType type) +{ + GDBusObjectStub *stub = G_DBUS_OBJECT_STUB (object); + GDBusProxy *ret; + + ret = g_hash_table_lookup (stub->priv->map_name_to_iface, interface_name); + if (ret != NULL) + { + g_warn_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (ret, type)); + g_object_ref (ret); + } + return ret; +} + +static gpointer +g_dbus_object_stub_peek_with_typecheck (GDBusObject *object, + const gchar *interface_name, + GType type) +{ + GDBusInterfaceStub *ret; + ret = g_dbus_object_stub_lookup_with_typecheck (object, interface_name, type); + if (ret != NULL) + g_object_unref (ret); + return ret; +} + +static void +dbus_object_interface_init (GDBusObjectIface *iface) +{ + iface->get_object_path = g_dbus_object_stub_get_object_path; + iface->get_interfaces = g_dbus_object_stub_get_interfaces; + iface->get_interface = g_dbus_object_stub_get_interface; + iface->lookup_with_typecheck = g_dbus_object_stub_lookup_with_typecheck; + iface->peek_with_typecheck = g_dbus_object_stub_peek_with_typecheck; +} diff --git a/src/gdbusobjectstub.h b/src/gdbusobjectstub.h new file mode 100644 index 0000000..f6fbc9a --- /dev/null +++ b/src/gdbusobjectstub.h @@ -0,0 +1,82 @@ +/* GDBus - GLib D-Bus Library + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#ifndef __G_DBUS_OBJECT_STUB_H__ +#define __G_DBUS_OBJECT_STUB_H__ + +#include <gio/gio.h> +#include <gdbusinterface.h> +#include <gdbusinterfacestub.h> + +G_BEGIN_DECLS + +#define G_TYPE_DBUS_OBJECT_STUB (g_dbus_object_stub_get_type ()) +#define G_DBUS_OBJECT_STUB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_OBJECT_STUB, GDBusObjectStub)) +#define G_DBUS_OBJECT_STUB_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_OBJECT_STUB, GDBusObjectStubClass)) +#define G_DBUS_OBJECT_STUB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_OBJECT_STUB, GDBusObjectStubClass)) +#define G_IS_DBUS_OBJECT_STUB(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_OBJECT_STUB)) +#define G_IS_DBUS_OBJECT_STUB_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_OBJECT_STUB)) + +typedef struct _GDBusObjectStubClass GDBusObjectStubClass; +typedef struct _GDBusObjectStubPrivate GDBusObjectStubPrivate; + +/** + * GDBusObjectStub: + * + * The #GDBusObjectStub structure contains private data and should only be + * accessed using the provided API. + */ +struct _GDBusObjectStub +{ + /*< private >*/ + GObject parent_instance; + GDBusObjectStubPrivate *priv; +}; + +/** + * GDBusObjectStubClass: + * @parent_class: The parent class. + * + * Class structure for #GDBusObjectStub. + */ +struct _GDBusObjectStubClass +{ + GObjectClass parent_class; + /*< private >*/ + gpointer padding[8]; +}; + +GType g_dbus_object_stub_get_type (void) G_GNUC_CONST; +GDBusObjectStub *g_dbus_object_stub_new (const gchar *object_path); +void g_dbus_object_stub_flush (GDBusObjectStub *object); +void g_dbus_object_stub_add_interface (GDBusObjectStub *object, + GDBusInterfaceStub *interface); +void g_dbus_object_stub_remove_interface (GDBusObjectStub *object, + GDBusInterfaceStub *interface); +void g_dbus_object_stub_remove_interface_by_name (GDBusObjectStub *object, + const gchar *interface_name); +void g_dbus_object_stub_set_object_path (GDBusObjectStub *object, + const gchar *object_path); + +G_END_DECLS + +#endif /* __G_DBUS_OBJECT_STUB_H */ diff --git a/src/gdbusproxymanager.c b/src/gdbusproxymanager.c index 2599a0b..e0cd26a 100644 --- a/src/gdbusproxymanager.c +++ b/src/gdbusproxymanager.c @@ -25,6 +25,7 @@ #include "gdbuscodegen-marshal.h" #include "gdbuscodegen-enumtypes.h" #include "gdbusproxymanager.h" +#include "gdbusobject.h" /** * SECTION:gdbusproxymanager @@ -41,7 +42,7 @@ * object, connect to the #GDBusProxyManager::object-proxy-added and * #GDBusProxyManager::object-proxy-removed signals and inspect the * #GDBusObjectProxy objects returned by - * g_dbus_proxy_manager_get_all(). + * g_dbus_proxy_manager_get_objects(). * * If the name for a #GDBusProxyManager is not owned by anyone at * object construction time, the default behavior is to request the @@ -52,7 +53,7 @@ * is not possible to launch an owner for the requested name. In this * case, #GDBusProxyManager object construction still succeeds but * there will be no object proxies - * (e.g. g_dbus_proxy_manager_get_all() returns the empty list) and + * (e.g. g_dbus_proxy_manager_get_objects() returns the empty list) and * the #GDBusProxyManager:name-owner property is %NULL. * * The owner of the requested name can come and go (for example @@ -288,11 +289,16 @@ g_dbus_proxy_manager_set_property (GObject *_object, } } +static void _add_gdbusinterface_iface_to_gdbusproxy (void); + static void g_dbus_proxy_manager_class_init (GDBusProxyManagerClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + /* Hack until this is merged into libgio (extending types at run-time isn't really safe in any way) */ + _add_gdbusinterface_iface_to_gdbusproxy (); + gobject_class->finalize = g_dbus_proxy_manager_finalize; gobject_class->set_property = g_dbus_proxy_manager_set_property; gobject_class->get_property = g_dbus_proxy_manager_get_property; @@ -995,7 +1001,7 @@ signal_cb (GDBusConnection *connection, { GDBusProxyManager *manager = G_DBUS_PROXY_MANAGER (user_data); GDBusObjectProxy *object_proxy; - GDBusProxy *interface_proxy; + GDBusInterface *interface; object_proxy = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path); if (object_proxy == NULL) @@ -1017,8 +1023,8 @@ signal_cb (GDBusConnection *connection, &changed_properties, &invalidated_properties); - interface_proxy = g_dbus_object_proxy_lookup (object_proxy, interface_name); - if (interface_proxy != NULL) + interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object_proxy), interface_name); + if (interface != NULL) { GVariantIter property_iter; const gchar *property_name; @@ -1032,7 +1038,7 @@ signal_cb (GDBusConnection *connection, &property_name, &property_value)) { - g_dbus_proxy_set_cached_property (interface_proxy, + g_dbus_proxy_set_cached_property (G_DBUS_PROXY (interface), property_name, property_value); g_variant_unref (property_value); @@ -1040,7 +1046,7 @@ signal_cb (GDBusConnection *connection, for (n = 0; invalidated_properties[n] != NULL; n++) { - g_dbus_proxy_set_cached_property (interface_proxy, + g_dbus_proxy_set_cached_property (G_DBUS_PROXY (interface), invalidated_properties[n], NULL); } @@ -1049,14 +1055,14 @@ signal_cb (GDBusConnection *connection, signals[INTERFACE_PROXY_PROPERTIES_CHANGED_SIGNAL], 0, object_proxy, - interface_proxy, + interface, changed_properties, invalidated_properties); - g_signal_emit_by_name (interface_proxy, + g_signal_emit_by_name (interface, "g-properties-changed", changed_properties, invalidated_properties); - g_object_unref (interface_proxy); + g_object_unref (interface); } g_variant_unref (changed_properties); g_free (invalidated_properties); @@ -1065,23 +1071,23 @@ signal_cb (GDBusConnection *connection, else { /* regular signal - just dispatch it */ - interface_proxy = g_dbus_object_proxy_lookup (object_proxy, interface_name); - if (interface_proxy != NULL) + interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object_proxy), interface_name); + if (interface != NULL) { g_signal_emit (manager, signals[INTERFACE_PROXY_SIGNAL_SIGNAL], 0, object_proxy, - interface_proxy, + interface, sender_name, signal_name, parameters); - g_signal_emit_by_name (interface_proxy, + g_signal_emit_by_name (interface, "g-signal", sender_name, signal_name, parameters); - g_object_unref (interface_proxy); + g_object_unref (interface); } } @@ -1477,6 +1483,11 @@ add_interfaces (GDBusProxyManager *manager, GVariantIter property_iter; const gchar *property_name; GVariant *property_value; + + /* associate the interface proxy with the object */ + g_dbus_interface_set_object (G_DBUS_INTERFACE (interface_proxy), + G_DBUS_OBJECT (op)); + g_variant_iter_init (&property_iter, properties); while (g_variant_iter_next (&property_iter, "{&sv}", @@ -1533,7 +1544,7 @@ remove_interfaces (GDBusProxyManager *manager, goto out; } - interfaces = g_dbus_object_proxy_get_all (op); + interfaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (op)); num_interfaces = g_list_length (interfaces); g_list_foreach (interfaces, (GFunc) g_object_unref, NULL); g_list_free (interfaces); @@ -1555,17 +1566,17 @@ remove_interfaces (GDBusProxyManager *manager, { for (n = 0; interface_names != NULL && interface_names[n] != NULL; n++) { - GDBusProxy *interface_proxy; - interface_proxy = g_dbus_object_proxy_lookup (op, interface_names[n]); + GDBusInterface *interface; + interface = g_dbus_object_get_interface (G_DBUS_OBJECT (op), interface_names[n]); _g_dbus_object_proxy_remove_interface (op, interface_names[n]); - if (interface_proxy != NULL) + if (interface != NULL) { g_signal_emit (manager, signals[INTERFACE_PROXY_REMOVED_SIGNAL], 0, op, - interface_proxy); - g_object_unref (interface_proxy); + interface); + g_object_unref (interface); } } } @@ -1635,7 +1646,7 @@ on_control_proxy_g_signal (GDBusProxy *proxy, /* ---------------------------------------------------------------------------------------------------- */ /** - * g_dbus_proxy_manager_lookup: + * g_dbus_proxy_manager_get_object: * @manager: A #GDBusProxyManager. * @object_path: Object path to lookup. * @@ -1643,11 +1654,11 @@ on_control_proxy_g_signal (GDBusProxy *proxy, * * Returns: A #GDBusObjectProxy or %NULL. Free with g_object_unref(). */ -GDBusObjectProxy * -g_dbus_proxy_manager_lookup (GDBusProxyManager *manager, - const gchar *object_path) +GDBusObject * +g_dbus_proxy_manager_get_object (GDBusProxyManager *manager, + const gchar *object_path) { - GDBusObjectProxy *ret; + GDBusObject *ret; g_return_val_if_fail (G_IS_DBUS_PROXY_MANAGER (manager), NULL); g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); @@ -1659,7 +1670,7 @@ g_dbus_proxy_manager_lookup (GDBusProxyManager *manager, } /** - * g_dbus_proxy_manager_lookup_interface: + * g_dbus_proxy_manager_get_interface: * @manager: A #GDBusProxyManager. * @object_path: Object path to lookup. * @interface_name: Interface to lookup. @@ -1674,12 +1685,12 @@ g_dbus_proxy_manager_lookup (GDBusProxyManager *manager, * Returns: A #GDBusProxy instance or %NULL. Free with g_object_unref(). */ GDBusProxy * -g_dbus_proxy_manager_lookup_interface (GDBusProxyManager *manager, - const gchar *object_path, - const gchar *interface_name) +g_dbus_proxy_manager_get_interface (GDBusProxyManager *manager, + const gchar *object_path, + const gchar *interface_name) { - GDBusProxy *ret; - GDBusObjectProxy *object_proxy; + GDBusInterface *ret; + GDBusObject *object; g_return_val_if_fail (G_IS_DBUS_PROXY_MANAGER (manager), NULL); g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); @@ -1687,19 +1698,19 @@ g_dbus_proxy_manager_lookup_interface (GDBusProxyManager *manager, ret = NULL; - object_proxy = g_dbus_proxy_manager_lookup (manager, object_path); - if (object_proxy == NULL) + object = g_dbus_proxy_manager_get_object (manager, object_path); + if (object == NULL) goto out; - ret = g_dbus_object_proxy_lookup (object_proxy, interface_name); - g_object_unref (object_proxy); + ret = g_dbus_object_get_interface (object, interface_name); + g_object_unref (object); out: - return ret; + return (GDBusProxy *) ret; } /** - * g_dbus_proxy_manager_get_all: + * g_dbus_proxy_manager_get_objects: * @manager: A #GDBusProxyManager. * * Gets all #GDBusObjectProxy objects known to @manager. @@ -1709,7 +1720,7 @@ g_dbus_proxy_manager_lookup_interface (GDBusProxyManager *manager, * freed with g_object_unref(). */ GList * -g_dbus_proxy_manager_get_all (GDBusProxyManager *manager) +g_dbus_proxy_manager_get_objects (GDBusProxyManager *manager) { GList *ret; @@ -1720,3 +1731,45 @@ g_dbus_proxy_manager_get_all (GDBusProxyManager *manager) return ret; } +/* ---------------------------------------------------------------------------------------------------- */ +/* Hack until this is merged into libgio (extending types at run-time isn't really safe in any way) */ + +static GDBusInterfaceInfo * +_g_dbus_proxy_get_info (GDBusInterface *interface) +{ + GDBusProxy *proxy = G_DBUS_PROXY (interface); + return g_dbus_proxy_get_interface_info (proxy); +} + +static GDBusObject * +_g_dbus_proxy_get_object (GDBusInterface *interface) +{ + return g_object_get_data (G_OBJECT (interface), "-x-gdbus-binding-tool-object"); +} + +static void +_g_dbus_proxy_set_object (GDBusInterface *interface, + GDBusObject *object) +{ + g_object_set_data (G_OBJECT (interface), "-x-gdbus-binding-tool-object", object); +} + +static void +gdbusproxy_gdbusinterface_iface_init (GDBusInterfaceIface *iface) +{ + iface->get_info = _g_dbus_proxy_get_info; + iface->get_object = _g_dbus_proxy_get_object; + iface->set_object = _g_dbus_proxy_set_object; +} + +static void +_add_gdbusinterface_iface_to_gdbusproxy (void) +{ + static GInterfaceInfo info = {0}; + info.interface_init = (GInterfaceInitFunc) gdbusproxy_gdbusinterface_iface_init; + g_type_add_interface_static (G_TYPE_DBUS_PROXY, + G_TYPE_DBUS_INTERFACE, + &info); +} + +/* ---------------------------------------------------------------------------------------------------- */ diff --git a/src/gdbusproxymanager.h b/src/gdbusproxymanager.h index b43849b..256d0f8 100644 --- a/src/gdbusproxymanager.h +++ b/src/gdbusproxymanager.h @@ -24,6 +24,7 @@ #define __G_DBUS_PROXY_MANAGER_H__ #include <gio/gio.h> +#include <gdbusobject.h> #include <gdbusobjectproxy.h> G_BEGIN_DECLS @@ -70,12 +71,12 @@ struct _GDBusProxyManagerClass /* signals */ void (*object_proxy_added) (GDBusProxyManager *manager, - GDBusObjectProxy *object_proxy); + GDBusObjectProxy *proxy); void (*object_proxy_removed) (GDBusProxyManager *manager, - GDBusObjectProxy *object_proxy); + GDBusObjectProxy *proxy); void (*interface_proxy_added) (GDBusProxyManager *manager, - GDBusObjectProxy *object_proxy, + GDBusObjectProxy *proxy, GDBusProxy *interface_proxy); void (*interface_proxy_removed) (GDBusProxyManager *manager, GDBusObjectProxy *object_proxy, @@ -180,10 +181,10 @@ GDBusProxyManagerFlags g_dbus_proxy_manager_get_flags (GDBusProxyManage const gchar *g_dbus_proxy_manager_get_name (GDBusProxyManager *manager); gchar *g_dbus_proxy_manager_get_name_owner (GDBusProxyManager *manager); const gchar *g_dbus_proxy_manager_get_object_path (GDBusProxyManager *manager); -GList *g_dbus_proxy_manager_get_all (GDBusProxyManager *manager); -GDBusObjectProxy *g_dbus_proxy_manager_lookup (GDBusProxyManager *manager, +GList *g_dbus_proxy_manager_get_objects (GDBusProxyManager *manager); +GDBusObject *g_dbus_proxy_manager_get_object (GDBusProxyManager *manager, const gchar *object_path); -GDBusProxy *g_dbus_proxy_manager_lookup_interface (GDBusProxyManager *manager, +GDBusProxy *g_dbus_proxy_manager_get_interface (GDBusProxyManager *manager, const gchar *object_path, const gchar *interface_name); /* TODO : @@ -26,6 +26,7 @@ #include <gdbusobjectmanager.h> #include <gdbusproxymanager.h> +#include <gdbusobjectstub.h> #include "test-generated.h" @@ -207,7 +208,7 @@ on_handle_request_multi_property_mods (FooBar *object, foo_bar_set_i (object, foo_bar_get_i (object) + 1); foo_bar_set_y (object, foo_bar_get_y (object) + 1); foo_bar_set_i (object, foo_bar_get_i (object) + 1); - g_dbus_interface_flush (G_DBUS_INTERFACE (object)); + g_dbus_interface_stub_flush (G_DBUS_INTERFACE_STUB (object)); foo_bar_set_y (object, foo_bar_get_y (object) + 1); foo_bar_set_i (object, foo_bar_get_i (object) + 1); foo_bar_complete_request_multi_property_mods (object, invocation); @@ -306,10 +307,10 @@ on_bus_acquired (GDBusConnection *connection, foo_bar_set_readonly_property (exported_bar_object, "blah"); g_assert_cmpstr (foo_bar_get_writeonly_property (exported_bar_object), ==, "Mr. Burns"); - g_dbus_interface_register_object (G_DBUS_INTERFACE (exported_bar_object), - connection, - "/bar", - &error); + g_dbus_interface_stub_export (G_DBUS_INTERFACE_STUB (exported_bar_object), + connection, + "/bar", + &error); g_assert_no_error (error); g_signal_connect (exported_bar_object, "handle-hello-world", @@ -333,10 +334,10 @@ on_bus_acquired (GDBusConnection *connection, NULL); exported_bat_object = foo_bat_stub_new (); - g_dbus_interface_register_object (G_DBUS_INTERFACE (exported_bat_object), - connection, - "/bat", - &error); + g_dbus_interface_stub_export (G_DBUS_INTERFACE_STUB (exported_bat_object), + connection, + "/bat", + &error); g_assert_no_error (error); g_signal_connect (exported_bat_object, "handle-force-method", @@ -1075,8 +1076,8 @@ typedef struct guint num_object_proxy_added_signals; guint num_object_proxy_removed_signals; - guint num_interface_proxy_added_signals; - guint num_interface_proxy_removed_signals; + guint num_interface_added_signals; + guint num_interface_removed_signals; } OMData; static gint @@ -1319,21 +1320,21 @@ get_proxy_type (GDBusProxyManager *manager, } static void -on_interface_proxy_added (GDBusObjectProxy *object_proxy, - GDBusProxy *interface_proxy, - gpointer user_data) +on_interface_added (GDBusObject *object, + GDBusInterface *interface, + gpointer user_data) { OMData *om_data = user_data; - om_data->num_interface_proxy_added_signals += 1; + om_data->num_interface_added_signals += 1; } static void -on_interface_proxy_removed (GDBusObjectProxy *object_proxy, - GDBusProxy *interface_proxy, - gpointer user_data) +on_interface_removed (GDBusObject *object, + GDBusInterface *interface, + gpointer user_data) { OMData *om_data = user_data; - om_data->num_interface_proxy_removed_signals += 1; + om_data->num_interface_removed_signals += 1; } static void @@ -1344,12 +1345,12 @@ on_object_proxy_added (GDBusProxyManager *manager, OMData *om_data = user_data; om_data->num_object_proxy_added_signals += 1; g_signal_connect (object_proxy, - "interface-proxy-added", - G_CALLBACK (on_interface_proxy_added), + "interface-added", + G_CALLBACK (on_interface_added), om_data); g_signal_connect (object_proxy, - "interface-proxy-removed", - G_CALLBACK (on_interface_proxy_removed), + "interface-removed", + G_CALLBACK (on_interface_removed), om_data); } @@ -1361,10 +1362,10 @@ on_object_proxy_removed (GDBusProxyManager *manager, OMData *om_data = user_data; om_data->num_object_proxy_removed_signals += 1; g_assert_cmpint (g_signal_handlers_disconnect_by_func (object_proxy, - G_CALLBACK (on_interface_proxy_added), + G_CALLBACK (on_interface_added), om_data), ==, 1); g_assert_cmpint (g_signal_handlers_disconnect_by_func (object_proxy, - G_CALLBACK (on_interface_proxy_removed), + G_CALLBACK (on_interface_removed), om_data), ==, 1); } @@ -1389,9 +1390,10 @@ om_check_property_and_signal_emission (GMainLoop *loop, static void check_object_manager (void) { - GDBusObject *o; - GDBusObject *o2; - GDBusInterface *i; + GDBusObjectStub *o; + GDBusObjectStub *o2; + GDBusInterfaceStub *i; + GDBusInterfaceStub *i2; GDBusConnection *c; GDBusObjectManager *manager; GDBusNodeInfo *info; @@ -1402,12 +1404,13 @@ check_object_manager (void) GDBusProxyManager *pm; GList *object_proxies; GList *proxies; - GDBusObjectProxy *op; + GDBusObject *op; GDBusProxy *p; FooBar *bar_stub; FooBar *bar_p; FooBar *bar_p2; FooComAcmeCoyote *coyote_p; + guint old_ref_count; loop = g_main_loop_new (NULL, FALSE); @@ -1491,29 +1494,27 @@ check_object_manager (void) G_CALLBACK (on_object_proxy_removed), om_data); /* ... check there are no object proxies yet */ - object_proxies = g_dbus_proxy_manager_get_all (pm); + object_proxies = g_dbus_proxy_manager_get_objects (pm); g_assert (object_proxies == NULL); /* First, export an object with a single interface (also check that - * g_dbus_interface_get_object() works) + * g_dbus_interface_get_object() works and that the object isn't reffed) */ - o = g_dbus_object_new ("/managed/first"); - i = G_DBUS_INTERFACE (foo_bar_stub_new ()); - g_assert (g_dbus_interface_get_object (i) == NULL); + o = g_dbus_object_stub_new ("/managed/first"); + i = G_DBUS_INTERFACE_STUB (foo_bar_stub_new ()); + g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (i)) == NULL); g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1); - g_dbus_object_add_interface (o, i); + g_dbus_object_stub_add_interface (o, i); g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1); - g_assert (g_dbus_interface_get_object (i) == o); - g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 2); - g_object_unref (o); + g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (i)) == G_DBUS_OBJECT (o)); g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1); - g_dbus_object_remove_interface (o, i); - g_assert (g_dbus_interface_get_object (i) == NULL); g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1); - g_dbus_object_add_interface (o, i); - g_assert (g_dbus_interface_get_object (i) == o); - g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 2); - g_object_unref (o); + g_dbus_object_stub_remove_interface (o, i); + g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (i)) == NULL); + g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1); + g_dbus_object_stub_add_interface (o, i); + g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (i)) == G_DBUS_OBJECT (o)); + g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1); g_dbus_object_manager_export (manager, o); /* ... check we get the InterfacesAdded signal */ @@ -1522,8 +1523,8 @@ check_object_manager (void) g_assert_cmpint (om_data->state, ==, 2); g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 1); g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 0); - g_assert_cmpint (om_data->num_interface_proxy_added_signals, ==, 0); - g_assert_cmpint (om_data->num_interface_proxy_removed_signals, ==, 0); + g_assert_cmpint (om_data->num_interface_added_signals, ==, 0); + g_assert_cmpint (om_data->num_interface_removed_signals, ==, 0); /* ... check there's one non-standard interfaces */ info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop); g_assert_cmpint (count_interfaces (info), ==, 4); /* Bar + Properties,Introspectable,Peer */ @@ -1531,7 +1532,7 @@ check_object_manager (void) g_dbus_node_info_unref (info); /* Now, check adding the same interface replaces the existing one */ - g_dbus_object_add_interface (o, i); + g_dbus_object_stub_add_interface (o, i); /* ... check we get the InterfacesRemoved */ om_data->state = 3; g_main_loop_run (om_data->loop); @@ -1539,8 +1540,8 @@ check_object_manager (void) g_assert_cmpint (om_data->state, ==, 6); g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 2); g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 1); - g_assert_cmpint (om_data->num_interface_proxy_added_signals, ==, 0); - g_assert_cmpint (om_data->num_interface_proxy_removed_signals, ==, 0); + g_assert_cmpint (om_data->num_interface_added_signals, ==, 0); + g_assert_cmpint (om_data->num_interface_removed_signals, ==, 0); /* ... check introspection data */ info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop); g_assert_cmpint (count_interfaces (info), ==, 4); /* Bar + Properties,Introspectable,Peer */ @@ -1549,16 +1550,16 @@ check_object_manager (void) g_object_unref (i); /* check adding an interface of same type (but not same object) replaces the existing one */ - i = G_DBUS_INTERFACE (foo_bar_stub_new ()); - g_dbus_object_add_interface (o, i); + i = G_DBUS_INTERFACE_STUB (foo_bar_stub_new ()); + g_dbus_object_stub_add_interface (o, i); /* ... check we get the InterfacesRemoved and then InterfacesAdded */ om_data->state = 7; g_main_loop_run (om_data->loop); g_assert_cmpint (om_data->state, ==, 10); g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 3); g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 2); - g_assert_cmpint (om_data->num_interface_proxy_added_signals, ==, 0); - g_assert_cmpint (om_data->num_interface_proxy_removed_signals, ==, 0); + g_assert_cmpint (om_data->num_interface_added_signals, ==, 0); + g_assert_cmpint (om_data->num_interface_removed_signals, ==, 0); /* ... check introspection data */ info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop); g_assert_cmpint (count_interfaces (info), ==, 4); /* Bar + Properties,Introspectable,Peer */ @@ -1567,8 +1568,8 @@ check_object_manager (void) g_object_unref (i); /* check adding an interface of another type doesn't replace the existing one */ - i = G_DBUS_INTERFACE (foo_bat_stub_new ()); - g_dbus_object_add_interface (o, i); + i = G_DBUS_INTERFACE_STUB (foo_bat_stub_new ()); + g_dbus_object_stub_add_interface (o, i); g_object_unref (i); /* ... check we get the InterfacesAdded */ om_data->state = 11; @@ -1576,8 +1577,8 @@ check_object_manager (void) g_assert_cmpint (om_data->state, ==, 12); g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 3); g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 2); - g_assert_cmpint (om_data->num_interface_proxy_added_signals, ==, 1); - g_assert_cmpint (om_data->num_interface_proxy_removed_signals, ==, 0); + g_assert_cmpint (om_data->num_interface_added_signals, ==, 1); + g_assert_cmpint (om_data->num_interface_removed_signals, ==, 0); /* ... check introspection data */ info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop); g_assert_cmpint (count_interfaces (info), ==, 5); /* Bar,Bat + Properties,Introspectable,Peer */ @@ -1586,15 +1587,15 @@ check_object_manager (void) g_dbus_node_info_unref (info); /* check we can remove an interface */ - g_dbus_object_remove_interface_by_name (o, "org.project.Bar"); + g_dbus_object_stub_remove_interface_by_name (o, "org.project.Bar"); /* ... check we get the InterfacesRemoved */ om_data->state = 13; g_main_loop_run (om_data->loop); g_assert_cmpint (om_data->state, ==, 14); g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 3); g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 2); - g_assert_cmpint (om_data->num_interface_proxy_added_signals, ==, 1); - g_assert_cmpint (om_data->num_interface_proxy_removed_signals, ==, 1); + g_assert_cmpint (om_data->num_interface_added_signals, ==, 1); + g_assert_cmpint (om_data->num_interface_removed_signals, ==, 1); /* ... check introspection data */ info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop); g_assert_cmpint (count_interfaces (info), ==, 4); /* Bat + Properties,Introspectable,Peer */ @@ -1605,7 +1606,7 @@ check_object_manager (void) * (Note: if a signal was emitted we'd assert in the signal handler * because we're in state 14) */ - g_dbus_object_remove_interface_by_name (o, "org.project.Bar"); + g_dbus_object_stub_remove_interface_by_name (o, "org.project.Bar"); /* ... check introspection data */ info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop); g_assert_cmpint (count_interfaces (info), ==, 4); /* Bat + Properties,Introspectable,Peer */ @@ -1613,23 +1614,23 @@ check_object_manager (void) g_dbus_node_info_unref (info); /* remove the last interface */ - g_dbus_object_remove_interface_by_name (o, "org.project.Bat"); + g_dbus_object_stub_remove_interface_by_name (o, "org.project.Bat"); /* ... check we get the InterfacesRemoved */ om_data->state = 15; g_main_loop_run (om_data->loop); g_assert_cmpint (om_data->state, ==, 16); g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 3); g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 3); - g_assert_cmpint (om_data->num_interface_proxy_added_signals, ==, 1); - g_assert_cmpint (om_data->num_interface_proxy_removed_signals, ==, 1); + g_assert_cmpint (om_data->num_interface_added_signals, ==, 1); + g_assert_cmpint (om_data->num_interface_removed_signals, ==, 1); /* ... check introspection data */ info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop); g_assert_cmpint (count_interfaces (info), ==, 0); /* nothing */ g_dbus_node_info_unref (info); /* and add an interface again */ - i = G_DBUS_INTERFACE (foo_com_acme_coyote_stub_new ()); - g_dbus_object_add_interface (o, i); + i = G_DBUS_INTERFACE_STUB (foo_com_acme_coyote_stub_new ()); + g_dbus_object_stub_add_interface (o, i); g_object_unref (i); /* ... check we get the InterfacesAdded */ om_data->state = 17; @@ -1637,8 +1638,8 @@ check_object_manager (void) g_assert_cmpint (om_data->state, ==, 18); g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 4); g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 3); - g_assert_cmpint (om_data->num_interface_proxy_added_signals, ==, 1); - g_assert_cmpint (om_data->num_interface_proxy_removed_signals, ==, 1); + g_assert_cmpint (om_data->num_interface_added_signals, ==, 1); + g_assert_cmpint (om_data->num_interface_removed_signals, ==, 1); /* ... check introspection data */ info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop); g_assert_cmpint (count_interfaces (info), ==, 4); /* com.acme.Coyote + Properties,Introspectable,Peer */ @@ -1652,13 +1653,13 @@ check_object_manager (void) /* -------------------------------------------------- */ /* create a new object with two interfaces */ - o2 = g_dbus_object_new ("/managed/second"); - i = G_DBUS_INTERFACE (foo_bar_stub_new ()); + o2 = g_dbus_object_stub_new ("/managed/second"); + i = G_DBUS_INTERFACE_STUB (foo_bar_stub_new ()); bar_stub = FOO_BAR (i); /* save for later test */ - g_dbus_object_add_interface (o2, i); + g_dbus_object_stub_add_interface (o2, i); g_object_unref (i); - i = G_DBUS_INTERFACE (foo_bat_stub_new ()); - g_dbus_object_add_interface (o2, i); + i = G_DBUS_INTERFACE_STUB (foo_bat_stub_new ()); + g_dbus_object_stub_add_interface (o2, i); g_object_unref (i); /* ... add it */ g_dbus_object_manager_export (manager, o2); @@ -1668,8 +1669,8 @@ check_object_manager (void) g_assert_cmpint (om_data->state, ==, 102); g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 5); g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 3); - g_assert_cmpint (om_data->num_interface_proxy_added_signals, ==, 1); - g_assert_cmpint (om_data->num_interface_proxy_removed_signals, ==, 1); + g_assert_cmpint (om_data->num_interface_added_signals, ==, 1); + g_assert_cmpint (om_data->num_interface_removed_signals, ==, 1); /* -------------------------------------------------- */ @@ -1679,43 +1680,61 @@ check_object_manager (void) om_check_get_all (c, loop, "({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}, '/managed/second': {'org.project.Bar': {'y': <byte 0x00>, 'b': <false>, 'n': <int16 0>, 'q': <uint16 0>, 'i': <0>, 'u': <uint32 0>, 'x': <int64 0>, 't': <uint64 0>, 'd': <0.0>, 's': <''>, 'o': <objectpath '/'>, 'g': <signature ''>, 'ay': <b''>, 'as': <@as []>, 'aay': <@aay []>, 'ao': <@ao []>, 'ag': <@ag []>, 'FinallyNormalName': <''>, 'ReadonlyProperty': <''>, 'unset_i': <0>, 'unset_d': <0.0>, 'unset_s': <''>, 'unset_o': <objectpath '/'>, 'unset_g': <signature ''>, 'unset_ay': <b''>, 'unset_as': <@as []>, 'unset_ao': <@ao []>, 'unset_ag': <@ag []>, 'unset_struct': <(0, 0.0, '', objectpath '/', signature '', @ay [], @as [], @ao [], @ag [])>}, 'org.project.Bat': {'force_i': <0>, 'force_s': <''>, 'force_ay': <@ay []>, 'force_struct': <(0,)>}}},)"); + /* check that the _GET_ and _PEEK_ macros work on the server side */ + i = FOO_PEEK_BAR (o); + g_assert (i == NULL); + i = FOO_PEEK_COM_ACME_COYOTE (o); + g_assert (i != NULL); + g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (i), G_TYPE_DBUS_INTERFACE_STUB)); + g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (i), FOO_TYPE_COM_ACME_COYOTE)); + g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (i), FOO_TYPE_COM_ACME_COYOTE_STUB)); + /* ... and that PEEK doesn't increase the ref_count but GET does */ + g_assert_cmpint (G_OBJECT (i)->ref_count, ==, 2); + i2 = FOO_PEEK_COM_ACME_COYOTE (o); + g_assert (i == i2); + g_assert_cmpint (G_OBJECT (i)->ref_count, ==, 2); + i2 = FOO_GET_COM_ACME_COYOTE (o); + g_assert (i == i2); + g_assert_cmpint (G_OBJECT (i)->ref_count, ==, 3); + g_object_unref (i); + /* Also check that the ProxyManager returns these objects - and * that they are of the right GType cf. what we requested via * our ::get-proxy-type signal handler */ - object_proxies = g_dbus_proxy_manager_get_all (pm); + object_proxies = g_dbus_proxy_manager_get_objects (pm); g_assert (g_list_length (object_proxies) == 2); g_list_foreach (object_proxies, (GFunc) g_object_unref, NULL); g_list_free (object_proxies); - op = g_dbus_proxy_manager_lookup (pm, "/managed/first"); + op = g_dbus_proxy_manager_get_object (pm, "/managed/first"); g_assert (op != NULL); - g_assert_cmpstr (g_dbus_object_proxy_get_object_path (op), ==, "/managed/first"); - proxies = g_dbus_object_proxy_get_all (op); + g_assert_cmpstr (g_dbus_object_get_object_path (op), ==, "/managed/first"); + proxies = g_dbus_object_get_interfaces (op); g_assert (g_list_length (proxies) == 1); g_list_foreach (proxies, (GFunc) g_object_unref, NULL); g_list_free (proxies); - p = g_dbus_object_proxy_lookup (op, "com.acme.Coyote"); + p = G_DBUS_PROXY (g_dbus_object_get_interface (op, "com.acme.Coyote")); g_assert (p != NULL); g_assert_cmpint (G_TYPE_FROM_INSTANCE (p), ==, G_TYPE_DBUS_PROXY); g_assert (!g_type_is_a (G_TYPE_FROM_INSTANCE (p), FOO_TYPE_COM_ACME_COYOTE)); g_object_unref (p); - p = g_dbus_object_proxy_lookup (op, "org.project.NonExisting"); + p = (GDBusProxy *) g_dbus_object_get_interface (op, "org.project.NonExisting"); g_assert (p == NULL); g_object_unref (op); /* -- */ - op = g_dbus_proxy_manager_lookup (pm, "/managed/second"); + op = g_dbus_proxy_manager_get_object (pm, "/managed/second"); g_assert (op != NULL); - g_assert_cmpstr (g_dbus_object_proxy_get_object_path (op), ==, "/managed/second"); - proxies = g_dbus_object_proxy_get_all (op); + g_assert_cmpstr (g_dbus_object_get_object_path (op), ==, "/managed/second"); + proxies = g_dbus_object_get_interfaces (op); g_assert (g_list_length (proxies) == 2); g_list_foreach (proxies, (GFunc) g_object_unref, NULL); g_list_free (proxies); - p = g_dbus_object_proxy_lookup (op, "org.project.Bat"); + p = G_DBUS_PROXY (g_dbus_object_get_interface (op, "org.project.Bat")); g_assert (p != NULL); g_assert_cmpint (G_TYPE_FROM_INSTANCE (p), ==, FOO_TYPE_BAT_PROXY); g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (p), FOO_TYPE_BAT)); g_object_unref (p); - p = g_dbus_object_proxy_lookup (op, "org.project.Bar"); + p = G_DBUS_PROXY (g_dbus_object_get_interface (op, "org.project.Bar")); g_assert (p != NULL); g_assert_cmpint (G_TYPE_FROM_INSTANCE (p), ==, FOO_TYPE_BAR_PROXY); g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (p), FOO_TYPE_BAR)); @@ -1724,22 +1743,25 @@ check_object_manager (void) */ om_check_property_and_signal_emission (loop, bar_stub, FOO_BAR (p)); g_object_unref (p); - p = g_dbus_object_proxy_lookup (op, "org.project.NonExisting"); + p = (GDBusProxy *) g_dbus_object_get_interface (op, "org.project.NonExisting"); g_assert (p == NULL); g_object_unref (op); /* -------------------------------------------------- */ - /* check that the _GET_ and _PEEK_ macros work */ - op = g_dbus_proxy_manager_lookup (pm, "/managed/second"); + /* check that the _GET_ and _PEEK_ macros work on the proxy side */ + op = g_dbus_proxy_manager_get_object (pm, "/managed/second"); bar_p = FOO_GET_BAR (op); + old_ref_count = G_OBJECT (op)->ref_count; + g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (bar_p)) == op); + g_assert_cmpint (old_ref_count, ==, G_OBJECT (op)->ref_count); g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (bar_p), FOO_TYPE_BAR)); g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (bar_p), G_TYPE_DBUS_PROXY)); - g_assert_cmpint (G_OBJECT(bar_p)->ref_count, ==, 2); + g_assert_cmpint (G_OBJECT (bar_p)->ref_count, ==, 2); g_object_unref (bar_p); bar_p2 = FOO_PEEK_BAR (op); g_assert (bar_p2 == bar_p); - g_assert_cmpint (G_OBJECT(bar_p)->ref_count, ==, 1); + g_assert_cmpint (G_OBJECT (bar_p)->ref_count, ==, 1); coyote_p = FOO_GET_COM_ACME_COYOTE (op); g_assert (coyote_p == NULL); coyote_p = FOO_PEEK_COM_ACME_COYOTE (op); @@ -1749,7 +1771,7 @@ check_object_manager (void) /* Also, check that we warn on stderr in case the get_proxy_type() function is * wrong etc. */ - op = g_dbus_proxy_manager_lookup (pm, "/managed/first"); + op = g_dbus_proxy_manager_get_object (pm, "/managed/first"); bar_p = FOO_GET_BAR (op); g_assert (bar_p == NULL); if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR)) @@ -1769,8 +1791,8 @@ check_object_manager (void) g_assert_cmpint (om_data->state, ==, 104); g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 5); g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 4); - g_assert_cmpint (om_data->num_interface_proxy_added_signals, ==, 1); - g_assert_cmpint (om_data->num_interface_proxy_removed_signals, ==, 1); + g_assert_cmpint (om_data->num_interface_added_signals, ==, 1); + g_assert_cmpint (om_data->num_interface_removed_signals, ==, 1); /* ... check introspection data (there should be nothing) */ info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/second", loop); g_assert_cmpint (count_nodes (info), ==, 0); @@ -1820,6 +1842,7 @@ check_name_forcing (void) g_assert (foo_rocket123_get_speed_xyz != NULL); } +/* ---------------------------------------------------------------------------------------------------- */ gint main (gint argc, gchar *argv[]) |