Logitech Wireless Keyboard for Wii
The wireless keyboard for the video game console Wii™ produced by Logitech, Inc., is a cheap input device ideal to enter short text (such as web search strings, quick email replies, chat messages, etc.). It features:
- compact size (30x16.5x2cm)
- full-size keys
- six dedicated keys
- 2.4GHz wireless connection
- slot on the back side to store the connection USB key
- mechanical power switch to save up battery energy
It misses an important key, though, the left Alt_L key.
Contents
Installation
Provided that kernel module usbhid is loaded and HAL is running, the keyboard is automatically recognised as Logitech USB Wireless HID Receiver as soon as the USB key is attached.
lorcap ~ $ lshal > /tmp/hal USB key receiver inserted. wait 2-3 seconds to settle... lorcap ~ $ lshal > /tmp/hal-wii lorcap ~ $ diff --old-line-format="" \ --unchanged-line-format="" \ --new-line-format="%L" \ /tmp/hal /tmp/hal-wii \ | egrep -v "^Dump" udi = '/org/freedesktop/Hal/devices/usb_device_46d_cab1_noserial' info.linux.driver = 'usb' (string) info.parent = '/org/freedesktop/Hal/devices/usb_device_1d6b_1_0000_00_1d_0' (string) info.product = 'USB Wireless HID Receiver' (string) info.subsystem = 'usb_device' (string) info.udi = '/org/freedesktop/Hal/devices/usb_device_46d_cab1_noserial' (string) info.vendor = 'Logitech, Inc.' (string) linux.device_file = '/dev/bus/usb/002/003' (string) linux.hotplug_type = 2 (0x2) (int) linux.subsystem = 'usb' (string) linux.sysfs_path = '/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1' (string) usb_device.bus_number = 2 (0x2) (int) usb_device.can_wake_up = true (bool) usb_device.configuration_value = 1 (0x1) (int) usb_device.device_class = 0 (0x0) (int) usb_device.device_protocol = 0 (0x0) (int) usb_device.device_revision_bcd = 288 (0x120) (int) usb_device.device_subclass = 0 (0x0) (int) usb_device.is_self_powered = false (bool) usb_device.linux.device_number = 3 (0x3) (int) usb_device.linux.sysfs_path = '/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1' (string) usb_device.max_power = 100 (0x64) (int) usb_device.num_configurations = 1 (0x1) (int) usb_device.num_interfaces = 1 (0x1) (int) usb_device.num_ports = 0 (0x0) (int) usb_device.product = 'USB Wireless HID Receiver' (string) usb_device.product_id = 51889 (0xcab1) (int) usb_device.speed = 1.5 (1.5) (double) usb_device.vendor = 'Logitech, Inc.' (string) usb_device.vendor_id = 1133 (0x46d) (int) usb_device.version = 2.0 (2) (double) udi = '/org/freedesktop/Hal/devices/usb_device_46d_cab1_noserial_usbraw' info.capabilities = {'usbraw'} (string list) info.category = 'usbraw' (string) info.parent = '/org/freedesktop/Hal/devices/usb_device_46d_cab1_noserial' (string) info.product = 'USB Raw Device Access' (string) info.subsystem = 'usb_device' (string) info.udi = '/org/freedesktop/Hal/devices/usb_device_46d_cab1_noserial_usbraw' (string) linux.device_file = '/dev/usbdev2.3' (string) linux.hotplug_type = 2 (0x2) (int) linux.subsystem = 'usb_device' (string) linux.sysfs_path = '/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/usb_device/usbdev2.3' (string) usbraw.device = '/dev/usbdev2.3' (string) udi = '/org/freedesktop/Hal/devices/usb_device_46d_cab1_noserial_if0' info.linux.driver = 'usbhid' (string) info.parent = '/org/freedesktop/Hal/devices/usb_device_46d_cab1_noserial' (string) info.product = 'USB HID Interface' (string) info.subsystem = 'usb' (string) info.udi = '/org/freedesktop/Hal/devices/usb_device_46d_cab1_noserial_if0' (string) linux.hotplug_type = 2 (0x2) (int) linux.subsystem = 'usb' (string) linux.sysfs_path = '/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.0' (string) usb.bus_number = 2 (0x2) (int) usb.can_wake_up = true (bool) usb.configuration_value = 1 (0x1) (int) usb.device_class = 0 (0x0) (int) usb.device_protocol = 0 (0x0) (int) usb.device_revision_bcd = 288 (0x120) (int) usb.device_subclass = 0 (0x0) (int) usb.interface.class = 3 (0x3) (int) usb.interface.number = 0 (0x0) (int) usb.interface.protocol = 1 (0x1) (int) usb.interface.subclass = 1 (0x1) (int) usb.is_self_powered = false (bool) usb.linux.device_number = 3 (0x3) (int) usb.linux.sysfs_path = '/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.0' (string) usb.max_power = 100 (0x64) (int) usb.num_configurations = 1 (0x1) (int) usb.num_interfaces = 1 (0x1) (int) usb.num_ports = 0 (0x0) (int) usb.product = 'USB HID Interface' (string) usb.product_id = 51889 (0xcab1) (int) usb.speed = 1.5 (1.5) (double) usb.vendor = 'Logitech, Inc.' (string) usb.vendor_id = 1133 (0x46d) (int) usb.version = 2.0 (2) (double) udi = '/org/freedesktop/Hal/devices/usb_device_46d_cab1_noserial_if0_logicaldev_input' info.addons.singleton = {'hald-addon-input'} (string list) info.capabilities = {'input', 'input.keyboard', 'input.keypad', 'input.keys', 'button'} (string list) info.category = 'input' (string) info.parent = '/org/freedesktop/Hal/devices/usb_device_46d_cab1_noserial_if0' (string) info.product = 'Logitech USB Wireless HID Receiver' (string) info.subsystem = 'input' (string) info.udi = '/org/freedesktop/Hal/devices/usb_device_46d_cab1_noserial_if0_logicaldev_input' (string) input.device = '/dev/input/event11' (string) input.originating_device = '/org/freedesktop/Hal/devices/usb_device_46d_cab1_noserial_if0' (string) input.product = 'Logitech USB Wireless HID Receiver' (string) input.x11_driver = 'evdev' (string) input.xkb.layout = 'it' (string) input.xkb.model = 'evdev' (string) input.xkb.rules = 'base' (string) input.xkb.variant = (string) linux.device_file = '/dev/input/event11' (string) linux.hotplug_type = 2 (0x2) (int) linux.subsystem = 'input' (string) linux.sysfs_path = '/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.0/input/input12/event11' (string)
Keyboard Layout
The keyboard found at the local store provides an Italian layout. It features six extra keys:
- Quit, between Esc and F1
- Zoom_In and Zoom_Out, in place of Windows key and left Alt_L
- Backward and Forward, between Space and AltGr
- Ok just below the right Shift_R.
The keyboard provides also the four arrow keys (Up, Down, Left, and Right) on the lower right-hand-side corner which come very handy when surfing through MythTV menus. In the same place, there is also the blue key FN which, when combined with the arrow keys, serve as Page_Up, Page_Down, Begin, and End.
The blue key FN can be used to enter digits with a keypad layout. Unfortunately, FN and keypad keys are all on the right-hand-side of the keyboard and the digits should be entered with one hand by pressing two keys at the same time.
The biggest shortcoming of the keyboard, though, is that it misses the left Alt_L key. The ALT_L is vital for a more advanced usage of the home theater hosting MythTV, e.g., when text console is required.
Scancodes
The key codes, called scancodes and produced by the keyboard at each key press/release, can be shown with the utility showkey run in a text console. Even when using the kernel parameter atkbd.softram=0, as suggested in showkey's manual page, the scancodes don't change.
lorcap ~ $ showkey -s kb mode was UNICODE [ if you are trying this under X, it might not work since the X server is also reading /dev/console ] press any key (program terminates 10s after last keypress)... 0x9c 0x38 0x0e # Quit = Alt_L Backspace 0xb8 0x8e 0x4a # Zoom_Out = KP_Subtract 0xca 0x4e # Zoom_In = KP_Add 0xce 0xe0 0x1d 0xe0 0x4b # Backward = Control_L Left 0xe0 0x9d 0xe0 0xcb 0xe0 0x1d 0xe0 0x4d # Forward = Control_L Right 0xe0 0x9d 0xe0 0xcd 0x38 0x1c # Ok = Alt_L Return 0xb8 0x9c
Keycodes
Keycodes are numbers assigned by the kernel to each individual physical key and read by applications.
lorcap ~ $ showkey -k kb mode was UNICODE [ if you are trying this under X, it might not work since the X server is also reading /dev/console ] press any key (program terminates 10s after last keypress)... keycode 28 release keycode 56 press # Quit = Alt_L keycode 14 press # Backspace keycode 56 release keycode 14 release keycode 74 press # Zoom_Out = KP_Subtract keycode 74 release keycode 78 press # Zoom_In = KP_Add keycode 78 release keycode 97 press # Backward = Control_L keycode 105 press # Left keycode 97 release keycode 105 release keycode 97 press # Forward = Control_L keycode 106 press # Right keycode 97 release keycode 106 release keycode 56 press # Ok = Alt_L keycode 28 press # Return keycode 56 release keycode 28 release
HAL Keymap
As seen above, the keyboard does not generate any special scancode and the use of setkeycodes or an equivalent utility is probably useless. Nonetheless, here it is the way to re-bind a scancode with a new keycode using HAL. Create the file 30-keymap-wii.fdi in /etc/hal/fdi/policy/ with the following customizable content:
<?xml version="1.0" encoding="ISO-8859-1"?> <deviceinfo version="0.2"> <device> <match key="@input.originating_device:info.linux.driver" string="usbhid"> <match key="info.product" string="Logitech USB Wireless HID Receiver"> <append key="input.keymap.data" type="strlist">4a:volumedown</append> <append key="input.keymap.data" type="strlist">4e:volumeup</append> <addset key="info.capabilities" type="strlist">input.keymap</addset> </match> </match> </device> </deviceinfo>
How to Add the Alt_L Key
Console and X require two different utilities in order to get back the Alt_L key. The following instructions assume you want to bind the key Zoom_In, which is equivalent to the keypad add.
Alt_L in a Console
The Alt_L key can be obtained via utility loadkeys. Choose the key which will be used as Alt_L, e.g. Zoom_In, and then issue the following command:
lorcap ~ $ echo "keycode 78 = Alt" | loadkeys it - Loading /usr/share/kbd/keymaps/i386/qwerty/it.map.gz Loading <stdin>
Alternatively, it is possible to place a map file wii.map in /usr/share/kbd/keymaps/i386/qwerty/:
lorcap ~ $ echo "keycode 78 = Alt" > /usr/share/kbd/keymaps/i386/qwerty/wii.map loadkeys it wii Loading /usr/share/kbd/keymaps/i386/qwerty/it.map.gz Loading /usr/share/kbd/keymaps/i386/qwerty/wii.map
One more option is to have only one map file:
lorcap ~ $ cd /usr/share/kbd/keymaps/i386/qwerty lorcap ~ $ echo 'include "it.map"' > wii.map lorcap ~ $ echo 'keycode 78 = Alt" >> wii.map lorcap ~ $ cd lorcap ~ $ loadkeys wii Loading /usr/share/kbd/keymaps/i386/qwerty/wii.map
Alt_L under X
The command to use and get back the Alt_L is xmodmap. Because special keys produce ordinary keys which are already defined, expression keysym can be used.
lorcap ~ $ xmodmap -e 'keysym KP_Add = Alt_L'
To check that the new binding is working, run xev under X and press the new key:
lorcap ~ $ xev KeyPress event, serial 43, synthetic NO, window 0x1000001, root 0x10b, subw 0x0, time 1980226, (-463,-67), root:(380,54), state 0x0, keycode 86 (keysym 0xffe9, Alt_L), same_screen YES, XKeysymToKeycode returns keycode: 64 XLookupString gives 0 bytes: XmbLookupString gives 0 bytes: XFilterEvent returns: False KeyRelease event, serial 43, synthetic NO, window 0x1000001, root 0x10b, subw 0x0, time 1980298, (-463,-67), root:(380,54), state 0x8, keycode 86 (keysym 0xffe9, Alt_L), same_screen YES, XKeysymToKeycode returns keycode: 64 XLookupString gives 0 bytes: XFilterEvent returns: False
When everything is working, the definitive expression can be written to .xmodmaprc:
lorcap ~ $ echo 'keysym KP_Add = Alt_L' >> ~/.xmodmaprc