D-Bus Makes for Application Teamwork

Tagged with Regular Expressions

D-Bus gives Linux a significant benefit that Windows long claimed as part of its dominance: a component model.

It's worth a moment to understand clearly what this has meant for Windows. COM, and its relatives DDE, DCOM, OLE, and so on, standardized inter-process communications (IPC) to such an extent that there's a whole market of little COM-based conveniences that play together more-or-less reliably. Windows programmers have the expectation they can plug in a COM piece that implements a visual widget or a hardware interface, and it'll work.

That's something Linux has lacked. We especially need to understand the situation now, because Linux Developer Network's theme this month is "desktop development." Linux certainly has a wealth of IPC mechanisms, but they have never been used in a sufficiently standard way to support the "ecology" or marketplace Windows has enjoyed. In part it's not necessary, because the prevalence of shared open-source solutions solves programming needs without proprietary components. However, even fully free software can benefit from the leverage other applications and libraries give.

Let's see what D-Bus adds to the mix.

Just Another IPC?

More precisely, let's look at how we can program creatively with D-Bus, and what it brings to the applications we're developing.

At one level, D-Bus is just another definition for IPC, like CORBA or SOAP or named pipes or any of scores of other examples that move data between processes. D-Bus particularly emphasizes the different processes on a particular desktop, though, that is, the different processes visible within a particular user's local "workspace". D-Bus indirectly helps standardize the semantics of, for example, "drag and drop": what does it mean when you drag the icon for a particular document visible on the desktop within the window manager of your choice, to the icon for a particular application? D-Bus itself is available not only cross-platform, for operating systems beyond Linux, but cross-desktop, operating roughly equally well on whichever desktop manager you and your end-users launch.

At this point, D-Bus technology is reliable, well-understood, and in wide use. The standard tutorial on D-Bus explains the low-level technology well, despite its authors' disclaimers about the incompleteness of the tutorial. "Connect Desktop apps using D-BUS" is a seminal presentation on how to use D-Bus in C or Python to get from one application to another.

Not so well-appreciated, in contrast, are the higher-level practices and conventions D-Bus's low-level IPC enables. It is hard to "get a handle" on these, and keep up with the latest and best D-Bus results. While there are multiple published lists of dozens of applications that use D-Bus, including those of Wikipedia and freedesktop.org, we know there are at least dozens of other applications currently on none of the lists.

Language-Neutral Scriptability

One of the pleasant patterns D-Bus encourages is language-neutral scriptability. Suppose you're the author of an application that would profit from an extension language: you want to expose aspects of the application so end-users can configure or script it themselves. Traditionally, one embedded a language that's particularly good at "playing with others," like Lua or Tcl, within the same process as the application.

D-Bus, though, makes it possible to set the application up as a simple D-Bus server process, then use any D-Bus-capable scripting language to control it. As an application developer, you short-cut any training in or justification of a particular scripting language--your users simply pick one that already makes them comfortable.

Skype exemplifies this capability. Skype is a popular proprietary voice-over-internet family of products, which embeds an open application programming interface. Skype applications have been written in C, Python, Java, Mono, Perl, Ruby, and likely other applications. Schelte Bron, a developer experienced with home automation systems, wrote a general-purpose binding of D-Bus to Tcl he calls dbus-tcl. This makes it possible to write such demonstrations as

      package require dbus
       dbus connect
      
       # Setup a handler for messages from Skype
       dbus register /com/Skype/Client notify
      
       # Setup a handler for name change signals ...
       dbus register /org/freedesktop/DBus monitor
       # ... and ask the D-Bus server to notify us about name changes
       dbus filter add -type signal -path /org/freedesktop/DBus \
         -interface org.freedesktop.DBus -member NameOwnerChanged
      
       # Print a string on stdout with a timestamp in milliseconds
       proc ts {str} {
           set ts [clock milliseconds]
           set s [expr {$ts / 1000}]
           set ms [expr {$ts % 1000}]
           puts [format {%s.%03d: %s} [clock format $s -format %T] $ms $str]
       }
      
       # Send a command to Skype
       proc skypecmd {args} {
           ts [info level 0]
           set rc [dbus call -autostart no -dest com.Skype.API \
             /com/Skype com.Skype.API Invoke [join $args]]
           ts "=> $rc"
           return $rc
       }
      
       # Handle notify calls from Skype
       proc notify {info args} {
           ts [join $args]
       }
      
       # Connect to Skype
       proc connect {} {
           after cancel connect
           # We get an error if Skype is not running
           if {[catch {skypecmd NAME skype-tcl} result]} return
           if {$result eq "OK"} {
              # Skype is running and connected. Initiate communication.
              skypecmd PROTOCOL 7
              skypecmd GET SKYPEVERSION
           } else {
              # Skype is not yet ready. Try again a little later.
              after 500 connect
           }
       }
      
       proc monitor {info name old new} {
           if {$name eq "com.Skype.API"} {
              # As soon as Skype starts, try to connect
              if {$old eq ""} connect
              # Report when Skype terminates
              if {$new eq ""} {ts "Skype terminated"}
           }
       }
      
       connect
       vwait forever
    

The original of this program appears in The Tclers' Wiki.

This example shows how easy it is to have programmatic access to such events within Skype as a name change signal. The bindings in other languages such as Python and Perl are just as idiomatic and concise.

If you begin to work on your own D-Bus projects, make sure to learn the debugging or introspection tools taught by this KDE tutorial. qdbus is an example: among its capabilities are reports from the command line on the services, objects, and interfaces of both the system and session bus. Also valuable: Ars Technica provides working code and commentary for a D-Bus-based applet, which turns the Pidgin instant-messaging application into a Twitter source.

Later in the year, we'll return to look at other examples of the growing popularity of D-Bus as a programming interface in a Linux desktop based on communicating components. D-Bus doesn't play exactly the same technical role as COM or DCOM; its networking semantics are different, it's not "baked in" development tools at the same low level, and so on. D-Bus does look to be on course, though, for wide and productive use, and, as its Windows analogues have done, will encourage a more component-based approach to desktop programming.

Kathryn and Cameron run their own consultancy, Phaseit, Inc., specializing in high-reliability and high-performance applications managed by high-level languages. They write about scripting languages and related topics in their "Regular Expressions" columns.

 

4
Average: 4 (2 votes)