Apr 30, 2008

D-Bus Sightseeing

I figured it was time to learn more about D-Bus. Today, let me share some useful calls that I found so far. Hopefully they will inspire you to experimenting too and together we will have a chance of learning more.
$ dbus-send --print-reply \
--dest=org.kde.klipper \
/klipper \
org.kde.klipper.klipper.getClipboardContents
method return sender=:1.37 -> dest=:1.73 reply_serial=2
string "Hello D-Bus"

Your result will be probably different. In fact, I spent several minutes wondering why the method does not return anything and just repeats its name ;-)
The meaning of the parameters: --dest is the destination connection; apparently D-Bus cannot find it out from the following parameter: /klipper: the destination object. org.kde.klipper.klipper is the interface. Most objects have their own interface plus the introspection interface org.freedesktop.DBus.Introspectable. getClipboardContents is of course the method name.

For further exploration, the GUI tool qdbusviewer is very useful. Try it for calling getClipboardContents now.
$ dbus-send --type=method_call --dest=org.kde.kwin \
/KWin org.kde.KWin.nextDesktop
$ dbus-send --type=method_call --dest=org.kde.kwin \
/KWin org.kde.KWin.previousDesktop
$ dbus-send --type=method_call --dest=org.kde.plasma \
/App org.kde.plasma.App.toggleDashboard
The type option is necessary because dbus-call defaults to type=signal which would not work. (BTW does anyone have a nice example for demonstrating a signal?) With print-reply in the first example, type=method_call is implied.

Let's pass some arguments:
$ dbus-send --type=method_call --dest=org.kde.klipper \
/klipper org.kde.klipper.klipper.setClipboardContents \
string:'Test Beta2!'
$ dbus-send --type=method_call --dest=org.kde.krunner \
/Interface org.kde.krunner.Interface.display \
string:'system'
So far we have been using the session bus. The system-wide bus offers even more fun:
$ dbus-send --system --print-reply \
--dest=org.freedesktop.NetworkManagerSystemSettings \
/org/freedesktop/NetworkManagerSettings \
org.freedesktop.NetworkManagerSettings.ListConnections

array [
object path "/org/freedesktop/NetworkManagerSettings/0"
object path "/org/freedesktop/NetworkManagerSettings/1"
object path "/org/freedesktop/NetworkManagerSettings/2"
]

$ dbus-send --system --print-reply \
--dest=org.freedesktop.NetworkManagerSystemSettings \
/org/freedesktop/NetworkManagerSettings/1 \
org.freedesktop.NetworkManagerSettings.Connection.GetSettings

array [
dict entry(
string "802-11-wireless"
array [
dict entry(
string "ssid"
variant array [
byte 102
byte 114
byte 111
byte 103
byte 115
]
)
dict entry(
string "security"
variant string "802-11-wireless-security"
)
]
)
/* more data. BTW you can't see any of this in qdbusviewer. */
]
(Interesting, every even call to NMS fails with a timeout)

Finally, a long list to scroll up while the music plays:
$ dbus-send --system --print-reply \
--dest=org.freedesktop.Hal \
/org/freedesktop/Hal/Manager \
org.freedesktop.Hal.Manager.GetAllDevices

2 comments:

korshak said...

Can i ask you to give some working "hello world" example with dbus-send for KNotify?
I think it can be very usable to run notifications from bash or perl scripts,
or just make something like that:
emerge -uND --world && knotify "Done!"

But i still can not understand DBus logic :(

Martin Vidner said...

The answer was enough for a whole new post :-)