Aus Linux-Magazin 09/2005

Wegweiser durch die Gnome-APIs

Der Desktop mit der Pfote findet auch hierzulande immer mehr Anhänger. Damit wächst die Bedeutung von Gnome als Entwicklungsplattform, deren GUI-Toolkit GTK sogar auf Windows und Mac läuft. Dieser Artikel verhilft zur Orientierung auf den verschlungenen Entwicklungswegen.

Wer in die Gnome-Programmierung einsteigen will und einen Blick auf die API-Dokumentation [1] wirft, verliert leicht die Orientierung. Viele Links führen ins Leere oder auf veraltete Seiten. Dieser Artikel zeichnet eine übersichtliche Karte der Gnome-Landschaft.

API-Verwirrung

Der angehende Gnome-Programmierer sieht sich gleich mit mehreren Problemen konfrontiert: Es gibt rund 30 einzelne Bibliotheken mit eigenen APIs, deren Funktionalitäten sich aber oft überschneiden. Vielfach lösen neue Libraries alte ab, aber die Dokumentationsseiten des alten API spiegeln das nicht wider. Auch die ohnehin seltenen Tutorials benutzen viele veraltete Funktionen, ohne auf diesen Umstand hinzuweisen. Häufig beschreiben sie die einzelnen Objekte und Methoden gar nicht in ihrer Funktion, sondern beschränken sich auf allgemeine Beschreibung der Art “Das ist der Eingabeparameter”.

So sind zum Beispiel mit der Version 2 die GObject-Funktionen von GTK in die Glib gewandert, deren Dokumention sich wie die aller anderen vorgestellten Bibliotheken auf [1] findet. Signalfunktionen heißen statt »gtk_signal_…()« nun »g_signal…()«. Andererseits enthält GTK 2.6 nun Objekte und Methoden, die vorher in der Gnome-Bibliothek Libgnome zu finden waren. So implementiert ab GTK 2.6 das Objekt »GtkAboutDialog« statt bisher »GnomeAbout« den beliebten About-Dialog.

Die Basis: Glib

Abgesehen von solchen, auch entwicklungsbedingten Ungereimtheiten gliedert sich das Gnome-Entwicklungsmodell in Schichten. Ganz unten liegt die Glib-Bibliothek, die mit grafischen Benutzeroberflächen nichts zu tun hat. Sie stellt grundlegende Typen zur Verfügung, die zum Teil denen der Standard-C-Bibliothek Glibc entsprechen. Allerdings sind die Glib-Typen so implementiert, dass sie plattformübergreifend funktionieren – GTK gibt es auch auf Windows und Mac. Glib kennt unter anderem »gchar«, »guchar« (unsigned), »gint«, »guint«, »gfloat«, »gdouble« und 64-Bit-Typen wie »gint64« und »guint64«.

Über diese grundlegenden Dinge hinaus enthält die Glib Funktionen für Speicherverwaltung, Timer, String-, Dateifunktionen und einiges mehr. Darüber liegt GDK (GTK Drawing Kit), das Funktionen für einfache Zeichnungen anbietet. GDK abstrahiert vom darunter liegenden Grafiksystem, also unter Unix/Linux von der Xlib, unter Windows von den Win32-Zeichenfunktionen. Darauf baut GTK auf, das schlichte GUI-Widgets, aber auch komplexe Elemente wie Menüs, Datei- oder About-Dialoge bereitstellt.

Für Zeichenoperationen wie Linien und Rechtecke verwenden die Toolkits die Libart. Bitmap-Operationen und Bilddateiformate deckt die Bibliothek Gdkpixbuf ab. Die vielen Gnome-Bibliotheken ergänzen die GTK-GUI-Funktionen. Die kommende GTK-Version nutzt die neue Cairo-Grafikbibliothek, die komplexe, hoch optimierte Zeichenfunktionen mit Bezierkurven und Antialiasing bietet.

Sprachfragen

Wie viele Fachbücher bereits feststellen: Objektorientieres Programmieren passt gut zu grafischen Oberflächen. So erben spezialisierte GUI-Widgets Eigenschaften und Methoden von ihren Eltern, zum Beispiel »GtkButton« von »GtkWidget«. Objekte besitzen nicht nur Eigenschaften, die Aussehen und Verhalten bestimmen. Sie empfangen auch Nachrichten, die das Fenstersystem verschickt, wenn Benutzer auf GUI-Elemente klicken. Bei GTK heißen diese Nachrichten Signale, die trotz Namensgleichheit wenig mit den Unix-Signalen für Interprozesskommunikation zu tun haben.

