XML überall

Nach etlichen Monaten Entwicklungsarbeit ist die erste Betaversion von KDE 2.0 erschienen. Für harten Produktionseinsatz taugt sie noch nicht, doch die technischen Neuerungen lohnen allemal einen Blick.

In Pocket speichern vorlesen Druckansicht 5 Kommentare lesen
Lesezeit: 9 Min.
Von
  • Christian Kirsch
Inhaltsverzeichnis

Nach KDE 1.x sollte alles anders und besser werden: Wie im Artikel ‘Stück für Stück’ [1] beschrieben, wollten die Programmierer mittels CORBA Objekte zwischen allen Applikationen austauschen und den Desktop so in die oberste Liga der modernen Softwareentwicklung katapultieren. Den hehren Idealen folgte bald die Ernüchterung: Für die üblichen Desktopanwendungen stellte sich CORBA als zu schwerfällig und ressourcenfressend heraus.

Da sie ohne Komponenten und Objekte nicht weiterarbeiten wollten, schrieben die Entwickler flugs ihr eigenes Protokoll. Dieses DCOP (Desktop Communication Protocol) bietet Nachrichtenaustausch und den Aufruf von Funktionen in anderen Programmen. Dazu später mehr.

Ein Kennzeichen von KDE war von je her der transparente Umgang mit lokalen Dateien und denen auf anderen Rechnern. Dieses Prinzip setzt KDE 2 mit einer KIO genannten Bibliothek fort. Sie implementiert Ein- und Ausgabe in einem separaten Prozess und ermöglicht den Zugriff auf alle relevanten Netzwerkprotokolle, unter anderem HTTP, FTP, POP, IMAP, NFS, SMB und LDAP. Das modulare Design der Klassen soll es ermöglichen, neue Protokolle einfach einzuklinken und so allen KDE-Anwendungen zur Verfügung zu stellen.

Nicht alle dieser Protokolle sind jedoch bisher implementiert, so war in den Quellen der Betaversion kein Code für LDAP zu finden. Anderes ist zwar vorhanden, tut aber nichts Sinnvolles; so liefert im Browser die Eingabe von smb:/host trotz Eingabe von Benutzernamen und Passwort keine Ausgabe. Eine hübsche Neuerung funktioniert aber schon: Umgebungsvariablen in URLs löst die Bibliothek auf - $KDEDIR verwandelt sich so beispielsweise in /opt/kde2, und im Browser erscheint der Verzeichnisinhalt.

KIO enthält auch die neue Klasse KDirWatch, die Verzeichnisse auf Veränderungen hin überwacht. Während Anwender bisher oft Dateiansichten im kfm manuell aktualisieren mussten, entfällt dies jetzt - dank KDirWatch merkt der KDE-Dateimanager selbst, wenn jemand in einem Verzeichnis eine neue Datei angelegt hat, und passt die Darstellung an.

Als Komponentenmodell benutzt KDE nun KParts. Dessen Klassen ermöglichen es einem Prozess, innerhalb einer anderen Anwendung zu laufen, und kontrollieren dabei alle Aspekte des GUI. Praktisch wirkt sich dies so aus, dass der neue Dateimanager Konqueror ein KWord-Dokument als Preview anzeigen kann, indem er eine Instanz von KWord in sein Fenster einbettet und diesem Programm dann die Darstellung überlässt. Übrigens ist das Paket KOffice, zu dem KWord gehört, Teil dieser Beta.

Neu ist gleichfalls die Klasse KHTML, die sämtliche HTML-relevanten Standards unterstützen soll. HTML 4, JavaScript, Cascading Style Sheets, SSL, Netscape Plugins - alles ist versprochen. Implementiert ist derzeit jedoch nicht jedes Detail, Seiten mit JavaScript brachten den Browser durchaus gelegentlich zum Absturz.

Am weitesten scheint bisher DCOP vorangeschritten zu sein, und für diesen Bereich existiert auch eine detaillierte Online-Dokumentation. Das Protokoll stellt mit Sockets die Verbindung zwischen zwei Programmen her und bedient sich des X11-Standards ICE (Inter Client Exchange). Applikationen, die sich dieser Möglichkeit des Datenaustauschs bedienen wollen, müssen mit DCOPClient::attach() eine Verbindung zum DCOP-Server herstellen und sich mit client->registerAs("client") anmelden. Anschließend können sie Anfragen anderer Programme verarbeiten.

