Generic HID "MCE" Remotes

From MythTV Official Wiki
Jump to: navigation, search

Generic HID "MCE" Remotes

An example of one of many of these remotes.

This is for any generic remote that uses the USB HID keyboard drivers. These remotes tend to be very popular on eBay, advertising themselves as MCE Remotes and originating from Asia. One popular model at the moment is the YAOCOO MCEY06

The HDPLEX internal remote is also a USB HID Device that can benefit from these techniques.

Description

These remotes act and look just like a USB keyboard (and sometime a mouse as well) to the system. There is no need for any LIRC drivers for this to work, provided a sufficiently recent kernel.

When plugging in one of these, dmesg should show something similar to the following:

usb 1-2: new low speed USB device using ohci_hcd and address 3
usb 1-2: configuration #1 chosen from 1 choice
input: USB HID v1.10 Keyboard [HOLTEK USB To PS2 Devic] on usb-0000:00:0b.0-2
input,hiddev96: USB HID v1.10 Mouse [HOLTEK USB To PS2 Devic] on usb-0000:00:0b.0-2

Unfortunately the keypresses simulated by these remotes may not all work with MythTV. For example, the remote linked above uses Ctrl+b, Ctrl+p, Ctrl+f for reverse skip, pause, and forward skip, while using Ctrl+B, Ctrl+P, Ctrl+F for rewind, play and ffwd. I don't believe MythTV keybindings are case sensitive so the Ctrl+b and Ctrl+Shift+b are indistinguishable from each other. In addition to this, there are a number of keys that generate unmapped keycodes which don't work in MythTV.

Solutions

There are two ways to solve the problem created by the mapping of these devices. You can use xmodmap, which was the first solution proposed in the MythTV wiki. Unfortunately, using xmodmap means that if you connect a usb keyboard to your frontend it's keys will also be remapped. This will leave you unable to type a capital P, B, F, etc... The other solution involves the use of XKB remapping, a more complex approach that does permit remapping on a per device basis.

xmodmap

Ctrl+Shift keys
In order to make those Ctrl+Shift keys work we need to remap the shifted keys to a different character. First, using xev, run through all the buttons on your remote making a note of which buttons generate which keys. Second, choose some unused shifted characters for use in the remap. For example, if not used we can make Shift+b = '<', Shift+p = '?' and Shift+f = '>' using xmodmap.

In your .xinitrc place the following:

xmodmap -e "keycode 56 = b less"
xmodmap -e "keycode 33 = p question"
xmodmap -e "keycode 41 = f greater" 

Now in your MythTV keybinds, you can use Ctrl+< for the skip back button, Ctrl+? for the play button, and Ctrl+> for the skip forward button.

Restart X and mythfrontend then verify that the keys work as expected. You can go ahead and add more lines into your .xinitrc for the remaining double keys

Unknown keys
If you have buttons on your remote that generate no valid keys but valid keycodes, you can assign some keys to those buttons and set them in your mythtv keybindings.

xmodmap -e "keycode 167 = F1"
xmodmap -e "keycode 223 = F2"
...


Other buttons
If you still have buttons on your remote that do nothing in xev and are NOT for the mouse component (if exists), then you may have a remote that created two /dev/input/ entries, one for the USB HID Keyboard and another for a USB HID Consumer device. The consumer device can likely be used with LIRC to get the remaining keys functions. Please have a look at the Snapstream firefly mini article for more information on this configuration.

XKB Remapping

This solution is pretty much the same as the one proposed for xmodmap, however it allows the remapping to occur on a per device basis. This allows you to remap your remote while leaving other input devices, such as USB keyboards, functioning normally. This example is based on the Internal IR remote in the HDPLEX system, running on an installation of ubuntu 11.04 with openbox as the window manager, but the principles and some specifics should apply in to any USB HID remote device, OS and window manager.

This work is heavily based on this page on XKB remapping, I also found this other page helpful in understanding what goes into a keyboard layout.

The first requirement is ensuring that you have a version of xbcomp > 1.2.0 with per device support. This was added in this commit, unfortunately this version is not included in ubuntu 11.04. To build a version with support use the following diff file against the apt-get source of x11-xkb-utils. You can and then you can build an updated version of the package with per device support.

Here is a complete log showing the commands in the build process.

