X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=extras%2Fkeymap%2Fkeymap.c;h=b565c33e2fa010180ad3543b1df8ad16ea90dd8f;hp=b708f38e7b838259a991dc9d78de720dbb2a28df;hb=11a421dab5ab4bf9b40464a64b81c9d5c282f414;hpb=d0d3183278f987e583dfb5cd8720930148ed26f3 diff --git a/extras/keymap/keymap.c b/extras/keymap/keymap.c index b708f38e7..b565c33e2 100644 --- a/extras/keymap/keymap.c +++ b/extras/keymap/keymap.c @@ -153,6 +153,34 @@ 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, const char *filename) { int r = 0; int line = 0; @@ -219,7 +247,7 @@ static const char* default_keymap_path(const char* path) { static char result[PATH_MAX]; - /* If keymap file is given without a path, assume udev diretory; must end with '/' * */ + /* If keymap file is given without a path, assume udev directory; must end with '/' * */ if (!strchr(path, '/')) { snprintf(result, sizeof(result), "%s%s", LIBEXECDIR "/keymaps/", path); return result; @@ -230,15 +258,22 @@ static const char* default_keymap_path(const char* path) static void print_key(struct input_event *event) { static int cur_scancode = 0; + const char *keyname; /* 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])); + if (event->type == EV_KEY && event->value) { + keyname = key_names[event->code]; + if (keyname != NULL) + printf("scan code: 0x%02X key code: %s\n", cur_scancode, + format_keyname(key_names[event->code])); + else + printf("scan code: 0x%02X key code: %03X\n", cur_scancode, + event->code); + } } static void interactive(int fd) @@ -272,6 +307,20 @@ static void interactive(int fd) ioctl(fd, EVIOCGRAB, 0); } +static void help(int error) +{ + const char* h = "Usage: keymap []\n" + " keymap scancode keyname [...]\n" + " keymap -i \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[] = { @@ -281,6 +330,7 @@ int main(int argc, char **argv) }; int fd = -1; int opt_interactive = 0; + int i; while (1) { int option; @@ -291,8 +341,7 @@ int main(int argc, char **argv) switch (option) { case 'h': - printf("Usage: keymap []\n\n"); - return 0; + help(0); case 'i': opt_interactive = 1; @@ -302,21 +351,35 @@ int main(int argc, char **argv) } } - if (argc < optind+1 || argc > optind+2) { - fprintf(stderr, "Usage: keymap []\n\n"); - return 2; - } + if (argc < optind+1) + help (1); if ((fd = evdev_open(argv[optind])) < 0) return 3; - if (argc == optind+2) - merge_table(fd, default_keymap_path(argv[optind+1])); - else { + /* one argument (device): dump or interactive */ + if (argc == optind+1) { if (opt_interactive) interactive(fd); else dump_table(fd); + return 0; } - return 0; + + /* two arguments (device, mapfile): set map file */ + if (argc == optind+2) { + merge_table(fd, default_keymap_path(argv[optind+1])); + 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 */ }