-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathxhidecursor.c
More file actions
84 lines (80 loc) · 2.61 KB
/
Copy pathxhidecursor.c
File metadata and controls
84 lines (80 loc) · 2.61 KB
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
78
79
80
81
82
83
84
#include <X11/XKBlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xfixes.h>
#include <X11/extensions/XInput2.h>
#include <stdio.h>
#ifdef __OpenBSD__
#include <unistd.h>
#endif
static Display *d;
static Window r;
static void xi_select_events(const int event) {
unsigned char mask[XIMaskLen(XI_LASTEVENT)] = {0};
XISetMask(mask, event);
XIEventMask event_mask = {
.deviceid = XIAllMasterDevices,
.mask_len = sizeof(mask),
.mask = mask
};
XISelectEvents(d, r, &event_mask, 1);
}
int main(void) {
// Check runtime requirements.
if (!(d = XOpenDisplay(NULL))) {
fprintf(stderr, "xhidecursor: cannot open display %s\n", XDisplayName(NULL));
return 1;
}
int fixes_major, fixes_minor;
if (!XFixesQueryVersion(d, &fixes_major, &fixes_minor) || fixes_major < 4) {
fprintf(stderr, "xhidecursor: XFixes version 4.0 or later is required\n");
XCloseDisplay(d);
return 1;
}
int xi_major = 2, xi_minor = 2;
if (XIQueryVersion(d, &xi_major, &xi_minor) != Success ||
xi_major < 2 || (xi_major == 2 && xi_minor < 1)) {
fprintf(stderr, "xhidecursor: XInput2 version 2.1 or later is required\n");
XCloseDisplay(d);
return 1;
}
// Restrict system operations to stdio and the existing X connection.
#ifdef __OpenBSD__
if (pledge("stdio", NULL) == -1) {
perror("xhidecursor: pledge");
XCloseDisplay(d);
return 1;
}
#endif
// Process input events.
r = XDefaultRootWindow(d);
xi_select_events(XI_RawKeyPress);
while (True) {
XEvent e;
XNextEvent(d, &e);
if (e.type != GenericEvent || !XGetEventData(d, &e.xcookie))
continue;
XGenericEventCookie *c = &e.xcookie;
switch (c->evtype) {
// XSync discards queued events to prevent cursor-state races between key presses and mouse movement.
case XI_RawKeyPress: {
const XIRawEvent *raw_e = c->data;
const KeyCode keycode = (KeyCode)raw_e->detail;
const KeySym keysym = XkbKeycodeToKeysym(d, keycode, 0, 0);
if (!IsModifierKey(keysym)) {
xi_select_events(XI_RawMotion);
XFixesHideCursor(d, r);
XSync(d, True);
}
break;
} case XI_RawMotion:
xi_select_events(XI_RawKeyPress);
XFixesShowCursor(d, r);
XSync(d, True);
break;
default:
break;
}
XFreeEventData(d, c);
}
}