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 | |
t and nil | → | 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.
- An array must contain only elements of the same D-Bus type. It can be empty.
- A variant must contain only a single element.
- A dictionary entry must be an element of an array, and it must contain only a key-value pair of two elements, with a basic D-Bus type key.
- There are no restrictions for structs.
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.
⇒ 3Function: dbus-string-to-byte-array string
Sometimes, D-Bus methods require as input parameter an array of bytes, instead of a string. This function converts string into an array of bytes of the UTF-8 encoding of string. 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 | → | t or nil |
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
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 Lisp string. The contents of byte-array should be the byte sequence of a UTF-8 encoded string. 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