dbus-tutorial: replace the entire GLib section with "use GDBus"
authorSimon McVittie <simon.mcvittie@collabora.co.uk>
Wed, 10 Sep 2014 12:53:39 +0000 (13:53 +0100)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Wed, 29 Oct 2014 14:15:53 +0000 (14:15 +0000)
Also provide links to relevant GLib and Qt documentation.

Bug: https://bugs.freedesktop.org/show_bug.cgi?id=25140

doc/dbus-tutorial.xml

index 3d14e5f..c4d9504 100644 (file)
   </sect1>
 
   <sect1 id="glib-client">
-    <title>GLib API: Using Remote Objects</title>
-
-    <para>
-      The GLib binding is defined in the header file
-      <literal>&lt;dbus/dbus-glib.h&gt;</literal>.
-    </para>
-
-    <sect2 id="glib-typemappings">
-      <title>D-Bus - GLib type mappings</title>
-      <para>
-       The heart of the GLib bindings for D-Bus is the mapping it
-       provides between D-Bus "type signatures" and GLib types
-       (<literal>GType</literal>). The D-Bus type system is composed of
-       a number of "basic" types, along with several "container" types.
-      </para>
-      <sect3 id="glib-basic-typemappings">
-       <title>Basic type mappings</title>
-       <para>
-         Below is a list of the basic types, along with their associated
-         mapping to a <literal>GType</literal>.
-         <informaltable>
-           <tgroup cols="4">
-             <thead>
-               <row>
-                 <entry>D-Bus basic type</entry>
-                 <entry>GType</entry>
-                 <entry>Free function</entry>
-                 <entry>Notes</entry>
-               </row>
-             </thead>
-             <tbody>
-               <row>
-                 <entry><literal>BYTE</literal></entry>
-                 <entry><literal>G_TYPE_UCHAR</literal></entry>
-                 <entry></entry>
-                 <entry></entry>
-                 </row><row>
-                 <entry><literal>BOOLEAN</literal></entry>
-                 <entry><literal>G_TYPE_BOOLEAN</literal></entry>
-                 <entry></entry>
-                 <entry></entry>
-                 </row><row>
-                 <entry><literal>INT16</literal></entry>
-                 <entry><literal>G_TYPE_INT</literal></entry>
-                 <entry></entry>
-                 <entry>Will be changed to a <literal>G_TYPE_INT16</literal> once GLib has it</entry>
-                 </row><row>
-                 <entry><literal>UINT16</literal></entry>
-                 <entry><literal>G_TYPE_UINT</literal></entry>
-                 <entry></entry>
-                 <entry>Will be changed to a <literal>G_TYPE_UINT16</literal> once GLib has it</entry>
-                 </row><row>
-                 <entry><literal>INT32</literal></entry>
-                 <entry><literal>G_TYPE_INT</literal></entry>
-                 <entry></entry>
-                 <entry>Will be changed to a <literal>G_TYPE_INT32</literal> once GLib has it</entry>
-                 </row><row>
-                 <entry><literal>UINT32</literal></entry>
-                 <entry><literal>G_TYPE_UINT</literal></entry>
-                 <entry></entry>
-                 <entry>Will be changed to a <literal>G_TYPE_UINT32</literal> once GLib has it</entry>
-                 </row><row>
-                 <entry><literal>INT64</literal></entry>
-                 <entry><literal>G_TYPE_GINT64</literal></entry>
-                 <entry></entry>
-                 <entry></entry>
-                 </row><row>
-                 <entry><literal>UINT64</literal></entry>
-                 <entry><literal>G_TYPE_GUINT64</literal></entry>
-                 <entry></entry>
-                 <entry></entry>
-                 </row><row>
-                 <entry><literal>DOUBLE</literal></entry>
-                 <entry><literal>G_TYPE_DOUBLE</literal></entry>
-                 <entry></entry>
-                 <entry></entry>
-                 </row><row>
-                 <entry><literal>STRING</literal></entry>
-                 <entry><literal>G_TYPE_STRING</literal></entry>
-                 <entry><literal>g_free</literal></entry>
-                 <entry></entry>
-                 </row><row>
-                 <entry><literal>OBJECT_PATH</literal></entry>
-                 <entry><literal>DBUS_TYPE_G_PROXY</literal></entry>
-                 <entry><literal>g_object_unref</literal></entry>
-                 <entry>The returned proxy does not have an interface set; use <literal>dbus_g_proxy_set_interface</literal> to invoke methods</entry>
-               </row>
-             </tbody>
-           </tgroup>
-         </informaltable>
-         As you can see, the basic mapping is fairly straightforward.
-       </para>
-      </sect3>
-      <sect3 id="glib-container-typemappings">
-       <title>Container type mappings</title>
-       <para>
-         The D-Bus type system also has a number of "container"
-         types, such as <literal>DBUS_TYPE_ARRAY</literal> and
-         <literal>DBUS_TYPE_STRUCT</literal>.  The D-Bus type system
-         is fully recursive, so one can for example have an array of
-         array of strings (i.e. type signature
-         <literal>aas</literal>).
-       </para>
-       <para>
-         However, not all of these types are in common use; for
-         example, at the time of this writing the author knows of no
-         one using <literal>DBUS_TYPE_STRUCT</literal>, or a
-         <literal>DBUS_TYPE_ARRAY</literal> containing any non-basic
-         type.  The approach the GLib bindings take is pragmatic; try
-         to map the most common types in the most obvious way, and
-         let using less common and more complex types be less
-         "natural".
-       </para>
-       <para>
-         First, D-Bus type signatures which have an "obvious"
-         corresponding built-in GLib type are mapped using that type:
-         <informaltable>
-           <tgroup cols="6">
-             <thead>
-               <row>
-                 <entry>D-Bus type signature</entry>
-                 <entry>Description</entry>
-                 <entry>GType</entry>
-                 <entry>C typedef</entry>
-                 <entry>Free function</entry>
-                 <entry>Notes</entry>
-               </row>
-             </thead>
-             <tbody>
-               <row>
-                 <entry><literal>as</literal></entry>
-                 <entry>Array of strings</entry>
-                 <entry><literal>G_TYPE_STRV</literal></entry>
-                 <entry><literal>char **</literal></entry>
-                 <entry><literal>g_strfreev</literal></entry>
-                 <entry></entry>
-                 </row><row>
-                 <entry><literal>v</literal></entry>
-                 <entry>Generic value container</entry>
-                 <entry><literal>G_TYPE_VALUE</literal></entry>
-                 <entry><literal>GValue *</literal></entry>
-                 <entry><literal>g_value_unset</literal></entry>
-                 <entry>The calling conventions for values expect that method callers have allocated return values; see below.</entry>
-               </row>
-             </tbody>
-           </tgroup>
-         </informaltable>
-       </para>
-       <para>
-         The next most common recursive type signatures are arrays of
-         basic values.  The most obvious mapping for arrays of basic
-         types is a <literal>GArray</literal>.  Now, GLib does not
-         provide a builtin <literal>GType</literal> for
-         <literal>GArray</literal>.  However, we actually need more than
-         that - we need a "parameterized" type which includes the
-         contained type.  Why we need this we will see below.
-       </para>
-       <para>
-         The approach taken is to create these types in the D-Bus GLib
-         bindings; however, there is nothing D-Bus specific about them.
-         In the future, we hope to include such "fundamental" types in GLib
-         itself.
-         <informaltable>
-           <tgroup cols="6">
-             <thead>
-               <row>
-                 <entry>D-Bus type signature</entry>
-                 <entry>Description</entry>
-                 <entry>GType</entry>
-                 <entry>C typedef</entry>
-                 <entry>Free function</entry>
-                 <entry>Notes</entry>
-               </row>
-             </thead>
-             <tbody>
-               <row>
-                 <entry><literal>ay</literal></entry>
-                 <entry>Array of bytes</entry>
-                 <entry><literal>DBUS_TYPE_G_UCHAR_ARRAY</literal></entry>
-                 <entry><literal>GArray *</literal></entry>
-                 <entry>g_array_free</entry>
-                 <entry></entry>
-               </row>
-               <row>
-                 <entry><literal>au</literal></entry>
-                 <entry>Array of uint</entry>
-                 <entry><literal>DBUS_TYPE_G_UINT_ARRAY</literal></entry>
-                 <entry><literal>GArray *</literal></entry>
-                 <entry>g_array_free</entry>
-                 <entry></entry>
-               </row>
-               <row>
-                 <entry><literal>ai</literal></entry>
-                 <entry>Array of int</entry>
-                 <entry><literal>DBUS_TYPE_G_INT_ARRAY</literal></entry>
-                 <entry><literal>GArray *</literal></entry>
-                 <entry>g_array_free</entry>
-                 <entry></entry>
-               </row>
-               <row>
-                 <entry><literal>ax</literal></entry>
-                 <entry>Array of int64</entry>
-                 <entry><literal>DBUS_TYPE_G_INT64_ARRAY</literal></entry>
-                 <entry><literal>GArray *</literal></entry>
-                 <entry>g_array_free</entry>
-                 <entry></entry>
-               </row>
-               <row>
-                 <entry><literal>at</literal></entry>
-                 <entry>Array of uint64</entry>
-                 <entry><literal>DBUS_TYPE_G_UINT64_ARRAY</literal></entry>
-                 <entry><literal>GArray *</literal></entry>
-                 <entry>g_array_free</entry>
-                 <entry></entry>
-               </row>
-               <row>
-                 <entry><literal>ad</literal></entry>
-                 <entry>Array of double</entry>
-                 <entry><literal>DBUS_TYPE_G_DOUBLE_ARRAY</literal></entry>
-                 <entry><literal>GArray *</literal></entry>
-                 <entry>g_array_free</entry>
-                 <entry></entry>
-               </row>
-               <row>
-                 <entry><literal>ab</literal></entry>
-                 <entry>Array of boolean</entry>
-                 <entry><literal>DBUS_TYPE_G_BOOLEAN_ARRAY</literal></entry>
-                 <entry><literal>GArray *</literal></entry>
-                 <entry>g_array_free</entry>
-                 <entry></entry>
-               </row>
-             </tbody>
-           </tgroup>
-         </informaltable>
-       </para>
-       <para>
-         D-Bus also includes a special type DBUS_TYPE_DICT_ENTRY which
-         is only valid in arrays.  It's intended to be mapped to a "dictionary"
-         type by bindings.  The obvious GLib mapping here is GHashTable.  Again,
-         however, there is no builtin <literal>GType</literal> for a GHashTable.
-         Moreover, just like for arrays, we need a parameterized type so that
-         the bindings can communiate which types are contained in the hash table.
-       </para>
-       <para>
-         At present, only strings are supported.  Work is in progress to
-         include more types.
-         <informaltable>
-           <tgroup cols="6">
-             <thead>
-               <row>
-                 <entry>D-Bus type signature</entry>
-                 <entry>Description</entry>
-                 <entry>GType</entry>
-                 <entry>C typedef</entry>
-                 <entry>Free function</entry>
-                 <entry>Notes</entry>
-               </row>
-             </thead>
-             <tbody>
-               <row>
-                 <entry><literal>a{ss}</literal></entry>
-                 <entry>Dictionary mapping strings to strings</entry>
-                 <entry><literal>DBUS_TYPE_G_STRING_STRING_HASHTABLE</literal></entry>
-                 <entry><literal>GHashTable *</literal></entry>
-                 <entry>g_hash_table_destroy</entry>
-                 <entry></entry>
-               </row>
-             </tbody>
-           </tgroup>
-         </informaltable>
-       </para>
-      </sect3>
-      <sect3 id="glib-generic-typemappings">
-       <title>Arbitrarily recursive type mappings</title>
-       <para>
-         Finally, it is possible users will want to write or invoke D-Bus
-         methods which have arbitrarily complex type signatures not
-         directly supported by these bindings.  For this case, we have a
-         <literal>DBusGValue</literal> which acts as a kind of special
-         variant value which may be iterated over manually.  The
-         <literal>GType</literal> associated is
-         <literal>DBUS_TYPE_G_VALUE</literal>.
-       </para>
-       <para>
-         TODO insert usage of <literal>DBUS_TYPE_G_VALUE</literal> here.
-       </para>
-      </sect3>
-    </sect2>
-    <sect2 id="sample-program-1">
-      <title>A sample program</title>
-      <para>Here is a D-Bus program using the GLib bindings.
-<programlisting>      
-int
-main (int argc, char **argv)
-{
-  DBusGConnection *connection;
-  GError *error;
-  DBusGProxy *proxy;
-  char **name_list;
-  char **name_list_ptr;
-  
-  g_type_init ();
-
-  error = NULL;
-  connection = dbus_g_bus_get (DBUS_BUS_SESSION,
-                               &amp;error);
-  if (connection == NULL)
-    {
-      g_printerr ("Failed to open connection to bus: %s\n",
-                  error-&gt;message);
-      g_error_free (error);
-      exit (1);
-    }
-
-  /* Create a proxy object for the "bus driver" (name "org.freedesktop.DBus") */
-  
-  proxy = dbus_g_proxy_new_for_name (connection,
-                                     DBUS_SERVICE_DBUS,
-                                     DBUS_PATH_DBUS,
-                                     DBUS_INTERFACE_DBUS);
-
-  /* Call ListNames method, wait for reply */
-  error = NULL;
-  if (!dbus_g_proxy_call (proxy, "ListNames", &amp;error, G_TYPE_INVALID,
-                          G_TYPE_STRV, &amp;name_list, G_TYPE_INVALID))
-    {
-      /* Just do demonstrate remote exceptions versus regular GError */
-      if (error->domain == DBUS_GERROR &amp;&amp; error->code == DBUS_GERROR_REMOTE_EXCEPTION)
-        g_printerr ("Caught remote method exception %s: %s",
-                   dbus_g_error_get_name (error),
-                   error-&gt;message);
-      else
-        g_printerr ("Error: %s\n", error-&gt;message);
-      g_error_free (error);
-      exit (1);
-    }
-
-  /* Print the results */
-  g_print ("Names on the message bus:\n");
-  
-  for (name_list_ptr = name_list; *name_list_ptr; name_list_ptr++)
-    {
-      g_print ("  %s\n", *name_list_ptr);
-    }
-  g_strfreev (name_list);
-
-  g_object_unref (proxy);
-
-  return 0;
-}
-</programlisting>
-    </para>
-    </sect2>
-    <sect2 id="glib-program-setup">
-      <title>Program initalization</title>
-      <para>
-       A connection to the bus is acquired using
-       <literal>dbus_g_bus_get</literal>.  Next, a proxy
-       is created for the object "/org/freedesktop/DBus" with
-       interface <literal>org.freedesktop.DBus</literal>
-       on the service <literal>org.freedesktop.DBus</literal>.
-       This is a proxy for the message bus itself.
-      </para>
-    </sect2>
-    <sect2 id="glib-method-invocation">
-      <title>Understanding method invocation</title>
-      <para>
-       You have a number of choices for method invocation.  First, as
-       used above, <literal>dbus_g_proxy_call</literal> sends a
-       method call to the remote object, and blocks until a reply is
-       recieved.  The outgoing arguments are specified in the varargs
-       array, terminated with <literal>G_TYPE_INVALID</literal>.
-       Next, pointers to return values are specified, followed again
-       by <literal>G_TYPE_INVALID</literal>.
-      </para>
-      <para>
-       To invoke a method asynchronously, use
-       <literal>dbus_g_proxy_begin_call</literal>.  This returns a
-       <literal>DBusGPendingCall</literal> object; you may then set a
-       notification function using
-       <literal>dbus_g_pending_call_set_notify</literal>.
-      </para>
-    </sect2>
-    <sect2 id="glib-signal-connection">
-      <title>Connecting to object signals</title>
-      <para>
-       You may connect to signals using
-       <literal>dbus_g_proxy_add_signal</literal> and
-       <literal>dbus_g_proxy_connect_signal</literal>.  You must
-       invoke <literal>dbus_g_proxy_add_signal</literal> to specify
-       the signature of your signal handlers; you may then invoke
-       <literal>dbus_g_proxy_connect_signal</literal> multiple times.
-      </para>
-      <para>
-       Note that it will often be the case that there is no builtin
-       marshaller for the type signature of a remote signal.  In that
-       case, you must generate a marshaller yourself by using
-       <application>glib-genmarshal</application>, and then register
-       it using <literal>dbus_g_object_register_marshaller</literal>.
-      </para>
-    </sect2>
-    <sect2 id="glib-error-handling">
-      <title>Error handling and remote exceptions</title>
-      <para>
-       All of the GLib binding methods such as
-       <literal>dbus_g_proxy_end_call</literal> return a
-       <literal>GError</literal>.  This <literal>GError</literal> can
-       represent two different things:
-      <itemizedlist>
-       <listitem>
-         <para>
-           An internal D-Bus error, such as an out-of-memory
-           condition, an I/O error, or a network timeout.  Errors
-           generated by the D-Bus library itself have the domain
-           <literal>DBUS_GERROR</literal>, and a corresponding code
-           such as <literal>DBUS_GERROR_NO_MEMORY</literal>.  It will
-           not be typical for applications to handle these errors
-           specifically.
-         </para>
-       </listitem>
-       <listitem>
-         <para>
-           A remote D-Bus exception, thrown by the peer, bus, or
-           service.  D-Bus remote exceptions have both a textual
-           "name" and a "message".  The GLib bindings store this
-           information in the <literal>GError</literal>, but some
-           special rules apply.
-         </para>
-         <para>
-           The set error will have the domain
-           <literal>DBUS_GERROR</literal> as above, and will also
-           have the code
-           <literal>DBUS_GERROR_REMOTE_EXCEPTION</literal>.  In order
-           to access the remote exception name, you must use a
-           special accessor, such as
-           <literal>dbus_g_error_has_name</literal> or
-           <literal>dbus_g_error_get_name</literal>.  The remote
-           exception detailed message is accessible via the regular
-           GError <literal>message</literal> member.
-         </para>
-       </listitem>
-      </itemizedlist>
-      </para>
-    </sect2>
-    <sect2 id="glib-more-examples">
-      <title>More examples of method invocation</title>
-      <sect3 id="glib-sending-stuff">
-       <title>Sending an integer and string, receiving an array of bytes</title>
-       <para>
-<programlisting>
-  GArray *arr;
-  
-  error = NULL;
-  if (!dbus_g_proxy_call (proxy, "Foobar", &amp;error,
-                          G_TYPE_INT, 42, G_TYPE_STRING, "hello",
-                         G_TYPE_INVALID,
-                         DBUS_TYPE_G_UCHAR_ARRAY, &amp;arr, G_TYPE_INVALID))
-    {
-      /* Handle error */
-    }
-   g_assert (arr != NULL);
-   printf ("got back %u values", arr->len);
-</programlisting>
-       </para>
-      </sect3>
-      <sect3 id="glib-sending-hash">
-       <title>Sending a GHashTable</title>
-       <para>
-<programlisting>
-  GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal);
-  guint32 ret;
-  
-  g_hash_table_insert (hash, "foo", "bar");
-  g_hash_table_insert (hash, "baz", "whee");
-
-  error = NULL;
-  if (!dbus_g_proxy_call (proxy, "HashSize", &amp;error,
-                          DBUS_TYPE_G_STRING_STRING_HASH, hash, G_TYPE_INVALID,
-                         G_TYPE_UINT, &amp;ret, G_TYPE_INVALID))
-    {
-      /* Handle error */
-    }
-  g_assert (ret == 2);
-  g_hash_table_destroy (hash);
-</programlisting>
-       </para>
-      </sect3>
-      <sect3 id="glib-receiving-bool-int">
-       <title>Receiving a boolean and a string</title>
-       <para>
-<programlisting>
-  gboolean boolret;
-  char *strret;
-  
-  error = NULL;
-  if (!dbus_g_proxy_call (proxy, "GetStuff", &amp;error,
-                         G_TYPE_INVALID,
-                          G_TYPE_BOOLEAN, &amp;boolret,
-                          G_TYPE_STRING, &amp;strret,
-                         G_TYPE_INVALID))
-    {
-      /* Handle error */
-    }
-  printf ("%s %s", boolret ? "TRUE" : "FALSE", strret);
-  g_free (strret);
-</programlisting>
-       </para>
-      </sect3>
-      <sect3 id="glib-sending-str-arrays">
-       <title>Sending two arrays of strings</title>
-       <para>
-<programlisting>
-  /* NULL terminate */
-  char *strs_static[] = {"foo", "bar", "baz", NULL};
-  /* Take pointer to array; cannot pass array directly */
-  char **strs_static_p = strs_static;
-  char **strs_dynamic;
-
-  strs_dynamic = g_new (char *, 4);
-  strs_dynamic[0] = g_strdup ("hello");
-  strs_dynamic[1] = g_strdup ("world");
-  strs_dynamic[2] = g_strdup ("!");
-  /* NULL terminate */
-  strs_dynamic[3] = NULL;
-  
-  error = NULL;
-  if (!dbus_g_proxy_call (proxy, "TwoStrArrays", &amp;error,
-                          G_TYPE_STRV, strs_static_p,
-                          G_TYPE_STRV, strs_dynamic,
-                         G_TYPE_INVALID,
-                         G_TYPE_INVALID))
-    {
-      /* Handle error */
-    }
-   g_strfreev (strs_dynamic);
-</programlisting>
-       </para>
-      </sect3>
-      <sect3 id="glib-getting-str-array">
-       <title>Sending a boolean, receiving an array of strings</title>
-       <para>
-<programlisting>
-  char **strs;
-  char **strs_p;
-  gboolean blah;
-
-  error = NULL;
-  blah = TRUE;
-  if (!dbus_g_proxy_call (proxy, "GetStrs", &amp;error,
-                          G_TYPE_BOOLEAN, blah,
-                         G_TYPE_INVALID,
-                          G_TYPE_STRV, &amp;strs,
-                         G_TYPE_INVALID))
-    {
-      /* Handle error */
-    }
-   for (strs_p = strs; *strs_p; strs_p++)
-     printf ("got string: \"%s\"", *strs_p);
-   g_strfreev (strs);
-</programlisting>
-       </para>
-      </sect3>
-      <sect3 id="glib-sending-variant">
-       <title>Sending a variant</title>
-       <para>
-<programlisting>
-  GValue val = {0, };
-
-  g_value_init (&amp;val, G_TYPE_STRING);
-  g_value_set_string (&amp;val, "hello world");
-  
-  error = NULL;
-  if (!dbus_g_proxy_call (proxy, "SendVariant", &amp;error,
-                          G_TYPE_VALUE, &amp;val, G_TYPE_INVALID,
-                         G_TYPE_INVALID))
-    {
-      /* Handle error */
-    }
-  g_assert (ret == 2);
-  g_value_unset (&amp;val);
-</programlisting>
-       </para>
-      </sect3>
-      <sect3 id="glib-receiving-variant">
-       <title>Receiving a variant</title>
-       <para>
-<programlisting>
-  GValue val = {0, };
-
-  error = NULL;
-  if (!dbus_g_proxy_call (proxy, "GetVariant", &amp;error, G_TYPE_INVALID,
-                          G_TYPE_VALUE, &amp;val, G_TYPE_INVALID))
-    {
-      /* Handle error */
-    }
-  if (G_VALUE_TYPE (&amp;val) == G_TYPE_STRING)
-    printf ("%s\n", g_value_get_string (&amp;val));
-  else if (G_VALUE_TYPE (&amp;val) == G_TYPE_INT)
-    printf ("%d\n", g_value_get_int (&amp;val));
-  else
-    ...
-  g_value_unset (&amp;val);
-</programlisting>
-       </para>
-      </sect3>
-    </sect2>
-
-    <sect2 id="glib-generated-bindings">
-      <title>Generated Bindings</title>
-      <para>
-        By using the Introspection XML files, convenient client-side bindings
-        can be automatically created to ease the use of a remote DBus object.
-      </para>
-      <para>
-        Here is a sample XML file which describes an object that exposes
-        one method, named <literal>ManyArgs</literal>.
-        <programlisting>
-&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
-&lt;node name="/com/example/MyObject"&gt;
-  &lt;interface name="com.example.MyObject"&gt;
-    &lt;method name="ManyArgs"&gt;
-      &lt;arg type="u" name="x" direction="in" /&gt;
-      &lt;arg type="s" name="str" direction="in" /&gt;
-      &lt;arg type="d" name="trouble" direction="in" /&gt;
-      &lt;arg type="d" name="d_ret" direction="out" /&gt;
-      &lt;arg type="s" name="str_ret" direction="out" /&gt;
-    &lt;/method&gt;
-  &lt;/interface&gt;
-&lt;/node&gt;
-</programlisting>
-      </para>
-      <para>
-        Run <literal>dbus-binding-tool --mode=glib-client
-          <replaceable>FILENAME</replaceable> &gt;
-          <replaceable>HEADER_NAME</replaceable></literal> to generate the header
-        file.  For example: <command>dbus-binding-tool --mode=glib-client
-          my-object.xml &gt; my-object-bindings.h</command>.  This will generate
-        inline functions with the following prototypes:
-        <programlisting>
-/* This is a blocking call */
-gboolean
-com_example_MyObject_many_args (DBusGProxy *proxy, const guint IN_x,
-                                const char * IN_str, const gdouble IN_trouble,
-                                gdouble* OUT_d_ret, char ** OUT_str_ret,
-                                GError **error);
-
-/* This is a non-blocking call */
-DBusGProxyCall*
-com_example_MyObject_many_args_async (DBusGProxy *proxy, const guint IN_x,
-                                      const char * IN_str, const gdouble IN_trouble,
-                                      com_example_MyObject_many_args_reply callback,
-                                      gpointer userdata);
-
-/* This is the typedef for the non-blocking callback */
-typedef void
-(*com_example_MyObject_many_args_reply)
-(DBusGProxy *proxy, gdouble OUT_d_ret, char * OUT_str_ret,
- GError *error, gpointer userdata);
-</programlisting>
-        The first argument in all functions is a <literal>DBusGProxy
-        *</literal>, which you should create with the usual
-        <literal>dbus_g_proxy_new_*</literal> functions.  Following that are the
-        "in" arguments, and then either the "out" arguments and a
-        <literal>GError *</literal> for the synchronous (blocking) function, or
-        callback and user data arguments for the asynchronous (non-blocking)
-        function.  The callback in the asynchronous function passes the
-        <literal>DBusGProxy *</literal>, the returned "out" arguments, an
-        <literal>GError *</literal> which is set if there was an error otherwise
-        <literal>NULL</literal>, and the user data.
-      </para>
-      <para>
-        As with the server-side bindings support (see <xref
-        linkend="glib-server"/>), the exact behaviour of the client-side
-        bindings can be manipulated using "annotations".  Currently the only
-        annotation used by the client bindings is
-        <literal>org.freedesktop.DBus.GLib.NoReply</literal>, which sets the
-        flag indicating that the client isn't expecting a reply to the method
-        call, so a reply shouldn't be sent.  This is often used to speed up
-        rapid method calls where there are no "out" arguments, and not knowing
-        if the method succeeded is an acceptable compromise to half the traffic
-        on the bus.
-      </para>
-    </sect2>
-  </sect1>
-
-  <sect1 id="glib-server">
-    <title>GLib API: Implementing Objects</title>
+    <title>GLib APIs</title>
     <para>
