Au commencement étaient les keycodes

Le premier problème de ce clavier est qu'il n'est pas bien compris par le noyau. Quand on est en console, la plupart des touches fonctionnent correctement, mais certaines sont inconnues au niveau du noyau et ne sont pas traduites en quoi que ce soit. Cela doit être réparé en premier, car même si la plupart des gens n'utilisent que l'interface graphique, celle-ci repose sur le noyau pour savoir quels codes de touches correspondent à quelles touches.

Je l'ai fait par essai et erreur, appuyant sur les touches de mon clavier jusqu'à ce que le message terrible arrive :

atkbd.c: Use 'setkeycodes e016 ' to make it known.
atkbd.c: Unknown key released (translated set 2, code 0x96 on isa0060/serio0).

Quand le noyau connaît la transformation, il est possible pour X d'utiliser les touches (sinon X ne reçoit rien du tout). J'ai mis en jaune les touches qui avaient besoin d'être initialisées par le script suivant (à mettre dans /etc/init.d, faire un lien dans /etc/rcS.d/S47keymap-logitech (le fichier complet est attaché ci-dessous):

setkeycodes e011 216;setkeycodes e012 212;setkeycodes e013 218
setkeycodes e014 221;setkeycodes e016 135;setkeycodes e03b 181
setkeycodes e03c 232;setkeycodes e03d 233;setkeycodes e03e 231
setkeycodes e03f 131;setkeycodes e040 182;setkeycodes e041 210
setkeycodes e042 234;setkeycodes e043 157;setkeycodes e044 235
setkeycodes e057 148;setkeycodes e058 149

Il y a d'autres choses faites dans le script complet, en particulier je lie chaque touche anciennement inconnue à une chaîne de caractère qui la décrit quand elle est utilisée en console. Gadget, mais on ne se refait pas. Attention, les touches de fonction et la roulette de gauche sont correctes ; c'est les touches de fonction utilisées en dehors du « Verrouillage fonction » et le clic-roulette qui ne sont pas reconnues (j'ai lié ce dernier à Coller).

Comment ai-je trouvé les codes à mettre là ? La première fois, j'ai mis des valeurs non utilisées prises au hasard. Puis j'ai trouvé des informations intéressantes dans /usr/share/X11/xkb/keycodes/evdev qui m'ont donné les codes prédéfinis pour evdev, ce qui était bien. Toutefois :

<I222> = 222;   // #define KEY_QUESTION            214
<I223> = 223; // #define KEY_EMAIL 215
<I224> = 224; // #define KEY_CHAT 216
<I225> = 225; // #define KEY_SEARCH 217
<I226> = 226; // #define KEY_CONNECT 218
<I227> = 227; // #define KEY_FINANCE 219

Vous voyez qu'il y a sur chaque ligne deux numéros: le deuxième est le bon, et vaut 8 de moins que le premier. Toutefois, sur certaines lignes, il n'y a qu'un seul nombre et il faut donc enlever 8 au nombre avant de le mettre en deuxième argument de setkeycodes. Si vous respectez ces définitions, la deuxième étape sera plus simple (moins de choses à faire pour utiliser pour X).

Apprenons quelque chose à XKB

XKB est la couche logicielle de X qui s'occupe des claviers, des modificateurs, de leurs dispositions. L'un des problème c'est que si vous modifiez vos fichiers, les changements ne seront pas conservés d'une mise à jour à la suivante de xkb-data. Pour raisons historiques, l'un de ces fichiers a été transformé en conffile, les autres sont dans /usr/share/X11/xkb. Avec l'arrivée de evdev, celui qui est marqué comme étant un conffile n'est même plus celui à modifier de toute façon.

Donc la deuxième étape est finalement de faire un script qui patche ces fichiers, met en place des diversions, et permet de revenir en arrière. Je vous donne directement le résultat en fichier attaché, sachant qu'il est important pour moi de ne pas corrompre la base de données des claviers). D'où mon fichier /etc/init.d/fixkeyboard (lié en tant que /etc/rcS.d/S47fixkeyboard et /etc/rc{0,1,6}.d/K47fixkeyboard).

Attention : le script attaché n'est pas LSB-compliant (n'utilise pas les fonctions LSB pour afficher ses messages) et utilise bash. Je n'avais pas le temps de faire mieux ; si quelqu'un rédige mieux, qu'il m'en envoie une copie !

