#include #include #include #include #include #include #include extern "C" { #include } // 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); } void search_toontown_windows(const xdo_t* xdo, Window** windowlist_ret, unsigned int* nwindows_ret) { search_windows_by_name(xdo, "Toontown.*", windowlist_ret, nwindows_ret); } void send_keysequence(const xdo_t* xdo) { Window* windows; unsigned int nwindows; search_toontown_windows(xdo, &windows, &nwindows); for(unsigned int i=0; itype == KeyPress) ? "p" : "r", key_event->keycode, key_event->state ); //if(key_event.state == ControlMask) { 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; }