Zum Inhalt springen
Startseite » Linux: Touchscreen im Zwei-Monitor-Setup zähmen

Linux: Touchscreen im Zwei-Monitor-Setup zähmen

Ich betreibe einen vdr an meinem (Röhren-)Fernseher, gleichzeitig werden auf einem Touch-TFT noch Informationen zur laufenden und kommenden Sendung über osd2web ausgegeben.

vdr Menü Touchscreen

Das Problem dabei, es wollte mir einfach nicht gelingen den Touscreen zu kalibrieren, bzw. zu nutzen, da bei meiner Xserver Konfiguration immer die gesamte Fläche aus beiden Bildschirmen als Touchoberfläche angenommen wurde, was natürlich nicht funktionieren konnte.(Es hat einige Zeit gedauert, bis ich dahinter gekommen bin.:-/)

Voraussetzung für das Ganze hier ist natürlich, daß die Touchfunktion grundsätzlich funktioniert und das TFT mittels libinput angesteuert wird, sollte das nicht der Fall sein, muß man sich erst einmal um einen entsprechenden Treiber kümmern, das soll aber nicht Gegenstand dieses Artikels sein.


Erstmal meine xorg.conf:

Section "ServerLayout"
    Identifier     "Default Layout"
    Screen       0 "TV" 0 0
    Screen       1 "TFT" LeftOf "TV"
    InputDevice    "Keyboard0" "CoreKeyboard"
    InputDevice    "Mouse0" "CorePointer"
EndSection

##############  primärer Monitor (Fernseher) ################

Section "Monitor"
    Identifier     "Panasonic TV"
    VendorName     "Panasonic"
    ModelName      "TX32M20D"

    HorizSync       14-17
    VertRefresh     49-61
    Modeline "VGA2Scart_16_9" 19 1024 1032 1120 1216 576 581 586 625 -Hsync -Vsync interlace

    Option         "DPMS"
    Option         "ExactModeTimingsDVI" "True"
EndSection

Section "Device"
    Identifier     "NVIDIA Corporation GK107 [GeForce GT 640]-0"
    Driver         "nvidia"
    VendorName     "NVIDIA Corporation"
    Screen          0
    BusID          "PCI:1:0:0"
EndSection

Section "Screen"
    Identifier     "TV"
    Device         "NVIDIA Corporation GK107 [GeForce GT 640]-0"
    Monitor        "Panasonic TV"
    DefaultDepth    24
    SubSection     "Display"
        Depth       24
        Modes      "VGA2Scart_16_9"
    EndSubSection
EndSection


############### sekundärer Monitor (osd2web/graphtftng) ######################

Section "Monitor"
    Identifier     "Iiyama 1531sr"
    VendorName     "Iiyama"
    ModelName      "1531sr"
    Option         "DPMS"
EndSection

Section "Device"
    Identifier     "NVIDIA Corporation GK107 [GeForce GT 640]-1"
    Driver         "nvidia"
    VendorName     "NVIDIA Corporation"
    Screen          1
    BusID          "PCI:1:0:0"
EndSection

Section "Screen"
    Identifier     "TFT"
    Device         "NVIDIA Corporation GK107 [GeForce GT 640]-1"
    Monitor        "Iiyama 1531sr"
    DefaultDepth    24
    SubSection     "Display"
        Depth       24
        Modes      "1024x768" "1024x768_60"
    EndSubSection


    Option         "CustomEDID" "DFP-2:/etc/X11/iiyama_plt1531.edid"

EndSection

############# Input Devices ##########################

Section "InputDevice"
    # generated from default
    Identifier     "Mouse0"
    Driver         "mouse"
    Option         "Protocol" "auto"
    Option         "Device" "/dev/psaux"
    Option         "Emulate3Buttons" "no"
    Option         "ZAxisMapping" "4 5"
EndSection


Section "InputDevice"
    # generated from default
    Identifier     "Keyboard0"
    Driver         "kbd"
EndSection

############### Extensions ############################

Section "Extensions"
    Option         "Composite" "Disable"
EndSection

Soweit so gut, das funktioniert schonmal, nur der vemaledeite Touchscreen wollte nicht, wie ich wollte. Die Touchfunktion funktionierte, aber der Mauszeiger war überall, nur nicht da wo ich ihn haben wollte.;)
Nach sehr langer Suche bin ich dann bei Archlinux fündig geworden, auf dieser Seite wurde es genau erklärt, was man tun muß um den Touchscreen zu bändigen.
Ich gebe das hier jetzt noch einmal grob wieder, auch aufgrund der Tatsache, daß es sich um einen englischen Artikel handelt.

Zuerst gilt es einmal die gesamte Auflösung der beiden Monitore zu bestimmen, das kann man mit xrandr machen. Sollte man, so wie ich, die Konfiguration remote machen, also z.B. mit ssh, dann muß man den Befehlen jeweils per DISPLAY Variable angeben auf welchen Screen sich die Abfrage bezieht, in meinem Fall hat der Fernseher die :0.0 und der TFT Touchscreen die :0.1, dann sieht die Abfrage so aus:

DISPLAY=:0.0 xrandr und DISPLAY=:0.1 xrandr

In den dann folgenden Ausgaben sollte man so etwas finden:

3600x1230      50.0* 

Das bedeutet eine maximale Ausdehnung beider Monitore von 3600 Pixeln in der Breite und 1230 Pixeln in der Höhe.
(Macht man das remote, bekommt man natürlich immer nur die Werte eines Monitors und muß diese dann addieren), in meinem fall war das 1024×768 und 1024×576 dies ergibt eine Gesamtauflösung von 2048×768.