-      At the moment, to expose a GObject via D-Bus, you must
-      write XML by hand which describes the methods exported
-      by the object.  In the future, this manual step will
-      be obviated by the upcoming GLib introspection support.
+      The recommended GLib API for D-Bus is GDBus, which has been
+      distributed with GLib since version 2.26. It is not documented here.
+      See <ulink url="https://developer.gnome.org/gio/stable/gdbus-convenience.html">the
+        GLib documentation</ulink> for details of how to use GDBus.
     </para>
-    <para>
-      Here is a sample XML file which describes an object that exposes
-      one method, named <literal>ManyArgs</literal>.
-<programlisting>
-&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
-
-&lt;node name="/com/example/MyObject"&gt;
 
-  &lt;interface name="com.example.MyObject"&gt;
-    &lt;annotation name="org.freedesktop.DBus.GLib.CSymbol" value="my_object"/&gt;
-    &lt;method name="ManyArgs"&gt;
-      &lt;!-- This is optional, and in this case is redunundant --&gt;
-      &lt;annotation name="org.freedesktop.DBus.GLib.CSymbol" value="my_object_many_args"/&gt;
-      &lt;arg type="u" name="x" direction="in" /&gt;
-      &lt;arg type="s" name="str" direction="in" /&gt;
-      &lt;arg type="d" name="trouble" direction="in" /&gt;
-      &lt;arg type="d" name="d_ret" direction="out" /&gt;
-      &lt;arg type="s" name="str_ret" direction="out" /&gt;
-    &lt;/method&gt;
-  &lt;/interface&gt;
-&lt;/node&gt;
-</programlisting>
-    </para>
     <para>
