summaryrefslogtreecommitdiff
path: root/src/extras/keymap/keymap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/extras/keymap/keymap.c')
-rw-r--r--src/extras/keymap/keymap.c670
1 files changed, 335 insertions, 335 deletions
diff --git a/src/extras/keymap/keymap.c b/src/extras/keymap/keymap.c
index 6bcfaefa18..92ec67b3a6 100644
--- a/src/extras/keymap/keymap.c
+++ b/src/extras/keymap/keymap.c
@@ -45,403 +45,403 @@ const struct key* lookup_key (const char *str, unsigned int len);
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;
+ 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];
+ 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];
+ int codes[2];
- codes[0] = scancode;
- codes[1] = keycode;
+ codes[0] = scancode;
+ codes[1] = keycode;
- if (ioctl(fd, EVIOCSKEYCODE, codes) < 0) {
- fprintf(stderr, "EVIOCSKEYCODE: %m\n");
- return -1;
- }
- return 0;
+ 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;
+ int version;
- if (ioctl(fd, EVIOCGVERSION, &version)) {
- fprintf(stderr, "EVIOCGVERSION: %m\n");
- return -1;
- }
+ 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;
+ 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;
+ 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 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;
+ char version[256], name[256];
+ int scancode, r = -1;
- if (evdev_driver_version(fd, version, sizeof(version)) < 0)
- goto fail;
+ if (evdev_driver_version(fd, version, sizeof(version)) < 0)
+ goto fail;
- if (evdev_device_name(fd, name, sizeof(name)) < 0)
- goto fail;
+ if (evdev_device_name(fd, name, sizeof(name)) < 0)
+ goto fail;
- printf("### evdev %s, driver '%s'\n", version, name);
+ printf("### evdev %s, driver '%s'\n", version, name);
- r = 0;
- for (scancode = 0; scancode < MAX_SCANCODES; scancode++) {
- int keycode;
+ 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 = 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);
- }
+ 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;
+ 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);
+ 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;
- 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);
- }
+ int r = 0;
+ int line = 0;
+
+ 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:
- fclose(f);
- return r;
+ 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;
+ 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(uint32_t 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);
+ 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;
- uint32_t 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);
+ struct input_event ev;
+ uint32_t 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);
}
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);
- }
+ 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, "r");
- 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];
- snprintf(keymap_path, sizeof(keymap_path), "%s%s", SYSCONFDIR "/udev/keymaps/", filearg);
- FILE *f = fopen(keymap_path, "r");
- if (f) {
- merge_table(fd, f);
- } else {
- snprintf(keymap_path, sizeof(keymap_path), "%s%s", PKGLIBEXECDIR "/keymaps/", filearg);
- f = fopen(keymap_path, "r");
- 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 */
+ 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, "r");
+ 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];
+ snprintf(keymap_path, sizeof(keymap_path), "%s%s", SYSCONFDIR "/udev/keymaps/", filearg);
+ FILE *f = fopen(keymap_path, "r");
+ if (f) {
+ merge_table(fd, f);
+ } else {
+ snprintf(keymap_path, sizeof(keymap_path), "%s%s", PKGLIBEXECDIR "/keymaps/", filearg);
+ f = fopen(keymap_path, "r");
+ 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 */
}