diff options
Diffstat (limited to 'keymap')
-rw-r--r-- | keymap/95-keymap.rules | 8 | ||||
-rw-r--r-- | keymap/Makefile.am | 48 | ||||
-rw-r--r-- | keymap/README.keymap.txt | 100 | ||||
-rwxr-xr-x | keymap/check-keymaps.sh | 18 | ||||
-rwxr-xr-x | keymap/findkeyboards | 45 | ||||
-rw-r--r-- | keymap/keymap.c | 69 | ||||
-rw-r--r-- | keymap/keymaps/hewlett-packard | 2 | ||||
-rw-r--r-- | keymap/keymaps/hewlett-packard-tx2 | 3 | ||||
-rw-r--r-- | keymap/keymaps/lenovo-thinkpad_x200_tablet | 6 |
9 files changed, 284 insertions, 15 deletions
diff --git a/keymap/95-keymap.rules b/keymap/95-keymap.rules index 9849696..e6c5438 100644 --- a/keymap/95-keymap.rules +++ b/keymap/95-keymap.rules @@ -10,9 +10,9 @@ ATTR{[dmi/id]sys_vendor}=="IBM*", ATTR{name}=="ThinkPad Extra Buttons", RUN+="ke ATTR{[dmi/id]sys_vendor}=="LENOVO*", ATTR{name}=="ThinkPad Extra Buttons", RUN+="keymap $name module-lenovo" ATTR{[dmi/id]sys_vendor}=="ASUS*", ATTR{name}=="Asus Extra Buttons", ATTR{[dmi/id]product_name}=="W3J", RUN+="keymap $name module-asus-w3j" -ATTR{[dmi/id]sys_vendor}=="Sony*", ATTR{name}=="Sony Vaio Keys", RUN+="keymap $name sony" +ATTR{[dmi/id]sys_vendor}=="Sony*", ATTR{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony" # Older Vaios have some different keys -ATTR{[dmi/id]sys_vendor}=="Sony*", ATTR{[dmi/id]product_name}=="*PCG-C1*|*PCG-K25*|*PCG-F1*|*PCG-F2*|*PCG-F3*|*PCG-F4*|*PCG-F5*|*PCG-F6*|*PCG-FX*|*PCG-FRV*|*PCG-GR*|*PCG-TR*|*PCG-NV*|*PCG-Z*|*VGN-S360*|*VGN-SZ2HP_B*", ATTR{name}=="Sony Vaio Keys", RUN+="keymap $name sony-old" +ATTR{[dmi/id]sys_vendor}=="Sony*", ATTR{[dmi/id]product_name}=="*PCG-C1*|*PCG-K25*|*PCG-F1*|*PCG-F2*|*PCG-F3*|*PCG-F4*|*PCG-F5*|*PCG-F6*|*PCG-FX*|*PCG-FRV*|*PCG-GR*|*PCG-TR*|*PCG-NV*|*PCG-Z*|*VGN-S360*|*VGN-SZ2HP_B*", ATTR{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony-old" # # The following rules belong to standard i8042 AT keyboard with high key codes. @@ -28,12 +28,14 @@ ATTR{[dmi/id]sys_vendor}=="Compaq*", ATTR{[dmi/id]product_name}=="*E500*|*Evo N6 ATTR{[dmi/id]sys_vendor}=="LENOVO*", ATTR{[dmi/id]product_version}=="*3000*", RUN+="keymap $name lenovo-3000" ATTR{[dmi/id]sys_vendor}=="LENOVO*", ATTR{[dmi/id]product_version}=="ThinkPad X6*", ATTR{[dmi/id]product_version}=="* Tablet" RUN+="keymap $name lenovo-thinkpad_x6_tablet" +ATTR{[dmi/id]sys_vendor}=="LENOVO*", ATTR{[dmi/id]product_version}=="ThinkPad X200 Tablet*", ATTR{[dmi/id]product_version}=="* Tablet" RUN+="keymap $name lenovo-thinkpad_x200_tablet" ATTR{[dmi/id]sys_vendor}=="Hewlett-Packard*", RUN+="keymap $name hewlett-packard" ATTR{[dmi/id]sys_vendor}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[tT][aA][bB][lL][eE][tT]*", RUN+="keymap $name hewlett-packard-tablet" ATTR{[dmi/id]sys_vendor}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[pP][aA][vV][iI][lL][iI][oO][nN]*", RUN+="keymap $name hewlett-packard-pavilion" ATTR{[dmi/id]sys_vendor}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*Compaq*|*EliteBook*", RUN+="keymap $name hewlett-packard-compaq_elitebook" ATTR{[dmi/id]sys_vendor}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*2510p*|*2530p*", RUN+="keymap $name hewlett-packard-2510p_2530p" +ATTR{[dmi/id]sys_vendor}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[tT][xX]2*", RUN+="keymap $name hewlett-packard-tx2" ATTR{[dmi/id]sys_vendor}=="Acer*", RUN+="keymap $name acer" ATTR{[dmi/id]sys_vendor}=="Acer*", ATTR{[dmi/id]product_name}=="Extensa*", ATTR{[dmi/id]product_name}=="*5210*|*5220*|*5610*|*5620*|*5720*", RUN+="keymap $name acer-extensa_5xxx" @@ -59,7 +61,7 @@ ATTR{[dmi/id]sys_vendor}=="INVENTEC", ATTR{[dmi/id]product_name}=="SYMPHONY 6.0/ ATTR{[dmi/id]sys_vendor}=="MAXDATA", ATTR{[dmi/id]product_name}=="Pro 7000*", RUN+="keymap $name maxdata-pro_7000" -ATTR{[dmi/id]sys_vendor}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*NC10*|*SP55S*|*SQ45S70S*|*SX60P*|*SX30S*|*R59P/R60P/R61P*|*Q210*|*Q310*|*X05*", RUN+="keymap $name samsung-other" +ATTR{[dmi/id]sys_vendor}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*NC10*|*SP55S*|*SQ45S70S*|*SX60P*|*SX30S*|*R59P/R60P/R61P*|*Q210*|*Q310*|*X05*|*P560*", RUN+="keymap $name samsung-other" ATTR{[dmi/id]sys_vendor}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*SX20S*", RUN+="keymap $name samsung-sx20s" ATTR{[dmi/id]sys_vendor}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="SQ1US", RUN+="keymap $name samsung-sq1us" diff --git a/keymap/Makefile.am b/keymap/Makefile.am index c7984ec..c3ba967 100644 --- a/keymap/Makefile.am +++ b/keymap/Makefile.am @@ -20,7 +20,49 @@ udevrulesdir = $(udev_prefix)/lib/udev/rules.d dist_udevrules_DATA = 95-keymap.rules udevkeymapdir = $(udevhomedir)/keymaps -udevkeymap_DATA = keymaps/* +udevkeymap_DATA = \ + keymaps/acer \ + keymaps/acer-aspire_5920g \ + keymaps/acer-extensa_5xxx \ + keymaps/acer-travelmate_6292 \ + keymaps/acer-travelmate_c300 \ + keymaps/asus \ + keymaps/benq-joybook_r22 \ + keymaps/compaq-e_evo \ + keymaps/dell \ + keymaps/fujitsu-amilo_pa_2548 \ + keymaps/fujitsu-amilo_pro_edition_v3505 \ + keymaps/fujitsu-amilo_pro_v3205 \ + keymaps/fujitsu-amilo_si_1520 \ + keymaps/fujitsu-esprimo_mobile_v5 \ + keymaps/fujitsu-esprimo_mobile_v6 \ + keymaps/hewlett-packard \ + keymaps/hewlett-packard-2510p_2530p \ + keymaps/hewlett-packard-compaq_elitebook \ + keymaps/hewlett-packard-pavilion \ + keymaps/hewlett-packard-tablet \ + keymaps/hewlett-packard-tx2 \ + keymaps/inventec-symphony_6.0_7.0 \ + keymaps/lenovo-3000 \ + keymaps/lenovo-thinkpad_x6_tablet \ + keymaps/lenovo-thinkpad_x200_tablet \ + keymaps/maxdata-pro_7000 \ + keymaps/medion-fid2060 \ + keymaps/medionnb-a555 \ + keymaps/micro-star \ + keymaps/module-asus-w3j \ + keymaps/module-ibm \ + keymaps/module-lenovo \ + keymaps/module-sony \ + keymaps/module-sony-old \ + keymaps/oqo-model2 \ + keymaps/samsung-other \ + keymaps/samsung-sq1us \ + keymaps/samsung-sx20s \ + keymaps/toshiba-satellite_a100 \ + keymaps/toshiba-satellite_a110 + +dist_pkgdata_SCRIPTS = findkeyboards # keymap program @@ -31,7 +73,9 @@ keymap_SOURCES = keymap.c nodist_keymap_SOURCES = keys-from-name.h keys-to-name.h keymap_CPPFLAGS = $(AM_CPPFLAGS) -EXTRA_DIST=keymaps +dist_doc_DATA = README.keymap.txt + +EXTRA_DIST=keymaps check-keymaps.sh BUILT_SOURCES = keys-from-name.h keys-to-name.h CLEANFILES = keys.txt keys-from-name.gperf keys-from-name.h keys-to-name.h TESTS = check-keymaps.sh diff --git a/keymap/README.keymap.txt b/keymap/README.keymap.txt new file mode 100644 index 0000000..cbd1f3d --- /dev/null +++ b/keymap/README.keymap.txt @@ -0,0 +1,100 @@ += The udev keymap tool = + +== Introduction == + +This udev extension configures computer model specific key mappings. This is +particularly necessary for the non-standard extra keys found on many laptops, +such as "brightness up", "next song", "www browser", or "suspend". Often these +are accessed with the Fn key. + +Every key produces a "scan code", which is highly vendor/model specific for the +nonstandard keys. This tool maintains mappings for these scan codes to standard +"key codes", which denote the "meaning" of the key. The key codes are defined +in /usr/include/linux/input.h. + +If some of your keys on your keyboard are not working at all, or produce the +wrong effect, then a very likely cause of this is that the scan code -> key +code mapping is incorrect on your computer. + +== Structure == + +udev-keymap consists of the following parts: + + keymaps/*:: mappings of scan codes to key code names + + 95-keymap.rules:: udev rules for mapping system vendor/product names and + input module names to one of the keymaps above + + keymap:: manipulate an evdev input device: + * write a key map file into a device (used by udev rules) + * dump current scan → key code mapping + * interactively display scan and key codes of pressed keys + + findkeyboards:: display evdev input devices which belong to actual keyboards, + i. e. those suitable for the keymap program + + fdi2rules.py:: convert hal keymap FDIs into udev rules and key map files + (Please note that this is far from perfect, since the mapping between fdi and + udev rules is not straightforward, and impossible in some cases.) + +== Fixing broken keys == + +In order to make a broken key work on your system and send it back to upstream +for inclusion you need to do the following steps: + + 1. Find the keyboard device. + + Run /usr/share/udev-extras/findkeyboards. This should always give you an "AT + keyboard" and possibly a "module". Some laptops (notably Thinkpads, Sonys, and + Acers) have multimedia/function keys on a separate input device instead of the + primary keyboard. The keyboard device should have a name like "input/event3". + In the following commands, the name will be written as "input/eventX". + + 2. Dump current mapping: + + sudo /lib/udev/keymap input/eventX > /tmp/orig-map.txt + + 3. Find broken scan codes: + + sudo /lib/udev/keymap -i input/eventX + + Press all multimedia/function keys and check if the key name that gets printed + out is plausible. If it is unknown or wrong, write down the scan code (looks + like "0x1E") and the intended functionality of this key. Look in + /usr/include/linux/input.h for an available KEY_XXXXX constant which most + closely approximates this functionality and write it down as the new key code. + + For example, you might press a key labeled "web browser" which currently + produces "unknown". Note down this: + + 0x1E www # Fn+F2 web browser + + Repeat that for all other keys. Write the resulting list into a file. Look at + /lib/udev/keymaps/ for existing key map files and make sure that you use the + same structure. + + 4. Find out your system vendor and product: + + cat /sys/class/dmi/id/sys_vendor + cat cat /sys/class/dmi/id/product_name + + 5. Generate a device dump with "udevadm info --export-db > /tmp/udev-db.txt". + + 6. Send the system vendor/product names, the key mapping from step 3, + /tmp/orig-map.txt from step 2, and /tmp/udev-db.txt from step 5 + to the bug tracker, so that they can be included in the next release: + + https://bugs.launchpad.net/udev-extras/+bugs + +For local testing, copy your map file to /lib/udev/keymaps/ with an appropriate +name, and add an appropriate udev rule to /lib/udev/rules.d/95-keymap.rules: + + * If you selected an "AT keyboard", add the rule to the section after + 'LABEL="keyboard_vendorcheck"'. + + * If you selected a "module", add the rule to the top section where the + "ThinkPad Extra Buttons" are. + +== Author == + +keymap is written and maintained by Martin Pitt <martin.pitt@ubuntu.com>. diff --git a/keymap/check-keymaps.sh b/keymap/check-keymaps.sh index bb38378..dc46f59 100755 --- a/keymap/check-keymaps.sh +++ b/keymap/check-keymaps.sh @@ -1,7 +1,8 @@ #!/bin/bash -# check that all key names in keymaps/* are known in <linux/input.h> -KEYLIST=${srcdir:-.}/keys.txt +# check that all key names in keymaps/* are known in <linux/input.h> +KEYLIST=./keys.txt +RULES=95-keymap.rules [ -e "$KEYLIST" ] || { echo "need $KEYLIST please build first" >&2 @@ -14,3 +15,16 @@ missing=$(join -v 2 <(awk '{print tolower(substr($1,5))}' $KEYLIST | sort -u) <( echo "$missing" >&2 exit 1 } + +# check that all maps referred to in $RULES exist +maps=$(sed -rn '/keymap \$name/ { s/^.*\$name ([^"]+).*$/\1/; p }' $RULES) +for m in $maps; do + [ -e keymaps/$m ] || { + echo "ERROR: unknown map name in $RULES: $m" >&2 + exit 1 + } + grep -q "keymaps/$m\>" Makefile.am || { + echo "ERROR: map file $m is not added to Makefile.am" >&2 + exit 1 + } +done diff --git a/keymap/findkeyboards b/keymap/findkeyboards new file mode 100755 index 0000000..e39084c --- /dev/null +++ b/keymap/findkeyboards @@ -0,0 +1,45 @@ +#!/bin/sh -e +# Find "real" keyboard devices and print their device path. +# Author: Martin Pitt <martin.pitt@ubuntu.com> +# +# Copyright (C) 2009, Canonical Ltd. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + + +# print a list of input devices which are keyboard-like +keyboard_devices() { + input_devs=`udevadm trigger --dry-run --verbose --subsystem-match=input --attr-match=dev` + + # standard AT keyboard + for dev in $input_devs; do + info=`udevadm info --attribute-walk --path=$dev` + + if echo "$info" | grep -q 'DRIVERS=="atkbd"'; then + echo -n 'AT keyboard: ' + udevadm info --query=name --path=$dev + fi + done + + # modules + module=`udevadm trigger --verbose --dry-run --subsystem-match=input --attr-match=name='*Extra Buttons'` + module="$module +`udevadm trigger --verbose --dry-run --subsystem-match=input --attr-match=name='Sony Vaio Keys'`" + for m in $module; do + evdev=`ls -d $m/event* 2>/dev/null` + if [ -e "$evdev/dev" ]; then + echo -n 'module: ' + udevadm info --query=name --path=$evdev + fi + done +} + +keyboard_devices diff --git a/keymap/keymap.c b/keymap/keymap.c index 516dbc0..c48d934 100644 --- a/keymap/keymap.c +++ b/keymap/keymap.c @@ -228,18 +228,65 @@ static const char* default_keymap_path(const char* path) return path; } +static void print_key(struct input_event *event) +{ + static int cur_scancode = 0; + + /* save scan code for next EV_KEY event */ + if (event->type == EV_MSC && event->code == MSC_SCAN) + cur_scancode = event->value; + + /* key press */ + if (event->type == EV_KEY && event->value) + printf("scan code: 0x%02X key code: %s\n", cur_scancode, + format_keyname(key_names[event->code])); +} + +static void interactive(int fd) +{ + struct input_event ev; + int run = 1; + + /* grab input device */ + ioctl(fd, EVIOCGRAB, 1); + + puts("Press ESC to finish"); + while (run) { + switch (read(fd, &ev, sizeof(ev))) { + case -1: + perror("read"); + run = 0; + break; + case 0: + run = 0; + break; + default: + print_key(&ev); + /* stop on Escape key release */ + if (ev.type == EV_KEY && ev.code == KEY_ESC && ev.value == 0) + run = 0; + break; + } + } + + /* release input device */ + ioctl(fd, EVIOCGRAB, 0); +} + int main(int argc, char **argv) { static const struct option options[] = { { "help", no_argument, NULL, 'h' }, + { "interactive", no_argument, NULL, 'i' }, {} }; int fd = -1; + int opt_interactive = 0; while (1) { int option; - option = getopt_long(argc, argv, "h", options, NULL); + option = getopt_long(argc, argv, "hi", options, NULL); if (option == -1) break; @@ -247,22 +294,30 @@ int main(int argc, char **argv) case 'h': printf("Usage: keymap <event device> [<map file>]\n\n"); return 0; + + case 'i': + opt_interactive = 1; + break; default: return 1; } } - if (argc < 2 || argc > 3) { + if (argc < optind+1 || argc > optind+2) { fprintf(stderr, "Usage: keymap <event device> [<map file>]\n\n"); return 2; } - if ((fd = evdev_open(argv[1])) < 0) + if ((fd = evdev_open(argv[optind])) < 0) return 3; - if (argc == 3) - merge_table(fd, default_keymap_path(argv[2])); - else - dump_table(fd); + if (argc == optind+2) + merge_table(fd, default_keymap_path(argv[optind+1])); + else { + if (opt_interactive) + interactive(fd); + else + dump_table(fd); + } return 0; } diff --git a/keymap/keymaps/hewlett-packard b/keymap/keymaps/hewlett-packard index d688085..4461fa2 100644 --- a/keymap/keymaps/hewlett-packard +++ b/keymap/keymaps/hewlett-packard @@ -5,7 +5,7 @@ 0x8C media # music 0x8E dvd 0xB1 help -0xB3 f21 # FIXME: Auto brightness +0xB3 f23 # FIXME: Auto brightness 0xD7 wlan 0x92 brightnessdown # FnF7 (FnF9 on 6730b) 0x97 brightnessup # FnF8 (FnF10 on 6730b) diff --git a/keymap/keymaps/hewlett-packard-tx2 b/keymap/keymaps/hewlett-packard-tx2 new file mode 100644 index 0000000..206c004 --- /dev/null +++ b/keymap/keymaps/hewlett-packard-tx2 @@ -0,0 +1,3 @@ +0xC2 media +0xD8 f22 # Toggle touchpad button on tx2 (OFF) +0xD9 f22 # Toggle touchpad button on tx2 (ON) diff --git a/keymap/keymaps/lenovo-thinkpad_x200_tablet b/keymap/keymaps/lenovo-thinkpad_x200_tablet new file mode 100644 index 0000000..31ea3b2 --- /dev/null +++ b/keymap/keymaps/lenovo-thinkpad_x200_tablet @@ -0,0 +1,6 @@ +0x5D menu +0x63 fn +0x66 screenlock +0x67 cyclewindows # bezel circular arrow +0x68 setup # bezel setup / menu +0x6c direction # rotate screen |