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

From thewoodcraft.org
Jump to navigation Jump to search
PoznámkaJako vývojář a správce disklessové infrastruktury Katedry řídící techniky ČVUT na Karlově náměstí v Praze pracuji od r. 2008 a od roku 2016 dělám tutéž práci i pro Katedru kybernetiky, která sídlí v téže budově.

Disklessová infrastruktura se používá většinou v počítačových laboratořích. Do onoho roku 2008 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.

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

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