summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2004-01-25 17:23:20 +0000
committerLennart Poettering <lennart@poettering.net>2004-01-25 17:23:20 +0000
commitef3bc3e3aa0b9bf5129bdedf05402f289d768373 (patch)
tree893eb3a1766bc308988bcfaf42bd4929f8f66d56 /src
parent51964b41b60bd6e20b94abca8987b2a73b9251f6 (diff)
initial commit
git-svn-id: file:///home/lennart/svn/public/keyfuzz/trunk@3 e03e4fad-c0d1-0310-aabf-8987f8117c4c
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am37
-rw-r--r--src/keyfuzz.c220
-rw-r--r--src/keyfuzz.ggo7
3 files changed, 264 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..c0b154a
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,37 @@
+# $Id$
+#
+# This file is part of keyfuzz.
+#
+# keyfuzz 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.
+#
+# keyfuzz 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 keyfuzz; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+sbin_PROGRAMS = keyfuzz
+
+keyfuzz_SOURCES = keyfuzz.c cmdline.c cmdline.h
+keyfuzz_CFLAGS = $(AM_CFLAGS) -DPKGSYSCONFDIR="\"${sysconfdir}/@PACKAGE@\""
+
+EXTRA_DIST = keyfuzz.ggo
+MAINTAINERCLEANFILES =
+BUILT_SOURCES =
+CLEANFILES =
+
+if USE_GENGETOPT
+
+CLEANFILES += cmdline.c cmdline.h
+BUILT_SOURCES += cmdline.c cmdline.h
+
+cmdline.c cmdline.h: keyfuzz.ggo Makefile
+ gengetopt < $<
+
+endif
diff --git a/src/keyfuzz.c b/src/keyfuzz.c
new file mode 100644
index 0000000..e2857ba
--- /dev/null
+++ b/src/keyfuzz.c
@@ -0,0 +1,220 @@
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/input.h>
+
+#include "cmdline.h"
+
+#define MAX_SCANCODES 1024
+
+static struct gengetopt_args_info args;
+
+int evdev_open(const char *dev) {
+ int fd;
+ char fn[PATH_MAX];
+
+ if (!strchr(dev, '/')) {
+ snprintf(fn, sizeof(fn), "/dev/input/%s", dev);
+ dev = fn;
+ }
+
+ if ((fd = open(dev, O_RDWR)) < 0) {
+ fprintf(stderr, "open('%s'): %s\n", dev, strerror(errno));
+ return -1;
+ }
+
+ return fd;
+}
+
+int evdev_driver_version(int fd, char *v, size_t l) {
+ int version;
+
+ if (ioctl(fd, EVIOCGVERSION, &version)) {
+ fprintf(stderr, "EVIOCGVERSION: %s\n", strerror(errno));
+ return -1;
+ }
+
+ snprintf(v, l,
+ "%i.%i.%i.",
+ version >> 16,
+ (version >> 8) & 0xff,
+ version & 0xff);
+
+ return 0;
+}
+
+int evdev_device_name(int fd, char *n, size_t l) {
+
+ if (ioctl(fd, EVIOCGNAME(l), n) < 0) {
+ fprintf(stderr, "EVIOCGNAME: %s\n", strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+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: %s\n", strerror(errno));
+ return -1;
+ }
+ }
+
+ return codes[1];
+}
+
+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: %s\n", strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+int print_info(int fd) {
+ char version[256], name[256];
+ int 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 driver version %s\n"
+ "device name: %s\n",
+ version, name);
+
+ r = 0;
+
+fail:
+ return r;
+}
+
+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;
+ }
+
+ printf("0x%03x\t0x%03x\n", scancode, keycode);
+ }
+
+ if (!r)
+ printf("### EOF\n");
+
+fail:
+ return r;
+}
+
+int merge_table(int fd) {
+ int r = -1;
+ int line = 0;
+
+ while (!feof(stdin)) {
+ char s[256], *p;
+ int scancode, new_keycode, old_keycode;
+
+ if (!fgets(s, sizeof(s), stdin))
+ break;
+
+ line++;
+
+ p = s+strspn(s, "\t ");
+
+ if (*p == '#' || *p == '\n')
+ continue;
+
+ if (sscanf(p, "%i %i", &scancode, &new_keycode) != 2) {
+ fprintf(stderr, "Parse failure at line %i\n", line);
+ goto fail;
+ }
+
+ if ((old_keycode = evdev_get_keycode(fd, scancode, 0)) < 0)
+ goto fail;
+
+ if (evdev_set_keycode(fd, scancode, new_keycode) < 0)
+ goto fail;
+
+ if (args.verbose_flag && new_keycode != old_keycode)
+ fprintf(stderr, "Remapped scancode 0x%02x to 0x%02x. (prior: 0x%02x)\n", scancode, new_keycode, old_keycode);
+ }
+
+ r = 0;
+
+fail:
+
+ return r;
+}
+
+int main(int argc, char *argv[]) {
+ int fd = -1, r = 1;
+
+ cmdline_parser(argc, argv, &args);
+
+ if (!args.get_flag && !args.set_flag && !args.info_flag) {
+ cmdline_parser_print_help();
+ goto fail;
+ }
+
+ if ((fd = evdev_open(args.device_arg ? args.device_arg : "event0")) < 0)
+ goto fail;
+
+ if (args.get_flag) {
+
+ if (dump_table(fd) < 0)
+ goto fail;
+
+ } else if (args.set_flag) {
+
+ if (merge_table(fd) < 0)
+ goto fail;
+
+ } else if (args.info_flag) {
+
+ if (print_info(fd) < 0)
+ goto fail;
+ }
+
+ r = 0;
+
+fail:
+ if (fd >= 0)
+ close(fd);
+
+ return r;
+}
diff --git a/src/keyfuzz.ggo b/src/keyfuzz.ggo
new file mode 100644
index 0000000..8e66e1c
--- /dev/null
+++ b/src/keyfuzz.ggo
@@ -0,0 +1,7 @@
+purpose "Linux input layer scancode remapper"
+
+option "set" s "Set/merge the maping table" flag off
+option "get" g "Get the key mapping table" flag off
+option "info" i "Show driver information" flag off
+option "device" d "Specify the device to use" string no
+option "verbose" v "Enable verbose mode" flag off