diff --git a/doc/dbus-tutorial.xml b/doc/dbus-tutorial.xml
index 3d14e5f7..c4d9504e 100644
--- a/doc/dbus-tutorial.xml
+++ b/doc/dbus-tutorial.xml
@@ -704,939 +704,19 @@
- GLib API: Using Remote Objects
+ GLib APIs
+
+ 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 the
+ GLib documentation for details of how to use GDBus.
+
- The GLib binding is defined in the header file
- <dbus/dbus-glib.h>.
+ 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.
-
-
- D-Bus - GLib type mappings
-
- The heart of the GLib bindings for D-Bus is the mapping it
- provides between D-Bus "type signatures" and GLib types
- (GType). The D-Bus type system is composed of
- a number of "basic" types, along with several "container" types.
-
-
- Basic type mappings
-
- Below is a list of the basic types, along with their associated
- mapping to a GType.
-
-
-
-
- D-Bus basic type
- GType
- Free function
- Notes
-
-
-
-
- BYTE
- G_TYPE_UCHAR
-
-
-
- BOOLEAN
- G_TYPE_BOOLEAN
-
-
-
- INT16
- G_TYPE_INT
-
- Will be changed to a G_TYPE_INT16 once GLib has it
-
- UINT16
- G_TYPE_UINT
-
- Will be changed to a G_TYPE_UINT16 once GLib has it
-
- INT32
- G_TYPE_INT
-
- Will be changed to a G_TYPE_INT32 once GLib has it
-
- UINT32
- G_TYPE_UINT
-
- Will be changed to a G_TYPE_UINT32 once GLib has it
-
- INT64
- G_TYPE_GINT64
-
-
-
- UINT64
- G_TYPE_GUINT64
-
-
-
- DOUBLE
- G_TYPE_DOUBLE
-
-
-
- STRING
- G_TYPE_STRING
- g_free
-
-
- OBJECT_PATH
- DBUS_TYPE_G_PROXY
- g_object_unref
- The returned proxy does not have an interface set; use dbus_g_proxy_set_interface to invoke methods
-
-
-
-
- As you can see, the basic mapping is fairly straightforward.
-
-
-
- Container type mappings
-
- The D-Bus type system also has a number of "container"
- types, such as DBUS_TYPE_ARRAY and
- DBUS_TYPE_STRUCT. The D-Bus type system
- is fully recursive, so one can for example have an array of
- array of strings (i.e. type signature
- aas).
-
-
- 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 DBUS_TYPE_STRUCT, or a
- DBUS_TYPE_ARRAY 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".
-
-
- First, D-Bus type signatures which have an "obvious"
- corresponding built-in GLib type are mapped using that type:
-
-
-
-
- D-Bus type signature
- Description
- GType
- C typedef
- Free function
- Notes
-
-
-
-
- as
- Array of strings
- G_TYPE_STRV
- char **
- g_strfreev
-
-
- v
- Generic value container
- G_TYPE_VALUE
- GValue *
- g_value_unset
- The calling conventions for values expect that method callers have allocated return values; see below.
-
-
-
-
-
-
- The next most common recursive type signatures are arrays of
- basic values. The most obvious mapping for arrays of basic
- types is a GArray. Now, GLib does not
- provide a builtin GType for
- GArray. 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.
-
-
- 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.
-
-
-
-
- D-Bus type signature
- Description
- GType
- C typedef
- Free function
- Notes
-
-
-
-
- ay
- Array of bytes
- DBUS_TYPE_G_UCHAR_ARRAY
- GArray *
- g_array_free
-
-
-
- au
- Array of uint
- DBUS_TYPE_G_UINT_ARRAY
- GArray *
- g_array_free
-
-
-
- ai
- Array of int
- DBUS_TYPE_G_INT_ARRAY
- GArray *
- g_array_free
-
-
-
- ax
- Array of int64
- DBUS_TYPE_G_INT64_ARRAY
- GArray *
- g_array_free
-
-
-
- at
- Array of uint64
- DBUS_TYPE_G_UINT64_ARRAY
- GArray *
- g_array_free
-
-
-
- ad
- Array of double
- DBUS_TYPE_G_DOUBLE_ARRAY
- GArray *
- g_array_free
-
-
-
- ab
- Array of boolean
- DBUS_TYPE_G_BOOLEAN_ARRAY
- GArray *
- g_array_free
-
-
-
-
-
-
-
- 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 GType 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.
-
-
- At present, only strings are supported. Work is in progress to
- include more types.
-
-
-
-
- D-Bus type signature
- Description
- GType
- C typedef
- Free function
- Notes
-
-
-
-
- a{ss}
- Dictionary mapping strings to strings
- DBUS_TYPE_G_STRING_STRING_HASHTABLE
- GHashTable *
- g_hash_table_destroy
-
-
-
-
-
-
-
-
- Arbitrarily recursive type mappings
-
- 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
- DBusGValue which acts as a kind of special
- variant value which may be iterated over manually. The
- GType associated is
- DBUS_TYPE_G_VALUE.
-
-
- TODO insert usage of DBUS_TYPE_G_VALUE here.
-
-
-
-
- A sample program
- Here is a D-Bus program using the GLib bindings.
-
-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,
- &error);
- if (connection == NULL)
- {
- g_printerr ("Failed to open connection to bus: %s\n",
- error->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", &error, G_TYPE_INVALID,
- G_TYPE_STRV, &name_list, G_TYPE_INVALID))
- {
- /* Just do demonstrate remote exceptions versus regular GError */
- if (error->domain == DBUS_GERROR && error->code == DBUS_GERROR_REMOTE_EXCEPTION)
- g_printerr ("Caught remote method exception %s: %s",
- dbus_g_error_get_name (error),
- error->message);
- else
- g_printerr ("Error: %s\n", error->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;
-}
-
-
-
-
- Program initalization
-
- A connection to the bus is acquired using
- dbus_g_bus_get. Next, a proxy
- is created for the object "/org/freedesktop/DBus" with
- interface org.freedesktop.DBus
- on the service org.freedesktop.DBus.
- This is a proxy for the message bus itself.
-
-
-
- Understanding method invocation
-
- You have a number of choices for method invocation. First, as
- used above, dbus_g_proxy_call 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 G_TYPE_INVALID.
- Next, pointers to return values are specified, followed again
- by G_TYPE_INVALID.
-
-
- To invoke a method asynchronously, use
- dbus_g_proxy_begin_call. This returns a
- DBusGPendingCall object; you may then set a
- notification function using
- dbus_g_pending_call_set_notify.
-
-
-
- Connecting to object signals
-
- You may connect to signals using
- dbus_g_proxy_add_signal and
- dbus_g_proxy_connect_signal. You must
- invoke dbus_g_proxy_add_signal to specify
- the signature of your signal handlers; you may then invoke
- dbus_g_proxy_connect_signal multiple times.
-
-
- 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
- glib-genmarshal, and then register
- it using dbus_g_object_register_marshaller.
-
-
-
- Error handling and remote exceptions
-
- All of the GLib binding methods such as
- dbus_g_proxy_end_call return a
- GError. This GError can
- represent two different things:
-
-
-
- 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
- DBUS_GERROR, and a corresponding code
- such as DBUS_GERROR_NO_MEMORY. It will
- not be typical for applications to handle these errors
- specifically.
-
-
-
-
- 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 GError, but some
- special rules apply.
-
-
- The set error will have the domain
- DBUS_GERROR as above, and will also
- have the code
- DBUS_GERROR_REMOTE_EXCEPTION. In order
- to access the remote exception name, you must use a
- special accessor, such as
- dbus_g_error_has_name or
- dbus_g_error_get_name. The remote
- exception detailed message is accessible via the regular
- GError message member.
-
-
-
-
-
-
- More examples of method invocation
-
- Sending an integer and string, receiving an array of bytes
-
-
- GArray *arr;
-
- error = NULL;
- if (!dbus_g_proxy_call (proxy, "Foobar", &error,
- G_TYPE_INT, 42, G_TYPE_STRING, "hello",
- G_TYPE_INVALID,
- DBUS_TYPE_G_UCHAR_ARRAY, &arr, G_TYPE_INVALID))
- {
- /* Handle error */
- }
- g_assert (arr != NULL);
- printf ("got back %u values", arr->len);
-
-
-
-
- Sending a GHashTable
-
-
- 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", &error,
- DBUS_TYPE_G_STRING_STRING_HASH, hash, G_TYPE_INVALID,
- G_TYPE_UINT, &ret, G_TYPE_INVALID))
- {
- /* Handle error */
- }
- g_assert (ret == 2);
- g_hash_table_destroy (hash);
-
-
-
-
- Receiving a boolean and a string
-
-
- gboolean boolret;
- char *strret;
-
- error = NULL;
- if (!dbus_g_proxy_call (proxy, "GetStuff", &error,
- G_TYPE_INVALID,
- G_TYPE_BOOLEAN, &boolret,
- G_TYPE_STRING, &strret,
- G_TYPE_INVALID))
- {
- /* Handle error */
- }
- printf ("%s %s", boolret ? "TRUE" : "FALSE", strret);
- g_free (strret);
-
-
-
-
- Sending two arrays of strings
-
-
- /* 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", &error,
- G_TYPE_STRV, strs_static_p,
- G_TYPE_STRV, strs_dynamic,
- G_TYPE_INVALID,
- G_TYPE_INVALID))
- {
- /* Handle error */
- }
- g_strfreev (strs_dynamic);
-
-
-
-
- Sending a boolean, receiving an array of strings
-
-
- char **strs;
- char **strs_p;
- gboolean blah;
-
- error = NULL;
- blah = TRUE;
- if (!dbus_g_proxy_call (proxy, "GetStrs", &error,
- G_TYPE_BOOLEAN, blah,
- G_TYPE_INVALID,
- G_TYPE_STRV, &strs,
- G_TYPE_INVALID))
- {
- /* Handle error */
- }
- for (strs_p = strs; *strs_p; strs_p++)
- printf ("got string: \"%s\"", *strs_p);
- g_strfreev (strs);
-
-
-
-
- Sending a variant
-
-
- GValue val = {0, };
-
- g_value_init (&val, G_TYPE_STRING);
- g_value_set_string (&val, "hello world");
-
- error = NULL;
- if (!dbus_g_proxy_call (proxy, "SendVariant", &error,
- G_TYPE_VALUE, &val, G_TYPE_INVALID,
- G_TYPE_INVALID))
- {
- /* Handle error */
- }
- g_assert (ret == 2);
- g_value_unset (&val);
-
-
-
-
- Receiving a variant
-
-
- GValue val = {0, };
-
- error = NULL;
- if (!dbus_g_proxy_call (proxy, "GetVariant", &error, G_TYPE_INVALID,
- G_TYPE_VALUE, &val, G_TYPE_INVALID))
- {
- /* Handle error */
- }
- if (G_VALUE_TYPE (&val) == G_TYPE_STRING)
- printf ("%s\n", g_value_get_string (&val));
- else if (G_VALUE_TYPE (&val) == G_TYPE_INT)
- printf ("%d\n", g_value_get_int (&val));
- else
- ...
- g_value_unset (&val);
-
-
-
-
-
-
- Generated Bindings
-
- By using the Introspection XML files, convenient client-side bindings
- can be automatically created to ease the use of a remote DBus object.
-
-
- Here is a sample XML file which describes an object that exposes
- one method, named ManyArgs.
-
-<?xml version="1.0" encoding="UTF-8" ?>
-<node name="/com/example/MyObject">
- <interface name="com.example.MyObject">
- <method name="ManyArgs">
- <arg type="u" name="x" direction="in" />
- <arg type="s" name="str" direction="in" />
- <arg type="d" name="trouble" direction="in" />
- <arg type="d" name="d_ret" direction="out" />
- <arg type="s" name="str_ret" direction="out" />
- </method>
- </interface>
-</node>
-
-
-
- Run dbus-binding-tool --mode=glib-client
- FILENAME >
- HEADER_NAME to generate the header
- file. For example: dbus-binding-tool --mode=glib-client
- my-object.xml > my-object-bindings.h. This will generate
- inline functions with the following prototypes:
-
-/* 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);
-
- The first argument in all functions is a DBusGProxy
- *, which you should create with the usual
- dbus_g_proxy_new_* functions. Following that are the
- "in" arguments, and then either the "out" arguments and a
- GError * 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
- DBusGProxy *, the returned "out" arguments, an
- GError * which is set if there was an error otherwise
- NULL, and the user data.
-
-
- As with the server-side bindings support (see ), the exact behaviour of the client-side
- bindings can be manipulated using "annotations". Currently the only
- annotation used by the client bindings is
- org.freedesktop.DBus.GLib.NoReply, 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.
-
-
-
-
-
- GLib API: Implementing Objects
-
- 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.
-
-
- Here is a sample XML file which describes an object that exposes
- one method, named ManyArgs.
-
-<?xml version="1.0" encoding="UTF-8" ?>
-
-<node name="/com/example/MyObject">
-
- <interface name="com.example.MyObject">
- <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="my_object"/>
- <method name="ManyArgs">
- <!-- This is optional, and in this case is redunundant -->
- <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="my_object_many_args"/>
- <arg type="u" name="x" direction="in" />
- <arg type="s" name="str" direction="in" />
- <arg type="d" name="trouble" direction="in" />
- <arg type="d" name="d_ret" direction="out" />
- <arg type="s" name="str_ret" direction="out" />
- </method>
- </interface>
-</node>
-
-
-
- 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
- (my_object). In addition, if particular
- methods symbol names deviate from C convention
- (i.e. ManyArgs ->
- many_args), you may specify an annotation
- giving the C symbol.
-
-
- Once you have written this XML, run dbus-binding-tool --mode=glib-server FILENAME > HEADER_NAME. to
- generate a header file. For example: dbus-binding-tool --mode=glib-server my-object.xml > my-object-glue.h.
-
-
- Next, include the generated header in your program, and invoke
- dbus_g_object_class_install_info in the class
- initializer, passing the object class and "object info" included in the
- header. For example:
-
- dbus_g_object_type_install_info (COM_FOO_TYPE_MY_OBJECT, &com_foo_my_object_info);
-
- This should be done exactly once per object class.
-
-
- To actually implement the method, just define a C function named e.g.
- my_object_many_args in the same file as the info
- header is included. At the moment, it is required that this function
- conform to the following rules:
-
-
-
- The function must return a value of type gboolean;
- TRUE on success, and FALSE
- otherwise.
-
-
-
-
- The first parameter is a pointer to an instance of the object.
-
-
-
-
- Following the object instance pointer are the method
- input values.
-
-
-
-
- Following the input values are pointers to return values.
-
-
-
-
- The final parameter must be a GError **.
- If the function returns FALSE for an
- error, the error parameter must be initalized with
- g_set_error.
-
-
-
-
-
- Finally, you can export an object using dbus_g_connection_register_g_object. For example:
-
- dbus_g_connection_register_g_object (connection,
- "/com/foo/MyObject",
- obj);
-
-
-
-
- Server-side Annotations
-
- There are several annotations that are used when generating the
- server-side bindings. The most common annotation is
- org.freedesktop.DBus.GLib.CSymbol but there are other
- annotations which are often useful.
-
-
- org.freedesktop.DBus.GLib.CSymbol
-
-
- 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.
-
-
-
-
- org.freedesktop.DBus.GLib.Async
-
-
- 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.
-
-
- When a method is asynchronous, the function prototype is
- different. It is required that the function conform to the
- following rules:
-
-
-
- The function must return a value of type gboolean;
- TRUE on success, and FALSE
- otherwise. TODO: the return value is currently ignored.
-
-
-
-
- The first parameter is a pointer to an instance of the object.
-
-
-
-
- Following the object instance pointer are the method
- input values.
-
-
-
-
- The final parameter must be a
- DBusGMethodInvocation *. This is used
- when sending the response message back to the client, by
- calling dbus_g_method_return or
- dbus_g_method_return_error.
-
-
-
-
-
-
-
- org.freedesktop.DBus.GLib.Const
-
- This attribute can only be applied to "out"
- <arg> nodes, and specifies that the
- parameter isn't being copied when returned. For example, this
- turns a 's' argument from a char ** to a
- const char **, and results in the argument not
- being freed by DBus after the message is sent.
-
-
-
-
- org.freedesktop.DBus.GLib.ReturnVal
-
-
- This attribute can only be applied to "out"
- <arg> nodes, and alters the expected
- function signature. It currently can be set to two values:
- "" or "error". 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 GError
- * 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 "error", then the
- final argument is a GError * as usual.
-
-
- Some examples to demonstrate the usage. This introspection XML:
-
-<method name="Increment">
- <arg type="u" name="x" />
- <arg type="u" direction="out" />
-</method>
-
- Expects the following function declaration:
-
-gboolean
-my_object_increment (MyObject *obj, gint32 x, gint32 *ret, GError **error);
-
-
-
- This introspection XML:
-
-<method name="IncrementRetval">
- <arg type="u" name="x" />
- <arg type="u" direction="out" >
- <annotation name="org.freedesktop.DBus.GLib.ReturnVal" value=""/>
- </arg>
-</method>
-
- Expects the following function declaration:
-
-gint32
-my_object_increment_retval (MyObject *obj, gint32 x)
-
-
-
- This introspection XML:
-
-<method name="IncrementRetvalError">
- <arg type="u" name="x" />
- <arg type="u" direction="out" >
- <annotation name="org.freedesktop.DBus.GLib.ReturnVal" value="error"/>
- </arg>
-</method>
-
- Expects the following function declaration:
-
-gint32
-my_object_increment_retval_error (MyObject *obj, gint32 x, GError **error)
-
-
-
-
-
-
-
@@ -1650,18 +730,12 @@ my_object_increment_retval_error (MyObject *obj, gint32 x, GError **error)
- Qt API: Using Remote Objects
+ Qt API
-
- The Qt bindings are not yet documented.
-
-
-
-
-
- Qt API: Implementing Objects
-
- 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
+ the Qt
+ documentation for details of how to use QtDBus.