|
|
452870 |
|
|
|
452870 |
#include "app.h"
|
|
|
452870 |
|
|
|
452870 |
#include <x11 xutil.h=""></x11>
|
|
|
452870 |
#include <x11 extensions="" xtest.h=""></x11>
|
|
|
452870 |
|
|
|
452870 |
|
|
|
452870 |
int inputInit(Input *in, App *app) {
|
|
|
452870 |
LOGDBG("input: init");
|
|
|
452870 |
|
|
|
452870 |
in->app = app;
|
|
|
452870 |
in->mappedKeyCode = 0;
|
|
|
452870 |
in->mappedPressed = 0;
|
|
|
452870 |
|
|
|
452870 |
LOGDBG("input: init: connect to X11");
|
|
|
452870 |
in->dpy = XOpenDisplay(NULL);
|
|
|
452870 |
if (!in->dpy)
|
|
|
452870 |
return LOGERR("input: init: cannot connect to X11");
|
|
|
452870 |
|
|
|
452870 |
LOGDBG("input: init: search free keycode for temporary mappings");
|
|
|
452870 |
int kk = 0, kc0 = 0, kc1 = 0;
|
|
|
452870 |
XDisplayKeycodes(in->dpy, &kc0, &kc1);
|
|
|
452870 |
KeySym *ks = XGetKeyboardMapping(in->dpy, kc0, kc1 - kc0 + 1, &kk);
|
|
|
452870 |
for(int kc = kc0; kc <= kc1; ++kc) {
|
|
|
452870 |
int found = 1;
|
|
|
452870 |
for(int i = 0; i < kk; ++i, ++ks)
|
|
|
452870 |
if (ks[kc*kk + i]) { found = 0; break; }
|
|
|
452870 |
if (found)
|
|
|
452870 |
{ in->mappedKeyCode = kc; break; }
|
|
|
452870 |
}
|
|
|
452870 |
|
|
|
452870 |
return 1;
|
|
|
452870 |
|
|
|
452870 |
LOGDBG("input: init: found keycode %d", in->mappedKeyCode);
|
|
|
452870 |
if (!in->mappedKeyCode)
|
|
|
452870 |
LOGWRN("input: init: cannot found free keycode for temporary mappings, some keys may not work");
|
|
|
452870 |
|
|
|
452870 |
return 1;
|
|
|
452870 |
}
|
|
|
452870 |
|
|
|
452870 |
|
|
|
452870 |
void inputDeinit(Input *in) {
|
|
|
452870 |
LOGDBG("input: deinit");
|
|
|
452870 |
XCloseDisplay(in->dpy);
|
|
|
452870 |
}
|
|
|
452870 |
|
|
|
452870 |
|
|
|
452870 |
void inputEvent(Input *in, unsigned int keySym, int press) {
|
|
|
452870 |
LOGDBG("input: event: keySym=%u press=%d", keySym, press);
|
|
|
452870 |
|
|
|
452870 |
KeyCode keycode = XKeysymToKeycode(in->dpy, keySym);
|
|
|
452870 |
|
|
|
452870 |
if (!keycode) {
|
|
|
452870 |
if (!in->mappedKeyCode) {
|
|
|
452870 |
LOGWRN("input: event: no keycode mapped to keySym[%u], and no free keycodes for temporary mapping", keySym);
|
|
|
452870 |
return;
|
|
|
452870 |
}
|
|
|
452870 |
|
|
|
452870 |
keycode = in->mappedKeyCode;
|
|
|
452870 |
LOGDBG("input: event: temporary remap: keySym[%u] -> keycode[%hhu]", keySym, keycode);
|
|
|
452870 |
|
|
|
452870 |
if (in->mappedPressed) {
|
|
|
452870 |
LOGWRN("input: event: temporary remap: mapped keys collision, release previously mapped key");
|
|
|
452870 |
XTestFakeKeyEvent(in->dpy, keycode, False, CurrentTime);
|
|
|
452870 |
XSync(in->dpy, False);
|
|
|
452870 |
}
|
|
|
452870 |
|
|
|
452870 |
KeySym ks[2];
|
|
|
452870 |
XConvertCase(keySym, &ks[0], &ks[1]);
|
|
|
452870 |
LOGDBG("input: event: temporary remap: keySym[%u] -> keySyms[%lu, %lu]", keySym, ks[0], ks[1]);
|
|
|
452870 |
XChangeKeyboardMapping(in->dpy, keycode, ks[0] == ks[1] ? 1 : 2, ks, 1);
|
|
|
452870 |
XSync(in->dpy, False);
|
|
|
452870 |
}
|
|
|
452870 |
|
|
|
452870 |
if (keycode == in->mappedKeyCode)
|
|
|
452870 |
in->mappedPressed = press;
|
|
|
452870 |
|
|
|
452870 |
LOGDBG("input: event: keycode=%hhu press=%d", keycode, press);
|
|
|
452870 |
XTestFakeKeyEvent(in->dpy, keycode, press, CurrentTime);
|
|
|
452870 |
XSync(in->dpy, False);
|
|
|
452870 |
}
|
|
|
452870 |
|