Um ein GTK-GUI aufzubauen, muss der Programmierer also neue GUI-Objekte erzeugen und sie mit den erwarteten Signalen (zum Beispiel einem Klick), verbinden (Listing 1, Zeile 23). Startet er den GTK-Main-Loop (Zeile 31), verarbeitet das GTK-Runtimesystem die Events und schickt sie an die Applikation.

Abbildung 1: Die Gnome-IDE Anjuta ist ein komplexer Sourcecode-Editor, der zum GUI-Design externe Programme heranzieht. Die bereits erhältliche Entwicklungsversion bietet wesentlich mehr Features.

Abbildung 1: Die Gnome-IDE Anjuta ist ein komplexer Sourcecode-Editor, der zum GUI-Design externe Programme heranzieht. Die bereits erhältliche Entwicklungsversion bietet wesentlich mehr Features.

Implementiert in C

Obwohl GTK stark objektorientiert ist, haben die Entwickler bei der Implementierung auf C zurückgegriffen. Neben den üblichen Geschmacksfragen war ein Grund für die Auswahl die bei der Gnome-Entstehung wenig standardkonforme Implementation des GNU-C++-Compilers. Nun lässt sich sicherlich auch in C objektorientiert programmieren, aber die Vorgehensweise ist in manchen Fällen etwas umständlich.

Alternativ bietet Gnome einige andere Sprachbindungen, die in unterschiedlichem Umfang das jeweils aktuelle C-API widerspiegeln. Am besten sind die Python-Bindings, für die es auch die meisten Beispiele und Dokus gibt. Auch mit Ruby ist Gnome-Entwicklung gut möglich, allerdings ist diese Sprache hierzulande weniger verbreitet. Schließlich ermöglicht der GNU-Java-Compiler GCJ mit den passenden Klassen sogar native Gnome-Programme in Java.

Listing 1:
»simple.c«

01 #include <gtk/gtk.h>
02 
03 static void button_clicked(GtkWidget *button, gpointer data)
04 {
05    g_printf("button '%s' clickedn", gtk_button_get_label(GTK_BUTTON(button)));
06 }
07 
08 static void delete_handler(GtkWidget *widget, gpointer data)
09 {
10   gtk_main_quit();
11 }
12 
13 int main(int argc , char **argv)
14 {
15   GtkWidget *button;
16   GtkWidget *window;
17 
18   gtk_init(&argc, &argv);
19 
20   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
21 
22   button = gtk_button_new_with_label("Button 1");
23   g_signal_connect (GTK_OBJECT (button), "clicked",
24                     GTK_SIGNAL_FUNC (button_clicked),
25                     "Button 1n");
26   gtk_container_add(GTK_CONTAINER(window), button);
27   gtk_widget_show(button);
28   gtk_widget_show(window);
29 
30   //  Gtk Main Loop
31   gtk_main();
32 
33 }

Wer es mit C versuchen möchte, sollte einen Blick auf das GObject-API in der Glib werfen. Es implementiert das komplette in Gnome verwendete Objektsystem. Das Objekt ist dabei das erste Argument der aufgerufenen Methode, danach folgen die eigentlichen Funktionsparamater, zum Beispiel:

gtk_widget_show (button, Arg1, Arg2 ...)

In echtem GTK-Code kommt meist noch eine explizite Typumwandlung (Cast) hinzu, da die Funktionen – der Sprache C gemäß – nicht polymorph sind, sich also nicht auf Parameter unterschiedlicher Typen einstellen. So erwartet »gtk_widget_show()« einen Objektparameter vom Typ »GtkWidget«. Wurde »button« zum Beispiel als »GtkButton« instanziiert, führt die obige Konstruktion zu einer Compiler-Warnung. Den nötigen Cast erledigt ein passendes Makro:

gtk_widget_show(GTK_WIDGET(button), ...)

Um Abstürze des eigenen Programms zu vermeiden, empfiehlt es sich, so zu programmieren, dass gar keine Warnungen übrig bleiben.

Daten dauerhaft speichern

