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

3 years ago
  1. /* copyright Constantin Fürst 2021, licensed under GPLv3, a copy is provided in LICENSE */
  2. /* non-major portions of the code were taken from DWM (https://dwm.suckless.org) */
  3. /* inspired and named after keym by Chris Willcocks (https://github.com/cwkx/keym) */
  4. #include <stdio.h>
  5. #include <unistd.h>
  6. #include <stdint.h>
  7. #include <inttypes.h>
  8. #include <X11/Xlib.h>
  9. #include "config.h"
  10. #include "typedefs.h"
  11. keym_state state;
  12. void eventhandler(XEvent *e) {
  13. uint32_t arg;
  14. KeySym keysym;
  15. XKeyEvent *ev;
  16. ev = &e->xkey;
  17. keysym = XKeycodeToKeysym(state.display, (KeyCode)ev->keycode, 0);
  18. for (uint32_t i = 0; i < LENGTH(keys); i++) {
  19. if (
  20. keysym == keys[i].keysym &&
  21. CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) &&
  22. keys[i].func
  23. )
  24. {
  25. arg = keys[i].arg;
  26. switch (ev->type) {
  27. case KeyRelease:
  28. arg |= KEY_RELEASE_MASK;
  29. break;
  30. case KeyPress:
  31. default: break;
  32. }
  33. keys[i].func(&arg);
  34. }
  35. }
  36. }
  37. void grabkeys() {
  38. KeyCode code;
  39. XUngrabKey(state.display, AnyKey, AnyModifier, state.window);
  40. for (uint32_t i = 0; i < LENGTH(keys); i++) {
  41. if ((code = XKeysymToKeycode(state.display, keys[i].keysym))) {
  42. XGrabKey(state.display, code, keys[i].mod, state.window, True, GrabModeAsync, GrabModeAsync);
  43. }
  44. }
  45. }
  46. int setup() {
  47. state.speed = 1;
  48. state.quit = False;
  49. if (!(state.display = XOpenDisplay(NULL))) {
  50. fprintf(stderr, "[x] error opening display\n");
  51. return 1;
  52. }
  53. state.window = XDefaultRootWindow(state.display);
  54. state.screen = DefaultScreen(state.display);
  55. XSelectInput(state.display, state.window, ExposureMask | KeyPressMask);
  56. XMapWindow(state.display, state.window);
  57. state.x11_fd = ConnectionNumber(state.display);;
  58. grabkeys();
  59. return 0;
  60. }
  61. void cleanup() {
  62. XUngrabKey(state.display, AnyKey, AnyModifier, state.window);
  63. FD_CLR(state.x11_fd, &state.in_fds);
  64. XUnmapWindow(state.display,state.window);
  65. XCloseDisplay(state.display);
  66. }
  67. void set_x_update(uint32_t tv_usec) {
  68. FD_ZERO(&state.in_fds);
  69. FD_SET(state.x11_fd, &state.in_fds);
  70. struct timeval tv;
  71. tv.tv_sec = 0;
  72. tv.tv_usec = tv_usec;
  73. select(state.x11_fd + 1, &state.in_fds, NULL, NULL, &tv);
  74. }
  75. void move_pointer_by_state() {
  76. XWarpPointer(state.display, None, None, 0, 0, 0, 0, state.x, state.y);
  77. }
  78. int main() {
  79. XEvent ev;
  80. if (setup() != 0) return -1;
  81. XSync(state.display, False);
  82. while (!state.quit) {
  83. while (XPending(state.display))
  84. XNextEvent(state.display, &ev);
  85. set_x_update(speeds[state.speed]);
  86. eventhandler(&ev);
  87. move_pointer_by_state();
  88. }
  89. cleanup();
  90. return 1;
  91. }