[comment {-*- tcl -*- doctools manpage}]
[vset libname dbus]
[vset cmdname dbus]
[manpage_begin [vset libname] n 4.1]
[copyright {2008 Schelte Bron}]
[moddesc   {Tcl DBus extension}]
[titledesc {Tcl library for interacting with the DBus}]
[require Tcl "8.5 9.0"]
[require [vset libname] 4.1]
[see_also dbif]
[description]

The [package [vset libname]] package provides commands to interact with DBus
message buses. There are three well-known bus names: [const session],
[const system], and [const starter]. The [const starter] bus only applies
when the application has been started as a result of a method call from
another application. In that case, the [const starter] bus refers to bus on
which the other application issued the method call.
If the application was not started as a result of a method call by another
application, [const starter] is just another name for the [const session] bus.

[section "Bus IDs"]

Most subcommands take an optional [arg busID] argument.
This may be specified in either of two ways: By DBus handle or by well-known
bus name.
A DBus handle is obtained using the [cmd [vset cmdname]] [method connect]
subcommand.
The [package [vset libname]] library also maintains a per-interpreter set of
three aliases, with the same names as the well-known buses. 
Whenever a connection is created on one of these well-known buses, a check
is made whether the alias for that bus already refers to a connection.
If not, the alias is assigned to the newly created connection. The assignment
remains in effect for the lifetime of the connection. When the connection is
closed, the alias becomes unassigned.
[para]
If the [arg busID] argument is omitted, it defaults to [const session].

[section "DBus subcommands"]

[list_begin definitions]

[call [cmd [vset cmdname]] [method call] [opt [arg busID]] \
  [opt "[option -autostart] [opt [arg boolean]]"] \
  [opt "[option -dest] [arg target]"] \
  [opt "[option -details] [opt [arg boolean]]"] \
  [opt "[option -handler] [arg script]"] \
  [opt "[option -signature] [arg string]"] \
  [opt "[option -timeout] [arg ms]"] \
  [arg path] [arg interface] [arg method] \
  [opt "[arg arg] [arg ...]"] \
]

Send a method call onto the dbus and optionally wait for a reply.

If the signature of the DBus [const method_return] reply only contains one
top-level element, the arguments of the [const method_return] message are
returned as a single value. More complex structures are returned as a list.

The details of the dbus response message are added to the interpreter's
return options dictionary. The entries will be the same as those described
for the event details in the [sectref "Event Handlers"] section below.

[para]

If the response to the DBus [const method_call] message is a DBus
[const error] message, the command will produce an error. In that case the
errorCode variable will be set to [const DBUS] [const CALL] [const REPLY],
followed by the dbus error name.

[para]

The [option -autostart] option specifies whether the bus server should
attempt to start an associated application if the destination name does not
currently exist on the bus. [arg Boolean] may have any proper boolean value,
such as [const 1] or [const no]. Defaults to 1 (true).

[para]

The [option -timeout] option specifies the maximum time to wait for a
response. A negative timeout indicates that no response should be requested. 

[para]

If a script is specified with the [option -handler] option, the call will be
asynchronous. In that case the command returns the serial of the request.
The script will be executed when a response comes back or when there is an
error.

[para]

The [option -signature] option defines the types of arguments to be sent on
the dbus. See the [sectref Signatures] section for more information.
If no signature is specified, all arguments will be sent as strings.

[para]

The [option -details] option specifies how variant arguments in the return
value are represented. With the default value of FALSE, only the value of a
variant argument is provided. But in some situations the Tcl code may need
to be able to also obtain the argument type. When this option is set to TRUE,
each variant argument is represented as a list with two elements. The first
list element contains the signature of the argument and the second list
element is the value.

[para]

[call [cmd [vset cmdname]] [method close] [opt [arg busID]]]

Close the connection to the DBus. This will cleanup all handlers, listeners,
and the optional monitor script registered for the [arg busID].

[para]

[call [cmd [vset cmdname]] [method connect] [opt [arg address]]]

Connect to the DBus. The [arg address] argument specifies the bus to connect
to. This can be either one of the well-known buses ('session', 'system' or
'starter'), or a transport name followed by a colon, and then an optional,
comma-separated list of keys and values in the form key=value.
The command returns a handle that can be used as the [arg busID] argument
in other [vset libname] commands.

[para]

It is possible to create multiple connections to the same DBus. But that should
normally be avoided, unless there is a good reason. One good reason would be if
the program uses normal DBus operations, but also needs to monitor the traffic
on the DBus using the BecomeMonitor method.

[para]

