D-BUS interfaces and whatnot (Re: KDE/kdebase/konqueror/settings/performance)

Thiago Macieira thiago at kde.org
Wed Jun 7 18:42:21 BST 2006


[Quite long an email, but read it]

Lubos Lunak wrote:
> Could the HOWTO be a bit more detailed guidelines (or rather, have a
> more prominent place) about this D-BUS stuff like interfaces, object
> paths and whatnot? 

You can use the following table to remember:

	DCOP		    DBUS
1 application ID		service name
2 object ID		object path
3 interface		interface name
4 function name		member name

1 and 2 are the arguments to DCOPRef; 1, 2 and 4 are the arguments in a 
normal DCOP call using the 'dcop' command-line utility (minus the 
parameters, of course).

#3 is part of DCOP, despite we never using it. You can see it in the 
original screenshot[1] of kdcop, after the KDE Three Beta meeting that 
created the tool.

[1] http://www.kde.org/history/pics/kdcop.png

We never removed the functionality.


The service name is how an application chooses to be known by other 
applications. One application can have zero or more service names. The 
service names are "brokered" by the D-BUS bus service daemon 
(service "org.freedesktop.DBus"): if an application requests a name that 
is already taken, it will be queued. Whenever a name change occurs, 
signals are emitted. Etc.

Service names are always in the dotted form, starting with the domain name 
of the service, for namespacing purposes. In KDE, we're using org.kde 
followed by the application name -- KOffice applications get org.koffice.

You generally want to have a service name if you have anything interesting 
that other processes may want to see. For instance, the 
service "org.freedesktop.Hal" provides the HAL service, which is a 
freedesktop.org service. That means it exports a known set of objects and 
we know what function calls there are in those objects.

By the same token, the service "org.kde.kded" will provide the KDE Daemon 
services, which are a kde.org service.


Objects are organised in a hierarchy, so you've got a path to find them. 
For example, the path "/object/subobject" could be considered the 
following Qt code:

	QObject root;
	QObject object;
	QObject subobject;

	object.setParent(root);
	subobject.setParent(object);

In fact, if you registered the "root" object at "/" with the 
ExportChildObjects flag, that's exactly what will happen.


Interfaces are contract that an object is following: interfaces are 
generally standardised, so we know exactly what an interface does. So, 
for instance, if a KDE screensaver decided to implement 
interface "org.freedesktop.ScreenSaver", we would know exactly which 
methods are available, what they do, what values they return, what errors 
they can emit, what signals they can emit and what properties are 
available.

We must also regard our own interfaces as a contract between our 
applications and our script-writers. They become subject to "binary 
compatibility": we cannot remove a method that we previously had, nor can 
we change a method's parameters, etc.

I'm thinking of adding a flag saying "this interface is public" (a.k.a. 
KDE_EXPORT) or "this interface is private, don't use it". But the fact 
that you are exporting an interface means that someone is going to use 
it. Otherwise, you shouldn't waste memory.

Interfaces are also named with a dotted form, where the name starts with 
the entity that defined that interface.

> Currently I can only find in the section about 
> DCOPRef that appid -> service name, i.e. the first thing for
> QDBusInterfacePtr, name passed to DCOPObject -> object path, i.e. the
> second thing to QDBusInterfacePtr and the third thing is "dcop appid
> name interfaces()".

That's the porting guide, or "how should I convert my existing DCOP 
class".

> One more thing: With dcop it had to be "dcop kded Konqy_preloader",
> because it was in kded, and registering once more led to having all
> objects available in both DCOP appid's. Is it the same with D-BUS, or
> is there some way no to have that kded in there (because I don't really
> care where it is and it prevents it from moving, just like having to
> mention kdesktop in "dcop kdesktop KBackgroundIface" is annoying)?

An application can request as many service names as it wants. So, if 
kdesktop requests the name "org.kde.Background" because it's the 
application that handles the background, so be it. Later, if the 
application that handles the background becomes "plasma" 
or "plasmadesktop", it'll still request that service name and it'll still 
provide the same objects and same interfaces.

In fact, some KDE applications will request "org.freedesktop.XXXX" names.

Now, there is currently no way of exporting some objects in one service 
name and not in others, short of opening another D-BUS connection (yes, 
you can do that and it's not difficult).

This means that if kded requests org.kde.kded and org.kde.mediamanager, it 
means ALL modules will be present in both service names.

>PS: I'd also appreciate if somebody could point me to some doc
> explaining what the three arguments to QDBusInterfacePtr actually are.
> I'm afraid I still don't quite get it even after reading the FAQ entry.
> Especially what the interface is actually supposed to be good for is
> completely beyond me.

service name, object path and interface name, with the last one being 
optional.

If you use an empty interface, your QDBusInterfacePtr will be a "merge" of 
all interfaces available in the remote object, just like DCOP.

Richard Dale wrote:
>Yes, and why do some of the things have slashes and others don't?

The thing that looks like a path is the object path.

Everything else uses the dotted form, which starts with the domain of the 
organisation that defined that service or interface.

Yes, I realise the redundancy. To make matters worse, people currently 
writing D-BUS applications put the organisation domain in the object path 
as well. However, the interface is optional.

The point is, if you want "Konqueror's (PID 1234) MainWindow", you know 
exactly which service to look for (org.kde.konqueror-1234), which object 
to look for (/konqueror/MainWindow_1) and you already know exactly what 
methods you're going to find there (the methods, signals and properties 
of interface org.kde.KMainWindow).

This also means that an application written in Java or in C in 2006 can be 
reasonably sure that it'll still be able to place calls to Konqueror's 
Main Window in 2008, by which time we will have extensively modified 
KMainWindow (the C++ class in libkdeui).

Also, suppose someone that a glib-based application likes the idea of 
allowing people to quit it so much that they export 
the "org.kde.KApplication" interface. They're allowed to, but it also 
means they must export ALL the methods that the interface has, including 
such things like "notifyConfigurationChanged". That way, we can tell any 
KDE application or that glib application to quit using the same methods 
and same code.

It is, however, much more likely that someone comes up with 
an "org.freedesktop.MainApplication" interface, which is supposed to 
contain a single method called "Quit", inspired by 
our "org.kde.KApplication" interface. This means the KDE applications 
will export BOTH interfaces, even though internally there is only one 
function that does the actual quitting.

(No, it doesn't get us rid of all the redundancy, because you can only 
talk to an interface in an object if you know where that object is)

>Is it possible to come up
>with a simpler equivalent to dbus-send for normal humans?

It's called "dbus" and it's part of QtDBus.

It works just like the "dcop" tool, which means that it looks into what 
you want to call in order to convert the arguments. If you have 47 and 
you're trying to call a method that takes a QString, it'll send as a 
string.

If you have "hello world" and the method takes a QByteArray, it'll be sent 
as a byte array.

If you write "abc" or 65.32 and the method takes an int, the conversion 
will probably fail and no call will be placed.

-- 
Thiago Macieira  -  thiago (AT) macieira.info - thiago (AT) kde.org
  thiago.macieira (AT) trolltech.com     Trolltech AS
    GPG: 0x6EF45358                   |  Sandakerveien 116,
    E067 918B B660 DBD1 105C          |  NO-0402
    966C 33F5 F005 6EF4 5358          |  Oslo, Norway
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 191 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/kde-core-devel/attachments/20060607/90d684d9/attachment.sig>


More information about the kde-core-devel mailing list