Gästebuch / Guestbook
  • Tay-Tec
  • Rhythmus
  • Rhythmus
  • Theorie
  • Persönlich
  • Android App
  • Cube
  • Geschichte
  • Lösungen
  • Muster
  • Links
  • Legende
  • Reisen
  • Schweden 1999
  • Tom
  • Lebenslauf
  • Diplomarbeit
  • Antje
  • Sina
  • Der X-Server

    Das X-Window System

     

     Prinzip des X-Window Systems
    Figure: Prinzip des X-Window Systems

    Das X-Window System ist ein netzwerkfähiges Grafiksystem für Geräte-unabhängigen Zugriff auf Grafik-Hardware. Es ist nach dem Client/Server-Prinzip, wie in Abbildung 3 gezeigt, aufgebaut, wobei der X-Server direkt mit der Grafik-Hardware zusammenarbeitet und für die eigentliche Darstellung der Grafiken, dem Auslesen der Eingabegeräte und für Rückmeldungen an den Benutzer sorgt. Prinzipiell arbeitet der Benutzter des X-Window Systems direkt an der Grafik-Hardware, die vom X-Server gesteuert wird. Die Anwendungen (Clients), die er dabei benutzt, können auf einem beliebigem anderem Computer, der mit dem Computer des X-Servers in Verbindung steht, laufen. Der X-Server nimmt die Eingaben des Benutzers entgegen, wandelt diese in sogenannte Events um und sendet sie mit Hilfe des X-Protokolls zu den Clients, die auf diese Events reagieren und ihrerseits dem X-Server Befehle (Requests) zur Darstellung oder Bearbeitung von Grafiken, zur Steuerung des Servers oder ähnlichem mit dem X-Protokoll senden, welche der X-Server dann sequentiell und asynchron abarbeitet. Dabei bedienen sich die Clients im einfachsten Fall der X-Library, die Funktionen zur Verfügung stellt, um mit dem X-Server über das X-Protokoll kommunizieren zu können.

    Ausgelegt ist das X-Window System für die Arbeit mit Pixel-Displays mit den unterschiedlichsten Farbtiefen, von 1-Bit monochrom bis 32-Bit TrueColor. Wie im VISA-Projekt gezeigt, können auch Hochleistungs-Grafik-Prozessoren unterstützt werden.

    Für die Kommunikation zwischen Client und Server ist eine fehlerkorrigierte Verbindung nötig, die heute üblicherweise mit TCP/IP hergestellt wird. Ein sinnvolles Arbeiten mit dem X-Window System ist etwa ab Übertragungsraten von 2 KByte/s möglich.

    Da das X-Window System keine Definition einer Benutzer-Schnittstelle auf der Anwendungsebene enthält, kann es auf alle Erfordernisse angepaßt werden und ist damit zeitlos. Durch den Einsatz sogenannter Toolkits, wie Motif, XView o.ä., haben sich mehrere Standards für die Schnittstelle zwischen Mensch und X-Applikation gebildet. Diese Toolkits erlauben dann den einfacheren Aufbau solcher User-Interfaces, welche die effiziente Arbeit mit einem Grafiksystem erst ermöglichen.

    Der Server

    Der Server ist, wie bereits angedeutet, für die Arbeit mit der Grafik-Hardware und das Halten der Verbindungen mit Clients zuständig. Mehrere Clients können parallel mit dem Server arbeiten und sich dabei irgendwo im Netzwerk befinden.

    Aufgebaut ist der X-Server als monolithisches Gebilde, welches sich intern grundsätzlich in 3 Teile gliedert, die nach den Funktionsgruppen klassifiziert werden, die sie enthalten.

    Der

    • Device Independent (DIX) Layer - enthält die Funktionen die von allen Implementierungen benutzt werden und die unabhängig von Betriebssystem und Hardware sind. Das Herz des Layers sind die main() und dispatch() Funktion mit der Initialisierung des Servers und der Hauptschleife, in der die gesammelten Input-Events der Eingabegeräte zu den Clients gesendet und die Requests der Clients bearbeitet werden. Die eigentliche Funktionalität liegt allerdings in den anderen Layern. Die wichtigsten Aufrufe zur Initialisierung des Servers und der Event-Bearbeitung sind in Anhang A dargestellt.
    • Operating System (OS) Layer - enthält die für das Betriebssystem spezifischen Funktionen. Auch diese Funktionen sind von der Hardware unabhängig. Daher wird ein großer Teil der Funktionen für die Ein- und Ausgabe durch den DDX-Layer bereitgestellt. Beschrieben wird der DDX-Layer in [ADK94], [IF92].
    • Device Dependent (DDX) Layer - enthält die auf die spezielle Hardware zugeschnittenen Funktionen.

    Erweiterungen (Extensions) wie die Phigs Extension to X - PEX und die XInput Extension erweitern den X-Server mit zusätzlicher Funktionalität, wie eigenen Extension-spezifischen Requests, Events und Errors. Dabei wird auch das X-Protokoll erweitert, so daß auch auf der Client-Seite des X-Window Systems zusätzliche Bibliotheken erforderlich sind, um das erweiterte Protokoll auswerten und generieren zu können. Im Falle der erwähnten Extensions sind das die libPEX5 und libXi. Extensions sind intern oft, ähnlich wie der X-Server, in einen DIX/OS/DDX-Teil aufgeteilt und als größtenteils eigenständiger Teil in den Server integriert.

    Eingabeverarbeitung 

    Strukturen

    Es wird zwischen Core und Extension Devices unterschieden. Als Core Devices  werden die standardmäßig vorhandenen Eingabegeräte Maus (Core Pointer) und die Tastatur (Core Keyboard) bezeichnet. In der DIX-Struktur InputInfo  gibt es zwei Listen, in denen auf alle aktiven und inaktiven Devices verwiesen wird. Diese Listen sind vom Typ DeviceIntPtr, der als Zeiger auf _DeviceIntRec  Strukturen definiert ist. Diese Struktur enthält die Zustands-Informationen, Zeiger auf die Funktionen über die das Gerät angesprochen wird und die privaten Daten des Gerätes.

    Neben den beiden Listen mit den aktiven und inaktiven Geräten gibt es auch noch zwei spezielle Verweise auf die Core Devices. Auch diese sind vom Typ DeviceIntPtr.

    Einer der wichtigsten Teile der _DeviceIntRec Struktur ist die am Anfang stehende DeviceRec  Struktur. Diese enthält neben dem Zustand des Gerätes auch Zeiger auf die Funktionen, die die Eingaben bearbeiten. Weiterhin existiert ein Zeiger auf die privaten Daten des Gerätes. Welche Struktur über diesen Zeiger angesprochen wird, ist von System zu System unterschiedlich. Der DIX-Layer nutzt diesen Zeiger nicht. Für die Implementierung des Gerätetreibers wurde für die 3D-Eingabegeräte eine eigene Struktur definiert, die alle wichtigen Daten über das jeweilige Eingabegerät enthält. Diese Struktur wird im Abschnitt 5.4.3 beschrieben. Leider läßt Hewlett Packard hier nur eine eigene Struktur zu. Das hat zur Folge, daß sich der im Rahmen dieser Arbeit entwickelte Gerätetreiber nicht bei einem HP-X-Server einsetzen läßt. Allerdings bietet HP eine einfache Möglichkeit zusätzliche Eingabegeräte zur Laufzeit des Servers in Form einer Shared Library einzubinden. Die Beschreibung einer solchen Library für die Space Mouse  findet sich im Abschnitt 5.2

    Initialisierung

    Die Core Devices werden aus der Hauptfunktion main  des X-Servers durch die Funktion InitInput  initialisiert. InitInput ist eine DDX-Funktion und dementsprechend für jede System-Plattform unterschiedlich.

    Im folgenden wird die Initialisierung der Core Devices für mehrere System-Plattformen beschrieben.

    XFree86

      Mit der dem DIX-Layer Funktion AddInputDevice  wird jeweils eine _DeviceIntRec Struktur für die Maus und die Tastatur initialisiert. Als Parameter werden die gerätespezifische Funktion für die Initialisierung des Devices und ein Flag übergeben. Die Initialisierungsfunktion wird dann aus der XFree86 spezifischen xf86Info  entnommen. Diese Struktur wird während der Auswertung der Kommandozeilen-Argumente und der Konfigurationsdatei initialisiert.

    Nun werden die Devices mit den Funktionen RegisterKeyboardDevice  beziehungsweise RegisterPointerDevice  in der InputInfo Struktur als Core Device angemeldet.

    Dem DDX-Layer wird über die Funktion miRegisterPointerDevice  seines mi -Teiles mitgeteilt, welches Device als Core Pointer arbeiten soll. Mittels der Funktion mieqInit  wird die Event-Queue  initialisiert.

    SUN
      Die komplette Initialisierung der Core Devices wird mittels der DIX-Funktionen AddInputDevice, RegisterKeyboardDevice beziehungsweise RegisterPointerDevice und der mi-Funktionen mieqInit und miRegisterPointerDevice durchgeführt. Als Besonderheit wird mittels der Funktion OsSignal  ein SIGIO-Handler  installiert, mit dem dann die internen X-Server Events erzeugt werden. In Abschnitt 5.4.5 wird genauer auf den SIGIO-Handler eingegangen.

    Bis auf diese Besonderheit und der Nicht-Verwendung einer eigenen DDX-spezifischen Struktur werden die Core Devices bei SUN wie bei XFree86 initialisiert.

    HP-UX
      InitInput ruft die Funktion x_init_device  für die Initialisierung der Core Devices auf und übergibt die HP-spezifische HPInputDevice  Struktur mit den Daten des zu initialisierenden Gerätes an diese Funktion. Entnommen werden diese Strukturen einem, von der Funktion init_l_devs  aufgebautem, Feld.

    Für die Initialisierung der _DeviceIntRec Strukturen wird die Funktion hpAddInputDevice  aufgerufen, die ihrerseits AddInputDevice aufruft. Danach wird in Abhängigkeit davon, welches Core Device zu initialisieren ist, das Gerät äquivalent zu XFree86 in der InputInfo Struktur angemeldet.

    Allerdings läßt Hewlett Packard, im Gegensatz zu allen anderen Plattformen, bei seinem Server nicht zu, daß die Eingabegeräte eine andere als die HP spezifische Struktur für die privaten Daten enthalten.

    Ablauf im X-Server

    Um einen Gerätetreiber in den X-Server integrieren zu können, ist etwas Verständnis für den internen Ablauf der Eingabeverarbeitung und Eventerzeugung notwendig.

     

     Ablaufschema des X-Servers
    Figure: Ablaufschema des X-Servers

     

    Abbildung 4 zeigt den groben Ablauf der dispatch-Funktion. Diese DIX-Funktion ist die Kernfunktion des X-Servers. Am Beginn der Funktion wird durch einen simplen Vergleich der Zeiger auf den Kopf und das Ende der Event-Queue überprüft, ob Eingaben aufgetreten sind. Sollte dies der Fall sein, werden die Events durch die Funktion ProcessInputEvents  an die interessierten Clients ausgeliefert. ProcessInputEvents gehört genau wie die Event-Queue zum DDX-Layer. Bei vielen Plattformen besteht die Funktion nur aus dem Aufruf der mi-Funktionen mieqProcessInputEvents und miPointerUpdate, die für die Verarbeitung der Events und die Neudarstellung des Mauszeigers zuständig sind.

    Sind alle Events verarbeitet, wird die Funktion WaitForSomething , die in Abbildung 5 grob dargestellt ist, aufgerufen. Diese wartet mit Hilfe des Systemaufrufs select darauf, daß von einem Eingabegerät Daten gelesen werden können. Danach werden die verschiedenen Wakeup-Handler  aufgerufen. Das sind Funktionen die von Bestandteilen des X-Servers, die an Eingaben interessiert sind, mit der Funktion RegisterBlockAndWakeupHandlers installiert werden. WaitForSomething ruft dann diese Funktionen der Reihe nach auf. Innerhalb der Wakeup-Handler werden die Daten von den physischen Geräten verarbeitet und die daraus entstandenen Events in der Event-Queue gespeichert. Die Event-Queue ist ein, als Ringspeicher, angelegter Speicherbereich. Die gespeicherten Events werden durch zwei Zeiger adressiert, von denen der eine auf den Anfang und der andere auf das Ende der gespeicherten Events verweist.

     

      Prinzip der WaitForSomething Funktion
    Figure 5: Prinzip der WaitForSomething Funktion

     

    Die Erzeugung der Events der Core Devices wird bei den meisten Plattformen zum größten Teil durch den mi-Teil  des X-Servers übernommen. Für die Erzeugung der Events sind die Dateien mi/mieq.c und mi/mipointer.c zuständig. Bei der Initialisierung des mi-Teils, durch die Funktion InitInput wird die Event-Queue aufgebaut und die als Core Devices fungierenden Geräte werden gespeichert.

    Um Motion-Events zu erzeugen und den Mauszeiger zu bewegen, ruft ein Gerät lediglich die Funktion miPointerAbsoluteCursor  auf, der die neue Position des Mauszeigers übergeben wird.

    Für die Speicherung von Button-Events wird eine minimal initialisierte Event-Struktur an die Funktion mieqEnqueue übergeben. Diese vervollständigt den Event und speichert ihn in der Event-Queue.