Myši, klávesnice, touchpady a jiné v linuxovém prostředí

Z thewoodcraft.org


Do mých 22 let mne počítače nezajímaly. Jejich možnosti mne zaujaly až po roce 1991, kdy jsem je začal využívat především pro DTP práce. S internetem jsem se setkal až coby student politologie a religionistiky na MU v Brně, počátkem roku 1998. A přes webové technologie jsem se dostal od MS Windows k Linuxu. Roku 2003 jsem nastoupil jako adminitrátor MS Windows serveru a webu na ÚMOb Ostrava-Jih – do r. 2010 to byl největší obecní úřad v ČR, který na 90% pracovních stanic (cca 250 strojů) používal linuxový desktop. Tam jsem se dostal k virtualizaci a definitivně přestal používat MS Windows.

Na jaře 2008 jsme se rozhodli přestěhovat do Prahy a na základě mé inzerce na jobs.cz jsem dostal nabídku abych nastoupil jako administrátor linuxové infrastruktury počítačových laboratoří na Katedru řídící techniky ČVUT na Karlově náměstí v Praze. Do té doby pro mne znamenal pojem laboratoř místnost plnou baněk, zkumavek a křivulí. Počítačové laboratoře však připomínají spíš klasickou školní třídu, vybavenou výpočetní technikou, na níž se studenti učí programovat.

A tak jsem se dostal k disklessovému linuxu. V počítačových laboratořích DCE se tehdy používal tzv. half-diskless, který vyžadoval lokálně nainstalovaný zavaděč GRUB se zakompilovaným ovladačem síťové karty. Což znamenalo, že každá pracovní stanice vyžadovala vlastní sestavení zavaděče a to bylo dost nepraktické. Proto jsem během následujících čtyř let přepracoval celou laboratorní infrastrukturu na full-diskless. Na DCE takto fungují laboratoře od r. 2010 – více viz Přehled vývoje infrastruktury pro diskless Debian na katedře DCE.

Přechodem na full-diskless jsem získal víc volného času a víceméně náhodou jsem začal pracovat na vedlejšák jako administrátor unixové infrastruktury pro eIdentity. Tam jsem mohl prakticky uplatnit další technologie s nimiž jsem se seznámil při budování disklessové infrastruktury na DCE. Realizoval jsem několik virtualizačních clusterů i distribuovaná úložiště.

Od roku 2014 se diskless DCE propaguje i do laboratoří spravovaných katedrou počítačů.

V roce 2016 jsem po pěti letech definitivně ukončil práci pro eIdentity, protože jsem svůj volný čas u počítače chtěl nadále věnovat už jen tomuto serveru, který běží od r. 2013. A svůj pracovní čas jsem rozdělil mezi DCE a Katedru kybernetiky, která sídlí ve stejné budově – pro její počítačové laboratoře jsem vytvořil obdobnou infrastrukturu.

Do léta roku 2019 byl laboratorní diskless na DCE a DC provozován výhradně přes pevnou síť, ale od zimního semestru by měl stejný diskless běžet v rámci DC i na TurtleBotech přes Wi-Fi.

Myši, klávesnice, touchpady, dotyková plocha na monitoru, aj. – to vše patří mezi vstupně-výstupní zařízení (I/O – z angl. Input/Output), jejichž prostřednictvím je realizována interakce mezi počítačem a jeho obsluhou.

O rozpoznání hardwarového zařízení se v linuxu stará udev. Jakmile zjistí, že se objevilo nové zařízení, pokusí se podle jeho identifikátoru zjistit jaký se má použít ovladač. Identifikátor tvoří dvě čísla (v hexa), kterými se nové zařízení ohlásí:

user@stroj:~# lsusb | grep Logitech
Bus 004 Device 003: ID 046d:c050 Logitech, Inc. RX 250 Optical Mouse
                        |    \
                        \     kód zařízení
                         kód výrobce

Pokud zjistí, že v linuxovém jádře odpovídající ovladač dosud není, pokusí se ho zavést. Jádro při zavedení ovladače osahá zařízení a pokud jde o vstupní zařízení vytvoří přes evdev v adresáři /dev/input očíslované zařízení event.

Původně to fungovalo tak, že pro každý typ hardware existovalo zařízení, které se i podobně jmenovalo – např. /dev/input/mouse Pokud ho Xorg server při spouštění našel, použil k jeho obsluze odpovídající driver – v případě myši to byl modul /usr/lib/xorg/modules/input/mouse_drv.so.

