gdbus-codegen: Generate GDBusObject{,Proxy,Skeleton} subtypes

Signed-off-by: David Zeuthen <davidz@redhat.com>
This commit is contained in:
David Zeuthen 2011-04-25 09:29:18 -04:00
parent 58eb4da5c5
commit bbe945183b
19 changed files with 685 additions and 359 deletions

View File

@ -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>

View File

@ -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
@ -3395,6 +3396,47 @@ EXAMPLE_IS_CAT_SKELETON
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>

View File

@ -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

View File

@ -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>

View File

@ -93,6 +93,13 @@ class CodeGenerator:
'} _ExtendedGDBusPropertyInfo;\n'
'\n')
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'
@ -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,9 +496,96 @@ 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))
@ -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()

View File

@ -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

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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
*/

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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 */

View File

@ -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: