aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/programs/Xserver
diff options
context:
space:
mode:
authorAlexander Wuerstlein <arw@arw.name>2015-02-13 09:52:21 +0100
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2015-02-13 09:52:21 +0100
commite91277d02bf1288909daed3b0de8f876f6403acf (patch)
tree527aa5a009cd50e66767af09703818616328c50c /nx-X11/programs/Xserver
parent4dc1bd0043aed6b92526cbda26991be1f611a121 (diff)
downloadnx-libs-e91277d02bf1288909daed3b0de8f876f6403acf.tar.gz
nx-libs-e91277d02bf1288909daed3b0de8f876f6403acf.tar.bz2
nx-libs-e91277d02bf1288909daed3b0de8f876f6403acf.zip
Make nxagent-specific keyboard bindings configurable (320_nxagent_configurable-keystrokes.full.patch).
Replaces the hardcoded nxagent keybindings by a configurable table of keybindings. The default configuration is the same as the original one, to maintain compatibility. A user/administrator can either specify a command line parameter, environment variable or place a file in ~/.nx/config/keystrokes.cfg or /etc/nxagent/keystrokes.cfg to reconfigure these keybindings. The configuration file format is XML, a dependency on libxml2 is added to allow parsing the configuration.
Diffstat (limited to 'nx-X11/programs/Xserver')
-rw-r--r--nx-X11/programs/Xserver/Imakefile9
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Args.c16
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Args.h2
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Imakefile9
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Keystroke.c700
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Keystroke.h47
6 files changed, 546 insertions, 237 deletions
diff --git a/nx-X11/programs/Xserver/Imakefile b/nx-X11/programs/Xserver/Imakefile
index c803a9915..c31102bbc 100644
--- a/nx-X11/programs/Xserver/Imakefile
+++ b/nx-X11/programs/Xserver/Imakefile
@@ -1013,15 +1013,18 @@ $(NXAGENTOBJS) $(NXAGENTLIBS) $(NXAGENTSYSLIBS):: $(NXAGENTDIRS)
#if defined(SunArchitecture)
NXAGENTNXLIBS = -L ../../../nxcomp -L ../../../nxcompext -L ../../../nxcompshad \
-lXcomp -lXcompext -lXcompshad -lrt -L/usr/sfw/lib -lXrender -lXfixes \
- -L../../../nx-X11/exports/lib -lXtst -lXdamage -lXrandr -lXcomposite -lXdmcp
+ -L../../../nx-X11/exports/lib -lXtst -lXdamage -lXrandr -lXcomposite -lXdmcp \
+`pkg-config --libs libxml-2.0`
#elif defined(cygwinArchitecture)
NXAGENTNXLIBS = -L ../../../nxcomp -L ../../../nxcompext \
-lXcomp -lXcompext -lXrender -lX11 -lXext -lXcomposite -lXfixes \
- -L ../../../nxcompshad -lXcompshad -L../../../nx-X11/exports/lib -lXtst -lXdmcp
+ -L ../../../nxcompshad -lXcompshad -L../../../nx-X11/exports/lib -lXtst -lXdmcp \
+`pkg-config --libs libxml-2.0`
#else
NXAGENTNXLIBS = -L ../../../nxcomp -L ../../../nxcompext -L ../../../nxcompshad \
-lXcomp -lXcompext -lXcompshad -lXrender -lX11 -lXext -lXfixes \
- -L../../../nx-X11/exports/lib -lXtst -lXdamage -lXrandr -lXcomposite -lXinerama -lXdmcp
+ -L../../../nx-X11/exports/lib -lXtst -lXdamage -lXrandr -lXcomposite -lXinerama -lXdmcp \
+`pkg-config --libs libxml-2.0`
#endif
#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c
index 7074a1818..07e967065 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c
@@ -149,6 +149,8 @@ static int nxagentGetDialogName(void);
char nxagentVerbose = 0;
+char *nxagentKeystrokeFile = NULL;
+
int ddxProcessArgument(int argc, char *argv[], int i)
{
/*
@@ -1022,6 +1024,20 @@ int ddxProcessArgument(int argc, char *argv[], int i)
return 1;
}
+ if (!strcmp(argv[i], "-keystrokefile"))
+ {
+ if (i + 1 < argc)
+ {
+ if (NULL != (nxagentKeystrokeFile = strdup(argv[i + 1])))
+ {
+ return 2;
+ } else {
+ FatalError("malloc failed");
+ }
+ }
+ return 0;
+ }
+
return 0;
}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.h b/nx-X11/programs/Xserver/hw/nxagent/Args.h
index 8f4d05d6c..85734be23 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.h
@@ -83,4 +83,6 @@ extern int nxagentUserDefinedFontPath;
extern int nxagentRemoteMajor;
+extern char *nxagentKeystrokeFile;
+
#endif /* __Args_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Imakefile b/nx-X11/programs/Xserver/hw/nxagent/Imakefile
index a8e162102..d812c7f70 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Imakefile
+++ b/nx-X11/programs/Xserver/hw/nxagent/Imakefile
@@ -142,7 +142,8 @@ INCLUDES = -I. -I../../../../../nxcomp -I../../../../../nxcompext -I../../../../
-I../../miext/damage -I../../miext/cw \
-I../../GL/glx -I../../GL/include -I../../../../lib/GL/include -I../../Xext \
-I$(EXTINCSRC) -I$(XINCLUDESRC) \
- $(VFBINCLUDES) $(NXFONTINCLUDES) $(LIBXRANDRINCLUDES)
+ $(VFBINCLUDES) $(NXFONTINCLUDES) $(LIBXRANDRINCLUDES) \
+ `pkg-config --cflags-only-I libxml-2.0`
#ifdef SunArchitecture
INCLUDES = -I. -I../../../../../nxcomp -I../../../../../nxcompext -I../../../../../nxcompshad \
-I../../../../extras/Mesa/include \
@@ -152,7 +153,8 @@ INCLUDES = -I. -I../../../../../nxcomp -I../../../../../nxcompext -I../../../../
-I../../GL/glx -I../../GL/include -I../../../../lib/GL/include -I../../Xext \
-I../../miext/damage -I../../miext/cw \
-I$(EXTINCSRC) -I$(XINCLUDESRC) \
- $(VFBINCLUDES) $(NXFONTINCLUDES) $(LIBXRANDRINCLUDES)
+ $(VFBINCLUDES) $(NXFONTINCLUDES) $(LIBXRANDRINCLUDES) \
+ `pkg-config --cflags-only-I libxml-2.0`
#else
#ifdef cygwinArchitecture
INCLUDES = -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
@@ -162,7 +164,8 @@ INCLUDES = -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
-I../../../../../nxcomp -I../../../../../nxcompext -I../../../../../nxcompshad \
-I../../../../extras/Mesa/include \
-I$(EXTINCSRC) -I$(XINCLUDESRC) \
- $(VFBINCLUDES) $(NXFONTINCLUDES) $(LIBXRANDRINCLUDES)
+ $(VFBINCLUDES) $(NXFONTINCLUDES) $(LIBXRANDRINCLUDES) \
+ `pkg-config --cflags-only-I libxml-2.0`
#endif
#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
index 6c6e477ab..d61c65b1a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
@@ -28,8 +28,15 @@
#include "Keystroke.h"
#include "Drawable.h"
+#include <unistd.h>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
extern Bool nxagentWMIsRunning;
extern Bool nxagentIpaq;
+extern char *nxagentKeystrokeFile;
+Bool nxagentKeystrokeFileParsed = False;
#ifdef NX_DEBUG_INPUT
int nxagentDebugInputDevices = 0;
@@ -47,10 +54,370 @@ extern void nxagentDeactivateInputDevicesGrabs();
#undef DEBUG
#undef DUMP
+
+/* this table is used to parse actions given on the command line or in the
+ * config file, therefore indices have to match the enum in Keystroke.h */
+char * nxagentSpecialKeystrokeNames[] = {
+ "end_marker",
+ "close_session",
+ "switch_all_screens",
+ "minimize",
+ "left",
+ "up",
+ "right",
+ "down",
+ "resize",
+ "defer",
+ "ignore",
+ "force_synchronization",
+
+ "debug_tree",
+ "regions_on_screen",
+ "test_input",
+ "deactivate_input_devices_grab",
+
+ "fullscreen",
+ "viewport_move_left",
+ "viewport_move_up",
+ "viewport_move_right",
+ "viewport_move_down",
+ NULL,
+};
+
+struct nxagentSpecialKeystrokeMap default_map[] = {
+ /* stroke, modifierMask, modifierAltMeta, keysym */
+ {KEYSTROKE_DEBUG_TREE, ControlMask, 1, XK_q},
+ {KEYSTROKE_DEBUG_TREE, ControlMask, 1, XK_Q},
+ {KEYSTROKE_CLOSE_SESSION, ControlMask, 1, XK_t},
+ {KEYSTROKE_CLOSE_SESSION, ControlMask, 1, XK_T},
+ {KEYSTROKE_SWITCH_ALL_SCREENS, ControlMask, 1, XK_f},
+ {KEYSTROKE_SWITCH_ALL_SCREENS, ControlMask, 1, XK_F},
+ {KEYSTROKE_MINIMIZE, ControlMask, 1, XK_m},
+ {KEYSTROKE_MINIMIZE, ControlMask, 1, XK_M},
+ {KEYSTROKE_LEFT, ControlMask, 1, XK_Left},
+ {KEYSTROKE_LEFT, ControlMask, 1, XK_KP_Left},
+ {KEYSTROKE_UP, ControlMask, 1, XK_Up},
+ {KEYSTROKE_UP, ControlMask, 1, XK_KP_Up},
+ {KEYSTROKE_RIGHT, ControlMask, 1, XK_Right},
+ {KEYSTROKE_RIGHT, ControlMask, 1, XK_KP_Right},
+ {KEYSTROKE_DOWN, ControlMask, 1, XK_Down},
+ {KEYSTROKE_DOWN, ControlMask, 1, XK_KP_Down},
+ {KEYSTROKE_RESIZE, ControlMask, 1, XK_r},
+ {KEYSTROKE_RESIZE, ControlMask, 1, XK_R},
+ {KEYSTROKE_DEFER, ControlMask, 1, XK_e},
+ {KEYSTROKE_DEFER, ControlMask, 1, XK_E},
+ {KEYSTROKE_IGNORE, ControlMask, 1, XK_BackSpace},
+ {KEYSTROKE_IGNORE, 0, 0, XK_Terminate_Server},
+ {KEYSTROKE_FORCE_SYNCHRONIZATION, ControlMask, 1, XK_j},
+ {KEYSTROKE_FORCE_SYNCHRONIZATION, ControlMask, 1, XK_J},
+ {KEYSTROKE_REGIONS_ON_SCREEN, ControlMask, 1, XK_a},
+ {KEYSTROKE_REGIONS_ON_SCREEN, ControlMask, 1, XK_A},
+ {KEYSTROKE_TEST_INPUT, ControlMask, 1, XK_x},
+ {KEYSTROKE_TEST_INPUT, ControlMask, 1, XK_X},
+ {KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB, ControlMask, 1, XK_y},
+ {KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB, ControlMask, 1, XK_Y},
+ {KEYSTROKE_FULLSCREEN, ControlMask | ShiftMask, 1, XK_f},
+ {KEYSTROKE_FULLSCREEN, ControlMask | ShiftMask, 1, XK_F},
+ {KEYSTROKE_VIEWPORT_MOVE_LEFT, ControlMask | ShiftMask, 1, XK_Left},
+ {KEYSTROKE_VIEWPORT_MOVE_LEFT, ControlMask | ShiftMask, 1, XK_KP_Left},
+ {KEYSTROKE_VIEWPORT_MOVE_UP, ControlMask | ShiftMask, 1, XK_Up},
+ {KEYSTROKE_VIEWPORT_MOVE_UP, ControlMask | ShiftMask, 1, XK_KP_Up},
+ {KEYSTROKE_VIEWPORT_MOVE_RIGHT, ControlMask | ShiftMask, 1, XK_Right},
+ {KEYSTROKE_VIEWPORT_MOVE_RIGHT, ControlMask | ShiftMask, 1, XK_KP_Right},
+ {KEYSTROKE_VIEWPORT_MOVE_DOWN, ControlMask | ShiftMask, 1, XK_Down},
+ {KEYSTROKE_VIEWPORT_MOVE_DOWN, ControlMask | ShiftMask, 1, XK_KP_Down},
+ {KEYSTROKE_END_MARKER, 0, 0, 0},
+};
+struct nxagentSpecialKeystrokeMap *map = default_map;
+
+static int modifier_matches(unsigned int mask, int compare_alt_meta, unsigned int state)
+{
+ /* nxagentAltMetaMask needs special handling
+ * it seems to me its an and-ed mask of all possible meta and alt keys
+ * somehow...
+ *
+ * otherwise this function would be just a simple bitop
+ */
+ int ret = 1;
+
+ if (compare_alt_meta) {
+ if (! (state & nxagentAltMetaMask)) {
+ ret = 0;
+ }
+
+ mask &= ~nxagentAltMetaMask;
+ }
+
+ /* all modifiers except meta/alt have to match exactly, extra bits are evil */
+ if ((mask & state) != mask) {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int read_binding_from_xmlnode(xmlNode *node, struct nxagentSpecialKeystrokeMap *ret)
+{
+ int successful = 0;
+ struct nxagentSpecialKeystrokeMap new = {0, 0, 0, 0};
+ xmlAttr *attr;
+
+ for (attr = node->properties; attr; attr = attr->next)
+ {
+ /* ignore attributes without data (which should never happen anyways) */
+ if (attr->children->content == NULL)
+ {
+ char *aname = (attr->name)?(attr->name):"unknown";
+ fprintf(stderr, "attribute %s with NULL value", aname);
+ continue;
+ }
+ if (strcmp((char *)attr->name, "action") == 0)
+ {
+ int i;
+ for (i = 0; nxagentSpecialKeystrokeNames[i] != NULL; i++)
+ {
+ if (strcmp(nxagentSpecialKeystrokeNames[i],(char *)attr->children->content) == 0)
+ {
+ /* this relies on the values of enum nxagentSpecialKeystroke and the
+ * indices of nxagentSpecialKeystrokeNames being in sync */
+ new.stroke = i;
+ break;
+ }
+ }
+ continue;
+ }
+ else if (strcmp((char *)attr->name, "key") == 0)
+ {
+ new.keysym = XStringToKeysym((char *)attr->children->content);
+ /* NoSymbol is usually 0, but could there be weird implementations? */
+ if (new.keysym == NoSymbol)
+ {
+ new.keysym = 0;
+ }
+ continue;
+ }
+
+ /* ignore attributes with value="0" or "false", everything else is interpreted as true */
+ if (strcmp((char *)attr->children->content, "0") == 0 || strcmp((char *)attr->children->content, "false") == 0)
+ continue;
+
+ if (strcmp((char *)attr->name, "Mod1") == 0)
+ {
+ new.modifierMask |= Mod1Mask;
+ }
+ else if (strcmp((char *)attr->name, "Mod2") == 0)
+ {
+ new.modifierMask |= Mod2Mask;
+ }
+ else if (strcmp((char *)attr->name, "Mod3") == 0)
+ {
+ new.modifierMask |= Mod3Mask;
+ }
+ else if (strcmp((char *)attr->name, "Mod4") == 0)
+ {
+ new.modifierMask |= Mod4Mask;
+ }
+ else if (strcmp((char *)attr->name, "Control") == 0)
+ {
+ new.modifierMask |= ControlMask;
+ }
+ else if (strcmp((char *)attr->name, "Shift") == 0)
+ {
+ new.modifierMask |= ShiftMask;
+ }
+ else if (strcmp((char *)attr->name, "Lock") == 0)
+ {
+ new.modifierMask |= LockMask;
+ }
+ else if (strcmp((char *)attr->name, "AltMeta") == 0)
+ {
+ new.modifierAltMeta = 1;
+ }
+ }
+
+ if (new.stroke != 0 && new.keysym != 0)
+ {
+ /* keysym and stroke are required, everything else is optional */
+ successful = 1;
+ memcpy(ret, &new, sizeof(struct nxagentSpecialKeystrokeMap));
+ }
+ return successful;
+}
+
+/*
+ * searches a keystroke xml file
+ *
+ * search order:
+ * - '-keystrokefile' commandline parameter
+ * - $NXAGENT_KEYSTROKEFILE environment variable
+ * - $HOME/.nx/config/keystrokes.cfg
+ * - /etc/nxagent/keystrokes.cfg
+ * - hardcoded traditional NX default settings
+ */
+static void parse_keystroke_file(void)
+{
+ char *filename = NULL;
+
+ char *homefile = "/.nx/config/keystrokes.cfg";
+ char *etcfile = "/etc/nxagent/keystrokes.cfg";
+
+ if (nxagentKeystrokeFile != NULL && access(nxagentKeystrokeFile, R_OK) == 0)
+ {
+ filename = strdup(nxagentKeystrokeFile);
+ if (filename == NULL)
+ {
+ fprintf(stderr, "malloc failed");
+ exit(EXIT_FAILURE);
+ }
+ }
+ else if ((filename = getenv("NXAGENT_KEYSTROKEFILE")) != NULL && access(filename, R_OK) == 0)
+ {
+ filename = strdup(filename);
+ if (filename == NULL)
+ {
+ fprintf(stderr, "malloc failed");
+ exit(EXIT_FAILURE);
+ }
+ }
+ else
+ {
+ char *homedir = getenv("HOME");
+ filename = NULL;
+ if (homedir != NULL)
+ {
+ homedir = strdup(homedir);
+ if (homedir == NULL)
+ {
+ fprintf(stderr, "malloc failed");
+exit(EXIT_FAILURE);
+ }
+ filename = calloc(1, strlen(homefile) + strlen(homedir) + 1);
+ if (filename == NULL)
+ {
+ fprintf(stderr, "malloc failed");
+ exit(EXIT_FAILURE);
+ }
+ strcpy(filename, homedir);
+ strcpy(filename + strlen(homedir), homefile);
+ if (homedir)
+ {
+ free(homedir);
+ }
+ }
+
+ if (access(filename, R_OK) == 0)
+ {
+ /* empty */
+ }
+ else if (access(etcfile, R_OK) == 0)
+ {
+ if (filename)
+ free(filename);
+ filename = strdup(etcfile);
+ if (filename == NULL)
+ {
+ fprintf(stderr, "malloc failed");
+ exit(EXIT_FAILURE);
+ }
+ }
+ else
+ {
+ if (filename)
+free(filename);
+ filename = NULL;
+ }
+ }
+
+ /* now we know which file to read, if any */
+ if (filename)
+ {
+ xmlDoc *doc = NULL;
+ xmlNode *root = NULL;
+ LIBXML_TEST_VERSION
+ doc = xmlReadFile(filename, NULL, 0);
+ if (doc != NULL)
+ {
+ xmlNode *cur = NULL;
+ root = xmlDocGetRootElement(doc);
+
+ for (cur = root; cur; cur = cur->next)
+ {
+ if (cur->type == XML_ELEMENT_NODE && strcmp((char *)cur->name, "keystrokes") == 0)
+{
+ xmlNode *bindings = NULL;
+ int num = 0;
+ int idx = 0;
+
+ for (bindings = cur->children; bindings; bindings = bindings->next)
+ {
+ if (bindings->type == XML_ELEMENT_NODE && strcmp((char *)bindings->name, "keystroke") == 0)
+ {
+ num++;
+ }
+ }
+ map = calloc((num + 1), sizeof(struct nxagentSpecialKeystrokeMap));
+ if (map == NULL)
+ {
+ fprintf(stderr, "malloc failed");
+ exit(EXIT_FAILURE);
+ }
+
+ for (bindings = cur->children; bindings; bindings = bindings->next)
+ {
+ if (bindings->type == XML_ELEMENT_NODE && strcmp((char *)bindings->name, "keystroke") == 0)
+ {
+ int res = 0;
+ res = read_binding_from_xmlnode(bindings, &(map[idx]));
+ if (res)
+ idx++;
+ }
+ }
+
+ map[idx].stroke = KEYSTROKE_END_MARKER;
+ }
+ }
+
+ xmlFreeDoc(doc);
+ xmlCleanupParser();
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf("XML parsing for %s failed\n", filename);
+ #endif
+ }
+ free(filename);
+ }
+}
+
+static enum nxagentSpecialKeystroke find_keystroke(XKeyEvent *X)
+{
+ KeySym keysym = XKeycodeToKeysym(nxagentDisplay, X->keycode, 0);
+ struct nxagentSpecialKeystrokeMap *cur = map;
+
+ if (! nxagentKeystrokeFileParsed)
+ {
+ parse_keystroke_file();
+ nxagentKeystrokeFileParsed = True;
+ }
+
+ enum nxagentSpecialKeystroke ret = KEYSTROKE_NOTHING;
+
+ while (cur->stroke != KEYSTROKE_END_MARKER) {
+ if (cur->keysym == keysym && modifier_matches(cur->modifierMask, cur->modifierAltMeta, X->state)) {
+ return cur->stroke;
+ }
+ cur++;
+ }
+
+ return ret;
+}
+
int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
{
KeySym sym;
int index = 0;
+ enum nxagentSpecialKeystroke stroke = find_keystroke(X);
*result = doNothing;
@@ -87,257 +454,128 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
return 1;
}
- if ((X -> state & nxagentAltMetaMask) &&
- ((X -> state & (ControlMask | ShiftMask)) == ControlMask))
- {
- switch (sym)
- {
+ switch (stroke) {
+ case KEYSTROKE_DEBUG_TREE:
#ifdef DEBUG_TREE
-
- case XK_q:
- case XK_Q:
- {
- *result = doDebugTree;
-
- break;
- }
-
- #endif /* DEBUG_TREE */
-
- case XK_t:
- case XK_T:
- {
- *result = doCloseSession;
-
- break;
- }
- case XK_f:
- case XK_F:
- {
- if (nxagentOption(Rootless) == False)
- {
- *result = doSwitchAllScreens;
- }
-
- break;
- }
- case XK_m:
- case XK_M:
- {
- if (nxagentOption(Rootless) == False)
- {
- *result = doMinimize;
- }
-
- break;
- }
- case XK_Left:
- case XK_KP_Left:
- {
- if (nxagentOption(Rootless) == False &&
- nxagentOption(DesktopResize) == False)
- {
- *result = doViewportLeft;
- }
-
- break;
- }
- case XK_Up:
- case XK_KP_Up:
- {
- if (nxagentOption(Rootless) == False &&
- nxagentOption(DesktopResize) == False)
- {
- *result = doViewportUp;
- }
-
- break;
+ *result = doDebugTree;
+ #endif
+ break;
+ case KEYSTROKE_CLOSE_SESSION:
+ *result = doCloseSession;
+ break;
+ case KEYSTROKE_SWITCH_ALL_SCREENS:
+ if (nxagentOption(Rootless) == False) {
+ *result = doSwitchAllScreens;
}
- case XK_Right:
- case XK_KP_Right:
- {
- if (nxagentOption(Rootless) == False &&
- nxagentOption(DesktopResize) == False)
- {
- *result = doViewportRight;
- }
-
- break;
+ break;
+ case KEYSTROKE_MINIMIZE:
+ if (nxagentOption(Rootless) == False) {
+ *result = doMinimize;
}
- case XK_Down:
- case XK_KP_Down:
- {
- if (nxagentOption(Rootless) == 0 &&
- nxagentOption(DesktopResize) == 0)
- {
- *result = doViewportDown;
- }
-
- break;
+ break;
+ case KEYSTROKE_LEFT:
+ if (nxagentOption(Rootless) == False &&
+ nxagentOption(DesktopResize) == False) {
+ *result = doViewportLeft;
}
- case XK_R:
- case XK_r:
- {
- if (nxagentOption(Rootless) == 0)
- {
- *result = doSwitchResizeMode;
- }
-
- break;
+ break;
+ case KEYSTROKE_UP:
+ if (nxagentOption(Rootless) == False &&
+ nxagentOption(DesktopResize) == False) {
+ *result = doViewportUp;
}
- case XK_E:
- case XK_e:
- {
- *result = doSwitchDeferMode;
-
- break;
+ break;
+ case KEYSTROKE_RIGHT:
+ if (nxagentOption(Rootless) == False &&
+ nxagentOption(DesktopResize) == False) {
+ *result = doViewportRight;
}
- case XK_BackSpace:
- case XK_Terminate_Server:
- {
- /*
- * Discard Ctrl-Alt-BackSpace key.
- */
-
- return 1;
-
- break;
+ break;
+ case KEYSTROKE_DOWN:
+ if (nxagentOption(Rootless) == False &&
+ nxagentOption(DesktopResize) == False) {
+ *result = doViewportDown;
}
-
- case XK_J:
- case XK_j:
- {
- nxagentForceSynchronization = 1;
-
- return 1;
+ break;
+ case KEYSTROKE_RESIZE:
+ if (nxagentOption(Rootless) == False) {
+ *result = doSwitchResizeMode;
}
-
+ break;
+ case KEYSTROKE_DEFER:
+ *result = doSwitchDeferMode;
+ break;
+ case KEYSTROKE_IGNORE:
+ /* this is used e.g. to ignore C-A-Backspace aka XK_Terminate_Server */
+ return 1;
+ break;
+ case KEYSTROKE_FORCE_SYNCHRONIZATION:
+ nxagentForceSynchronization = 1;
+ break;
+ case KEYSTROKE_REGIONS_ON_SCREEN:
#ifdef DUMP
-
- case XK_A:
- case XK_a:
- {
- /*
- * Used to test the lazy encoding.
- */
-
- nxagentRegionsOnScreen();
-
- return 1;
- }
-
+ nxagentRegionsOnScreen();
#endif
-
+ break;
+ case KEYSTROKE_TEST_INPUT:
+ /*
+ * Used to test the input devices state.
+ */
#ifdef NX_DEBUG_INPUT
-
- case XK_X:
- case XK_x:
- {
- /*
- * Used to test the input devices state.
- */
-
- if (X -> type == KeyPress)
- {
- if (nxagentDebugInputDevices == 0)
- {
- fprintf(stderr, "Info: Turning input devices debug ON.\n");
-
- nxagentDebugInputDevices = 1;
- }
- else
- {
- fprintf(stderr, "Info: Turning input devices debug OFF.\n");
-
- nxagentDebugInputDevices = 0;
-
- nxagentLastInputDevicesDumpTime = 0;
- }
+ if (X -> type == KeyPress) {
+ if (nxagentDebugInputDevices == 0) {
+ fprintf(stderr, "Info: Turning input devices debug ON.\n");
+ nxagentDebugInputDevices = 1;
+ } else {
+ fprintf(stderr, "Info: Turning input devices debug OFF.\n");
+ nxagentDebugInputDevices = 0;
+ nxagentLastInputDevicesDumpTime = 0;
}
-
- return 1;
}
-
- case XK_Y:
- case XK_y:
- {
- /*
- * Used to deactivate input devices grab.
- */
-
- if (X -> type == KeyPress)
- {
- nxagentDeactivateInputDevicesGrabs();
- }
-
- return 1;
+ return 1;
+ #endif
+ break;
+ case KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB:
+ #ifdef NX_DEBUG_INPUT
+ if (X->type == KeyPress) {
+ nxagentDeactivateInputDevicesGrab();
}
-
+ return 1;
#endif
- }
- }
- else if ((X -> state & nxagentAltMetaMask) &&
- ((X -> state & (ControlMask | ShiftMask)) == (ControlMask |
- ShiftMask)))
- {
- switch (sym)
- {
- case XK_f:
- case XK_F:
- {
- if (nxagentOption(Rootless) == 0)
- {
- *result = doSwitchFullscreen;
- }
-
- break;
+ break;
+ case KEYSTROKE_FULLSCREEN:
+ if (nxagentOption(Rootless) == 0) {
+ *result = doSwitchFullscreen;
}
- case XK_Left:
- case XK_KP_Left:
- {
- if (nxagentOption(Rootless) == 0 &&
- nxagentOption(DesktopResize) == 0)
- {
- *result = doViewportMoveLeft;
- }
-
- break;
+ break;
+ case KEYSTROKE_VIEWPORT_MOVE_LEFT:
+ if (nxagentOption(Rootless) == 0 &&
+ nxagentOption(DesktopResize) == 0) {
+ *result = doViewportMoveLeft;
}
- case XK_Up:
- case XK_KP_Up:
- {
- if (nxagentOption(Rootless) == 0 &&
- nxagentOption(DesktopResize) == 0)
- {
- *result = doViewportMoveUp;
- }
-
- break;
+ break;
+ case KEYSTROKE_VIEWPORT_MOVE_UP:
+ if (nxagentOption(Rootless) == 0 &&
+ nxagentOption(DesktopResize) == 0) {
+ *result = doViewportMoveUp;
}
- case XK_Right:
- case XK_KP_Right:
- {
- if (nxagentOption(Rootless) == 0 &&
- nxagentOption(DesktopResize) == 0)
- {
- *result = doViewportMoveRight;
- }
-
- break;
+ break;
+ case KEYSTROKE_VIEWPORT_MOVE_RIGHT:
+ if (nxagentOption(Rootless) == 0 &&
+ nxagentOption(DesktopResize) == 0) {
+ *result = doViewportMoveRight;
}
- case XK_Down:
- case XK_KP_Down:
- {
- if (nxagentOption(Rootless) == 0 &&
- nxagentOption(DesktopResize) == 0)
- {
- *result = doViewportMoveDown;
- }
-
- break;
+ break;
+ case KEYSTROKE_VIEWPORT_MOVE_DOWN:
+ if (nxagentOption(Rootless) == 0 &&
+ nxagentOption(DesktopResize) == 0) {
+ *result = doViewportMoveDown;
}
- }
+ break;
+ case KEYSTROKE_NOTHING: /* do nothing. difference to KEYSTROKE_IGNORE is the return value */
+ case KEYSTROKE_END_MARKER: /* just to make gcc STFU */
+ case KEYSTROKE_MAX:
+ break;
}
-
return (*result == doNothing) ? 0 : 1;
}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
index ef71a8851..d9575c875 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
@@ -24,4 +24,51 @@ extern int nxagentCheckSpecialKeystroke(XKeyEvent*, enum HandleEventResult*);
unsigned int nxagentAltMetaMask;
+/* 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 */
+
+/* also be aware that if changing any numerical values, you also need to change values
+ * Keystroke.c nxagentSpecialKeystrokeNames */
+enum nxagentSpecialKeystroke {
+ /* 0 is used as end marker */
+ KEYSTROKE_END_MARKER = 0,
+ KEYSTROKE_CLOSE_SESSION = 1,
+ KEYSTROKE_SWITCH_ALL_SCREENS = 2,
+ KEYSTROKE_MINIMIZE = 3,
+ KEYSTROKE_LEFT = 4,
+ KEYSTROKE_UP = 5,
+ KEYSTROKE_RIGHT = 6,
+ KEYSTROKE_DOWN = 7,
+ KEYSTROKE_RESIZE = 8,
+ KEYSTROKE_DEFER = 9,
+ KEYSTROKE_IGNORE = 10,
+ KEYSTROKE_FORCE_SYNCHRONIZATION = 11,
+
+ /* stuff used for debugging, probably not useful for most people */
+ KEYSTROKE_DEBUG_TREE = 12,
+ KEYSTROKE_REGIONS_ON_SCREEN = 13,
+ KEYSTROKE_TEST_INPUT = 14,
+ KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB = 15,
+
+ KEYSTROKE_FULLSCREEN = 16,
+ KEYSTROKE_VIEWPORT_MOVE_LEFT = 17,
+ KEYSTROKE_VIEWPORT_MOVE_UP = 18,
+ KEYSTROKE_VIEWPORT_MOVE_RIGHT = 19,
+ KEYSTROKE_VIEWPORT_MOVE_DOWN = 20,
+
+ KEYSTROKE_NOTHING = 21,
+
+ /* insert more here, increment KEYSTROKE_MAX accordingly.
+ * then update string translation below */
+
+ KEYSTROKE_MAX=22,
+};
+
+struct nxagentSpecialKeystrokeMap {
+ enum nxagentSpecialKeystroke stroke;
+ unsigned int modifierMask; /* everything except alt/meta */
+ int modifierAltMeta; /* modifier combination should include alt/meta */
+ KeySym keysym;
+};
+
#endif /* __Keystroke_H__ */