To byla oproti dávné minulosti ohromná výhoda, protože původní XFree86 server do verze 4.x vůbec modulární nebyl a ovladače zařízení v něm musely být natvrdo zadrátované. Vývoj X.Org serveru ale začal forkem verze XFree86 4.4 RC2 (číslované jako X11R6.7.0), která již byla částečně modulární.

Většinu běžných modulů u X serveru časem nahradil generický modul evdev, ale ne všechny. Například tablety stále používaly modul wacom a touchpady synaptics – což byly ovladače, které měly víc konfiguračních možností, než generický evdev.

Původně tedy události z myši procházely:

Linux kernel → libevdev → xf86-input-evdev → X server → X client

Protože tím X server hrabal jejich prostřednictvím přímo do prostoru jádra, mohl zapříčinit i jeho pád. Proto vznikla knihovna libinput, aby vše zastřešila a oddělila zařízení od správce oken. U X.org serveru se objevila od verze 1.16 (červen 2014). Dnes tedy události probublávají takto…

Linux kernel → libevdev → libinput → xf86-input-libinput → X server → X client
                      |           ↘                     ↘           ↘
                       ↘           libinput-tools        xinput      x11-utils
                        evemu-tools
PoznámkaI když se u novějších verzí X.Org serveru používá k obsluze vstupů již zpravidla pouze libinput, stále se můžete dostat do situace, kdy bude nutné použít jiný ovladač. Proto je následující část věnovaná tomu, jak na různých úrovních vstupně-výstupní zařízení zkoumat a podle potřeby s nimi pracovat.

Zkoumáme zařízení v /dev/input

Veškerá zařízení, rozpoznaná jádrem najdeme v adresáři /dev/input, pojmenovaná event a doplněná pořadovým číslem.

Ale můžete tam najít i: js0 (joystick), mice, mouse0, aj. Jsou to rozhraní, pro aplikace, které nechtějí číst data přes evdev, ale přímo ze zařízení.

Protože z generického pojmenování zařízení není zřejmé oč jde, existují ještě dva adresáře, ze kterých na ně odkazují pojmenované symlinky. Buď podle jména, nebo podle cesty na sběrnici. Chcete-li tedy prozkoumat neznámé zařízení, máte několik možností.

Jde-li o zařízení které lze připojit dodatečně, můžete sledovat výstup z příkazu dmesg,

root@stroj:~# dmesg -we
…
[úno27 15:32] usb 4-1: new low-speed USB device number 3 using xhci_hcd
[  +0,188430] usb 4-1: New USB device found, idVendor=078c, idProduct=0401, bcdDevice= 1.01
[  +0,000005] usb 4-1: New USB device strings: Mfr=1, Product=2, SerialNumber=4
[  +0,000002] usb 4-1: Product: Digitizer
[  +0,000002] usb 4-1: Manufacturer: GTCO CalComp
[  +0,000002] usb 4-1: SerialNumber: IWBRD0501501001
[  +0,072346] input: GTCO_CalComp as /devices/pci0000:00/0000:00:10.1/usb4/4-1/4-1:1.0/input/input28
[  +0,000697] usbcore: registered new interface driver gtco

V tomto případě šlo o zařízení funkčně podobné SMART Boardu. Digitizér je v podstatě tablet velikosti školní tabule. Od SMART Boardu se liší v použití. Nejde o interaktivní tabuli, i když by se nejspíš dal digitizér tímto způsobem v kombinaci s projektorem využít, ale o zařízení určené pro digitalizaci plánů, či šablon.

Po vylistování cesty která se objevila v logu je zřejmé, že tabule byla funkční:

root@stroj:~# ls /sys/devices/pci0000:00/0000:00:10.1/usb4/4-1/4-1:1.0/input/input28
capabilities  device  event19  id  js1  modalias  name  phys  power  properties  subsystem  uevent  uniq

Na výpisu je vidět, že evdev vytvořil příslušné zařízení s názvem event19. Bohužel digitizér nebylo možné otestovat, protože aktivní pera, které byly jeho součástí nefungovaly a na příslušné zařízení neposílaly žádné události.

Hledáme zařízení v adresáři /sys

Pro vyhledání zařízení v adresáři /sys můžeme zkusit použít také find

user@stroj:~$ find /sys -type d -name 'input[0-9]*'
…
/sys/devices/pci0000:00/0000:00:10.1/usb4/4-1/4-1:1.0/input/input28
…

evemu-tools

