Commit afceb7eb authored by Ulrich Sibiller's avatar Ulrich Sibiller Committed by Mike Gabriel

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
parent b7169bdc
......@@ -41,6 +41,7 @@
#include "Display.h"
#include "Dialog.h"
#include "Utils.h"
#include "Keystroke.h"
#include <nx/NX.h>
#include "compext/Compext.h"
......@@ -187,6 +188,7 @@ void nxagentLaunchDialog(DialogType dialogType)
int *pid;
char *type;
char *message;
char *strings[2] = {NULL}; /* don't forget to add free() calls if you change the number */
int local;
const char *window = NULL;
......@@ -247,6 +249,7 @@ void nxagentLaunchDialog(DialogType dialogType)
type = DIALOG_ENABLE_DESKTOP_RESIZE_MODE_TYPE;
local = DIALOG_ENABLE_DESKTOP_RESIZE_MODE_LOCAL;
pid = &nxagentEnableRandRModeDialogPid;
strings[0] = nxagentFindFirstKeystroke("resize");
break;
}
case DIALOG_DISABLE_DESKTOP_RESIZE_MODE:
......@@ -255,6 +258,8 @@ void nxagentLaunchDialog(DialogType dialogType)
type = DIALOG_DISABLE_DESKTOP_RESIZE_MODE_TYPE;
local = DIALOG_DISABLE_DESKTOP_RESIZE_MODE_LOCAL;
pid = &nxagentDisableRandRModeDialogPid;
strings[0] = nxagentFindFirstKeystroke("resize");
strings[1] = nxagentFindMatchingKeystrokes("viewport_");
break;
}
case DIALOG_ENABLE_DEFER_MODE:
......@@ -263,6 +268,7 @@ void nxagentLaunchDialog(DialogType dialogType)
type = DIALOG_ENABLE_DEFER_MODE_TYPE;
local = DIALOG_ENABLE_DEFER_MODE_LOCAL;
pid = &nxagentEnableDeferModePid;
strings[0] = nxagentFindFirstKeystroke("defer");
break;
}
case DIALOG_DISABLE_DEFER_MODE:
......@@ -271,6 +277,7 @@ void nxagentLaunchDialog(DialogType dialogType)
type = DIALOG_DISABLE_DEFER_MODE_TYPE;
local = DIALOG_DISABLE_DEFER_MODE_LOCAL;
pid = &nxagentDisableDeferModePid;
strings[0] = nxagentFindFirstKeystroke("defer");
break;
}
case DIALOG_ENABLE_AUTOGRAB_MODE:
......@@ -279,6 +286,7 @@ void nxagentLaunchDialog(DialogType dialogType)
type = DIALOG_ENABLE_AUTOGRAB_MODE_TYPE;
local = DIALOG_ENABLE_AUTOGRAB_MODE_LOCAL;
pid = &nxagentEnableAutograbModePid;
strings[0] = nxagentFindFirstKeystroke("autograb");
break;
}
case DIALOG_DISABLE_AUTOGRAB_MODE:
......@@ -287,6 +295,7 @@ void nxagentLaunchDialog(DialogType dialogType)
type = DIALOG_DISABLE_AUTOGRAB_MODE_TYPE;
local = DIALOG_DISABLE_AUTOGRAB_MODE_LOCAL;
pid = &nxagentDisableAutograbModePid;
strings[0] = nxagentFindFirstKeystroke("autograb");
break;
}
default:
......@@ -321,6 +330,17 @@ void nxagentLaunchDialog(DialogType dialogType)
return;
}
char *msg = NULL;
if (-1 == asprintf(&msg, message, strings[0], strings[1]))
{
#ifdef DEBUG
fprintf(stderr, "%s: could not allocate message string.\n", __func__);
#endif
SAFE_free(strings[0]);
SAFE_free(strings[1]);
return;
}
/*
* We don't want to receive SIGCHLD before we store the child pid.
*/
......@@ -331,9 +351,13 @@ void nxagentLaunchDialog(DialogType dialogType)
sigprocmask(SIG_BLOCK, &set, &oldSet);
*pid = NXTransDialog(nxagentDialogName, message, window,
*pid = NXTransDialog(nxagentDialogName, msg, window,
type, local, dialogDisplay);
SAFE_free(strings[0]);
SAFE_free(strings[1]);
SAFE_free(msg);
#ifdef TEST
fprintf(stderr, "nxagentLaunchDialog: Launched dialog %s with pid [%d] on display %s.\n",
DECODE_DIALOG_TYPE(dialogType), *pid, dialogDisplay);
......
......@@ -174,7 +174,7 @@ nxagentFailedReconnectionMessage
"\
The session is now running in desktop resize mode.\n\
You can resize the desktop by simply dragging the\n\
desktop window's border. You can press Ctrl+Alt+R\n\
desktop window's border. You can press %s\n\
again to disable this option.\
"
......@@ -187,9 +187,12 @@ again to disable this option.\
"\
The session is now running in viewport mode. You can\n\
navigate across different areas of the desktop window\n\
by dragging the desktop with the mouse or by using the\n\
arrows keys while pressing Ctrl+Alt. Press Ctrl+Alt+R\n\
again to return to the desktop resize mode.\
by dragging the desktop with the mouse while pressing\n\
Ctrl+Alt or use the keystrokes listed below. Press\n\
%s again to return to the desktop resize mode.\n\
\n\
Use these keystrokes to navigate:\n\
%s\
"
#define DIALOG_DISABLE_DESKTOP_RESIZE_MODE_TYPE "ok"
......@@ -201,7 +204,7 @@ again to return to the desktop resize mode.\
\
"\
Deferred screen updates are now enabled. You can press\n\
Ctrl+Alt+E again to disable this option.\
%s again to disable this option.\
"
#define DIALOG_ENABLE_DEFER_MODE_TYPE "ok"
......@@ -213,7 +216,7 @@ Ctrl+Alt+E again to disable this option.\
\
"\
Deferred screen updates are now disabled. You can press\n\
Ctrl+Alt+E to enable it again.\
%s to enable it again.\
"
#define DIALOG_DISABLE_DEFER_MODE_TYPE "ok"
......@@ -225,7 +228,7 @@ Ctrl+Alt+E to enable it again.\
\
"\
Keyboard auto-grabbing mode is now enabled. You can press\n\
Ctrl+Alt+G again to disable auto-grabbing.\
%s again to disable auto-grabbing.\
"
#define DIALOG_ENABLE_AUTOGRAB_MODE_TYPE "ok"
......@@ -237,7 +240,7 @@ Ctrl+Alt+G again to disable auto-grabbing.\
\
"\
Keyboard auto-grabbing mode is now disabled. You can press\n\
Ctrl+Alt+G again to re-enable auto-grabbing.\
%s again to re-enable auto-grabbing.\
"
#define DIALOG_DISABLE_AUTOGRAB_MODE_TYPE "ok"
......
......@@ -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<n> 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<n> 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
......
......@@ -32,6 +32,9 @@ extern Bool nxagentCheckSpecialKeystroke(XKeyEvent*, enum HandleEventResult*);
extern void nxagentDumpKeystrokes(void);
extern void nxagentInitKeystrokes(Bool force);
char *nxagentFindFirstKeystroke(char *name);
char *nxagentFindMatchingKeystrokes(char *name);
/* keep this sorted, do not rely on any numerical value in this enum, and be aware
* that KEYSTROKE_MAX may be used in a malloc */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment