Para encontrar algo que me guste, hay que rebuscar mucho

User login

Mando a distancia infrarrojo funcionando en Ubuntu 18 (BUG? FEATURE?)

El problema

Ya expliqué hace tiempo cómo utilizar el mando infrarrojo en un NUC Intel D54250WYKH con Linux (Mint 17) pero la semana pasada actualicé a Mint 19 y he tenido dos sorpresas:

  1. Una agradable: El receptor infrarojo nuvoton es reconocido directamente sin necesidad de modificar nada.
  2. Una DESAGRADABLE, MUCHO: Aunque el mapeado de teclas con ir-keytable funciona perfectamente (como se puede ver en la captura de debajo), ningún programa "normal" es capaz de leer las pulsaciones de botones.

En un primer momento pensé que podría ser un fallo de Mint 19 así que probé con 18, con varios escritorios (Cinnamon, Mate, XFCE), con Ubuntu 18.04 LTS, con 18.10, con Lubuntu… siempre con el mismo resultado. El lector infrarrojo leía las pulsaciones de teclas, las traducía a eventos de teclado (que podía leer con el test de ir-keytable, showkeys o cualquier otro lector de eventos), pero por alguna razón al sistema operativo le daba exactamente igual. Si intentaba "escribir" esas teclas con el mando a distancia en un editor de texto, en la consola, o en Kodi no ocurría absolutamente nada.

alternate

La explicación?

(siento no poder expresarme con propiedad en este apartado, los temas técnicos de linux a nivel de kernel, xorg, udev… se me escapan)

El origen del problema es algo así: El mando infrarrojo emite unos pulsos de luz que el lector recibe y "traduce" a eventos de teclado ("KEY_A" por ejemplo) y envía al sistema operativo. Ese envío se hace como un teclado virtual (a todos los efectos nuestro sistema operativo piensa que tiene un teclado normal y corriente enchufado). El problema está en que dependiendo de qué "teclado virtual" identifique Linux, habrá unas teclas permitidas y otras que no de modo que cualquier tecla no permitida será ignorada por el sistema operativo. Por ejemplo, un mando a distancia Mierdonic TS1000 sólo tiene las teclas A-B-C-D. Si en nuestro mapeado de ir-keytable añadimos la tecla Z, ésta será ignorada por el sistema operativo.

La solución "oficial"

La solución oficial pasa por averiguar qué teclas son las permitidas para nuestro mando a distancia y en nuestro archivo de mapeado limitarnos a usar sólo esas. Para ello ejecutamos:

$ ir-keytable

Y en la salida, si nuestro lector infrarrojo es compatible, debemos ver la tabla de conversión utilizada.

alternate

Ahora debemos averiguar en qué archivo se almacena dicha tabla de conversión. Para ello hacemos $ cat /etc/rc_maps.cfg y veremos que nuestra tabla está en el archivo:

alternate

La ruta completa del archivo será /lib/udev/rc_keymaps/rc6_mce y podemos ver su contenido haciendo $ cat /lib/udev/rc_keymaps/rc6_mce. Las teclas listadas serán las únicas que podemos utilizar en nuestros archivos de mapeado para ir-keytable.

# table rc6_mce, type: RC6
0x800f0400 KEY_NUMERIC_0
0x800f0401 KEY_NUMERIC_1
0x800f0402 KEY_NUMERIC_2
0x800f0403 KEY_NUMERIC_3
0x800f0404 KEY_NUMERIC_4
0x800f0405 KEY_NUMERIC_5
0x800f0406 KEY_NUMERIC_6
0x800f0407 KEY_NUMERIC_7
0x800f0408 KEY_NUMERIC_8
0x800f0409 KEY_NUMERIC_9
0x800f040a KEY_DELETE
0x800f040b KEY_ENTER
0x800f040c KEY_SLEEP
0x800f040d KEY_MEDIA
0x800f040e KEY_MUTE
0x800f040f KEY_INFO
0x800f0410 KEY_VOLUMEUP
0x800f0411 KEY_VOLUMEDOWN
0x800f0412 KEY_CHANNELUP
0x800f0413 KEY_CHANNELDOWN
0x800f0414 KEY_FASTFORWARD
0x800f0415 KEY_REWIND
0x800f0416 KEY_PLAY
0x800f0417 KEY_RECORD
0x800f0418 KEY_PAUSE
0x800f0419 KEY_STOP
0x800f041a KEY_NEXT
0x800f041b KEY_PREVIOUS
0x800f041c KEY_NUMERIC_POUND
0x800f041d KEY_NUMERIC_STAR
0x800f041e KEY_UP
0x800f041f KEY_DOWN
0x800f0420 KEY_LEFT
0x800f0421 KEY_RIGHT
0x800f0422 KEY_OK
0x800f0423 KEY_EXIT
0x800f0424 KEY_DVD
0x800f0425 KEY_TUNER
0x800f0426 KEY_EPG
0x800f0427 KEY_ZOOM
0x800f0432 KEY_MODE
0x800f0433 KEY_PRESENTATION
0x800f0434 KEY_EJECTCD
0x800f043a KEY_BRIGHTNESSUP
0x800f0446 KEY_TV
0x800f0447 KEY_AUDIO
0x800f0448 KEY_PVR
0x800f0449 KEY_CAMERA
0x800f044a KEY_VIDEO
0x800f044c KEY_LANGUAGE
0x800f044d KEY_TITLE
0x800f044e KEY_PRINT
0x800f0450 KEY_RADIO
0x800f045a KEY_SUBTITLE
0x800f045b KEY_RED
0x800f045c KEY_GREEN
0x800f045d KEY_YELLOW
0x800f045e KEY_BLUE
0x800f0465 KEY_POWER2
0x800f0469 KEY_MESSENGER
0x800f046e KEY_PLAYPAUSE
0x800f046f KEY_PLAYER
0x800f0480 KEY_BRIGHTNESSDOWN
0x800f0481 KEY_PLAYPAUSE

La solución "ampliada"

Como no quería limitarme a las pocas teclas disponibles y para no tener que modificar archivos del sistema, una solución es crear el archivo de configuración /etc/rc_keymaps/rc6_mce y en él pegar el siguiente contenido que incluye TODAS las teclas:

