keymap: move from udev-extras

This commit is contained in:
Martin Pitt 2009-06-17 11:56:52 +02:00 committed by Kay Sievers
parent a8aab0e95b
commit 2417dc20f5
49 changed files with 944 additions and 0 deletions

View File

@ -7,6 +7,7 @@ dnl AM_SILENT_RULES
AC_SYS_LARGEFILE
AC_CONFIG_MACRO_DIR([m4])
AC_PROG_LIBTOOL
AC_PROG_AWK
GTK_DOC_CHECK(1.10)
AC_PREFIX_DEFAULT([/usr])
AC_PATH_PROG([XSLTPROC], [xsltproc])
@ -49,6 +50,8 @@ AC_ARG_ENABLE([extras],
AS_HELP_STRING([--disable-extras], [disable extras with external dependencies]),
[], [enable_extras=yes])
if test "x$enable_extras" = xyes; then
AC_PATH_PROG([GPERF], [gperf])
PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.7.0 gobject-2.0 >= 2.7.0])
AC_SUBST([GLIB_CFLAGS])
AC_SUBST([GLIB_LIBS])
@ -121,6 +124,7 @@ AC_CONFIG_FILES([
extras/gudev/gudev-1.0.pc
extras/gudev/docs/Makefile
extras/gudev/docs/version.xml
extras/keymap/Makefile
])
AC_OUTPUT
@ -154,4 +158,5 @@ AC_MSG_RESULT([
pci.ids: ${PCI_DATABASE}
xsltproc: ${XSLTPROC}
gperf: ${GPERF}
])

View File

@ -19,5 +19,6 @@ SUBDIRS += \
udev-acl \
usb-db \
hid2hci \
keymap \
gudev
endif

6
extras/keymap/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
keymap
keys-from-name.gperf
keys-from-name.h
keys-to-name.h
keys.txt

View File