Comment inclure des modifications personnelles d'un plan de clavier ?

Maintenant que notre système XKB peut être patchée facilement, il faut le patcher. J'ai aussi la version qui fait la modification pour le système de règles base (pas d'utilisation de evdev). Je ne compte plus l'utiliser, mais bon, je l'ai. Toutefois, pour des raisons de simplicité de ce tutoriel, je vais ne pas en tenir compte.

La première chose à faire est de tester ce qui marche déjà. La plupart des chose sont reconnues d'office (j'ai choisi un modèle de clavier proche de l'Elite Keyboard, mais en fait, evdev ignore le modèle pour ce qui est des touches multimédia). En utilisant xev pour vérifier les keycodes, j'ai pu m'assurer que tout ce qui était traduit en symboles dans la section evdev de /usr/share/X11/xkb/symbols/inet fonctionnait.

// Evdev Standardized Keycodes
partial alphanumeric_keys
xkb_symbols "evdev" {
key <MUTE> { [ XF86AudioMute ] };
key <VOL-> { [ XF86AudioLowerVolume ] };
key <VOL+> { [ XF86AudioRaiseVolume ] };
key <POWR> { [ XF86PowerOff ] };
key <STOP> { [ Cancel ] };
key <AGAI> { [ Redo ] };
key <PROP> { [ SunProps ] };
...

Donc en fait, presque rien à changer... sauf que certaines lignes sont commentées, évidemment pour des touches dont j'avais besoin :

    key <I223>   {      [ XF86Mail              ]       };
// key <I224> { [ XF86Messenger ] }; // KEY_CHAT
key <I225> { [ XF86Search ] };
// key <I226> { [ XF86Go ] }; // KEY_CONNECT
key <I227> { [ XF86Finance ] };

C'est vraiment dommage, car à part ces deux lignes, tout était en place. Un jour, il faudra que je comprenne pourquoi elles ont été commentées.

De toute façon, j'avais aussi ma disposition de clavier personnelle à mettre. Comme cette petite réparation est moins intrusive, je vais la décrire (et uniquement elle) au cas où ça servirait à quelqu'un.

Donc, je dois en gros rajouter ces deux lignes à la définition de mon clavier.

Je préfère ne pas changer les modèles usuels (auquel cas c'est très simple : je décommente les deux lignes et c'est fini ; si ces lignes sont commentées, il y a peut-être une raison sérieuse), donc je vais créer une option spéciale juste pour ces deux touches.

Je copie d'abord /usr/share/X11/xkb vers /usr/share/X11/xkb.orig et /usr/share/X11/xkb.mod. Je n'éditerai que le répertoire mod, puis un diff -d -x 'rules/x{free86,org}*' -x 'rules/base.xml' -ur ../xkb.orig/ . > /etc/X11/xkb/keyboard.patch et un cd /etc/X11/xkb; diff -u base.xml.orig base.xml > /etc/X11/xkb/xml.patch fera le reste.

Remarque : la commande complexe pour le diff n'est pas nécessaire si on n'édite que les règles de la série evdev. C'est à cause des liens symboliques.

Pour ajouter une option, il faut donc d'abord modifier les règles (rules) de base et de evdev. J'ai d'abord ajouté un modèle logielite à la liste des modèles. Un peu plus loi, j'ai ajouté le support pour mes nouveaux symboles dans la liste des options :

...
! option = symbols
fixinet:logielite = +inet(logielite)
grp:shift_toggle = +group(shifts_toggle)
...

Maintenant, ce travail devrait normalement être fait dans les deux formats de règles (base et evdev) et dans trois fichiers différents (je ne vais le faire que pour evdev). Le deuxième format est l'index (pour les applications qui n'utilisent pas libxklavier). Voilà donc le fichier rules/evdev.lst :

