You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

121 lines
2.8 KiB

/* copyright Constantin Fürst 2021, licensed under GPLv3, a copy is provided in LICENSE */
/* non-major portions of the code were taken from DWM (https://dwm.suckless.org) */
/* inspired and named after keym by Chris Willcocks (https://github.com/cwkx/keym) */
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <inttypes.h>
#include <X11/Xlib.h>
#include "config.h"
#include "typedefs.h"
keym_state state;
void eventhandler(XEvent *e) {
uint32_t arg;
KeySym keysym;
XKeyEvent *ev;
ev = &e->xkey;
keysym = XKeycodeToKeysym(state.display, (KeyCode)ev->keycode, 0);
for (uint32_t i = 0; i < LENGTH(keys); i++) {
if (
keysym == keys[i].keysym &&
CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) &&
keys[i].func
)
{
arg = keys[i].arg;
switch (ev->type) {
case KeyRelease:
arg |= KEY_RELEASE_MASK;
break;
case KeyPress:
default: break;
}
keys[i].func(&arg);
}
}
}
void grabkeys() {
KeyCode code;
XUngrabKey(state.display, AnyKey, AnyModifier, state.window);
for (uint32_t i = 0; i < LENGTH(keys); i++) {
if ((code = XKeysymToKeycode(state.display, keys[i].keysym))) {
XGrabKey(state.display, code, keys[i].mod, state.window, True, GrabModeAsync, GrabModeAsync);
}
}
}
int setup() {
state.speed = 1;
state.quit = False;
if (!(state.display = XOpenDisplay(NULL))) {
fprintf(stderr, "[x] error opening display\n");
return 1;
}
state.window = XDefaultRootWindow(state.display);
state.screen = DefaultScreen(state.display);
XSelectInput(state.display, state.window, ExposureMask | KeyPressMask);
XMapWindow(state.display, state.window);
state.x11_fd = ConnectionNumber(state.display);;
grabkeys();
return 0;
}
void cleanup() {
XUngrabKey(state.display, AnyKey, AnyModifier, state.window);
FD_CLR(state.x11_fd, &state.in_fds);
XUnmapWindow(state.display,state.window);
XCloseDisplay(state.display);
}
void set_x_update(uint32_t tv_usec) {
FD_ZERO(&state.in_fds);
FD_SET(state.x11_fd, &state.in_fds);
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = tv_usec;
select(state.x11_fd + 1, &state.in_fds, NULL, NULL, &tv);
}
void move_pointer_by_state() {
XWarpPointer(state.display, None, None, 0, 0, 0, 0, state.x, state.y);
}
int main() {
XEvent ev;
if (setup() != 0) return -1;
XSync(state.display, False);
while (!state.quit) {
while (XPending(state.display))
XNextEvent(state.display, &ev);
set_x_update(speeds[state.speed]);
eventhandler(&ev);
move_pointer_by_state();
}
cleanup();
return 1;
}