Další možnosti zkoumání nabízí balík nástrojů evemu-tools, který si nejspíš budete muset doinstalovat. Obsahuje víc nástrojů, nás však v tuto chvíli zajímá především utilita evemu-describe, která umí vypsat informace o zařízení. S její pomocí můžete zjistit nejenom o jaké zařízení jde, ale i kódy událostí, které se na něm mohou objevit.

Podobný výstup nabídne utilita, která s těmito nástroji spolupracuje evtest, která je rovněž v samostatném balíku, který si budete muset doinstalovat.

root@stroj:~# evtest /dev/input/event28
Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x78c product 0x401 version 0x101
Input device name: "GTCO_CalComp"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
  Event type 3 (EV_ABS)
    Event code 0 (ABS_X)
      Value  87381
      Min        0
      Max    74000
    Event code 1 (ABS_Y)
      Value  20155
      Min        0
      Max    42000
    Event code 24 (ABS_PRESSURE)
      Value      0
      Min        0
      Max        0
    Event code 25 (ABS_DISTANCE)
      Value      0
      Min        0
      Max        1
    Event code 26 (ABS_TILT_X)
      Value      0
      Min        0
      Max        0
    Event code 27 (ABS_TILT_Y)
      Value      0
      Min        0
      Max        0
    Event code 40 (ABS_MISC)
      Value      1
      Min        0
      Max      255
  Event type 4 (EV_MSC)
    Event code 0 (MSC_SERIAL)
    Event code 3 (MSC_RAW)
    Event code 4 (MSC_SCAN)
Properties:
…

Nedělá v podstatě nic jiného, než že postupně zavolá evemu-describe a pak evemu-record, jehož výstup "přetočí" na standarní výstup, kde můžete průběžně sledovat jaké události ze zařízení přicházejí. Utilita evemu-record totiž svůj výstup ukládá do souboru. Záznam událostí z tohoto souboru se dá i znovu přehrát – pomocí nástroje evemu-play.

Přes tyto nástroje však můžete zkoumat pouze generická zařízení typu event. Pokud se pokusíte tenhle nástroj poštvat na jiný typ zařízení, tak pochopitelně pohoříte.

Sledujeme události přes evtest

Pokud na zařízení přicházejí nějaké události, vypadá výstup zhruba takhle:

E: 1.912203 0000 0000 0000      # ------------ SYN_REPORT (0) ---------- +24ms
E: 2.368213 0004 0004 589826    # EV_MSC / MSC_SCAN             589826
E: 2.368213 0001 0111 0001      # EV_KEY / BTN_RIGHT            1
E: 2.368213 0000 0000 0000      # ------------ SYN_REPORT (0) ---------- +456ms
E: 2.528220 0004 0004 589826    # EV_MSC / MSC_SCAN             589826
E: 2.528220 0001 0111 0000      # EV_KEY / BTN_RIGHT            0

Pochopitelně se liší v závislosti na tom, jaké události zařízení podporuje. Tento ukázkový výstup patří k myši. K dispozici je i nástroj evemu-event, přes který lze na vybrané zařízení odeslat určitá událost, protože zažízení tohoto typu jsou obousměrná. Tohle je ukázkový příklad, jak se to dá udělat:

~# evemu-event /dev/input/event2 --type 1 --code 273 --value 0

Typ a kód události odpovídají konfiguraci zařízení (viz výše). V tomto případě ke číslo 273 kód pro pravé tlačíko myši (BTN_RIGHT)

Jen pro úplnost uvádím že existuje také nástroj evemu-device, přes který si lze vytvořit a nakonfigurovat vlastní virtuální vstupní zařízení.

libinput-tools

Jednotlivé nástroje zastupuje příkaz libinput, které volá na základě předaného příkazu:

~# libinput list-devices
…
Device:           Lid Switch
Kernel:           /dev/input/event5
Group:            3
Seat:             seat0, default
Capabilities:     switch
Tap-to-click:     n/a
Tap-and-drag:     n/a
Tap drag lock:    n/a
Left-handed:      n/a
Nat.scrolling:    n/a
Middle emulation: n/a
Calibration:      n/a
Scroll methods:   none
Click methods:    none
Disable-w-typing: n/a
Accel profiles:   n/a
Rotation:         n/a

…
Device:           Logitech USB-PS/2 Optical Mouse
Kernel:           /dev/input/event3
Group:            6
Seat:             seat0, default
Capabilities:     pointer 
Tap-to-click:     n/a
Tap-and-drag:     n/a
Tap drag lock:    n/a
Left-handed:      disabled
Nat.scrolling:    disabled
Middle emulation: disabled
Calibration:      n/a
Scroll methods:   button
Click methods:    none
Disable-w-typing: n/a
Accel profiles:   flat *adaptive
Rotation:         n/a