[call [cmd [vset cmdname]] [method error] [opt [arg busID]] \
  [opt "[option -name] [arg string]"] \
  [arg destination] [arg serial] \
  [opt message] \
]

Send a DBus [const error] message with the specified [arg serial] and
[arg destination]. If the [option -name] option is not specified, it
defaults to "org.freedesktop.DBus.Error.Failed".

The values for [arg destination] and [arg serial] can be obtained from event
information fields 'sender' and 'serial' correspondingly.
See [sectref "Event Handlers"] below for more information.

[para]

When employing this subcommand, make sure the result of the
[method [vset cmdname]] [method method] script isn't automatically returned
to the caller by using the [option -async] option of the [cmd return]
command. See [method [vset cmdname]] [method method] for more information.

[para]

[call [cmd [vset cmdname]] [method filter] [opt [arg busID]] [arg subcommand] \
  [arg key] [arg value] [opt [arg ...]] \
]

The [method add] subcommand adds a match rule to match messages going through
the message bus. The [method remove] subcommand removes the most recently
added rule that exactly matches the specified [arg key]/[arg value] pairs.
If there is no matching rule, the command is silently ignored.
Available keys are: [arg arg#], [arg arg#path], [arg arg0namespace],
[arg destination], [arg eavesdrop], [arg interface], [arg member], [arg path],
[arg path_namespace], [arg sender], and [arg type], where # represents an
argument index (0 to 63).
Using both [arg path] and [arg path_namespace] in the same match rule is not
allowed.
The command returns the match rule passed to libdbus.

[para]

[call [cmd [vset cmdname]] [method info] [opt [arg busID]] [arg option]]

The info command can be used to obtain information about the DBus.
Available [method info] options are:
[list_begin commands]
[cmd_def [method capabilities]] Returns a dict describing the capabilities of
the dbus connection. Currently only one capability has been defined: unixfd,
which indicates if file descriptor passing is supported on the dbus connection.
[cmd_def [method local]] The object path used in local/in-process-generated
messages ([const /org/freedesktop/DBus/Local]).
[cmd_def [method machineid]] Get the UUID of the local machine.
[cmd_def [method name]] Get the unique name of the connection as assigned by
the message bus.
[cmd_def [method path]] The object path used to talk to the bus itself
([const /org/freedesktop/DBus]).
[cmd_def [method pending]] Report if any messages are in the queue to be sent.
[cmd_def [method serverid]] Get the UUID of the server we are authenticated to.
[cmd_def [method service]] The bus name used to talk to the bus itself
([const org.freedesktop.DBus]).
[cmd_def [method version]]Returns the version of libdbus.
[list_end]
[para]

[call [cmd [vset cmdname]] [method listen] [opt [arg busID]] \
  [opt [option -details]] \
  [opt "[arg path] [opt "[arg member] [opt [arg script]]"]"] \
]

Register a [arg script] to be called when the signal named "[arg member]" at
[arg path] appears on the DBus.
See [sectref "Event Handlers"] below for more information.

[para]

If the [arg path] argument is an empty string, [arg script] will be executed
whenever a signal message is received for any path, unless a dedicated
listener for the exact path has been defined.
The [arg member] argument may be specified as either a signal name or an
interface and signal name joined by a period. If no interface is specified,
the script will be called for signals with any interface.

[para]

If [arg script] is an empty string, the currently registered command for the
specified signal and path will be unregistered.

If the [arg script] argument is not specified, the currently registered
command for the specified signal and path, if any, is returned.
If no [arg member] argument is specified a list of all registered signals
and associated commands at the specified path is returned.
If no [arg path] argument is specified a list of all paths and their
registered signals and associated commands is returned.

[para]

The [option -details] option causes variant arguments to be represented as a
list with two elements: The first list element contains the signature of the
argument and the second list element is the value.

[para]

In most cases it will be necessary to set up a filter to ensure the desired
signals are delivered to the application.
Otherwise only signals that are explicitly sent to the application will be
received. Signals don't usually have a destination specified.

[para]

[call [cmd [vset cmdname]] [method method] [opt [arg busID]] \
  [opt [option -details]] \
  [opt "[arg path] [opt "[arg member] [opt [arg script]]"]"] \
]

Register a [arg script] to be called when method [arg member] is invoked at
the specified [arg path].
See [sectref "Event Handlers"] below for more information.

[para]

If the [arg path] argument is an empty string, [arg script] will be executed
whenever a method call message is received for any path, unless a dedicated
method handler for the exact path has been defined.
The [arg member] argument may be specified as either a method name or an
interface and method name joined by a period. If no interface is specified,
the script will be called for methods with any interface, unless another
handler is specified for the method including the interface.

If [arg script] is an empty string, the currently registered command for the
specified method and path will be unregistered.

[para]

If the [arg script] argument is not specified, the currently registered
command for the specified method and path, if any, is returned. 

If no [arg member] argument is specified a list of all registered methods
and associated commands at the specified path is returned.

If no [arg path] argument is specified a list of all paths and their
registered methods and associated commands is returned.

[para]

When [arg script] is evaluated, the return value of the script will normally
be returned to the caller using a DBus [const method_return] message in a
string argument.

If the execution of [arg script] ends with an error, the error message is
returned to the caller in a DBus [const error] message. By default, the
error name is "org.freedesktop.DBus.Error.Failed". But the script may pass
a [option -name] option (along with [option -code] [arg error]) to the Tcl
[cmd return] command to return a different error name.
Any DBus errors that happen while sending these messages back to the caller
are silently ignored. 

If the caller specified the [const no_reply] flag in the [const method_call]
as TRUE, no [const method_return] or [const error] message will be returned.

[para]

The script code recognizes an additional [option -async] option for the Tcl 
[cmd return] command. When that option is specified with a true boolean 
value ([const true], [const yes], [const 1]), the return value from the body
will not automatically be returned to the caller. A response message should
then be generated using the [cmd [vset cmdname]] [method return] or 
[cmd [vset cmdname]] [method error] subcommands.

[para]

This method provides more advanced control over the returned messages. It
allows for more complex data structures than just a string to be returned.
It also makes it possible to generate a return message some time after
[arg script] has already finished. Additionally, any dbus errors while
sending back the return message can be detected and handled.

[para]

The [option -details] option causes variant arguments to be represented as a
list with two elements: The first list element contains the signature of the
argument and the second list element is the value.

[para]

[call [cmd [vset cmdname]] [method monitor] [opt [arg busID]] \
  [opt [option -details]] [arg script] \
]

Register a [arg script] to be executed when any DBus message is received.

See [sectref "Event Handlers"] below for more information.

[para]

This can be useful for building special purpose programs that need to see
all activity on the DBus, for example a DBus monitoring program. 
If [arg script] is an empty string, the currently configured monitor script
will be removed.

[para]

The [option -details] option causes variant arguments to be represented as a
list with two elements: The first list element contains the signature of the
argument and the second list element is the value.

[para]

[call [cmd [vset cmdname]] [method name] [opt [arg busID]] \
  [opt "[option -option] [arg ...]"] [arg name] \
]

Request the bus to assign a given name to the connection. The command will
generate an error in all cases where it was unsuccessful in making the
application the primary owner of the name. 

[para]

The [option -yield] option specifies that the application will release the
requested name when some other application requests the same name and has
indicated that it wants to take over ownership of the name. The application
will be informed by a [emph NameLost] signal when it loses ownership of the
name.

The following command can be used to exit the application when the name is
taken over by another process:
[example_begin]
dbus listen [lb]dbus info path[rb] [lb]dbus info service[rb].NameLost \
  [lb]list apply {{name info str} {if {$str eq $name} exit}} $name[rb]
[example_end]

The [option -replace] option indicates that the application wants to take
over the ownership of the name from the application that is currently the
primary owner, if any. This request will only be honored if the current
owner has indicated that it will release the name on request.
See also the [option -yield] option.

[para]

If the requested name is currently in use and the [option -replace] option
has not been specified, or the [option -replace] option was specified but
the current owner is unwilling to give up its ownership, the name request
will normally be queued. Then when the name is released by current owner it
is assigned to the next requester in the queue and a signal is sent to inform
that requester that it is now the primary owner of the name.

The [option -noqueue] option may be specified to indicate that the name
request should not be queued.

[para]

Note that even if the request has been queued, the command will generate an
error because the goal of becoming the primary owner of the name has not
been achieved.

[para]

[call [cmd [vset cmdname]] [method release] [opt [arg busID]] [arg name]]

Asks the bus to unassign the given name from this connection.

[para]

[call [cmd [vset cmdname]] [method return] [opt [arg busID]] \
  [opt "[option -signature] [arg string]"] \
  [arg destination] [arg serial] \
  [opt "[arg arg] [arg ...]"] \
]

Send a DBus [const method_return] message with the specified [arg serial]
and [arg destination]. 

The values for [arg destination] and [arg serial] can be obtained from event
information fields 'sender' and 'serial' correspondingly. 

See [sectref "Event Handlers"] below for more information.

[para]

When employing this subcommand, make sure the result of the
[method [vset cmdname]] [method method] script isn't automatically returned
to the caller by using the [option -async] option of the [cmd return]
command. See [method [vset cmdname]] [method method] for more information.

[para]

[call [cmd [vset cmdname]] [method signal] [opt [arg busID]] \
  [opt "[option -dest] [arg target]"] \
  [opt "[option -signature] [arg string]"] \
  [arg object] [arg interface] [arg name] \
  [opt "[arg arg] [arg ...]"] \
]

Send a signal onto the dbus with the specified type signature. If no
[option -signature] option is provided, all [arg arg]s will be sent as
strings.
Signals are normally broadcast on the bus.
In specific scenarios, a signal may only need to be sent to a specific
destination.
This can be achieved by using the [option -dest] option.
The command returns the serial number of the dbus message.

[para]

[call [cmd [vset cmdname]] [method unknown] [opt [arg busID]] \
  [opt [option -details]] [opt "[arg path] [opt [arg script]]"] \
]

Register a [arg script] to be called when an unknown method is invoked at
the specified [arg path].
See [sectref "Event Handlers"] below for more information.

[para]

If the [arg path] argument is an empty string, [arg script] will be executed
whenever an unknown method call message is received for any path, unless a
dedicated unknown handler for the exact path has been defined.

If [arg script] is an empty string, the currently registered command for the
specified path will be unregistered.

[para]

If the [arg script] argument is not specified, the currently registered
command for the specified path, if any, is returned. 

If no [arg path] argument is specified, a list of all paths and their
registered unknown handlers is returned.

[para]

An unknown handler will usually return an error, but it is also possible to
return a non-error response. The [cmd [vset cmdname]] [method error] and
[cmd [vset cmdname]] [method return] subcommands should be used for this
purpose.

Contrary to the [cmd [vset cmdname]] [method method] subcommand, the return
value of the handler will not automatically be returned to the caller.

Any uncaught error in the evaluation of [arg script] will be reported back
to the caller.

[para]

The [option -details] option causes variant arguments to be represented as a
list with two elements: The first list element contains the signature of the
argument and the second list element is the value.

[para]

It will generally not be necessary to set up unknown handlers. If no unknown
handler is specified, the package returns an
[const org.freedesktop.dbus.error.unknownmethod] error back to the caller of
an unknown method.

[para]

[call [cmd [vset cmdname]] [method validate] [arg class] [arg string]]

Validates [arg string] against the rules of the D-Bus specification for
the type of value specified by [arg class]. Returns 1 if validation passes,
otherwise returns 0. The following classes are recognized (the class name
can be abbreviated):

[list_begin definitions]
[def [const interface]] Two or more dot-separated non-empty elements.
Each element only contains the ASCII characters 
"[lb]A-Z[rb][lb]a-z[rb][lb]0-9[rb]_" and does not begin with a digit.

[def [const member]] A string that only contains the ASCII characters
"[lb]A-Z[rb][lb]a-z[rb][lb]0-9[rb]_" and does not begin with a digit.

[def [const name]] Either a unique connection name, or a well-known
connection name. Unique connection names begin with a colon and consist of
at least two dot-separated non-empty elements. Each element only contains
the ASCII characters "[lb]A-Z[rb][lb]a-z[rb][lb]0-9[rb]_-".
Well-known connection names consist of at least two dot-separated
non-empty elements. Each element only contains the ASCII characters
"[lb]A-Z[rb][lb]a-z[rb][lb]0-9[rb]_-" and does not begin with a digit.

[def [const path]] A slash followed by zero or more slash-separated 
non-empty elements. Each element only contains the ASCII characters
"[lb]A-Z[rb][lb]a-z[rb][lb]0-9[rb]_".

[def [const signature]] A valid D-Bus message type signature. See
[sectref Signatures] below for more information on what constitutes a
valid signature.
[list_end]
[para]

[list_end]

[section "Event Handlers"]
The [method call], [method listen], [method method], [method monitor], and
[method unknown] methods provide the ability to define event handlers. The
specified script will be used as the prefix for a command that will be
evaluated whenever the corresponding DBus event occurs. When the DBus event
occurs, a Tcl command will be generated by concatenating the script with one
or more arguments. The first argument is a dict containing information about
the event. If the DBus event contained any arguments they will be appended to
the command as separate arguments.

[para]
The dict with the event details contains the following information:
[list_begin definitions]
[def member] The interface member being invoked (for methods) or emitted
(for signals).
[def interface] The interface this message is being sent to (for methods)
or being emitted from (for signals). The interface name is fully-qualified.
[def path] The object path this message is being sent to (for methods) or
being emitted from (for signals).
[def sender] The unique name of the connection which originated this message,
or the empty string if unknown or inapplicable. The sender is filled in by
the message bus. Note, the returned sender is always the unique bus name.
Connections may own multiple other bus names, but those are not found in the
sender field.
[def destination] The destination of a message or the empty string if there
is none set.
[def messagetype] The type of a message. Possible values are
[const method_call], [const method_return], [const error], and [const signal].
[def signature] The type signature of the message, i.e. the type specification
of the arguments in the message payload. See [sectref Signatures] below for
more information.
[def serial] The serial of a message or 0 if none has been specified. The
message's serial number is provided by the application sending the message
and is used to identify replies to this message. All messages received on a
connection will have a serial provided by the remote application. When
sending messages a serial will automatically be assigned by the [vset libname]
library.
[def replyserial] The serial that the message is a reply to or 0 if none.
[def noreply] Flag indicating if the sender expects a reply. Set to 1 if a
reply is [emph not] required.
[def autostart] Flag indicating if the message will cause an owner for
destination name to be auto-started.
[def errorname] The error name of a received error message. An empty string
for all other message types.
[list_end]

The event handlers are executed at global level (outside the context of any
Tcl procedure) in the interpreter in which the event handler was installed.

[section Signatures]
The DBus specification defines typed arguments. This doesn't fit well with
the Tcl philosophy of [term "everything is a string"]. To be able to closely
control the type of the arguments to be sent onto the DBus a [const signature]
can be supplied. The signature definition is exactly the same as in the DBus
specification. A signature is a string where a single character or group of
characters specifies the type of an argument. The following types exist:
[list_begin definitions]
[def s] A UTF-8 encoded, nul-terminated Unicode string.
[def b] A boolean, FALSE (0), or TRUE (1).
[def y] A byte (8-bit unsigned integer).
[def n] A 16-bit signed integer.
[def q] A 16-bit unsigned integer.
[def i] A 32-bit signed integer.
[def u] A 32-bit unsigned integer.
[def x] A 64-bit signed integer.
[def t] A 64-bit unsigned integer.
[def d] An 8-byte double in IEEE 754 format.
[def h] A file descriptor. 
[def g] A type signature.
[def o] An object path.
[def a#] A D-Bus array type, which is similar to a Tcl list. The # specifies
the type of the array elements. This can be any type, including another
array, a struct or a dict entry.
[def v] A D-Bus variant type. The provided value should be a two-element list,
containing a signature and the actual value. See [sectref "Variant Arguments"]
for more information.
[def (...)] A struct. The string inside the parentheses defines the types of
the arguments within the struct, which may consist of a combination of any
of the existing types.
[def {{##}}] A dict entry. Dict entries may only occur as array elements. The
first # specifies the type of the dict key. This must be a basic type
(one of 'sbynqiuxtdgo'). The second # specifies the type of the dict value.
This can again be any existing type.
[list_end]
[emph Example]: The signature 'vaas(id)a{i(ss)}' specifies four arguments and
translates to Tcl terminology as follows: The type of the first argument
('v') is extracted from its value. The second argument ('aas') is a list
containing lists of strings. The third argument ('(id)') is a list containing
an integer and a double. The last argument ('a{i(ss)}') is a dict (an array
of dict entries) with integer keys and each value is a list of two strings.

[subsection "Variant Arguments"]

When a signature specifies that an argument is of type "variant", the
argument can still be almost anything. Additional information needs to be
located to determine how to package the value for transmission onto the
dbus. The preferred way is for the argument to be a two-element list where
the first element specifies the signature for the value and the second
element is the actual value.

[para]

The signature for a variant argument has to specify a single complete type.
The value of the second list element must match the signature, otherwise an
error will be reported.

[para]

If the value provided for a variant argument is not a two-element list, or
the first element is not a valid signature for a single complete type, the
code will attempt to automatically determine the type of the provided value.
It does this by selecting a signature based on the internal representation
of the value according to the following table:
[list_begin definitions]
[def "string: s"]
[def "int: i"]
[def "wideInt: x"]
[def "double: d"]
[def "boolean: b"]
[def "list: as"]
[def "dict: a{ss}"]
[def "anything else: s"]
[list_end]

[subsection "File descriptors"]
On output, the value provided for a file handler argument must be an open Tcl
channel (such as has been created with the open or socket commands). An error
will be thrown if the value does not represent an open channel, or if the dbus
connection does not support passing file handler arguments.
[para]
On input, a new channel will be created and its name passed to the script. The
new channel is opened for both reading and writing. If this is not desired,
either direction may be closed using the appropriate half-close version of the
close command.
[para]
The channel name is likely to be different in the two involved applications.
When finished with the channel, both parties are responsible for closing the
channel using their own channel reference.
[manpage_end]