# table rc6_mce, type: RC6
0x000000 KEY_0
0x000001 KEY_1
0x000002 KEY_102ND
0x000003 KEY_10CHANNELSDOWN
0x000004 KEY_10CHANNELSUP
0x000005 KEY_2
0x000006 KEY_3
0x000007 KEY_4
0x000008 KEY_5
0x000009 KEY_6
0x00000a KEY_7
0x00000b KEY_8
0x00000c KEY_9
0x00000d KEY_A
0x00000e KEY_AB
0x00000f KEY_ADDRESSBOOK
0x000010 KEY_AGAIN
0x000011 KEY_ALS_TOGGLE
0x000012 KEY_ALTERASE
0x000013 KEY_ANGLE
0x000014 KEY_APOSTROPHE
0x000015 KEY_APPSELECT
0x000016 KEY_ARCHIVE
0x000017 KEY_ATTENDANT_OFF
0x000018 KEY_ATTENDANT_ON
0x000019 KEY_ATTENDANT_TOGGLE
0x00001a KEY_AUDIO
0x00001b KEY_AUX
0x00001c KEY_B
0x00001d KEY_BACK
0x00001e KEY_BACKSLASH
0x00001f KEY_BACKSPACE
0x000020 KEY_BASSBOOST
0x000021 KEY_BATTERY
0x000022 KEY_BLUE
0x000023 KEY_BLUETOOTH
0x000024 KEY_BOOKMARKS
0x000025 KEY_BREAK
0x000026 KEY_BRIGHTNESS_AUTO
0x000027 KEY_BRIGHTNESS_CYCLE
0x000028 KEY_BRIGHTNESS_MAX
0x000029 KEY_BRIGHTNESS_MIN
0x00002a KEY_BRIGHTNESSDOWN
0x00002b KEY_BRIGHTNESSUP
0x00002c KEY_BRL_DOT1
0x00002d KEY_BRL_DOT10
0x00002e KEY_BRL_DOT2
0x00002f KEY_BRL_DOT3
0x000030 KEY_BRL_DOT4
0x000031 KEY_BRL_DOT5
0x000032 KEY_BRL_DOT6
0x000033 KEY_BRL_DOT7
0x000034 KEY_BRL_DOT8
0x000035 KEY_BRL_DOT9
0x000036 KEY_BUTTONCONFIG
0x000037 KEY_C
0x000038 KEY_CALC
0x000039 KEY_CALENDAR
0x00003a KEY_CAMERA
0x00003b KEY_CAMERA_DOWN
0x00003c KEY_CAMERA_FOCUS
0x00003d KEY_CAMERA_LEFT
0x00003e KEY_CAMERA_RIGHT
0x00003f KEY_CAMERA_UP
0x000040 KEY_CAMERA_ZOOMIN
0x000041 KEY_CAMERA_ZOOMOUT
0x000042 KEY_CANCEL
0x000043 KEY_CAPSLOCK
0x000044 KEY_CD
0x000045 KEY_CHANNEL
0x000046 KEY_CHANNELDOWN
0x000047 KEY_CHANNELUP
0x000048 KEY_CHAT
0x000049 KEY_CLEAR
0x00004a KEY_CLOSE
0x00004b KEY_CLOSECD
0x00004c KEY_COFFEE
0x00004d KEY_COMMA
0x00004e KEY_COMPOSE
0x00004f KEY_COMPUTER
0x000050 KEY_CONFIG
0x000051 KEY_CONNECT
0x000052 KEY_CONTEXT_MENU
0x000053 KEY_CONTROLPANEL
0x000054 KEY_COPY
0x000055 KEY_CUT
0x000056 KEY_CYCLEWINDOWS
0x000057 KEY_D
0x000058 KEY_DASHBOARD
0x000059 KEY_DATABASE
0x00005a KEY_DEL_EOL
0x00005b KEY_DEL_EOS
0x00005c KEY_DEL_LINE
0x00005d KEY_DELETE
0x00005e KEY_DELETEFILE
0x00005f KEY_DIGITS
0x000060 KEY_DIRECTORY
0x000061 KEY_DISPLAY_OFF
0x000062 KEY_DISPLAYTOGGLE
0x000063 KEY_DOCUMENTS
0x000064 KEY_DOLLAR
0x000065 KEY_DOT
0x000066 KEY_DOWN
0x000067 KEY_DVD
0x000068 KEY_E
0x000069 KEY_EDIT
0x00006a KEY_EDITOR
0x00006b KEY_EJECTCD
0x00006c KEY_EJECTCLOSECD
0x00006d KEY_EMAIL
0x00006e KEY_END
0x00006f KEY_ENTER
0x000070 KEY_EPG
0x000071 KEY_EQUAL
0x000072 KEY_ESC
0x000073 KEY_EURO
0x000074 KEY_EXIT
0x000075 KEY_F
0x000076 KEY_F1
0x000077 KEY_F10
0x000078 KEY_F11
0x000079 KEY_F12
0x00007a KEY_F13
0x00007b KEY_F14
0x00007c KEY_F15
0x00007d KEY_F16
0x00007e KEY_F17
0x00007f KEY_F18
0x000080 KEY_F19
0x000081 KEY_F2
0x000082 KEY_F20
0x000083 KEY_F21
0x000084 KEY_F22
0x000085 KEY_F23
0x000086 KEY_F24
0x000087 KEY_F3
0x000088 KEY_F4
0x000089 KEY_F5
0x00008a KEY_F6
0x00008b KEY_F7
0x00008c KEY_F8
0x00008d KEY_F9
0x00008e KEY_FASTFORWARD
0x00008f KEY_FAVORITES
0x000090 KEY_FILE
0x000091 KEY_FINANCE
0x000092 KEY_FIND
0x000093 KEY_FIRST
0x000094 KEY_FN
0x000095 KEY_FN_1
0x000096 KEY_FN_2
0x000097 KEY_FN_B
0x000098 KEY_FN_D
0x000099 KEY_FN_E
0x00009a KEY_FN_ESC
0x00009b KEY_FN_F
0x00009c KEY_FN_F1
0x00009d KEY_FN_F10
0x00009e KEY_FN_F11
0x00009f KEY_FN_F12
0x0000a0 KEY_FN_F2
0x0000a1 KEY_FN_F3
0x0000a2 KEY_FN_F4
0x0000a3 KEY_FN_F5
0x0000a4 KEY_FN_F6
0x0000a5 KEY_FN_F7
0x0000a6 KEY_FN_F8
0x0000a7 KEY_FN_F9
0x0000a8 KEY_FN_S
0x0000a9 KEY_FORWARD
0x0000aa KEY_FORWARDMAIL
0x0000ab KEY_FRAMEBACK
0x0000ac KEY_FRAMEFORWARD
0x0000ad KEY_FRONT
0x0000ae KEY_G
0x0000af KEY_GAMES
0x0000b0 KEY_GOTO
0x0000b1 KEY_GRAPHICSEDITOR
0x0000b2 KEY_GRAVE
0x0000b3 KEY_GREEN
0x0000b4 KEY_H
0x0000b5 KEY_HANGEUL
0x0000b6 KEY_HANJA
0x0000b7 KEY_HELP
0x0000b8 KEY_HENKAN
0x0000b9 KEY_HIRAGANA
0x0000ba KEY_HOME
0x0000bb KEY_HOMEPAGE
0x0000bc KEY_HP
0x0000bd KEY_I
0x0000be KEY_IMAGES
0x0000bf KEY_INFO
0x0000c0 KEY_INS_LINE
0x0000c1 KEY_INSERT
0x0000c2 KEY_ISO
0x0000c3 KEY_J
0x0000c4 KEY_JOURNAL
0x0000c5 KEY_K
0x0000c6 KEY_KATAKANA
0x0000c7 KEY_KATAKANAHIRAGANA
0x0000c8 KEY_KBDILLUMDOWN
0x0000c9 KEY_KBDILLUMTOGGLE
0x0000ca KEY_KBDILLUMUP
0x0000cb KEY_KBDINPUTASSIST_ACCEPT
0x0000cc KEY_KBDINPUTASSIST_CANCEL
0x0000cd KEY_KBDINPUTASSIST_NEXT
0x0000ce KEY_KBDINPUTASSIST_NEXTGROUP
0x0000cf KEY_KBDINPUTASSIST_PREV
0x0000d0 KEY_KBDINPUTASSIST_PREVGROUP
0x0000d1 KEY_KEYBOARD
0x0000d2 KEY_KP0
0x0000d3 KEY_KP1
0x0000d4 KEY_KP2
0x0000d5 KEY_KP3
0x0000d6 KEY_KP4
0x0000d7 KEY_KP5
0x0000d8 KEY_KP6
0x0000d9 KEY_KP7
0x0000da KEY_KP8
0x0000db KEY_KP9
0x0000dc KEY_KPASTERISK
0x0000dd KEY_KPCOMMA
0x0000de KEY_KPDOT
0x0000df KEY_KPENTER
0x0000e0 KEY_KPEQUAL
0x0000e1 KEY_KPJPCOMMA
0x0000e2 KEY_KPLEFTPAREN
0x0000e3 KEY_KPMINUS
0x0000e4 KEY_KPPLUS
0x0000e5 KEY_KPPLUSMINUS
0x0000e6 KEY_KPRIGHTPAREN
0x0000e7 KEY_KPSLASH
0x0000e8 KEY_L
0x0000e9 KEY_LANGUAGE
0x0000ea KEY_LAST
0x0000eb KEY_LEFT
0x0000ec KEY_LEFTALT
0x0000ed KEY_LEFTBRACE
0x0000ee KEY_LEFTCTRL
0x0000ef KEY_LEFTMETA
0x0000f0 KEY_LEFTSHIFT
0x0000f1 KEY_LIGHTS_TOGGLE
0x0000f2 KEY_LINEFEED
0x0000f3 KEY_LIST
0x0000f4 KEY_LOGOFF
0x0000f5 KEY_M
0x0000f6 KEY_MACRO
0x0000f7 KEY_MAIL
0x0000f8 KEY_MAX
0x0000f9 KEY_MEDIA
0x0000fa KEY_MEDIA_REPEAT
0x0000fb KEY_MEMO
0x0000fc KEY_MENU
0x0000fd KEY_MESSENGER
0x0000fe KEY_MHP
0x0000ff KEY_MICMUTE
0x000100 KEY_MINUS
0x000101 KEY_MODE
0x000102 KEY_MOVE
0x000103 KEY_MP3
0x000104 KEY_MSDOS
0x000105 KEY_MUHENKAN
0x000106 KEY_MUTE
0x000107 KEY_N
0x000108 KEY_NEW
0x000109 KEY_NEWS
0x00010a KEY_NEXT
0x00010b KEY_NEXTSONG
0x00010c KEY_NUMERIC_0
0x00010d KEY_NUMERIC_1
0x00010e KEY_NUMERIC_11
0x00010f KEY_NUMERIC_12
0x000110 KEY_NUMERIC_2
0x000111 KEY_NUMERIC_3
0x000112 KEY_NUMERIC_4
0x000113 KEY_NUMERIC_5
0x000114 KEY_NUMERIC_6
0x000115 KEY_NUMERIC_7
0x000116 KEY_NUMERIC_8
0x000117 KEY_NUMERIC_9
0x000118 KEY_NUMERIC_A
0x000119 KEY_NUMERIC_B
0x00011a KEY_NUMERIC_C
0x00011b KEY_NUMERIC_D
0x00011c KEY_NUMERIC_POUND
0x00011d KEY_NUMERIC_STAR
0x00011e KEY_NUMLOCK
0x00011f KEY_O
0x000120 KEY_OK
0x000121 KEY_OPEN
0x000122 KEY_OPTION
0x000123 KEY_P
0x000124 KEY_PAGEDOWN
0x000125 KEY_PAGEUP
0x000126 KEY_PASTE
0x000127 KEY_PAUSE
0x000128 KEY_PAUSECD
0x000129 KEY_PC
0x00012a KEY_PHONE
0x00012b KEY_PLAY
0x00012c KEY_PLAYCD
0x00012d KEY_PLAYER
0x00012e KEY_PLAYPAUSE
0x00012f KEY_POWER
0x000130 KEY_POWER2
0x000131 KEY_PRESENTATION
0x000132 KEY_PREVIOUS
0x000133 KEY_PREVIOUSSONG
0x000134 KEY_PRINT
0x000135 KEY_PROG1
0x000136 KEY_PROG2
0x000137 KEY_PROG3
0x000138 KEY_PROG4
0x000139 KEY_PROGRAM
0x00013a KEY_PROPS
0x00013b KEY_PVR
0x00013c KEY_Q
0x00013d KEY_QUESTION
0x00013e KEY_R
0x00013f KEY_RADIO
0x000140 KEY_RECORD
0x000141 KEY_RED
0x000142 KEY_REDO
0x000143 KEY_REFRESH
0x000144 KEY_REPLY
0x000145 KEY_RESTART
0x000146 KEY_REWIND
0x000147 KEY_RFKILL
0x000148 KEY_RIGHT
0x000149 KEY_RIGHTALT
0x00014a KEY_RIGHTBRACE
0x00014b KEY_RIGHTCTRL
0x00014c KEY_RIGHTMETA
0x00014d KEY_RIGHTSHIFT
0x00014e KEY_RO
0x00014f KEY_ROTATE_DISPLAY
0x000150 KEY_S
0x000151 KEY_SAT
0x000152 KEY_SAT2
0x000153 KEY_SAVE
0x000154 KEY_SCALE
0x000155 KEY_SCREEN
0x000156 KEY_SCREENSAVER
0x000157 KEY_SCROLLDOWN
0x000158 KEY_SCROLLLOCK
0x000159 KEY_SCROLLUP
0x00015a KEY_SEARCH
0x00015b KEY_SELECT
0x00015c KEY_SEMICOLON
0x00015d KEY_SEND
0x00015e KEY_SENDFILE
0x00015f KEY_SETUP
0x000160 KEY_SHOP
0x000161 KEY_SHUFFLE
0x000162 KEY_SLASH
0x000163 KEY_SLEEP
0x000164 KEY_SLOW
0x000165 KEY_SOUND
0x000166 KEY_SPACE
0x000167 KEY_SPELLCHECK
0x000168 KEY_SPORT
0x000169 KEY_SPREADSHEET
0x00016a KEY_STOP
0x00016b KEY_STOPCD
0x00016c KEY_SUBTITLE
0x00016d KEY_SUSPEND
0x00016e KEY_SWITCHVIDEOMODE
0x00016f KEY_SYSRQ
0x000170 KEY_T
0x000171 KEY_TAB
0x000172 KEY_TAPE
0x000173 KEY_TASKMANAGER
0x000174 KEY_TEEN
0x000175 KEY_TEXT
0x000176 KEY_TIME
0x000177 KEY_TITLE
0x000178 KEY_TOUCHPAD_OFF
0x000179 KEY_TOUCHPAD_ON
0x00017a KEY_TOUCHPAD_TOGGLE
0x00017b KEY_TUNER
0x00017c KEY_TV
0x00017d KEY_TV2
0x00017e KEY_TWEN
0x00017f KEY_U
0x000180 KEY_UNDO
0x000181 KEY_UP
0x000182 KEY_UWB
0x000183 KEY_V
0x000184 KEY_VCR
0x000185 KEY_VCR2
0x000186 KEY_VENDOR
0x000187 KEY_VIDEO
0x000188 KEY_VIDEO_NEXT
0x000189 KEY_VIDEO_PREV
0x00018a KEY_VIDEOPHONE
0x00018b KEY_VOICECOMMAND
0x00018c KEY_VOICEMAIL
0x00018d KEY_VOLUMEDOWN
0x00018e KEY_VOLUMEUP
0x00018f KEY_W
0x000190 KEY_WAKEUP
0x000191 KEY_WLAN
0x000192 KEY_WORDPROCESSOR
0x000193 KEY_WPS_BUTTON
0x000194 KEY_WWAN
0x000195 KEY_WWW
0x000196 KEY_X
0x000197 KEY_XFER
0x000198 KEY_Y
0x000199 KEY_YELLOW
0x00019a KEY_YEN
0x00019b KEY_Z
0x00019c KEY_ZENKAKUHANKAKU
0x00019d KEY_ZOOM
0x00019e KEY_ZOOMIN
0x00019f KEY_ZOOMOUT
0x0001a0 KEY_ZOOMRESET

