DBus and Gambas
Introduction
The
DBus system is (almost) fully supported in Gambas 3, by the
gb.dbus
component.
What is DBus ? It is a "message bus system", i.e. a little program that can
pass different kinds of messages between applications. It's like the old KDE 3
DCOP system. For more information, see
http://dbus.freedesktop.org.
There are normally two kind of bus running on your machine: the "system bus",
that is global and unique, and the "session bus", that is launched for each
connected user.
gb.dbus allows you to:
-
Call any method or property exported by any application that is connected with the bus.
-
Catch any signal raised by any interface.
-
Export any Gambas object to DBus.
Note that the gb.dbus component has a part written in C and a part written in
Gambas. The part written in C provide hidden classes (whose name begins with
"_"
) that the part written in Gambas uses to provided the full (and easy!)
component interface.
Using objects exported by other applications
Calling methods or properties
To call a method, use the following syntax:
DBus[Application][ObjectPath].Method(Arguments)
To get the value of a property, do:
DBus[Application][ObjectPath].Property
And to set the value of a property, do:
DBus[Application][ObjectPath].Property = Value
Application is the string that identifies the application on the bus.
It can begin with
"system://"
or
"session://"
to define which bus
you want to connect with.
By default you connect with the session bus.
Examples
DBus["org.kde.kmail"]["/kmail/kmail_mainwindow_1"].geometry = [0, 24, 1024, 768]
Catching signals
Catching signals relies on two classes:
DBusObserver, and
DBusSignal.
DBusObserver is a low-level class that you should not use unless you have very specific needs.
Instead, use the DBusSignal class that is built upon the DBusObserver class.
To watch a signal, just create a new DBusSignal object that way:
hSignal = New DBusSignal(Bus, Interface, Every) As "MySignal"
-
Bus is the bus you are connecting with.
-
Interface is the name of the interface that raises the signal.
-
Every is an optional boolean flag that allows you to catch signals sent to all applications, not just yours.
Examples
MySignal = New DBusSignal(DBus.System, "org.freedesktop.Hal.Manager") As "DBusSignal"
...
Public Sub DBusSignal_Signal(Signal As String, Arguments As Variant[])
If Signal = "DeviceAdded" Then
...
EndIf
End
Exporting Gambas object to other applications
Registering the object
To export a Gambas object to
DBus, this object must inherit the
DBusObject class.
Then you have to register it to the bus with the
DBus.Session.Register or DBus.System.Register method.
Use the first method to register your object on the
Session bus, the second one to register it on the
System bus.
Examples
Dim hObject As MyClass ' MyClass inherits DBusObject
DBus.Session.Register(hObject, "/object/path")
The Gambas object is attached to an "object path", because all objects exposed
to the DBus by your application are like a hierarchical file system.
As soon as at least one object is registered, your application will be visible on the bus.
The name of your application on the bus is defined by the
DBus.Name property. By default, it is defined as
org.gambas.<xxx>
where
<xxx>
is the value of
Application.Name.
What is exported?
-
Public methods whose name has no underscore inside, and whose arguments and return type can be converted to a DBus datatype.
-
Public properties whose name has no underscore inside, and whose type can be converted to a DBus datatype.
As soon as you register at least one object, your application appears on the
bus with the name
"org.gambas.<application name>"
.
All these methods and properties are exported with an interface name named
"org.gambas.<application name>.<class name>"
.
You can check that with the DBus explorer example, or the qdbusviewer Qt4
program.
Implementing a specific interface
An object can implement specific
DBus interfaces by using the third optional argument of the Register method.
That third argument is a string array of interface names.
If this argument is not specified, then, as before, all public methods
and properties are put under the
org.gambas.<appname>.<classname>
interface.
But if this argument is specified, then all public methods and properties
whose name begins with the interface name are put under this interface.
The interface name is normalized in the method name, by replacing points by underscores,
and by adding another underscore between the interface name and the method name.
Examples
' "Open" method of the org.mpris.MediaPlayer2 interface
Public Sub org_mpris_MediaPlayer2_Open()
...
End
' "Play" method of the org.mpris.MediaPlayer2.Player interface
Public Sub org_mpris_MediaPlayer2_Player_Play()
...
End
' "Enabled" property of the org.mpris.MediaPlayer2 interface
Property org_mpris_MediaPlayer2_Enabled As Boolean
...
DBus.Session.Register(MyMediaPlayer, "/org/mpris/MediaPlayer2",["org.mpris.MediaPlayer2","org.mrpris.MediaPlayer2.Player"])
Raising signals
Since 3.9
You can raise D-Bus signals since Gambas 3.9 only.
To let an object raise signals, you must declare them first as Gambas events.
The name of the event must be the normalized name of the interface, followed by an underscore and the normalized name of the signal.
The signal is emitted to the D-Bus bus by using the
DBusApplication.Raise method.
For example, in
gb.dbus.trayicon component, the internal DBusStatusIcon class is a DBusObject implementing the
org.kde.StatusNotifierItem
interface
that can raise the "NewIcon" signal, among many others.
It is implemented that way:
Inherits DBusObject
...
Event org_kde_StatusNotifierItem_NewIcon
...
The "NewIcon" signal must be raised when the status icon image changes. It is raised in the function that implements the
Picture property:
Private Sub Picture_Write(Value As Picture)
...
DBus[GetServiceName()].Raise($hObject, "org.kde.StatusNotifierItem.NewIcon")
End
Datatype mapping
Here is a summary of how Gambas datatypes are translated to DBus datatypes, and vice versa.
Note. In this list
DBusObject refers to the DBusObject path string not the gambas DBusObject.class
Gambas datatype
|
DBus datatype
|
Boolean
|
b
|
Byte
|
y
|
Short
|
n
q
|
Integer
|
i
u
|
Long
|
x
t
|
Single
|
d
|
Float
|
d
|
Date
|
d
|
Pointer
|
x
|
String
|
s
|
Variant
|
v
|
String
(DBusObject path)
|
o
|
Boolean[]
|
ab
|
Byte[]
|
ay
|
Short[]
|
an
aq
|
Integer[]
|
ai
au
|
Long[]
|
ax
at
|
Single[]
|
ad
|
Float[]
|
ad
|
Date[]
|
ad
|
Pointer[]
|
ax
|
String[]
|
as
|
Variant[]
|
av
(TTT) *
aT *
|
String[]
(of DBusObject paths)
|
ao
|
Collection
|
a{sv}
|
*T
represents any DBus datatype.