From be3453c37d1a347c09e906c5e46f2e39bbb02a2e Mon Sep 17 00:00:00 2001 From: mbattista Date: Sat, 10 Apr 2021 11:43:04 +0000 Subject: [PATCH 01/18] pressing key with multiple pressed keys --- server/internal/remote/manager.go | 6 +- server/internal/xorg/xorg.c | 128 +++++++++++++++++++++++++++--- 2 files changed, 121 insertions(+), 13 deletions(-) diff --git a/server/internal/remote/manager.go b/server/internal/remote/manager.go index 20fd34db..a66d9ca6 100644 --- a/server/internal/remote/manager.go +++ b/server/internal/remote/manager.go @@ -248,9 +248,9 @@ func (manager *RemoteManager) SetKeyboardLayout(layout string) { // Workaround for https://github.com/m1k1o/neko/issues/45 // When pressing `shift` + `,` instead of `<` comes `>`. variant := "" - if layout == "us" { - variant = "mac" // TODO: Test all keys. - } +// if layout == "us" { +// variant = "mac" // TODO: Test all keys. +// } exec.Command("setxkbmap", layout, variant).Run() } diff --git a/server/internal/xorg/xorg.c b/server/internal/xorg/xorg.c index 3acb27b8..1669fa43 100644 --- a/server/internal/xorg/xorg.c +++ b/server/internal/xorg/xorg.c @@ -6,6 +6,69 @@ static char *NAME = ":0.0"; static int REGISTERED = 0; static int DIRTY = 0; +struct linked_list +{ + unsigned long number; + int keycode; + struct linked_list *next; +}; + +typedef struct linked_list node; +node *head=NULL, *last=NULL; + +void insertAtLast(unsigned long value, int keycode) { + node *temp_node; + temp_node = (node *) malloc(sizeof(node)); + + temp_node->number = value; + temp_node->keycode = keycode; + temp_node->next = NULL; + + //For the 1st element + if(head == NULL) { + head = temp_node; + last = temp_node; + } else { + last->next = temp_node; + last = temp_node; + } +} + +void deleteItem(int value) { + node *myNode = head, *previous=NULL; + + while(myNode!=NULL) { + if(myNode->number==value) { + if(previous==NULL) + head = myNode->next; + else + previous->next = myNode->next; + + free(myNode); //need to free up the memory to prevent memory leak + break; + } + + previous = myNode; + myNode = myNode->next; + } +} + +int searchItem(int value) { + node *searchNode = head; + int flag = 0; + + while(searchNode != NULL) { + if(searchNode->number==value) { + flag = searchNode->keycode; + break; + } else { + searchNode = searchNode->next; + } + } + + return flag; +} + Display *getXDisplay(void) { /* Close the display if displayName has changed */ if (DIRTY) { @@ -96,21 +159,66 @@ void XButton(unsigned int button, int down) { } } +KeyCode XkbKeysymToKeycode(KeySym keysym) { + XkbDescPtr xkb; + XkbStateRec state; + unsigned keycode; + Display *dpy = getXDisplay(); + + xkb = XkbGetMap(dpy, XkbAllComponentsMask, XkbUseCoreKbd); + if (!xkb) + return 0; + + XkbGetState(dpy, XkbUseCoreKbd, &state); + + for (keycode = xkb->min_key_code; + keycode <= xkb->max_key_code; + keycode++) { + KeySym cursym; + unsigned int mods; + XkbTranslateKeyCode(xkb, keycode, state.compat_state, &mods, &cursym); + if (cursym == keysym) + break; + } + + if (keycode > xkb->max_key_code) + keycode = 0; + + XkbFreeKeyboard(xkb, XkbAllComponentsMask, True); + + return keycode; +} + void XKey(unsigned long key, int down) { if (key != 0) { Display *display = getXDisplay(); - KeyCode code = XKeysymToKeycode(display, key); +// KeyCode code = XKeysymToKeycode(display, key); - // Map non-existing keysyms to new keycodes - if(code == 0) { - int min, max, numcodes; - XDisplayKeycodes(display, &min, &max); - XGetKeyboardMapping(display, min, max-min, &numcodes); + int code; - code = (max-min+1)*numcodes; - KeySym keysym_list[numcodes]; - for(int i=0;i Date: Sat, 10 Apr 2021 23:17:05 +0000 Subject: [PATCH 02/18] with comments for if stucts are needed later --- server/internal/xorg/xorg.c | 105 ++++++++++++++++++++--------------- server/internal/xorg/xorg.go | 10 +++- server/internal/xorg/xorg.h | 2 +- 3 files changed, 69 insertions(+), 48 deletions(-) diff --git a/server/internal/xorg/xorg.c b/server/internal/xorg/xorg.c index 1669fa43..1952a30a 100644 --- a/server/internal/xorg/xorg.c +++ b/server/internal/xorg/xorg.c @@ -9,14 +9,14 @@ static int DIRTY = 0; struct linked_list { unsigned long number; - int keycode; + KeyCode keycode; struct linked_list *next; }; typedef struct linked_list node; -node *head=NULL, *last=NULL; +node *head = NULL, *last = NULL; -void insertAtLast(unsigned long value, int keycode) { +void insertAtLast(unsigned long value, KeyCode keycode) { node *temp_node; temp_node = (node *) malloc(sizeof(node)); @@ -25,7 +25,7 @@ void insertAtLast(unsigned long value, int keycode) { temp_node->next = NULL; //For the 1st element - if(head == NULL) { + if(!head) { head = temp_node; last = temp_node; } else { @@ -34,17 +34,17 @@ void insertAtLast(unsigned long value, int keycode) { } } -void deleteItem(int value) { - node *myNode = head, *previous=NULL; +void deleteItem(unsigned long value) { + node *myNode = head, *previous = NULL; - while(myNode!=NULL) { - if(myNode->number==value) { - if(previous==NULL) + while(myNode) { + if(myNode->number == value) { + if(!previous) head = myNode->next; else previous->next = myNode->next; - free(myNode); //need to free up the memory to prevent memory leak + free(myNode); break; } @@ -53,20 +53,18 @@ void deleteItem(int value) { } } -int searchItem(int value) { +node *searchItemNode(unsigned long value) { node *searchNode = head; - int flag = 0; - while(searchNode != NULL) { - if(searchNode->number==value) { - flag = searchNode->keycode; + while(searchNode) { + if(searchNode->number == value) { break; } else { searchNode = searchNode->next; } } - return flag; + return searchNode; } Display *getXDisplay(void) { @@ -189,41 +187,58 @@ KeyCode XkbKeysymToKeycode(KeySym keysym) { return keycode; } -void XKey(unsigned long key, int down) { - if (key != 0) { - Display *display = getXDisplay(); -// KeyCode code = XKeysymToKeycode(display, key); +int XKey(unsigned long key, int down) { + Display *display = getXDisplay(); + KeyCode code = -2; +// node *compareNode; +// compareNode = searchItemNode(key); - int code; + if (down) { +// if (compareNode && compareNode != last) { +// code = compareNode->keycode; +// } else { + code = XkbKeysymToKeycode(key); + if (!code) { + int min, max, numcodes; + XDisplayKeycodes(display, &min, &max); + XGetKeyboardMapping(display, min, max-min, &numcodes); - if (down) { - code = searchItem(key); - if (code == 0) { - // XKeysymToKeycode() doesn't respect state, so we have to use - // something slightly more complex - code = XkbKeysymToKeycode(key); - // Map non-existing keysyms to new keycodes - if(code == 0) { - int min, max, numcodes; - XDisplayKeycodes(display, &min, &max); - XGetKeyboardMapping(display, min, max-min, &numcodes); - - code = (max-min+1)*numcodes; - KeySym keysym_list[numcodes]; - for(int i=0;ikeycode; + + code = XkbKeysymToKeycode(key); + if (!code) { + int min, max, numcodes; + XDisplayKeycodes(display, &min, &max); + XGetKeyboardMapping(display, min, max-min, &numcodes); + + code = (max-min+1)*numcodes; + KeySym keysym_list[numcodes]; + for(int i=0;i Date: Sat, 10 Apr 2021 23:22:37 +0000 Subject: [PATCH 03/18] list not really needed --- server/internal/xorg/xorg.c | 127 +++++++---------------------------- server/internal/xorg/xorg.go | 8 +-- 2 files changed, 28 insertions(+), 107 deletions(-) diff --git a/server/internal/xorg/xorg.c b/server/internal/xorg/xorg.c index 1952a30a..b076f47b 100644 --- a/server/internal/xorg/xorg.c +++ b/server/internal/xorg/xorg.c @@ -6,67 +6,6 @@ static char *NAME = ":0.0"; static int REGISTERED = 0; static int DIRTY = 0; -struct linked_list -{ - unsigned long number; - KeyCode keycode; - struct linked_list *next; -}; - -typedef struct linked_list node; -node *head = NULL, *last = NULL; - -void insertAtLast(unsigned long value, KeyCode keycode) { - node *temp_node; - temp_node = (node *) malloc(sizeof(node)); - - temp_node->number = value; - temp_node->keycode = keycode; - temp_node->next = NULL; - - //For the 1st element - if(!head) { - head = temp_node; - last = temp_node; - } else { - last->next = temp_node; - last = temp_node; - } -} - -void deleteItem(unsigned long value) { - node *myNode = head, *previous = NULL; - - while(myNode) { - if(myNode->number == value) { - if(!previous) - head = myNode->next; - else - previous->next = myNode->next; - - free(myNode); - break; - } - - previous = myNode; - myNode = myNode->next; - } -} - -node *searchItemNode(unsigned long value) { - node *searchNode = head; - - while(searchNode) { - if(searchNode->number == value) { - break; - } else { - searchNode = searchNode->next; - } - } - - return searchNode; -} - Display *getXDisplay(void) { /* Close the display if displayName has changed */ if (DIRTY) { @@ -190,55 +129,41 @@ KeyCode XkbKeysymToKeycode(KeySym keysym) { int XKey(unsigned long key, int down) { Display *display = getXDisplay(); KeyCode code = -2; -// node *compareNode; -// compareNode = searchItemNode(key); if (down) { -// if (compareNode && compareNode != last) { -// code = compareNode->keycode; -// } else { - code = XkbKeysymToKeycode(key); - if (!code) { - int min, max, numcodes; - XDisplayKeycodes(display, &min, &max); - XGetKeyboardMapping(display, min, max-min, &numcodes); + code = XkbKeysymToKeycode(key); + if (!code) { + int min, max, numcodes; + XDisplayKeycodes(display, &min, &max); + XGetKeyboardMapping(display, min, max-min, &numcodes); - code = (max-min+1)*numcodes; - KeySym keysym_list[numcodes]; - for(int i=0;ikeycode; + code = XkbKeysymToKeycode(key); + if (!code) { + int min, max, numcodes; + XDisplayKeycodes(display, &min, &max); + XGetKeyboardMapping(display, min, max-min, &numcodes); - code = XkbKeysymToKeycode(key); - if (!code) { - int min, max, numcodes; - XDisplayKeycodes(display, &min, &max); - XGetKeyboardMapping(display, min, max-min, &numcodes); + code = (max-min+1)*numcodes; + KeySym keysym_list[numcodes]; + for(int i=0;i Date: Sat, 10 Apr 2021 23:33:58 +0000 Subject: [PATCH 04/18] duplicated code --- server/internal/xorg/xorg.c | 45 +++++++++++-------------------------- 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/server/internal/xorg/xorg.c b/server/internal/xorg/xorg.c index b076f47b..885dbd48 100644 --- a/server/internal/xorg/xorg.c +++ b/server/internal/xorg/xorg.c @@ -130,40 +130,21 @@ int XKey(unsigned long key, int down) { Display *display = getXDisplay(); KeyCode code = -2; - if (down) { - code = XkbKeysymToKeycode(key); - if (!code) { - int min, max, numcodes; - XDisplayKeycodes(display, &min, &max); - XGetKeyboardMapping(display, min, max-min, &numcodes); + code = XkbKeysymToKeycode(key); + if (!code) { + int min, max, numcodes; + XDisplayKeycodes(display, &min, &max); + XGetKeyboardMapping(display, min, max-min, &numcodes); - code = (max-min+1)*numcodes; - KeySym keysym_list[numcodes]; - for(int i=0;i Date: Sat, 10 Apr 2021 23:48:23 +0000 Subject: [PATCH 05/18] more cleanup --- server/internal/xorg/xorg.c | 6 +++--- server/internal/xorg/xorg.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server/internal/xorg/xorg.c b/server/internal/xorg/xorg.c index 885dbd48..ab716eee 100644 --- a/server/internal/xorg/xorg.c +++ b/server/internal/xorg/xorg.c @@ -126,9 +126,9 @@ KeyCode XkbKeysymToKeycode(KeySym keysym) { return keycode; } -int XKey(unsigned long key, int down) { +void XKey(unsigned long key, int down) { Display *display = getXDisplay(); - KeyCode code = -2; + KeyCode code = 0; code = XkbKeysymToKeycode(key); if (!code) { @@ -142,7 +142,7 @@ int XKey(unsigned long key, int down) { XChangeKeyboardMapping(display, code, numcodes, keysym_list, 1); } if (!code) - return -1; + return; XTestFakeKeyEvent(display, code, down, CurrentTime); XSync(display, 0); } diff --git a/server/internal/xorg/xorg.h b/server/internal/xorg/xorg.h index e561c2dd..5e102606 100644 --- a/server/internal/xorg/xorg.h +++ b/server/internal/xorg/xorg.h @@ -27,7 +27,7 @@ void XMove(int x, int y); void XScroll(int x, int y); void XButton(unsigned int button, int down); - int XKey(unsigned long key, int down); + void XKey(unsigned long key, int down); void XClipboardSet(char *src); char *XClipboardGet(); From 07d111af367f78d91e78bcd17c4df548f40ab7e0 Mon Sep 17 00:00:00 2001 From: mbattista Date: Sun, 11 Apr 2021 08:35:54 +0000 Subject: [PATCH 06/18] readded list. removed bug. --- server/internal/xorg/xorg.c | 86 ++++++++++++++++++++++++++++++++++++ server/internal/xorg/xorg.go | 2 +- 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/server/internal/xorg/xorg.c b/server/internal/xorg/xorg.c index ab716eee..60ca8e65 100644 --- a/server/internal/xorg/xorg.c +++ b/server/internal/xorg/xorg.c @@ -6,6 +6,72 @@ static char *NAME = ":0.0"; static int REGISTERED = 0; static int DIRTY = 0; +struct linked_list +{ + unsigned long number; + KeyCode keycode; + struct linked_list *next; +}; + +typedef struct linked_list node; +node *head = NULL, *last = NULL; + +void insertAtLast(unsigned long value, KeyCode keycode) { + node *temp_node; + temp_node = (node *) malloc(sizeof(node)); + + temp_node->number = value; + temp_node->keycode = keycode; + temp_node->next = NULL; + + //For the 1st element + if(!head) { + head = temp_node; + last = temp_node; + } else { + last->next = temp_node; + last = temp_node; + } +} + +void deleteItem(unsigned long value) { + node *myNode = head, *previous = NULL; + + while(myNode) { + if(myNode->number == value) { + if(!previous) + head = myNode->next; + else + previous->next = myNode->next; + + free(myNode); + break; + } + + previous = myNode; + myNode = myNode->next; + } +} + +node *searchItemNode(unsigned long value) { + node *searchNode = head; + bool foundNode = false; + + while(searchNode) { + if(searchNode->number == value) { + foundNode = true; + break; + } else { + searchNode = searchNode->next; + } + } + + if (foundNode) + return searchNode; + + return NULL; +} + Display *getXDisplay(void) { /* Close the display if displayName has changed */ if (DIRTY) { @@ -129,6 +195,22 @@ KeyCode XkbKeysymToKeycode(KeySym keysym) { void XKey(unsigned long key, int down) { Display *display = getXDisplay(); KeyCode code = 0; + node *compareNode; + + // Key is released. Look it up + if (!down) { + compareNode = searchItemNode(key); + + // The key is known, use the known KeyCode + if (compareNode) { + code = compareNode->keycode; + XTestFakeKeyEvent(display, code, down, CurrentTime); + XSync(display, 0); + + deleteItem(key); + return; + } + } code = XkbKeysymToKeycode(key); if (!code) { @@ -143,6 +225,10 @@ void XKey(unsigned long key, int down) { } if (!code) return; + + if (down) { + insertAtLast(key, code); + } XTestFakeKeyEvent(display, code, down, CurrentTime); XSync(display, 0); } diff --git a/server/internal/xorg/xorg.go b/server/internal/xorg/xorg.go index 107f4387..6243e4d0 100644 --- a/server/internal/xorg/xorg.go +++ b/server/internal/xorg/xorg.go @@ -75,7 +75,7 @@ func KeyDown(code uint64) error { debounce_key[code] = time.Now() - C.XKey(C.ulong(code), C.int(1)) + C.XKey(C.ulong(code), C.int(1)) return nil } From c54e8327ac9b2983dea80928707ac38d6d5bc44c Mon Sep 17 00:00:00 2001 From: m1k1o Date: Sun, 11 Apr 2021 12:12:06 +0200 Subject: [PATCH 07/18] revert 'workaround for #45.' --- server/internal/remote/manager.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/server/internal/remote/manager.go b/server/internal/remote/manager.go index a66d9ca6..02db80fd 100644 --- a/server/internal/remote/manager.go +++ b/server/internal/remote/manager.go @@ -245,14 +245,7 @@ func (manager *RemoteManager) GetScreenSize() *types.ScreenSize { } func (manager *RemoteManager) SetKeyboardLayout(layout string) { - // Workaround for https://github.com/m1k1o/neko/issues/45 - // When pressing `shift` + `,` instead of `<` comes `>`. - variant := "" -// if layout == "us" { -// variant = "mac" // TODO: Test all keys. -// } - - exec.Command("setxkbmap", layout, variant).Run() + exec.Command("setxkbmap", layout).Run() } func (manager *RemoteManager) SetKeyboardModifiers(NumLock int, CapsLock int, ScrollLock int) { From b2effce0e709622be721911ee09e147ae69d92b3 Mon Sep 17 00:00:00 2001 From: m1k1o Date: Sun, 11 Apr 2021 12:25:02 +0200 Subject: [PATCH 08/18] lint fix. --- server/internal/xorg/xorg.c | 49 ++++++++++++++++-------------------- server/internal/xorg/xorg.go | 3 +-- 2 files changed, 22 insertions(+), 30 deletions(-) diff --git a/server/internal/xorg/xorg.c b/server/internal/xorg/xorg.c index 60ca8e65..1908cdfc 100644 --- a/server/internal/xorg/xorg.c +++ b/server/internal/xorg/xorg.c @@ -6,26 +6,23 @@ static char *NAME = ":0.0"; static int REGISTERED = 0; static int DIRTY = 0; -struct linked_list -{ - unsigned long number; - KeyCode keycode; - struct linked_list *next; -}; +typedef struct linked_list { + unsigned long number; + KeyCode keycode; + struct linked_list *next; +} node; -typedef struct linked_list node; node *head = NULL, *last = NULL; void insertAtLast(unsigned long value, KeyCode keycode) { - node *temp_node; - temp_node = (node *) malloc(sizeof(node)); + node *temp_node = (node *) malloc(sizeof(node)); temp_node->number = value; temp_node->keycode = keycode; temp_node->next = NULL; - //For the 1st element - if(!head) { + // For the 1st element + if (!head) { head = temp_node; last = temp_node; } else { @@ -37,9 +34,9 @@ void insertAtLast(unsigned long value, KeyCode keycode) { void deleteItem(unsigned long value) { node *myNode = head, *previous = NULL; - while(myNode) { - if(myNode->number == value) { - if(!previous) + while (myNode) { + if (myNode->number == value) { + if (!previous) head = myNode->next; else previous->next = myNode->next; @@ -55,19 +52,14 @@ void deleteItem(unsigned long value) { node *searchItemNode(unsigned long value) { node *searchNode = head; - bool foundNode = false; - while(searchNode) { - if(searchNode->number == value) { - foundNode = true; - break; - } else { - searchNode = searchNode->next; + while (searchNode) { + if (searchNode->number == value) { + return searchNode; } - } - if (foundNode) - return searchNode; + searchNode = searchNode->next; + } return NULL; } @@ -220,15 +212,16 @@ void XKey(unsigned long key, int down) { code = (max-min+1)*numcodes; KeySym keysym_list[numcodes]; - for(int i=0;i Date: Sun, 11 Apr 2021 12:26:45 +0200 Subject: [PATCH 09/18] remove additional newline. --- server/internal/xorg/xorg.go | 1 - 1 file changed, 1 deletion(-) diff --git a/server/internal/xorg/xorg.go b/server/internal/xorg/xorg.go index 181be696..2086e3d5 100644 --- a/server/internal/xorg/xorg.go +++ b/server/internal/xorg/xorg.go @@ -76,7 +76,6 @@ func KeyDown(code uint64) error { debounce_key[code] = time.Now() C.XKey(C.ulong(code), C.int(1)) - return nil } From 9386cbb2e2a6e1acbc9815f6cbaa37c0e863bf01 Mon Sep 17 00:00:00 2001 From: mbattista Date: Sun, 11 Apr 2021 12:38:18 +0000 Subject: [PATCH 10/18] append -> insert --- server/internal/xorg/xorg.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/server/internal/xorg/xorg.c b/server/internal/xorg/xorg.c index 1908cdfc..d5702f61 100644 --- a/server/internal/xorg/xorg.c +++ b/server/internal/xorg/xorg.c @@ -12,9 +12,9 @@ typedef struct linked_list { struct linked_list *next; } node; -node *head = NULL, *last = NULL; +node *head = NULL; -void insertAtLast(unsigned long value, KeyCode keycode) { +void insertItem(unsigned long value, KeyCode keycode) { node *temp_node = (node *) malloc(sizeof(node)); temp_node->number = value; @@ -22,13 +22,10 @@ void insertAtLast(unsigned long value, KeyCode keycode) { temp_node->next = NULL; // For the 1st element - if (!head) { - head = temp_node; - last = temp_node; - } else { - last->next = temp_node; - last = temp_node; + if (head) { + temp_node->next = head; } + head = temp_node; } void deleteItem(unsigned long value) { @@ -220,7 +217,7 @@ void XKey(unsigned long key, int down) { return; if (down) - insertAtLast(key, code); + insertItem(key, code); XTestFakeKeyEvent(display, code, down, CurrentTime); XSync(display, 0); From 7f226842df323f2614ee1cbb4fc16cc6db20c761 Mon Sep 17 00:00:00 2001 From: mbattista Date: Mon, 12 Apr 2021 14:16:57 +0000 Subject: [PATCH 11/18] loopbreaker and fixes --- server/internal/xorg/xorg.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/server/internal/xorg/xorg.c b/server/internal/xorg/xorg.c index d5702f61..0fb37052 100644 --- a/server/internal/xorg/xorg.c +++ b/server/internal/xorg/xorg.c @@ -30,6 +30,7 @@ void insertItem(unsigned long value, KeyCode keycode) { void deleteItem(unsigned long value) { node *myNode = head, *previous = NULL; + int i = 0; while (myNode) { if (myNode->number == value) { @@ -44,11 +45,17 @@ void deleteItem(unsigned long value) { previous = myNode; myNode = myNode->next; + if (i++ > 120) { + // this should lead to a panic + printf("loop over limit"); + break; + } } } node *searchItemNode(unsigned long value) { node *searchNode = head; + int i = 0; while (searchNode) { if (searchNode->number == value) { @@ -56,6 +63,12 @@ node *searchItemNode(unsigned long value) { } searchNode = searchNode->next; + + if (i++ > 120) { + // this should lead to a panic + printf("loop over limit"); + break; + } } return NULL; @@ -151,24 +164,27 @@ void XButton(unsigned int button, int down) { } } -KeyCode XkbKeysymToKeycode(KeySym keysym) { +KeyCode XkbKeysymToKeycode(Display *dpy, KeySym keysym) { XkbDescPtr xkb; XkbStateRec state; + unsigned int mods; unsigned keycode; - Display *dpy = getXDisplay(); 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 mods; - XkbTranslateKeyCode(xkb, keycode, state.compat_state, &mods, &cursym); + unsigned int out_mods; + XkbTranslateKeyCode(xkb, keycode, mods, &out_mods, &cursym); if (cursym == keysym) break; } @@ -178,6 +194,11 @@ KeyCode XkbKeysymToKeycode(KeySym keysym) { 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 XkbKeysymToKeycode(dpy, XK_ISO_Left_Tab); + return keycode; } @@ -201,7 +222,7 @@ void XKey(unsigned long key, int down) { } } - code = XkbKeysymToKeycode(key); + code = XkbKeysymToKeycode(display, key); if (!code) { int min, max, numcodes; XDisplayKeycodes(display, &min, &max); From b169195b6962f1a20d02ebd0de6f1258b717b623 Mon Sep 17 00:00:00 2001 From: m1k1o Date: Mon, 12 Apr 2021 19:22:59 +0200 Subject: [PATCH 12/18] xorg ulong -> KeySym. --- server/internal/xorg/xorg.c | 16 ++++++++-------- server/internal/xorg/xorg.go | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/server/internal/xorg/xorg.c b/server/internal/xorg/xorg.c index 0fb37052..6ee518f2 100644 --- a/server/internal/xorg/xorg.c +++ b/server/internal/xorg/xorg.c @@ -7,17 +7,17 @@ static int REGISTERED = 0; static int DIRTY = 0; typedef struct linked_list { - unsigned long number; + KeySym keysym; KeyCode keycode; struct linked_list *next; } node; node *head = NULL; -void insertItem(unsigned long value, KeyCode keycode) { +void insertItem(KeySym keysym, KeyCode keycode) { node *temp_node = (node *) malloc(sizeof(node)); - temp_node->number = value; + temp_node->keysym = keysym; temp_node->keycode = keycode; temp_node->next = NULL; @@ -28,12 +28,12 @@ void insertItem(unsigned long value, KeyCode keycode) { head = temp_node; } -void deleteItem(unsigned long value) { +void deleteItem(KeySym keysym) { node *myNode = head, *previous = NULL; int i = 0; while (myNode) { - if (myNode->number == value) { + if (myNode->keysym == keysym) { if (!previous) head = myNode->next; else @@ -53,12 +53,12 @@ void deleteItem(unsigned long value) { } } -node *searchItemNode(unsigned long value) { +node *searchItemNode(KeySym keysym) { node *searchNode = head; int i = 0; while (searchNode) { - if (searchNode->number == value) { + if (searchNode->keysym == keysym) { return searchNode; } @@ -202,7 +202,7 @@ KeyCode XkbKeysymToKeycode(Display *dpy, KeySym keysym) { return keycode; } -void XKey(unsigned long key, int down) { +void XKey(KeySym key, int down) { Display *display = getXDisplay(); KeyCode code = 0; node *compareNode; diff --git a/server/internal/xorg/xorg.go b/server/internal/xorg/xorg.go index 2086e3d5..015ec4a1 100644 --- a/server/internal/xorg/xorg.go +++ b/server/internal/xorg/xorg.go @@ -75,7 +75,7 @@ func KeyDown(code uint64) error { debounce_key[code] = time.Now() - C.XKey(C.ulong(code), C.int(1)) + C.XKey(C.KeySym(code), C.int(1)) return nil } @@ -103,7 +103,7 @@ func KeyUp(code uint64) error { delete(debounce_key, code) - C.XKey(C.ulong(code), C.int(0)) + C.XKey(C.KeySym(code), C.int(0)) return nil } From 285d4b630b75cb72ba243a27a6f655b7eec62a9b Mon Sep 17 00:00:00 2001 From: m1k1o Date: Mon, 12 Apr 2021 19:29:19 +0200 Subject: [PATCH 13/18] node -> xkeys_t, moved to .h file. --- server/internal/xorg/xorg.c | 18 ++++++------------ server/internal/xorg/xorg.h | 6 ++++++ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/server/internal/xorg/xorg.c b/server/internal/xorg/xorg.c index 6ee518f2..e46d0ab6 100644 --- a/server/internal/xorg/xorg.c +++ b/server/internal/xorg/xorg.c @@ -6,16 +6,10 @@ static char *NAME = ":0.0"; static int REGISTERED = 0; static int DIRTY = 0; -typedef struct linked_list { - KeySym keysym; - KeyCode keycode; - struct linked_list *next; -} node; - -node *head = NULL; +xkeys_t *head = NULL; void insertItem(KeySym keysym, KeyCode keycode) { - node *temp_node = (node *) malloc(sizeof(node)); + xkeys_t *temp_node = (xkeys_t *) malloc(sizeof(xkeys_t)); temp_node->keysym = keysym; temp_node->keycode = keycode; @@ -29,7 +23,7 @@ void insertItem(KeySym keysym, KeyCode keycode) { } void deleteItem(KeySym keysym) { - node *myNode = head, *previous = NULL; + xkeys_t *myNode = head, *previous = NULL; int i = 0; while (myNode) { @@ -53,8 +47,8 @@ void deleteItem(KeySym keysym) { } } -node *searchItemNode(KeySym keysym) { - node *searchNode = head; +xkeys_t *searchItemNode(KeySym keysym) { + xkeys_t *searchNode = head; int i = 0; while (searchNode) { @@ -205,7 +199,7 @@ KeyCode XkbKeysymToKeycode(Display *dpy, KeySym keysym) { void XKey(KeySym key, int down) { Display *display = getXDisplay(); KeyCode code = 0; - node *compareNode; + xkeys_t *compareNode; // Key is released. Look it up if (!down) { diff --git a/server/internal/xorg/xorg.h b/server/internal/xorg/xorg.h index 5e102606..bdef5a5b 100644 --- a/server/internal/xorg/xorg.h +++ b/server/internal/xorg/xorg.h @@ -16,6 +16,12 @@ extern void goCreateScreenSize(int index, int width, int height, int mwidth, int mheight); extern void goSetScreenRates(int index, int rate_index, short rate); + typedef struct xkeys_t { + KeySym keysym; + KeyCode keycode; + struct xkeys_t *next; + } xkeys_t; + /* Returns the main display, closed either on exit or when closeMainDisplay() * is invoked. This removes a bit of the overhead of calling XOpenDisplay() & * XCloseDisplay() everytime the main display needs to be used. From 1307236f86dc1965386df16986d079315f7bd55c Mon Sep 17 00:00:00 2001 From: m1k1o Date: Mon, 12 Apr 2021 19:30:19 +0200 Subject: [PATCH 14/18] change head list name. --- server/internal/xorg/xorg.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/server/internal/xorg/xorg.c b/server/internal/xorg/xorg.c index e46d0ab6..03bec969 100644 --- a/server/internal/xorg/xorg.c +++ b/server/internal/xorg/xorg.c @@ -6,30 +6,25 @@ static char *NAME = ":0.0"; static int REGISTERED = 0; static int DIRTY = 0; -xkeys_t *head = NULL; +xkeys_t *xKeysHead = NULL; void insertItem(KeySym keysym, KeyCode keycode) { xkeys_t *temp_node = (xkeys_t *) malloc(sizeof(xkeys_t)); temp_node->keysym = keysym; temp_node->keycode = keycode; - temp_node->next = NULL; - - // For the 1st element - if (head) { - temp_node->next = head; - } - head = temp_node; + temp_node->next = xKeysHead; + xKeysHead = temp_node; } void deleteItem(KeySym keysym) { - xkeys_t *myNode = head, *previous = NULL; + xkeys_t *myNode = xKeysHead, *previous = NULL; int i = 0; while (myNode) { if (myNode->keysym == keysym) { if (!previous) - head = myNode->next; + xKeysHead = myNode->next; else previous->next = myNode->next; @@ -48,7 +43,7 @@ void deleteItem(KeySym keysym) { } xkeys_t *searchItemNode(KeySym keysym) { - xkeys_t *searchNode = head; + xkeys_t *searchNode = xKeysHead; int i = 0; while (searchNode) { From 1ec8bd34a66542b0d1910ad442a9da2da486afef Mon Sep 17 00:00:00 2001 From: m1k1o Date: Mon, 12 Apr 2021 19:38:13 +0200 Subject: [PATCH 15/18] xorg join search + delete to pop. --- server/internal/xorg/xorg.c | 51 +++++++++---------------------------- 1 file changed, 12 insertions(+), 39 deletions(-) diff --git a/server/internal/xorg/xorg.c b/server/internal/xorg/xorg.c index 03bec969..b8e30884 100644 --- a/server/internal/xorg/xorg.c +++ b/server/internal/xorg/xorg.c @@ -8,7 +8,7 @@ static int DIRTY = 0; xkeys_t *xKeysHead = NULL; -void insertItem(KeySym keysym, KeyCode keycode) { +void XKeysInsert(KeySym keysym, KeyCode keycode) { xkeys_t *temp_node = (xkeys_t *) malloc(sizeof(xkeys_t)); temp_node->keysym = keysym; @@ -17,19 +17,22 @@ void insertItem(KeySym keysym, KeyCode keycode) { xKeysHead = temp_node; } -void deleteItem(KeySym keysym) { +KeyCode XKeysPop(KeySym keysym) { xkeys_t *myNode = xKeysHead, *previous = NULL; + KeyCode keycode = 0; int i = 0; while (myNode) { if (myNode->keysym == keysym) { + keycode = myNode->keycode; + if (!previous) xKeysHead = myNode->next; else previous->next = myNode->next; free(myNode); - break; + return keycode; } previous = myNode; @@ -40,27 +43,8 @@ void deleteItem(KeySym keysym) { break; } } -} -xkeys_t *searchItemNode(KeySym keysym) { - xkeys_t *searchNode = xKeysHead; - int i = 0; - - while (searchNode) { - if (searchNode->keysym == keysym) { - return searchNode; - } - - searchNode = searchNode->next; - - if (i++ > 120) { - // this should lead to a panic - printf("loop over limit"); - break; - } - } - - return NULL; + return 0; } Display *getXDisplay(void) { @@ -194,24 +178,13 @@ KeyCode XkbKeysymToKeycode(Display *dpy, KeySym keysym) { void XKey(KeySym key, int down) { Display *display = getXDisplay(); KeyCode code = 0; - xkeys_t *compareNode; - // Key is released. Look it up - if (!down) { - compareNode = searchItemNode(key); + if (!down) + code = XKeysPop(key); - // The key is known, use the known KeyCode - if (compareNode) { - code = compareNode->keycode; - XTestFakeKeyEvent(display, code, down, CurrentTime); - XSync(display, 0); + if (!code) + code = XkbKeysymToKeycode(display, key); - deleteItem(key); - return; - } - } - - code = XkbKeysymToKeycode(display, key); if (!code) { int min, max, numcodes; XDisplayKeycodes(display, &min, &max); @@ -227,7 +200,7 @@ void XKey(KeySym key, int down) { return; if (down) - insertItem(key, code); + XKeysInsert(key, code); XTestFakeKeyEvent(display, code, down, CurrentTime); XSync(display, 0); From b13b1907f4c8c33053563599a90ca7f6f6456cc0 Mon Sep 17 00:00:00 2001 From: m1k1o Date: Mon, 12 Apr 2021 19:41:36 +0200 Subject: [PATCH 16/18] xorg simplifz names. --- server/internal/xorg/xorg.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/server/internal/xorg/xorg.c b/server/internal/xorg/xorg.c index b8e30884..8861c456 100644 --- a/server/internal/xorg/xorg.c +++ b/server/internal/xorg/xorg.c @@ -9,34 +9,35 @@ static int DIRTY = 0; xkeys_t *xKeysHead = NULL; void XKeysInsert(KeySym keysym, KeyCode keycode) { - xkeys_t *temp_node = (xkeys_t *) malloc(sizeof(xkeys_t)); + xkeys_t *node = (xkeys_t *) malloc(sizeof(xkeys_t)); - temp_node->keysym = keysym; - temp_node->keycode = keycode; - temp_node->next = xKeysHead; - xKeysHead = temp_node; + node->keysym = keysym; + node->keycode = keycode; + node->next = xKeysHead; + xKeysHead = node; } KeyCode XKeysPop(KeySym keysym) { - xkeys_t *myNode = xKeysHead, *previous = NULL; KeyCode keycode = 0; + xkeys_t *node = xKeysHead, + *previous = NULL; int i = 0; - while (myNode) { - if (myNode->keysym == keysym) { - keycode = myNode->keycode; + while (node) { + if (node->keysym == keysym) { + keycode = node->keycode; if (!previous) - xKeysHead = myNode->next; + xKeysHead = node->next; else - previous->next = myNode->next; + previous->next = node->next; - free(myNode); + free(node); return keycode; } - previous = myNode; - myNode = myNode->next; + previous = node; + node = node->next; if (i++ > 120) { // this should lead to a panic printf("loop over limit"); From 4320a2b299f84de0559c50910406989c4a1ed122 Mon Sep 17 00:00:00 2001 From: m1k1o Date: Mon, 12 Apr 2021 19:42:58 +0200 Subject: [PATCH 17/18] xorg fix error reporting. --- server/internal/xorg/xorg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/internal/xorg/xorg.c b/server/internal/xorg/xorg.c index 8861c456..e31c6ac8 100644 --- a/server/internal/xorg/xorg.c +++ b/server/internal/xorg/xorg.c @@ -39,8 +39,8 @@ KeyCode XKeysPop(KeySym keysym) { previous = node; node = node->next; if (i++ > 120) { - // this should lead to a panic - printf("loop over limit"); + // this should NEVER HAPPEN + fprintf(stderr, "[FATAL-ERROR] XKeysPop() in xorg.c: reached maximum loop limit! Something is wrong\n"); break; } } @@ -65,7 +65,7 @@ Display *getXDisplay(void) { } if (DISPLAY == NULL) { - fputs("Could not open main display\n", stderr); + fprintf(stderr, "[FATAL-ERROR] XKeysPop() in xorg.c: Could not open main display!"); } else if (!REGISTERED) { atexit(&XDisplayClose); REGISTERED = 1; From f8ba35119eb740f37576c683c00b120726c058ac Mon Sep 17 00:00:00 2001 From: m1k1o Date: Mon, 12 Apr 2021 19:43:46 +0200 Subject: [PATCH 18/18] add XkbKeysymToKeycode source link. --- server/internal/xorg/xorg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/server/internal/xorg/xorg.c b/server/internal/xorg/xorg.c index e31c6ac8..8defa28a 100644 --- a/server/internal/xorg/xorg.c +++ b/server/internal/xorg/xorg.c @@ -138,6 +138,7 @@ void XButton(unsigned int button, int down) { } } +// From: https://github.com/TigerVNC/tigervnc/blob/0946e298075f8f7b6d63e552297a787c5f84d27c/unix/x0vncserver/XDesktop.cxx#L343-L379 KeyCode XkbKeysymToKeycode(Display *dpy, KeySym keysym) { XkbDescPtr xkb; XkbStateRec state;