Thursday, 17 April 2008

simple qdbus tutorial (part two)

Following on from part one of my qdbus tutorial, we move on to look into what happens when we try to manipulate a D-Bus capable application that is already running in remote session. This is not as easy as one might imagine. It's certainly not difficult, but it did take me a little while and some help off the mailing lists to work out what I wanted to do.

For demonstration purposes, I shall be logged in remotely on my home machine via ssh. If I run qdbus as per the last tutorial it fails immediately.
cm@pablo:~> qdbus
Could not connect to D-Bus server: org.freedesktop.DBus.Error.Spawn.ExecFailed: dbus-launch failed to autolaunch D-Bus session: Autolaunch error: X11 initialization failed.
X11? WTF? This may initially seem that qdbus is dependent on an accessible X session. Indeed, if I were to log out, and login again using ssh -X this problem would go away. The big issue being that I would then be connecting to the bus on the local machine and not the remote one which I am trying to manipulate.

What's really happening here is that qdbus is looking for the all important shell variable DBUS_SESSION_BUS_ADDRESS which contains a unique address for each bus. Not finding this, it's running dbus-launch --autostart to try and determine the address by querying another X window. Of course it then fails if it is unable to connect to any X session.

The obvious way to get around this is to set this variable. But how do we determine the bus address that we need to connect to our running instance of a program? This is not difficult, but it's not the most obvious method. As far as I am aware, there is no other easy way to do this - perhaps in future versions this will become more trivial.

The first thing to do is determine the PID of the app that we are after (ktorrent as in the last example).
cm@pablo:~> ps -ef|grep -i ktorrent
cm 4685 1 1 08:50 ? 00:06:17 ktorrent
So, we can see that ktorrent has a PID of 4685. Now to determine the relevant bus address being used by this program (obviously replacing the example PID with the actual one).
cm@pablo:~> cat /proc/4685/environ
This will spew out a stack of environment variables, amongst them, with any luck, the one we are after: DBUS_SESSION_BUS_ADDRESS. What we want to do is export this shell variable, so it is available to our shell session and we in turn will be able to manipulate our app:
export DBUS_SESSION_BUS_ADDRESS="unix:abstract=/tmp/dbus-tIGLky9nbN,guid=49eaa775154aa8aa83ba330048070013"
The above will all be on one line of course (or properly escaped). Having done this, set your faces to stunned as now when you run qdbus, you are now seeing the apps on the correct bus:
cm@pablo:~> qdbus
:1.0
org.ktorrent.ktorrent
:1.2
org.kde.klauncher
:1.3
org.kde.kded
org.kde.kwalletd
:1.69
:1.70
org.freedesktop.DBus
And that's the end of my introduction to qdbus!

simple qdbus tutorial (part one)

If you are a reasonably seasoned user of kde, the chances are you will have encountered the Desktop COmmunications Protocol, or DCOP. Now, DCOP has many uses, it is useful for apps to communicate with each other, it is certainly handy when scripting for a GUI app. Personally I find the most useful aspect of DCOP is the ability to control GUI apps remotely, and to see what they are up to. For example, if I wish to find out what song amarok is playing on a remote machine, I can execute the following on the command line (as root):
dcop --user fred amarok player nowPlaying
Pretty nifty. But DCOP is now being phased out, and is being replaced by D-Bus. D-Bus is heavily influenced by DCOP and the basics are fairly easily learned.

This post will attempt to show how to communicate with D-Bus, specifically using qdbus. (qdbusviewer may be a topic for another time, but do have a look at it - it may be a whole lot more self-explanatory).

First off, let's see what happens when we run qdbus on its own:
cm@fool:~> qdbus
:1.0
org.kde.KResourcesManager
org.kde.kopete
:1.2
org.kde.klauncher
:1.23
:1.3
org.kde.kded
org.kde.kwalletd
:1.30
org.ktorrent.ktorrent
:1.37
:1.38
:1.6
org.kde.kwalletmanager
:1.8
org.kde.knotify
org.freedesktop.DBus
That give us a list of all the applications we can manipulate using qdbus. In this instance we'll focus on ktorrent. First I want to see what objects are available in the application:
cm@fool:~> qdbus org.ktorrent.ktorrent
/
/KDebug
/KIO
/KIO/Scheduler
/KTorrent
/MainApplication
/ktorrent
/ktorrent/MainWindow_1
/ktorrent/MainWindow_1/actions
/ktorrent/MainWindow_1/actions/file_new
/ktorrent/MainWindow_1/actions/file_open
/ktorrent/MainWindow_1/actions/file_quit
/ktorrent/MainWindow_1/actions/options_show_statusbar
/ktorrent/MainWindow_1/actions/options_show_menubar
/ktorrent/MainWindow_1/actions/options_configure
/ktorrent/MainWindow_1/actions/options_configure_keybinding
/ktorrent/MainWindow_1/actions/options_configure_toolbars
/ktorrent/MainWindow_1/actions/help_contents
/ktorrent/MainWindow_1/actions/help_whats_this
/ktorrent/MainWindow_1/actions/help_report_bug
/ktorrent/MainWindow_1/actions/switch_application_language
/ktorrent/MainWindow_1/actions/help_about_app
/ktorrent/MainWindow_1/actions/help_about_kde
Each of these objects will have methods (functions) and variables, with which we can manipulate the program, and learn about the current status of the program.
cm@fool:~> qdbus org.ktorrent.ktorrent /KTorrent
method int org.ktorrent.KTorrent.downloadSpeed(QString torrent)
method void org.ktorrent.KTorrent.start(QString torrent)
method void org.ktorrent.KTorrent.startAll()
method void org.ktorrent.KTorrent.stop(QString torrent)
method void org.ktorrent.KTorrent.stopAll()
signal void org.ktorrent.KTorrent.torrentAdded(QString tor)
signal void org.ktorrent.KTorrent.torrentRemoved(QString tor)
method QStringList org.ktorrent.KTorrent.torrents()
method int org.ktorrent.KTorrent.uploadSpeed(QString torrent)
method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface_name, QString property_name)
method void org.freedesktop.DBus.Properties.Set(QString interface_name, QString property_name, QDBusVariant value)
method QString org.freedesktop.DBus.Introspectable.Introspect()
This gives me a list of available methods with any required arguments in brackets. The names of many of these functions makes their use obvious, for example the org.ktorrent.KTorrent.stopAll() function will stop all active torrents. If we try it, we find out that that is indeed what happens. Similarly, qdbus org.ktorrent.ktorrent /KTorrent org.ktorrent.KTorrent.torrents will list the torrents currently being downloaded:
cm@fool:~> qdbus org.ktorrent.ktorrent /KTorrent org.ktorrent.KTorrent.torrents
drivexv_drivexv.zip
As we can see, one torrent is currently being downloaded, a zip file from stereogum. A couple of things to note. Although the function description will contain brackets, the command itself must not. Arguments must be placed sequentially after the function, again without brackets.