johnf@argon:~/src/custom_xkb$ apt-get source x11-xkb-utils
Reading package lists... Done
Building dependency tree
Reading state information... Done
[...]
dpkg-source: info: extracting x11-xkb-utils in x11-xkb-utils-7.6+2
dpkg-source: info: unpacking x11-xkb-utils_7.6+2.tar.gz
johnf@argon:~/src/custom_xkb$ wget http://zioncluster.ca/mythtv/ubuntu_xkb_diff_file
[...]
2011-08-22 22:02:16 (264 MB/s) - `ubuntu_xkb_diff_file' saved [2575/2575]
johnf@argon:~/src/custom_xkb$ patch -p0 < ubuntu_xkb_diff_file
patching file x11-xkb-utils-7.6+2/debian/changelog
patching file x11-xkb-utils-7.6+2/debian/patches/12_per_device_xkbcomp
patching file x11-xkb-utils-7.6+2/debian/patches/series
patching file x11-xkb-utils-7.6+2/xkbcomp/xkbcomp.c
johnf@argon:~/src/custom_xkb$ cd x11-xkb-utils-7.6+2
johnf@argon:~/src/custom_xkb/x11-xkb-utils-7.6+2$ dpkg-buildpackage -rfakeroot -uc -b
dpkg-deb: building package `x11-xkb-utils' in `../x11-xkb-utils_7.6+2-johnf1_amd64.deb'.
dpkg-deb: building package `x11-xkb-utils-udeb' in `../x11-xkb-utils-udeb_7.6+2-johnf1_amd64.udeb'.
 dpkg-genchanges -b >../x11-xkb-utils_7.6+2-johnf1_amd64.changes
dpkg-genchanges: binary-only upload - not including any source code
 dpkg-source --after-build x11-xkb-utils-7.6+2
dpkg-buildpackage: binary only upload (no source included)
[...]
johnf@argon:~/src/custom_xkb/x11-xkb-utils-7.6+2$ cd ..
johnf@argon:~/src/custom_xkb$ sudo dpkg -i x11-xkb-utils-udeb_7.6+2-johnf1_amd64.udeb

Now that we have xkbcomp with per device support we can put it to use.

We will need to locate the unique string that will allow you to identify your remote. We will use the command xinput list to view input devices.

mythtv@argon:~$ xinput list
⎡ Virtual core pointer                    	id=2	[master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer              	id=4	[slave  pointer  (2)]
⎜   ↳ HOLTEK                                  	id=9	[slave  pointer  (2)]
⎜   ↳ Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint	id=11	[slave  pointer  (2)]
⎣ Virtual core keyboard                   	id=3	[master keyboard (2)]
    ↳ Virtual core XTEST keyboard             	id=5	[slave  keyboard (3)]
    ↳ Power Button                            	id=6	[slave  keyboard (3)]
    ↳ Power Button                            	id=7	[slave  keyboard (3)]
    ↳ HOLTEK                                  	id=8	[slave  keyboard (3)]
    ↳ Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint	id=10	[slave  keyboard (3)]

My remote is identified by the string HOLTEK.

Knowing the string for the remote, we can now create a script to remap the HOLTEK HID input specifically. This script is adapted from a very usful article on the subject of XKB remapping. I have placed this script in /home/mythtv/scripts/remap_remote, it is called from the .xinitrc file I use when starting X.

remote_id=$(
  xinput list |
  sed -n 's/.*HOLTEK.*id=\([0-9]*\).*keyboard.*/\1/p'
)
[ "$remote_id" ] || exit

mkdir -p /tmp/xkb/symbols
cat >/tmp/xkb/symbols/custom <<\EOF
xkb_symbols "remote" {
    key <I166>   {      [ Escape ]       };
    key <AD10> {        [ p,    question ]       };
    key <MENU> {	[ I ]	};
    key <FK04> { [ XF86Sleep, XF86Sleep]        };
};
EOF

setxkbmap -device $remote_id -print | sed 's/\(xkb_symbols.*\)"/\1+custom(remote)"/' | xkbcomp -I/tmp/xkb -i $remote_id -synch - $DISPLAY 2>/dev/null

This command remaps the buttons that I am concerned with. In order, they are the exit button (remapped to escape), the play/pause button (upper case P remapped to question mark), the MENU button (remapped to I) and the power button (remapped to XF86Sleep). I don't use the fast forward / rewind buttons, but they could be remapped as described in the xmodmap section.

You will need to update your remote configuration using mythweb, and tell it to use Ctrl+? as the play button. The other remappings shouldn't require mythtv configuration changes.

By default the remote generated alt+shift+F4 when you press the power button. I remapped this to XF86Sleep, however the Alt keypress remained and/or openbox didn't handle it properly. To have the box suspend with the power button I edited my openbox configuration (.config/openbox/rc.xml) and added the following in the <keyboard> section:

 
    <keybind key="A-XF86Sleep">
      <action name="Execute">
        <command>sh -c 'sudo /etc/acpi/sleep.sh'</command>
      </action>
    </keybind>

This should have your remote fully functional, while allowing other input devices to be used normally.