MythTV: Use All Buttons of Your Remote Control - Without LIRC
It can be really frustrating to get a remote control to work properly under Linux with LIRC and programs like MythTV, mplayer or XMBC. This article shows how to avoid using LIRC altogether: Treat the remote like any other keyboard, then change the keyboard mapping to use the application's key shortcuts. Because we do this before the keypresses reach X11, it avoids the dreaded problem of keys with codes >255 not working.
LIRC is used by many programs to receive input from a remote control. When LIRC was first written, it was great to have a shared API so you could use any remote with any program. However, it was also always a hassle to configure remotes to work properly. These days, new programs should use the Linux kernel's nice unified "evdev" interface together with the IR keymaps that have also become part of the kernel, but unfortunately many programs still depend on the LIRC user-space setup with its unrecognized (or double-pressed) buttons and extra delay after button presses.
Recently, I tried (not for the first time) to get one of my two remotes working with MythTV and got annoyed at LIRC again: Only some buttons on the remote worked, others such as the all-important "OK" button were not recognized in MythTV.
Searching about the problem on the web turns up no end of complicated/expensive advice: The MythTV Wiki suggests bypassing LIRC by buying both an IR keyboard and a universal remote that can be reprogrammed to send the keyboard codes. Alternatively, you can buy the flirc device, or you can patch and recompile your X11 evdev driver.
Furthermore, you always need to find a matching
lircd.conf for your remote and test the setup with
mode2 before even trying out MythTV.
A better solution is simply to remap the keycodes of the remote on the kernel side, before they reach X11. Apparently the first mention of this approach is this post on the XMBC forum by "darkscout", also Wyliecoyoteuk described it in his post How to forget LIRC for MythTV remotes. Below, I'm providing some copy & paste shell code snippets to make the process simpler.
- A remote control that provides an "evdev" (dev/input) interface. Most recent remotes that are supported under Linux have this.
- Optionally, the
irrecordprogram from the LIRC distribution to output a list of all possible keycode names.
Note: All of the following commands need access to the remote's device. To avoid any related problems, best work as root.
Step 0: Does the Kernel Know About the Remote?
ir-keytable -t, then press a few buttons on the remote. If nothing is output, you need to check whether the remote is supported and the respective kernel module is loaded.
Step 1: Find Device for Your Remote Control
ir-keytable without any arguments. This is the example output for my X10 MCE remote (a 2.4 GHz radio remote, not IR). We are interested in the device path under /dev:
# ir-keytable Found /sys/class/rc/rc0/ (/dev/input/event7) with: Driver ati_remote, table rc-medion-x10-or2x Supported protocols: other Enabled protocols: Repeat delay = 500 ms, repeat period = 125 ms
My other remote (an old Terratec Cinergy T²) does not appear here, but it can be found by looking at the right directory inside /dev:
# ls -l /dev/input/by-path/*-ir lrwxrwxrwx 1 root root 9 May 20 14:22 /dev/input/by-path/pci-0000:00:1a.7-usb-0:4-event-ir -> ../event6
Step 2: Record Default Keyboard Map
ir-keytable --read --device=/dev/input/PATH to get the current kernel-provided mapping for the remote (excerpt):
scancode 0x001e = KEY_OK (0x160) scancode 0x0020 = KEY_BACK (0x9e) scancode 0x002f = KEY_INFO (0x166) scancode 0x0031 = KEY_EPG (0x16d)
Step 3: Edit Keyboard Map
Note the highlighted keycodes above which have 3 digits after the "0x", i.e. the values are >255. We want to remap them to values <=255 to avoid all the problems with unrecognized button presses. But I suggest to also remap the other buttons for convenience: For example, in MythTV Play/Pause is the keyboard shortcut "P", so you can remap that button on the remote to the "P" key and leave the MythTV setup unchanged.
A list of available keycodes is output by
irrecord -l, or see below.
It is up to you what keys to assign to the buttons. For a setup with a single application, the easiest approach is to use the application's shortcuts directly. In other cases, you may want to use rarely-used keys (e.g. KEY_F13 keys and higher or the numeric keypad, KEY_KP0) and assign shortcuts in the application. You can only configure simple key presses and not Shift/Ctrl combinations - if you need the latter, first cause a simple keypress to execute a custom command (e.g. with Gnome's keyboard shortcuts) and then use a utility like
xdotool to synthesize a key combination in X11.
For the example above, I mapped the keys to the MythTV shortcuts:
scancode 0x001e = KEY_ENTER # was KEY_OK scancode 0x0020 = KEY_ESC # was KEY_BACK scancode 0x002f = KEY_I # was KEY_INFO scancode 0x0031 = KEY_S # was KEY_EPG
Step 4: Load New Keyboard Map - Profit!
To make the remote use the changed keymap, execute:
ir-keytable --write=FILENAME --device=/dev/input/PATH
To make the setting permanent, you can execute the command from udev once the device is detected. Alternatively, just put it into a startup script, but then remember to explicitly load the relevant kernel module for your hardware before executing it. Under Debian, put your file into /etc/rc_keymaps and add information about the driver, table and file in /etc/rc_maps.cfg
KEY_0 KEY_102ND KEY_1 KEY_2 KEY_3 KEY_4 KEY_5 KEY_6 KEY_7 KEY_8 KEY_9 KEY_A KEY_AB KEY_ADDRESSBOOK KEY_AGAIN KEY_ALTERASE KEY_ANGLE KEY_APOSTROPHE KEY_ARCHIVE KEY_AUDIO KEY_AUX KEY_B KEY_BACK KEY_BACKSLASH KEY_BACKSPACE KEY_BASSBOOST KEY_BATTERY KEY_BLUE KEY_BLUETOOTH KEY_BOOKMARKS KEY_BREAK KEY_BRIGHTNESS_CYCLE KEY_BRIGHTNESSDOWN KEY_BRIGHTNESSUP KEY_BRIGHTNESS_ZERO KEY_BRL_DOT10 KEY_BRL_DOT1 KEY_BRL_DOT2 KEY_BRL_DOT3 KEY_BRL_DOT4 KEY_BRL_DOT5 KEY_BRL_DOT6 KEY_BRL_DOT7 KEY_BRL_DOT8 KEY_BRL_DOT9 KEY_C KEY_CALC KEY_CALENDAR KEY_CAMERA KEY_CANCEL KEY_CAPSLOCK KEY_CD KEY_CHANNEL KEY_CHANNELDOWN KEY_CHANNELUP KEY_CHAT KEY_CLEAR KEY_CLOSE KEY_CLOSECD KEY_COFFEE KEY_COMMA KEY_COMPOSE KEY_COMPUTER KEY_CONFIG KEY_CONNECT KEY_CONTEXT_MENU KEY_COPY KEY_CUT KEY_CYCLEWINDOWS KEY_D KEY_DASHBOARD KEY_DATABASE KEY_DEL_EOL KEY_DEL_EOS KEY_DELETE KEY_DELETEFILE KEY_DEL_LINE KEY_DIGITS KEY_DIRECTION KEY_DIRECTORY KEY_DISPLAY_OFF KEY_DISPLAYTOGGLE KEY_DOCUMENTS KEY_DOLLAR KEY_DOT KEY_DOWN KEY_DVD KEY_E KEY_EDIT KEY_EDITOR KEY_EJECTCD KEY_EJECTCLOSECD KEY_EMAIL KEY_END KEY_ENTER KEY_EPG KEY_EQUAL KEY_ESC KEY_EURO KEY_EXIT KEY_F10 KEY_F11 KEY_F12 KEY_F13 KEY_F14 KEY_F15 KEY_F1 KEY_F16 KEY_F17 KEY_F18 KEY_F19 KEY_F20 KEY_F21 KEY_F22 KEY_F23 KEY_F24 KEY_F2 KEY_F KEY_F3 KEY_F4 KEY_F5 KEY_F6 KEY_F7 KEY_F8 KEY_F9 KEY_FASTFORWARD KEY_FAVORITES KEY_FILE KEY_FINANCE KEY_FIND KEY_FIRST KEY_FN KEY_FN_1 KEY_FN_2 KEY_FN_B KEY_FN_D KEY_FN_E KEY_FN_ESC KEY_FN_F KEY_FN_F10 KEY_FN_F1 KEY_FN_F11 KEY_FN_F12 KEY_FN_F2 KEY_FN_F3 KEY_FN_F4 KEY_FN_F5 KEY_FN_F6 KEY_FN_F7 KEY_FN_F8 KEY_FN_F9 KEY_FN_S KEY_FORWARD KEY_FORWARDMAIL KEY_FRAMEBACK KEY_FRAMEFORWARD KEY_FRONT KEY_G KEY_GAMES KEY_GOTO KEY_GRAPHICSEDITOR KEY_GRAVE KEY_GREEN KEY_H KEY_HANGEUL KEY_HANJA KEY_HELP KEY_HENKAN KEY_HIRAGANA KEY_HOME KEY_HOMEPAGE KEY_HP KEY_I KEY_INFO KEY_INSERT KEY_INS_LINE KEY_ISO KEY_J KEY_K KEY_KATAKANA KEY_KATAKANAHIRAGANA KEY_KBDILLUMDOWN KEY_KBDILLUMTOGGLE KEY_KBDILLUMUP KEY_KEYBOARD KEY_KP0 KEY_KP1 KEY_KP2 KEY_KP3 KEY_KP4 KEY_KP5 KEY_KP6 KEY_KP7 KEY_KP8 KEY_KP9 KEY_KPASTERISK KEY_KPCOMMA KEY_KPDOT KEY_KPENTER KEY_KPEQUAL KEY_KPJPCOMMA KEY_KPLEFTPAREN KEY_KPMINUS KEY_KPPLUS KEY_KPPLUSMINUS KEY_KPRIGHTPAREN KEY_KPSLASH KEY_L KEY_LANGUAGE KEY_LAST KEY_LEFT KEY_LEFTALT KEY_LEFTBRACE KEY_LEFTCTRL KEY_LEFTMETA KEY_LEFTSHIFT KEY_LINEFEED KEY_LIST KEY_LOGOFF KEY_M KEY_MACRO KEY_MAIL KEY_MAX KEY_MEDIA KEY_MEDIA_REPEAT KEY_MEMO KEY_MENU KEY_MESSENGER KEY_MHP KEY_MINUS KEY_MODE KEY_MOVE KEY_MP3 KEY_MSDOS KEY_MUHENKAN KEY_MUTE KEY_N KEY_NEW KEY_NEWS KEY_NEXT KEY_NEXTSONG KEY_NUMERIC_0 KEY_NUMERIC_1 KEY_NUMERIC_2 KEY_NUMERIC_3 KEY_NUMERIC_4 KEY_NUMERIC_5 KEY_NUMERIC_6 KEY_NUMERIC_7 KEY_NUMERIC_8 KEY_NUMERIC_9 KEY_NUMERIC_POUND KEY_NUMERIC_STAR KEY_NUMLOCK KEY_O KEY_OK KEY_OPEN KEY_OPTION KEY_P KEY_PAGEDOWN KEY_PAGEUP KEY_PASTE KEY_PAUSE KEY_PAUSECD KEY_PC KEY_PHONE KEY_PLAY KEY_PLAYCD KEY_PLAYER KEY_PLAYPAUSE KEY_POWER KEY_POWER2 KEY_PRESENTATION KEY_PREVIOUS KEY_PREVIOUSSONG KEY_PRINT KEY_PROG1 KEY_PROG2 KEY_PROG3 KEY_PROG4 KEY_PROGRAM KEY_PROPS KEY_PVR KEY_Q KEY_QUESTION KEY_R KEY_RADIO KEY_RECORD KEY_RED KEY_REDO KEY_REFRESH KEY_REPLY KEY_RESERVED KEY_RESTART KEY_REWIND KEY_RFKILL KEY_RIGHT KEY_RIGHTALT KEY_RIGHTBRACE KEY_RIGHTCTRL KEY_RIGHTMETA KEY_RIGHTSHIFT KEY_RO KEY_S KEY_SAT KEY_SAT2 KEY_SAVE KEY_SCALE KEY_SCREEN KEY_SCROLLDOWN KEY_SCROLLLOCK KEY_SCROLLUP KEY_SEARCH KEY_SELECT KEY_SEMICOLON KEY_SEND KEY_SENDFILE KEY_SETUP KEY_SHOP KEY_SHUFFLE KEY_SLASH KEY_SLEEP KEY_SLOW KEY_SOUND KEY_SPACE KEY_SPELLCHECK KEY_SPORT KEY_SPREADSHEET KEY_STOP KEY_STOPCD KEY_SUBTITLE KEY_SUSPEND KEY_SWITCHVIDEOMODE KEY_SYSRQ KEY_T KEY_TAB KEY_TAPE KEY_TEEN KEY_TEXT KEY_TIME KEY_TITLE KEY_TUNER KEY_TV KEY_TV2 KEY_TWEN KEY_U KEY_UNDO KEY_UNKNOWN KEY_UP KEY_UWB KEY_V KEY_VCR KEY_VCR2 KEY_VENDOR KEY_VIDEO KEY_VIDEO_NEXT KEY_VIDEOPHONE KEY_VIDEO_PREV KEY_VOICEMAIL KEY_VOLUMEDOWN KEY_VOLUMEUP KEY_W KEY_WAKEUP KEY_WIMAX KEY_WLAN KEY_WORDPROCESSOR KEY_WWW KEY_X KEY_XFER KEY_Y KEY_YELLOW KEY_YEN KEY_Z KEY_ZENKAKUHANKAKU KEY_ZOOM KEY_ZOOMIN KEY_ZOOMOUT KEY_ZOOMRESET BTN_0 BTN_1 BTN_2 BTN_3 BTN_4 BTN_5 BTN_6 BTN_7 BTN_8 BTN_9 BTN_A BTN_B BTN_BACK BTN_BASE BTN_BASE2 BTN_BASE3 BTN_BASE4 BTN_BASE5 BTN_BASE6 BTN_C BTN_DEAD BTN_DIGI BTN_EXTRA BTN_FORWARD BTN_GAMEPAD BTN_GEAR_DOWN BTN_GEAR_UP BTN_JOYSTICK BTN_LEFT BTN_MIDDLE BTN_MISC BTN_MODE BTN_MOUSE BTN_PINKIE BTN_RIGHT BTN_SELECT BTN_SIDE BTN_START BTN_STYLUS BTN_STYLUS2 BTN_TASK BTN_THUMB BTN_THUMB2 BTN_THUMBL BTN_THUMBR BTN_TL BTN_TL2 BTN_TOOL_AIRBRUSH BTN_TOOL_BRUSH BTN_TOOL_DOUBLETAP BTN_TOOL_FINGER BTN_TOOL_LENS BTN_TOOL_MOUSE BTN_TOOL_PEN BTN_TOOL_PENCIL BTN_TOOL_QUADTAP BTN_TOOL_RUBBER BTN_TOOL_TRIPLETAP BTN_TOP BTN_TOP2 BTN_TOUCH BTN_TR BTN_TR2 BTN_TRIGGER BTN_WHEEL BTN_X BTN_Y BTN_Z