...
logicink Logitech Internet Navigator Keyboard
logielite Logitech Elite Keyboard
logiex110 Logitech Cordless Desktop EX110
...
esperanto:dvorak To the corresponding key in a Dvorak keyboard.
fixinet Adding fixes to the multimedia keyboards
fixinet:logielite To the Logitech Elite Keyboard

Le troisième est le fichier XML (celui qui, pour base est dans /etc au lieu de /usr), evdev.xml:

--- ../xkb.orig/rules/evdev.xml	2009-04-14 11:00:25.000000000 +0200
+++ ./rules/evdev.xml 2009-04-20 12:51:46.000000000 +0200
@@ -715,6 +715,13 @@
</model>
<model>
<configItem>
+ <name>logielite</name>
+ <description>Logitech Elite Keyboard</description>
+ <vendor>Logitech</vendor>
+ </configItem>
+ </model>
+ <model>
+ <configItem>
<name>logiex110</name>
<description>Logitech Cordless Desktop EX110</description>
<vendor>Logitech</vendor>
@@ -4898,5 +4905,17 @@
</configItem>
</option>
</group>
+ <group allowMultipleSelection="true">
+ <configItem>
+ <name>fixinet</name>
+ <description>Adding fixes to the multimedia keyboards</description>
+ </configItem>
+ <option>
+ <configItem>
+ <name>fixinet:logielite</name>
+ <description>To the Logitech Elite Keyboard.</description>
+ </configItem>
+ </option>
+ </group>
</optionList>
</xkbConfigRegistry>

Presque tout est prêt. Il faut juste mettre nos définitions dans le répertoire symbols (j'ai ajouté mon code dans symbols/inet) :

// Logitech Elite Keyboard
partial alphanumeric_keys
xkb_symbols "logielite" {
key <I224> { [ XF86Messenger ] };
key <I226> { [ XF86iTouch ] };
};

Bien sûr, il faut aussi modifier l'index symbols.dir (dans le répertoire de base) :

--- ../xkb.orig/symbols.dir	2009-04-14 11:00:25.000000000 +0200
+++ symbols.dir 2009-04-20 12:58:20.000000000 +0200
@@ -684,6 +684,7 @@
--p----- a------- inet(logiaccess)
--p----- a------- inet(logicda)
--p----- a------- inet(logicink)
+--p----- a------- inet(logielite)
--p----- a------- inet(logiex110)
--p----- a------- inet(logiinkse)
--p----- a------- inet(logiinkseusb)

Ceci fait, je génère le patch (diff -ur ../xkb.orig ./ > /etc/X11/xkb/keyboard.patch), lance /etc/init.d/fixkeyboard start, et voilà. Les fichiers attachés contiennent aussi mon clavier français personnel.

Comment paramétrer tout ça ?

C'est la partie qui cause le plus débat. Personnellement, j'ai trouvé ça très simple, et je n'ai rien eu à changer à part dans un seul fichier, alors bon. La voie la plus simple est de configurer /etc/default/console-setup :

# The following variables describe your keyboard and can have the same
# values as the XkbModel, XkbLayout, XkbVariant and XkbOptions options
# in /etc/X11/xorg.conf.
XKBMODEL="logielite"
XKBLAYOUT="fr"
XKBVARIANT="complete" # ou "latin9"
XKBOPTIONS="compose:menu,fixinet:logielite"

On relance console-setup, on relance X, Tout devrait fonctionner très bien.

L'autre façon de faire, c'est d'utiliser votre environnement de travail : pour Gnome, Système->Préférences->Clavier->Agencements->Options de l'agencement->Adding fixes to the multimedia keyboards->To the Logitech Elite Keyboard (ce n'est pas traduit).

Il y a aussi des façons de ne pas utiliser console-setup et d'utiliser juste hal.

La dernière chose faire est de lier ces touches à des effets utiles (les touches multimédia, hein). Au moins compiz et Metacity savent le faire (et un certain nombre de touches ont déjà des effets prévus).