-      This XML is in the same format as the D-Bus introspection XML
-      format. Except we must include an "annotation" which give the C
-      symbols corresponding to the object implementation prefix
-      (<literal>my_object</literal>).  In addition, if particular
-      methods symbol names deviate from C convention
-      (i.e. <literal>ManyArgs</literal> -&gt;
-      <literal>many_args</literal>), you may specify an annotation
-      giving the C symbol.
+      An older API, dbus-glib, also exists. It is deprecated and should
+      not be used in new code. Whenever possible, porting existing code
+      from dbus-glib to GDBus is also recommended.
     </para>
-    <para>
-      Once you have written this XML, run <literal>dbus-binding-tool --mode=glib-server <replaceable>FILENAME</replaceable> &gt; <replaceable>HEADER_NAME</replaceable>.</literal> to
-      generate a header file.  For example: <command>dbus-binding-tool --mode=glib-server my-object.xml &gt; my-object-glue.h</command>.
-    </para>
-    <para>
-      Next, include the generated header in your program, and invoke
-      <literal>dbus_g_object_class_install_info</literal> in the class
-      initializer, passing the object class and "object info" included in the
-      header.  For example:
-      <programlisting>
-       dbus_g_object_type_install_info (COM_FOO_TYPE_MY_OBJECT, &amp;com_foo_my_object_info);
-      </programlisting>
-      This should be done exactly once per object class.
-    </para>
-    <para>
-      To actually implement the method, just define a C function named e.g.
-      <literal>my_object_many_args</literal> in the same file as the info
-      header is included.  At the moment, it is required that this function
-      conform to the following rules:
-      <itemizedlist>
-       <listitem>
-         <para>
-           The function must return a value of type <literal>gboolean</literal>;
-           <literal>TRUE</literal> on success, and <literal>FALSE</literal>
-           otherwise.
-         </para>
-       </listitem>
-       <listitem>
-         <para>
-           The first parameter is a pointer to an instance of the object.
-         </para>
-       </listitem>
-       <listitem>
-         <para>
-           Following the object instance pointer are the method
-           input values.
-         </para>
-       </listitem>
-       <listitem>
-         <para>
-           Following the input values are pointers to return values.
-         </para>
-       </listitem>
-       <listitem>
-         <para>
-           The final parameter must be a <literal>GError **</literal>.
-           If the function returns <literal>FALSE</literal> for an
-           error, the error parameter must be initalized with
-           <literal>g_set_error</literal>.
-         </para>
-       </listitem>
-      </itemizedlist>
-    </para>
-    <para>
-      Finally, you can export an object using <literal>dbus_g_connection_register_g_object</literal>.  For example:
-      <programlisting>
-         dbus_g_connection_register_g_object (connection,
-                                               "/com/foo/MyObject",
-                                               obj);
-      </programlisting>
-    </para>
-
-    <sect2 id="glib-annotations">
-      <title>Server-side Annotations</title>
-      <para>
-        There are several annotations that are used when generating the
-        server-side bindings.  The most common annotation is
-        <literal>org.freedesktop.DBus.GLib.CSymbol</literal> but there are other
-        annotations which are often useful.
-        <variablelist>
-          <varlistentry>
-            <term><literal>org.freedesktop.DBus.GLib.CSymbol</literal></term>
-            <listitem>
-              <para>
-                This annotation is used to specify the C symbol names for
-                the various types (interface, method, etc), if it differs from the
-                name DBus generates.
-              </para>
-            </listitem>
-          </varlistentry>
-          <varlistentry>
-            <term><literal>org.freedesktop.DBus.GLib.Async</literal></term>
-            <listitem>
-              <para>
-                This annotation marks the method implementation as an
-                asynchronous function, which doesn't return a response straight
-                away but will send the response at some later point to complete
-                the call.  This is used to implement non-blocking services where
-                method calls can take time.
-              </para>
-              <para>
-                When a method is asynchronous, the function prototype is
-                different. It is required that the function conform to the
-                following rules:
-                <itemizedlist>
-                  <listitem>
-                    <para>
-                      The function must return a value of type <literal>gboolean</literal>;
-                      <literal>TRUE</literal> on success, and <literal>FALSE</literal>
-                      otherwise. TODO: the return value is currently ignored.
-                    </para>
-                  </listitem>
-                  <listitem>
-                    <para>
-                      The first parameter is a pointer to an instance of the object.
-                    </para>
-                  </listitem>
-                  <listitem>
-                    <para>
-                      Following the object instance pointer are the method
-                      input values.
-                    </para>
-                  </listitem>
-                  <listitem>
-                    <para>
-                      The final parameter must be a
-                      <literal>DBusGMethodInvocation *</literal>.  This is used
-                      when sending the response message back to the client, by
-                      calling <literal>dbus_g_method_return</literal> or
-                      <literal>dbus_g_method_return_error</literal>.
-                    </para>
-                  </listitem>
-                </itemizedlist>
-              </para>
-            </listitem>
-          </varlistentry>
-          <varlistentry>
-            <term><literal>org.freedesktop.DBus.GLib.Const</literal></term>
-            <listitem>
-              <para>This attribute can only be applied to "out"
-              <literal>&lt;arg&gt;</literal> nodes, and specifies that the
-              parameter isn't being copied when returned.  For example, this
-              turns a 's' argument from a <literal>char **</literal> to a
-              <literal>const char **</literal>, and results in the argument not
-              being freed by DBus after the message is sent.
-              </para>
-            </listitem>
-          </varlistentry>
-          <varlistentry>
-            <term><literal>org.freedesktop.DBus.GLib.ReturnVal</literal></term>
-            <listitem>
-              <para>
-                This attribute can only be applied to "out"
-                <literal>&lt;arg&gt;</literal> nodes, and alters the expected
-                function signature.  It currently can be set to two values:
-                <literal>""</literal> or <literal>"error"</literal>.  The
-                argument marked with this attribute is not returned via a
-                pointer argument, but by the function's return value.  If the
-                attribute's value is the empty string, the <literal>GError
-                *</literal> argument is also omitted so there is no standard way
-                to return an error value.  This is very useful for interfacing
-                with existing code, as it is possible to match existing APIs.
-                If the attribute's value is <literal>"error"</literal>, then the
-                final argument is a <literal>GError *</literal> as usual.
-              </para>
-              <para>
-                Some examples to demonstrate the usage. This introspection XML:
-                <programlisting>
-&lt;method name="Increment"&gt;
-  &lt;arg type="u" name="x" /&gt;
-  &lt;arg type="u" direction="out" /&gt;
-&lt;/method&gt;
-                </programlisting>
-                Expects the following function declaration:
-                <programlisting>
-gboolean
-my_object_increment (MyObject *obj, gint32 x, gint32 *ret, GError **error);
-                </programlisting>
-              </para>
-              <para>
-                This introspection XML:
-                <programlisting>
-&lt;method name="IncrementRetval"&gt;
-  &lt;arg type="u" name="x" /&gt;
-  &lt;arg type="u" direction="out" &gt;
-    &lt;annotation name="org.freedesktop.DBus.GLib.ReturnVal" value=""/&gt;
-  &lt;/arg&gt;
-&lt;/method&gt;
-                </programlisting>
-                Expects the following function declaration:
-                <programlisting>
-gint32
-my_object_increment_retval (MyObject *obj, gint32 x)
-                </programlisting>
-              </para>
-              <para>
-                This introspection XML:
-                <programlisting>
-&lt;method name="IncrementRetvalError"&gt;
-  &lt;arg type="u" name="x" /&gt;
-  &lt;arg type="u" direction="out" &gt;
-    &lt;annotation name="org.freedesktop.DBus.GLib.ReturnVal" value="error"/&gt;
-  &lt;/arg&gt;
-&lt;/method&gt;
-                </programlisting>
-                Expects the following function declaration:
-                <programlisting>
-gint32
-my_object_increment_retval_error (MyObject *obj, gint32 x, GError **error)
-                </programlisting>
-              </para>
-            </listitem>
-          </varlistentry>
-        </variablelist>
-      </para>
-    </sect2>
   </sect1>
 
   <sect1 id="python-client">
@@ -1650,18 +730,12 @@ my_object_increment_retval_error (MyObject *obj, gint32 x, GError **error)
   </sect1>
 
   <sect1 id="qt-client">
-    <title>Qt API: Using Remote Objects</title>
-    <para>
-      
-      The Qt bindings are not yet documented.
-
-    </para>
-  </sect1>
-
-  <sect1 id="qt-server">
-    <title>Qt API: Implementing Objects</title>
+    <title>Qt API</title>
     <para>
-      The Qt bindings are not yet documented.
+      The Qt binding for libdbus, QtDBus, has been distributed with Qt
+      since version 4.2. It is not documented here. See
+      <ulink url="http://qt-project.org/doc/qt-5/qtdbus-index.html">the Qt
+        documentation</ulink> for details of how to use QtDBus.
     </para>
   </sect1>
 </article>