|
@@ -1,12 +1,29 @@
|
|
|
#include <cstring>
|
|
|
#include <cassert>
|
|
|
#include <cstdio>
|
|
|
-#include <set>
|
|
|
+#include <map>
|
|
|
#include <X11/Xlib.h>
|
|
|
+#define XK_MISCELLANY
|
|
|
+#define XK_LATIN1
|
|
|
+#include <X11/keysymdef.h>
|
|
|
extern "C" {
|
|
|
#include <xdo.h>
|
|
|
}
|
|
|
|
|
|
+const std::map<KeySym, const char*> kbd_map = {
|
|
|
+ {XK_w, "Up"},
|
|
|
+ {XK_a, "Left"},
|
|
|
+ {XK_s, "Down"},
|
|
|
+ {XK_d, "Right"},
|
|
|
+ {XK_Up, "Up"},
|
|
|
+ {XK_Left, "Left"},
|
|
|
+ {XK_Down, "Down"},
|
|
|
+ {XK_Right, "Right"},
|
|
|
+ {XK_Control_L, "Control_L"},
|
|
|
+ {XK_Control_R, "Control_R"},
|
|
|
+ {XK_Delete, "Delete"},
|
|
|
+};
|
|
|
+
|
|
|
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) {
|
|
@@ -49,6 +66,27 @@ class ToontownKeyboardManager {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ bool handle_key(XKeyEvent* key_event) {
|
|
|
+ // https://tronche.com/gui/x/xlib/utilities/keyboard/XLookupKeysym.html
|
|
|
+ KeySym key_symbol = XLookupKeysym(key_event, 0);
|
|
|
+ if(key_event->state == ControlMask && key_symbol == XK_c) {
|
|
|
+ return false; // Ctrl-c
|
|
|
+ } else {
|
|
|
+ auto kbd_map_it = kbd_map.find(key_symbol);
|
|
|
+ if(kbd_map_it != kbd_map.end()) {
|
|
|
+ send_keyseq(kbd_map_it->second, key_event->type);
|
|
|
+ } else if(key_event->type == KeyPress) {
|
|
|
+ printf(
|
|
|
+ "no mapping for '%s' (%#lx)\n",
|
|
|
+ XKeysymToString(key_symbol),
|
|
|
+ key_symbol
|
|
|
+ );
|
|
|
+
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
static Bool key_autorepeat_predicate(Display* display, XEvent* event, XPointer arg) {
|
|
|
XKeyEvent* release_event = (XKeyEvent*)arg;
|
|
|
return event->type == KeyPress
|
|
@@ -58,25 +96,12 @@ class ToontownKeyboardManager {
|
|
|
|
|
|
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 %lu\n",
|
|
|
- // (key_event->type == KeyPress) ? "p" : "r",
|
|
|
- // key_event->keycode,
|
|
|
- // key_symbol,
|
|
|
- // key_str,
|
|
|
- // key_event->state
|
|
|
- // , key_event->time
|
|
|
- // );
|
|
|
- if(key_event->state == ControlMask && key_symbol == XStringToKeysym("c")) {
|
|
|
- return false; // Ctrl-c
|
|
|
+ XEvent repeat_event;
|
|
|
+ if(!XCheckIfEvent(display, &repeat_event, key_autorepeat_predicate, (XPointer)key_event)) {
|
|
|
+ return handle_key(key_event);
|
|
|
} else {
|
|
|
- XEvent repeat_event;
|
|
|
- if(!XCheckIfEvent(display, &repeat_event, key_autorepeat_predicate, (XPointer)key_event)) {
|
|
|
- send_keyseq(key_str, key_event->type);
|
|
|
- }
|
|
|
+ // ignore auto release event
|
|
|
+ // xcheckifevent() removed the associated auto press event
|
|
|
return true;
|
|
|
}
|
|
|
}
|