Remapping remote control key codes greater than 255
- 1 Key mapping using event_key_remap
- 2 Building the xf86-input-evdev driver
- 3 Determining the codes generated by your remote control
Key mapping using event_key_remap
Version 11 of the X protocol only supports single-byte key codes - so key codes above 255 are ignored. Unfortunately, buttons on many keyboards and remote controls, particularly those intended for "multi-media" purposes, generate key codes higher than 255 for many of their buttons. These codes are simply ignored by X and will not work.
This issue has been raised as a bug at bugs.freedesktop.org and support for more key codes is on the wish list for version 12 of X.
Until version 12 is released, however, Gianni Ceccarelli has created a patched version of the 'xf86-input-evdev' driver which allows key codes to be remapped from one value another. Details are on his page here. If you require version 2.6.0 or later of the evdev driver, you should use the code-remap-2.6.0 branch.
Building the xf86-input-evdev driver
The instructions below are based on Mythbuntu 10.04 and may need to be varied slightly for your distribution.
If you do not have git installed, the following command will install it for you:
sudo apt-get install git-core
Downloading the patched driver
These commands will download the source for the modified 'xf86-input-evdev' driver:
git clone git://www.thenautilus.net/xf86-input-evdev cd xf86-input-evdev git pull git://www.thenautilus.net/xf86-input-evdev code-remap-2.4.0
If you require version 2.6.0 of the evdev driver, replace the last line with:
git pull git://www.thenautilus.net/xf86-input-evdev code-remap-2.6.0
Building the driver
./autogen.sh ./configure make sudo make install
If the driver is being built on a system which is not normally used for development then the 'autogen' and the 'configure' steps above may complain about missing tools and libraries. The command:
sudo apt-get install build-essential
will normally fetch everything that is required, but some other packages may need to be installed depending on your system and/or distribution. Keep running 'autogen' until it runs cleanly without complaining, and then do the same for 'configure'.
(Note: I also needed xserver-xorg-dev, xutils-dev, libtool, and autoconf: sudo apt-get install xserver-xorg-dev xutils-dev libtool autoconf)
Instructing X to use the patched driver
By default, the 'make install' script above copies the new driver into /usr/local/lib/xorg/modules, though this can be overridden if you want to. For the default case, this path needs to be added to the ModulePath for X:
Section "Files" ModulePath "/usr/local/lib/xorg/modules,/usr/lib/xorg/extra-modules,/usr/lib/xorg/modules" EndSection
Now restart X (eg reboot the machine or restart gdm etc) and check that the new module is being used:
grep evdev_drv /var/log/Xorg.0.log
The output should be something like:
(II) Loading /usr/local/lib/xorg/modules/input/evdev_drv.so
This shows that the evdev driver is being loaded from /usr/local/lib, and not /usr/lib.
Gianni describes how to use event_key_remap with HAL configuration on his web page; an alternative method is to add the following entries to your xorg.conf file:
Section "ServerLayout" Identifier "your-layout-name" ... add the following line to the existing lines in this section ... InputDevice "RF remote" "SendCoreEvents" EndSection Section "InputDevice" Identifier "RF remote" Driver "evdev" Option "Device" "your-device-id" <-- for example, "/dev/input/event4" Option "event_key_remap" "402=111 403=116" EndSection
The magic line is the 'event_key_remap' option which has been added to the 'evdev' driver by the patches. In the example above, codes 402 and 403 (which are ignored by X since they are above 255) from the remote control are respectively mapped to codes 111 and 116 (which will be handled properly by X).
You will need to modify the 'event_key_remap' line with all the various codes that you need for your own remote control handset.
In order to find out which device is your remote, use the next section Work out which devices are involved.
Determining the codes generated by your remote control
All the commands below are for Mythbuntu 10.04 (Ubuntu 10.04 TLS) and may need to be varied slightly for your distribution.
Work out which devices are involved
Use the command:
ls -l /dev/input/by-id/
to list the devices which have been detected. You should see something like:
lrwxrwxrwx 1 root root 9 2010-06-12 19:47 usb-Topseed_Tech_Corp._USB_RF_Combo_Device-event-kbd -> ../event3 lrwxrwxrwx 1 root root 9 2010-06-12 19:47 usb-Topseed_Tech_Corp._USB_RF_Combo_Device-event-mouse -> ../event4 lrwxrwxrwx 1 root root 9 2010-06-12 19:47 usb-Topseed_Tech_Corp._USB_RF_Combo_Device-mouse -> ../mouse1
In this example, the TopSeed RF receiver generates keyboard events on /dev/input/event3, and mouse events on /dev/input/event4 - but the device numbers on your system may vary. The following steps will need to be repeated for each of the relevant 'event' devices (ie 'event3' and 'event4' in the example above) - ignore the 'mouse1' device.
Determine the key codes generated by your remote handset
Make sure that the MythTV front end is not running before you try the next step, otherwise it will capture the events that you are trying to watch. Use the command:
This will do two things. Firstly, evtest prints out a list of all the key codes that the device reports it can generate. This may not be accurate, but is a good start. As an example, the TopSeed TSBX-2404 remote control reports:
... other lines snipped ... Event code 389 (DVD) Event code 396 (Memo) Event code 397 (Calendar) Event code 402 (ChannelUp) Event code 403 (ChannelDown) Event code 405 (Last) Event code 416 (?) ... further lines follow ...
This reveals that the 'Channel Up' button on the remote handset is expected to produce key code 402.
Next, start pressing buttons on the remote handset. As you do so, you will see output such as the following:
Event: time 1276380069.599655, type 4 (Misc), code 4 (ScanCode), value c008d Event: time 1276380069.599675, type 1 (Key), code 362 (Program), value 0 Event: time 1276380069.599682, -------------- Report Sync ------------ Event: time 1276380101.623667, type 4 (Misc), code 4 (ScanCode), value c0224 Event: time 1276380101.623695, type 1 (Key), code 158 (Back), value 1 Event: time 1276380101.623698, -------------- Report Sync ------------
The example output above shows that the 'Program' key generates key code 362, and the 'Back' key generates code 158. Although these codes may be obvious from the initial event listing that evtest gives when it runs, this may help to identify which button on the handset is which, since it is not always obvious what the buttons are called - especially in the case of buttons bearing symbols or icons.
Work out what you want the keys to do
Use this command:
to dump out the X key mapping table. The output lists all the key codes from 8 to 255:
keycode 8 = keycode 9 = Escape NoSymbol Escape keycode 10 = 1 exclam 1 exclam onesuperior exclamdown keycode 11 = 2 at 2 quotedbl twosuperior oneeighth keycode 12 = 3 numbersign 3 sterling threesuperior sterling ... more key codes listed here ... keycode 109 = Linefeed NoSymbol Linefeed keycode 110 = Home NoSymbol Home keycode 111 = Up NoSymbol Up keycode 112 = Prior NoSymbol Prior keycode 113 = Left NoSymbol Left keycode 114 = Right NoSymbol Right keycode 115 = End NoSymbol End keycode 116 = Down NoSymbol Down ... then more key codes until ... keycode 254 = keycode 255 =
This table shows, for example, that key code 111 is handled as 'Up'.
Therefore, if you have a button on your remote handset which generates key code 402, for example, and you want that button to be treated by X (and therefore MythTV) as 'Up', then you need to remap key code 402 to code 111 in your 'event_key_remap' line in 'xorg.conf'. Repeat for each button on the remote handset that you need to remap.
Just as an FYI, you can remap *any* key to another key, you are not limited to keys above 255. For example, here is what I have remapped:
Option "event_key_remap" "272=104 352=104 128=9 273=9 139=58 96=31 18=26 32=40 46=54 33=41"
And to further explain, in evtest <device> pressing the check mark on my remote (ATI Remote Wonder) yields:
Event: time 1309016366.536995, type 1 (Key), code 96 (KPEnter), value 1 Event: time 1309016366.537004, -------------- Report Sync ------------ Event: time 1309016366.537020, type 1 (Key), code 96 (KPEnter), value 0 Event: time 1309016366.537022, -------------- Report Sync ------------
Then from the output of xmodmap -pke I see that keycode 31 is mapped to 'i I i I' so, as you can see, I have mapped my check mark button (code 96) to the 'I' button (keycode 31) as shown in my xorg.conf snippet.