viernes, 30 de abril de 2021

 Como cambiar la asignación de una tecla en Linux.

Contexto.

Tengo una laptop que solo tiene la tecla Ctrl del lado izquierdo, del lado derecho donde en un teclado estándar latinoamericano debería estar el Ctrl Derecho fueron a poner la tecla flecha derecha. 

La siguiente imagen indica como se encuentra mi teclado:




¿El problema?

Quiero volver a tener la tecla Ctrl Derecho y quiero que las cuatro teclas de navegación (las flechas arriba, abajo, izquierda y derecha) tengan un tamaño normal.

¿Qué opciones tengo?


La natural es comprar un teclado para usar la laptop, pero como no quiero ir cargando un teclado a donde quiera que vaya he decidido usar las teclas 1,2,3 y 5 del teclado numérico como teclas de navegación. La tecla que hoy es flecha derecha se convertirá en mi Ctrl Derecho y la tecla que hoy es flecha izquierda se convertirá en mi tecla de menú (la tecla de menú es la que funciona como si pulsáramos click derecho con el mouse, es la que dice Menú en la siguiente imagen de un teclado estándar latinoamericano).


Solución.


Nos apoyaremos de udev el cual es el gestor de dispositivos que atiende a nivel de núcleo y que dicho sea de paso nos va a permitir que el mapeo que hagamos no dependa de si entramos en modo gráfico o por terminales tty.

¿Como se trabaja con udev? 


Vamos a escribir un archivo de texto con el remapeo de las teclas, este tendrá el identificador del dispositivo (formado por el bus, vendedor, el numero de producto y la versión del dispositivo).

También en el archivo vamos a colocar una serie de claves para indicar el mapeo de las teclas hacia el comportamiento que deseo que tengan.

Para encontrar el identificador del dispositivo y las claves nos apoyaremos de la utilitaria evtest.
Así que vamos en el siguiente orden:

1. Instalar evtest (se usará para ver el código que se dispara cuando se pulsa una tecla)

# dnf install evtest

2. Ejecutar evtest. Nada más hacerlo se mostrara una lista con dispositivos de entrada permitiéndonos elegir el que uno quiera. Naturalmente elegimos el de nuestro teclado (el 3 en mi caso).

# evtest 
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0: Power Button
/dev/input/event1: Lid Switch
/dev/input/event2: Power Button
/dev/input/event3: AT Translated Set 2 keyboard
/dev/input/event4: SynPS/2 Synaptics TouchPad
/dev/input/event5: Video Bus
/dev/input/event6: HP Wireless hotkeys
/dev/input/event7: PC Speaker
/dev/input/event8: HP WMI hotkeys
/dev/input/event9: HDA ATI HDMI HDMI/DP,pcm=3
/dev/input/event10: HD-Audio Generic Mic
/dev/input/event11: HD-Audio Generic Headphone
/dev/input/event12: HP TrueVision HD Camera: HP Tru
Select the device event number [0-12]: 3

3. Al dar enter evtest nos mostrará una salida interactiva de las teclas que pulsemos. Para salir se pulsa  Ctrl+C.  Pongo en color negro el bus, el vendor, el product  y la versión que nos arroja el comando. A continuación la salida que se genera en mi maquina:

Input driver version is 1.0.1
Input device ID: bus 0x11 vendor 0x1 product 0x1 version 0xab41
Input device name: "AT Translated Set 2 keyboard"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 1 (KEY_ESC)
    Event code 2 (KEY_1)
    Event code 3 (KEY_2)
    Event code 4 (KEY_3)
    Event code 5 (KEY_4)
    Event code 6 (KEY_5)
    Event code 7 (KEY_6)
    Event code 8 (KEY_7)
    Event code 9 (KEY_8)
    Event code 10 (KEY_9)
    Event code 11 (KEY_0)
    Event code 12 (KEY_MINUS)
    Event code 13 (KEY_EQUAL)
    Event code 14 (KEY_BACKSPACE)
    Event code 15 (KEY_TAB)
    Event code 16 (KEY_Q)
    Event code 17 (KEY_W)
    Event code 18 (KEY_E)
    Event code 19 (KEY_R)
    Event code 20 (KEY_T)
    Event code 21 (KEY_Y)
    Event code 22 (KEY_U)
    Event code 23 (KEY_I)
    Event code 24 (KEY_O)
    Event code 25 (KEY_P)
    Event code 26 (KEY_LEFTBRACE)
    Event code 27 (KEY_RIGHTBRACE)
    Event code 28 (KEY_ENTER)
    Event code 29 (KEY_LEFTCTRL)
    Event code 30 (KEY_A)
    Event code 31 (KEY_S)
    Event code 32 (KEY_D)
    Event code 33 (KEY_F)
    Event code 34 (KEY_G)
    Event code 35 (KEY_H)
    Event code 36 (KEY_J)
    Event code 37 (KEY_K)
    Event code 38 (KEY_L)
    Event code 39 (KEY_SEMICOLON)
    Event code 40 (KEY_APOSTROPHE)
    Event code 41 (KEY_GRAVE)
    Event code 42 (KEY_LEFTSHIFT)
    Event code 43 (KEY_BACKSLASH)
    Event code 44 (KEY_Z)
    Event code 45 (KEY_X)
    Event code 46 (KEY_C)
    Event code 47 (KEY_V)
    Event code 48 (KEY_B)
    Event code 49 (KEY_N)
    Event code 50 (KEY_M)
    Event code 51 (KEY_COMMA)
    Event code 52 (KEY_DOT)
    Event code 53 (KEY_SLASH)
    Event code 54 (KEY_RIGHTSHIFT)
    Event code 55 (KEY_KPASTERISK)
    Event code 56 (KEY_LEFTALT)
    Event code 57 (KEY_SPACE)
    Event code 58 (KEY_CAPSLOCK)
    Event code 59 (KEY_F1)
    Event code 60 (KEY_F2)
    Event code 61 (KEY_F3)
    Event code 62 (KEY_F4)
    Event code 63 (KEY_F5)
    Event code 64 (KEY_F6)
    Event code 65 (KEY_F7)
    Event code 66 (KEY_F8)
    Event code 67 (KEY_F9)
    Event code 68 (KEY_F10)
    Event code 69 (KEY_NUMLOCK)
    Event code 70 (KEY_SCROLLLOCK)
    Event code 71 (KEY_KP7)
    Event code 72 (KEY_KP8)
    Event code 73 (KEY_KP9)
    Event code 74 (KEY_KPMINUS)
    Event code 75 (KEY_KP4)
    Event code 76 (KEY_KP5)
    Event code 77 (KEY_KP6)
    Event code 78 (KEY_KPPLUS)
    Event code 79 (KEY_KP1)
    Event code 80 (KEY_KP2)
    Event code 81 (KEY_KP3)
    Event code 82 (KEY_KP0)
    Event code 83 (KEY_KPDOT)
    Event code 85 (KEY_ZENKAKUHANKAKU)
    Event code 86 (KEY_102ND)
    Event code 87 (KEY_F11)
    Event code 88 (KEY_F12)
    Event code 89 (KEY_RO)
    Event code 90 (KEY_KATAKANA)
    Event code 91 (KEY_HIRAGANA)
    Event code 92 (KEY_HENKAN)
    Event code 93 (KEY_KATAKANAHIRAGANA)
    Event code 94 (KEY_MUHENKAN)
    Event code 95 (KEY_KPJPCOMMA)
    Event code 96 (KEY_KPENTER)
    Event code 97 (KEY_RIGHTCTRL)
    Event code 98 (KEY_KPSLASH)
    Event code 99 (KEY_SYSRQ)
    Event code 100 (KEY_RIGHTALT)
    Event code 102 (KEY_HOME)
    Event code 103 (KEY_UP)
    Event code 104 (KEY_PAGEUP)
    Event code 105 (KEY_LEFT)
    Event code 106 (KEY_RIGHT)
    Event code 107 (KEY_END)
    Event code 108 (KEY_DOWN)
    Event code 109 (KEY_PAGEDOWN)
    Event code 110 (KEY_INSERT)
    Event code 111 (KEY_DELETE)
    Event code 112 (KEY_MACRO)
    Event code 113 (KEY_MUTE)
    Event code 114 (KEY_VOLUMEDOWN)
    Event code 115 (KEY_VOLUMEUP)
    Event code 116 (KEY_POWER)
    Event code 117 (KEY_KPEQUAL)
    Event code 118 (KEY_KPPLUSMINUS)
    Event code 119 (KEY_PAUSE)
    Event code 121 (KEY_KPCOMMA)
    Event code 122 (KEY_HANGUEL)
    Event code 123 (KEY_HANJA)
    Event code 124 (KEY_YEN)
    Event code 125 (KEY_LEFTMETA)
    Event code 126 (KEY_RIGHTMETA)
    Event code 127 (KEY_COMPOSE)
    Event code 128 (KEY_STOP)
    Event code 138 (KEY_HELP)
    Event code 140 (KEY_CALC)
    Event code 142 (KEY_SLEEP)
    Event code 143 (KEY_WAKEUP)
    Event code 152 (KEY_SCREENLOCK)
    Event code 155 (KEY_MAIL)
    Event code 156 (KEY_BOOKMARKS)
    Event code 157 (KEY_COMPUTER)
    Event code 158 (KEY_BACK)
    Event code 159 (KEY_FORWARD)
    Event code 163 (KEY_NEXTSONG)
    Event code 164 (KEY_PLAYPAUSE)
    Event code 165 (KEY_PREVIOUSSONG)
    Event code 166 (KEY_STOPCD)
    Event code 172 (KEY_HOMEPAGE)
    Event code 173 (KEY_REFRESH)
    Event code 183 (KEY_F13)
    Event code 184 (KEY_F14)
    Event code 185 (KEY_F15)
    Event code 212 (KEY_CAMERA)
    Event code 217 (KEY_SEARCH)
    Event code 224 (KEY_BRIGHTNESSDOWN)
    Event code 225 (KEY_BRIGHTNESSUP)
    Event code 226 (KEY_MEDIA)
    Event code 227 (KEY_SWITCHVIDEOMODE)
    Event code 236 (KEY_BATTERY)
    Event code 238 (KEY_WLAN)
    Event code 240 (KEY_UNKNOWN)
    Event code 389 (KEY_DVD)
    Event code 465 (KEY_FN_ESC)
  Event type 4 (EV_MSC)
    Event code 4 (MSC_SCAN)
  Event type 17 (EV_LED)
    Event code 0 (LED_NUML) state 0
    Event code 1 (LED_CAPSL) state 0
    Event code 2 (LED_SCROLLL) state 0
