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
  • Implementierung

    Möglichkeiten

    Prinzipiell bieten sich mehrere Möglichkeiten an, 3D-Eingabegeräte in das X-Window System zu integrieren.

    Direkte Integration in den X-Server
    Die Treibersoftware wird, auf die XInput Extension aufbauend, direkt in den Server integriert und ist damit ein fester Bestandteil des Servers. Alle internen Möglichkeiten des Servers können ausgenutzt werden. Um den Treiber einzubinden, ergibt sich ein hoher Portierungsaufwand, da für jede Änderung in der Treibersoftware der X-Server teilweise neu übersetzt und neu gelinkt werden muß. Fr den Anwendungsprogrammierer stellt sich der Treiber als zusätzliches Eingabegerät des X-Servers dar.
    Shared Library Modul
    Die Treibersoftware wird als dynamisch in den X-Server nachladbares Modul implementiert. Nach dem Laden des Treibers ist für den Anwendungsprogrammierer kein Unterschied zu der Lösung der direkten Integration in den X-Server spürbar. Der Portierungsaufwand für verschiedene Werte ist gering, da alle Änderungen nur in dem Shared Library Modul durchzuführen sind. Leider ist der grundsätzliche Aufbau dieser Module nicht standardisiert und damit Plattform/Hersteller-spezifisch. Im Rahmen dieser Arbeit wird eine Implementation eines solchen Moduls für die X-Server auf HP-UX Workstations (HP9000/7xx) vorgestellt.
    Externe Treiberprogramme
    Die portabelste Lösung ergibt sich durch die Implementierung derTreibersoftware in einem externen selbstttig laufendem Programm, da die meisten Input-Gerte über eine serielle Schnittstelle (RS232) verfügen und die Programmierung der seriellen Schnittstellen für die verschiedenen System-Plattformen durch den POSIX Standard weitgehend standardisiert ist. Die Benutzung der Treibersoftware in Anwendungsprogrammen ist durch die Notwendigkeit der Benutzung von Interprozeßkommunikation zwischen Treiber- und Anwendungsprogramm relativ kompliziert. Dabei wird über den X-Server die Kommunikation zwischen Treiber-Programm und den Applikationen durchgeführt. Die XInput-Extension muß nicht im X-Server vorhanden sein, daß als Kommunikationsmittel des X-Window Systems Atome und zur Verfügung stehen.

    Die Treibersoftware Magellan der Vertriebsgesellschaft für die Space Mouse}, der SPACE CONTROL Gesellschaft für 3D-Systeme mbH ist ein Beispiel fr diesen Lösungsansatz.

    Ladbares Modul für X-Server unter HP-UX 

    Allgemeines

    Die HP-UX X-Server haben die Möglichkeit, mit Hilfe von zur Laufzeit nachladbaren Shared Libraries zusätzliche serielle Eingabegeräte zu unterstützen. Ein solches Modul erfüllt die Funktion eines Gerätetreibers. Beliebige Geräte, die Tastendrücke oder Bewegungsdaten liefern, können direkt eingebunden werden. Bei Geräten, die andere Daten liefern, wie zum Beispiel Strich-Code-Leser, müssen die Geräte-spezifischen Daten innerhalb des Moduls in das vom Interface zum X-Server definierte Format umgewandelt werden.

    Geräte, die über ein nachladbares Modul unterstützt werden, können sowohl die Standard Geräte  (Tastatur und Maus) ersetzen, als auch als Zusatzgeräte über die XInput Extension angesprochen werden.

    Innerhalb eines Modules müssen die folgenden fünf Funktionen immer vorhanden sein:

    1. Initialisierung des Gerätetreibers, durch Bekanntmachung der Funktionen des Moduls gegenüber dem X-Servers. Das ist die einzige Funktion, die global deklariert ist. Alle anderen Funktionen und Variablen des Moduls sind statisch oder lokal zu deklarieren.

      Diese Funktion wird nur einmalig beim Laden des Moduls durch den X-Server aufgerufen.

    2. gerätespezifische Initialisierung. Es wird die Initialisierung der seriellen Schnittstelle und des Eingabegerätes vorgenommen. Nach erfolgreichem Aufruf dieser Funktion ist das Gerät für Anwendungen benutzbar.
    3. Generieren eines Eingabe-'Events'. Es werden die vom Gerät gelesenen Daten in einem einfachen Format an den X-Server übergeben. Diese Lese-Routine muß nicht-blockierend arbeiten.
    4. Schreiben auf das Gerät. Mit dieser Funktion können, wenn vom jeweiligen Gerät unterstützt, Rückmeldungen an den Benutzer zum Gerät gesendet werden. Das könnte die Ansteuerung eines geräteinternen Piepsers, LED's oder eines Anzeigefeldes sein.
    5. Schließen des Gerätes.

    Um ein solches Modul benutzen zu können, muß es so kompiliert werden, daß eine Shared Library entsteht, welche anschließend in das Verzeichnis /usr/lib/X11/extensions/ zu kopieren ist. Durch einen Eintrag in der Konfigurationsdatei /usr/lib/X11/X*devices wird der X-Server veranlaßt, das Modul beim Start zu laden. Ein Eintrag enthält die Information, welche Shared Library zu benutzten ist, an welcher Schnittstelle das Gerät angeschlossen und in welcher Form das Gerät angesprochen werden soll. Der Eintrag für die SPACE MOUSE  könnte so wie in Abbildung 6 aussehen.

       

    Begin_Device_Description
    Name spacemouse.sl       # Name of the shared library
    Path /dev/tty00          # physical device
    Use pointer              # use it as the pointer core device
    # can be 'extension' for the use
    # as an Input Extension device 
    End_Device_Description
    

    Figure: HP-Modul Konfigurationsdatei

    Aufbau, Funktionsweise

    Das Modul besteht neben den in Abschnitt 5.2.1 beschriebenen Funktionen, die die Standard-Einsprungpunkte in das Modul darstellen, noch aus einigen wenigen privaten Funktionen (Hilfsfunktionen).

    Die Standardfunktionen:

    spacemouse_Init
    in ein Integer-Wert zu wandeln.
    dolog
    Schreiben von Debug-Informationen in das Syslog.

    Fazit

    Bei der Implementierung eines solchen Moduls haben sich neben dem Vorteil der geringen Entwicklungszeit allerdings auch einige Nachteile ergeben, die den Einsatz solcher nachladbaren Module einschränken.

    • Der wohl größte Nachteil ist darin zu sehen, daß Module dieser Art prinzipiell vom HP X-Server unterstützt werden, obwohl die meisten Betriebssysteme Shared Libraries benutzten. Für alle anderen Plattformen die von der MIT-SI unterstützt werden, existiert kein Verfahren zum dynamischen Nachladen von Gerätetreibern zur Laufzeit. Wenn allerdings ein Gerätetreiber für ein serielles Eingabegerät unter HP-UX zu entwickeln ist, ist die Implementierung eines solchen Treibers in Modul-Form sehr zu empfehlen, da ein solches Modul sowohl unter den von Hewlett-Packard gelieferten Standard X-Servern, als auch unter den aus der MIT-SI-Distribution erzeugten X-Servern funktioniert.
    • Ein weiterer Nachteil besteht im speziellen Fall der 3D Eingabegeräte darin, daß solche Geräte mit Hilfe eines solchen Moduls nicht gleichzeitig als das Core Pointer und als XInput Extension Gerät arbeiten können. Zwar sind prinzipiell beide Arbeitsmodi möglich, allerdings nur ausschließlich, da die Wahl des Arbeitsmodus nur über die Konfigurationsdatei X*devices  erfolgen kann.
    • Dadurch, daß innerhalb des Moduls nicht festgestellt werden kann, in welchem Arbeitsmodus das Modul benutzt wird, ergeben sich ergonomische Schwierigkeiten. Die Y-Achse (Bewegung) der normalen Zeiger-Geräte, wie Maus, Trackball, Tablett entspricht bei vielen 3D Geräten der Z-Achse. Bewegungen des Bildschirm-Zeigers in Y-Richtung müssen dann durch die Auf/Ab-Bewegung an den Geräten gesteuert werden, was zumindest gewöhnungsbedürftig ist.

    Gerätetreiber im X-Server

     

    Allgemeines

    Ziel einer Software Implementierung sollte neben einer guten Leistungsfähigkeit, auch immer eine möglichst hohe Portabilität sein. Für die Integration eines Gerätetreibers in den X-Server bedeutet das, daß die Schnittstellen vom Gerätetreiber zum X-Server möglichst system- und plattformunabhängig sind. Dieses läßt sich auf einfache Weise durch die Reduktion auf eine möglichst geringe Anzahl von Schnittstellen erreichen. Im Falle des im Rahmen dieser Arbeit entwickelten Treibers beschränken sich die Änderungen im Quelltext des originalen X-Servers im Allgemeinen auf das Hinzufügen einer Zeile in der Funktion InitInput .

    Weitgehende Universalität oder einfache Erweiterbarkeit des Gerätetreibers läßt sich durch Schaffung einer dem Aufbau des X-Servers ähnlichen Struktur, also die Unterteilung in einen DIX/OS und einen DDX Teil, für den Gerätetreiber erreichen.

    Problemanalyse

    Forderungen an den Gerätetreiber sind:

    • Nutzung der XInput-Extension für die Implementierung
    • das Erzeugen von 3D-XInput-Extension und 2D-Core Events
    • die einfache Implementierung der Unterstützung für andere 3D-Eingabegeräte
    • eine möglichst hohe Portabilität
    • der sichere Betrieb 

    Die Nutzung der XInput-Extension für die Implementierung

    hat die Vorteile:

    1. Es existiert eine X-Protokoll Erweiterung, die benutzt werden kann. Daher kann die Definition eines eigenen Protokolls und damit einer eigenen Extension entfallen.[PS94]
    2. Auf der Client-Seite existieren die benötigten Bibliotheken, um 3D-Events zu empfangen und zu verarbeiten. Innerhalb eines Events ist die XInput-Extension in der Lage, Werte von bis zu 6 Achsen und Zustände von 512 Tasten zu übertragen. In den Bibliotheken existieren weiterhin Funktionen, um Geräte der Extension zu steuern oder Eigenschaften der Geräte für die private Nutzung durch eine Applikation zu blockieren. Es existieren die gleichen Möglichkeiten wie bei den Core Devices . Die Entwicklung von eigenen Bibliotheken kann entfallen.[PS92]
    3. Im Server existieren Funktionen und Strukturen, um XInput-Extension konforme Geräte einzubinden und Events für die Übertragung zu den interessierten Applikationen (Clients) an den X-Server zu übergeben.

    Zusammengefaßt kann man sagen, daß man sich durch die Verwendung der XInput-Extension weitgehend auf die Unterstützung der eigentlichen Geräte bei Implementierung eines Gerätetreibers konzentrieren kann.

    Das Erzeugen von 3D-XInput-Extension und 2D-Core Events

    ist eine der zentralen Forderungen der GMD im Rahmen ihres VISA-Projektes. Dabei soll die Möglichkeit geschaffen werden, mit einem 3D-Eingabegerät gleichzeitig sowohl 3D-Steueraufgaben zu erfüllen, als auch als Pointer des X-Window Systems zu arbeiten. Dabei sollte es möglich sein, auf die standardmäßig vorhandene Maus ganz zu verzichten.

    Dabei bieten sich drei Möglichkeiten an:

    1. Die Aufteilung des physischen Gerätes auf zwei logische Eingabegeräte  des X-Servers. Dabei übernimmt dann das eine logische Gerät die Aufgaben des Core Pointers , während das andere Gerät für die Erzeugung von 3D-Events mit Hilfe der XInput Extension zuständig ist.
    2. Das physische Gerät wird nur von einem logischen Eingabegerät  der XInput Extension verwaltet. Dieses muß dann zwei Arbeitsmodi besitzen. Im 2D-Modus arbeitet das Gerät dann als Core Pointer, während es im 3D-Modus XInput Extension konforme Events mit den 3D-Daten liefert.
    3. Eine Kombination der beiden genannten Lösungsansätze . Es werden zwei logische Eingabegeräte benutzt, von denen aber immer nur jeweils eines aktiv ist.

    Alle drei Lösungen haben ihre Vor- und Nachteile, die hier dargelegt werden. Bei der Verwendung von zwei getrennten Geräten

    • ist die gleichzeitige Benutzung des originalen Core Pointers des X-Servers praktisch nicht mehr möglich, da dessen Aufgaben ja komplett von dem einen der beiden logischen Geräte übernommen wird, beziehungsweise man sich schon beim Start des X-Servers entscheiden muß, welches Gerät als Core Pointer arbeiten soll. Da die 2D-Steuerung mit Hilfe von 3D-Eingabegeräten oft ergonomische Probleme bereitet, ist dies einer der Hauptgründe, warum diese Lösung für die Implementierung nicht in Frage kam.
    • die gleichzeitige Erzeugung von Core Pointer und XInput-Extension Events. Der X-Server muß annähernd die doppelte Anzahl von Events bearbeiten und an die Clients schicken. Weit schlimmer als der dadurch entstehende Performance-Verlust ist die Tatsache, daß sich bei 3D-Steuerungen der Maus-Zeiger mitbewegen würde. Das kann dazu führen, daß die Applikation den Input Focus verliert und damit auch die 3D-Steuerung unterbrochen wird. In einer anderen Anwendung, die nun möglicherweise den Input Focus erhalten hat, können diese Events zu schweren und nicht beabsichtigten Auswirkungen führen. Das ist der Hauptgrund, warum diese Lösung nicht akzeptabel ist.
    • muß relativ stark in die originalen Quellen des X-Servers eingegriffen werden. Das widerspricht dem Ziel einer möglichst hohen Portabilität und Universalität. Auch dieser Grund spricht relativ stark gegen diesen Lösungsansatz.

    Die Nachteile die der Lösungsansatz 2 hat, lassen sich eher vermuten, als genau vorhersagen:

    • Probleme beim Umschalten zwischen den beiden Arbeitsmodi. Das könnten Probleme bei der Stabilität des X-Servers sein oder ``Effekte'' auf der Client Seite des X-Window Systems. Ob das wirklich ein Nachteil ist, läßt sich erst durch Testen des fertigen Gerätetreibers feststellen.
    • Der originale Core Pointer muß beim Start des X-Servers zumindestens initialisiert werden, da sonst das Umschalten der Arbeitsmodi des Gerätetreibers nicht funktionieren kann. Das ist ein relativ starker Grund, der gegen diese Lösung spricht. Allerdings testen die X-Server der verschiedenen System-Plattformen im allgemeinen nicht die physische Präsenz ihrer Eingabegeräte.

    Bei diesem Lösungsansatz wird vorrausgesetzt, daß das Eingabegerät fast ausschließlich im 3D-Modus arbeitet und das standardmäßige 2D-Eingabegerät für die normale Arbeit mit dem X-Server genutzt wird. Es ergeben sich folgende Vorteile:

    • Für beide Arbeitsmodi steht das optimierte Eingabegerät zur Verfügung.
    • Die Art der Umschaltung zwischen den Arbeitsmodi entspricht der Vorgehensweise, die von XInput Extension intern verwendet wird.
    • Mehrere Eingabegeräte können auf einfache Weise unterstützt werden.
    Aus diesen Gründen erschien dieser Lösungsansatz als der praktikabelste und bildete daher die Grundlage für die Implementation.

    Der Lösungsansatz 3 entspricht bis auf die Idee der Umschaltung der Arbeitsmodi dem Ansatz 1. Die grundsätzliche Idee dieser beiden Ansätze ist es, für die komplette Steuerung nur ein Eingabegerät zu verwenden. Der Unterschied zum Lösungsansatz 2 besteht hauptsächlich in der Philosophie der Implementierung. Um diesen Lösungsansatz zu verwirklichen, sind durch die Ersetzung des originalen Core Pointers relativ starke Eingriffe in den X-Server notwendig.

    Die Erzeugung der 2D-Daten

    ist ein weiteres Problem. Die SPACE MOUSE  hat bereits, wie schon in Abschnitt 2.4 erwähnt, zwei verschiedene Arbeitsmodi für den 2D- und 3D-Modus. Allerdings unterscheiden sich die beiden Modi sowohl in den physischen Parametern der seriellen Schnittstelle, als auch in dem Protokoll mit dem die Daten mit dem Computer ausgetauscht werden.

    Aus diesen beiden Gründen wurde ein anderer Weg gewählt. Es wird für beide Modi der physische 3D-Modus benutzt. Damit entfällt sowohl die heikle Umschaltung der Schnittstellenparameter, als auch die Implementierung von zwei verschiedenen Übertragungsprotokollen. Auf eine Kombination von mehreren Achsen und Tasten wurde aus Gründen der Einfachheit verzichtet.

    Die einfache Implementierung der Unterstützung für andere 3D-Eingabegeräte

    läßt sich erreichen, wenn innerhalb des Gerätetreibers, Software-Schnittstellen implementiert werden, die eine möglichst einfache Integration von anderen Geräten ermöglichen.

    Dazu sind möglichst viele der Funktionen des Gerätetreibers, als von den physischen Geräten unabhängige, Funktionen zu implementieren. Solche Funktionen könnten Teile der Initialisierung des Gerätes, die Übergabe von Events an den X-Server, das physische Lesen und Schreiben von/auf Geräte sein. Idealfall wäre, wenn nur die gerätespezifische Initialisierung und das Protokoll des jeweiligen Gerätes für jedes Gerät neu zu implementieren sind. 

    Eine möglichst hohe Portabilität

    läßt sich durch die Verwendung von systemunabhängigen Standard-Funktionen und durch die Geringhaltung der Eingriffe in den originalen Quellcode des X-Servers erreichen.

    Mittel dazu sind die Verwendung von Funktionen des ANSI-  bzw. POSIX-Standards  und die Nutzung von DIX- bzw. mi-Funktionen.

    Der sichere Betrieb

    ist eine selbstverständliche Forderung, die durch eine ``saubere'' Programmierung und Testen des fertigen Servers mit dem integrierten Gerätetreiber erreicht werden kann.

    Zum Testen eignet sich am besten eine kleine Test-Applikation, die allerdings nicht alle Fälle, die beim Betrieb des X-Servers auftreten können, abtesten kann. 

    Beschreibung des Gerätetreibers

    Allgemeines

    Für die Implementierung wurde der Lösungsansatz 2 (siehe Seite ) gewählt. Dazu wird vom Gerätetreiber beim Start des X-Servers ein von der XInput Extension verwaltetes Gerät initialisiert. Dieses ist damit am Anfang ein reines 3D-Eingabegerät, dessen Initialisierung keinen Einfluß auf die anderen Eingabegeräte des X-Servers hat. Das Gerät ist im 3D-Modus. Um das Gerät auch als das Core Device Maus nutzen zu können, muß es in den 2D-Modus umgeschaltet werden. Dazu stellt die XInput Extension die Funktion ProcXChangePointerDevice  zur Verfügung. Mit Hilfe dieser Funktion ist ein Client in der Lage die Maus durch ein beliebiges anderes Eingabegerät zu ersetzten. Die Maus wird dabei zu einem durch die XInput Extension verwaltetem Gerät und das andere Gerät zum Core Pointer. Für den Gerätetreiber wurde noch eine andere Möglichkeit für die Umschaltung der beiden Modi entwickelt. Diese besteht darin, daß durch den Druck einer reservierten Taste der Betriebsmodus umgeschaltet wird. Dazu wurde eine neue Funktion nach dem Vorbild von ProcXChangePointerDevice entwickelt. Bei der SPACE MOUSE, wird die '*'-Taste für die Umschaltung genutzt. Für die Zurückschaltung in den 3D-Modus muß die Taste erneut gedrückt werden.

    In den folgenden Abschnitten wird der Gerätetreiber dokumentiert. Die wichtigsten Funktionen der einzelnen Quelldateien werden näher beschrieben.

    Alle Pfadangaben beziehen sich auf das Root-Verzeichnis der Distribution des X-Consortiums des X-Window Systems, auf das Root-Verzeichnis der X-Server Quellen oder auf das Verzeichnis mit den Quellen des Gerätetreibers.

    Grundaufbau

    Prinzipiell besteht der Gerätetreiber für einen Gerätetyp aus zwei Quelldateien. Davon enthält die erste Datei 3dinput.c allgemeine Funktionen, die für alle Gerätetypen nutzbar sind, während die zweite Datei alle spezifischen Funktionen für einen Gerätetyp enthält. Für jeden weiteren zu unterstützenden Gerätetyp kommt damit nur eine weitere Quelldatei hinzu.

    Alle Funktionen die ursprünglich in Xi/stubs.c definiert sind und die durch den Gerätetreiber ersetzt werden, werden in xi_stubs.c implementiert.

    Zusätzlich gibt es noch eine Include-Datei mit den Deklarationen der Strukturen, Variablen und Funktionen die im Gerätetreiber benötigt werden.

    In den folgenden Abschnitten wird auf die einzelnen Quellen näher eingegangen. 

    Die Struktur d3_private

    Die Struktur d3_private  (Abbildung 7) enthält alle Daten und Statusinformationen für jedes Gerät, welches vom Gerätetreiber unterstützt wird. Ein Verweis der DeviceIntRec Struktur, die für jedes Eingabegerät des X-Servers existiert, zeigt auf eine initialisierte Struktur dieses Typs.

    Durch die Verlagerung der Eingabepuffer, Filedescriptoren, Masken aus den Funktionen des Gerätetreibers in diese Struktur, ist es möglich, daß der Gerätetreiber auch mehrere Geräte des gleichen Typs, zum Beispiel zwei Space Mouse Geräte, verwalten kann.

    Die Eingabepuffer wurden so groß gewählt, daß mehrere Datenpakete in einem Stück vom Gerät gelesen werden können. Dadurch kann die Anzahl der Systemaufrufe auf ein Minimum reduziert werden.

      

    typedef struct d3_private {
    /*
    ** global data
    */
    struct    d3_private *nxt;       /* next 3d-input device */
    DeviceIntPtr d3_dev;             /* hack */
    char *d3_name;                   /* logical name */
    char *d3_path;                   /* physical device path */
    int d3_fd;                       /* filedescriptor */
    /*
    ** Buffers for the device read routine
    */
    char d3_bufa[MAXREAD+1], d3_bufb[MAXREAD+1];
    char *d3_akt, *d3_bck;
    int d3_idx;
    /*
    ** data for event processing
    */
    int d3_xaxis, d3_yaxis;          /* axis for core pointer */
    KeyButMask d3_bmask;             /* Buttonmask */
    KeyButMask d3_rmask1, d3_rmask2; /* raw Buttonmasks */
    void (*d3_enqueue)ARG( ( struct d3_private *prv ) );
    } d3_private;
    

    Figure 7: Die Struktur d3_private

    3dinput.c

    d3_AddInputDevices

      ist die zentrale Funktion des Gerätetreibers. Diese parameterlose Funktion, aus InitInput  aufgerufen, sorgt für die Initialisierung der verschiedenen durch den Gerätetreiber unterstützten Geräte.

    Welche Geräte mit welchen Parametern zu initialisieren sind, wird in der Konfigurationsdatei $LIBDIR/d3_devices festgelegt. Konfigurierbar sind:

    der logische Name
    des Gerätes whrend der Arbeit.
    der Typ
    des physischen Gerätes. Zur Zeit wird nur die SPACE MOUSE unterstützt.
    Pfad
    der Spezialdatei, die dem physischen Gerät zugeordnet ist.

      

    #
    # Defines for the DLR-SpaceMouse
    #
    Device  SpaceMouse
    Typ     SpaceMouse
    Path    /dev/cua1
    
    Figure: Konfigurationsdatei $LIBDIR/d3_devices

    Die Konfigurationsdatei ist zeilenweise aufgebaut. Gültige Zeilen bestehen aus einem der drei Schlüsselworte am Zeilenanfang und einem dem Schlüsselwort zugeordnetem Wert. Leerzeilen und Zeichen nach einem '#' werden ignoriert. Jede Gerätedefinitition beginnt mit dem Schlüsselwort device mit dem nachgestellten Gerätenamen, der nur einmal vorkommen sollte. Der Gerätepfad wird nach dem Schlüsselwort path und der Gerätetyp nach dem Schlüsselwort typ definiert. Ein Beispieleintrag ist in Abbildung 8 dargestellt.

    Nach dem Einlesen eines vollständigen Eintrages, wird für das zu initialisierende Gerät eine Struktur angelegt und beim X-Server angemeldet. Nach der vollständigen Abarbeitung der Konfigurationsdatei wird ein sogenannter Wakeup-Handler beim X-Server angemeldet, der beim Anliegen von Daten von einem Eingabegerät aufgerufen wird und für das Lesen dieser Daten und das Erzeugen von Events zuständig ist.

    d3_ChangePointerDevice

      ist die Funktion, die bei der Umschaltung des Arbeitsmodus, aufgerufen wird. Der Aufruf wird durch den Benutzer mittels einem Tastendruck der reservierten Taste des Gerätes ausgelößt. Die äquivalente Funktion ProcXChangePointerDevice der XInput Extension ist in Xi/chgptr.c zu finden.

    d3_WakeupHandler

      wird durch den DIX-Layer aufgerufen, wenn Zeichen an den Schnittstellen gelesen werden können. Die Funktion überprüft für jedes Gerät des Gerätetreibers ob die Daten für dieses Gerät bestimmt sind und ob das Gerät aktiv ist. Sollte dies der Fall sein, wird die dem Gerät zugeordnete Routine zum Lesen der Zeichen und Erzeugen der Events aufgerufen.

    d3_EnqueueButtonEvent und d3_EnqueueMotionEvent

    werden von den gerätespezifischen Funktionen zum Erzeugen von 2D- oder 3D-Events aufgerufen. Je nachdem ob das Gerät als Core Pointer fungiert oder nicht, wird die Art der zu erzeugenden Events gewählt.

    Für die Erzeugung der 2D-Events werden Funktionen des mi-Teils des X-Servers genutzt. Diese sorgen neben der Erzeugung der Events auch für die Neudarstellung des Mauszeigers auf dem Bildschirm. Bei der Implementierung der Event-Generierung mit diesen Funktionen hat sich eine weitere Möglichkeit für die gleichzeitige Nutzung eines Eingabegerätes als Extension und Core Device ergeben. Auf diese wird später noch eingegangen.

    Elementare Funktionen

    zum Lesen und Schreiben von Daten vom/auf das Gerät und für die Fehlersuche sind ebenfalls in diesem Modul implementiert. Die Funktion d3_readln  ermöglicht das blockierungsfreie Lesen von Zeilen. Die Funktion liest so viele Daten wie möglich. Wenn eine vollständige Zeile gelesen wurde, wird diese als Ergebnis der Funktion zurückgegeben.

     

    SIGIO

      Nicht alle Plattformen benutzen den Weg, Events durch einen Wakeup-Handler zu erzeugen. SUN bietet die Möglichkeit, dieses mit Hilfe eines Signal-Handlers zu tun. Dazu wird nach dem Öffnen einer Gerätedatei diese so initialisiert, daß bei jedem zu lesenden Zeichen das SIGIO-Signal an den Prozess gesendet wird. Dieser fängt dieses mittels einem zuvor installierten Signal-Handlers ab. Er kann nun die Zeichen von den Gerätedateien lesen und bearbeiten. Dieser Vorgang läuft parallel zu den anderen Abläufen in diesem Prozeß ab.

    Im Fall des X-Servers bedeutet dies, daß Events parallel zu den anderen Abläufen, wie der Abarbeitung von Requests von Clients, erzeugt werden können. Vorteilhaft daran ist, daß bei stark belastetem Server dieser flüssiger arbeiten kann, da ein Teil der Event-Erzeugung schon parallel zu den anderen Arbeiten des Servers durchgeführt wird.

    Allerdings hat diese Vorgehsweise auch ihre Nachteile. So steigt die Anzahl der Systemaufrufe dadurch, daß im Normalfall bei jedem empfangenen Zeichen das Signal ausgelößt wird und im Signal-Handler die verschiedenen Eingabegeräte bei jedem empfangenen Signal der Reihe nach abgefragt werden. Bestimmte Funktionen, zum Beispiel die Funktion ProcessInputEvents  dürfen auch nicht unterbrochen werden. Die Möglichkeit, daß der SIGIO-Handler diese Funktion zu einem kritischen Zeitpunkt unterbricht, ist theoretisch gegeben und kann zu schwerwiegenden Störungen des X-Servers führen.

    Da beim SUN X-Server der SIGIO-Handler Standard ist, wird er durch den Gerätetreiber benutzt. Dafür mußte allerdings an einer weiteren Stelle in den originalen Quellcode eingegriffen werden, da keine Software-Schnittstelle zum Mitabfragen von zusätzlichen Eingabegeräten vorhanden ist. Bei der Initialisierung der durch den Gerätetreiber verwalteten Geräte werden für jedes Gerät die Signale angefordert und der Wakeup-Handler wird nicht installiert. Statt dessen wird der SIGIO-Handler genutzt.

    spacemouse.c

    Die Hauptfunktionen dieses Moduls sind spacemouse_proc , die für die Initialisierung, Statusänderung und das Schließen des Gerätes zuständig ist [Sac91] und spacemouse_enqueue . Diese Funktion liest die Daten vom Gerät. Für die Auswertung der Daten und die Erzeugung von Events werden von der Funktion in Abhängigkeit davon, ob es sich bei den gelesenen Daten um ein Motion- oder Button-Paket handelt, zwei unterschiedliche Funktionen aufgerufen. Die für das Motion-Paket zuständige Funktion wertet nur dieses Paket aus und generiert daraus ein Motion-Event. Die andere Funktion wertet das Button-Paket nicht nur aus, sondern fängt auch die '*' Taste ab, um den Betriebsmodus des Gerätes, wie bereits beschrieben, umzuschalten. Bei allen anderen Tasten werden die entsprechenden Events generiert.

    xi_stubs.c

    In diesem Modul ist zur Zeit nur die Funktion ChangePointerDevice  implementiert, die für die geräteabhängigen Änderungen bei der Umschaltung eines Gerätes der XInput Extension in den Core Pointer notwendig sind. 

    Installation

    Als Hardware-Erweiterung des X-Servers befindet sich der Quellcode des Gerätetreibers im Verzeichnis xc/programs/Xserver/hw/3dinput/.

    Für die Integration des Quellcodes in den X-Server sind noch die folgenden Dateien zu patchen.

    xc/config/cf/Project.templ
    Definition eines Symbols, für die Unterscheidung, ob der Gerätetreiber in den Server zu integrieren ist oder nicht
    xc/programs/Xserver/Imakefile
    Hinzufügen der Regeln für den Bau des Gerätetreibers und dessen Integration in den Server
    xc/programs/Xserver/Imakefile
    Einbinden von stubs.c in die XInput Extension
    xc/programs/Xserver/Xi/stubs.c
    Auskommentieren der geräteabhängigen Funktion ChangePointerDevice , da diese im Gerätetreiber neu definiert wird.
    xc/programs/Xserver/mi/mieq.c
    Hinzufügen einer Funktion zum Ändern des Core Pointer Gerätes.

    Um den Gerätetrieber zu initialisieren, muß die DDX-Funktion InitInput  gepatcht werden. Für die einzelnen Plattformen sind das:

    XFree86:
    xc/programs/Xserver/hw/xfree86/common/xf86Init.c
    SUN:
    xc/programs/Xserver/hw/sun/sunInit.c
    Bei der Verwendung des SIGIO-Handlers  bei dem SUN X-Server ist zusätzlich noch die Funktion sunEnqueueEvents  zu ändern.

    Fazit

    Die Implementierung eines Gerätetreibers in den X-Server ermöglicht die vollständige Integration von Eingabegeräten mit allen ihren Möglichkeiten in das X-Window System. Da sich die Nutzung dieser Geräte nur in wenigen Details von der Nutzung der Core Devices unterscheidet, ist es Applikationen auf einfachste Weise möglich, diese zu benutzen.

    Neben dem Einsatz als Gerät der XInput Extension ist es auch möglich, die Core Devices zu ersetzten und deren Aufgaben zu übernehmen. Das kann bis zu ihrem vollständigen Ersatz führen. Allerdings ist dabei zu bedenken, daß die 3D-Eingabegeräte nicht für die 2D-Eingabe optimiert sind. Daher gibt es bei der 2D-Eingabe oft ergonomische Probleme.

    Bis auf Hewlett Packard, bei denen sogar die Tastatur als Core Pointer arbeiten kann, unterstützt keine andere Plattform die XInput Extension standardmäßig. Daher ist auch bei keiner Plattform vorgesehen, daß ein Core Device als Extension Device arbeiten kann. Das führt dazu, daß ein Core Device auch dann keine Extension Events erzeugen kann, wenn es vorübergehend als Extension Device angemeldet ist.

    Während der Testphase des Gerätetreibers haben sich einige Nachteile der Umschaltung zwischen dem 2D- und 3D-Modus ergeben.

    • Während der Arbeit als Core Pointer existiert das Gerät nicht mehr als 3D-Gerät. Eine in dieser Zeit gestartete Applikation, die dieses Gerät als 3D-Gerät benötigt, wird also kein Gerät finden, welches ihren Anforderungen entspricht.
    • Der ursprüngliche Core Pointer ist aus dem oben genannten Grund nicht in der Lage als XInput Extension Gerät zu arbeiten.

    Beide Nachteile fallen allerdings nicht ins Gewicht, wenn man die vom Gerätetreiber unterstützten Geräte als reine 3D-Eingabegeräte betrachtet, die nur äußerst selten und kurzzeitig als Core Pointer arbeiten.

    Für Anwendungsgebiete in denen der originale Core Pointer komplett ersetzt werden soll, ergibt sich, neben der Neuimplementierung des Gerätetreibers nach dem Lösungsansatz 3, noch eine weitere wesentlich einfachere Möglichkeit. Auf diese wird im nächsten Abschnitt kurz eingegangen.

    Erweiterungs- und Verbesserungsmöglichkeiten 

    Verbesserung der Ergonomie

    Bei der SPACE MOUSE ist es praktisch nicht möglich, mit einer Hand die Position des Mauszeigers zu kontrollieren und gleichzeitig eine Taste zu drücken. Diese Art die Maus zu benutzen, ist bei Drag-And-Drop und Markierungsaufgaben, wie sie bei allen modernen grafischen Oberflächen vorkommen, sehr häufig.

    Daraus ergibt sich für den Gerätetreiber der SPACE MOUSE im 2D-Modus eine Verbesserungsmöglichkeit. Von den 9 Tasten des Gerätes werden, wenn das Gerät als Core Pointer arbeitet, nur 5 durch das X-Window System unterstützt. Die nicht benutzten Tasten könnte man dazu nutzen, den Zustand der unterstützten Tasten umzuschalten. Dann wäre es möglich bei Drag-And-Drop mit einer solchen Taste ein Objekt auszuwählen, diese Taste loszulassen, das Objekt zu bewegen und durch nochmaliges Drücken der Taste den Drag-And-Drop Vorgang zu beenden. Dazu müßten Zustandsänderungen dieser Tasten noch vor der Erzeugung der Events abgefangen und entsprechende Masken für d3_EnqueueButtonEvent generiert werden.

    Kompletter Ersatz des originalen Core Pointers

    Um Core Pointer Events zu erzeugen, ist es nicht unbedingt erforderlich, ein Extension-Gerät als Core Pointer anzumelden oder durch den Gerätetreiber zwei unterschiedliche Geräte zu initialisieren, von denen eines permanent als Core Pointer arbeitet.

    Der jetzt vorhandene Gerätetreiber kann mit relativ geringem Aufwand so verändert werden, daß ein Gerät als Core Pointer arbeiten kann ohne seinen Status als 3D-Eingabegerät zu verlieren.

    Dazu müßte die Struktur d3_private  durch ein Flag, welches den Modus in dem das Gerät arbeitet charakterisiert, ergänzt werden. Dieses Flag wird beim Drücken der reservierten Taste jeweils umgeschaltet. In den für die Erzeugung der Events zuständigen Funktionen wird dann, anstatt nur darauf zu testen ob dieses Gerät gerade der Core Pointer ist, einfach dieses Flag zusätzlich getestet.

    Da die 2D-Events durch die mi-Funktionen generiert werden und im mi-Teil lokal gespeichert ist, welche Geräte als Core Devices fungieren, werden die Events diesen Geräten einfach ''untergeschoben''.

    Die Möglichkeit, daß eine Applikation den Arbeitsmodus eines Gerät mittels der Funktion XChangePointerDevice umschalten kann, wäre weiterhin gegeben.

    Andere Erweiterungen

    Die vorliegende Implementierung könnte noch durch Feedback-Funktionen erweitert werden. Im Fall der SPACE MOUSE könnte dann der interne Pieper durch Anwendungen angesprochen werden. Um dies zu realisieren, müßten in spacemouse.c die entsprechenden Strukturen initialisiert und die fehlenden Funktionen hinzugefügt werden.