Blame input.c

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