Die meisten Anwendungen speichern Daten, die sie beim nächsten Start wieder einlesen, ob es sich um Userdaten handelt oder um die Position der Fenster auf dem Desktop. Gnome bietet mit GConf eine zentrale Datenbank für alle Arten applikationsspezifischer Daten, ähnlich der Windows Registry. Über Variablennamen, die wie Unix-Pfadnamen aufgebaut sind, lassen sich Daten verschiedener Typen speichern: Integer, String, Float, Bool, List, Pair und ein komplexer Typ GConfschema.

Auch das API ist recht komplex, aber einfache Werte speichern erfordert keinen großen Aufwand. Auch GConf enthält einen Event-Mechanismus, der Anwendungen benachrichtigt, wenn sich ein Wert ändert, für den sie sich registriert haben. Komplexe Datenspeicherung übernimmt das Gnome-DB-API. Es ist den bekannten Interfaces – etwa für MySQL – vergleichbar und besitzt Backends für verbreitete Datenbanken.

Die Dateizugriffe deckt bei Gnome die Gnome-VFS-Bibliothek ab. Sie bringt nicht nur Entsprechungen für die bekannten Unix-File-Funktionen mit, sondern stellt auch komplexere Dienste bereit. Sie beherrscht lokale und entfernte URLs über Protokolle wie HTTP, (S)FTP und so weiter. Recht einfach lässt sich der Gnome-VFS-Layer durch eigene Module erweitern [2].

Ganz modern erlaubt Gnome-VFS auch asynchrone Dateizugriffe. Dabei setzen Anwendungen eine Datei-Operation in Gang und arbeiten unverzüglich weiter. Steht das gewünschte File bereit, erhält die Anwendung eine Nachricht und holt die Daten ab. In neueren Versionen macht Gnome-VFS auch Gebrauch vom Hardware-Abstraktions-Layer HAL, um zum Beispiel logische Volumes zu überwachen. Zur Interprozesskommunikation benutzt Gnome-VFS bislang noch Orbit, es gibt aber schon eine Implementation, die auf D-Bus [3] basiert.

Gute GUI-Designer

Es gibt kein komplett integriertes Entwicklungs-Tool wie Visual Dotnet von Microsoft. Die IDE Anjuta [4] ist nur ein etwas komplexerer Editor und besitzt zum Beispiel keinen GUI-Editor (Abbildung 1). Für diese Aufgabe setzt Anjuta Glade ein, das sich vor einiger Zeit als Standard-GUI-Builder für GTK etabliert hat (Abbildung 2). Das Programm beschränkt sich auf das Design von GTK- und teilweise auch Gnome-GUIs. Es generiert Code in verschiedenen Sprachen oder schreibt eine XML-Beschreibung des GUI (Listing 2). Mit Hilfe der Libglade lässt sich diese Beschreibung zur Laufzeit eines Programms laden und mit Signalen und Events verbinden.

Listing 2: Glade-XML

01 <?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
02 <!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
03 
04 <glade-interface>
05 
06 <widget class="GtkWindow" id="window1">
07   <property name="visible">True</property>
08   <property name="title" translatable="yes">window1</property>
09   ...
10   <signal name="delete_event" handler="on_window1_delete_event" last_modification_time="Tue, 28 Jun 2005 21:12:06 GMT"/>
11   ...

Listing 3: Menü mit
UI-Manager

01 <ui>
02   <menubar>
03     <menu name="FileMenu" action="FileMenuAction">
04       <menuitem name="Open" action="OpenAction" />
05       <menuitem name="Quit" action="QuitAction" />
06     </menu>
07     <menu name="EditMenu" action="EditMenuAction">
08       <menuitem name="Copy" action="CopyAction"/>
09       <menuitem name="Paste" action="PasteAction"/>
10       <menuitem name="Stop" action="StopAction"/>
11     </menu>
12   </menubar>
13 </ui>

Mit der aktuellen GTK-Version 2.6 haben die Entwickler viele neue Widgets eingeführt, von denen die meisten recht umfassende Funktionalität besitzen, so der »GtkFileChooser« als Standard-Dateidialog. Die »GtkUIManager« genannte Komponente vereinfacht den Aufbau der Menüleisten, die praktisch jedes Programm enthält (File, Edit …). Dazu dient ebenfalls ein XML-Format, das nicht kompatibel zum Glade-Format ist (Listing 3). In Version 3 wird auch Glade davon Gebrauch machen [5]. Wer schon jetzt den praktischen »GtkUIManager« verwenden will, sollte einen Blick auf Gazpacho [6] werfen, einen recht neuen GUI-Editor, der Glade durchaus das Wasser reichen kann (Abbildung 3).