Solche Kommunikationsversuche gibt es in zwei Varianten: ohne und mit Rückgabe von Daten. Für den ersten Fall reicht Code dieser Art:

QByteArray data;
QDataStream arg(data, IO_WriteOnly);
arg << "Hello world";
client->send("appID", "parentObj/childObj", "display(QString)", data);

Dadurch würde das Objekt childObj, das Kind von parentObj ist, in der Applikation appID die Zeichenkette ‘Hello World’ mit der Routine display verarbeiten. Hierbei ist appID der Name, mit dem sich die Applikation registerAs-Aufruf angemeldet hat. Will ein Programm von einem anderen Daten zurückbekommen, muss es call statt send benutzen, etwa so:

client->call("appID", "parentObj/childObj",
"display(QString)",data, replyType, replyData);
QDataStream reply(replyData, IO_ReadOnly);
if (replyType == "QString") {
QString result;
reply > result;
print("Antwort: %s\n",result.latin1);
}

Auf der anderen Seite muss die antwortende Anwendung die Methode process definieren, die eintrudelnde Requests verarbeitet. Wie Listing 1 zeigt, ist deren erster Parameter die komplette Signatur der auszuführenden Funktion, es folgen deren Parameter.

Mehr Infos

Listing 1: RPC-Verarbeitung

bool childObj::process(const QString &function, 
const QByte Array &data, QCString &replyType,
QByteArray &replyData) {
if (function == "display(QString)") {
QDataStream arg(data, IO_ReadOnly);
QString str;
arg >> str;
QString result = self->display(str);
QDataStream reply(replyData, IO_WriteOnly);
reply << result;
replyType = "QString";
return true;
} else ...
}

Damit sich Entwickler nicht ständig mit call()- und send()-Aufrufen herumschlagen müssen, stellt KDE 2 die beiden Werkzeuge dcopidl und dcopidl2cpp zur Verfügung. Damit lassen sich aus angereicherten C++-Klassendefinitionen XML-Schnittstellenbeschreibungen nebst dazugehörigen Stubs und Skeletons generieren.

Offensichtlich wendet sich DCOP vor allem an C++-Entwickler. KDE 2 enthält jedoch einen weiteren Baustein, der sich dieses Protokolls bedient, um Applikationen von außen bedienbar zu machen - und zwar unabhängig von einer bestimmten Sprache. Natürlich benutzt es dazu des Webs liebstes Kind XML.

In XML verpackte Requests kann man via HTTP an einen Serverprozess schicken, der sie in DCOP konvertiert, an das gewünschte Programm weiterreicht, gegebenenfalls auf Rückgaben wartet und diese dann in Form eines XML-Dokuments an die aufrufende Applikation ausliefert. Der HTTP-Header eines solchen Requests sieht so aus:

POST /appname HTTP/1.0
Content-Type: text/xml
Content-length: <Länge>

Dabei ist appname wiederum der Name der gewünschten Applikation. Als XML-Dokument kann man dieses weiterreichen:

<?xml version="1.0"?>
<methodCall>
<methodName>childObj.display</methodName>
<params>
<param><string>SeCrEt</string>
</param>
<param><string>Hello world</string>
</param>
</params>
</methodCall>

Im Unterschied zu DCOP verlangt XML-RPC als ersten Parameter jedes Methodenaufrufs das Authentifizierungstoken, das der KDE-XML-Server beim Start in ~/.kxmrpcd ablegt, beispielsweise:

3143,D5WAxg8@e_Rm1d|^

Vor dem Komma steht der Port, auf dem der Server HTTP-Requests erwartet, danach der Authentifizierungscode. Er soll gewährleisten, dass nur der Benutzer Anwendungen fernsteuern kann, der sie auch gestartet hat. XML-RPC ist ein standardisiertes Verfahren, und es existieren verschiedene Sprachanbindungen. So gibt es ein Perl-Modul samt Beispielclient, den man zum Sperren des Bildschirms benutzen kann:

