diff options
author | dec05eba <dec05eba@protonmail.com> | 2025-01-04 05:39:16 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2025-01-04 05:39:16 +0100 |
commit | 52ce22ae22670b11c2bc5fac0583e1a4aa4e19f0 (patch) | |
tree | 67c6e6a02c567b45252074e2672bde6bc9ffde6f /tools | |
parent | f379b87b33282a7d583ce5e57be684a718f6a68d (diff) |
Add option to only grab virtual devices, to support input remapping software
Diffstat (limited to 'tools')
-rw-r--r-- | tools/gsr-global-hotkeys/keyboard_event.c | 33 | ||||
-rw-r--r-- | tools/gsr-global-hotkeys/keyboard_event.h | 8 | ||||
-rw-r--r-- | tools/gsr-global-hotkeys/main.c | 30 |
3 files changed, 67 insertions, 4 deletions
diff --git a/tools/gsr-global-hotkeys/keyboard_event.c b/tools/gsr-global-hotkeys/keyboard_event.c index 63aeeef..79e7f17 100644 --- a/tools/gsr-global-hotkeys/keyboard_event.c +++ b/tools/gsr-global-hotkeys/keyboard_event.c @@ -213,11 +213,41 @@ static bool keyboard_event_has_event_with_dev_input_fd(keyboard_event *self, int return false; } +/* TODO: Is there a more efficient way to do this? */ +static bool dev_input_is_virtual(int dev_input_id) { + DIR *dir = opendir("/sys/devices/virtual/input"); + if(!dir) + return false; + + bool is_virtual = false; + char virtual_input_filepath[1024]; + for(;;) { + struct dirent *entry = readdir(dir); + if(!entry) + break; + + if(strncmp(entry->d_name, "input", 5) != 0) + continue; + + snprintf(virtual_input_filepath, sizeof(virtual_input_filepath), "/sys/devices/virtual/input/%s/event%d", entry->d_name, dev_input_id); + if(access(virtual_input_filepath, F_OK) == 0) { + is_virtual = true; + break; + } + } + + closedir(dir); + return is_virtual; +} + static bool keyboard_event_try_add_device_if_keyboard(keyboard_event *self, const char *dev_input_filepath) { const int dev_input_id = get_dev_input_id_from_filepath(dev_input_filepath); if(dev_input_id == -1) return false; + if(self->grab_type == KEYBOARD_GRAB_TYPE_VIRTUAL && !dev_input_is_virtual(dev_input_id)) + return false; + if(keyboard_event_has_event_with_dev_input_fd(self, dev_input_id)) return false; @@ -373,10 +403,11 @@ static int setup_virtual_keyboard_input(const char *name) { return fd; } -bool keyboard_event_init(keyboard_event *self, bool poll_stdout_error, bool exclusive_grab) { +bool keyboard_event_init(keyboard_event *self, bool poll_stdout_error, bool exclusive_grab, keyboard_grab_type grab_type) { memset(self, 0, sizeof(*self)); self->stdout_event_index = -1; self->hotplug_event_index = -1; + self->grab_type = grab_type; if(exclusive_grab) { self->uinput_fd = setup_virtual_keyboard_input(GSR_UI_VIRTUAL_KEYBOARD_NAME); diff --git a/tools/gsr-global-hotkeys/keyboard_event.h b/tools/gsr-global-hotkeys/keyboard_event.h index d12b684..5310aca 100644 --- a/tools/gsr-global-hotkeys/keyboard_event.h +++ b/tools/gsr-global-hotkeys/keyboard_event.h @@ -36,6 +36,11 @@ typedef struct { int num_keys_pressed; } event_extra_data; +typedef enum { + KEYBOARD_GRAB_TYPE_ALL, + KEYBOARD_GRAB_TYPE_VIRTUAL +} keyboard_grab_type; + typedef struct { struct pollfd event_polls[MAX_EVENT_POLLS]; /* Current size is |num_event_polls| */ event_extra_data event_extra_data[MAX_EVENT_POLLS]; /* Current size is |num_event_polls| */ @@ -45,6 +50,7 @@ typedef struct { int hotplug_event_index; int uinput_fd; bool stdout_failed; + keyboard_grab_type grab_type; hotplug_event hotplug_ev; @@ -62,7 +68,7 @@ typedef struct { /* Return true to allow other applications to receive the key input (when using exclusive grab) */ typedef bool (*key_callback)(uint32_t key, uint32_t modifiers, int press_status, void *userdata); -bool keyboard_event_init(keyboard_event *self, bool poll_stdout_error, bool exclusive_grab); +bool keyboard_event_init(keyboard_event *self, bool poll_stdout_error, bool exclusive_grab, keyboard_grab_type grab_type); void keyboard_event_deinit(keyboard_event *self); /* If |timeout_milliseconds| is -1 then wait until an event is received */ diff --git a/tools/gsr-global-hotkeys/main.c b/tools/gsr-global-hotkeys/main.c index aeea660..6f057a7 100644 --- a/tools/gsr-global-hotkeys/main.c +++ b/tools/gsr-global-hotkeys/main.c @@ -3,6 +3,7 @@ /* C stdlib */ #include <stdio.h> #include <stdint.h> +#include <string.h> /* POSIX */ #include <unistd.h> @@ -37,7 +38,32 @@ static bool on_key_callback(uint32_t key, uint32_t modifiers, int press_status, return true; } -int main(void) { +static void usage(void) { + fprintf(stderr, "usage: gsr-global-hotkeys [--all|--virtual]\n"); + fprintf(stderr, "OPTIONS:\n"); + fprintf(stderr, " --all Grab all devices.\n"); + fprintf(stderr, " --virtual Grab all virtual devices only.\n"); +} + +int main(int argc, char **argv) { + keyboard_grab_type grab_type = KEYBOARD_GRAB_TYPE_ALL; + if(argc == 2) { + const char *grab_type_arg = argv[1]; + if(strcmp(grab_type_arg, "--all") == 0) { + grab_type = KEYBOARD_GRAB_TYPE_ALL; + } else if(strcmp(grab_type_arg, "--virtual") == 0) { + grab_type = KEYBOARD_GRAB_TYPE_VIRTUAL; + } else { + fprintf(stderr, "Error: expected --all or --virtual, got %s\n", grab_type_arg); + usage(); + return 1; + } + } else if(argc != 1) { + fprintf(stderr, "Error: expected 0 or 1 arguments, got %d argument(s)\n", argc); + usage(); + return 1; + } + const uid_t user_id = getuid(); if(geteuid() != 0) { if(setuid(0) == -1) { @@ -47,7 +73,7 @@ int main(void) { } keyboard_event keyboard_ev; - if(!keyboard_event_init(&keyboard_ev, true, true)) { + if(!keyboard_event_init(&keyboard_ev, true, true, grab_type)) { fprintf(stderr, "Error: failed to setup hotplugging and no keyboard input devices were found\n"); setuid(user_id); return 1; |