@ -0,0 +1,79 @@
ACTION!="add", GOTO="keyboard_end"
SUBSYSTEM!="input", GOTO="keyboard_end"
KERNEL!="event*", GOTO="keyboard_end"
ENV{DMI_VENDOR}="$attr{[dmi/id]sys_vendor}"
ENV{DMI_VENDOR}=="", GOTO="keyboard_end"
#
# The following are exposed as separate input devices with low key codes, thus
# we need to check their input device product name
#
ENV{DMI_VENDOR}=="IBM*", KERNELS=="input*", ATTRS{name}=="ThinkPad Extra Buttons", RUN+="keymap $name module-ibm"
ENV{DMI_VENDOR}=="LENOVO*", KERNELS=="input*", ATTRS{name}=="ThinkPad Extra Buttons", RUN+="keymap $name module-lenovo"
ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Asus Extra Buttons", ATTR{[dmi/id]product_name}=="W3J", RUN+="keymap $name module-asus-w3j"
ENV{DMI_VENDOR}=="Sony*", KERNELS=="input*", ATTRS{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony"
# Older Vaios have some different keys
ENV{DMI_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*", ATTRS{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony-old"
#
# The following rules belong to standard i8042 AT keyboard with high key codes.
#
DRIVERS=="atkbd", GOTO="keyboard_vendorcheck"
GOTO="keyboard_end"
LABEL="keyboard_vendorcheck"
ENV{DMI_VENDOR}=="Dell*", RUN+="keymap $name dell"
ENV{DMI_VENDOR}=="Compaq*", ATTR{[dmi/id]product_name}=="*E500*|*Evo N610c*|*Evo N600c*", RUN+="keymap $name compaq-e_evo"
ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="*3000*", RUN+="keymap $name lenovo-3000"
ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="ThinkPad X6*", ATTR{[dmi/id]product_version}=="* Tablet" RUN+="keymap $name lenovo-thinkpad_x6_tablet"
ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="ThinkPad X200 Tablet*", ATTR{[dmi/id]product_version}=="* Tablet" RUN+="keymap $name lenovo-thinkpad_x200_tablet"
ENV{DMI_VENDOR}=="Hewlett-Packard*", RUN+="keymap $name hewlett-packard"
ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[tT][aA][bB][lL][eE][tT]*", RUN+="keymap $name hewlett-packard-tablet"
ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[pP][aA][vV][iI][lL][iI][oO][nN]*", RUN+="keymap $name hewlett-packard-pavilion"
ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*Compaq*|*EliteBook*", RUN+="keymap $name hewlett-packard-compaq_elitebook"
ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*2510p*|*2530p*", RUN+="keymap $name hewlett-packard-2510p_2530p"
ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[tT][xX]2*", RUN+="keymap $name hewlett-packard-tx2"
ENV{DMI_VENDOR}=="Acer*", RUN+="keymap $name acer"
ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Extensa*", ATTR{[dmi/id]product_name}=="*5210*|*5220*|*5610*|*5620*|*5720*", RUN+="keymap $name acer-extensa_5xxx"
ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="TravelMate*C300*", RUN+="keymap $name acer-travelmate_c300"
ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="TravelMate*6292*", RUN+="keymap $name acer-travelmate_6292"
ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Aspire 5920G", RUN+="keymap $name acer-aspire_5920g"
ENV{DMI_VENDOR}=="*BenQ*", ATTR{[dmi/id]product_name}=="*Joybook R22*", RUN+="keymap $name benq-joybook_r22"
ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*AMILO Pro V3205*", RUN+="keymap $name fujitsu-amilo_pro_v3205"
ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*AMILO Pa 2548*", RUN+="keymap $name fujitsu-amilo_pa_2548"
ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*ESPRIMO Mobile V5*", RUN+="keymap $name fujitsu-esprimo_mobile_v5"
ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*ESPRIMO Mobile V6*", RUN+="keymap $name fujitsu-esprimo_mobile_v6"
ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*AMILO Pro Edition V3505*", RUN+="keymap $name fujitsu-amilo_pro_edition_v3505"
ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*Amilo Si 1520*", RUN+="keymap $name fujitsu-amilo_si_1520"
ENV{DMI_VENDOR}=="MEDION*", ATTR{[dmi/id]product_name}=="*FID2060*", RUN+="keymap $name medion-fid2060"
ENV{DMI_VENDOR}=="MEDIONNB", ATTR{[dmi/id]product_name}=="A555*", RUN+="keymap $name medionnb-a555"
ENV{DMI_VENDOR}=="MICRO-STAR*", RUN+="keymap $name micro-star"
ENV{DMI_VENDOR}=="INVENTEC", ATTR{[dmi/id]product_name}=="SYMPHONY 6.0/7.0", RUN+="keymap $name inventec-symphony_6.0_7.0"
ENV{DMI_VENDOR}=="MAXDATA", ATTR{[dmi/id]product_name}=="Pro 7000*", RUN+="keymap $name maxdata-pro_7000"
ENV{DMI_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*|*R560*", RUN+="keymap $name samsung-other"
ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*SX20S*", RUN+="keymap $name samsung-sx20s"
ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="SQ1US", RUN+="keymap $name samsung-sq1us"
ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="SATELLITE A100", RUN+="keymap $name toshiba-satellite_a100"
ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="Satellite A110", RUN+="keymap $name toshiba-satellite_a110"
ENV{DMI_VENDOR}=="OQO Inc.*", ATTR{[dmi/id]product_name}=="OQO Model 2*", RUN+="keymap $name oqo-model2"
ENV{DMI_VENDOR}=="ASUS", RUN+="keymap $name asus"
LABEL="keyboard_end"

94
extras/keymap/Makefile.am Normal file
View File

@ -0,0 +1,94 @@
# keymap 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.
#
# keymap 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.
#
# You should have received a copy of the GNU General Public License
# along with keymap; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
include $(top_srcdir)/Makefile.am.inc
# rules and keymaps
dist_udevrules_DATA = 95-keymap.rules
udevkeymapdir = $(libexecdir)/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
libexec_PROGRAMS = keymap
keymap_SOURCES = keymap.c
nodist_keymap_SOURCES = keys-from-name.h keys-to-name.h
keymap_CPPFLAGS = $(AM_CPPFLAGS)
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
#
# generation of keys-{from,to}-name.h from linux/input.h and gperf
#
keys.txt: /usr/include/linux/input.h
$(AWK) '/^#define.*KEY_/ { if ($$2 != "KEY_MAX" && $$2 != "KEY_CNT") { print $$2 } }' < $< > $@
keys-from-name.gperf: keys.txt
$(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_CNT] = { "} { print "[" $$1 "] = \"" $$1 "\"," } END{print "};"}' < $< > $@

View File

@ -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 /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>.

30
extras/keymap/check-keymaps.sh Executable file
View File

@ -0,0 +1,30 @@
#!/bin/bash
# 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
exit 1
}
missing=$(join -v 2 <(awk '{print tolower(substr($1,5))}' $KEYLIST | sort -u) <(awk '{print $2}' keymaps/*|sort -u))
[ -z "$missing" ] || {
echo "ERROR: unknown key names in keymaps/*:" >&2
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

45
extras/keymap/findkeyboards Executable file
View File

@ -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

324
extras/keymap/keymap.c Normal file
View File

@ -0,0 +1,324 @@
/*
* keymap - dump keymap of an evdev device or set a new keymap from a file
*
* Based on keyfuzz by Lennart Poettering <mzqrovna@0pointer.net>
* Adapted for udev-extras by Martin Pitt <martin.pitt@ubuntu.com>
*
* Copyright (C) 2006, Lennart Poettering
* Copyright (C) 2009, Canonical Ltd.
*
* keymap 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.
*
* keymap 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.
*
* You should have received a copy of the GNU General Public License
* along with keymap; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <fcntl.h>
#include <getopt.h>
#include <sys/ioctl.h>
#include <linux/input.h>
const struct key* lookup_key (const char *str, unsigned int len);
#include "keys-from-name.h"
#include "keys-to-name.h"
#define MAX_SCANCODES 1024
/* If keymap file is given without a path, assume this one; must end with '/' * */
#define DEFAULT_PATH "/lib/udev/keymaps/"
static int evdev_open(const char *dev)
{
int fd;
char fn[PATH_MAX];
if (strncmp(dev, "/dev", 4) != 0) {
snprintf(fn, sizeof(fn), "/dev/%s", dev);
dev = fn;
}
if ((fd = open(dev, O_RDWR)) < 0) {
fprintf(stderr, "error open('%s'): %m\n", dev);
return -1;
}
return fd;
}
static int evdev_get_keycode(int fd, int scancode, int e)
{
int codes[2];
codes[0] = scancode;
if (ioctl(fd, EVIOCGKEYCODE, codes) < 0) {
if (e && errno == EINVAL) {
return -2;
} else {
fprintf(stderr, "EVIOCGKEYCODE: %m\n");
return -1;
}
}
return codes[1];
}
static int evdev_set_keycode(int fd, int scancode, int keycode)
{
int codes[2];
codes[0] = scancode;
codes[1] = keycode;
if (ioctl(fd, EVIOCSKEYCODE, codes) < 0) {
fprintf(stderr, "EVIOCSKEYCODE: %m\n");
return -1;
}
return 0;
}
static int evdev_driver_version(int fd, char *v, size_t l)
{
int version;
if (ioctl(fd, EVIOCGVERSION, &version)) {
fprintf(stderr, "EVIOCGVERSION: %m\n");
return -1;
}
snprintf(v, l, "%i.%i.%i.", version >> 16, (version >> 8) & 0xff, version & 0xff);
return 0;
}
static int evdev_device_name(int fd, char *n, size_t l)
{
if (ioctl(fd, EVIOCGNAME(l), n) < 0) {
fprintf(stderr, "EVIOCGNAME: %m\n");
return -1;
}
return 0;
}
/* Return a lower-case string with KEY_ prefix removed */
static const char* format_keyname(const char* key) {
static char result[101];
const char* s;
int len;
for (s = key+4, len = 0; *s && len < 100; ++len, ++s)
result[len] = tolower(*s);
result[len] = '\0';
return result;
}
static int dump_table(int fd) {
char version[256], name[256];
int scancode, r = -1;
if (evdev_driver_version(fd, version, sizeof(version)) < 0)
goto fail;
if (evdev_device_name(fd, name, sizeof(name)) < 0)
goto fail;
printf("### evdev %s, driver '%s'\n", version, name);
r = 0;
for (scancode = 0; scancode < MAX_SCANCODES; scancode++) {
int keycode;
if ((keycode = evdev_get_keycode(fd, scancode, 1)) < 0) {
if (keycode != -2)
r = -1;
break;
}
if (keycode < KEY_MAX && key_names[keycode])
printf("0x%03x %s\n", scancode, format_keyname(key_names[keycode]));
else
printf("0x%03x 0x%03x\n", scancode, keycode);
}
fail:
return r;
}
static int merge_table(int fd, const char *filename) {
int r = 0;
int line = 0;
FILE* f;
f = fopen(filename, "r");
if (!f) {
perror(filename);
r = -1;
goto fail;
}
while (!feof(f)) {
char s[256], *p;
int scancode, new_keycode, old_keycode;
if (!fgets(s, sizeof(s), f))
break;
line++;
p = s+strspn(s, "\t ");
if (*p == '#' || *p == '\n')
continue;
if (sscanf(p, "%i %i", &scancode, &new_keycode) != 2) {
char t[105] = "KEY_UNKNOWN";
const struct key *k;
if (sscanf(p, "%i %100s", &scancode, t+4) != 2) {
fprintf(stderr, "WARNING: Parse failure at line %i, ignoring.\n", line);
r = -1;
continue;
}
if (!(k = lookup_key(t, strlen(t)))) {
fprintf(stderr, "WARNING: Unknown key '%s' at line %i, ignoring.\n", t, line);
r = -1;
continue;
}
new_keycode = k->id;
}
if ((old_keycode = evdev_get_keycode(fd, scancode, 0)) < 0) {
r = -1;
goto fail;
}
if (evdev_set_keycode(fd, scancode, new_keycode) < 0) {
r = -1;
goto fail;
}
if (new_keycode != old_keycode)
fprintf(stderr, "Remapped scancode 0x%02x to 0x%02x (prior: 0x%02x)\n",
scancode, new_keycode, old_keycode);
}
fail:
return r;
}
static const char* default_keymap_path(const char* path)
{
static char result[PATH_MAX];
if (!strchr(path, '/')) {
snprintf(result, sizeof(result), "%s%s", DEFAULT_PATH, path);
return result;
}
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, "hi", options, NULL);
if (option == -1)
break;
switch (option) {
case 'h':
printf("Usage: keymap <event device> [<map file>]\n\n");
return 0;
case 'i':
opt_interactive = 1;
break;
default:
return 1;
}
}
if (argc < optind+1 || argc > optind+2) {
fprintf(stderr, "Usage: keymap <event device> [<map file>]\n\n");
return 2;
}
if ((fd = evdev_open(argv[optind])) < 0)
return 3;
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;
}

View File

@ -0,0 +1,22 @@
0xA5 help # Fn+F1
0xA6 setup # Fn+F2 Acer eSettings
0xA7 battery # Fn+F3 Power Management
0xA9 switchvideomode # Fn+F5
0xB3 euro
0xB4 dollar
0xCE brightnessup # Fn+Right
0xD4 bluetooth # (toggle) off-to-on
0xD5 wlan # (toggle) on-to-off
0xD6 wlan # (toggle) off-to-on
0xD7 bluetooth # (toggle) on-to-off
0xD8 bluetooth # (toggle) off-to-on
0xD9 brightnessup # Fn+Right
0xEE brightnessup # Fn+Right
0xEF brightnessdown # Fn+Left
0xF1 f22 # Fn+F7 Touchpad toggle (off-to-on)
0xF2 f22 # Fn+F7 Touchpad toggle (on-to-off)
0xF3 prog2 # "P2" programmable button
0xF4 prog1 # "P1" programmable button
0xF5 presentation
0xF8 fn
0xF9 f23 # Launch NTI shadow

View File

@ -0,0 +1,4 @@
0x8A media
0xB2 www
0x92 prog2
0xD9 bluetooth # (toggle) on-to-off

View File

@ -0,0 +1 @@
0xEE screenlock # Windows Lock function

View File

@ -0,0 +1 @@
0xD9 bluetooth # (toggle) on-to-off

View File

@ -0,0 +1,5 @@
0x67 f24 # FIXME: rotate screen
0x68 up
0x69 down
0x6B fn
0x6C screenlock # FIXME: lock tablet device/buttons

View File

@ -0,0 +1,3 @@
0xED volumeup
0xEE volumedown
0xEF mute

View File

@ -0,0 +1 @@
0x6E wlan # Fn+F1

View File

@ -0,0 +1,4 @@
0xA3 www # I key
0x9A search
0x9E email
0x9F homepage

View File

@ -0,0 +1,27 @@
0x81 playpause # Play/Pause
0x82 stopcd # Stop
0x83 previoussong # Previous song
0x84 nextsong # Next song
0x85 brightnessdown # Fn+Down arrow Brightness Down
0x86 brightnessup # Fn+Up arrow Brightness Up
0x87 battery # Fn+F3 battery icon
0x88 wlan # Fn+F2 Turn On/Off Wireless
0x89 ejectclosecd # Fn+F10 Eject CD
0x8A suspend # Fn+F1 hibernate
0x8B switchvideomode # Fn+F8 CRT/LCD (high keycode: "displaytoggle")
0x8C f23 # Fn+Right arrow Auto Brightness
0x8F switchvideomode # Fn+F7 aspect ratio
0x90 previoussong # Front panel previous song
0x91 prog1 # Wifi Catcher (DELL Specific)
0x92 media # MediaDirect button (house icon)
0x93 f23 # FIXME Fn+Left arrow Auto Brightness
0x95 camera # Shutter button Takes a picture if optional camera available
0x97 email # Tablet email button
0x98 f21 # FIXME: Tablet screen rotatation
0x99 nextsong # Front panel next song
0x9A setup # Tablet tools button
0x9B switchvideomode # Display Toggle button
0xA2 playpause # Front panel play/pause
0xA4 stopcd # Front panel stop
0xD8 screenlock # FIXME: Tablet lock button
0xED media # MediaDirect button

View File

@ -0,0 +1,3 @@
0xE0 volumedown
0xE1 volumeup
0xE5 prog1

View File

@ -0,0 +1,4 @@
0xA5 help # Fn-F1
0xA9 switchvideomode # Fn-F3
0xD9 brightnessdown # Fn-F8
0xE0 brightnessup # Fn-F9

View File

@ -0,0 +1,2 @@
0xF4 f21 # FIXME: silent-mode decrease CPU/GPU clock
0xF7 switchvideomode # Fn+F3

View File

@ -0,0 +1,6 @@
0xE1 wlan
0xF3 wlan
0xEE brightnessdown
0xE0 brightnessup
0xE2 bluetooth
0xF7 video

View File

@ -0,0 +1,4 @@
0xA9 switchvideomode
0xD9 brightnessdown
0xDF sleep
0xEF brightnessup

View File

@ -0,0 +1,2 @@
0xCE brightnessup
0xEF brightnessdown

View File

@ -0,0 +1,12 @@
0x81 fn_esc
0x89 battery # FnF8
0x8A screenlock # FnF6
0x8B camera
0x8C media # music
0x8E dvd
0xB1 help
0xB3 f23 # FIXME: Auto brightness
0xD7 wlan
0x92 brightnessdown # FnF7 (FnF9 on 6730b)
0x97 brightnessup # FnF8 (FnF10 on 6730b)
0xEE switchvideomode # FnF4

View File

@ -0,0 +1,2 @@
0xD8 f22 # touchpad off
0xD9 f23 # touchpad on

View File

@ -0,0 +1,2 @@
0x88 presentation
0xD9 help # I key (high keycode: "info")

View File

@ -0,0 +1,3 @@
0x88 media # FIXME: quick play
0xD8 f22 # touchpad off
0xD9 f23 # touchpad on

View File

@ -0,0 +1,6 @@
0x82 prog2 # Funny Key
0x83 prog1 # Q
0x84 tab
0x85 esc
0x86 pageup
0x87 pagedown

View File

@ -0,0 +1,3 @@
0xC2 media
0xD8 f22 # Toggle touchpad button on tx2 (OFF)
0xD9 f22 # Toggle touchpad button on tx2 (ON)

View File

@ -0,0 +1,2 @@
0xF3 prog2
0xF4 prog1

View File

@ -0,0 +1,5 @@
0x8B switchvideomode # Fn+F7 video
0x96 wlan # Fn+F5 wireless
0x97 sleep # Fn+F4 suspend
0x98 suspend # Fn+F12 hibernate
0xB4 prog1 # Lenovo Care

View File

@ -0,0 +1,6 @@
0x5D menu
0x63 fn
0x66 screenlock
0x67 cyclewindows # bezel circular arrow
0x68 setup # bezel setup / menu
0x6c direction # rotate screen

View File

@ -0,0 +1,8 @@
0x6C f21 # rotate
0x68 screenlock # screenlock
0x6B esc # escape
0x6D right # right on d-pad
0x6E left # left on d-pad
0x71 up # up on d-pad
0x6F down # down on d-pad
0x69 enter # enter on d-pad

View File

@ -0,0 +1,9 @@
0x97 prog2
0x9F prog1
0xA0 mute # Fn-F5
0x82 www
0xEC email
0xAE volumedown # Fn-Down
0xB0 volumeup # Fn-Up
0xDF suspend # Fn+F2
0xF5 help

View File

@ -0,0 +1,2 @@
0x6B channeldown # Thottle Down
0x6D channelup # Thottle Up

View File

@ -0,0 +1,4 @@
0x63 www # N button
0x66 prog1 # link 1 button
0x67 email # envelope button
0x69 prog2 # link 2 button

View File

@ -0,0 +1,12 @@
0xA0 mute # Fn-F9
0xAE volumedown # Fn-F7
0xB0 volumeup # Fn-F8
0xB2 www # e button
0xDF sleep # Fn-F12
0xE2 bluetooth # satellite dish2
0xE4 f22 # Fn-F3 Touchpad disable
0xEC email # envelope button
0xF6 wlan # satellite dish1
0xF7 brightnessdown # Fn-F4
0xF8 brightnessup # Fn-F5
0xF9 search

View File

@ -0,0 +1,11 @@
0x41 nextsong
0x45 playpause
0x43 stopcd
0x40 previoussong
0x4C ejectclosecd
0x32 mute
0x31 volumedown
0x30 volumeup
0x5D wlan
0x7E bluetooth
0x8A media # high keycode: "tv"

View File

@ -0,0 +1,16 @@
0x01 battery # Fn+F2
0x02 screenlock # Fn+F3
0x03 sleep # Fn+F4
0x04 radio # Fn+F5
0x06 switchvideomode # Fn+F7
0x07 zoom # Fn+F8 screen expand
0x08 f24 # Fn+F9 undock
0x0B suspend # Fn+F12
0x0F brightnessup # Fn+Home
0x10 brightnessdown # Fn+End
0x11 kbdillumtoggle # Fn+PgUp - ThinkLight
0x13 zoom # Fn+Space
0x14 volumeup
0x15 volumedown
0x16 mute
0x17 prog1 # ThinkPad/ThinkVantage button (high keycode: "vendor")

View File

@ -0,0 +1,16 @@
0x1 screenlock # Fn+F2
0x2 battery # Fn+F3
0x3 sleep # Fn+F4
0x4 radio # Fn+F5
0x6 switchvideomode # Fn+F7
0x7 f22 # Fn+F8 touchpadtoggle
0x8 f24 # Fn+F9 undock
0xB suspend # Fn+F12
0xF brightnessup # Fn+Home
0x10 brightnessdown # Fn+End
0x11 kbdillumtoggle # Fn+PgUp - ThinkLight
0x13 zoom # Fn+Space
0x14 volumeup
0x15 volumedown
0x16 mute
0x17 prog1 # ThinkPad/ThinkVantage button (high keycode: "vendor")

View File

@ -0,0 +1,8 @@
0x06 mute # Fn+F2
0x07 volumedown # Fn+F3
0x08 volumeup # Fn+F4
0x09 brightnessdown # Fn+F5
0x0A brightnessup # Fn+F6
0x0B switchvideomode # Fn+F7
0x0E zoom # Fn+F10
0x10 suspend # Fn+F12

View File

@ -0,0 +1,2 @@
0x06 battery
0x07 mute

View File

@ -0,0 +1,5 @@
0x8E wlan
0xF0 switchvideomode
0xF1 mute
0xF2 volumedown
0xF3 volumeup

View File

@ -0,0 +1,14 @@
0x74 prog1 # User key
0x75 www
0x78 mail
0x82 switchvideomode # Fn+F4 CRT/LCD (high keycode: "displaytoggle")
0x83 battery # Fn+F2
0x84 prog1 # Fn+F5 backlight on/off
0x86 wlan # Fn+F9
0x88 brightnessup # Fn-Up
0x89 brightnessdown # Fn-Down
0xB1 prog2 # Fn+F7 run Samsung Magic Doctor (keypressed event is generated twice)
0xB3 prog3 # Fn+F8 switch power mode (battery/dynamic/performance)
0xB4 wlan # Fn+F9 (X60P)
0xF7 f22 # Fn+F10 Touchpad on
0xF9 f22 # Fn+F10 Touchpad off

View File

@ -0,0 +1,7 @@
0xD4 menu
0xD8 f1
0xD9 f10
0xD6 f3
0xD7 f9
0xE4 f5
0xEE f11

View File

@ -0,0 +1,4 @@
0x74 mute
0x75 mute
0x77 f21 # FIXME: Touchpad on
0x79 f21 # FIXME: Touchpad off

View File

@ -0,0 +1,2 @@
0xA4 stopcd
0xB2 www

View File

@ -0,0 +1,10 @@
0x92 stop
0x93 www
0x94 media
0x9E f21 # FIXME: Touchpad on
0x9F f21 # FIXME: Touchpad off
0xB9 nextsong
0xD9 brightnessup
0xEE screenlock
0xF4 previoussong
0xF7 playpause