diff options
Diffstat (limited to 'tools/gsr-global-hotkeys/main.c')
-rw-r--r-- | tools/gsr-global-hotkeys/main.c | 87 |
1 files changed, 80 insertions, 7 deletions
diff --git a/tools/gsr-global-hotkeys/main.c b/tools/gsr-global-hotkeys/main.c index 6f057a7..b64d60f 100644 --- a/tools/gsr-global-hotkeys/main.c +++ b/tools/gsr-global-hotkeys/main.c @@ -7,6 +7,7 @@ /* POSIX */ #include <unistd.h> +#include <dlfcn.h> typedef struct { uint32_t key; @@ -16,12 +17,12 @@ typedef struct { #define NUM_GLOBAL_HOTKEYS 6 static global_hotkey global_hotkeys[NUM_GLOBAL_HOTKEYS] = { - { .key = KEY_Z, .modifiers = KEYBOARD_MODKEY_ALT, .action = "show_hide" }, - { .key = KEY_F9, .modifiers = KEYBOARD_MODKEY_ALT, .action = "record" }, - { .key = KEY_F7, .modifiers = KEYBOARD_MODKEY_ALT, .action = "pause" }, - { .key = KEY_F8, .modifiers = KEYBOARD_MODKEY_ALT, .action = "stream" }, - { .key = KEY_F10, .modifiers = KEYBOARD_MODKEY_ALT | KEYBOARD_MODKEY_SHIFT, .action = "replay_start" }, - { .key = KEY_F10, .modifiers = KEYBOARD_MODKEY_ALT, .action = "replay_save" } + { .key = KEY_Z, .modifiers = KEYBOARD_MODKEY_LALT, .action = "show_hide" }, + { .key = KEY_F9, .modifiers = KEYBOARD_MODKEY_LALT, .action = "record" }, + { .key = KEY_F7, .modifiers = KEYBOARD_MODKEY_LALT, .action = "pause" }, + { .key = KEY_F8, .modifiers = KEYBOARD_MODKEY_LALT, .action = "stream" }, + { .key = KEY_F10, .modifiers = KEYBOARD_MODKEY_LALT | KEYBOARD_MODKEY_SHIFT, .action = "replay_start" }, + { .key = KEY_F10, .modifiers = KEYBOARD_MODKEY_LALT, .action = "replay_save" } }; static bool on_key_callback(uint32_t key, uint32_t modifiers, int press_status, void *userdata) { @@ -45,6 +46,76 @@ static void usage(void) { fprintf(stderr, " --virtual Grab all virtual devices only.\n"); } +typedef void* (*XOpenDisplay_FUNC)(const char*); +typedef int (*XErrorHandler_FUNC)(void *display, void* error_event); +typedef XErrorHandler_FUNC (*XSetErrorHandler_FUNC)(XErrorHandler_FUNC handler); + +static int x_ignore_error(void *display, void *ee) { + (void)display; + (void)ee; + return 0; +} + +static x11_context setup_x11_context(void) { + x11_context x_context = {0}; + XSetErrorHandler_FUNC XSetErrorHandler = NULL; + + void *x11_lib = dlopen("libX11.so.6", RTLD_LAZY); + if(!x11_lib) { + fprintf(stderr, "Warning: dlopen libX11.so.6 failed\n"); + return x_context; + } + + XOpenDisplay_FUNC XOpenDisplay = dlsym(x11_lib, "XOpenDisplay"); + if(!XOpenDisplay) { + fprintf(stderr, "Warning: dlsym XOpenDisplay failed\n"); + goto fail; + } + + x_context.XKeycodeToKeysym = dlsym(x11_lib, "XKeycodeToKeysym"); + if(!x_context.XKeycodeToKeysym) { + fprintf(stderr, "Warning: dlsym XKeycodeToKeysym failed\n"); + goto fail; + } + + x_context.XPending = dlsym(x11_lib, "XPending"); + if(!x_context.XPending) { + fprintf(stderr, "Warning: dlsym XPending failed\n"); + goto fail; + } + + x_context.XNextEvent = dlsym(x11_lib, "XNextEvent"); + if(!x_context.XNextEvent) { + fprintf(stderr, "Warning: dlsym XNextEvent failed\n"); + goto fail; + } + + x_context.XRefreshKeyboardMapping = dlsym(x11_lib, "XRefreshKeyboardMapping"); + if(!x_context.XRefreshKeyboardMapping) { + fprintf(stderr, "Warning: dlsym XRefreshKeyboardMapping failed\n"); + goto fail; + } + + x_context.display = XOpenDisplay(NULL); + if(!x_context.display) { + fprintf(stderr, "Warning: XOpenDisplay failed\n"); + goto fail; + } + + XSetErrorHandler = dlsym(x11_lib, "XSetErrorHandler"); + if(XSetErrorHandler) + XSetErrorHandler(x_ignore_error); + else + fprintf(stderr, "Warning: dlsym XSetErrorHandler failed\n"); + + return x_context; + + fail: + memset(&x_context, 0, sizeof(x_context)); + dlclose(x11_lib); + return x_context; +} + int main(int argc, char **argv) { keyboard_grab_type grab_type = KEYBOARD_GRAB_TYPE_ALL; if(argc == 2) { @@ -64,6 +135,8 @@ int main(int argc, char **argv) { return 1; } + x11_context x_context = setup_x11_context(); + const uid_t user_id = getuid(); if(geteuid() != 0) { if(setuid(0) == -1) { @@ -73,7 +146,7 @@ int main(int argc, char **argv) { } keyboard_event keyboard_ev; - if(!keyboard_event_init(&keyboard_ev, true, true, grab_type)) { + if(!keyboard_event_init(&keyboard_ev, true, true, grab_type, x_context)) { fprintf(stderr, "Error: failed to setup hotplugging and no keyboard input devices were found\n"); setuid(user_id); return 1; |