From afceb7ebaed13dd680a1acfb8354b736a1fd2cc3 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Sat, 18 Jan 2020 18:20:00 +0100 Subject: Dialog.c: show configured keystrokes in dialogs Instead of hardcoding the keystrokes in Dialog.h determine the currently configured keystrokes for the action and insert them into the dialog strings. Fixes ArcticaProject/nx-libs#438 --- nx-X11/programs/Xserver/hw/nxagent/Keystroke.c | 129 ++++++++++++++++++++----- 1 file changed, 105 insertions(+), 24 deletions(-) (limited to 'nx-X11/programs/Xserver/hw/nxagent/Keystroke.c') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c index ea139b10f..2f89195f5 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c @@ -428,35 +428,117 @@ void nxagentInitKeystrokes(Bool force) nxagentDumpKeystrokes(); } -void nxagentDumpKeystrokes(void) +static char *nxagentGetSingleKeystrokeString(struct nxagentSpecialKeystrokeMap *cur) +{ + if (!cur) + return strdup(""); /* caller is expected to free the returned string */ + + char *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9, *s10, *s11; + s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = s9 = s10 = s11 = ""; + + unsigned int mask = cur->modifierMask; + + if (mask & ControlMask) {s1 = "Ctrl+"; mask &= ~ControlMask;} + if (mask & ShiftMask) {s2 = "Shift+"; mask &= ~ShiftMask;} + + /* these are only here for better readable modifier names. Normally + they are covered by the Mod and Lock lines below */ + if (cur->modifierAltMeta) {s3 = "Alt+"; mask &= ~(cur->modifierAltMeta);} + if (mask & nxagentCapsMask) {s4 = "CapsLock+"; mask &= ~nxagentCapsMask;} + if (mask & nxagentNumlockMask) {s5 = "NumLock+"; mask &= ~nxagentNumlockMask;} + + if (mask & Mod1Mask) {s6 = "Mod1+"; mask &= ~Mod1Mask;} + if (mask & Mod2Mask) {s7 = "Mod2+"; mask &= ~Mod2Mask;} + if (mask & Mod3Mask) {s8 = "Mod3+"; mask &= ~Mod3Mask;} + if (mask & Mod4Mask) {s9 = "Mod4+"; mask &= ~Mod4Mask;} + if (mask & Mod5Mask) {s10 = "Mod5+"; mask &= ~Mod5Mask;} + if (mask & LockMask) {s11 = "Lock+"; mask &= ~LockMask;} + + char *ret = NULL; + asprintf(&ret, "%s%s%s%s%s%s%s%s%s%s%s%s", s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, XKeysymToString(cur->keysym)); + return ret; +} + +/* + * return the _first_ keystroke for the passed keystroke name + * + * e.g. nxagentFindFirstKeystroke("resize") -> "Ctrl+Alt+r" + * + * result must be free()d after use. + */ +char *nxagentFindFirstKeystroke(char *name) +{ + for (struct nxagentSpecialKeystrokeMap *cur = map; cur->stroke != KEYSTROKE_END_MARKER; cur++) + { + if (nxagentSpecialKeystrokeNames[cur->stroke] && + strcmp(nxagentSpecialKeystrokeNames[cur->stroke], name) == 0) + { + return nxagentGetSingleKeystrokeString(cur); + } + } + return NULL; +} + +/* + * return a string with linefeeds of all keystrokes who's name starts + * with the the passed string, + * + * e.g. nxagentFindKeystrokeString("viewport_scroll_") + * -> + * " viewport_scroll_left : Ctrl+Alt+Left + * viewport_scroll_left : Ctrl+Alt+KP_Left + * viewport_scroll_up : Ctrl+Alt+Up + * viewport_scroll_up : Ctrl+Alt+KP_Up + * viewport_scroll_right : Ctrl+Alt+Right + * viewport_scroll_right : Ctrl+Alt+KP_Right + * viewport_scroll_down : Ctrl+Alt+Down + * viewport_scroll_down : Ctrl+Alt+KP_Down + * " + * result must be free()d after use. + */ +char *nxagentFindMatchingKeystrokes(char *name) { int maxlen = 0; for (int i = 0; nxagentSpecialKeystrokeNames[i]; i++) maxlen = max(maxlen, strlen(nxagentSpecialKeystrokeNames[i])); - fprintf(stderr, "Currently known keystrokes:\n"); - - for (struct nxagentSpecialKeystrokeMap *cur = map; cur->stroke != KEYSTROKE_END_MARKER; cur++) { - unsigned int mask = cur->modifierMask; - fprintf(stderr, " %-*s ", maxlen, nxagentSpecialKeystrokeNames[cur->stroke]); - if (mask & ControlMask) {fprintf(stderr, "Ctrl+"); mask &= ~ControlMask;} - if (mask & ShiftMask) {fprintf(stderr, "Shift+"); mask &= ~ShiftMask;} - - /* these are only here for better readable modifier - names. Normally they are covered by the Mod and Lock lines - below */ - if (cur->modifierAltMeta) {fprintf(stderr, "Alt+"); mask &= ~(cur->modifierAltMeta);} - if (mask & nxagentCapsMask) {fprintf(stderr, "CapsLock+"); mask &= ~nxagentCapsMask;} - if (mask & nxagentNumlockMask) {fprintf(stderr, "NumLock+"); mask &= ~nxagentNumlockMask;} - - if (mask & Mod1Mask) {fprintf(stderr, "Mod1+"); mask &= ~Mod1Mask;} - if (mask & Mod2Mask) {fprintf(stderr, "Mod2+"); mask &= ~Mod2Mask;} - if (mask & Mod3Mask) {fprintf(stderr, "Mod3+"); mask &= ~Mod3Mask;} - if (mask & Mod4Mask) {fprintf(stderr, "Mod4+"); mask &= ~Mod4Mask;} - if (mask & Mod5Mask) {fprintf(stderr, "Mod5+"); mask &= ~Mod5Mask;} - if (mask & LockMask) {fprintf(stderr, "Lock+"); mask &= ~LockMask;} - fprintf(stderr, "%s\n", XKeysymToString(cur->keysym)); + char * res = strdup(""); /* let the caller free the string */ + for (struct nxagentSpecialKeystrokeMap *cur = map; cur->stroke != KEYSTROKE_END_MARKER; cur++) + { + if (nxagentSpecialKeystrokeNames[cur->stroke] && + strncmp(nxagentSpecialKeystrokeNames[cur->stroke], name, strlen(name)) == 0) + { + char *tmp; + char *tmp1 = nxagentGetSingleKeystrokeString(cur); + if (-1 == asprintf(&tmp, "%s %-*s : %s\n", res, maxlen, + nxagentSpecialKeystrokeNames[cur->stroke], + tmp1)) + { + SAFE_free(tmp1); + #ifdef TEST + fprintf(stderr, "%s: returning incomplete result:\n%s", __func__, res); + #endif + return res; + } + else + { + SAFE_free(tmp1); + free(res); + res = tmp; + } + } } + #ifdef TEST + fprintf(stderr, "%s: returning result:\n%s", __func__, res); + #endif + return res; +} + +void nxagentDumpKeystrokes(void) +{ + char *s = nxagentFindMatchingKeystrokes(""); + fprintf(stderr, "Currently known keystrokes:\n%s", s); + SAFE_free(s); } static enum nxagentSpecialKeystroke find_keystroke(XKeyEvent *X) @@ -465,7 +547,6 @@ static enum nxagentSpecialKeystroke find_keystroke(XKeyEvent *X) KeySym keysym = XKeycodeToKeysym(nxagentDisplay, X->keycode, 0); - #ifdef DEBUG fprintf(stderr, "%s: got keysym '%c' (%d)\n", __func__, keysym, keysym); #endif -- cgit v1.2.3