And that's the basic usage of qdbus. Next time we'll look at doing this remotely, as the above will not work on a remote machine without tinkering a little. The reason being that you will most likely be querying a different bus to the one that is running your app.

Saturday, 12 April 2008

Zenburn for Konsole Redux

One of my favorite kde apps is konsole. A while ago I discovered Zenburn which is just about the only sane colorscheme for terminal editing of any sort, and especially in vim. Then I discovered that some enterprising chap had knocked together Zenburn for konsole. Seventh heaven ensued. But lately, as I've been dabbling in kde4 I've been really missing Zenburn in the new version of konsole. So I give you Zenburn for Konsole Redux, shamelessly built on the hard work of others so that you don't have to spend half your evening fiddling about with annoying colorscheme settings just to get it right.

UPDATED: Thanks to Sterling Winter who pointed out in the comments that the link no longer works. So here it is inline, hopefully blogger will react sanely as it so often doesn't with any code examples etc. :)

[Background]
Bold=false
Color=63,63,63
Transparency=true

[BackgroundIntense]
Bold=false
Color=63,63,63
Transparency=true

[Color0]
Bold=false
Color=63,63,63
Transparency=false

[Color0Intense]
Bold=false
Color=112,144,128
Transparency=false

[Color1]
Bold=false
Color=112,80,80
Transparency=false

[Color1Intense]
Bold=false
Color=220,163,163
Transparency=false

[Color2]
Bold=false
Color=96,180,138
Transparency=false

[Color2Intense]
Bold=false
Color=195,191,159
Transparency=false

[Color3]
Bold=false
Color=223,175,143
Transparency=false

[Color3Intense]
Bold=false
Color=240,223,175
Transparency=false

[Color4]
Bold=false
Color=80,96,112
Transparency=false

[Color4Intense]
Bold=false
Color=148,192,243
Transparency=false

[Color5]
Bold=false
Color=220,140,195
Transparency=false

[Color5Intense]
Bold=false
Color=236,147,211
Transparency=false

[Color6]
Bold=false
Color=140,209,211
Transparency=false

[Color6Intense]
Bold=false
Color=147,225,227
Transparency=false

[Color7]
Bold=false
Color=220,220,204
Transparency=false

[Color7Intense]
Bold=false
Color=255,255,255
Transparency=false

[Foreground]
Bold=false
Color=220,220,204
Transparency=false

[ForegroundIntense]
Bold=true
Color=220,220,204
Transparency=false

[General]
Description=Zenburn
Opacity=1

Copy it into ~/.kde4/share/apps/konsole/Zenburn.colorscheme and select it in the Settings->Manage Profiles->Edit Profiles Appearance tab.


Monday, 7 April 2008

And We're Off

I am trying out blokkal for the first time - I think that's where previous blogging attempts slowed to a stop - not having a quick and simple local client every time I had a post in my head. This blog will be an attempt to share my experiences, good and bad, about my linux distro of choice, openSUSE. I've been using it for at least 9 years after cutting my teeth on Redhat long before it branched into Fedora, and a look at several other distros. If I remember correctly it all started with SuSE 6 point something - certainly these archives look vaguely familiar. SuSE has *traditionally* provided a slicker desktop than the competition and that's what attracted me to it in the first place, although I've had plenty of dabbling in Debian based distros since, mostly work related. Debian (and hence, Ubuntu) have traditionally had better package management and I think that remains the case, although it will be interesting to see if openSUSE's new Sat Solver manages to compete. The openSUSE Build Service will hopefully help to bridge that gap.

Anyways, interesting times ahead, with kde4 out and looking the business, although I am yet to find it useable enough to make the switch permanent - a combination of show-stopping bugs and lack of features in konsole scaring me away. I'm a kde type mostly, although I feel very comfortable on the command line and do most of my day to day work there, including use of the redoubtable mutt.

I'm afraid I've a bit of tendency towards industrial strength language from time to time. It's only words, get over it.