…

Tento příkaz vypíše všechna event zařízení, s nimiž umí libinput pracovat. Pokud zařízení nepodporuje nějaké vlastnosti, je u příslušného parametru uvedeno n/a, případně none.

Pokud zařízení má nějakou vlastnost, kterou libinput nepodporuje, tak příkaz oznámí chybu a vlastnosti příslušného zařízení nevypíše!

Pro takové zařízení lze vytvořit v adresáři /usr/share/libinput soubor s příponou .quirks, který pro příslušnou vlastnost chybějící výchozí parametry nastaví. U takového zařízení si je pak můžeme vypsat.

~# libinput quirks list /dev/input/event5
AttrLidSwitchReliability=reliable

Záměrně jsem u předchozího výpisu uvedl i /dev/input/event5, abyste si mohli ten výstup porovnat.

Odpovídající soubor /usr/share/libinput/10-generic-lid.quirks má následující obsah:

~$ cat /usr/share/libinput/10-generic-lid.quirks
# Do not edit this file, it will be overwritten on update

[Lid Switch Ct9]
MatchName=*Lid Switch*
MatchDMIModalias=dmi:*:ct9:*
AttrLidSwitchReliability=reliable

[Lid Switch Ct10]
MatchName=*Lid Switch*
MatchDMIModalias=dmi:*:ct10:*
AttrLidSwitchReliability=reliable

Sledujeme události přes libinput debug-events

Událostmi, které procházejí z event zařízení přes libinput můžeme sledovat přes akci debug-events – ovšem pouze v případě, že s ním umí pracovat.

~# libinput debug-events --device /dev/input/event3
-event3   DEVICE_ADDED     Logitech USB-PS/2 Optical Mouse   seat0 default group1  cap:p left scroll-nat scroll-button
 event3   POINTER_MOTION    +2.42s        2.00/  1.00 ( +6.00/ +3.00)
 event3   POINTER_MOTION    +2.43s        3.69/  1.84 ( +4.00/ +2.00)
 event3   POINTER_MOTION    +2.44s        2.35/  4.70 ( +2.00/ +4.00)
 event3   POINTER_MOTION    +2.45s        2.10/  1.05 ( +2.00/ +1.00
…
Upozornění Pokud libinput oznámí chybu na zařízení a odmítne ho sledovat, ale přes evtest zjistíte, že na ně události přicházejí. Tak to znamená, že v konfiguraci X serveru musíte použít jiný ovladač, než libinput. Můžete zkusit použít evdev, synaptics, nebo wacom – podle typu zařízení.

Události, které procházejí přes libinput můžeme rovněž zaznamenávat a přehrávat, podobně, jako když použijeme evemu-tools.

Kromě toho ale máme k dispozici ještě jeden příkaz: measure, který umožňuje měřit speciální vlastnosti u dotykových zařízení, jako je dotyková obrazovka (touchscreen), nebo touchpad.

xinput

Přes utilitu xinput si lze vypsat aktuální seznam připojených zařízení. V tomto konkrétním případě odfiltrovaný na zařízení typu keyboard (klávesnice).

user@stroj:~$ xinput -list
⎡ Virtual core pointer                          id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ Logitech USB Optical Mouse                id=9    [slave  pointer  (2)]
⎜   ↳ SynPS/2 Synaptics TouchPad                id=12   [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)]
    ↳ Video Bus                                 id=7    [slave  keyboard (3)]
    ↳ Sleep Button                              id=8    [slave  keyboard (3)]
    ↳ HP HD Webcam [Fixed]: HP HD Web           id=10   [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=11   [slave  keyboard (3)]
    ↳   USB Keyboard System Control             id=13   [slave  keyboard (3)]
    ↳   USB Keyboard                            id=14   [slave  keyboard (3)]
    ↳   USB Keyboard Consumer Control           id=15   [slave  keyboard (3)]

V tomto konkrétním příkladě bylo potřeba zjistit id druhé klávesnice (připojené přes USB), aby u ní bylo možné použít jiné rozložení kláves:

user@stroj:~$ setxkbmap -device 14 -layout us

Transformační matice

Schéma závislosti jednotlivých položek transformační matice vůči celkové pracovní ploše (screenu), při kalibraci vstupního zařízení SMART Boardu.

Mapování kláves a sledování událostí přes xev