Nun gilt es den Namen des Touchscreendevices herauszubekommen, dazu benutzt man den Befehl

xinput list

Die Ausgabe sieht dann, in meinem Fall, so aus:

xxxx@vdr:~$ DISPLAY=:0.1 xinput list
 ⎡ Virtual core pointer                     id=2 [master pointer  (3)]
 ⎜   ↳ Virtual core XTEST pointer               id=4 [slave  pointer  (2)]
 ⎜   ↳ ORTEK W/L Keyboard/Mouse                 id=9 [slave  pointer  (2)]
 ⎜   ↳ eGalaxTouch Virtual Device for Single    id=10 [slave  pointer  (2)]
 ⎣ Virtual core keyboard                    id=3 [master keyboard (2)]
 ↳ Virtual core XTEST keyboard              id=5 [slave  keyboard (3)]
 ↳ Power Button                             id=6 [slave  keyboard (3)]
 ↳ Power Button                             id=7 [slave  keyboard (3)]
 ↳ ORTEK W/L Keyboard/Mouse                 id=8 [slave  keyboard (3)]

Unschwer zu erkennen ist, daß es sich um „eGalaxTouch“ mit der ID 10 handelt.


Jetzt lassen wir uns die Eigenschaften des Touch Devices mit dem Befehl xinput list-props anzeigen:

xxxxxxx@vdr:~$ DISPLAY=:0.1 xinput list-props "eGalaxTouch Virtual Device for Single"
 Device 'eGalaxTouch Virtual Device for Single':
 Device Enabled (152): 1
 Coordinate Transformation Matrix (154): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
 libinput Natural Scrolling Enabled (419): 0
 libinput Natural Scrolling Enabled Default (420): 0
 libinput Calibration Matrix (421): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
 libinput Calibration Matrix Default (422): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
 libinput Left Handed Enabled (423): 0
 libinput Left Handed Enabled Default (424): 0
 libinput Send Events Modes Available (425): 1, 0
 libinput Send Events Mode Enabled (426): 0, 0
 libinput Send Events Mode Enabled Default (427): 0, 0
 Device Node (275): "/dev/input/event20"
 Device Product ID (274): 3823, 16
 libinput Drag Lock Buttons (428):
 libinput Horizontal Scroll Enabled (429): 1

Da interessiert uns besonders die „Coordinate Transformation Matrix“, die es gilt auf die eigenen Gegebenheiten anzupassen. Mit Hilfe dieser Matrix schrumpft man praktisch die Gesamtanzeige auf ein Rechteck zusammen, sodaß nur noch dieses für die Touchfunktionalität benutzt wird.
Dazu muß man erstmal folgende Werte ermitteln, bzw. wissen:

  • Höhe der Touchfläche
  • Breite der Touchfläche
  • Horizontaler Offset (x Offset) (Anzahl der Pixel zwischen der linken Kante der Gesamtfläche und der linken Kante der Touchfläche)
  • Vertikaler Offset (y Offset) (Anzahl der Pixel zwischen der oberen Kante der Gesamtfläche und der oberen Kante der Touchfläche)

Nun gilt es die Werte für die Matrix zu berechnen:

  • c0 = Touchflächenbreite / Gesamtbreite
  • c2 = Touchflächenhöhe / Gesamthöhe
  • c1 = Touchfläche x-Offset / Gesamtbreite
  • c3 = Touchfläche y-Offset / Gesamthöhe

Die Matrix sieht so aus:

[ c0 0  c1 ]
[ 0  c2 c3 ]
[ 0  0  1  ]

Auf mein Touch TFT angewendet sieht das dann folgendermaßen aus:

  • c0 = 1024 / 2048 = 0.5
  • c2 = 768 / 768 = 1
  • c1 = 0 / 2048 = 0
  • c3 = 0 / 768 = 0

Nun muß diese Matrix an das TFT geschickt werden, das macht man mit diesem Befehl, wobei die Matrix einfach hintereinander weg eingegeben wird:

xinput set-prop "Device Name" --type=float "Coordinate Transformation Matrix" c0 0 c1 0 c2 c3 0 0 1

Im meinem Fall sieht das dann so aus:

xinput set-prop "eGalaxTouch Virtual Device for Single" --type=float "Coordinate Transformation Matrix" 0.5 0 0 0 1 0 0 0 1

Nun sollte das Touch TFT richtig funktionieren. Bei mir war das so.:-D

Sollte das nicht so sein, gibt es Hinweise im Archlinux Artikel.

Nun gibt es aber noch ein kleines Problem, die Einstellungen gehen beim nächsten Neustart wieder verloren.:-(

Aber auch dafür gibt es eine Lösung, eigentlich zwei Lösungen.

Die erste wäre das Erstellen einer udev Regel, in /etc/udev/rules.d/ erstellt man eine Datei 98-touchscreen-cal.rules mit folgendem Inhalt:

ATTRS{name}=="eGalaxTouch Virtual Device for Single", ENV{LIBINPUT_CALIBRATION_MATRIX}="0.5 0 0 0 1 0 0 0 1"

Die zweite Möglichkeit ist eine Datei 98-screen-calibration.conf in /etc/X11/xorg.conf.d/ zu erstellen, die folgende Konfig entält:

Section "InputClass"
       Identifier      "calibration"
       MatchProduct    "eGalaxTouch Virtual Device for Single"
       Option          "TransformationMatrix"  "0.5 0 0 0 1 0 0 0 1"
EndSection

Funktionieren tut beides, ist wahrscheinlich Geschmackssache wofür man sich entscheidet.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert