gdbus-codegen: Add --c-generate-object-manager option + doc improvements
authorDavid Zeuthen <davidz@redhat.com>
Tue, 12 Apr 2011 15:50:34 +0000 (11:50 -0400)
committerDavid Zeuthen <davidz@redhat.com>
Tue, 12 Apr 2011 15:50:34 +0000 (11:50 -0400)
Signed-off-by: David Zeuthen <davidz@redhat.com>
docs/reference/gio/Makefile.am
docs/reference/gio/gdbus-codegen.xml
docs/reference/gio/gio-docs.xml
docs/reference/gio/migrating-gdbus.xml
gio/gdbus-codegen/codegen.py
gio/gdbus-codegen/codegen_main.py
gio/tests/Makefile.am
gio/tests/gdbus-example-objectmanager.xml

index 6c522ee..70e5d74 100644 (file)
@@ -157,7 +157,9 @@ expand_content_files =              \
        migrating-posix.xml     \
        migrating-gnome-vfs.xml \
        migrating-gconf.xml     \
-       migrating-gdbus.xml
+       migrating-gdbus.xml     \
+       gdbus-codegen.xml       \
+       $(NULL)
 
 extra_files =                  \
        version.xml.in          \
index 9b0952a..50cf264 100644 (file)
@@ -8,15 +8,16 @@
 
 <refnamediv>
   <refname>gdbus-codegen</refname>
-  <refpurpose>GLib D-Bus code generator</refpurpose>
+  <refpurpose>GLib D-Bus code and documentation generator</refpurpose>
 </refnamediv>
 
 <refsynopsisdiv>
   <cmdsynopsis>
     <command>gdbus-codegen</command>
     <arg><option>--interface-prefix</option> <replaceable>org.project.Prefix</replaceable></arg>
-    <arg><option>--c-namespace</option> <replaceable>YourProject</replaceable></arg>
     <arg><option>--generate-c-code</option> <replaceable>OUTFILES</replaceable></arg>
+    <arg><option>--c-namespace</option> <replaceable>YourProject</replaceable></arg>
+    <arg><option>--c-generate-object-manager</option></arg>
     <arg><option>--generate-docbook</option> <replaceable>OUTFILES</replaceable></arg>
     <group choice="plain" rep="repeat">
       <arg>
   <para>
     <command>gdbus-codegen</command> is used to generate code and/or
     documentation for one or more D-Bus interfaces. The tool reads
-    D-Bus Introspection XML files and generates output files. The tool
-    currently supports generating C code (via
+    <ulink
+    url="http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format">D-Bus
+    Introspection XML</ulink> files and generates output files. The
+    tool currently supports generating C code (via
     <option>--generate-c-code</option>) and Docbook XML (via
     <option>--generate-docbook</option>).
   </para>
+</refsect1>
+
+<refsect1>
+  <title>Generating C code</title>
   <para>
     When generating C code, an abstract
-    <type>GInterface</type>-derived type is generated for each D-Bus
+    #GTypeInterface<!-- -->-derived type is generated for each D-Bus
     interface. Additionally, for every generated type,
     <type>FooBar</type>, two concrete instantiable types,
     <type>FooBarProxy</type> and <type>FooBarStub</type>, implementing
     said interface are also generated. The former is derived from
-    <type>GDBusProxy</type> and intended for use on the client side
+    #GDBusProxy and intended for use on the client side
     while the latter is derived from the
-    <type>GDBusInterfaceStub</type> type making it easy to export on a
-    <type>GDBusConnection</type> either directly or via a
-    <type>GDBusObjectManagerServer</type>.
+    #GDBusInterfaceStub type making it easy to export on a
+    #GDBusConnection either directly or via a
+    #GDBusObjectManagerServer instance.
+  </para>
+</refsect1>
+
+<refsect1>
+  <title>Generating Docbook documentation</title>
+  <para>
+    Each generated Docbook XML file (see the
+    <option>--generate-docbook</option> option for details) is a <ulink
+    url="http://www.docbook.org/tdg/en/html/refentry.html"><literal>RefEntry</literal></ulink>
+    article describing the D-Bus interface.
   </para>
 </refsect1>
 
       <listitem>
         <para>
           Generate Docbook Documentation for each D-Bus interface and
-          put it in
-          <filename>OUTFILES-org.Project.IfaceName.xml</filename> (where
-          <literal>org.Project.IfaceName</literal> is a place-holder for
-          the interface name).
+          put it in <filename>OUTFILES-NAME.xml</filename> where
+          <literal>NAME</literal> is a place-holder for the interface
+          name, e.g. <literal>net.Corp.FooBar</literal> and so on.
         </para>
       </listitem>
     </varlistentry>
     </varlistentry>
 
     <varlistentry>
+      <term><option>--c-generate-object-manager</option></term>
+      <listitem>
+        <para>
+          If this option is passed a #GDBusObjectManagerClient
+          subclass with an appropriate #GDBusProxyTypeFunc is
+          generated.
+        </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
       <term><option>--annotate</option></term>
       <listitem>
         <para>
@@ -192,7 +219,7 @@ gdbus-codegen --c-namespace MyApp                           \
       <term><literal>org.gtk.GDBus.C.ForceGVariant</literal></term>
       <listitem>
         <para>
-          If set to a non-empty string, a <type>GVariant</type> will
+          If set to a non-empty string, a #GVariant instance will
           be used instead of the natural C type. This annotation can
           be used on any <literal>&lt;arg&gt;</literal> and
           <literal>&lt;property&gt;</literal> element.
@@ -318,7 +345,7 @@ gdbus-codegen --generate-c-code myapp-generated       \
     two files called
     <filename>myapp-generated.[ch]</filename> are
     generated. The files provide an abstract
-    <type>GInterface</type>-derived type called
+    #GTypeInterface<!-- -->-derived type called
     <type>MyAppFrobber</type> as well as two instantiable types with
     the same name but suffixed with <type>Proxy</type> and
     <type>Stub</type>. The generated file, roughly, contains the
@@ -425,13 +452,13 @@ my_app_frobber_proxy_new_sync   (GDBusConnection     *connection,
 ]]></programlisting></informalexample>
   <para>
     Thus, for every D-Bus method, there will be three C functions for
-    calling the method, one <type>GObject</type> signal for handling
-    an incoming call and one C function for completing an incoming
-    call. For every D-Bus signal, there's one <type>GObject</type>
-    signal and one C function for emitting it. For every D-Bus
-    property, two C functions are generated (one setter, one getter)
-    and one <type>GObject</type> property. The following table
-    summarizes the generated facilities and where they are applicable:
+    calling the method, one #GObject signal for handling an incoming
+    call and one C function for completing an incoming call. For every
+    D-Bus signal, there's one #GObject signal and one C function for
+    emitting it. For every D-Bus property, two C functions are
+    generated (one setter, one getter) and one #GObject property. The
+    following table summarizes the generated facilities and where they
+    are applicable:
   </para>
   <informaltable>
     <tgroup cols="3">
@@ -461,12 +488,12 @@ my_app_frobber_proxy_new_sync   (GDBusConnection     *connection,
         <row>
           <entry>Properties (Reading)</entry>
           <entry>Use <function>m_a_f_get_verbose()</function> or <parameter>:verbose</parameter>.</entry>
-          <entry>Implement <type>GObject</type>'s <function>get_property()</function> vfunc.</entry>
+          <entry>Implement #GObject<!-- -->'s <function>get_property()</function> vfunc.</entry>
         </row>
         <row>
           <entry>Properties (writing)</entry>
           <entry>Use <function>m_a_f_set_verbose()</function> or <parameter>:verbose</parameter>.</entry>
-          <entry>Implement <type>GObject</type>'s <function>set_property()</function> vfunc.</entry>
+          <entry>Implement #GObject<!-- -->'s <function>set_property()</function> vfunc.</entry>
         </row>
       </tbody>
     </tgroup>
@@ -494,27 +521,26 @@ my_app_frobber_proxy_new_sync   (GDBusConnection     *connection,
     g_object_unref (proxy);
 ]]></programlisting></informalexample>
     <para>
-      Instead of using the generic <type>GDBusProxy</type> facilities,
-      one can use the generated methods such as
+      Instead of using the generic #GDBusProxy facilities, one can use
+      the generated methods such as
       <function>my_app_frobber_call_hello_world()</function> to invoke
       the <function>net.Corp.MyApp.Frobber.HelloWorld()</function>
       D-Bus method, connect to the the
       <function>::notification</function> GObject signal to receive
