Nedávno som v rámci upgradu prišiel k novej klávesnici. A 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.
/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> };
... key{ [ 2, at ], [lcaron, 2] }; key { [ 3, numbersign ], [scaron, 3] }; key { [ 4, dollar ], [ccaron, 4] }; key { [ 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 pomohlo ;-)):
#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 uží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ú.