123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- #include <cstring>
- #include <cassert>
- #include <cstdio>
- #include <thread>
- #include <chrono>
- #include <X11/Xlib.h>
- #include <X11/keysymdef.h>
- extern "C" {
- #include <xdo.h>
- }
- // const auto KEY_INTERVAL = std::chrono::seconds(64);
- const useconds_t KEY_DELAY = 12000; // microseconds
- void search_windows_by_name(const xdo_t* xdo, const char* name_regex, Window** windowlist_ret, unsigned int* nwindows_ret) {
- xdo_search_t search;
- memset(&search, 0, sizeof(xdo_search_t));
- search.max_depth = -1;
- search.require = xdo_search::SEARCH_ALL;
- search.searchmask |= SEARCH_NAME;
- search.winname = name_regex;
- xdo_search_windows(xdo, &search, windowlist_ret, nwindows_ret);
- }
- class ToontownKeyboardManager {
- Display* display;
- int screen;
- Window main_window;
- xdo_t* xdo;
- void search_toontown_windows(Window** windowlist_ret, unsigned int* nwindows_ret) {
- search_windows_by_name(xdo, "Toontown.*", windowlist_ret, nwindows_ret);
- }
- void send_keys(const char* keysequence) {
- Window* windows;
- unsigned int nwindows;
- search_toontown_windows(&windows, &nwindows);
- for(unsigned int i=0; i<nwindows; i++) {
- // file:///usr/share/doc/libxdo-dev/html/xdo_8h.html
- // http://www.cl.cam.ac.uk/~mgk25/ucs/keysymdef.h
- xdo_send_keysequence_window(xdo, windows[i], keysequence, KEY_DELAY);
- }
- }
- bool key_event(XKeyEvent* key_event) {
- // https://tronche.com/gui/x/xlib/events/keyboard-pointer/keyboard-pointer.html#XKeyEvent
- // https://tronche.com/gui/x/xlib/utilities/keyboard/XLookupKeysym.html
- KeySym key_symbol = XLookupKeysym(key_event, 0);
- const char* key_str = XKeysymToString(key_symbol);
- printf(
- "%s %d %lu %s %d\n",
- (key_event->type == KeyPress) ? "p" : "r",
- key_event->keycode,
- key_symbol,
- key_str,
- key_event->state
- );
- if(key_event->state == ControlMask && key_symbol == XStringToKeysym("c")) {
- return false; // Ctrl-c
- } else {
- if(key_event->type == KeyPress) {
- send_keys(key_str);
- }
- return true;
- }
- }
- bool window_event(XEvent* event) {
- if(event->type == KeyPress || event->type == KeyRelease) {
- return key_event(&event->xkey);
- } else {
- printf("window event %d", event->type);
- return true;
- }
- }
- public:
- ToontownKeyboardManager() {
- display = XOpenDisplay(NULL);
- assert(display);
- screen = XDefaultScreen(display);
- xdo = xdo_new(NULL);
- assert(xdo);
- // https://tronche.com/gui/x/xlib/window/XCreateWindow.html
- main_window = XCreateSimpleWindow(
- display,
- RootWindow(display, screen), // parent
- 0, // x
- 0, // y
- 50, // width
- 50, // height
- 1, // border width
- 0, // border
- 0 // background
- );
- XSelectInput(display, main_window, KeyPressMask | KeyReleaseMask);
- XMapWindow(display, main_window);
- }
- void loop() {
- XEvent event;
- do {
- XNextEvent(display, &event);
- } while(window_event(&event));
- }
- ~ToontownKeyboardManager() {
- XCloseDisplay(display);
- }
- };
- int main() {
- // http://stackoverflow.com/questions/2100654/ignore-auto-repeat-in-x11-applications
- // XAutoRepeatOn(display);
- ToontownKeyboardManager app;
- app.loop();
- return 0;
- }
|