diff options
author | David Zeuthen <davidz@redhat.com> | 2011-04-25 09:29:18 -0400 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2011-04-25 09:29:18 -0400 |
commit | bbe945183be11dafc037fdf5f92cea49202b6401 (patch) | |
tree | 14295987d2dd59ca9b4cf0fa7aa3448a518611f8 | |
parent | 58eb4da5c52f0847846368b5df4583080459a798 (diff) | |
download | glib-bbe945183be11dafc037fdf5f92cea49202b6401.tar.gz glib-bbe945183be11dafc037fdf5f92cea49202b6401.tar.bz2 glib-bbe945183be11dafc037fdf5f92cea49202b6401.zip |
gdbus-codegen: Generate GDBusObject{,Proxy,Skeleton} subtypes
Signed-off-by: David Zeuthen <davidz@redhat.com>
-rw-r--r-- | docs/reference/gio/gdbus-codegen.xml | 6 | ||||
-rw-r--r-- | docs/reference/gio/gio-sections.txt | 42 | ||||
-rw-r--r-- | docs/reference/gio/gio.types | 3 | ||||
-rw-r--r-- | docs/reference/gio/migrating-gdbus.xml | 5 | ||||
-rw-r--r-- | gio/gdbus-codegen/codegen.py | 582 | ||||
-rw-r--r-- | gio/gdbus-codegen/dbustypes.py | 2 | ||||
-rw-r--r-- | gio/gdbusobject.c | 57 | ||||
-rw-r--r-- | gio/gdbusobject.h | 17 | ||||
-rw-r--r-- | gio/gdbusobjectmanagerclient.c | 18 | ||||
-rw-r--r-- | gio/gdbusobjectproxy.c | 75 | ||||
-rw-r--r-- | gio/gdbusobjectproxy.h | 6 | ||||
-rw-r--r-- | gio/gdbusobjectskeleton.c | 31 | ||||
-rw-r--r-- | gio/gdbusprivate.h | 2 | ||||
-rw-r--r-- | gio/gio.symbols | 3 | ||||
-rw-r--r-- | gio/giotypes.h | 8 | ||||
-rw-r--r-- | gio/tests/gdbus-example-objectmanager-client.c | 6 | ||||
-rw-r--r-- | gio/tests/gdbus-example-objectmanager-server.c | 10 | ||||
-rw-r--r-- | gio/tests/gdbus-test-codegen.c | 165 | ||||
-rw-r--r-- | gio/tests/test-codegen.xml | 6 |
19 files changed, 685 insertions, 359 deletions
diff --git a/docs/reference/gio/gdbus-codegen.xml b/docs/reference/gio/gdbus-codegen.xml index 6eca71810..5f229d4ba 100644 --- a/docs/reference/gio/gdbus-codegen.xml +++ b/docs/reference/gio/gdbus-codegen.xml @@ -134,9 +134,9 @@ <term><option>--c-generate-object-manager</option></term> <listitem> <para> - If this option is passed a #GDBusObjectManagerClient - subclass with an appropriate #GDBusProxyTypeFunc is - generated. + If this option is passed, suitable #GDBusObject, + #GDBusObjectProxy, #GDBusObjectSkeleton and + #GDBusObjectManagerClient subclasses are generated. </para> </listitem> </varlistentry> diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt index 0d733a15b..690b45ac4 100644 --- a/docs/reference/gio/gio-sections.txt +++ b/docs/reference/gio/gio-sections.txt @@ -3195,6 +3195,7 @@ G_DBUS_OBJECT_GET_IFACE <TITLE>GDBusObjectProxy</TITLE> GDBusObjectProxy GDBusObjectProxyClass +g_dbus_object_proxy_new g_dbus_object_proxy_get_connection <SUBSECTION Standard> G_DBUS_OBJECT_PROXY @@ -3396,6 +3397,47 @@ EXAMPLE_IS_CAT_SKELETON_CLASS </SECTION> <SECTION> +<FILE>ExampleObject</FILE> +<TITLE>ExampleObject</TITLE> +ExampleObject +ExampleObjectIface +example_object_get_animal +example_object_get_cat +example_object_peek_animal +example_object_peek_cat +ExampleObjectProxy +ExampleObjectProxyClass +example_object_proxy_new +ExampleObjectSkeleton +ExampleObjectSkeletonClass +example_object_skeleton_new +example_object_skeleton_set_animal +example_object_skeleton_set_cat +<SUBSECTION Standard> +example_object_get_type +example_object_proxy_get_type +example_object_skeleton_get_type +ExampleObjectProxyPrivate +ExampleObjectSkeletonPrivate +EXAMPLE_IS_OBJECT +EXAMPLE_IS_OBJECT_PROXY +EXAMPLE_IS_OBJECT_PROXY_CLASS +EXAMPLE_IS_OBJECT_SKELETON +EXAMPLE_IS_OBJECT_SKELETON_CLASS +EXAMPLE_OBJECT +EXAMPLE_OBJECT_GET_IFACE +EXAMPLE_OBJECT_PROXY +EXAMPLE_OBJECT_PROXY_CLASS +EXAMPLE_OBJECT_PROXY_GET_CLASS +EXAMPLE_OBJECT_SKELETON +EXAMPLE_OBJECT_SKELETON_CLASS +EXAMPLE_OBJECT_SKELETON_GET_CLASS +EXAMPLE_TYPE_OBJECT +EXAMPLE_TYPE_OBJECT_PROXY +EXAMPLE_TYPE_OBJECT_SKELETON +</SECTION> + +<SECTION> <FILE>ExampleObjectManagerClient</FILE> <TITLE>ExampleObjectManagerClient</TITLE> ExampleObjectManagerClient diff --git a/docs/reference/gio/gio.types b/docs/reference/gio/gio.types index b40f68353..4938012f4 100644 --- a/docs/reference/gio/gio.types +++ b/docs/reference/gio/gio.types @@ -1,3 +1,6 @@ +example_object_get_type +example_object_proxy_get_type +example_object_skeleton_get_type example_animal_get_type example_animal_proxy_get_type example_animal_skeleton_get_type diff --git a/docs/reference/gio/migrating-gdbus.xml b/docs/reference/gio/migrating-gdbus.xml index 5d82eaaed..8977b746a 100644 --- a/docs/reference/gio/migrating-gdbus.xml +++ b/docs/reference/gio/migrating-gdbus.xml @@ -280,8 +280,8 @@ gdbus-codegen --interface-prefix org.gtk.GDBus.Example.ObjectManager. \ and <xref linkend="gdbus-example-codegen-client"/>. Additionally, since the generated code has 100% gtk-doc coverage, see - #ExampleAnimal, #ExampleCat and #ExampleObjectManagerClient - pages for documentation + #ExampleAnimal, #ExampleCat, #ExampleObject and + #ExampleObjectManagerClient pages for documentation. </para> <example id="gdbus-example-codegen-server"><title>Server-side application using generated code</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gdbus-example-objectmanager-server.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example> @@ -294,6 +294,7 @@ gdbus-codegen --interface-prefix org.gtk.GDBus.Example.ObjectManager. \ <xi:include href="../../../../gio/gdbus-example-objectmanager-generated-org.gtk.GDBus.Example.ObjectManager.Cat.xml"/> <xi:include href="ExampleAnimal.xml"/> <xi:include href="ExampleCat.xml"/> + <xi:include href="ExampleObject.xml"/> <xi:include href="ExampleObjectManagerClient.xml"/> </chapter> diff --git a/gio/gdbus-codegen/codegen.py b/gio/gdbus-codegen/codegen.py index 8ae519f0c..d60c6325d 100644 --- a/gio/gdbus-codegen/codegen.py +++ b/gio/gdbus-codegen/codegen.py @@ -95,6 +95,13 @@ class CodeGenerator: self.c.write('typedef struct\n' '{\n' + ' GDBusInterfaceInfo parent_struct;\n' + ' const gchar *hyphen_name;\n' + '} _ExtendedGDBusInterfaceInfo;\n' + '\n') + + self.c.write('typedef struct\n' + '{\n' ' const _ExtendedGDBusPropertyInfo *info;\n' ' guint prop_id;\n' ' GValue orig_value; /* the value before the change */\n' @@ -455,41 +462,6 @@ class CodeGenerator: %(i.camel_name, i.name_lower)) self.h.write('\n') - # Interface proxy accessors - self.h.write(self.docbook_gen.expand( - '/**\n' - ' * %sGET_%s:\n' - ' * @object: A #GDBusObject.\n' - ' *\n' - ' * Gets the #%s instance corresponding to the D-Bus interface #%s, if any.\n' - ' *\n' - ' * This macro can be used on both the client-side (passing a #GDBusObjectProxy) or the service-side (passing a #GDBusObjectSkeleton).\n' - ' *\n' - ' * This macro is just C convenience - other languages will use g_dbus_object_get_interface() to achieve the same result.\n' - ' *\n' - ' * Returns: (transfer full): A #%s or %%NULL if @object does not have said interface. Free with g_object_unref().\n' - %(i.ns_upper, i.name_upper, i.camel_name, i.name, i.camel_name))) - self.write_gtkdoc_deprecated_and_since_and_close(i, self.h, 0) - 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(self.docbook_gen.expand( - '/**\n' - ' * %sPEEK_%s:\n' - ' * @object: A #GDBusObject.\n' - ' *\n' - ' * Like the %sGET_%s() macro but doesn\'t increase the reference count on the returned object.\n' - ' *\n' - ' * This macro can be used on both the client-side (passing a #GDBusObjectProxy) or the service-side (passing a #GDBusObjectSkeleton).\n' - ' *\n' - ' * This macro is just C convenience - other languages will use g_dbus_object_get_interface() to achieve the same result..\n' - ' *\n' - ' * <warning>It is not safe to use the returned object if you are on another thread than where the #GDBusObjectManagerClient is running</warning>\n' - ' *\n' - ' * Returns: (transfer none): A #%s or %%NULL if @object does not have said interface. Do not free the returned object, it belongs to @object.\n' - %(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))) - self.write_gtkdoc_deprecated_and_since_and_close(i, self.h, 0) - 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 skeleton self.h.write('\n') self.h.write('/* ---- */\n') @@ -524,11 +496,98 @@ class CodeGenerator: self.h.write('\n') - # Finally, the proxy manager + # Finally, the Object, ObjectProxy, ObjectSkeleton and ObjectManagerClient if self.generate_objmanager: self.h.write('\n') self.h.write('/* ---- */\n') self.h.write('\n') + self.h.write('#define %sTYPE_OBJECT (%sobject_get_type ())\n'%(self.ns_upper, self.ns_lower)) + self.h.write('#define %sOBJECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT, %sObject))\n'%(self.ns_upper, self.ns_upper, self.namespace)) + self.h.write('#define %sIS_OBJECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT))\n'%(self.ns_upper, self.ns_upper)) + self.h.write('#define %sOBJECT_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), %sTYPE_OBJECT, %sObject))\n'%(self.ns_upper, self.ns_upper, self.namespace)) + self.h.write('\n') + self.h.write('struct _%sObject;\n'%(self.namespace)) + self.h.write('typedef struct _%sObject %sObject;\n'%(self.namespace, self.namespace)) + self.h.write('typedef struct _%sObjectIface %sObjectIface;\n'%(self.namespace, self.namespace)) + self.h.write('\n') + self.h.write('struct _%sObjectIface\n'%(self.namespace)) + self.h.write('{\n' + ' GTypeInterface parent_iface;\n' + '};\n' + '\n') + self.h.write('GType %sobject_get_type (void) G_GNUC_CONST;\n' + '\n' + %(self.ns_lower)) + for i in self.ifaces: + if i.deprecated: + self.h.write('G_GNUC_DEPRECATED ') + self.h.write ('%s *%sobject_get_%s (%sObject *object);\n' + %(i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace)) + for i in self.ifaces: + if i.deprecated: + self.h.write('G_GNUC_DEPRECATED ') + self.h.write ('%s *%sobject_peek_%s (%sObject *object);\n' + %(i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace)) + self.h.write('\n') + self.h.write('#define %sTYPE_OBJECT_PROXY (%sobject_proxy_get_type ())\n'%(self.ns_upper, self.ns_lower)) + self.h.write('#define %sOBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_PROXY, %sObjectProxy))\n'%(self.ns_upper, self.ns_upper, self.namespace)) + self.h.write('#define %sOBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_PROXY, %sObjectProxyClass))\n'%(self.ns_upper, self.ns_upper, self.namespace)) + self.h.write('#define %sOBJECT_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_PROXY, %sObjectProxyClass))\n'%(self.ns_upper, self.ns_upper, self.namespace)) + self.h.write('#define %sIS_OBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_PROXY))\n'%(self.ns_upper, self.ns_upper)) + self.h.write('#define %sIS_OBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_PROXY))\n'%(self.ns_upper, self.ns_upper)) + self.h.write('\n') + self.h.write('typedef struct _%sObjectProxy %sObjectProxy;\n'%(self.namespace, self.namespace)) + self.h.write('typedef struct _%sObjectProxyClass %sObjectProxyClass;\n'%(self.namespace, self.namespace)) + self.h.write('typedef struct _%sObjectProxyPrivate %sObjectProxyPrivate;\n'%(self.namespace, self.namespace)) + self.h.write('\n') + self.h.write('struct _%sObjectProxy\n'%(self.namespace)) + self.h.write('{\n') + self.h.write(' GDBusObjectProxy parent_instance;\n') + self.h.write(' %sObjectProxyPrivate *priv;\n'%(self.namespace)) + self.h.write('};\n') + self.h.write('\n') + self.h.write('struct _%sObjectProxyClass\n'%(self.namespace)) + self.h.write('{\n') + self.h.write(' GDBusObjectProxyClass parent_class;\n') + self.h.write('};\n') + self.h.write('\n') + self.h.write('GType %sobject_proxy_get_type (void) G_GNUC_CONST;\n'%(self.ns_lower)) + self.h.write('%sObjectProxy *%sobject_proxy_new (GDBusConnection *connection, const gchar *object_path);\n'%(self.namespace, self.ns_lower)) + self.h.write('\n') + self.h.write('#define %sTYPE_OBJECT_SKELETON (%sobject_skeleton_get_type ())\n'%(self.ns_upper, self.ns_lower)) + self.h.write('#define %sOBJECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_SKELETON, %sObjectSkeleton))\n'%(self.ns_upper, self.ns_upper, self.namespace)) + self.h.write('#define %sOBJECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_SKELETON, %sObjectSkeletonClass))\n'%(self.ns_upper, self.ns_upper, self.namespace)) + self.h.write('#define %sOBJECT_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_SKELETON, %sObjectSkeletonClass))\n'%(self.ns_upper, self.ns_upper, self.namespace)) + self.h.write('#define %sIS_OBJECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_SKELETON))\n'%(self.ns_upper, self.ns_upper)) + self.h.write('#define %sIS_OBJECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_SKELETON))\n'%(self.ns_upper, self.ns_upper)) + self.h.write('\n') + self.h.write('typedef struct _%sObjectSkeleton %sObjectSkeleton;\n'%(self.namespace, self.namespace)) + self.h.write('typedef struct _%sObjectSkeletonClass %sObjectSkeletonClass;\n'%(self.namespace, self.namespace)) + self.h.write('typedef struct _%sObjectSkeletonPrivate %sObjectSkeletonPrivate;\n'%(self.namespace, self.namespace)) + self.h.write('\n') + self.h.write('struct _%sObjectSkeleton\n'%(self.namespace)) + self.h.write('{\n') + self.h.write(' GDBusObjectSkeleton parent_instance;\n') + self.h.write(' %sObjectSkeletonPrivate *priv;\n'%(self.namespace)) + self.h.write('};\n') + self.h.write('\n') + self.h.write('struct _%sObjectSkeletonClass\n'%(self.namespace)) + self.h.write('{\n') + self.h.write(' GDBusObjectSkeletonClass parent_class;\n') + self.h.write('};\n') + self.h.write('\n') + self.h.write('GType %sobject_skeleton_get_type (void) G_GNUC_CONST;\n'%(self.ns_lower)) + self.h.write('%sObjectSkeleton *%sobject_skeleton_new (const gchar *object_path);\n' + %(self.namespace, self.ns_lower)) + for i in self.ifaces: + if i.deprecated: + self.h.write('G_GNUC_DEPRECATED ') + self.h.write ('void %sobject_skeleton_set_%s (%sObjectSkeleton *object, %s *interface_);\n' + %(self.ns_lower, i.name_upper.lower(), self.namespace, i.camel_name)) + self.h.write('\n') + + self.h.write('/* ---- */\n') + self.h.write('\n') self.h.write('#define %sTYPE_OBJECT_MANAGER_CLIENT (%sobject_manager_client_get_type ())\n'%(self.ns_upper, self.ns_lower)) self.h.write('#define %sOBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClient))\n'%(self.ns_upper, self.ns_upper, self.namespace)) self.h.write('#define %sOBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClientClass))\n'%(self.ns_upper, self.ns_upper, self.namespace)) @@ -799,28 +858,32 @@ class CodeGenerator: '\n') num_anno = self.generate_annotations('_%s_annotation_info'%(i.name_lower), i.annotations) - self.c.write('static const GDBusInterfaceInfo _%s_interface_info =\n' + self.c.write('static const _ExtendedGDBusInterfaceInfo _%s_interface_info =\n' '{\n' - ' -1,\n' - ' "%s",\n'%(i.name_lower, i.name)) + ' {\n' + ' -1,\n' + ' "%s",\n'%(i.name_lower, i.name)) if len(i.methods) == 0: - self.c.write(' NULL,\n') + self.c.write(' NULL,\n') else: - self.c.write(' (GDBusMethodInfo **) &_%s_method_info_pointers,\n'%(i.name_lower)) + self.c.write(' (GDBusMethodInfo **) &_%s_method_info_pointers,\n'%(i.name_lower)) if len(i.signals) == 0: - self.c.write(' NULL,\n') + self.c.write(' NULL,\n') else: - self.c.write(' (GDBusSignalInfo **) &_%s_signal_info_pointers,\n'%(i.name_lower)) + self.c.write(' (GDBusSignalInfo **) &_%s_signal_info_pointers,\n'%(i.name_lower)) if len(i.properties) == 0: - self.c.write(' NULL,\n') + self.c.write(' NULL,\n') else: - self.c.write(' (GDBusPropertyInfo **) &_%s_property_info_pointers,\n'%(i.name_lower)) + self.c.write(' (GDBusPropertyInfo **) &_%s_property_info_pointers,\n'%(i.name_lower)) if num_anno == 0: - self.c.write(' NULL\n') + self.c.write(' NULL\n') else: - self.c.write(' (GDBusAnnotationInfo **) &_%s_annotation_info_pointers\n'%(i.name_lower)) - self.c.write('};\n' - '\n') + self.c.write(' (GDBusAnnotationInfo **) &_%s_annotation_info_pointers\n'%(i.name_lower)) + self.c.write(' },\n' + ' "%s",\n' + '};\n' + '\n' + %(i.name_hyphen)) self.c.write('\n') self.c.write(self.docbook_gen.expand( '/**\n' @@ -1945,11 +2008,11 @@ class CodeGenerator: ' GVariantBuilder builder;\n' ' guint n;\n' ' g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));\n' - ' if (_%s_interface_info.properties == NULL)\n' + ' if (_%s_interface_info.parent_struct.properties == NULL)\n' ' goto out;\n' - ' for (n = 0; _%s_interface_info.properties[n] != NULL; n++)\n' + ' for (n = 0; _%s_interface_info.parent_struct.properties[n] != NULL; n++)\n' ' {\n' - ' GDBusPropertyInfo *info = _%s_interface_info.properties[n];\n' + ' GDBusPropertyInfo *info = _%s_interface_info.parent_struct.properties[n];\n' ' if (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)\n' ' {\n' ' GVariant *value;\n' @@ -2241,6 +2304,405 @@ class CodeGenerator: # --------------------------------------------------------------------------------------------------- + def generate_object(self): + self.c.write('/* ------------------------------------------------------------------------\n' + ' * Code for Object, ObjectProxy and ObjectSkeleton\n' + ' * ------------------------------------------------------------------------\n' + ' */\n' + '\n') + + self.c.write(self.docbook_gen.expand( + '/**\n' + ' * SECTION:%sObject\n' + ' * @title: %sObject\n' + ' * @short_description: Specialized GDBusObject types\n' + ' *\n' + ' * This section contains the #%sObject, #%sObjectProxy, and #%sObjectSkeleton types which make it easier to work with objects implementing generated types for D-Bus interfaces.\n' + ' */\n' + %(self.namespace, self.namespace, self.namespace, self.namespace, self.namespace))) + self.c.write('\n') + + self.c.write(self.docbook_gen.expand( + '/**\n' + ' * %sObject:\n' + ' *\n' + ' * The #%sObject type is a specialized container of interfaces.\n' + ' */\n' + %(self.namespace, self.namespace))) + self.c.write('\n') + + self.c.write(self.docbook_gen.expand( + '/**\n' + ' * %sObjectIface:\n' + ' * @parent_iface: The parent interface.\n' + ' *\n' + ' * Virtual table for the #%sObject interface.\n' + ' */\n' + %(self.namespace, self.namespace))) + self.c.write('\n') + + self.c.write('static void\n' + '%sobject_default_init (%sObjectIface *iface)\n' + '{\n' + %(self.ns_lower, self.namespace)); + for i in self.ifaces: + self.c.write(self.docbook_gen.expand( + ' /**\n' + ' * %sObject:%s:\n' + ' *\n' + ' * The #%s instance corresponding to the D-Bus interface #%s, if any.\n' + ' *\n' + ' * Connect to the #GObject::notify signal to get informed of property changes.\n' + %(self.namespace, i.name_hyphen, i.camel_name, i.name))) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 2) + self.c.write(' g_object_interface_install_property (iface, g_param_spec_object ("%s", "%s", "%s", %sTYPE_%s, G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS));\n' + '\n' + %(i.name_hyphen, i.name_hyphen, i.name_hyphen, self.ns_upper, i.name_upper)) + self.c.write('}\n' + '\n') + + self.c.write('typedef %sObjectIface %sObjectInterface;\n'%(self.namespace, self.namespace)) + self.c.write('G_DEFINE_INTERFACE_WITH_CODE (%sObject, %sobject, G_TYPE_OBJECT, g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_DBUS_OBJECT));\n'%(self.namespace, self.ns_lower)) + self.c.write('\n') + + for i in self.ifaces: + self.c.write(self.docbook_gen.expand( + '/**\n' + ' * %sobject_get_%s:\n' + ' * @object: A #%sObject.\n' + ' *\n' + ' * Gets the #%s instance for the D-Bus interface #%s on @object, if any.\n' + ' *\n' + ' * Returns: (transfer full): A #%s that must be freed with g_object_unref() or %%NULL if @object does not implement the interface.\n' + %(self.ns_lower, i.name_upper.lower(), i.camel_name, i.camel_name, i.name, i.camel_name))) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0) + self.c.write ('%s *%sobject_get_%s (%sObject *object)\n' + %(i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace)) + self.c.write('{\n' + ' GDBusInterface *ret;\n' + ' ret = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n' + ' if (ret == NULL)\n' + ' return NULL;\n' + ' return %s%s (ret);\n' + '}\n' + '\n' + %(i.name, self.ns_upper, i.name_upper)) + self.c.write('\n') + for i in self.ifaces: + self.c.write(self.docbook_gen.expand( + '/**\n' + ' * %sobject_peek_%s: (skip)\n' + ' * @object: A #%sObject.\n' + ' *\n' + ' * Like %sobject_get_%s() but doesn\' increase the reference count on the returned object.\n' + ' *\n' + ' * <warning>It is not safe to use the returned object if you are on another thread than the one where the #GDBusObjectManagerClient or #GDBusObjectManagerServer for @object is running.</warning>\n' + ' *\n' + ' * Returns: (transfer none): A #%s or %%NULL if @object does not implement the interface. Do not free the returned object, it is owned by @object.\n' + %(self.ns_lower, i.name_upper.lower(), i.camel_name, self.ns_lower, i.name_upper.lower(), i.camel_name))) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0) + self.c.write ('%s *%sobject_peek_%s (%sObject *object)\n' + %(i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace)) + self.c.write('{\n' + ' GDBusInterface *ret;\n' + ' ret = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n' + ' if (ret == NULL)\n' + ' return NULL;\n' + ' g_object_unref (ret);\n' + ' return %s%s (ret);\n' + '}\n' + '\n' + %(i.name, self.ns_upper, i.name_upper)) + self.c.write('\n') + # shared by ObjectProxy and ObjectSkeleton classes + self.c.write('static void\n' + '%sobject_notify (GDBusObject *object, GDBusInterface *interface)\n' + '{\n' + ' g_object_notify (G_OBJECT (object), ((_ExtendedGDBusInterfaceInfo *) g_dbus_interface_get_info (interface))->hyphen_name);\n' + '}\n' + '\n' + %(self.ns_lower)) + + self.c.write(self.docbook_gen.expand( + '/**\n' + ' * %sObjectProxy:\n' + ' *\n' + ' * The #%sObjectProxy structure contains only private data and should only be accessed using the provided API.\n' + %(self.namespace, self.namespace))) + self.c.write(' */\n') + self.c.write('\n') + self.c.write(self.docbook_gen.expand( + '/**\n' + ' * %sObjectProxyClass:\n' + ' * @parent_class: The parent class.\n' + ' *\n' + ' * Class structure for #%sObjectProxy.\n' + %(self.namespace, self.namespace))) + self.c.write(' */\n') + self.c.write('\n') + # class boilerplate + self.c.write('static void\n' + '%sobject_proxy__%sobject_iface_init (%sObjectIface *iface)\n' + '{\n' + '}\n' + '\n' + %(self.ns_lower, self.ns_lower, self.namespace)) + self.c.write('static void\n' + '%sobject_proxy__g_dbus_object_iface_init (GDBusObjectIface *iface)\n' + '{\n' + ' iface->interface_added = %sobject_notify;\n' + ' iface->interface_removed = %sobject_notify;\n' + '}\n' + '\n' + %(self.ns_lower, self.ns_lower, self.ns_lower)) + self.c.write('\n') + self.c.write('G_DEFINE_TYPE_WITH_CODE (%sObjectProxy, %sobject_proxy, G_TYPE_DBUS_OBJECT_PROXY,\n' + ' G_IMPLEMENT_INTERFACE (%sTYPE_OBJECT, %sobject_proxy__%sobject_iface_init)\n' + ' G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, %sobject_proxy__g_dbus_object_iface_init));\n' + '\n' + %(self.namespace, self.ns_lower, self.ns_upper, self.ns_lower, self.ns_lower, self.ns_lower)) + # class boilerplate + self.c.write('static void\n' + '%sobject_proxy_init (%sObjectProxy *object)\n' + '{\n' + '}\n' + '\n'%(self.ns_lower, self.namespace)) + self.c.write('static void\n' + '%sobject_proxy_set_property (GObject *_object,\n' + ' guint prop_id,\n' + ' const GValue *value,\n' + ' GParamSpec *pspec)\n' + '{\n' + ' G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec);\n' + %(self.ns_lower)) + self.c.write('}\n' + '\n'%()) + self.c.write('static void\n' + '%sobject_proxy_get_property (GObject *_object,\n' + ' guint prop_id,\n' + ' GValue *value,\n' + ' GParamSpec *pspec)\n' + '{\n' + ' %sObjectProxy *object = %sOBJECT_PROXY (_object);\n' + ' GDBusInterface *interface;\n' + '\n' + ' switch (prop_id)\n' + ' {\n' + %(self.ns_lower, self.namespace, self.ns_upper)) + n = 1 + for i in self.ifaces: + self.c.write(' case %d:\n' + ' interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n' + ' g_value_take_object (value, interface);\n' + ' break;\n' + '\n' + %(n, i.name)) + n += 1 + self.c.write(' default:\n' + ' G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec);\n' + ' break;\n' + ' }\n' + '}\n' + '\n'%()) + self.c.write('static void\n' + '%sobject_proxy_class_init (%sObjectProxyClass *klass)\n' + '{\n' + ' GObjectClass *gobject_class = G_OBJECT_CLASS (klass);\n' + '\n' + ' gobject_class->set_property = %sobject_proxy_set_property;\n' + ' gobject_class->get_property = %sobject_proxy_get_property;\n' + '\n' + %(self.ns_lower, self.namespace, self.ns_lower, self.ns_lower)) + n = 1 + for i in self.ifaces: + self.c.write(' g_object_class_override_property (gobject_class, %d, "%s");' + '\n' + %(n, i.name_hyphen)) + n += 1 + self.c.write('}\n' + '\n') + + self.c.write(self.docbook_gen.expand( + '/**\n' + ' * %sobject_proxy_new:\n' + ' * @connection: A #GDBusConnection.\n' + ' * @object_path: An object path.\n' + ' *\n' + ' * Creates a new proxy object.\n' + ' *\n' + ' * Returns: (transfer full): The proxy object.\n' + ' */\n' + %(self.ns_lower))) + self.c.write('%sObjectProxy *\n' + '%sobject_proxy_new (GDBusConnection *connection,\n' + ' const gchar *object_path)\n' + '{\n' + ' g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);\n' + ' g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);\n' + ' return %sOBJECT_PROXY (g_object_new (%sTYPE_OBJECT_PROXY, "connection", connection, "object-path", object_path, NULL));\n' + '}\n' + '\n'%(self.namespace, self.ns_lower, self.ns_upper, self.ns_upper)) + + self.c.write(self.docbook_gen.expand( + '/**\n' + ' * %sObjectSkeleton:\n' + ' *\n' + ' * The #%sObjectSkeleton structure contains only private data and should only be accessed using the provided API.\n' + %(self.namespace, self.namespace))) + self.c.write(' */\n') + self.c.write('\n') + self.c.write(self.docbook_gen.expand( + '/**\n' + ' * %sObjectSkeletonClass:\n' + ' * @parent_class: The parent class.\n' + ' *\n' + ' * Class structure for #%sObjectSkeleton.\n' + %(self.namespace, self.namespace))) + self.c.write(' */\n') + self.c.write('\n') + # class boilerplate + self.c.write('static void\n' + '%sobject_skeleton__%sobject_iface_init (%sObjectIface *iface)\n' + '{\n' + '}\n' + '\n' + %(self.ns_lower, self.ns_lower, self.namespace)) + self.c.write('\n') + self.c.write('static void\n' + '%sobject_skeleton__g_dbus_object_iface_init (GDBusObjectIface *iface)\n' + '{\n' + ' iface->interface_added = %sobject_notify;\n' + ' iface->interface_removed = %sobject_notify;\n' + '}\n' + '\n' + %(self.ns_lower, self.ns_lower, self.ns_lower)) + self.c.write('G_DEFINE_TYPE_WITH_CODE (%sObjectSkeleton, %sobject_skeleton, G_TYPE_DBUS_OBJECT_SKELETON,\n' + ' G_IMPLEMENT_INTERFACE (%sTYPE_OBJECT, %sobject_skeleton__%sobject_iface_init)\n' + ' G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, %sobject_skeleton__g_dbus_object_iface_init));\n' + '\n' + %(self.namespace, self.ns_lower, self.ns_upper, self.ns_lower, self.ns_lower, self.ns_lower)) + # class boilerplate + self.c.write('static void\n' + '%sobject_skeleton_init (%sObjectSkeleton *object)\n' + '{\n' + '}\n' + '\n'%(self.ns_lower, self.namespace)) + self.c.write('static void\n' + '%sobject_skeleton_set_property (GObject *_object,\n' + ' guint prop_id,\n' + ' const GValue *value,\n' + ' GParamSpec *pspec)\n' + '{\n' + ' %sObjectSkeleton *object = %sOBJECT_SKELETON (_object);\n' + ' GDBusInterfaceSkeleton *interface;\n' + '\n' + ' switch (prop_id)\n' + ' {\n' + %(self.ns_lower, self.namespace, self.ns_upper)) + n = 1 + for i in self.ifaces: + self.c.write(' case %d:\n' + ' interface = g_value_get_object (value);\n' + ' if (interface != NULL)\n' + ' {\n' + ' g_warn_if_fail (%sIS_%s (interface));\n' + ' g_dbus_object_skeleton_add_interface (G_DBUS_OBJECT_SKELETON (object), interface);\n' + ' }\n' + ' else\n' + ' {\n' + ' g_dbus_object_skeleton_remove_interface_by_name (G_DBUS_OBJECT_SKELETON (object), "%s");\n' + ' }\n' + ' break;\n' + '\n' + %(n, self.ns_upper, i.name_upper, i.name)) + n += 1 + self.c.write(' default:\n' + ' G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec);\n' + ' break;\n' + ' }\n' + '}\n' + '\n'%()) + self.c.write('static void\n' + '%sobject_skeleton_get_property (GObject *_object,\n' + ' guint prop_id,\n' + ' GValue *value,\n' + ' GParamSpec *pspec)\n' + '{\n' + ' %sObjectSkeleton *object = %sOBJECT_SKELETON (_object);\n' + ' GDBusInterface *interface;\n' + '\n' + ' switch (prop_id)\n' + ' {\n' + %(self.ns_lower, self.namespace, self.ns_upper)) + n = 1 + for i in self.ifaces: + self.c.write(' case %d:\n' + ' interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n' + ' g_value_take_object (value, interface);\n' + ' break;\n' + '\n' + %(n, i.name)) + n += 1 + self.c.write(' default:\n' + ' G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec);\n' + ' break;\n' + ' }\n' + '}\n' + '\n'%()) + self.c.write('static void\n' + '%sobject_skeleton_class_init (%sObjectSkeletonClass *klass)\n' + '{\n' + ' GObjectClass *gobject_class = G_OBJECT_CLASS (klass);\n' + '\n' + ' gobject_class->set_property = %sobject_skeleton_set_property;\n' + ' gobject_class->get_property = %sobject_skeleton_get_property;\n' + '\n' + %(self.ns_lower, self.namespace, self.ns_lower, self.ns_lower)) + n = 1 + for i in self.ifaces: + self.c.write(' g_object_class_override_property (gobject_class, %d, "%s");' + '\n' + %(n, i.name_hyphen)) + n += 1 + self.c.write('}\n' + '\n') + self.c.write(self.docbook_gen.expand( + '/**\n' + ' * %sobject_skeleton_new:\n' + ' * @object_path: An object path.\n' + ' *\n' + ' * Creates a new skeleton object.\n' + ' *\n' + ' * Returns: (transfer full): The skeleton object.\n' + ' */\n' + %(self.ns_lower))) + self.c.write('%sObjectSkeleton *\n' + '%sobject_skeleton_new (const gchar *object_path)\n' + '{\n' + ' g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);\n' + ' return %sOBJECT_SKELETON (g_object_new (%sTYPE_OBJECT_SKELETON, "object-path", object_path, NULL));\n' + '}\n' + '\n'%(self.namespace, self.ns_lower, self.ns_upper, self.ns_upper)) + for i in self.ifaces: + self.c.write(self.docbook_gen.expand( + '/**\n' + ' * %sobject_skeleton_set_%s:\n' + ' * @object: A #%sObjectSkeleton.\n' + ' * @interface_: (allow-none): A #%s or %%NULL to clear the interface.\n' + ' *\n' + ' * Sets the #%s instance for the D-Bus interface #%s on @object.\n' + %(self.ns_lower, i.name_upper.lower(), self.namespace, i.camel_name, i.camel_name, i.name))) + self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0) + self.c.write ('void %sobject_skeleton_set_%s (%sObjectSkeleton *object, %s *interface_)\n' + %(self.ns_lower, i.name_upper.lower(), self.namespace, i.camel_name)) + self.c.write('{\n' + ' g_object_set (G_OBJECT (object), "%s", interface_, NULL);\n' + '}\n' + '\n' + %(i.name_hyphen)) + self.c.write('\n') + + def generate_object_manager_client(self): self.c.write('/* ------------------------------------------------------------------------\n' ' * Code for ObjectManager client\n' @@ -2252,7 +2714,7 @@ class CodeGenerator: '/**\n' ' * SECTION:%sObjectManagerClient\n' ' * @title: %sObjectManagerClient\n' - ' * @short_description: Generated #GDBusObjectManagerClient subclass\n' + ' * @short_description: Generated GDBusObjectManagerClient type\n' ' *\n' ' * This section contains a #GDBusObjectManagerClient that uses %sobject_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc.\n' ' */\n' @@ -2300,13 +2762,13 @@ class CodeGenerator: ' * %sobject_manager_client_get_proxy_type:\n' ' * @manager: A #GDBusObjectManagerClient.\n' ' * @object_path: The object path of the remote object (unused).\n' - ' * @interface_name: Interface name of the remote object.\n' + ' * @interface_name: (allow-none): Interface name of the remote object or %%NULL to get the object proxy #GType.\n' ' * @user_data: User data (unused).\n' ' *\n' - ' * A #GDBusProxyTypeFunc that maps @interface_name to the generated #GDBusProxy<!-- -->-derived types.\n' + ' * A #GDBusProxyTypeFunc that maps @interface_name to the generated #GDBusObjectProxy<!-- -->- and #GDBusProxy<!-- -->-derived types.\n' ' *\n' - ' * Returns: A #GDBusProxy<!-- -->-derived #GType.\n' - %(self.ns_lower))) + ' * Returns: A #GDBusProxy<!-- -->-derived #GType if @interface_name is not %%NULL, otherwise the #GType for #%sObjectProxy.\n' + %(self.ns_lower, self.namespace))) self.c.write(' */\n') self.c.write('GType\n' '%sobject_manager_client_get_proxy_type (GDBusObjectManagerClient *manager, const gchar *object_path, const gchar *interface_name, gpointer user_data)\n' @@ -2316,9 +2778,12 @@ class CodeGenerator: ' static GHashTable *lookup_hash;\n' ' GType ret;\n' '\n' + ' if (interface_name == NULL)\n' + ' return %sTYPE_OBJECT_PROXY;\n' ' if (g_once_init_enter (&once_init_value))\n' ' {\n' - ' lookup_hash = g_hash_table_new (g_str_hash, g_str_equal);\n') + ' lookup_hash = g_hash_table_new (g_str_hash, g_str_equal);\n' + %(self.ns_upper)) for i in self.ifaces: self.c.write(' g_hash_table_insert (lookup_hash, "%s", GSIZE_TO_POINTER (%sTYPE_%s_PROXY));\n' %(i.name, i.ns_upper, i.name_upper)) @@ -2587,5 +3052,6 @@ class CodeGenerator: self.generate_proxy(i) self.generate_skeleton(i) if self.generate_objmanager: + self.generate_object() self.generate_object_manager_client() self.generate_outro() diff --git a/gio/gdbus-codegen/dbustypes.py b/gio/gdbus-codegen/dbustypes.py index 1eb1282d9..3a39f13ce 100644 --- a/gio/gdbus-codegen/dbustypes.py +++ b/gio/gdbus-codegen/dbustypes.py @@ -349,6 +349,8 @@ class Interface: self.name_lower = utils.camel_case_to_uscore(name_with_ns) self.name_upper = utils.camel_case_to_uscore(name).upper() + self.name_hyphen = self.name_upper.lower().replace('_', '-') + if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true': self.deprecated = True diff --git a/gio/gdbusobject.c b/gio/gdbusobject.c index c982fe0f3..8c16d6658 100644 --- a/gio/gdbusobject.c +++ b/gio/gdbusobject.c @@ -146,60 +146,3 @@ g_dbus_object_get_interface (GDBusObject *object, g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL); return iface->get_interface (object, interface_name); } - - -/** - * g_dbus_object_peek_with_typecheck: - * @object: A #GDBusObject. - * @interface_name: A D-Bus interface name. - * @type: The #GType that the returned object must conform to. - * - * Like g_dbus_object_lookup_with_typecheck() except that the caller - * does not own a reference to the returned object. - * - * <note><para>This function is intended to only be used in type - * implementations.</para></note> - * - * Returns: (transfer none): A #GDBusInterface implementing @type or - * %NULL if not found. Do not free the returned object, it is owned - * by @object. - * - * Since: 2.30 - */ -gpointer -g_dbus_object_peek_with_typecheck (GDBusObject *object, - const gchar *interface_name, - GType type) -{ - GDBusObjectIface *iface = G_DBUS_OBJECT_GET_IFACE (object); - g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL); - return iface->peek_with_typecheck (object, interface_name, type); -} - -/** - * g_dbus_object_lookup_with_typecheck: - * @object: A #GDBusObject. - * @interface_name: A D-Bus interface name. - * @type: The #GType that the returned object must conform to. - * - * Like g_dbus_object_get_interface() 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: (transfer full): A #GDBusInterface implementing @type or - * %NULL if not found. Free with g_object_unref(). - * - * Since: 2.30 - */ -gpointer -g_dbus_object_lookup_with_typecheck (GDBusObject *object, - const gchar *interface_name, - GType type) -{ - GDBusObjectIface *iface = G_DBUS_OBJECT_GET_IFACE (object); - g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL); - return iface->lookup_with_typecheck (object, interface_name, type); -} - diff --git a/gio/gdbusobject.h b/gio/gdbusobject.h index 603229f57..5212926b9 100644 --- a/gio/gdbusobject.h +++ b/gio/gdbusobject.h @@ -40,9 +40,6 @@ typedef struct _GDBusObjectIface GDBusObjectIface; * @get_object_path: Returns the object path. See g_dbus_object_get_object_path(). * @get_interfaces: Returns all interfaces. See g_dbus_object_get_interfaces(). * @get_interface: Returns an interface by name. See g_dbus_object_get_interface(). - * @lookup_with_typecheck: Like @get_interface but warns on stderr if the returned object, if any, - * does not conform to @type. Returned object must be freed by the caller. - * @peek_with_typecheck: Like @lookup_with_typecheck but does not transfer the reference. * @interface_added: Signal handler for the #GDBusObject::interface-added signal. * @interface_removed: Signal handler for the #GDBusObject::interface-removed signal. * @@ -64,13 +61,6 @@ struct _GDBusObjectIface GDBusInterface *(*get_interface) (GDBusObject *object, const gchar *interface_name); - gpointer (*lookup_with_typecheck) (GDBusObject *object, - const gchar *interface_name, - GType type); - gpointer (*peek_with_typecheck) (GDBusObject *object, - const gchar *interface_name, - GType type); - /* Signals */ void (*interface_added) (GDBusObject *object, GDBusInterface *interface_); @@ -85,13 +75,6 @@ GList *g_dbus_object_get_interfaces (GDBusObject *object); GDBusInterface *g_dbus_object_get_interface (GDBusObject *object, const gchar *interface_name); -gpointer g_dbus_object_peek_with_typecheck (GDBusObject *object, - const gchar *interface_name, - GType type); -gpointer g_dbus_object_lookup_with_typecheck (GDBusObject *object, - const gchar *interface_name, - GType type); - G_END_DECLS #endif /* __G_DBUS_OBJECT_H__ */ diff --git a/gio/gdbusobjectmanagerclient.c b/gio/gdbusobjectmanagerclient.c index fe33d4b37..474152d75 100644 --- a/gio/gdbusobjectmanagerclient.c +++ b/gio/gdbusobjectmanagerclient.c @@ -1387,7 +1387,23 @@ add_interfaces (GDBusObjectManagerClient *manager, op = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path); if (op == NULL) { - op = _g_dbus_object_proxy_new (manager->priv->connection, object_path); + GType object_proxy_type; + if (manager->priv->get_proxy_type_func != NULL) + { + object_proxy_type = manager->priv->get_proxy_type_func (manager, + object_path, + NULL, + manager->priv->get_proxy_type_user_data); + g_warn_if_fail (g_type_is_a (object_proxy_type, G_TYPE_DBUS_OBJECT_PROXY)); + } + else + { + object_proxy_type = G_TYPE_DBUS_OBJECT_PROXY; + } + op = g_object_new (object_proxy_type, + "connection", manager->priv->connection, + "object-path", object_path, + NULL); added = TRUE; } diff --git a/gio/gdbusobjectproxy.c b/gio/gdbusobjectproxy.c index 39d31266c..46f249bed 100644 --- a/gio/gdbusobjectproxy.c +++ b/gio/gdbusobjectproxy.c @@ -37,9 +37,9 @@ * @include: gio/gio.h * * 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 - * #GDBusObjectManagerClient to get one. + * with one or more D-Bus interfaces. Normally, you don't instantiate + * a #GDBusObjectProxy yourself - typically #GDBusObjectManagerClient + * is used to obtain it. * * Since: 2.30 */ @@ -104,8 +104,18 @@ g_dbus_object_proxy_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { + GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object); + switch (prop_id) { + case PROP_OBJECT_PATH: + proxy->priv->object_path = g_value_dup_string (value); + break; + + case PROP_CONNECTION: + proxy->priv->connection = g_value_dup_object (value); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec); break; @@ -134,7 +144,8 @@ g_dbus_object_proxy_class_init (GDBusObjectProxyClass *klass) "Object Path", "The object path of the proxy", NULL, - G_PARAM_READABLE | + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); /** @@ -146,11 +157,12 @@ g_dbus_object_proxy_class_init (GDBusObjectProxyClass *klass) */ g_object_class_install_property (gobject_class, PROP_CONNECTION, - g_param_spec_string ("connection", + g_param_spec_object ("connection", "Connection", "The connection of the proxy", - NULL, - G_PARAM_READABLE | + G_TYPE_DBUS_CONNECTION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); g_type_class_add_private (klass, sizeof (GDBusObjectProxyPrivate)); @@ -231,18 +243,15 @@ g_dbus_object_proxy_get_interfaces (GDBusObject *object) /* ---------------------------------------------------------------------------------------------------- */ GDBusObjectProxy * -_g_dbus_object_proxy_new (GDBusConnection *connection, - const gchar *object_path) +g_dbus_object_proxy_new (GDBusConnection *connection, + const gchar *object_path) { - GDBusObjectProxy *proxy; - g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); - - proxy = G_DBUS_OBJECT_PROXY (g_object_new (G_TYPE_DBUS_OBJECT_PROXY, NULL)); - proxy->priv->object_path = g_strdup (object_path); - proxy->priv->connection = g_object_ref (connection); - return proxy; + return G_DBUS_OBJECT_PROXY (g_object_new (G_TYPE_DBUS_OBJECT_PROXY, + "object-path", object_path, + "connection", connection, + NULL)); } void @@ -281,44 +290,10 @@ _g_dbus_object_proxy_remove_interface (GDBusObjectProxy *proxy, } } -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); - g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL); - - ret = g_hash_table_lookup (proxy->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_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/gio/gdbusobjectproxy.h b/gio/gdbusobjectproxy.h index c8e3f30af..58aef853c 100644 --- a/gio/gdbusobjectproxy.h +++ b/gio/gdbusobjectproxy.h @@ -68,8 +68,10 @@ struct _GDBusObjectProxyClass gpointer padding[8]; }; -GType g_dbus_object_proxy_get_type (void) G_GNUC_CONST; -GDBusConnection *g_dbus_object_proxy_get_connection (GDBusObjectProxy *proxy); +GType g_dbus_object_proxy_get_type (void) G_GNUC_CONST; +GDBusObjectProxy *g_dbus_object_proxy_new (GDBusConnection *connection, + const gchar *object_path); +GDBusConnection *g_dbus_object_proxy_get_connection (GDBusObjectProxy *proxy); G_END_DECLS diff --git a/gio/gdbusobjectskeleton.c b/gio/gdbusobjectskeleton.c index 134003fe0..ce7362fe2 100644 --- a/gio/gdbusobjectskeleton.c +++ b/gio/gdbusobjectskeleton.c @@ -435,43 +435,12 @@ g_dbus_object_skeleton_flush (GDBusObjectSkeleton *object) } } -static gpointer -g_dbus_object_skeleton_lookup_with_typecheck (GDBusObject *object, - const gchar *interface_name, - GType type) -{ - GDBusObjectSkeleton *skeleton = G_DBUS_OBJECT_SKELETON (object); - GDBusProxy *ret; - - ret = g_hash_table_lookup (skeleton->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_skeleton_peek_with_typecheck (GDBusObject *object, - const gchar *interface_name, - GType type) -{ - GDBusInterfaceSkeleton *ret; - ret = g_dbus_object_skeleton_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_skeleton_get_object_path; iface->get_interfaces = g_dbus_object_skeleton_get_interfaces; iface->get_interface = g_dbus_object_skeleton_get_interface; - iface->lookup_with_typecheck = g_dbus_object_skeleton_lookup_with_typecheck; - iface->peek_with_typecheck = g_dbus_object_skeleton_peek_with_typecheck; } gboolean diff --git a/gio/gdbusprivate.h b/gio/gdbusprivate.h index 203c4ac10..651d4d69c 100644 --- a/gio/gdbusprivate.h +++ b/gio/gdbusprivate.h @@ -133,8 +133,6 @@ gboolean _g_signal_accumulator_false_handled (GSignalInvocationHint *ihint, gboolean _g_dbus_object_skeleton_has_authorize_method_handlers (GDBusObjectSkeleton *object); -GDBusObjectProxy *_g_dbus_object_proxy_new (GDBusConnection *connection, - const gchar *object_path); void _g_dbus_object_proxy_add_interface (GDBusObjectProxy *proxy, GDBusProxy *interface_proxy); void _g_dbus_object_proxy_remove_interface (GDBusObjectProxy *proxy, diff --git a/gio/gio.symbols b/gio/gio.symbols index 0dfcb61f7..650ca963e 100644 --- a/gio/gio.symbols +++ b/gio/gio.symbols @@ -2121,13 +2121,12 @@ g_dbus_object_get_interface g_dbus_object_get_interfaces g_dbus_object_get_object_path g_dbus_object_get_type -g_dbus_object_lookup_with_typecheck -g_dbus_object_peek_with_typecheck #endif #endif #if IN_HEADER(__G_DBUS_OBJECT_PROXY_H__) #if IN_FILE(__G_DBUS_OBJECT_PROXY_C__) +g_dbus_object_proxy_new g_dbus_object_proxy_get_connection g_dbus_object_proxy_get_type #endif diff --git a/gio/giotypes.h b/gio/giotypes.h index a91eb106f..3cc4f66b7 100644 --- a/gio/giotypes.h +++ b/gio/giotypes.h @@ -431,18 +431,20 @@ typedef struct _GDBusObjectManagerServer GDBusObjectManagerServer; * GDBusProxyTypeFunc: * @manager: A #GDBusObjectManagerClient. * @object_path: The object path of the remote object. - * @interface_name: The interface name of the remote object. + * @interface_name: (allow-none): The interface name of the remote object or %NULL if a #GDBusObjectProxy #GType is requested. * @user_data: User data. * * Function signature for a function used to determine the #GType to - * use for an interface proxy. + * use for an interface proxy (if @interface_name is not %NULL) or + * object proxy (if @interface_name is %NULL). * * This function is called in the * <link linkend="g-main-context-push-thread-default">thread-default main loop</link> * that @manager was constructed in. * * Returns: A #GType to use for the remote object. The returned type - * must be a #GDBusProxy derived type. + * must be a #GDBusProxy<!-- -->- or #GDBusObjectProxy<!-- -->-derived + * type. * * Since: 2.30 */ diff --git a/gio/tests/gdbus-example-objectmanager-client.c b/gio/tests/gdbus-example-objectmanager-client.c index 19a3c8284..b413890d0 100644 --- a/gio/tests/gdbus-example-objectmanager-client.c +++ b/gio/tests/gdbus-example-objectmanager-client.c @@ -13,12 +13,12 @@ print_objects (GDBusObjectManager *manager) objects = g_dbus_object_manager_get_objects (manager); for (l = objects; l != NULL; l = l->next) { - GDBusObject *object = G_DBUS_OBJECT (l->data); + ExampleObject *object = EXAMPLE_OBJECT (l->data); GList *interfaces; GList *ll; - g_print (" - Object at %s\n", g_dbus_object_get_object_path (object)); + g_print (" - Object at %s\n", g_dbus_object_get_object_path (G_DBUS_OBJECT (object))); - interfaces = g_dbus_object_get_interfaces (object); + interfaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (object)); for (ll = interfaces; ll != NULL; ll = ll->next) { GDBusInterface *interface = G_DBUS_INTERFACE (ll->data); diff --git a/gio/tests/gdbus-example-objectmanager-server.c b/gio/tests/gdbus-example-objectmanager-server.c index 79d866c07..0ef9c498f 100644 --- a/gio/tests/gdbus-example-objectmanager-server.c +++ b/gio/tests/gdbus-example-objectmanager-server.c @@ -62,7 +62,7 @@ on_bus_acquired (GDBusConnection *connection, const gchar *name, gpointer user_data) { - GDBusObjectSkeleton *object; + ExampleObjectSkeleton *object; guint n; g_print ("Acquired a message bus connection\n"); @@ -77,7 +77,7 @@ on_bus_acquired (GDBusConnection *connection, /* Create a new D-Bus object at the path /example/Animals/N where N is 000..009 */ s = g_strdup_printf ("/example/Animals/%03d", n); - object = g_dbus_object_skeleton_new (s); + object = example_object_skeleton_new (s); g_free (s); /* Make the newly created object export the interface @@ -86,7 +86,7 @@ on_bus_acquired (GDBusConnection *connection, */ animal = example_animal_skeleton_new (); example_animal_set_mood (animal, "Happy"); - g_dbus_object_skeleton_add_interface (object, G_DBUS_INTERFACE_SKELETON (animal)); + example_object_skeleton_set_animal (object, animal); g_object_unref (animal); /* Cats are odd animals - so some of our objects implement the @@ -97,7 +97,7 @@ on_bus_acquired (GDBusConnection *connection, { ExampleCat *cat; cat = example_cat_skeleton_new (); - g_dbus_object_skeleton_add_interface (object, G_DBUS_INTERFACE_SKELETON (cat)); + example_object_skeleton_set_cat (object, cat); g_object_unref (cat); } @@ -108,7 +108,7 @@ on_bus_acquired (GDBusConnection *connection, NULL); /* user_data */ /* Export the object (@manager takes its own reference to @object) */ - g_dbus_object_manager_server_export (manager, object); + g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object)); g_object_unref (object); } } diff --git a/gio/tests/gdbus-test-codegen.c b/gio/tests/gdbus-test-codegen.c index f7e7de3c3..896573cfd 100644 --- a/gio/tests/gdbus-test-codegen.c +++ b/gio/tests/gdbus-test-codegen.c @@ -1624,7 +1624,7 @@ om_on_signal (GDBusConnection *connection, static GAsyncResult *om_res = NULL; static void -om_pm_start_cb (GDBusObjectManagerClient *manager, +om_pm_start_cb (FooObjectManagerClient *manager, GAsyncResult *res, gpointer user_data) { @@ -1633,26 +1633,6 @@ om_pm_start_cb (GDBusObjectManagerClient *manager, g_main_loop_quit (loop); } -static GType -get_proxy_type (GDBusObjectManagerClient *manager, - const gchar *object_path, - const gchar *interface_name, - gpointer user_data) -{ - GType type; - - g_assert_cmpint (GPOINTER_TO_UINT (user_data), ==, 42); - - type = G_TYPE_DBUS_PROXY; - /* only map Bar and Bat, not other interface types */ - if (g_strcmp0 (interface_name, "org.project.Bar") == 0) - type = FOO_TYPE_BAR_PROXY; - else if (g_strcmp0 (interface_name, "org.project.Bat") == 0) - type = FOO_TYPE_BAT_PROXY; - - return type; -} - static void on_interface_added (GDBusObject *object, GDBusInterface *interface, @@ -1724,10 +1704,9 @@ om_check_property_and_signal_emission (GMainLoop *loop, static void check_object_manager (void) { - GDBusObjectSkeleton *o; - GDBusObjectSkeleton *o2; + FooObjectSkeleton *o; + FooObjectSkeleton *o2; GDBusInterfaceSkeleton *i; - GDBusInterfaceSkeleton *i2; GDBusConnection *c; GDBusObjectManagerServer *manager; GDBusNodeInfo *info; @@ -1741,10 +1720,6 @@ check_object_manager (void) GDBusObject *op; GDBusProxy *p; FooBar *bar_skeleton; - FooBar *bar_p; - FooBar *bar_p2; - FooComAcmeCoyote *coyote_p; - guint old_ref_count; loop = g_main_loop_new (NULL, FALSE); @@ -1777,15 +1752,12 @@ check_object_manager (void) * GDBusObjectManagerClient firing before om_on_signal(). */ error = NULL; - pm = g_dbus_object_manager_client_new_sync (c, - G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, - g_dbus_connection_get_unique_name (c), - "/managed", - get_proxy_type, - GUINT_TO_POINTER (42), - NULL, /* GDestroyNotify */ - NULL, /* GCancellable */ - &error); + pm = foo_object_manager_client_new_sync (c, + G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, + g_dbus_connection_get_unique_name (c), + "/managed", + NULL, /* GCancellable */ + &error); g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD); g_error_free (error); g_assert (pm == NULL); @@ -1805,19 +1777,16 @@ check_object_manager (void) /* Now try to create the the proxy manager again - this time it should work */ error = NULL; - g_dbus_object_manager_client_new (c, - G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, - g_dbus_connection_get_unique_name (c), - "/managed", - get_proxy_type, - GUINT_TO_POINTER (42), - NULL, /* GDestroyNotify */ - NULL, /* GCancellable */ - (GAsyncReadyCallback) om_pm_start_cb, - loop); + foo_object_manager_client_new (c, + G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, + g_dbus_connection_get_unique_name (c), + "/managed", + NULL, /* GCancellable */ + (GAsyncReadyCallback) om_pm_start_cb, + loop); g_main_loop_run (loop); error = NULL; - pm = g_dbus_object_manager_client_new_finish (om_res, &error); + pm = foo_object_manager_client_new_finish (om_res, &error); g_object_unref (om_res); g_assert_no_error (error); g_assert (pm != NULL); @@ -1836,22 +1805,22 @@ check_object_manager (void) /* First, export an object with a single interface (also check that * g_dbus_interface_get_object() works and that the object isn't reffed) */ - o = g_dbus_object_skeleton_new ("/managed/first"); + o = foo_object_skeleton_new ("/managed/first"); i = G_DBUS_INTERFACE_SKELETON (foo_bar_skeleton_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_skeleton_add_interface (o, i); + foo_object_skeleton_set_bar (o, FOO_BAR (i)); g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1); 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_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1); - g_dbus_object_skeleton_remove_interface (o, i); + foo_object_skeleton_set_bar (o, NULL); g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (i)) == NULL); g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1); - g_dbus_object_skeleton_add_interface (o, i); + foo_object_skeleton_set_bar (o, FOO_BAR (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_server_export (manager, o); + g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (o)); /* ... check we get the InterfacesAdded signal */ om_data->state = 1; @@ -1868,7 +1837,7 @@ check_object_manager (void) g_dbus_node_info_unref (info); /* Now, check adding the same interface replaces the existing one */ - g_dbus_object_skeleton_add_interface (o, i); + foo_object_skeleton_set_bar (o, FOO_BAR (i)); /* ... check we get the InterfacesRemoved */ om_data->state = 3; g_main_loop_run (om_data->loop); @@ -1887,7 +1856,7 @@ check_object_manager (void) /* check adding an interface of same type (but not same object) replaces the existing one */ i = G_DBUS_INTERFACE_SKELETON (foo_bar_skeleton_new ()); - g_dbus_object_skeleton_add_interface (o, i); + foo_object_skeleton_set_bar (o, FOO_BAR (i)); /* ... check we get the InterfacesRemoved and then InterfacesAdded */ om_data->state = 7; g_main_loop_run (om_data->loop); @@ -1905,7 +1874,7 @@ check_object_manager (void) /* check adding an interface of another type doesn't replace the existing one */ i = G_DBUS_INTERFACE_SKELETON (foo_bat_skeleton_new ()); - g_dbus_object_skeleton_add_interface (o, i); + foo_object_skeleton_set_bat (o, FOO_BAT (i)); g_object_unref (i); /* ... check we get the InterfacesAdded */ om_data->state = 11; @@ -1923,7 +1892,7 @@ check_object_manager (void) g_dbus_node_info_unref (info); /* check we can remove an interface */ - g_dbus_object_skeleton_remove_interface_by_name (o, "org.project.Bar"); + foo_object_skeleton_set_bar (o, NULL); /* ... check we get the InterfacesRemoved */ om_data->state = 13; g_main_loop_run (om_data->loop); @@ -1942,7 +1911,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_skeleton_remove_interface_by_name (o, "org.project.Bar"); + foo_object_skeleton_set_bar (o, NULL); /* ... 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 */ @@ -1950,7 +1919,7 @@ check_object_manager (void) g_dbus_node_info_unref (info); /* remove the last interface */ - g_dbus_object_skeleton_remove_interface_by_name (o, "org.project.Bat"); + foo_object_skeleton_set_bat (o, NULL); /* ... check we get the InterfacesRemoved */ om_data->state = 15; g_main_loop_run (om_data->loop); @@ -1966,7 +1935,7 @@ check_object_manager (void) /* and add an interface again */ i = G_DBUS_INTERFACE_SKELETON (foo_com_acme_coyote_skeleton_new ()); - g_dbus_object_skeleton_add_interface (o, i); + foo_object_skeleton_set_com_acme_coyote (o, FOO_COM_ACME_COYOTE (i)); g_object_unref (i); /* ... check we get the InterfacesAdded */ om_data->state = 17; @@ -1989,16 +1958,16 @@ check_object_manager (void) /* -------------------------------------------------- */ /* create a new object with two interfaces */ - o2 = g_dbus_object_skeleton_new ("/managed/second"); + o2 = foo_object_skeleton_new ("/managed/second"); i = G_DBUS_INTERFACE_SKELETON (foo_bar_skeleton_new ()); bar_skeleton = FOO_BAR (i); /* save for later test */ - g_dbus_object_skeleton_add_interface (o2, i); + foo_object_skeleton_set_bar (o2, FOO_BAR (i)); g_object_unref (i); i = G_DBUS_INTERFACE_SKELETON (foo_bat_skeleton_new ()); - g_dbus_object_skeleton_add_interface (o2, i); + foo_object_skeleton_set_bat (o2, FOO_BAT (i)); g_object_unref (i); /* ... add it */ - g_dbus_object_manager_server_export (manager, o2); + g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (o2)); /* ... check we get the InterfacesAdded with _two_ interfaces */ om_data->state = 101; g_main_loop_run (om_data->loop); @@ -2016,27 +1985,9 @@ 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_SKELETON)); - 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_SKELETON)); - /* ... 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 ObjectManagerClient returns these objects - and - * that they are of the right GType cf. what we requested via - * our ::get-proxy-type signal handler + * that they are of the right GType cf. what was requested via + * the generated ::get-proxy-type signal handler */ object_proxies = g_dbus_object_manager_get_objects (pm); g_assert (g_list_length (object_proxies) == 2); @@ -2044,15 +1995,16 @@ check_object_manager (void) g_list_free (object_proxies); op = g_dbus_object_manager_get_object (pm, "/managed/first"); g_assert (op != NULL); + g_assert (FOO_IS_OBJECT_PROXY (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_PROXY (g_dbus_object_get_interface (op, "com.acme.Coyote")); + p = G_DBUS_PROXY (foo_object_get_com_acme_coyote (FOO_OBJECT (op))); 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_assert_cmpint (G_TYPE_FROM_INSTANCE (p), ==, FOO_TYPE_COM_ACME_COYOTE_PROXY); + g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (p), FOO_TYPE_COM_ACME_COYOTE)); g_object_unref (p); p = (GDBusProxy *) g_dbus_object_get_interface (op, "org.project.NonExisting"); g_assert (p == NULL); @@ -2060,17 +2012,18 @@ check_object_manager (void) /* -- */ op = g_dbus_object_manager_get_object (pm, "/managed/second"); g_assert (op != NULL); + g_assert (FOO_IS_OBJECT_PROXY (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_PROXY (g_dbus_object_get_interface (op, "org.project.Bat")); + p = G_DBUS_PROXY (foo_object_get_bat (FOO_OBJECT (op))); 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_PROXY (g_dbus_object_get_interface (op, "org.project.Bar")); + p = G_DBUS_PROXY (foo_object_get_bar (FOO_OBJECT (op))); 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)); @@ -2085,40 +2038,6 @@ check_object_manager (void) /* -------------------------------------------------- */ - /* check that the _GET_ and _PEEK_ macros work on the proxy side */ - op = g_dbus_object_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_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); - coyote_p = FOO_GET_COM_ACME_COYOTE (op); - g_assert (coyote_p == NULL); - coyote_p = FOO_PEEK_COM_ACME_COYOTE (op); - g_assert (coyote_p == NULL); - g_object_unref (op); - - /* Also, check that we warn on stderr in case the get_proxy_type() function is - * wrong etc. - */ - op = g_dbus_object_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)) - { - coyote_p = FOO_GET_COM_ACME_COYOTE (op); - } - g_test_trap_assert_stderr ("*runtime check failed: (G_TYPE_CHECK_INSTANCE_TYPE (ret, type))*"); - g_object_unref (op); - - /* -------------------------------------------------- */ - /* Now remove the second object added above */ g_dbus_object_manager_server_unexport (manager, "/managed/second"); /* ... check we get InterfacesRemoved with both interfaces */ diff --git a/gio/tests/test-codegen.xml b/gio/tests/test-codegen.xml index 162d850ab..84518a3fa 100644 --- a/gio/tests/test-codegen.xml +++ b/gio/tests/test-codegen.xml @@ -349,6 +349,9 @@ <signal name="BazSignal"/> </interface> + <!-- ChangingInterfaceV2: + @since: 2.0 + --> <interface name="ChangingInterfaceV2"> <!-- NewSignalIn2: @@ -370,6 +373,9 @@ <method name="FooMethod"/> </interface> + <!-- ChangingInterfaceV10: + @since: 10.0 + --> <interface name="ChangingInterfaceV10"> <!-- AddedSignalIn10: |