GTK-Funktionen verarbeiten diese Beschreibungen und bauen damit GUIs auf. Der Programmierer stellt eine C-Struktur mit Button-Namen und -Labels sowie die Namen der Event-Handler-Funktionen bereit (Listing 4). GTK stellt dann automatisch die nötigen Signalverbindungen her. Der GTK-UI-Manager vereinfacht den Aufbau von Menüs und Toolbars beträchtlich. Das Tutorial [7] gibt dafür ein verständliches Beispiel.

Die neueren Gnome-Versionen haben noch weitere Veränderungen gebracht. So scheint die Zeit von Bonobo/Orbit zu Ende zu gehen. Zur effizienten Kommunikation zwischen Anwendungen soll in Zukunft D-Bus dienen. Viele Anwendungen benutzen es bereits und seine Bindung zum Hardware Abstraction Layer wird es in Zukunft ohnehin unverzichtbar machen.

HAL ist das mächtige Bindeglied zwischen der Hardware, wie sie im Linux-Kernel erscheint, und dem Gnome-Desktop. Zusätzlich enthält der Layer Hardware-Informationen, die dem Kernel fehlen, die der Desktop aber braucht, um dem Benutzer sinnvolle Optionen zu bieten. So weiß HAL, dass es sich bei einem bestimmten USB-Mass-Storage-Device in Wirklichkeit um eine Kamera handelt, die spezielle Eigenschaften besitzt.

Für aller Herren Länder

Mit Version 2 hat GTK die entscheidenden Schritte zur Internationalisierung vollzogen. Fontconfig beherrscht internationalisierte Fonts mit Unicode-Zeichensätzen, die Pango-Bibliothek sorgt für das zur Sprache passende Absatzformat, egal ob von unten nach oben oder von rechts nach links. Wer internationalisierte Anwendungen schreibt, sollte diese Bibliotheken verwenden.

Zusätzlich ist es nötig, für alle im GUI auftauchenden Strings die Gettext-Funktionen einzusetzen. Sie ersetzen zur Laufzeit eines Gnome-Programms Platzhalter durch übersetzte Strings, die sich nach der Lokalisierung richten. Diese Strings finden sich in separaten Dateien mit der Endung ».po«, die unabhängig vom Sourcecode gepflegt werden können – das ermöglicht Übersetzungen durch Nicht-Programmierer.

Andererseits ist hier etwas kritisch anzumerken, dass es nicht ganz einfach ist, die Übersetzungsstruktur zu Beginn erst einmal anzulegen: Ein Gettext-Utility extrahiert zunächst die übersetzbaren Strings aus dem Sourcecode. Der Programmierer editiert anschließend die resultierende Pot-Datei. Mit weiteren Gettext-Hilfsprogrammen wandelt er mehrfach dieses File um. Das Resultat, eine ».mo«-Datei, muss er noch an die richtige Stelle des Lokalisierungsverzeichnisses schieben. Wenn er dann Glück hat, erscheint das GUI seines Programms in der Landessprache.

Abbildung 2: Der GUI-Designer Glade öffnet mehrere Fenster. Er speichert GUI-Beschreibungen in einem XML-Format oder generiert Code in verschiedenen Sprachen. Das moderne UI-Manager-Interface beherrscht er nicht.

Abbildung 2: Der GUI-Designer Glade öffnet mehrere Fenster. Er speichert GUI-Beschreibungen in einem XML-Format oder generiert Code in verschiedenen Sprachen. Das moderne UI-Manager-Interface beherrscht er nicht.

Abbildung 3: Die Gazpacho-Oberfläche besteht aus nur einem Fenster. Das Programm unterstützt auch den aktuellen GTK-UI-Manager, um Menüs aufzubauen. Davon abgesehen ist sein Dateiformat kompatibel zu Glade.

Abbildung 3: Die Gazpacho-Oberfläche besteht aus nur einem Fenster. Das Programm unterstützt auch den aktuellen GTK-UI-Manager, um Menüs aufzubauen. Davon abgesehen ist sein Dateiformat kompatibel zu Glade.

Ein eigenartiges Kapitel der Gnome-Entwicklung sind die Gnome-Applets, also Anwendungen, die meist ihr GUI verstecken. Sie fristen ihr Dasein im Gnome-Panel und zeigen nur ihr Icon oder Informationen in verkleinerter Form. Typischerweise überwachen Applets die Netzwerkverbindung und Online-Updates, verwalten Eingabemethoden oder andere nützliche Kleinigkeiten.

Eine Methode, Gnome-Applets zu schreiben, führt über Bonobo. Ein Applet registriert sich beim Bonobo-Server, fragt Interfaces ab und fordert Komponenten an, aus denen es seine Funktionalität zusammensetzt. Eine komplette Komponenten-Infrastruktur also, die für diesen Zweck etwas überdimensioniert ist.

Multimedia

Große Multimedia-Fähigkeiten besitzt GTK nicht. Gnome verleibte sich deshalb das komplette GStreamer-Projekt ein. Diese ziemlich komplexe Bibliothek ist ein Baukasten für viele Arten von Multimedia-Anwendungen. Zugrunde liegt ein Konzept von Signalquellen und -senken sowie Verbindungen zwischen diesen. So kann eine Anwendung als Quelle ihr Audiosignal in die Senke Soundkarte fließen lassen. Es gibt sogar einen grafischen Editor, um solche Signalketten am Bildschirm aufzubauen.

Um nur einen Systemklang abzuspielen, ist es einfacher, das alte OSS (Open Sound System) oder Alsa zu verwenden. Um die Verwirrung komplett zu machen, läuft die Audio-Wiedergabe in Gnome über den Sound-Daemon »esd«. Deshalb ist es häufig nötig, den Daemon von Hand zu beenden, wenn das gerade gestartete Soundprogramm nicht mit ihm zusammenarbeitet.

Sind Videocodecs wie Div-X oder Mpeg 4 auf dem Linux-Rechner installiert, stehen sie noch lange nicht allen interessierten Anwendungen zur Verfügung, es fehlt eine einheitliche Schnittstelle wie Direct Show. Nur Meta-Codecs wie FFmpeg, von dem auch GStreamer Gebrauch macht, beherrschen zumindest einige moderne Codecformate, den Rest erledigen Plugins. Für komplexe Multimedia-Anwendungen ist also GStreamer das passende API.

Mit Mut machbar

Die Gestaltungsmöglichkeiten für angehende Gnome-Programmierer sind enorm. Die Gnome-APIs decken alle Felder ab, die moderne Desktop-Applikationen brauchen: vom GUI-Toolkit über Dateizugriffe, eine Registry, Datenbanken, eigene Widgets bis zu Multimedia. Leider sind nicht alle APIs klar strukturiert und voneinander abgegrenzt. Auch die mangelhafte Dokumentation ist eine hohe Einstiegshürde.

Positiv ist dagegen die Vielfalt der möglichen Entwicklungssprachen von C über C++ bis zu vielen Skriptsprachen wie Python oder Ruby. Grafische Tools wie die kommende Anjuta-Version oder der neue GUI-Builder Gazpacho vereinfachen den Gnome-Entwicklungsprozess noch einmal. Wer ein bisschen Experimentierfreude mitbringt, kann durch die Gnome-APIs mit wenig Aufwand Gnome-Anwendungen schreiben.

Listing 4: C-Code für
UI-Manager

01 static GtkActionEntry actions[] =
02 {
03   { "StopAction", NULL,   // Name der Action im UIManager-XML
04     "_Stop", "<control>S",      // Menü-Shortcut, Hot-Key
05     "Stop search",              // Beschreibung
06     G_CALLBACK (stop_search) }, // Callback-Funktion
07    ...

Infos

[1] Gnome API-Docs: [http://developer.gnome.org/doc/API/]

[2] Gnome-VFS-Module selber schreiben: [http://developer.imendio.com/wiki/Writing_GnomeVFS_Modules]

[3] Gnome-VFS für D-Bus: [http://developer.imendio.com/wiki/GnomeVFS_D-BUS]

[4] Anjuta: [http://anjuta.sourceforge.net/]

[5] Pläne für Glade 3: [http://glade.gnome.org/todo.html]

[6] Gazpacho: [http://gazpacho.sicem.biz]

[7] GTK-UI-Manager-Tutorial: [http://live.gnome.org/GnomeLove_2fUIManagerTutorial]

LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben