chiark / gitweb /
switch from udev keymaps to hwdb
[elogind.git] / src / udev / keymap / keymap.c
diff --git a/src/udev/keymap/keymap.c b/src/udev/keymap/keymap.c
deleted file mode 100644 (file)
index ae0a19d..0000000
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * 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.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.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/limits.h>
-#include <linux/input.h>
-
-static const struct key* lookup_key (const char *str, unsigned int len);
-
-#include "keys-from-name.h"
-#include "keys-to-name.h"
-#include "macro.h"
-#include "util.h"
-
-#define MAX_SCANCODES 1024
-
-static int evdev_open(const char *dev)
-{
-        int fd;
-        char fn[PATH_MAX];
-
-        if (!startswith(dev, "/dev")) {
-                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, unsigned scancode, int e)
-{
-        unsigned codes[2];
-
-        codes[0] = scancode;
-        if (ioctl(fd, EVIOCGKEYCODE, codes) < 0) {
-                if (e && errno == EINVAL) {
-                        return -2;
-                } else {
-                        fprintf(stderr, "EVIOCGKEYCODE for scan code 0x%x: %m\n", scancode);
-                        return -1;
-                }
-        }
-        return codes[1];
-}
-
-static int evdev_set_keycode(int fd, unsigned scancode, int keycode)
-{
-        unsigned codes[2];
-
-        codes[0] = scancode;
-        codes[1] = (unsigned) 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];
-        unsigned scancode;
-        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 %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)
-                                continue;
-                        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 void set_key(int fd, const char* scancode_str, const char* keyname)
-{
-        unsigned scancode;
-        char *endptr;
-        char t[105] = "KEY_UNKNOWN";
-        const struct key *k;
-
-        scancode = (unsigned) strtol(scancode_str, &endptr, 0);
-        if (*endptr != '\0') {
-                fprintf(stderr, "ERROR: Invalid scancode\n");
-                exit(1);
-        }
-
-        snprintf(t, sizeof(t), "KEY_%s", keyname);
-
-        if (!(k = lookup_key(t, strlen(t)))) {
-                fprintf(stderr, "ERROR: Unknown key name '%s'\n", keyname);
-                exit(1);
-        }
-
-        if (evdev_set_keycode(fd, scancode, k->id) < 0)
-                fprintf(stderr, "setting scancode 0x%2X to key code %i failed\n",
-                        scancode, k->id);
-        else
-                printf("setting scancode 0x%2X to key code %i\n",
-                        scancode, k->id);
-}
-
-static int merge_table(int fd, FILE *f) {
-        int r = 0;
-        int line = 0;
-
-        while (!feof(f)) {
-                char s[256], *p;
-                unsigned scancode;
-                int 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;
-                        continue;
-                }
-
-                if (evdev_set_keycode(fd, scancode, new_keycode) < 0) {
-                        r = -1;
-                        continue;
-                }
-
-                if (new_keycode != old_keycode)
-                        fprintf(stderr, "Remapped scancode 0x%02x to 0x%02x (prior: 0x%02x)\n",
-                                scancode, new_keycode, old_keycode);
-        }
-
-        fclose(f);
-        return r;
-}
-
-
-/* read one event; return 1 if valid */
-static int read_event(int fd, struct input_event* ev)
-{
-        int ret;
-        ret = read(fd, ev, sizeof(struct input_event));
-
-        if (ret < 0) {
-                perror("read");
-                return 0;
-        }
-        if (ret != sizeof(struct input_event)) {
-                fprintf(stderr, "did not get enough data for event struct, aborting\n");
-                return 0;
-        }
-
-        return 1;
-}
-
-static void print_key(unsigned scancode, uint16_t keycode, int has_scan, int has_key)
-{
-        const char *keyname;
-
-        /* ignore key release events */
-        if (has_key == 1)
-                return;
-
-        if (has_key == 0 && has_scan != 0) {
-                fprintf(stderr, "got scan code event 0x%02X without a key code event\n",
-                        scancode);
-                return;
-        }
-
-        if (has_scan != 0)
-                printf("scan code: 0x%02X   ", scancode);
-        else
-                printf("(no scan code received)  ");
-
-        keyname = key_names[keycode];
-        if (keyname != NULL)
-                printf("key code: %s\n", format_keyname(keyname));
-        else
-                printf("key code: %03X\n", keycode);
-}
-
-static void interactive(int fd)
-{
-        struct input_event ev;
-        unsigned last_scan = 0;
-        uint16_t last_key = 0;
-        int has_scan; /* boolean */
-        int has_key; /* 0: none, 1: release, 2: press */
-
-        /* grab input device */
-        ioctl(fd, EVIOCGRAB, 1);
-        puts("Press ESC to finish, or Control-C if this device is not your primary keyboard");
-
-        has_scan = has_key = 0;
-        while (read_event(fd, &ev)) {
-                /* Drivers usually send the scan code first, then the key code,
-                 * then a SYN. Some drivers (like thinkpad_acpi) send the key
-                 * code first, and some drivers might not send SYN events, so
-                 * keep a robust state machine which can deal with any of those
-                 */
-
-                if (ev.type == EV_MSC && ev.code == MSC_SCAN) {
-                        if (has_scan) {
-                                fputs("driver did not send SYN event in between key events; previous event:\n",
-                                      stderr);
-                                print_key(last_scan, last_key, has_scan, has_key);
-                                has_key = 0;
-                        }
-
-                        last_scan = ev.value;
-                        has_scan = 1;
-                        /*printf("--- got scan %u; has scan %i key %i\n", last_scan, has_scan, has_key); */
-                }
-                else if (ev.type == EV_KEY) {
-                        if (has_key) {
-                                fputs("driver did not send SYN event in between key events; previous event:\n",
-                                      stderr);
-                                print_key(last_scan, last_key, has_scan, has_key);
-                                has_scan = 0;
-                        }
-
-                        last_key = ev.code;
-                        has_key = 1 + ev.value;
-                        /*printf("--- got key %hu; has scan %i key %i\n", last_key, has_scan, has_key);*/
-
-                        /* Stop on ESC */
-                        if (ev.code == KEY_ESC && ev.value == 0)
-                                break;
-                }
-                else if (ev.type == EV_SYN) {
-                        /*printf("--- got SYN; has scan %i key %i\n", has_scan, has_key);*/
-                        print_key(last_scan, last_key, has_scan, has_key);
-
-                        has_scan = has_key = 0;
-                }
-
-        }
-
-        /* release input device */
-        ioctl(fd, EVIOCGRAB, 0);
-}
-
-_noreturn_ static void help(int error)
-{
-        const char* h = "Usage: keymap <event device> [<map file>]\n"
-                        "       keymap <event device> scancode keyname [...]\n"
-                        "       keymap -i <event device>\n";
-        if (error) {
-                fputs(h, stderr);
-                exit(2);
-        } else {
-                fputs(h, stdout);
-                exit(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;
-        int i;
-
-        while (1) {
-                int option;
-
-                option = getopt_long(argc, argv, "hi", options, NULL);
-                if (option == -1)
-                        break;
-
-                switch (option) {
-                case 'h':
-                        help(0);
-
-                case 'i':
-                        opt_interactive = 1;
-                        break;
-                default:
-                        return 1;
-                }
-        }
-
-        if (argc < optind+1)
-                help (1);
-
-        if ((fd = evdev_open(argv[optind])) < 0)
-                return 3;
-
-        /* one argument (device): dump or interactive */
-        if (argc == optind+1) {
-                if (opt_interactive)
-                        interactive(fd);
-                else
-                        dump_table(fd);
-                return 0;
-        }
-
-        /* two arguments (device, mapfile): set map file */
-        if (argc == optind+2) {
-                const char *filearg = argv[optind+1];
-                if (strchr(filearg, '/')) {
-                        /* Keymap file argument is a path */
-                        FILE *f = fopen(filearg, "re");
-                        if (f)
-                                merge_table(fd, f);
-                        else
-                                perror(filearg);
-                } else {
-                        /* Keymap file argument is a filename */
-                        /* Open override file if present, otherwise default file */
-                        char keymap_path[PATH_MAX];
-                        FILE *f;
-
-                        snprintf(keymap_path, sizeof(keymap_path), "/etc/udev/keymaps/%s", filearg);
-                        f = fopen(keymap_path, "re");
-                        if (f) {
-                                merge_table(fd, f);
-                        } else {
-                                snprintf(keymap_path, sizeof(keymap_path), UDEVLIBEXECDIR "/keymaps/%s", filearg);
-                                f = fopen(keymap_path, "re");
-                                if (f)
-                                        merge_table(fd, f);
-                                else
-                                        perror(keymap_path);
-                        }
-                }
-                return 0;
-        }
-
-        /* more arguments (device, scancode/keyname pairs): set keys directly */
-        if ((argc - optind - 1) % 2 == 0) {
-                for (i = optind+1; i < argc; i += 2)
-                        set_key(fd, argv[i], argv[i+1]);
-                return 0;
-        }
-
-        /* invalid number of arguments */
-        help(1);
-        return 1; /* not reached */
-}