From cd9ac70cb9cb1a3d3727c4afe1cef729d92525dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Sun, 15 Jan 2023 16:23:48 +0100 Subject: [PATCH] update XkbAddKeyKeysym. --- server/internal/desktop/xorg/xorg.c | 117 ++++++++++------------------ 1 file changed, 39 insertions(+), 78 deletions(-) diff --git a/server/internal/desktop/xorg/xorg.c b/server/internal/desktop/xorg/xorg.c index 358d85473..aa4e98f7d 100644 --- a/server/internal/desktop/xorg/xorg.c +++ b/server/internal/desktop/xorg/xorg.c @@ -149,98 +149,59 @@ KeyCode XkbKeysymToKeycode(Display* dpy, KeySym keysym) { return keycode; } -static xkeycode_t *xFreeKeycodesHead = NULL; -int xNumcodes = 0; - -void XFreeKeycodesInit(Display* dpy) { - if (xFreeKeycodesHead != NULL) - return; - - KeyCode keycode; - KeySym *keysyms; - int min, max, numcodes; - - // get full keyboard mapping - XDisplayKeycodes(dpy, &min, &max); - keysyms = XGetKeyboardMapping(dpy, min, max-min, &numcodes); - xNumcodes = numcodes; - - // loop through all keycodes - xkeycode_t *last = NULL; - for (int i = min; i <= max; ++i) { - // check if keycode is empty - int isEmpty = 1; - for (int j = 0; j < numcodes; ++j) { - int symindex = ((i - min) * numcodes) + j; - if (keysyms[symindex] != 0) { - isEmpty = 0; - break; - } - } - if (!isEmpty) continue; - - xkeycode_t *entry = (xkeycode_t *) malloc(sizeof(xkeycode_t)); - if (entry == NULL) return; - - entry->keycode = i; - if (last == NULL) { - xFreeKeycodesHead = entry; - } else { - last->next = entry; - } - last = entry; - } +// From https://github.com/TigerVNC/tigervnc/blob/a434ef3377943e89165ac13c537cd0f28be97f84/unix/x0vncserver/XDesktop.cxx#L401-L453 +KeyCode XkbAddKeyKeysym(Display* dpy, KeySym keysym) { + int types[1]; + unsigned int key; + XkbDescPtr xkb; + XkbMapChangesRec changes; + KeySym *syms; + KeySym upper, lower; - // no free keycodes, pick last two keycodes anyway - if (last == NULL) { - xkeycode_t *entry1 = (xkeycode_t *) malloc(sizeof(xkeycode_t)); - if (entry1 == NULL) return; - entry1->keycode = max-1; + xkb = XkbGetMap(dpy, XkbAllComponentsMask, XkbUseCoreKbd); - xkeycode_t *entry2 = (xkeycode_t *) malloc(sizeof(xkeycode_t)); - if (entry2 == NULL) return; - entry2->keycode = max-2; + if (!xkb) + return 0; - xFreeKeycodesHead = entry1; - entry1->next = entry2; - last = entry2; + for (key = xkb->max_key_code; key >= xkb->min_key_code; key--) { + if (XkbKeyNumGroups(xkb, key) == 0) + break; } - // make as circular list - last->next = xFreeKeycodesHead; + // no free keycodes + if (key < xkb->min_key_code) + return 0; - XFree(keysyms); -} + // assign empty structure + changes = *(XkbMapChangesRec *) malloc(sizeof(XkbMapChangesRec)); + for (int i = 0; i < sizeof(changes); i++) ((char *) &changes)[i] = 0; -// get free keycode from list -KeyCode XFreeKeycodeGet() { - if (xFreeKeycodesHead == NULL) - return 0; + XConvertCase(keysym, &lower, &upper); - // move head to next entry - xkeycode_t *entry = xFreeKeycodesHead; - xFreeKeycodesHead = entry->next; + if (upper == lower) + types[XkbGroup1Index] = XkbOneLevelIndex; + else + types[XkbGroup1Index] = XkbAlphabeticIndex; - return entry->keycode; -} + XkbChangeTypesOfKey(xkb, key, 1, XkbGroup1Mask, types, &changes); -// map keysym to new keycode -KeyCode XKeysymMapNew(Display* dpy, KeySym keysym) { - // initialize free keycodes list - if (xFreeKeycodesHead == NULL) { - XFreeKeycodesInit(dpy); + syms = XkbKeySymsPtr(xkb,key); + if (upper == lower) + syms[0] = keysym; + else { + syms[0] = lower; + syms[1] = upper; } - KeyCode keycode = XFreeKeycodeGet(); + changes.changed |= XkbKeySymsMask; + changes.first_key_sym = key; + changes.num_key_syms = 1; - // no free keycodes, cannot map keysym - if (keycode != 0) { - KeySym keysym_list[xNumcodes]; - for(int i=0;i