diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 132 |
1 files changed, 22 insertions, 110 deletions
@@ -1,4 +1,8 @@ #define _DEFAULT_SOURCE + +#include "binding.h" +#include "bindings_file.h" + #include <stdlib.h> #include <errno.h> #include <string.h> @@ -7,8 +11,6 @@ #include <unistd.h> #include <fcntl.h> #include <dirent.h> -#include <ctype.h> -#include <linux/input.h> #include <linux/limits.h> #include <sys/inotify.h> #include <pwd.h> @@ -16,18 +18,10 @@ #define NPFDS 4096 -struct binding -{ - int code; - int value; - char *cmd; -}; - struct pollfd pfds[NPFDS] = {0}; int test_mode = 0; -size_t nbindings = 0; -struct binding *bindings = NULL; +uint64_t keys[KEYS_SIZE] = {0}; void add_device(const char name[static 1]) @@ -77,120 +71,38 @@ void process_inotify_watch(int inotify_fd) } } -void skip_space(char **c) +void run_binding(struct binding *binding) { - for (; **c && isspace(**c); (*c)++); -} - -int read_int(char **c, int out[static 1]) -{ - if (!isdigit(**c)) - { - return -1; - } - errno = 0; - char *end = NULL; - *out = strtol(*c, &end, 10); - if (errno) + if (fork() == 0) { - return -1; + execl("/bin/sh", "/bin/sh", "-c", binding->cmd); } - *c = end; - return 0; } -void parse_bindings_file(const char path[static 1]) +void process_key_event(int code, int value) { - size_t cap = 512; - bindings = malloc(sizeof (struct binding) * cap); - FILE *f = fopen(path, "r"); - if (f == NULL) + uint64_t old_keys[KEYS_SIZE]; + for (size_t i = 0; i < KEYS_SIZE; i++) { - fprintf(stderr, "failed to open bindings file: %s: %s\n", path, - strerror(errno)); - exit(EXIT_FAILURE); + old_keys[i] = keys[i]; } - - size_t line_nb = 0; - char *line = NULL; - size_t n; - while (getline(&line, &n, f) != -1) + if (value == RELEASED) { - line_nb++; - struct binding binding; - char *end = strchr(line, '#'); - if (end == NULL) - { - end = line + strlen(line); - } - *end = '\0'; - char *c = line; - - skip_space(&c); - if (c == end) continue; - - /* code */ - if (read_int(&c, &binding.code) < 0 || c >= end) - { - goto fail; - } - - /* press | release */ - skip_space(&c); - if (strncmp(c, "press", strlen("press")) == 0) - { - c += strlen("press"); - binding.value = 1; - } - else if (strncmp(c, "release", strlen("release")) == 0) - { - c += strlen("release"); - binding.value = 0; - } - else - { - goto fail; - } - - /* cmd */ - skip_space(&c); - if (c >= end) - { - goto fail; - } - binding.cmd = malloc(end - c + 1); - memcpy(binding.cmd, c, end - c + 1); - - if (nbindings >= cap) - { - cap *= 2; - bindings = realloc(bindings, cap * sizeof (struct binding)); - } - bindings[nbindings++] = binding; + clear_key(keys, code); } - if (!feof(f)) + else if (value == PRESSED) { - fprintf(stderr, "failed to read bindings file: %s: %s\n", path, - strerror(errno)); + set_key(keys, code); } - free(line); - fclose(f); - return; - -fail: - fprintf(stderr, "syntax error at line %ld\n", line_nb); - exit(EXIT_FAILURE); -} - -void run_binding(int code, int value) -{ for (size_t i = 0; i < nbindings; i++) { - if (bindings[i].code == code && bindings[i].value == value) + if (bindings[i].value == value) { - if (fork() == 0) + uint64_t *match_target = value == PRESSED ? keys : old_keys; + if (is_keys_subset_of(bindings[i].keys, match_target) + && has_key(bindings[i].keys, code)) { - execl("/bin/sh", "/bin/sh", "-c", bindings[i].cmd); + run_binding(bindings + i); } } } @@ -212,7 +124,7 @@ void process_input_device(int fd) } else { - run_binding(event.code, event.value); + process_key_event(event.code, event.value); } } } |