Key repeat handling:
  Repeat type 20 (EV_REP)
    Repeat code 0 (REP_DELAY)
      Value    250
    Repeat code 1 (REP_PERIOD)
      Value     33
Properties:
Testing ... (interrupt to exit)
Event: time 1619748608.609623, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1c
Event: time 1619748608.609623, type 1 (EV_KEY), code 28 (KEY_ENTER), value 0
Event: time 1619748608.609623, -------------- SYN_REPORT ------------
Event: time 1619748612.251256, type 4 (EV_MSC), code 4 (MSC_SCAN), value 38
Event: time 1619748612.251256, type 1 (EV_KEY), code 56 (KEY_LEFTALT), value 1
Event: time 1619748612.251256, -------------- SYN_REPORT ------------


4. Voy pulsando las teclas que deseo cambiar. Y anoto su codigo (value de la primera linea que he resaltado en negro):

Flecha derecha:
Event: time 1619748655.465088, type 4 (EV_MSC), code 4 (MSC_SCAN), value cd
Event: time 1619748655.465088, type 1 (EV_KEY), code 106 (KEY_RIGHT), value 1

Flecha izquierda:
Event: time 1619749026.099716, type 4 (EV_MSC), code 4 (MSC_SCAN), value cb
Event: time 1619749026.099716, type 1 (EV_KEY), code 105 (KEY_LEFT), value 1


Tecla numérica 1:
Event: time 1619749246.268599, type 4 (EV_MSC), code 4 (MSC_SCAN), value 4f
Event: time 1619749246.268599, type 1 (EV_KEY), code 79 (KEY_KP1), value 1


Tecla numérica 2:
Event: time 1619749212.411720, type 4 (EV_MSC), code 4 (MSC_SCAN), value 50
Event: time 1619749212.411720, type 1 (EV_KEY), code 80 (KEY_KP2), value 1


Tecla numérica 3:
Event: time 1619749176.392765, type 4 (EV_MSC), code 4 (MSC_SCAN), value 51
Event: time 1619749176.392765, type 1 (EV_KEY), code 81 (KEY_KP3), value 1

Tecla numérica 5:
Event: time 1619749152.801083, type 4 (EV_MSC), code 4 (MSC_SCAN), value 4c
Event: time 1619749152.801083, type 1 (EV_KEY), code 76 (KEY_KP5), value 1


Ahora generamos un archivo al que voy a llamar 99-miLaptop.teclado.hwdb en donde colocare las reglas para el remapeo. El contenido del archivo será:

evdev:input:b0011v0001p0001*
 KEYBOARD_KEY_cd=rightctrl
 KEYBOARD_KEY_cb=compose
 KEYBOARD_KEY_4f=left
 KEYBOARD_KEY_51=right
 KEYBOARD_KEY_4c=up
 KEYBOARD_KEY_50=down


5. La primera linea tiene el bus, vendor, product (bus, vendedor, identificador del producto) del dispositivo (el teclado) la versión no la coloco, me limito a poner un * 

Lo que viene delante de estas leyendas es el comportamiento que quiero que realicen.

rightctrl   Es el control derecho.
compose  Es la tecla de menu.
left, right, up, down   Son las teclas de navegacion.

¿Con que otros comportamientos puedo configurar una tecla?
Las leyendas y algunas descripciones de las mismas vienen en el archivo:

/usr/lib/udev/hwdb.d/60-keyboard.hwdb

6. El archivo generado debemos colocarlo en 

/etc/udev/hwdb.d/

7. Ejecutamos los comandos para actualizar y aplicar la regla:

# systemd-hwdb update

# udevadm trigger

Y listo. Probamos, ahora las teclas deben estar cambiadas. 

No hay comentarios:

Publicar un comentario