[patch] add keymap data to make random laptop vendor keys work
Lennart Poettering
mzuny at 0pointer.de
Mon Jun 4 07:33:29 PDT 2007
On Mon, 04.06.07 14:24, Richard Hughes (hughsient at gmail.com) wrote:
A few comments:
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <errno.h>
> +#include <string.h>
> +#include <fcntl.h>
> +#include <sys/ioctl.h>
> +
> +#include <linux/input.h>
> +#include <linux/kd.h>
No need to include "kd.h" if you use the linux input API.
> +static int
> +evdev_set_keycode (int fd, int scancode, int keycode)
> +{
> + int ret;
> + struct kbkeycode kb;
> +
> + kb.keycode = keycode;
> + kb.scancode = scancode;
Uh!
You have to pass an int[2] here, not a struct kbkeycode.
> + /* add each of the keys */
> + do {
> + values = sscanf (keymap_list[i], "%x:%i", &scancode, &keycode);
> + if (values == 2) {
> + printf ("hal-setup-keymap: Parsed %s to (%x, %i)", keymap_list[i], scancode, keycode);
> + evdev_set_keycode (fd, scancode, keycode);
> + } else {
> + printf ("hal-setup-keymap: Failed to parse %s", keymap_list[i]);
> + }
> + } while (keymap_list[i++] != NULL);
Please do not use the numeric Linux keycodes directly for
this. Firstly, this is not portable. Secondly, this is not extensible,
since the Linux keycode space is mostly depleted already. Use the
names instead. Eventually the kernel guys might come up with a
completely new mapping thing again, to extend the code space.
In keyfuzz I use these Makefile lines for generating a static gperf hashtable
for translating these keycodes:
<snip>
keys.txt: input.h Makefile
awk '/^#define.*KEY_/ { if ($$2 != "KEY_MAX") { print $$2 }
}' < $< > $@
keys-from-name.gperf: keys.txt Makefile
awk 'BEGIN{ print "struct key { const char*
name; unsigned short id; };"; print
"%null-strings"; print "%%";} { print $$1 ", "
$$1 }' < $< > $@
keys-from-name.h: keys-from-name.gperf Makefile
gperf -t --ignore-case -N lookup_key -H
hash_key_name -p -C < $< > $@
keys-to-name.h: keys.txt Makefile
awk 'BEGIN{ print "const char* const
key_names[KEY_MAX] = { "} { print "[" $$1 "] = \"" $$1
"\"," } END{print "};"}' < $< > $@
</snip>
Indenting borked. Get the original stuff from:
http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/Makefile.am?rev=19&root=keyfuzz&view=auto
You can probably omit the keys-to-name part, as you only want to
translate keycodes to names and not vice versa.
> + <!-- These are raw scancodes produced by the keyboard driver -->
> + <match key="info.product" string="AT Translated Set 2 keyboard">
> +
> + <match key="/org/freedesktop/Hal/devices/computer:system.hardware.vendor" prefix="LENOVO">
> + <match key="/org/freedesktop/Hal/devices/computer:smbios.system.version" contains="3000">
There seems to be an implicit guarantee that atkb shows up in the HAL
device tree after DMI. Is that really guaranteed in all cases?
> + <append key="input.keymap.data.linux" type="strlist">e016:238</append> <!-- Fn+F5 wireless KEY_WLAN -->
> + <append key="input.keymap.data.linux" type="strlist">e017:142</append> <!-- Fn+F4 suspend KEY_SLEEP -->
> + <append key="input.keymap.data.linux" type="strlist">e018:205</append> <!-- Fn+F12 hibernate KEY_SUSPEND -->
> + <append key="info.capabilities" type="strlist">input.keymap</append>
> + </match>
> + </match>
> +
> + </match>
> +
> + <!-- These are buttons synthesized in kernel drivers -->
> + <match key="info.product" string="ThinkPad Extra Buttons">
> + <match key="/org/freedesktop/Hal/devices/computer:system.hardware.vendor" prefix="LENOVO">
> + <append key="input.keymap.data.linux" type="strlist">007f:152</append> <!-- thinkvantage KEY_COFFEE -->
> + <append key="info.capabilities" type="strlist">input.keymap</append>
> + </match>
> + </match>
One question here: Why don't the thinkpad kernel drivers contain the proper
mappings anyway? Why is there the need for additional remapping from userspace?
Lennart
--
Lennart Poettering Red Hat, Inc.
lennart [at] poettering [dot] net ICQ# 11060553
http://0pointer.net/lennart/ GnuPG 0x1A015CC4
More information about the hal
mailing list