main.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include <cstring>
  2. #include <cassert>
  3. #include <cstdio>
  4. #include <thread>
  5. #include <chrono>
  6. #include <X11/Xlib.h>
  7. #include <X11/keysymdef.h>
  8. extern "C" {
  9. #include <xdo.h>
  10. }
  11. // const auto KEY_INTERVAL = std::chrono::seconds(64);
  12. const useconds_t KEY_DELAY = 12000; // microseconds
  13. void search_windows_by_name(const xdo_t* xdo, const char* name_regex, Window** windowlist_ret, unsigned int* nwindows_ret) {
  14. xdo_search_t search;
  15. memset(&search, 0, sizeof(xdo_search_t));
  16. search.max_depth = -1;
  17. search.require = xdo_search::SEARCH_ALL;
  18. search.searchmask |= SEARCH_NAME;
  19. search.winname = name_regex;
  20. xdo_search_windows(xdo, &search, windowlist_ret, nwindows_ret);
  21. }
  22. void search_toontown_windows(const xdo_t* xdo, Window** windowlist_ret, unsigned int* nwindows_ret) {
  23. search_windows_by_name(xdo, "Toontown.*", windowlist_ret, nwindows_ret);
  24. }
  25. void send_keysequence(const xdo_t* xdo) {
  26. Window* windows;
  27. unsigned int nwindows;
  28. search_toontown_windows(xdo, &windows, &nwindows);
  29. for(unsigned int i=0; i<nwindows; i++) {
  30. // http://www.cl.cam.ac.uk/~mgk25/ucs/keysymdef.h
  31. xdo_send_keysequence_window(xdo, windows[i], "Left", KEY_DELAY);
  32. xdo_send_keysequence_window(xdo, windows[i], "Right", KEY_DELAY);
  33. }
  34. }
  35. class ToontownKeyboardManager {
  36. Display* display;
  37. int screen;
  38. Window main_window;
  39. xdo_t* xdo;
  40. bool key_event(XKeyEvent* key_event) {
  41. // https://tronche.com/gui/x/xlib/events/keyboard-pointer/keyboard-pointer.html#XKeyEvent
  42. // https://tronche.com/gui/x/xlib/utilities/keyboard/XLookupKeysym.html
  43. KeySym key_symbol = XLookupKeysym(key_event, 0);
  44. printf(
  45. "%s %d %d\n",
  46. (key_event->type == KeyPress) ? "p" : "r",
  47. key_event->keycode,
  48. key_event->state
  49. );
  50. //if(key_event.state == ControlMask) {
  51. return true;
  52. }
  53. bool window_event(XEvent* event) {
  54. if(event->type == KeyPress || event->type == KeyRelease) {
  55. return key_event(&event->xkey);
  56. } else {
  57. printf("window event %d", event->type);
  58. return true;
  59. }
  60. }
  61. public:
  62. ToontownKeyboardManager() {
  63. display = XOpenDisplay(NULL);
  64. assert(display);
  65. screen = XDefaultScreen(display);
  66. xdo = xdo_new(NULL);
  67. assert(xdo);
  68. // https://tronche.com/gui/x/xlib/window/XCreateWindow.html
  69. main_window = XCreateSimpleWindow(
  70. display,
  71. RootWindow(display, screen), // parent
  72. 0, // x
  73. 0, // y
  74. 50, // width
  75. 50, // height
  76. 1, // border width
  77. 0, // border
  78. 0 // background
  79. );
  80. XSelectInput(display, main_window, KeyPressMask | KeyReleaseMask);
  81. XMapWindow(display, main_window);
  82. }
  83. void loop() {
  84. XEvent event;
  85. do {
  86. XNextEvent(display, &event);
  87. } while(window_event(&event));
  88. }
  89. ~ToontownKeyboardManager() {
  90. XCloseDisplay(display);
  91. }
  92. };
  93. int main() {
  94. // http://stackoverflow.com/questions/2100654/ignore-auto-repeat-in-x11-applications
  95. // XAutoRepeatOn(display);
  96. ToontownKeyboardManager app;
  97. app.loop();
  98. return 0;
  99. }