D-Bus integration in Emacs
This manual documents an API for usage of D-Bus in Emacs. D-Bus is a message bus system, a simple way for applications to talk to one another. An overview of D-Bus can be found at https://dbus.freedesktop.org/.
Copyright © 2007–2024 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with the Front-Cover Texts being “A GNU Manual”, and with the Back-Cover Texts as in (a) below. A copy of the license is included in the section entitled “GNU Free Documentation License”.
(a) The FSF’s Back-Cover Text is: “You have the freedom to copy and modify this GNU manual.”
Table of Contents
- 1 An overview of D-Bus
- 2 Inspection of D-Bus services.
- 3 Mapping Lisp types and D-Bus types.
- 4 Calling methods in a blocking way.
- 5 Calling methods non-blocking.
- 6 Offering own services.
- 7 Sending and receiving signals.
- 8 Alternative buses and environments.
- 9 Errors and events.
- 10 Monitoring messages.
- Index
- Appendix A GNU Free Documentation License
Next: Inspection of D-Bus services., Up: D-Bus integration in Emacs [Contents][Index]
1 An overview of D-Bus
D-Bus is an inter-process communication mechanism for applications residing on the same host. The communication is based on messages. Data in the messages is carried in a structured way, it is not just a byte stream.
The communication is connection oriented to two kinds of message buses: a so called system bus, and a session bus. On a given machine, there is always one single system bus for miscellaneous system-wide communication, like changing of hardware configuration. On the other hand, the session bus is always related to a single user’s session.
Every client application, which is connected to a bus, registers under a unique name at the bus. This name is used for identifying the client application. Such a unique name starts always with a colon, and looks like ‘:1.42’.
Additionally, a client application can register itself to a so called known name, which is a series of identifiers separated by dots, as in ‘org.gnu.Emacs’. If several applications register to the same known name, these registrations are queued, and only the first application which has registered for the known name is reachable via this name. If this application disconnects from the bus, the next queued unique name becomes the owner of this known name.
An application can install one or several objects under its name. Such objects are identified by an object path, which looks similar to paths in a filesystem. An example of such an object path could be ‘/org/gnu/Emacs/’.
Applications might send a request to an object, that means sending a message with some data as input parameters, and receiving a message from that object with the result of this message, the output parameters. Such a request is called method in D-Bus.
The other form of communication are signals. The underlying message is emitted from an object and will be received by all other applications which have registered for such a signal.
All methods and signals an object supports are called interface of the object. Interfaces are specified under a hierarchical name in D-Bus; an object can support several interfaces. Such an interface name could be ‘org.gnu.Emacs.TextEditor’ or ‘org.gnu.Emacs.FileManager’.
Next: Mapping Lisp types and D-Bus types., Previous: An overview of D-Bus, Up: D-Bus integration in Emacs [Contents][Index]
2 Inspection of D-Bus services.
- D-Bus version.
- Bus names.
- Knowing the details of D-Bus services.
- Detecting object paths and interfaces.
- Applying the functionality.
- What else to know about interfaces.
- The final details.
Next: Bus names., Up: Inspection of D-Bus services. [Contents][Index]
2.1 D-Bus version.
D-Bus has evolved over the years. New features have been added with new D-Bus versions. There are two variables, which allow the determination of the D-Bus version used.
- Variable: dbus-compiled-version ¶
This variable, a string, determines the version of D-Bus Emacs is compiled against. If it cannot be determined the value is
nil
.
- Variable: dbus-runtime-version ¶
The other D-Bus version to be checked is the version of D-Bus Emacs runs with. This string can be different from
dbus-compiled-version
. It is alsonil
, if it cannot be determined at runtime.
Next: Knowing the details of D-Bus services., Previous: D-Bus version., Up: Inspection of D-Bus services. [Contents][Index]
2.2 Bus names.
There are several basic functions which inspect the buses for registered names. Internally they use the basic interface ‘org.freedesktop.DBus’, which is supported by all objects of a bus.
- Function: dbus-list-activatable-names &optional bus ¶
This function returns the D-Bus service names, which can be activated for bus. It must be either the keyword
:system
(the default) or the keyword:session
. An activatable service is described in a service registration file. Under GNU/Linux, such files are located at /usr/share/dbus-1/system-services/ (for the:system
bus) or /usr/share/dbus-1/services/. An activatable service is not necessarily registered at bus already.The result is a list of strings, which is
nil
when there are no activatable service names at all. Example:;; Check, whether the document viewer can be accessed via D-Bus. (member "org.gnome.evince.Daemon" (dbus-list-activatable-names :session))
- Function: dbus-list-names bus ¶
This function returns all service names, which are registered at D-Bus bus. The result is a list of strings, which is
nil
when there are no registered service names at all. Well known names are strings like ‘org.freedesktop.DBus’. Names starting with ‘:’ are unique names for services.bus must be either the keyword
:system
or the keyword:session
.
- Function: dbus-list-known-names bus ¶
This function retrieves all registered services which correspond to a known name in bus. A service has a known name if it doesn’t start with ‘:’. The result is a list of strings, which is
nil
when there are no known names at all.bus must be either the keyword
:system
or the keyword:session
.
- Function: dbus-list-queued-owners bus service ¶
For a given service, registered at D-Bus bus under the name service, this function returns all queued unique names. The result is a list of strings, or
nil
when there are no queued names for service at all.bus must be either the keyword
:system
or the keyword:session
. service must be a known service name as string.
- Function: dbus-get-name-owner bus service ¶
For a given service, registered at D-Bus bus under the name service, this function returns the unique name of the name owner. The result is a string, or
nil
when there is no name owner of service.bus must be either the keyword
:system
or the keyword:session
. service must be a known service name as string.
- Function: dbus-ping bus service &optional timeout ¶
This function checks whether the service name service is registered at D-Bus bus. If service has not yet started, it is autostarted if possible. The result is either
t
ornil
.bus must be either the keyword
:system
or the keyword:session
. service must be a string. timeout, a nonnegative integer, specifies the maximum number of milliseconds beforedbus-ping
must return. The default value is 25,000. Example:(message "%s screensaver on board." (cond ((dbus-ping :session "org.gnome.ScreenSaver" 100) "Gnome") ((dbus-ping :session "org.freedesktop.ScreenSaver" 100) "KDE") (t "No")))
To check whether service is already running without autostarting it, you can instead write:
(member service (dbus-list-known-names bus))
- Function: dbus-get-unique-name bus ¶
This function returns the unique name, under which Emacs is registered at D-Bus bus, as a string.
bus must be either the keyword
:system
or the keyword:session
.
Next: Detecting object paths and interfaces., Previous: Bus names., Up: Inspection of D-Bus services. [Contents][Index]
2.3 Knowing the details of D-Bus services.
D-Bus services publish their interfaces. This can be retrieved and analyzed during runtime, in order to understand the used implementation.
The resulting introspection data are in XML format. The root
introspection element is always a node
element. It might have
a name
attribute, which denotes the (absolute) object path an
interface is introspected.
The root node
element may have node
and interface
children. A child node
element must have a name
attribute, this case it is the relative object path to the root
node
element.
An interface
element has just one attribute, name
, which
is the full name of that interface. The default interface
‘org.freedesktop.DBus.Introspectable’ is always present. Example:
<node name="/org/bluez"> <interface name="org.freedesktop.DBus.Introspectable"> … </interface> <interface name="org.bluez.Manager"> … </interface> <interface name="org.bluez.Database"> … </interface> <interface name="org.bluez.Security"> … </interface> <node name="service_audio"/> <node name="service_input"/> <node name="service_network"/> <node name="service_serial"/> </node>
Children of an interface
element can be method
,
signal
and property
elements. A method
element
stands for a D-Bus method of the surrounding interface. The element
itself has a name
attribute, showing the method name. Children
elements arg
stand for the arguments of a method. Example:
<method name="ResolveHostName"> <arg name="interface" type="i" direction="in"/> <arg name="protocol" type="i" direction="in"/> <arg name="name" type="s" direction="in"/> <arg name="aprotocol" type="i" direction="in"/> <arg name="flags" type="u" direction="in"/> <arg name="interface" type="i" direction="out"/> <arg name="protocol" type="i" direction="out"/> <arg name="name" type="s" direction="out"/> <arg name="aprotocol" type="i" direction="out"/> <arg name="address" type="s" direction="out"/> <arg name="flags" type="u" direction="out"/> </method>
arg
elements can have the attributes name
, type
and direction
. The name
attribute is optional. The
type
attribute stands for the signature of the argument
in D-Bus. For a discussion of D-Bus types and their Lisp
representation see Mapping Lisp types and D-Bus types..1
The direction
attribute of an arg
element can be only
‘in’ or ‘out’; in case it is omitted, it defaults to
‘in’.
A signal
element of an interface
has a similar
structure. The direction
attribute of an arg
child
element can be only ‘out’ here; which is also the default value.
Example:
<signal name="StateChanged"> <arg name="state" type="i"/> <arg name="error" type="s"/> </signal>
A property
element has no arg
child
element. It just has the attributes name
, type
and
access
, which are all mandatory. The access
attribute
allows the values ‘readwrite’, ‘read’, and ‘write’.
Example:
<property name="Status" type="u" direction="read"/>
annotation
elements can be children of interface
,
method
, signal
, and property
elements. Unlike
properties, which can change their values during lifetime of a D-Bus
object, annotations are static. Often they are used for code
generators of D-Bus language bindings. Example:
<annotation name="de.berlios.Pinot.GetStatistics" value="pinotDBus"/>
Annotations have just name
and value
attributes, both
must be strings.
- Function: dbus-introspect bus service path ¶
This function returns all interfaces and sub-nodes of service, registered at object path path at bus bus.
bus must be either the keyword
:system
or the keyword:session
. service must be a known service name, and path must be a valid object path. The last two parameters are strings. The result, the introspection data, is a string in XML format. Example:(dbus-introspect :system "org.freedesktop.Hal" "/org/freedesktop/Hal/devices/computer") ⇒ "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <node> <interface name="org.freedesktop.Hal.Device"> <method name="GetAllProperties"> <arg name="properties" direction="out" type="a{sv}"/> </method> … <signal name="PropertyModified"> <arg name="num_updates" type="i"/> <arg name="updates" type="a(sbb)"/> </signal> </interface> … </node>"
This example informs us, that the service ‘org.freedesktop.Hal’ at object path ‘/org/freedesktop/Hal/devices/computer’ offers the interface ‘org.freedesktop.Hal.Device’ (and 2 other interfaces not documented here). This interface contains the method ‘GetAllProperties’, which needs no input parameters, but returns as output parameter an array of dictionary entries (key-value pairs). Every dictionary entry has a string as key, and a variant as value.
The interface offers also a signal, which returns 2 parameters: an integer, and an array consisting of elements which are a struct of a string and 2 boolean values.2
- Function: dbus-introspect-xml bus service path ¶
This function serves a similar purpose to the function
dbus-introspect
. The returned value is a parsed XML tree, which can be used for further analysis. Example:(dbus-introspect-xml :session "org.freedesktop.xesam.searcher" "/org/freedesktop/xesam/searcher/main") ⇒ (node ((name . "/org/freedesktop/xesam/searcher/main")) (interface ((name . "org.freedesktop.xesam.Search")) (method ((name . "GetHitData")) (arg ((name . "search") (type . "s") (direction . "in"))) (arg ((name . "hit_ids") (type . "au") (direction . "in"))) (arg ((name . "fields") (type . "as") (direction . "in"))) (arg ((name . "hit_data") (type . "aav") (direction . "out")))) … (signal ((name . "HitsAdded")) (arg ((name . "search") (type . "s"))) (arg ((name . "count") (type . "u"))))) …)
- Function: dbus-introspect-get-attribute object attribute ¶
This function returns the attribute value of a D-Bus introspection object. The value of object can be any subtree of a parsed XML tree as retrieved with
dbus-introspect-xml
. attribute must be a string according to the attribute names in the D-Bus specification. Example:(dbus-introspect-get-attribute (dbus-introspect-xml :system "org.freedesktop.SystemToolsBackends" "/org/freedesktop/SystemToolsBackends/UsersConfig") "name") ⇒ "/org/freedesktop/SystemToolsBackends/UsersConfig"
If object has no attribute, the function returns
nil
.
Next: Applying the functionality., Previous: Knowing the details of D-Bus services., Up: Inspection of D-Bus services. [Contents][Index]
2.4 Detecting object paths and interfaces.
The first elements, to be introspected for a D-Bus object, are further object paths and interfaces.
- Function: dbus-introspect-get-node-names bus service path ¶
This function returns all node names of service in D-Bus bus at object path path as a list of strings. Example:
(dbus-introspect-get-node-names :session "org.gnome.seahorse" "/org/gnome/seahorse") ⇒ ("crypto" "keys")
The node names stand for further object paths of the D-Bus service, relative to path. In the example, ‘/org/gnome/seahorse/crypto’ and ‘/org/gnome/seahorse/keys’ are also object paths of the D-Bus service ‘org.gnome.seahorse’.
- Function: dbus-introspect-get-all-nodes bus service path ¶
This function returns all node names of service in D-Bus bus at object path path. It returns a list of strings with all object paths of service, starting at path. Example:
(dbus-introspect-get-all-nodes :session "org.gnome.seahorse" "/") ⇒ ("/" "/org" "/org/gnome" "/org/gnome/seahorse" "/org/gnome/seahorse/crypto" "/org/gnome/seahorse/keys" "/org/gnome/seahorse/keys/openpgp" "/org/gnome/seahorse/keys/openpgp/local" "/org/gnome/seahorse/keys/openssh" "/org/gnome/seahorse/keys/openssh/local")
- Function: dbus-introspect-get-interface-names bus service path ¶
This function returns a list strings of all interface names of service in D-Bus bus at object path path. This list will contain the default interface ‘org.freedesktop.DBus.Introspectable’.
Another default interface is ‘org.freedesktop.DBus.Properties’. If present,
interface
elements can also haveproperty
children. Example:(dbus-introspect-get-interface-names :system "org.freedesktop.Hal" "/org/freedesktop/Hal/devices/computer") ⇒ ("org.freedesktop.DBus.Introspectable" "org.freedesktop.Hal.Device" "org.freedesktop.Hal.Device.SystemPowerManagement" "org.freedesktop.Hal.Device.CPUFreq")
- Function: dbus-introspect-get-interface bus service path interface ¶
This function returns interface of service in D-Bus bus at object path path. The return value is an XML element. interface must be a string and a member of the list returned by
dbus-introspect-get-interface-names
. Example:(dbus-introspect-get-interface :session "org.freedesktop.xesam.searcher" "/org/freedesktop/xesam/searcher/main" "org.freedesktop.xesam.Search") ⇒ (interface ((name . "org.freedesktop.xesam.Search")) (method ((name . "GetHitData")) (arg ((name . "search") (type . "s") (direction . "in"))) (arg ((name . "hit_ids") (type . "au") (direction . "in"))) (arg ((name . "fields") (type . "as") (direction . "in"))) (arg ((name . "hit_data") (type . "aav") (direction . "out")))) … (signal ((name . "HitsAdded")) (arg ((name . "search") (type . "s"))) (arg ((name . "count") (type . "u")))))
With these functions, it is possible to retrieve all introspection data from a running system:
(progn (pop-to-buffer "*introspect*") (erase-buffer) (dolist (service (dbus-list-known-names :session)) (dolist (path (dbus-introspect-get-all-nodes :session service "/")) ;; We want to introspect only elements, which have more than ;; the default interface "org.freedesktop.DBus.Introspectable". (when (delete "org.freedesktop.DBus.Introspectable" (dbus-introspect-get-interface-names :session service path)) (insert (format "\nservice: \"%s\" path: \"%s\"\n" service path) (dbus-introspect :session service path)) (redisplay t)))))
Next: What else to know about interfaces., Previous: Detecting object paths and interfaces., Up: Inspection of D-Bus services. [Contents][Index]
2.5 Applying the functionality.
Methods and signals are the communication means to D-Bus. The following functions return their specifications.
- Function: dbus-introspect-get-method-names bus service path interface ¶
This function returns a list of strings of all method names of interface of service in D-Bus bus at object path path. Example:
(dbus-introspect-get-method-names :session "org.freedesktop.xesam.searcher" "/org/freedesktop/xesam/searcher/main" "org.freedesktop.xesam.Search") ⇒ ("GetState" "StartSearch" "GetHitCount" "GetHits" "NewSession" "CloseSession" "GetHitData" "SetProperty" "NewSearch" "GetProperty" "CloseSearch")
- Function: dbus-introspect-get-method bus service path interface method ¶
This function returns method of interface as an XML element. It must be located at service in D-Bus bus at object path path. method must be a string and a member of the list returned by
dbus-introspect-get-method-names
. Example:(dbus-introspect-get-method :session "org.freedesktop.xesam.searcher" "/org/freedesktop/xesam/searcher/main" "org.freedesktop.xesam.Search" "GetHitData") ⇒ (method ((name . "GetHitData")) (arg ((name . "search") (type . "s") (direction . "in"))) (arg ((name . "hit_ids") (type . "au") (direction . "in"))) (arg ((name . "fields") (type . "as") (direction . "in"))) (arg ((name . "hit_data") (type . "aav") (direction . "out"))))
- Function: dbus-introspect-get-signal-names bus service path interface ¶
This function returns a list of strings of all signal names of interface of service in D-Bus bus at object path path. Example:
(dbus-introspect-get-signal-names :session "org.freedesktop.xesam.searcher" "/org/freedesktop/xesam/searcher/main" "org.freedesktop.xesam.Search") ⇒ ("StateChanged" "SearchDone" "HitsModified" "HitsRemoved" "HitsAdded")
- Function: dbus-introspect-get-signal bus service path interface signal ¶
This function returns signal of interface as an XML element. It must be located at service in D-Bus bus at object path path. signal must be a string and a member of the list returned by
dbus-introspect-get-signal-names
. Example:(dbus-introspect-get-signal :session "org.freedesktop.xesam.searcher" "/org/freedesktop/xesam/searcher/main" "org.freedesktop.xesam.Search" "HitsAdded") ⇒ (signal ((name . "HitsAdded")) (arg ((name . "search") (type . "s"))) (arg ((name . "count") (type . "u"))))
Next: The final details., Previous: Applying the functionality., Up: Inspection of D-Bus services. [Contents][Index]
2.6 What else to know about interfaces.
Interfaces can have properties. These can be exposed via the ‘org.freedesktop.DBus.Properties’ interface3. That is, properties can be retrieved and changed during the lifetime of an element.
A generalized interface is ‘org.freedesktop.DBus.Objectmanager’4, which returns objects, their interfaces and properties for a given service in just one call.
Annotations, on the other hand, are static values for an element. Often, they are used to instruct generators, how to generate code from the interface for a given language binding.
- Function: dbus-introspect-get-property-names bus service path interface ¶
This function returns a list of strings with all property names of interface of service in D-Bus bus at object path path. Example:
(dbus-introspect-get-property-names :session "org.kde.kded" "/modules/networkstatus" "org.kde.Solid.Networking.Client") ⇒ ("Status")
If an interface declares properties, the corresponding element supports also the ‘org.freedesktop.DBus.Properties’ interface.
- Function: dbus-introspect-get-property bus service path interface property ¶
This function returns property of interface as an XML element. It must be located at service in D-Bus bus at object path path. property must be a string and a member of the list returned by
dbus-introspect-get-property-names
.A property value can be retrieved by the function
dbus-introspect-get-attribute
. Example:(dbus-introspect-get-property :session "org.kde.kded" "/modules/networkstatus" "org.kde.Solid.Networking.Client" "Status") ⇒ (property ((access . "read") (type . "u") (name . "Status"))) (dbus-introspect-get-attribute (dbus-introspect-get-property :session "org.kde.kded" "/modules/networkstatus" "org.kde.Solid.Networking.Client" "Status") "access") ⇒ "read"
- Function: dbus-get-property bus service path interface property ¶
This function returns the value of property of interface. It will be checked at bus, service, path. The result can be any valid D-Bus value. If there is no property, or property cannot be read, an error is raised. Example:
(dbus-get-property :session "org.kde.kded" "/modules/networkstatus" "org.kde.Solid.Networking.Client" "Status") ⇒ 4
- Function: dbus-set-property bus service path interface property [type] value ¶
This function sets the value of property of interface to value. It will be checked at bus, service, path. value can be preceded by a type keyword. When the value is successfully set, this function returns value. Example:
(dbus-set-property :session "org.kde.kaccess" "/MainApplication" "com.trolltech.Qt.QApplication" "doubleClickInterval" :uint16 500) ⇒ 500
- Function: dbus-get-all-properties bus service path interface ¶
This function returns all readable properties of interface. It will be checked at bus, service, path. The result is a list of cons cells. Every cons cell contains the name of the property, and its value. If there are no properties,
nil
is returned. Example:(dbus-get-all-properties :session "org.kde.kaccess" "/MainApplication" "com.trolltech.Qt.QApplication") ⇒ (("cursorFlashTime" . 1000) ("doubleClickInterval" . 500) ("keyboardInputInterval" . 400) ("wheelScrollLines" . 3) ("globalStrut" 0 0) ("startDragTime" . 500) ("startDragDistance" . 4) ("quitOnLastWindowClosed" . t) ("styleSheet" . ""))
- Function: dbus-get-all-managed-objects bus service path ¶
This function returns all objects at bus, service, path, and the children of path. The result is a list of objects. Every object is a cons cell of an existing path name, and the list of available interface objects. An interface object is another cons, whose car is the interface name and cdr is the list of properties as returned by
dbus-get-all-properties
for that path and interface. Example:(dbus-get-all-managed-objects :session "org.gnome.SettingsDaemon" "/") ⇒ (("/org/gnome/SettingsDaemon/Power" ("org.gnome.SettingsDaemon.Power.Keyboard") ("org.gnome.SettingsDaemon.Power.Screen") ("org.gnome.SettingsDaemon.Power" ("Icon" . ". GThemedIcon battery-full-charged-symbolic ") ("Tooltip" . "Laptop battery is charged")) ("org.freedesktop.DBus.Peer") ("org.freedesktop.DBus.Introspectable") ("org.freedesktop.DBus.Properties") ("org.freedesktop.DBus.ObjectManager")) …)
If possible, ‘org.freedesktop.DBus.ObjectManager.GetManagedObjects’ is used for retrieving the information. Otherwise, the information is collected via ‘org.freedesktop.DBus.Introspectable.Introspect’ and ‘org.freedesktop.DBus.Properties.GetAll’, which is slow.
An overview of all existing object paths, their interfaces and properties could be retrieved by the following code:
(let ((result (mapcar (lambda (service) (cons service (dbus-get-all-managed-objects :session service "/"))) (dbus-list-known-names :session)))) (pop-to-buffer "*objectmanager*") (erase-buffer) (pp result (current-buffer)))
- Function: dbus-introspect-get-annotation-names bus service path interface &optional name ¶
This function returns a list of all annotation names as list of strings. If name is
nil
, the annotations are children of interface, otherwise name must be amethod
,signal
, orproperty
XML element, where the annotations belong to. Example:(dbus-introspect-get-annotation-names :session "de.berlios.Pinot" "/de/berlios/Pinot" "de.berlios.Pinot" "GetStatistics") ⇒ ("de.berlios.Pinot.GetStatistics")
Default annotation names5 are
- ‘org.freedesktop.DBus.Deprecated’
Whether or not the entity is deprecated; defaults to
nil
- ‘org.freedesktop.DBus.GLib.CSymbol’
The C symbol; may be used for
methods
andinterfaces
- ‘org.freedesktop.DBus.Method.NoReply’
If set, don’t expect a reply to the
method
call; defaults tonil
- Function: dbus-introspect-get-annotation bus service path interface name annotation ¶
This function returns annotation as an XML object. If name is
nil
, annotation is a child of interface, otherwise name must be the name of amethod
,signal
, orproperty
XML element, where the annotation belongs to.An attribute value can be retrieved by
dbus-introspect-get-attribute
. Example:(dbus-introspect-get-annotation :session "de.berlios.Pinot" "/de/berlios/Pinot" "de.berlios.Pinot" "GetStatistics" "de.berlios.Pinot.GetStatistics") ⇒ (annotation ((name . "de.berlios.Pinot.GetStatistics") (value . "pinotDBus"))) (dbus-introspect-get-attribute (dbus-introspect-get-annotation :session "de.berlios.Pinot" "/de/berlios/Pinot" "de.berlios.Pinot" "GetStatistics" "de.berlios.Pinot.GetStatistics") "value") ⇒ "pinotDBus"
Previous: What else to know about interfaces., Up: Inspection of D-Bus services. [Contents][Index]
2.7 The final details.
Methods and signals have arguments. They are described in the
arg
XML elements.
- Function: dbus-introspect-get-argument-names bus service path interface name ¶
This function returns a list of all argument names as strings. name must be a
method
orsignal
XML element. Example:(dbus-introspect-get-argument-names :session "org.freedesktop.xesam.searcher" "/org/freedesktop/xesam/searcher/main" "org.freedesktop.xesam.Search" "GetHitData") ⇒ ("search" "hit_ids" "fields" "hit_data")
Argument names are optional; the function can therefore return
nil
, even if the method or signal has arguments.
- Function: dbus-introspect-get-argument bus service path interface name arg ¶
This function returns the argument arg as an XML object. name must be a
method
orsignal
XML element. Example:(dbus-introspect-get-argument :session "org.freedesktop.xesam.searcher" "/org/freedesktop/xesam/searcher/main" "org.freedesktop.xesam.Search" "GetHitData" "search") ⇒ (arg ((name . "search") (type . "s") (direction . "in")))
- Function: dbus-introspect-get-signature bus service path interface name &optional direction ¶
This function returns the signature of a
method
orsignal
, represented by name, as a string.If name is a
method
, direction can be either ‘in’ or ‘out’. If direction isnil
, ‘in’ is assumed.If name is a
signal
, and direction is non-nil
, direction must be ‘out’. Example:(dbus-introspect-get-signature :session "org.freedesktop.xesam.searcher" "/org/freedesktop/xesam/searcher/main" "org.freedesktop.xesam.Search" "GetHitData" "in") ⇒ "sauas" (dbus-introspect-get-signature :session "org.freedesktop.xesam.searcher" "/org/freedesktop/xesam/searcher/main" "org.freedesktop.xesam.Search" "HitsAdded") ⇒ "su"
Next: Calling methods in a blocking way., Previous: Inspection of D-Bus services., Up: D-Bus integration in Emacs [Contents][Index]
3 Mapping Lisp types and D-Bus types.
D-Bus method calls and signals accept usually several arguments as parameters, either as input parameter, or as output parameter. Every argument belongs to a D-Bus type.
Such arguments must be mapped between the value encoded as a D-Bus type, and the corresponding type of Lisp objects. The mapping is applied Lisp object → D-Bus type for input parameters, and D-Bus type → Lisp object for output parameters.
3.1 Input parameters.
Input parameters for D-Bus methods and signals occur as arguments of a Lisp function call. The following mapping to D-Bus types is applied, when the corresponding D-Bus message is created:
Lisp type | D-Bus type | |
| → | DBUS_TYPE_BOOLEAN |
natural number | → | DBUS_TYPE_UINT32 |
negative integer | → | DBUS_TYPE_INT32 |
float | → | DBUS_TYPE_DOUBLE |
string | → | DBUS_TYPE_STRING |
list | → | DBUS_TYPE_ARRAY |
Other Lisp objects, like symbols or hash tables, are not accepted as input parameters.
If it is necessary to use another D-Bus type, a corresponding type
keyword can be prepended to the corresponding Lisp object. Basic
D-Bus types are represented by the type keywords :byte
,
:boolean
, :int16
, :uint16
, :int32
,
:uint32
, :int64
, :uint64
, :double
,
:string
, :object-path
, :signature
and
:unix-fd
.
Example:
(dbus-call-method … nat-number string)
is equivalent to
(dbus-call-method … :uint32 nat-number :string string)
but different to
(dbus-call-method … :int32 nat-number :signature string)
The value for a D-Bus byte type can be any natural number. If the
number is larger than 255, it is truncated to the least significant
byte. For example, :byte 1025
is equal to :byte 1
. If
a character is used as argument, modifiers represented outside this
range are stripped off. For example, :byte ?x
is equal to
:byte ?\M-x
, but it is not equal to :byte ?\C-x
or
:byte ?\M-\C-x
.
Signed and unsigned D-Bus integer types expect a corresponding integer value. A unix file descriptor is restricted to the values 0…9.
If typed explicitly, a non-nil
boolean value like
:boolean 'symbol
is handled like t
or :boolean t
.
A D-Bus compound type is always represented as a list. The CAR
of this list can be the type keyword :array
, :variant
,
:struct
or :dict-entry
, which would result in a
corresponding D-Bus container. :array
is optional, because
this is the default compound D-Bus type for a list.
The objects being elements of the list are checked according to the D-Bus compound type rules.
If an empty array needs an element D-Bus type other than string, it
can contain exactly one element of D-Bus type :signature
. The
value of this element (a string) is used as the signature of the
elements of this array. Example:
(dbus-call-method :session "org.freedesktop.Notifications" "/org/freedesktop/Notifications" "org.freedesktop.Notifications" "Notify" "GNU Emacs" ; Application name. 0 ; No replacement of other notifications. "" ; No icon. "Notification summary" ; Summary. (format ; Body. "This is a test notification, raised from\n%S" (emacs-version)) '(:array) ; No actions (empty array of strings). '(:array :signature "{sv}") ; No hints ; (empty array of dictionary entries). :int32 -1) ; Default timeout. ⇒ 3
- Function: dbus-string-to-byte-array string ¶
Sometimes, D-Bus methods require as input parameter an array of bytes, instead of a string. If it is guaranteed, that string is a UTF-8 string, this function performs the conversion. Example:
(dbus-string-to-byte-array "/etc/hosts") ⇒ (:array :byte 47 :byte 101 :byte 116 :byte 99 :byte 47 :byte 104 :byte 111 :byte 115 :byte 116 :byte 115)
- Function: dbus-escape-as-identifier string ¶
This function escapes an arbitrary string so it follows the rules for a C identifier. The escaped string can be used as object path component, interface element component, bus name component or member name in D-Bus.
The escaping consists of replacing all non-alphanumerics, and the first character if it’s a digit, with an underscore and two lower-case hex digits. As a special case, "" is escaped to "_". Example:
(dbus-escape-as-identifier "0123abc_xyz\x01\xff") ⇒ "_30123abc_5fxyz_01_ff"
3.2 Output parameters.
Output parameters of D-Bus methods and signals are mapped to Lisp objects.
D-Bus type | Lisp type | |
DBUS_TYPE_BOOLEAN | → |
|
DBUS_TYPE_BYTE | → | natural number |
DBUS_TYPE_UINT16 | → | natural number |
DBUS_TYPE_INT16 | → | integer |
DBUS_TYPE_UINT32 | → | natural number |
DBUS_TYPE_UNIX_FD | → | natural number |
DBUS_TYPE_INT32 | → | integer |
DBUS_TYPE_UINT64 | → | natural number |
DBUS_TYPE_INT64 | → | integer |
DBUS_TYPE_DOUBLE | → | float |
DBUS_TYPE_STRING | → | string |
DBUS_TYPE_OBJECT_PATH | → | string |
DBUS_TYPE_SIGNATURE | → | string |
DBUS_TYPE_ARRAY | → | list |
DBUS_TYPE_VARIANT | → | list |
DBUS_TYPE_STRUCT | → | list |
DBUS_TYPE_DICT_ENTRY | → | list |
The resulting list of the last 4 D-Bus compound types contains as elements the elements of the D-Bus container, mapped according to the same rules.
The signal PropertyModified
, discussed as an example in
Inspection of D-Bus services., would offer as Lisp data the following object
(bool stands here for either nil
or t
):
(integer ((string bool bool) (string bool bool) …))
- Function: dbus-byte-array-to-string byte-array &optional multibyte ¶
If a D-Bus method or signal returns an array of bytes, which are known to represent a UTF-8 string, this function converts byte-array to the corresponding string. The string is unibyte encoded, unless multibyte is non-
nil
. Example:(dbus-byte-array-to-string '(47 101 116 99 47 104 111 115 116 115)) ⇒ "/etc/hosts"
- Function: dbus-unescape-from-identifier string ¶
This function retrieves the original string from the encoded string as a unibyte string. The value of string must have been encoded with
dbus-escape-as-identifier
. Example:(dbus-unescape-from-identifier "_30123abc_5fxyz_01_ff") ⇒ "0123abc_xyz\x01\xff"
If the original string used in
dbus-escape-as-identifier
is a multibyte string, it cannot be expected that this function returns that string:(string-equal (dbus-unescape-from-identifier (dbus-escape-as-identifier "Grüß Göttin")) "Grüß Göttin") ⇒ nil