Portál AbcLinuxu, 3. května 2025 17:27
Jak funguje klávesnice v systému X window, jak zjistit kódy nestandardních kláves, jak nastavit vlastní klávesovou mapu.
Nedávno som v rámci upgradu prišiel k novej klávesnici. Pri tej príležitosti som objavoval, ako na nej rozchodiť "multimediálne klávesy". A keď už som bol v tom, rozhodol som sa urobiť si klávesnicu podľa svojich predstáv: primárne s anglickým rozložením kláves, s možnosťou prepnutia do slovenčiny, so znakom euro a s funkčnými multimediálnymi klávesami. O získané skúsenosti sa teraz s vami podelím.
xev
je nástroj, ktorý nám pomôže v samotnom začiatku.
Dokáže vypisovať detailné údaje o udalostiach, ktoré zachytáva jeho okno.
Medzi takéto udalosti patria pohyby myšou, zmeny polohy či veľkosti okna.
Ale pre nás najzaujímavejšie sú udalosti od klávesnice. Stlačenie klávesy
je jedna udalosť. Jej uvoľnenie je udalosť druhá.
... KeyPress event, serial 31, synthetic NO, window 0x3200001, root 0x131, subw 0x0, time 8119928, (48,-173), root:(52,413), state 0x10, keycode 38 (keysym 0x61, a), same_screen YES, XLookupString gives 1 bytes: (61) "a" XmbLookupString gives 1 bytes: (61) "a" XFilterEvent returns: False KeyRelease event, serial 31, synthetic NO, window 0x3200001, root 0x131, subw 0x0, time 8119995, (48,-173), root:(52,413), state 0x10, keycode 38 (keysym 0x61, a), same_screen YES, XLookupString gives 1 bytes: (61) "a" ...
V tomto výpise je nás v prvom rade bude zaujímať údaj
keycode 38
a tiež
(keysym 0x61, a)
. Ten prvý hovorí o tom, aký kód
vyslala klávesnica pri stlačení, resp. uvoľnení klávesy, ktorú som stlačil.
Ten druhý hovorí, aký symbol dostane aplikácia na spracovanie. V
našom prípade dostane symbol a
, čo vo väčšine prípadov znamená
písmeno "a". Než sa ale od 38 dostaneme po "a", je to ešte kľukatá
cesta.
Keď X dostane z klávesnice keycode 38, tak najprv nazrie do tabuľky,
ktorú môžete nájsť v /etc/X11/xkb/keycodes/xfree86
:
... <CAPS> = 66; <AC01> = 38; <AC02> = 39; ...
Tam sa číslo 38 prevedie na označenie AC01
. Toto označenie
sa použije pri definovaní symbolov.
Aplikácie v X pracujú so symbolmi. Stlačená klávesa a
môže znamenať napísanie písmena "a", ale tiež napísanie písmena "A". O
význame klávesy hovorí súbor definujúci mapu symbolov, ktorý nájdete napr.
v /etc/X11/xkb/symbols/pc/us
. Pre účely svojich pokusov som si
vyrobil jeho kópiu /etc/X11/xkb/symbols/pc/sk_rastos
. Aby o ňom
systém vedel treba ho pripísať do zoznamu v
/etc/X11/xkb/symbols.dir
:
... --p----- a------- sk_qwerty(basic) --p----- a------- sk_rastos(basic)
V súbore s definíciou symbolov nájdeme niečo takéto
default partial hidden alphanumeric_keys modifier_keys xkb_symbols "basic" { name[Group1]= "US/ASCII"; include "pc/pc(common)" // Alphanumeric section key <TLDE> { [ grave, asciitilde ] }; key <AE01> { [ 1, exclam ] }; key <AE02> { [ 2, at ] }; ... key <AC01> { [ a, A ] }; ...
Ako vidíte, v tomto súbore sa označenie AC01 prevedie na symbol. Oblasť medzi hranatými zátvorkami sa označuje pojmom skupina (angl. group). V rámci jednej skupiny sú vymenované všetky symboly, ktoré môže dané označenie klávesy vrátiť aplikácii. V predchádzajúcom príklade vidíme, že klávesa ktorá posiela kód 38 môže poslať symbol a, alebo A. To, ktorý z nich to konkrétne je, rozhoduje stav modifikátorov. Najčastejšie používaným modifikátorom je klávesa Shift. Kód 38 bez stlačenej klávesy Shift spôsobí poslanie symbolu a. So stlačenou klávesou Shift je to A. Ak je uvedený len jeden symbol, použije sa bez ohľadu na to či je Shift (alebo iný modifikátor) stlačený alebo nie.
Jedna skupina môže priradzovať aj viacero symbolov jednej klávese:
... key <AD03> { [ e, E, EuroSign ] }; ...
Takýto riadok zariadi, že klávesou s označením AD03 môžeme napísať e, E ale aj znak €. Prirodzene na to potrebujeme "ďalší shift". Bežne sa na tento účel používa klávesa Alt vpravo od medzery. Aby sme ju takýmto spôsobom mohli použiť, musí súbor s mapovaním symbolov obsahovať nasledovné 2 riadky:
key <RALT> { type="TWO_LEVEL", [ ISO_Level3_Shift, ISO_Level3_Shift ] }; modifier_map Mod5 { <RALT> };
Systém X-windows umožňuje definovať viacero skupín prislúchajúcich jednej klávese. Využiť to možno napríklad na prepínanie lokálnej klávesnice. Ja používam najčastejšie anglickú klávesnicu, ale občas potrebujem aj klávesnicu slovenskú. Preto som si vyrobil vlastný súbor s mapovaním kláves na symboly:
... key <AE02> { [ 2, at ], [lcaron, 2] }; key <AE03> { [ 3, numbersign ], [scaron, 3] }; key <AE04> { [ 4, dollar ], [ccaron, 4] }; key <AE05> { [ 5, percent ], [tcaron, 5] }; ...
Zoznam použiteľných názvov symbolov možno nájsť napr. v súbore
/usr/include/X11/keysymdef.h
:
... #define XK_scaron 0x1b9 ... #define XK_ccaron 0x1e8 ...
Mnohé z nich sa dajú uhádnuť. Písmená s mäkčeňom sú nesú v sebe
označenie caron
(napr. lcaron, dcaron, Rcaron), písmená s
dĺžňom nesú v sebe označenie acute
(aacute,iacute,Eacute).
České u s krúžkom je uring, resp. Uring. Klávesy mäkčeň a dĺžeň, ktoré
symbol generujú až po stlačení ďalšej klávesy sa nazývajú mŕtve (dead)
klávesy: dead_caron a dead_acute.
No a keď už sme sa prehrýzli až sem, vrátime sa naspäť k multimediálnym klávesám. Klávesa, ktorá nemá priradený symbol, spôsobí nasledovný výstup z programu xev:
KeyRelease event, serial 31, synthetic NO, window 0x3400001, root 0x131, subw 0x0, time 17288868, (75,22), root:(79,608), state 0x10, keycode 176 (keysym 0x0, NoSymbol), same_screen YES, XLookupString gives 0 bytes:
Ako vidíte, klávesa s kódom 176, nemá priradený žiaden symbol. V
súbore /etc/X11/xkb/keycodes/xfree86
sa dočítame, že klávesa
dávajúca kód 176 má označenie I30. Keďže na klávese je
namaľovaný symbol označujúci pridávanie hlasitosti, tak hľadám niečo
podobné v /usr/include/X11/keysymdef.h
. Tam však nič také
nie je, ale niečo sa dá nájsť v /usr/include/X11/XF86keysym.h
(uznávam, že to nie je moc koncepčný krok, ale párkrát grep mi
pomohl ;-)):
#define XF86XK_AudioRaiseVolume 0x1008FF13
No a tak do súboru s definíciou pridávam riadok:
key <I30> { [ XF86AudioRaiseVolume ] };
Tento postup som použil na všetky klávesy na mojej klávesnici.
Prv než sa pokúsime nové mapovanie kláves použiť, môžeme urobiť
syntaktickú kontrolu pomocou xkbcomp
(ono to vlastne nie je
nástroj primárne na to určený, ale poslúži):
$ xkbcomp /etc/X11/xkb/symbols/pc/sk_rastos expected keysym, got Eurosign: line 42 of /etc/X11/xkb/symbols/pc/sk_rastos last scanned symbol is: Eurosign
Chyba v tomto prípade je v tom, že písmeno s v Eurosign má byť veľké: EuroSign.
Nové mapovanie kláves možno použiť pomocou programu
setxkbmap
a prepínača -layout
:
$ setxkbmap -layout sk_rastos
setxkbmap pozná tiež prepínač -option
, ktorým môžeme okrem
iného bližšie určiť spôsob prepínania medzi grupami. Nasledovný príkaz
napríklad umožní prepínanie medzi grupami súčasným stlačením oboch kláves
Shift. Prepnutie do druhej grupy je indikované zapnutím LED-ky
ScrollLock.
$ setxkbmap -layout sk_rastos -option grp:shift_toggle,grp_led:scroll
Alternatívne môžete definovať želané rozloženie kláves v konfiguračnom
súbore X-windows: /etc/X11/xorg.conf
resp.
/etc/X11/XF86Config
(podľa toho či používate X.Org alebo
XFree):
Section "InputDevice" Identifier "Keyboard0" Driver "keyboard" Option "XkbRules" "xorg" Option "XkbModel" "pc105" Option "XkbLayout" "sk_rastos" Option "XkbOptions" "grp:shift_toggle,grp_led:scroll" EndSection
Doteraz popisovaný spôsob definovania významu kláves je vhodný skôr
pre definovanie klávesnice, ktorá sa výrazným spôsobom líši od klávesníc,
ktoré sú dodávané s inštaláciou X-Windows. Vhodnejší je tiež tam, kde
chceme definovať rozloženie kláves pre viacero používateľov. Okrem tohoto
spôsobu máme ešte k dispozícii program xmodmap
. Ten takisto
dokáže meniť význam kláves (a dokonca aj tlačidiel na myši). Zmenu
definície jednej klávesy môžeme urobiť napr. takto:
xmodmap -e 'keycode 229=Find'
Takýmto príkazom necháme vykonať výraz, ktorý modifikuje mapu rozloženie
kláves. Konkrétne klávese, ktorá posiela kód 229, priradzujeme
symbol Find. Rovnako ako v predchádzajúcom prípade kód klávesy
získame pomocou programu xev a symboly, ktoré môžeme použiť opäť nájdeme v
keysymdef.h
resp. XF86keysym.h
. Pochopiteľne táto
zmena sa nezachová pre ďalšie sedenie. Kompletný popis schopností xmodmap
nájdete v manuálovej stránke.
Na záver by som rád vyjadril poďakovanie Yetimu, za inšpiráciu a nakopnutie správnym smerom a tiež nádej, že vám informácie z tohto článku k niečomu budú.
setxkbmap -model pc104 -layout cz_qwerty -variant basic
.
Parametry jsou v ~/.kde/share/config/kxkbrc
a naklika se to nekde v control centru v kbd layout
setxkbmap -model pc105 -layout en_US -variant basic (anglická) setxkbmap -model pc105 -layout cz_qwerty -variant basic (česká) setxkbmap -option grp_led:scroll,grp:shift_toggle,altwin:meta_win (nějaké doplňující volby)Ve Fedoře 3 jsem používal 'wokenice' jako modifikátory a nerozlišovalo se mezi pravou a levou wokenicí. Po upgrade funguje už jen levá wokenice a pravá se chová nějak podivně. Chtěl bych, aby obě wokenice byly použitelné jako modifikátor. Neví někdo, co s tím? Výpis z xev: Levá wokenice:
KeyPress event, serial 26, synthetic NO, window 0x3000001, root 0x60, subw 0x0, time 2831381, (85,116), root:(763,168), state 0x10, keycode 115 (keysym 0xffe7, Meta_L), same_screen YES, XLookupString gives 0 bytes: XmbLookupString gives 0 bytes: XFilterEvent returns: False KeyRelease event, serial 29, synthetic NO, window 0x3000001, root 0x60, subw 0x0, time 2831487, (85,116), root:(763,168), state 0x50, keycode 115 (keysym 0xffe7, Meta_L), same_screen YES, XLookupString gives 0 bytes:pravá wokenice:
ButtonPress event, serial 29, synthetic NO, window 0x3000001, root 0x60, subw 0x0, time 2835273, (85,116), root:(763,168), state 0x10, button 4, same_screen YES ButtonRelease event, serial 29, synthetic NO, window 0x3000001, root 0x60, subw 0x0, time 2835273, (85,116), root:(763,168), state 0x810, button 4, same_screen YES
Moc pekne. Rad bych doplnil, ze multimedialni klavesnici lze v Linuxu rozbehat pomerne komfortne take s pomoci projektu LinEAK.
Ja mam jiny problem: co delat, kdyz ta klavesa na klavesnici vubec negeneruje udalost ... cili zjevne ovladac klavesnice to neumi. Existuje nejaky jednoduchy zpusob, jak to rozbehnout, nebo by se musel upravit ovladac?
Tiež by sa oplatilo pozrieť, čo povie na tie klávesy program showkey
v konzole.
No a posledná vec, čo ma napadá: kedysi sa tu vyskytla debata o "evdev" a X. Nie som si tým istý, ale myslím, že to možno nejako súvisí.
X(7x) X(7x) NAME X - a portable, network-transparent window system SYNOPSIS The X Window System is a network transparent window system which runs on a wide range of computing and graphics machines. It should be rela- tively straightforward to build the X Consortium software distribution on most ANSI C and POSIX compliant systems. Commercial implementations are also available for a wide range of platforms. The X Consortium requests that the following names be used when refer- ring to this software: X X Window System X Version 11 X Window System, Version 11 X11 X Window System is a trademark of X Consortium, Inc.
aplay /usr/share/sounds/number_pressed_warning.wav.. přehraj a pak pokračuj jako obvykle. Tuším, je potřeba to namapovat nízkoúrovňově, tedy nejlépe přímo pro Xorg. Za nápady předem děkuji, věřím že nejsem jediný, komu by se taková zvuková výstraha hodila
V tomto výpise je nás v prvom rade bude zaujímať údaj keycode 38 a tiež (keysym 0x61, a). Ten prvý hovorí o tom, aký kód vyslala klávesnica pri stlačení, …xev hlasi dvojici <keycode, keysym>. keycode ovsem neni kod, ktery vysle klavesnice (tomu se rika scancode a casto je to pekne dlouha sekvence -- napr. u Pause), anybrz kod, kterym jadro oznacuje jednotlive klavesy. Zpracovani probiha takto:
bin. sekvence scan code klavesnice -------------> radic klavesnice ---------> keycode keysym jadro -------> X server ------> X klient
bin. sekvence scan code klavesnice -------------> radic klavesnice ---------> key name ovladač klávesnice -------> emulační vrstva klávesnice MS Multimedia simulovaný PS-2 keycode keysym ----------------------> X server ------> X klientAle mělo by to správně probíhat takto:
bin. sekvence scan code klavesnice -------------> radic klavesnice ---------> key name X key name ovladač klávesnice -------> X server ------> X klientV X je pomocí Option "CustomKeycodes" "on" zapnout MEDIUM_RAW mode (případně ještě kernel přepnout přepínačem atkbd_softraw). Ovšem v praxi je to zatím na nic, protože ovladač MEDIUM_RAW režimu v X stejně neumí zpracovat kódy kláves nad 240, které mu kernel posílá. Výsledkem je, že ne-MS multimediální klávesnice generují jiné kódy, než v kernelu 2.4, nebo negenerují nic. V případě AT klávesnic to lze nastavit, v případě jiných klávesnic je nutné se uchýlit ke změně kódů v kernelovém ovladači.
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.