aboutsummaryrefslogtreecommitdiff
path: root/gpu-screen-recorder-overlay-daemon/main.c
blob: 7db83bd6335db670baca0cefa2cc9e236ec7c7d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>

static int ignore_xerror(Display *display, XErrorEvent *ee) {
    (void)display;
    (void)ee;
    return 0;
}

static void sigterm_handler(int dummy) {
    (void)dummy;
}

static const KeySym toggle_overlay_key = XK_Z;
static void grab_keys(Display *display) {
    unsigned int numlockmask = 0; 
    KeyCode numlock_keycode = XKeysymToKeycode(display, XK_Num_Lock);
    XModifierKeymap *modmap = XGetModifierMapping(display);
    for(int i = 0; i < 8; ++i) {
        for(int j = 0; j < modmap->max_keypermod; ++j) {
            if(modmap->modifiermap[i * modmap->max_keypermod + j] == numlock_keycode)
                numlockmask = (1 << i); 
        }
    }   
    XFreeModifiermap(modmap);

    XErrorHandler prev_error_handler = XSetErrorHandler(ignore_xerror);
    
    Window root_window = DefaultRootWindow(display);
    unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
    for(int i = 0; i < 4; ++i) {
        XGrabKey(display, XKeysymToKeycode(display, toggle_overlay_key), Mod1Mask|modifiers[i], root_window, False, GrabModeAsync, GrabModeAsync);
    }    
    
    XSync(display, False);
    XSetErrorHandler(prev_error_handler);
}

static Window get_window_with_input_focus(Display *display) {
    Window window = None;
    int rev;
    if(!XGetInputFocus(display, &window, &rev))
        window = None;
    return window;
}

int main() {
    Display *display = XOpenDisplay(NULL);
    if(!display) {
        fprintf(stderr, "Error: XOpenDisplay failed\n");
        return 1;
    }

    grab_keys(display);
    const KeyCode overlay_keycode = XKeysymToKeycode(display, toggle_overlay_key);

    XSetErrorHandler(ignore_xerror);
    /* Killing gpu-screen-recorder with SIGTERM also gives us SIGTERM. We want to ignore that as that has no meaning here */
    signal(SIGTERM, sigterm_handler);

    XEvent xev;
    for(;;) {
        XNextEvent(display, &xev);
        if(xev.type == KeyRelease && xev.xkey.keycode == overlay_keycode) {
            Window window_with_input_focus = get_window_with_input_focus(display);
            if(window_with_input_focus && window_with_input_focus != DefaultRootWindow(display)) {
                char cmd[1024];
                snprintf(cmd, sizeof(cmd), "/home/dec05eba/git/gpu-screen-recorder-overlay/sibs-build/linux_x86_64/debug/gpu-screen-recorder-overlay %ld", window_with_input_focus);
                system(cmd);
            }
        }
    }
    return 0;
}