Como se puede ver, mis teclas están el las direcciones 0x000000 - 0x0001a0; fuera del rango normal 0x800f0400 - 0x800f0481. Ésto en principio no debería ser un problema ya que este mapeo no lo voy a utilizar y tan sólo lo creo para que el sistema operativo "active" esas teclas (aunque no estén mapeadas a ningún botón del mando).

A partir de aquí, deberíamos ser capaces de crear nuestros archivos de mapeo normales y aplicarlos sin problema con ir-keytable.

Enlaces de interés

Mientras buscaba información para solucionar el problema, me encontré con varios posts muy interesantes y más o menos completos sobre el tema (aunque no solucionaban mi problema). Conviene echarles un ojo y quizás alguien con más conocimientos técnicos pueda aclarar la situación.

Extra

alternate

Después de casi cuatro días haciendo mil pruebas y tirándome de los pelos, a punto he estado de comprarme un FLIRC: https://flirc.tv/more/flirc-usb. Por $20 tenemos una solución hardware que convierte casi cualquier mando a distancia (según sus creadores) en un teclado normal y corriente. Trae un programa muy sencillo para realizar los mapeos y además se pueden realizar los cambios de configuración desde línea de comandos por lo que en principio sería una solución casi perfecta para evitarse dolores de cabeza. Los únicos inconvenientes son los estéticos y prácticos al tener que utilizar uno de los puertos USB frontales de la caja de nuestro media player.