Monday, January 7, 2013

Interprocess Communication with DBus in GTK Applications (for Beginners)

This post is meant to provide pointers to where to start developing with GTK application that use DBus as  its inter-process communication platform.

Beginners starting to program DBus in GTK applications surely rather frustrated by the lack of up to date tutorials out there. Fear not, there's  actually a lot of sample codes and tutorials in the glib2 source code distribution! Albeit not exactly for real beginners. You should still read the DBus tutorial over at http://dbus.freedesktop.org/doc/dbus-tutorial.html to understand the concepts. It's impossible to understand the glib wrapper (in the GIO part of glib)  unless you understand the DBus concepts.

I'm using Slackware 14 at the moment. So, naturally, glib2 source code is in the second DVD in the l (library) package series. Mine is glib-2.32.4. The documentation related to DBus in Glib is under the GIO section because GIO is the part of Glib which implements the DBus bindings. If you have download glib-2.X source code, the documentation for the Glib DBus binding (GDBus) starts in the glib-[glib_version]/docs/reference/gio/html/index.html file. You'll be able to browse through all of the GDBus info from there, such as GDBusConnection, GDBusMessage and so on.

Now, for beginner, having a sample dbus server and client that actually works is of utmost importance. No problem, head over to glib GIO documentation over at http://developer.gnome.org/gio/2.29/GDBusConnection.html (Note: This is the online version of the GDBus binding documentation I mentioned in the previous paragraph). Scroll down to Example 2 (D-Bus server example), this is the DBus server source code. Now, for the DBus client, scroll down to Example 4 (D-Bus UNIX File Descriptor example), this is the DBus client source code.

Now, let's name the DBus server source code dbus_server.c and the client dbus_client.c. This is the Makefile I used to build both sample code:
all:
 gcc $(shell pkg-config --cflags --libs gtk+-3.0) dbus_server.c -o dbus_server
 gcc $(shell pkg-config --cflags --libs gtk+-3.0) dbus_client.c -o dbus_client

clean: 
 rm -vf *~ dbus_server dbus_client
Just invoke make to build them all in your shell. I made some changes to the DBus server code to display verbose logging in the shell. These are the changes:
77,78c77,78
<                                                  "As requested, here's a GError not registered "
<        "(G_IO_ERROR_FAILED_HANDLED)");
---
>                                                  "As requested, here's a GError not registered 
> (G_IO_ERROR_FAILED_HANDLED)");
85,86c85,86
<                                                  "As requested, here's a GError that is registered "
<        "(G_DBUS_ERROR_MATCH_RULE_NOT_FOUND)");
---
>                                                  "As requested, here's a GError that is registered 
> (G_DBUS_ERROR_MATCH_RULE_NOT_FOUND)");
160,161c160,161
<                                                       "Your message bus daemon does not support "
<             "file descriptor passing (need D-Bus >= 1.3.0)");
---
>                                                       "Your message bus daemon does not support file 
> descriptor passing (need D-Bus >= 1.3.0)");
298,299d297
<   g_printf("Timeout reached! \n");
< 
339,340d336
<   g_printf("DBus \"bus\" acquired! \n");
< 
361d356
<   g_printf("DBus \"name\" acquired! \n");
369,370d363
<   g_printf("Connection to DBus lost!\n");
< 
398,399d390
<   g_printf("Entering g_main_loop_new() ..\n");
< 
403,404d393
<   g_printf("Leaving g_main_loop_new() ..\n");
< 
411,413d399
< 
< 
They're not major changes, just to log where the execution is in the server code at runtime.

Screenshot time.. This is how it looks like when I run the DBus server and then the DBus client shortly thereafter. The screenshot is taken on the shell that runs the DBus server.

Mind you that this is Glib 2.0 used in GTK+3.0 or above, not GTK+2.0! Also, you should run the applications under X11, otherwise they will not be able to connect to DBus because the required glib2 library call failed. This is because in most Linux distribution, the GDK library--which GTK depends on--is built with X11 back-end. You can check this dependency with the following command:
me@my_machine:~/$ pkg-config --cflags --libs gdk
-I/usr/include/gtk-1.2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include -lgdk -lXext -lX11 -lm -lglib
As you can see, the output of the command in my machine shows dependency to X11, namely in the -lXext -lX11 linker parameters.

Anyway, you could actually watch the DBus "messages" in real time as the exchange from the server and client application happens with dbus-monitor. Just run dbus-monitor in another shell before you run the client. You could filter out unwanted messages from showing-up with dbus-monitor options.

Well, hopefully this is enough to help those poor souls looking for DBus and GTK beginner's guide out there.
Post a Comment

No comments: