|
|
/* 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; }
|