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
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
- Start kdcop from a terminal or from the KDE menu bar.
- From the list of applications, expand "kwin" (the KDE window manager).
- Now expand "KWinInterface" to show all the functions exported by the interface.
- 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 onnextDesktop()
and the display will switch to the next virtual desktop.
Example 2. Open up a new Konqueror window
- Start kdcop from a terminal or from the KDE menu bar.
- 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.
- From the list of applications, expand "konqueror-NNNNN."
- Now expand "KonquerorInterface" to show all the functions exported by the interface.
- Now double click on
openBrowserWindow()
. - 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.
- You should now see a new browser window open and direct to the URL you specified.
Figure 2. Enter the URL...
Figure 3. 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
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
- We begin by starting up KDevelop (I use the
run
command from the K menu). - We choose "New Project" from the Project menu -- this brings up the "Create New Project" wizard.
- 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.
- Continue through the rest of the wizard (you should be able to just "Next" most of it) until the end.
- 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).
- If we now fire up dcop (or kdcop) we can see that there is an entry for our newly created application!
- 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.
- Edit dwdcopappIface.h and add a new method in the k_dcop: section with the following signature:
virtual void dwprintln(QString str) = 0;
- Add the same method signature to the public: section of dwdcopappView.h
- 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.
- Build and execute the program.
- If we now fire up (k)dcop, we should see that the
dwprintln(QString)
method has been added to thedwdcopappIface
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). - 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
- Find DCOP documentation for KDE developers at the KDE Web site.
- See Chapter 13. DCOP-Desktop Communication Protocol from the book KDE 2.0 Development by David Sweet et al (Sams Publishing, 2001) as well as DCOP documentation from Preston Brown and Matthias Ettrich. Brown and Ettrich are also responsible for the dcop Class Index.
- Get information on DCOP and DCOP services in Chapter 4. Components and services from Bernd Gehrmann's KDE Architecture Overview.
- See Ladislav Strojil's What is DCOP? page.
- RPC/IPC within Kde discusses DCOP and provides examples using Java, sh, Perl, and other languages.
- In "Boost your efficiency" (Linux Magazine, November 2003) Scott Wheeler uses DCOP and scripting to turn his computer into a clock radio.
- In "Using DCOP from the command-line" (Linux Gazette, December 2003), Jimmy O'Regan uses DCOP and scripting to make e-Post-It notes available from the shell.
- See Ian Reinhart Geiser's slideshow on building a dcom interface for your application.
- The kdebindings package contains Qt/KDE bindings for Java to use Qt/KDE classes with Java, DCOP bindings for C, Java, Perl, Python to use DCOP in those langages and XParts to embed non-KDE apps as a KPart.
- "Introduction to KDE" (developerWorks, May 2001) focuses on version 2.1, but largely applies to later versions as well.
- "Coding with KParts" (developerWorks, February 2002) gives an introduction to KDE's architecture for graphical components, and compares KParts with other component models.
- The tutorial "Creating KParts components" (developerWorks, May 2002) by David Faure can help you learn more.
- DCOP communicates over sockets. Learn more about the nifty things in "Programming Linux Sockets" (developerWorks, October 2003) by David Mertz.
- In the developerWorks Linux zone, find more resources for Linux developers.
- Stay current with developerWorks technical events and Webcasts.
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
- Check out developerWorks blogs and get involved in the developerWorks community.
Comments
Dig deeper into Linux on developerWorks
Bluemix Developers Community
Get samples, articles, product docs, and community resources to help build, deploy, and manage your cloud apps.
developerWorks Weekly Newsletter
Keep up with the best and latest technical info to help you tackle your development challenges.
DevOps Services
Software development in the cloud. Register today to create a project.
IBM evaluation software
Evaluate IBM software and solutions, and transform challenges into opportunities.