rpc-client.pl \
http://localhost:1944/kdesktop KScreensaverIface.lock 'SrA\U@m^1uO}vRqm&'

Portnummer und Authentifizierungstoken sind hier hart kodiert, normalerweise würde man sie per ($port,$auth)=split(/,/,`cat ~/.kxmlrpcd`) aus der erwähnten Datei extrahieren. Zur Anzeige des Heise-Newstickers kann man analog

rpc-client.pl \
http://localhost:1944/konqueror KonquerorIface.openBrowserWindow \
"'SrA\U@m^1uO}vRqm', 'http://www.heise.de/newsticker'"

benutzen. Hier bekommt die Methode openBrowserWindow des Objekts KonquerorIface die zu öffnenden URLs übergeben. Ein letztes Beispiel öffnet das Fenster von kmail zur Erstellung einer Mail. Die Felder To:, CC: und Subject: sind bereits im Dialog durch die an openComposer übergebenen Argumente besetzt (siehe [[bild_url1] Screenshot Aufmacherbild]):

rpc-client.pl \ 
http://localhost:1944/kmail KMailIface.openComposer "'SrA\U@m^1uO}vRqm', \
'ck@ix.heise.de', 'ck@privat.org', '' , 'KMail-Test', 0"

Von anderen Sprachen lassen sich KDE-Anwendungen ähnlich bedienen; XML-RPC-Schnittstellen gibt es außerdem für Python, Java, Tcl, COM, ASP und PHP. Die KDE-Beta enthält sogar ein Beispiel, das dazu die Shell benutzt. Voraussetzung ist allerdings, dass sich das Programm als DCOP-Client registriert hat, und dies gilt bisher noch nicht für allzu viele KDE-Applikationen.

XML ist nicht nur Mittel zum RPC-Zweck, sondern dient jetzt zur GUI-Erstellung und Modifizierung. Statt hart kodierter Menüs und Toolbars benutzt KDE2 eine globale XML-Datei, die alle gebräuchlichen Menüs enthält. Applikationen können eigene Einträge in speziellen Konfigurationsdateien definieren. So enthält $KDEDIR/share/config/ui/ui_standards.rc Einträge wie

<Menu name="bookmarks">
<text>&amp;Bookmarks</text>
<Action name="bookmarks_add"/>
<Action name="bookmarks_edit"/>
<Separator/>
<MergeLocal/>
</Menu>

Ein Browser, der unter ‘Bookmarks’ die Möglichkeit bieten will, Lesezeichen im Netscape-Format zu importieren, enthält in $KDEDIR/share/apps/browser/broser.rc

<!DOCTYPE kpartgui>
<kpartgui name="browser">
<MenuBar>
<Menu name="bookmarks">
<Action name="import_ns4bookmarks"/>
</Menu>
</MenuBar>
</kpartgui>

Gleichzeitig muss in der Applikation eine Instanz der Klasse KAction namens import_ns4bookmarks definiert sein, etwa so:

KAction *newAct = new KAction(i18n("Import from &Netscape"),  0, this, SLOT
(import_ns4()), actionCollection(), "import_ns4bookmarks");

Im Browser erscheint nun im Bookmark-Menü als letzter Eintrag ‘Import from Netscape’. Häufig benutzte Funktionen sollen auch in der Toolbar erscheinen, wofür wiederum ein wenig XML-Code sorgt:

<ToolBar name="test">
<Action name="import_ns4bookmarks"/>
</ToolBar>

KAction sorgt dafür, dass die programminterne Funktion import_ns4 sowohl beim Anklicken des Icons in der Toolbar als auch bei Wahl des Menüeintrags ausgeführt wird. Programmierer können das Objekt benutzen, um beispielsweise gleichzeitig alle damit verbundenen GUI-Elemente zu (de)aktivieren.

Bei soviel Neuerungen verwundert es nicht, dass diese erste Beta von KDE 2 für den alltäglichen Einsatz noch nicht zu empfehlen ist. Einzelne Programme stürzen ab, manche sind noch nicht auf die neue API portiert. Entwickler sollten sich den Code jedoch schon genauer angucken.

[1] Torben Weis; KDE; Stück für Stück; OpenParts - ein freies Objektmodell für Unix; iX 8/1998, S. 58 (avr)