Remapping remote control key codes greater than 255

From MythTV Official Wiki
Jump to: navigation, search

Key mapping using ir-keytable/xmodmap/xkb

Important.png Note: Please see HID_Remotes for other solutions that may be simpler than event_key_remap.

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.

Installing git

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-x.y.z

where x.y.z is the version number you require. Check out the git summary at http://www.thenautilus.net/cgit/xf86-input-evdev/ to find out what the latest version is. Version 2.4.0 worked with Mythbuntu 10.04 but stopped working after upgrading Ubuntu to 12.04, as indicated by the error message "Failed to load module "evdev" (module requirement mismatch, 0)" in /var/log/Xorg.0.log. Building and installing version 2.8.0 worked with Mythbuntu 12.04.

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: To build version 2.6.0 you will also need xserver-xorg-dev, xutils-dev, libtool, and autoconf:

sudo apt-get install xserver-xorg-dev xutils-dev libtool autoconf

will get you the required packages. To build version 2.8.0 of the evdev driver you will need libudev-dev as well.)

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.

Configuring xorg.conf

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 

In order to always have the same "Device" option set, you can create the following udev rule:

cat /etc/udev/rules.d/100-mythtv.rules
# HDPVR
# Video device
KERNEL=="video[0-9]", ATTRS{product}=="Hauppauge HD PVR", SYMLINK+="HDPVR-VIDEO"
# Blaster device
SUBSYSTEM=="lirc", ATTRS{product}=="Hauppauge HD PVR" SYMLINK+="HDPVR-BLASTER"

Then the InputDevice section listed above would look like such:

   Section "InputDevice"
       Identifier  "RF remote"
       Driver      "evdev"
       Option      "Device" "/dev/HDPVR-BLASTER"
       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:

evtest /dev/input/event4

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:

xmodmap -pke

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.

User Notes

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.