Connect KDE applications using DCOP

Interprocess communication in scripts and at the command line

Hidden deep within the KDE desktop lies a powerful set of scripting technologies that can allow the power user to automate many tasks. In this article, Martyn Honeyford introduces these technologies and shows how you can use them to the fullest.

Martyn Honeyford (ibmmartyn@gmail.com), Software Engineer, IBM

Martyn Honeyford graduated from Nottingham University with a BS in Computer Science in 1996. He has worked as a software engineer at IBM UK Labs in Hursley, England, ever since. His current role is as a developer in the WebSphere MQ Everyplace development team. When not working, Martyn can usually be found either playing the electric guitar (badly) or playing video games more than most people would consider healthy.



26 February 2004

Every KDE desktop (from version 2.0 onwards) contains a little known yet very powerful feature called "Desktop COmmunication Protocol" or DCOP for short. From a developer's point of view, DCOP makes it very easy to add powerful scripting functionality to your applications. From a user's point of view, DCOP allows you to easily take control of your KDE applications and combine them in interesting and powerful ways.

What is DCOP?

At its heart, DCOP is basically a lightweight mechanism for inter-process communication which operates over sockets. DCOP comprises a single server (dcopserver, which is started automatically when KDE starts) and any number of clients (DCOP-enabled applications). DCOP clients can send messages to each other (via the server) to request information, ask for functions to be performed, and so on. For instance, Konqueror may (and indeed does) send DCOP messages to KMail to start up a new window with the "To" field filled in when a "mailto" link is clicked.

DCOP in action

The KDE desktop ships with two useful utilities which will help us make use of DCOP: dcop and kdcop.

The KDE DCOP browser -- kdcop

This is a little graphical utility which, once run, enumerates all of the DCOP clients running on the machine and presents them as a tree view. Each client can then be expanded to show which interfaces it supports.

Figure 1. DCOP in action
DCOP in action

This can then be expanded further, until the desired function is reached. Double clicking on the function will then call it (asking for arguments if required).

Example 1. Refresh the desktop

  1. Start kdcop from a terminal or from the KDE menu bar.
  2. From the list of applications, expand "kwin" (the KDE window manager).
  3. Now expand "KWinInterface" to show all the functions exported by the interface.
  4. These functions can now be double-clicked upon to execute them. For instance, double-click on refresh() and you should see the desktop refresh, double-click on nextDesktop() and the display will switch to the next virtual desktop.

Example 2. Open up a new Konqueror window

  1. Start kdcop from a terminal or from the KDE menu bar.
  2. Ensure that you have an instance of Konqueror running -- if one doesn't appear in the list, start a new instance. It will show up as "konqueror-NNNNN," where NNNNN is the PID of the Konqueror process.
  3. From the list of applications, expand "konqueror-NNNNN."
  4. Now expand "KonquerorInterface" to show all the functions exported by the interface.
  5. Now double click on openBrowserWindow().
  6. A dialog box should be displayed asking you to supply the URL argument. Type in a fully-qualified URL of your choice (e.g. "http://www.ibm.com/") and hit OK.
  7. You should now see a new browser window open and direct to the URL you specified.
Figure 2. Enter the URL...
Enter the URL...
Figure 3. And your favorite site pops up
And your favorite site pops up

While kdcop is a nice little tool to play around with to discover what interfaces an application supports, the second standard utility, simply named "dcop," will be of more use on a day-to-day basis.

The KDE Console DCOP client -- dcop

The command-line utility "dcop" is basically the same as kdcop, but is used from the command line. Hence, it is much more useful for scripting purposes.

For clarity, from this point onwards, dcop in lower-case refers to the command-line utility, and DCOP in upper-case refers to the DCOP architecture in general.

Let us illustrate with a few examples of the type of thing you can do using the dcop utility.

Example 3. Load up developerworks
As explained earlier, Konqueror processes show up in dcop as "konqueror-NNNNN," where "NNNNN" is the pid.

Thankfully, dcop supports wildcards, so the following command,

dcop konq*

will list all of the active dcop clients beginning in "konq."

In classic UNIX® tradition, we can combine this with the head command to give us only the first result as follows:

dcop konq* | head -1

This will print a single "konqueror-NNNNN" (or nothing if no Konqueror processes are running).

Ultimately we want to pass this single "konqueror-NNNNN" to dcop and call an appropriate function to open a URL -- we can do this simply in bash using the ` character as follows:

dcop `dcop konq* | head -1` konqueror-mainwindow#1 openURL www.ibm.com/developerworks

Figure 4. You could even alias a command-line call to your favorite Web site
A command-line call saves time over point-and-click

If you have not come across this before, enclosing something in ` characters basically says to execute the command(s) between the ` characters and replace them with the result. So the command

dcop `dcop konq* | head -1` konqueror-mainwindow#1 openURL www.ibm.com/developerworks

will execute the `dcop konq* | head -1` part, effectively giving us

dcop konqueor-NNNNN konqueror-mainwindow#1 openURL www.ibm.com/developerworks

which is then executed as normal to give us the desired effect.

Example 4. Make it fullscreen
In this example, we begin by starting a new instance of Konqueror:

konqueror &

Next we make it load developerworks:

dcop konqueror-$! konqueror-mainwindow#1 openURL www.ibm.com/developerworks

in bash, $! is automatically set by the shell to the PID of the last process to be started in the background, so this command will change the URL of the Konqueror application we just kicked off.

Finally, we would like to make Konqueror full-screen; this is a little more involved.

A quick period of investigation with kdcop shows some interesting-looking functions that may help here.

The konqueror-mainwindow#1 interface has an actions() function; executing this gives us a list of all the valid arguments to the action() function. Looking through this list, we can see one of the actions is called fullscreen. So far so good -- however calling the action() function and passing fullscreen as an argument in kdcop returns an error. A quick look at the function prototype for the action() function shows that it returns a type of DCOPRef. Unfortunately, kdcop cannot show these return types correctly.

All is not lost, however; we can do the same thing with dcop:

dcop konqueror-$! konqueror-mainwindow#1 action fullscreen

This returns

DCOPRef(konqueror-NNNNN,konqueror-mainwindow#1/action/fullscreen)

We can pass this returned value into another instance of dcop (again using the handy ` character):

dcop `dcop konqueror-$! konqueror-mainwindow#1 action fullscreen`

This gives us a list of potential functions, of which activate looks most likely. Let's try this:

dcop `dcop konqueror-$! konqueror-mainwindow#1 action fullscreen` activate

And voilà, the Konqueror window transforms into full-screen mode.

So the final script appears as follows:

konqueror &
dcop konqueror-$! konqueror-mainwindow#1 openURL www.ibm.com/developerworks
dcop `dcop konqueror-$! konqueror-mainwindow#1 action fullscreen` activate

Note that to get out of full-screen mode, you can just right-click on Konqueror and choose "Exit Full-Screen Mode" from the resulting menu.

Example 5. Instantly messaging a contact when they come online
This final example uses Kopete -- a KDE instant message client.

By now, this script should be fairly easy to follow. It takes two arguments, the contact name ($1) and the message ($2). It then loops, getting a list of reachable contacts via dcop, and using grep to check if the supplied name appears. If it doesn't, the loop continues. If it does, the loop terminates and the contact is sent a message (again using DCOP).

Listing 1. Greetings, Professor Falken
  name=$1;
  msg=$2;
  echo Waiting for $name to come online
  while ((`dcop kopete KopeteIface reachableContacts | grep -c $name` == 0))
  do
    sleep 5
  done
  echo Sending message "$msg" to "$name"
  dcop kopete KopeteIface messageContact $name "$msg"

Creating a DCOP-aware application

We will now create a simple DCOP-aware application.

For ease, I will be using the "KDevelop" IDE, which has a rather nifty application wizard that will do much of the work for us.

As I am bleeding edge kind of guy, I'm using the KDevelop 3.0 beta2, but earlier versions should have the same approximate steps.

A simple DCOP-aware application

  1. We begin by starting up KDevelop (I use the run command from the K menu).
  2. We choose "New Project" from the Project menu -- this brings up the "Create New Project" wizard.
  3. If we expand the C++ tree, and the KDE tree under that, we should see an entry called "Application Framework." Choose this entry, give your application a name (eg dwdcopapp) and fill in the other fields as required.
  4. Continue through the rest of the wizard (you should be able to just "Next" most of it) until the end.
  5. Once the project has been created, use KDevelop to build and run it. (you will have to say yes to running automake and friends the first time you build).
  6. If we now fire up dcop (or kdcop) we can see that there is an entry for our newly created application!
  7. If we play about with the entry in (k)dcop we can see that there is already a lot of functionality - we can open a URL, quit the application, and so on.

Let's now look at adding a new function to the list exported via dcop. As we already have a DCOP interface being created and initialized within the application, the easiest thing to do is to add a new method to the existing interface.

  1. Edit dwdcopappIface.h and add a new method in the k_dcop: section with the following signature:

virtual void dwprintln(QString str) = 0;

  1. Add the same method signature to the public: section of dwdcopappView.h
  1. Add the following code which implements our new function to dwdcopappView.cpp:
void dwdcopappView::dwprintln((QString str)
{
   std::cout << " We've been asked to print: " << str << endl;
   std::cout.flush();
}

Note that you will also have to put

#include <iostream>

after the existing include directives.

  1. Build and execute the program.
  2. If we now fire up (k)dcop, we should see that the dwprintln(QString) method has been added to the dwdcopappIface interface. If you execute this method and pass a string, it should be printed to the output window (or the command line, if you started the application outside of KDevelop).
  3. Additional methods can be added in the same way.

It is possible to add additional interfaces to the application in the same manner as the dwdcopappIface was added. The interested reader should read the "DCOP documentation for KDE developers" link listed below in Resources, which will tell you more than you ever need to know about this subject.


Other bindings

In addition to the utilities and C++ bindings for DCOP examined above, there are also a number of other DCOP bindings that provide interfaces to DCOP from many other popular programming/scripting languages including Perl, Java™, Python, C, and more.

These bindings can be found in the kdebindings package, which you may need to install separately depending upon which Linux® distribution you use.


Summary

I hope this article has given you some insight into the power of DCOP and will inspire you to add DCOP functionality to your own applications and combine existing KDE applications in interesting ways.

Resources

Learn

Get products and technologies

  • Kopete is the KDE instant messaging system.
  • The KDevelop IDE is publicly available under the GPL and supports many programming languages including Ada, Java, SQL, Perl, C and more.
  • Download the DCOP graphical browser from the kdcop CVS.
  • With IBM trial software, available for download directly from developerWorks, build your next development project on Linux.

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Linux on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Linux
ArticleID=110352
ArticleTitle=Connect KDE applications using DCOP
publish-date=02262004