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
  • Input Extension

    Allgemein

    Geräte die nicht den Core Devices  zugeordnet sind, werden durch die XInput Extension  kontrolliert. Clients können, die von den Core Devices unabhängigen XInput Extension Devices  öffnen und ihre Eingaben von diesen Geräten beziehen.

    Applikationen (Clients), die ein Gerät der Input Extension benutzen möchten, müssen zuerst feststellen, ob das gewünschte Gerät vorhanden ist. Nach dem anschließenden Öffnen des Gerätes legt die Applikation fest, welche Events es zu empfangen wünscht. Mögliche Event-Typen  sind:

    • DeviceKeyPress
    • DeviceKeyRelease
    • DeviceButtonPress
    • DeviceButtonRelease
    • DeviceMotionNotify
    • DeviceValuator

    Beliebige Geräte können von der Input Extension verwaltet werden. Geräte die Bewegungsdaten liefern, können dieses absolut zu einem Fixpunkt oder relativ, als Bewegungs- bzw. Rotationsgeschwindigkeit, tun.

    Die Geräte der Input Extension werden von den Clients über eine von der Extension definierten X Protokoll Erweiterung angesprochen. Einige Funktionen der Erweiterung sind: 

    GetExtensionVersion:
    Holen der Version der XInput-Extension zum Vergleichen und Feststellen ob die notwendige Funktionalität vorhanden ist.
    ListInputDevices:
    Auflisten der benutzbaren Geräte inklusive der Core Devices . Für jedes Gerät wird seine Geräte-Nummer, Typ und Klassifikation geliefert.
    OpenDevice:
    Mit Hilfe der mit ListInputDevices ermittelten Geräte-Nummer wird das Gerät für den Client ansprechbar gemacht.
    SetDeviceValuators:
    Geräte die absolute Positionen liefern, können mit diesem Aufruf zurückgesetzt werden.
    SelectExtensionEvent:
    Festlegen welche Events der X-Server für ein bestimmtes Fenster liefern soll. Übergeben wird eine Liste von Event-Klassen . Eine Event-Klasse ist ein 32 Bit Wert in dem der Event-Type und das Device kodiert sind. Die kodierten Werte erhält man mittels Makros.
    ChangePointerDevice:
    Wechseln des Gerätes, welches als Core Pointer fungiert.
    XDeviceBell:
    Auslösen eines Signaltones auf einem Extension Device.

    Benutzung eines 3D-Eingabegerätes

    Allgemeines

    Nachfolgend wird die Benutzung eines die XInput Extension  benutzenden Gerätes beschrieben. Die typische Arbeit mit einem solchen Gerät in einer Applikation gliedert sich im Wesentlichen in folgende Schritte:[Fer92][PS92]

    • Aufruf von XQueryExtension  zum Feststellen ob die Extension präsent ist.
    • Aufruf von XListInputDevices()  um alle verfügbaren Geräte herauszufinden. Der Aufruf dieser Funktion gibt einen Zeiger auf ein Feld mit Datenstrukturen (XDeviceInfo ) zurück. In diesen Datenstrukturen sind alle wichtigen Daten, wie Art und Eigenschaften des Gerätes, enthalten, die ein Client-Programm benötigt, um das von ihm gewünschte Gerät zu ermitteln.
    • Das gewünschte Gerät mit der Funktion XOpenDevice  öffnen.
    • Analog zur Arbeit mit den Core Devices  werden mit der Funktion XSelectExtensionEvent  die vom X-Server zu sendenden Events selektiert. Da im Gegensatz zu dem X-Core Protokoll die Event-Typen und -Masken der XInput Extension dynamisch durch spezielle, auf die Event-Klassen zugeschnittenen, Makros vergeben werden, wird dieser Funktion ein Feld mit den zu selektierenden Event-Klassen  übergeben.
    • Die Events der Extension werden mit den gleichen Funktionen bearbeitet, die auch für die Arbeit mit den Core Devices benutzt werden. Im Allgemeinen wird das die Funktion XNextEvent()  sein.

    Detailiertes Beispiel

    Um Geräte der XInput Extension benutzen zu können, müssen zusätzlich mit: 

    #include <X11/extensions/XInput.h>
    

    die Funktionen und Strukturen der XInput-Extension bekanntgemacht werden. XInput-Extension konforme Eingabegeräte haben in der Regel unterschiedliche Eigenschaften. Eine Anwendung braucht aber bestimmte Eigenschaften. Daher muß die Anwendung sich ein Gerät suchen, welches die gewünschten Eigenschaften hat. Folgende Funktion sucht ein 3D-Eingabegerät mit sechs Achsen.

    /*
    ** Open a XInput-Extension device
    */
    static XDevice *FindInputDevice( void )
    {
    XDeviceInfo *dinfo;
    char *ptr;
    int ndev, i, j;
    /*
    ** Is the XInput Extension präsent?
    */
    if( !XQueryExtension( dpy, INAME, &i, &i, &i)) {
    puts( "No XInput Extension" ); 
    return NULL;
    }
    /*
    ** List available input devices
    */
    dinfo = XListInputDevices( dpy, &ndev);
    for( i=0; i<ndev; i++ ) {
    /*
    ** Is the device an input extension device?
    */
    if( dinfo[i].use == IsXExtensionDevice) {
    ptr = (char *)dinfo[i].inputclassinfo;
    for( j=0; j<dinfo[i].num_classes; j++ ) {
    /*
    ** 6 degrees of freedom?
    */
    if( ((XAnyClassPtr)ptr)->class == ValuatorClass )  {
    if( ((XValuatorInfo *)ptr)->num_axes >= 6) {
    /*
    ** return the opened device
    */
    return XOpenDevice( dpy, dinfo[i].id);
    }
    }
    ptr += ((XAnyClassPtr)ptr)->length;
    }
    }
    }
    }
    

    Konnte das Gerät erfolgreich geöffnet werden, selektiert man die vom X-Server zu schickenden Events. Dabei ist zu beachten, daß die entsprechenden Event-Typen und -Klassen erst dynamisch zur Laufzeit der Applikation zu erzeugen sind. Der nachfolgenden Quelltextausschnitt zeigt dieses:

      int XiMotionClass=0, XiMotionType=0;
    ...
    if( (idev=FindInputDevice())) {
    DeviceMotionNotify( idev,
    XiMotionType,
    XiMotionClass );
    XSelectExtensionEvent( dpy, window, &XiMotionClass, 1 );
    }
    

    Die Verarbeitung der vom X-Server gesendeten Events kann folgendermaßen durchgeführt werden:

      ...
    while( !done ) {
    XNextEvent( dpy, &event);
    if( event.type==XiMotionType ) {
    t_x = xievent->axis_data[0];
    t_y = xievent->axis_data[1];
    t_z = xievent->axis_data[2];
    r_a = xievent->axis_data[3];
    r_b = xievent->axis_data[4];
    r_c = xievent->axis_data[5];      
    ...      
    } else {
    switch( event.type ) {
    case Expose:          
    ...