-      the <function>net.Corp.MyApp.Frobber::Notication</function> D-Bus
-      signal and get/set the
+      the <function>net.Corp.MyApp.Frobber::Notication</function>
+      D-Bus signal and get/set the
       <parameter>net.Corp.MyApp.Frobber:Verbose</parameter> D-Bus
       Property using either the GObject property
       <parameter>:verbose</parameter> or the
       <function>my_app_get_verbose()</function> and
       <function>my_app_set_verbose()</function> methods. Use the
-      standard <function>GObject::notify</function> signal to listen
-      to property changes.
+      standard #GObject::notify signal to listen to property changes.
     </para>
     <para>
-      Note that all property access is via <type>GDBusProxy</type>'s
+      Note that all property access is via #GDBusProxy<!-- -->'s
       property cache so no IO is ever done when reading properties.
-      Also note that setting a property will cause
-      <function>org.freedesktop.DBus.Properties.Set()</function> to be
+      Also note that setting a property will cause the
+      <ulink url="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties">org.freedesktop.DBus.Properties.Set</ulink> method to be
       called on the remote object. This call, however, is asynchronous
       so setting a property won't block. Further, the change is
       delayed and no error checking is possible.
@@ -525,27 +551,27 @@ my_app_frobber_proxy_new_sync   (GDBusConnection     *connection,
     <title>Server-side usage</title>
     <para>
       The generated <type>MyAppFrobber</type> interface is designed so
-      it is easy to implement it in a <type>GObject</type>
+      it is easy to implement it in a #GObject
       subclass. For example, to handle
       <function>HelloWorld()</function> method invocations, set the
       vfunc for <function>handle_hello_hello_world()</function> in the
       <type>MyAppFrobberIface</type> structure. Similary, to handle
       the <parameter>net.Corp.MyApp.Frobber:Verbose</parameter>
-      property override the <parameter>:verbose</parameter> GObject
+      property override the <parameter>:verbose</parameter> #GObject
       property from the subclass. To emit a signal, use
       e.g. <function>my_app_emit_signal()</function> or
-      <function>g_signal_emit_by_name()</function>.
+      g_signal_emit_by_name().
     </para>
     <para>
       Instead of subclassing, it is often easier to use the generated
       <type>MyAppFrobberStub</type> subclass. To handle incoming
       method calls, use <function>g_signal_connect()</function> with
       the <function>::handle-*</function> signals and instead of
-      overriding <type>GObject</type>'s
+      overriding #GObject<!-- -->'s
       <function>get_property()</function> and
       <function>set_property()</function> vfuncs, use
-      <function>g_object_get()</function> and
-      <function>g_object_set()</function> or the generated property
+      g_object_get() and
+      g_object_set() or the generated property
       getters and setters (the generated class has an internal
       property bag implementation).
     </para>
@@ -593,13 +619,13 @@ on_handle_hello_world (MyAppFrobber           *object,
 ]]></programlisting></informalexample>
     <para>
       To facility atomic changesets (multiple properties changing at
-      the same time), <function>GObject::notify</function> signals are
-      queued up when received. The queue is drained in an idle handler
-      and will cause emissions of the
-      <function>org.freedesktop.DBus.Properties::PropertiesChanged</function>
+      the same time), #GObject::notify signals are queued up when
+      received. The queue is drained in an idle handler and will cause
+      emissions of the <ulink
+      url="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties">org.freedesktop.DBus.Properties::PropertiesChanged</ulink>
       signal with all the properties that has changed. Use
-      <function>g_dbus_interface_stub_flush()</function> to empty the
-      queue immediately.
+      g_dbus_interface_stub_flush() or g_dbus_object_stub_flush() to
+      empty the queue immediately.
     </para>
   </refsect2>
 </refsect1>
@@ -607,24 +633,41 @@ on_handle_hello_world (MyAppFrobber           *object,
 <refsect1>
   <title>C Type Mapping</title>
   <para>
-    Scalar types, strings (including object paths (type-string
-    <literal>o</literal>), signatures (type-string
-    <literal>g</literal>) and bytestrings (type-string
-    <literal>ay</literal>)) and arrays of string (type-string
-    <literal>as</literal>) and arrays of bytestrings (type-string
-    <literal>aay</literal>) are mapped to the natural types,
-    e.g. <type>gboolean</type>, <type>gdouble</type>,
-    <type>gint</type>, <type>gchar*</type>, <type>gchar **</type> and
-    so on. Everything else is mapped to the <type>GVariant</type>
+    Scalar types
+    (type-strings
+    <link linkend="G-VARIANT-TYPE-BOOLEAN:CAPS">'b'</link>,
+    <link linkend="G-VARIANT-TYPE-BYTE:CAPS">'y'</link>,
+    <link linkend="G-VARIANT-TYPE-INT16:CAPS">'n'</link>,
+    <link linkend="G-VARIANT-TYPE-UINT16:CAPS">'q'</link>,
+    <link linkend="G-VARIANT-TYPE-INT32:CAPS">'i'</link>,
+    <link linkend="G-VARIANT-TYPE-UINT32:CAPS">'u'</link>,
+    <link linkend="G-VARIANT-TYPE-INT64:CAPS">'x'</link>,
+    <link linkend="G-VARIANT-TYPE-UINT64:CAPS">'t'</link>,
+    <link linkend="G-VARIANT-TYPE-HANDLE:CAPS">'h'</link> and
+    <link linkend="G-VARIANT-TYPE-DOUBLE:CAPS">'d'</link>)
+    ),
+    strings (type-strings
+    <link linkend="G-VARIANT-TYPE-STRING:CAPS">'s'</link>,
+    <link linkend="G-VARIANT-TYPE-BYTESTRING:CAPS">'ay'</link>,
+    <link linkend="G-VARIANT-TYPE-OBJECT-PATH:CAPS">'o'</link> and
+    <link linkend="G-VARIANT-TYPE-SIGNATURE:CAPS">'g'</link>) and
+    arrays of string (type-strings
+    <link linkend="G-VARIANT-TYPE-STRING-ARRAY:CAPS">'as'</link> and
+    <link linkend="G-VARIANT-TYPE-BYTESTRING-ARRAY:CAPS">'aay'</link>)
+    are mapped to the natural types,
+    e.g. #gboolean, #gdouble, #gint, <link linkend="gchararray">gchar*</link>,
+    <link linkend="GStrv">gchar**</link> and
+    so on. Everything else is mapped to the #GVariant
     type.
   </para>
   <para>
     This automatic mapping can be turned off by using the annotation
     <literal>org.gtk.GDBus.C.ForceGVariant</literal> - if used then a
-    <type>GVariant</type> is always exchanged instead of the
+    #GVariant is always exchanged instead of the
     corresponding native C type. This annotation may be convenient to
-    use when using the type-string <literal>ay</literal> for data with
-    embedded NUL bytes.
+    use when using
+    bytestrings (type-string <link linkend="G-VARIANT-TYPE-BYTESTRING:CAPS">'ay'</link>)
+    for data that could have embedded NUL bytes.
   </para>
 </refsect1>
 
@@ -648,7 +691,7 @@ on_handle_hello_world (MyAppFrobber           *object,
 <refsect1>
   <title>Author</title>
   <para>
-    Written by David Zeuthen <email>zeuthen@gmail.com</email> with
+    Written by David Zeuthen <email>zeuthen(at)gmail.com</email> with
     a lot of help from many others.
   </para>
 </refsect1>
index 4b90518..4a42fc4 100644 (file)
         <xi:include href="gsettings.xml"/>
         <xi:include href="glib-compile-schemas.xml"/>
         <xi:include href="gdbus.xml"/>
-        <xi:include href="gdbus-codegen.xml"/>
+        <xi:include href="xml/gdbus-codegen.xml"/>
     </chapter>
   </part>
 
index 770f5b1..ba2aa94 100644 (file)
@@ -238,7 +238,7 @@ on_name_acquired (GDBusConnection *connection,
   </section>
 
   <section id="gdbus-example-gdbus-codegen">
-    <title>Generating code with gdbus-codegen</title>
+    <title>Using gdbus-codegen</title>
 
     <para>
       dbus-glib comes with <command>dbus-binding-tool</command>, which
@@ -251,9 +251,10 @@ on_name_acquired (GDBusConnection *connection,
     <para>
       If this XML is processed like this
 <informalexample><programlisting><![CDATA[
-gdbus-codegen --c-namespace Example                                  \
-              --interface-prefix org.gtk.GDBus.Example.ObjectManager. \
+gdbus-codegen --interface-prefix org.gtk.GDBus.Example.ObjectManager. \
               --generate-c-code generated-code                       \
+              --c-namespace Example                                  \
+              --c-generate-object-manager                            \
               --generate-docbook generated-docs                       \
               gdbus-example-objectmanager.xml
 ]]></programlisting></informalexample>
index 5c67aeb..fbe2521 100644 (file)
@@ -10,7 +10,8 @@ import dbustypes
 # ----------------------------------------------------------------------------------------------------
 
 class CodeGenerator:
-    def __init__(self, ifaces, namespace, interface_prefix, h, c):
+    def __init__(self, ifaces, namespace, interface_prefix, generate_objmanager, h, c):
+        self.generate_objmanager = generate_objmanager
         self.ifaces = ifaces
         self.h = h
         self.c = c
@@ -417,79 +418,80 @@ class CodeGenerator:
             self.h.write('\n')
 
         # Finally, the proxy manager
-        self.h.write('\n')
-        self.h.write('/* ---- */\n')
-        self.h.write('\n')
-        self.h.write('#define %sTYPE_OBJECT_MANAGER_CLIENT (%sobject_manager_client_get_gtype ())\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))
-        self.h.write('#define %sOBJECT_MANAGER_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClientClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
-        self.h.write('#define %sIS_OBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_MANAGER_CLIENT))\n'%(self.ns_upper, self.ns_upper))
-        self.h.write('#define %sIS_OBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_MANAGER_CLIENT))\n'%(self.ns_upper, self.ns_upper))
-        self.h.write('\n')
-        self.h.write('typedef struct _%sObjectManagerClient %sObjectManagerClient;\n'%(self.namespace, self.namespace))
-        self.h.write('typedef struct _%sObjectManagerClientClass %sObjectManagerClientClass;\n'%(self.namespace, self.namespace))
-        self.h.write('typedef struct _%sObjectManagerClientPrivate %sObjectManagerClientPrivate;\n'%(self.namespace, self.namespace))
-        self.h.write('\n')
-        self.h.write('struct _%sObjectManagerClient\n'%(self.namespace))
-        self.h.write('{\n')
-        self.h.write('  GDBusObjectManagerClient parent_instance;\n')
-        self.h.write('  %sObjectManagerClientPrivate *priv;\n'%(self.namespace))
-        self.h.write('};\n')
-        self.h.write('\n')
-        self.h.write('struct _%sObjectManagerClientClass\n'%(self.namespace))
-        self.h.write('{\n')
-        self.h.write('  GDBusObjectManagerClientClass parent_class;\n')
-        self.h.write('};\n')
-        self.h.write('\n')
-        self.h.write('GType %sobject_manager_client_get_gtype (void) G_GNUC_CONST;\n'%(self.ns_lower))
-        self.h.write('\n')
-        self.h.write('GDBusProxyTypeFunc %sobject_manager_client_get_proxy_type_func (void);\n'%(self.ns_lower))
-        self.h.write('\n')
-        self.h.write('void %sobject_manager_client_new (\n'
-                     '    GDBusConnection        *connection,\n'
-                     '    GDBusObjectManagerClientFlags  flags,\n'
-                     '    const gchar            *name,\n'
-                     '    const gchar            *object_path,\n'
-                     '    GCancellable           *cancellable,\n'
-                     '    GAsyncReadyCallback     callback,\n'
-                     '    gpointer                user_data);\n'
-                     %(self.ns_lower))
-        self.h.write('GDBusObjectManager *%sobject_manager_client_new_finish (\n'
-                     '    GAsyncResult        *res,\n'
-                     '    GError             **error);\n'
-                     %(self.ns_lower))
-        self.h.write('GDBusObjectManager *%sobject_manager_client_new_sync (\n'
-                     '    GDBusConnection        *connection,\n'
-                     '    GDBusObjectManagerClientFlags  flags,\n'
-                     '    const gchar            *name,\n'
-                     '    const gchar            *object_path,\n'
-                     '    GCancellable           *cancellable,\n'
-                     '    GError                **error);\n'
-                     %(self.ns_lower))
-        self.h.write('\n')
-        self.h.write('void %sobject_manager_client_new_for_bus (\n'
-                     '    GBusType                bus_type,\n'
-                     '    GDBusObjectManagerClientFlags  flags,\n'
-                     '    const gchar            *name,\n'
-                     '    const gchar            *object_path,\n'
-                     '    GCancellable           *cancellable,\n'
-                     '    GAsyncReadyCallback     callback,\n'
-                     '    gpointer                user_data);\n'
-                     %(self.ns_lower))
-        self.h.write('GDBusObjectManager *%sobject_manager_client_new_for_bus_finish (\n'
-                     '    GAsyncResult        *res,\n'
-                     '    GError             **error);\n'
-                     %(self.ns_lower))
-        self.h.write('GDBusObjectManager *%sobject_manager_client_new_for_bus_sync (\n'
-                     '    GBusType                bus_type,\n'
-                     '    GDBusObjectManagerClientFlags  flags,\n'
-                     '    const gchar            *name,\n'
-                     '    const gchar            *object_path,\n'
-                     '    GCancellable           *cancellable,\n'
-                     '    GError                **error);\n'
-                     %(self.ns_lower))
-        self.h.write('\n')
+        if self.generate_objmanager:
+            self.h.write('\n')
+            self.h.write('/* ---- */\n')
+            self.h.write('\n')
+            self.h.write('#define %sTYPE_OBJECT_MANAGER_CLIENT (%sobject_manager_client_get_gtype ())\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))
+            self.h.write('#define %sOBJECT_MANAGER_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClientClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
+            self.h.write('#define %sIS_OBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_MANAGER_CLIENT))\n'%(self.ns_upper, self.ns_upper))
+            self.h.write('#define %sIS_OBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_MANAGER_CLIENT))\n'%(self.ns_upper, self.ns_upper))
+            self.h.write('\n')
+            self.h.write('typedef struct _%sObjectManagerClient %sObjectManagerClient;\n'%(self.namespace, self.namespace))
+            self.h.write('typedef struct _%sObjectManagerClientClass %sObjectManagerClientClass;\n'%(self.namespace, self.namespace))
+            self.h.write('typedef struct _%sObjectManagerClientPrivate %sObjectManagerClientPrivate;\n'%(self.namespace, self.namespace))
+            self.h.write('\n')
+            self.h.write('struct _%sObjectManagerClient\n'%(self.namespace))
+            self.h.write('{\n')
+            self.h.write('  GDBusObjectManagerClient parent_instance;\n')
+            self.h.write('  %sObjectManagerClientPrivate *priv;\n'%(self.namespace))
+            self.h.write('};\n')
+            self.h.write('\n')
+            self.h.write('struct _%sObjectManagerClientClass\n'%(self.namespace))
+            self.h.write('{\n')
+            self.h.write('  GDBusObjectManagerClientClass parent_class;\n')
+            self.h.write('};\n')
+            self.h.write('\n')
+            self.h.write('GType %sobject_manager_client_get_gtype (void) G_GNUC_CONST;\n'%(self.ns_lower))
+            self.h.write('\n')
+            self.h.write('GDBusProxyTypeFunc %sobject_manager_client_get_proxy_type_func (void);\n'%(self.ns_lower))
+            self.h.write('\n')
+            self.h.write('void %sobject_manager_client_new (\n'
+                         '    GDBusConnection        *connection,\n'
+                         '    GDBusObjectManagerClientFlags  flags,\n'
+                         '    const gchar            *name,\n'
+                         '    const gchar            *object_path,\n'
+                         '    GCancellable           *cancellable,\n'
+                         '    GAsyncReadyCallback     callback,\n'
+                         '    gpointer                user_data);\n'
+                         %(self.ns_lower))
+            self.h.write('GDBusObjectManager *%sobject_manager_client_new_finish (\n'
+                         '    GAsyncResult        *res,\n'
+                         '    GError             **error);\n'
+                         %(self.ns_lower))
+            self.h.write('GDBusObjectManager *%sobject_manager_client_new_sync (\n'
+                         '    GDBusConnection        *connection,\n'
+                         '    GDBusObjectManagerClientFlags  flags,\n'
+                         '    const gchar            *name,\n'
+                         '    const gchar            *object_path,\n'
+                         '    GCancellable           *cancellable,\n'
+                         '    GError                **error);\n'
+                         %(self.ns_lower))
+            self.h.write('\n')
+            self.h.write('void %sobject_manager_client_new_for_bus (\n'
+                         '    GBusType                bus_type,\n'
+                         '    GDBusObjectManagerClientFlags  flags,\n'
+                         '    const gchar            *name,\n'
+                         '    const gchar            *object_path,\n'
+                         '    GCancellable           *cancellable,\n'
+                         '    GAsyncReadyCallback     callback,\n'
+                         '    gpointer                user_data);\n'
+                         %(self.ns_lower))
+            self.h.write('GDBusObjectManager *%sobject_manager_client_new_for_bus_finish (\n'
+                         '    GAsyncResult        *res,\n'
+                         '    GError             **error);\n'
+                         %(self.ns_lower))
+            self.h.write('GDBusObjectManager *%sobject_manager_client_new_for_bus_sync (\n'
+                         '    GBusType                bus_type,\n'
+                         '    GDBusObjectManagerClientFlags  flags,\n'
+                         '    const gchar            *name,\n'
+                         '    const gchar            *object_path,\n'
+                         '    GCancellable           *cancellable,\n'
+                         '    GError                **error);\n'
+                         %(self.ns_lower))
+            self.h.write('\n')
 
     # ----------------------------------------------------------------------------------------------------
 
@@ -1915,5 +1917,6 @@ class CodeGenerator:
             self.generate_method_completers(i)
             self.generate_proxy(i)
             self.generate_stub(i)
-        self.generate_object_manager_client()
+        if self.generate_objmanager:
+            self.generate_object_manager_client()
         self.generate_outro()
index 9ab2d1f..45567fd 100644 (file)
@@ -132,6 +132,8 @@ def codegen_main():
                             help='String to strip from D-Bus interface names for code and docs')
     arg_parser.add_argument('--c-namespace', nargs='?', metavar='NAMESPACE', default='',
                             help='The namespace to use for generated C code')
+    arg_parser.add_argument('--c-generate-object-manager', action='store_true',
+                            help='Generate a GDBusObjectManagerClient subclass when generating C code')
     arg_parser.add_argument('--generate-c-code', nargs='?', metavar='OUTFILES',
                             help='Generate C code in OUTFILES.[ch]')
     arg_parser.add_argument('--generate-docbook', nargs='?', metavar='OUTFILES',
@@ -154,10 +156,15 @@ def codegen_main():
         i.post_process(args.interface_prefix, args.c_namespace)
 
     c_code = args.generate_c_code
+    print "args.c_generate_object_manager=", args.c_generate_object_manager
     if c_code:
         h = file(c_code + '.h', 'w')
         c = file(c_code + '.c', 'w')
-        gen = codegen.CodeGenerator(all_ifaces, args.c_namespace, args.interface_prefix, h, c);
+        gen = codegen.CodeGenerator(all_ifaces,
+                                    args.c_namespace,
+                                    args.interface_prefix,
+                                    args.c_generate_object_manager,
+                                    h, c);
         ret = gen.generate()
 
     docbook = args.generate_docbook
index be16488..998faaa 100644 (file)
@@ -242,9 +242,10 @@ gdbus_bz627724_LDADD = $(progs_ldadd)
 
 gdbus-test-codegen-generated.h gdbus-test-codegen-generated.c : test-codegen.xml
        $(PYTHON) $(top_srcdir)/gio/gdbus-codegen/codegen_main.py                                       \
-               --c-namespace Foo                                                                       \
                --interface-prefix org.project.                                                         \
                --generate-c-code gdbus-test-codegen-generated                                          \
+               --c-generate-object-manager                                                             \
+               --c-namespace Foo                                                                       \
                --generate-docbook gdbus-test-codegen-generated-doc                                     \
                --annotate "org.project.Bar" Key1 Value1                                                \
                --annotate "org.project.Bar" org.gtk.GDBus.Internal Value2                              \
@@ -443,8 +444,9 @@ proxy_LDADD   = $(progs_ldadd) \
 
 gdbus-example-objectmanager-generated.h gdbus-example-objectmanager-generated.c : gdbus-example-objectmanager.xml
        $(PYTHON) $(top_srcdir)/gio/gdbus-codegen/codegen_main.py               \
-               --c-namespace Example                                           \
                --interface-prefix org.gtk.GDBus.Example.ObjectManager.         \
+               --c-namespace Example                                           \
+               --c-generate-object-manager                                     \
                --generate-c-code gdbus-example-objectmanager-generated         \
                --generate-docbook gdbus-example-objectmanager-generated        \
                gdbus-example-objectmanager.xml                                 \
index 4e00c22..1ce7a11 100644 (file)
@@ -44,7 +44,7 @@
   </interface>
 
   <!-- org.gtk.GDBus.Example.ObjectManager.Cat:
-       @short_description: Another interface doc generated by gdbus-codegen
+       @short_description: More example docs generated by gdbus-codegen
 
        This D-Bus interface is used to describe a cat. Right now there
        are no properties, methods or signals associated with this