summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
authorpapush!2025-07-04 23:21:14 +0200
committerpapush!2025-07-04 23:25:07 +0200
commit0d1f4776521b286cb7c0091ac5bcd659cdc87132 (patch)
tree5b04bd12c45f6f30c34356241616496c5cb025e2 /src/main.c
parentff5e9f826d6e89f5ab1adb09e959afd5d1e17a5f (diff)
add multikey binds support
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c132
1 files changed, 22 insertions, 110 deletions
diff --git a/src/main.c b/src/main.c
index 7ecfc15..00c6eb2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);
}
}
}