mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
kecode to keysym respecting modifiers.
This commit is contained in:
parent
5acfae72be
commit
7d06f33ff0
@ -68,25 +68,114 @@ void XButton(unsigned int button, int down) {
|
|||||||
XSync(display, 0);
|
XSync(display, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XKey(unsigned long key, int down) {
|
static xkeyentry_t *pKeysHead = NULL;
|
||||||
if (key == 0) return;
|
|
||||||
|
void XKeyEntryAdd(KeySym keysym, KeyCode keycode) {
|
||||||
|
xkeyentry_t *entry = (xkeyentry_t *) malloc(sizeof(xkeyentry_t));
|
||||||
|
if (entry == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry->keysym = keysym;
|
||||||
|
entry->keycode = keycode;
|
||||||
|
entry->next = pKeysHead;
|
||||||
|
pKeysHead = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyCode XKeyEntryGet(KeySym keysym) {
|
||||||
|
xkeyentry_t *prev = NULL;
|
||||||
|
xkeyentry_t *curr = pKeysHead;
|
||||||
|
|
||||||
|
KeyCode keycode = 0;
|
||||||
|
while (curr != NULL) {
|
||||||
|
if (curr->keysym == keysym) {
|
||||||
|
keycode = curr->keycode;
|
||||||
|
|
||||||
|
if (prev == NULL) {
|
||||||
|
pKeysHead = curr->next;
|
||||||
|
} else {
|
||||||
|
prev->next = curr->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(curr);
|
||||||
|
return keycode;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = curr;
|
||||||
|
curr = curr->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// From https://github.com/TigerVNC/tigervnc/blob/0946e298075f8f7b6d63e552297a787c5f84d27c/unix/x0vncserver/XDesktop.cxx#L343-L379
|
||||||
|
KeyCode KbdXKeysymToKeycode(Display *dpy, KeySym keysym) {
|
||||||
|
XkbDescPtr xkb;
|
||||||
|
XkbStateRec state;
|
||||||
|
unsigned int mods;
|
||||||
|
unsigned keycode;
|
||||||
|
|
||||||
|
xkb = XkbGetMap(dpy, XkbAllComponentsMask, XkbUseCoreKbd);
|
||||||
|
if (!xkb)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
XkbGetState(dpy, XkbUseCoreKbd, &state);
|
||||||
|
// XkbStateFieldFromRec() doesn't work properly because
|
||||||
|
// state.lookup_mods isn't properly updated, so we do this manually
|
||||||
|
mods = XkbBuildCoreState(XkbStateMods(&state), state.group);
|
||||||
|
|
||||||
|
for (keycode = xkb->min_key_code;
|
||||||
|
keycode <= xkb->max_key_code;
|
||||||
|
keycode++) {
|
||||||
|
KeySym cursym;
|
||||||
|
unsigned int out_mods;
|
||||||
|
XkbTranslateKeyCode(xkb, keycode, mods, &out_mods, &cursym);
|
||||||
|
if (cursym == keysym)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keycode > xkb->max_key_code)
|
||||||
|
keycode = 0;
|
||||||
|
|
||||||
|
XkbFreeKeyboard(xkb, XkbAllComponentsMask, True);
|
||||||
|
|
||||||
|
// Shift+Tab is usually ISO_Left_Tab, but RFB hides this fact. Do
|
||||||
|
// another attempt if we failed the initial lookup
|
||||||
|
if ((keycode == 0) && (keysym == XK_Tab) && (mods & ShiftMask))
|
||||||
|
return KbdXKeysymToKeycode(dpy, XK_ISO_Left_Tab);
|
||||||
|
|
||||||
|
return keycode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XKey(KeySym keysym, int down) {
|
||||||
|
if (keysym == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
Display *display = getXDisplay();
|
Display *display = getXDisplay();
|
||||||
KeyCode code = XKeysymToKeycode(display, key);
|
KeyCode keycode = 0;
|
||||||
|
|
||||||
|
if (!down)
|
||||||
|
keycode = XKeyEntryGet(keysym);
|
||||||
|
|
||||||
|
if (keycode == 0)
|
||||||
|
keycode = KbdXKeysymToKeycode(display, keysym);
|
||||||
|
|
||||||
// Map non-existing keysyms to new keycodes
|
// Map non-existing keysyms to new keycodes
|
||||||
if (code == 0) {
|
if (keycode == 0) {
|
||||||
int min, max, numcodes;
|
int min, max, numcodes;
|
||||||
XDisplayKeycodes(display, &min, &max);
|
XDisplayKeycodes(display, &min, &max);
|
||||||
XGetKeyboardMapping(display, min, max-min, &numcodes);
|
XGetKeyboardMapping(display, min, max-min, &numcodes);
|
||||||
|
|
||||||
code = (max-min+1)*numcodes;
|
keycode = (max-min+1)*numcodes;
|
||||||
KeySym keysym_list[numcodes];
|
KeySym keysym_list[numcodes];
|
||||||
for(int i=0;i<numcodes;i++) keysym_list[i] = key;
|
for(int i=0;i<numcodes;i++) keysym_list[i] = keysym;
|
||||||
XChangeKeyboardMapping(display, code, numcodes, keysym_list, 1);
|
XChangeKeyboardMapping(display, keycode, numcodes, keysym_list, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
XTestFakeKeyEvent(display, code, down, CurrentTime);
|
if (down)
|
||||||
|
XKeyEntryAdd(keysym, keycode);
|
||||||
|
|
||||||
|
XTestFakeKeyEvent(display, keycode, down, CurrentTime);
|
||||||
XSync(display, 0);
|
XSync(display, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ func KeyDown(code uint32) error {
|
|||||||
|
|
||||||
debounce_key[code] = time.Now()
|
debounce_key[code] = time.Now()
|
||||||
|
|
||||||
C.XKey(C.ulong(code), C.int(1))
|
C.XKey(C.KeySym(code), C.int(1))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ func KeyUp(code uint32) error {
|
|||||||
|
|
||||||
delete(debounce_key, code)
|
delete(debounce_key, code)
|
||||||
|
|
||||||
C.XKey(C.ulong(code), C.int(0))
|
C.XKey(C.KeySym(code), C.int(0))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ func ResetKeys() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for code := range debounce_key {
|
for code := range debounce_key {
|
||||||
C.XKey(C.ulong(code), C.int(0))
|
C.XKey(C.KeySym(code), C.int(0))
|
||||||
delete(debounce_key, code)
|
delete(debounce_key, code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,7 +172,7 @@ func CheckKeys(duration time.Duration) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
C.XKey(C.ulong(code), C.int(0))
|
C.XKey(C.KeySym(code), C.int(0))
|
||||||
delete(debounce_key, code)
|
delete(debounce_key, code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,17 @@ void XMove(int x, int y);
|
|||||||
void XCursorPosition(int *x, int *y);
|
void XCursorPosition(int *x, int *y);
|
||||||
void XScroll(int x, int y);
|
void XScroll(int x, int y);
|
||||||
void XButton(unsigned int button, int down);
|
void XButton(unsigned int button, int down);
|
||||||
void XKey(unsigned long key, int down);
|
|
||||||
|
typedef struct xkeyentry_t {
|
||||||
|
KeySym keysym;
|
||||||
|
KeyCode keycode;
|
||||||
|
struct xkeyentry_t *next;
|
||||||
|
} xkeyentry_t;
|
||||||
|
|
||||||
|
static void XKeyEntryAdd(KeySym keysym, KeyCode keycode);
|
||||||
|
static KeyCode XKeyEntryGet(KeySym keysym);
|
||||||
|
static KeyCode XKeysymToKeycodeRespectingModifiers(Display *display, KeySym keysym);
|
||||||
|
void XKey(KeySym keysym, int down);
|
||||||
|
|
||||||
void XGetScreenConfigurations();
|
void XGetScreenConfigurations();
|
||||||
void XSetScreenConfiguration(int index, short rate);
|
void XSetScreenConfiguration(int index, short rate);
|
||||||
|
Loading…
Reference in New Issue
Block a user