aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Gabriel <mike.gabriel@das-netzwerkteam.de>2017-04-03 21:44:05 +0200
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2017-04-03 21:44:05 +0200
commit25d38bf360db8f02cb5d6f7c6861dcf9cc5fb206 (patch)
treec54c8522db340ff5984483a7530011a7bb23c079
parent147371a28bb23b4dd383ceccff0e279e9dba3bbe (diff)
parentee18cd43d873bc814ca40faabd29cc486061969f (diff)
downloadnx-libs-25d38bf360db8f02cb5d6f7c6861dcf9cc5fb206.tar.gz
nx-libs-25d38bf360db8f02cb5d6f7c6861dcf9cc5fb206.tar.bz2
nx-libs-25d38bf360db8f02cb5d6f7c6861dcf9cc5fb206.zip
Merge branch 'uli42-pr/cleanup_keystroke' into 3.6.x
Attributes GH PR #404: https://github.com/ArcticaProject/nx-libs/pull/404
-rw-r--r--doc/nxagent/README.keystrokes96
-rw-r--r--doc/nxagent/README.keystrokes.debug27
-rw-r--r--etc/keystrokes.cfg18
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Args.c2
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Events.c8
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Init.c3
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Keyboard.h3
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Keystroke.c296
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Keystroke.h62
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Reconnect.c5
10 files changed, 317 insertions, 203 deletions
diff --git a/doc/nxagent/README.keystrokes b/doc/nxagent/README.keystrokes
index 96bc158d2..3d55f5096 100644
--- a/doc/nxagent/README.keystrokes
+++ b/doc/nxagent/README.keystrokes
@@ -1,6 +1,6 @@
Configurable keybindings in nxagent
-Keybindings in the redistributed x2go version of nxagent can now be configured
+Keybindings in the redistributed x2go version of nxagent can be configured
by the user. This is done via a configuration file.
File location
@@ -40,29 +40,31 @@ The configuration file is XML with the following format:
<keystroke action="fullscreen" key="space" Mod1="0" Mod2="0" Control="0" Shift="0" AltMeta="0" />
</keystrokes>
-Each 'action' defines an action to be executed when receiving that keystroke. A
-list of possible actions is given below. Some of those actions are only
-available with debug builds of nxagent.
+Each 'action' defines an action to be executed when receiving that
+keystroke. A list of possible actions is given below. Some of those
+actions are only available with debug builds of nxagent.
Keys are given as a combination of 'key' and (optionally) a number of
modifiers. The key attribute is evaluated into a X11 key via the usual
XStringToKeysym function. A list of possible keys can be found in
-/usr/include/X11/keysymdef.h, the names are specified without the leading
-'XK_'. Evaluation is case-sensitive, so, 'space' and 'Escape' will work while
-'Space' and 'escape' won't.
+/usr/include/X11/keysymdef.h, the names are specified without the
+leading 'XK_'. Evaluation is case-sensitive, so, 'space' and 'Escape'
+will work while 'Space' and 'escape' won't.
-Modifiers are given as boolean attributes, possible modifiers are Mod1, Mod2,
-Mod3, Mod4, Mod5, Control, Shift, Lock. Sensible combinations strongly depend on your
-keyboard configuration, but usually you will need Mod1 and Control. Boolean in
-this context means '0', 'false' and an unspecified attribute are false, anything
-else is considered true.
+Modifiers are given as boolean attributes, possible modifiers are
+Mod1, Mod2, Mod3, Mod4, Mod5, Control, Shift, Lock. Sensible
+combinations strongly depend on your keyboard configuration, but
+usually you will need Mod1 and Control. Boolean in this context means
+'0', 'false' and an unspecified attribute are false, anything else is
+considered true.
Everything in this file is case-sensitive. Unknown lines are ignored.
-Keybindings are evaluated from top to bottom, so if a keybinding matches, other
-keybindings further down will be ignored. The contents of the file replaces the
-default keybindings, and only one file is read, no merging between different
-configuration files is done. This also means that an empty or invalid configuration
-file deactivates all keybindings.
+Keybindings are evaluated from top to bottom, so if a keybinding
+matches, other keybindings further down will be ignored. The contents
+of the file replaces the default keybindings, and only one file is
+read, no merging between different configuration files is done. This
+also means that an empty or invalid configuration file deactivates all
+keybindings.
If an attribute occurs more than once in a line the last one wins.
@@ -71,43 +73,41 @@ List of possible 'action' attributes:
close_session
This terminates the session.
+
fullscreen
- Switches the client window into or out of fullscreen mode, using only the current head.
+ Switches the client window into or out of fullscreen mode, using
+ only the current head.
+
switch_all_screens
- Switches the client window into or out of fullscreen mode, using all available heads.
+ Switches the client window into or out of fullscreen mode, using all
+ available heads.
+
minimize
- This will minimize the client window (even for fullscreen sessions.)
-left
-up
-right
-down
+ This will minimize the client window (even for fullscreen sessions).
+
resize
- This action switches between the auto-resize and viewport mode
- (static size). The default is auto-resize. In viewport mode one can
- use the 'viewport_move_up', 'viewport_move_down',
- 'viewport_move_left' and 'viewport_move_right' actions to move
- within the image.
+ This action switches between the auto-resize (default) and viewport
+ mode. In viewport mode the xserver screen size stays static even
+ if the nxagent window is resized. You will possibly only see a part of
+ the screen and can scroll around using the following actions:
+viewport_move_left/up/right/down
+ Moves the viewport left/up/right/down by the width resp. height of
+ the visible area.
+viewport_scroll_left/up/right/down
+ Scrolls the viewport left/up/right/down with increasing speed
+ (maximum step size is 200px).
+
defer
- activate/deactivate deferred screen updates.
+ Activates/deactivates deferred screen updates.
+
ignore
- Makes it possible to add 'ignore', as in nothing happens when certain keys are pressed.
-viewport_move_left
- Moves the image viewport to the left.
-viewport_move_up
- Moves the image viewport up.
-viewport_move_right
- Moves the image viewport to the right.
-viewport_move_down
- Moves the image viewport down.
+ Ignores the following keystroke, nothing will happen when this
+ keystroke is pressed.
+
reread_keystrokes
- forces nxagent to re-read the keystroke
- configuration. Useful to add/changes keystrokes for a running
- session.
+ Forces nxagent to re-read the keystroke configuration. Useful to
+ add/change keystrokes to a running session.
-Only in builds with certain debugging options enabled, ignored otherwise:
force_synchronization
- Forces the drawing of elements to be synchronized which can fix some visual bugs.
-debug_tree
-regions_on_screen
-test_input
-deactivate_input_devices_grab
+ Forces immediate drawing of elements to be synchronized which can
+ fix some visual bugs.
diff --git a/doc/nxagent/README.keystrokes.debug b/doc/nxagent/README.keystrokes.debug
new file mode 100644
index 000000000..85ec2613a
--- /dev/null
+++ b/doc/nxagent/README.keystrokes.debug
@@ -0,0 +1,27 @@
+Configurable keybindings for debugging nxagent
+
+Some keystrokes are only available in special debug builds of nxagent
+and will be ignored otherwise. These are
+
+debug_tree
+ Show the window trees of both internal and external
+ windows. Included if DEBUG_TREE is defined.
+
+regions_on_screen
+ Make corrupted regions visible. Included if DUMP is defined.
+
+test_input
+ Activate/deactive input device debugging. Included if NX_DEBUG_INPUT
+ is defined.
+
+deactivate_input_devices_grab
+ Release grab of input devices. Included if NX_DEBUG_INPUT is
+ defined.
+
+They can be configured by adding these lines to keystrokes.cfg, below
+keystrokes represent the default:
+
+<keystroke action="debug_tree" Control="1" AltMeta="1" key="q" />
+<keystroke action="regions_on_screen" Control="1" AltMeta="1" key="a" />
+<keystroke action="test_input" Control="1" AltMeta="1" key="x" />
+<keystroke action="deactivate_input_devices_grab" Control="1" AltMeta="1" key="y" />
diff --git a/etc/keystrokes.cfg b/etc/keystrokes.cfg
index 22cc8c7a0..b482119ad 100644
--- a/etc/keystrokes.cfg
+++ b/etc/keystrokes.cfg
@@ -4,17 +4,25 @@
<keystroke action="switch_all_screens" Control="1" AltMeta="1" key="f" />
<keystroke action="fullscreen" Control="1" Shift="1" AltMeta="1" key="f" />
<keystroke action="minimize" Control="1" AltMeta="1" key="m" />
-<keystroke action="resize" Control="1" AltMeta="1" key="r" />
<keystroke action="defer" Control="1" AltMeta="1" key="e" />
<keystroke action="ignore" Control="1" AltMeta="1" key="BackSpace" />
<keystroke action="force_synchronization" Control="1" AltMeta="1" key="j" />
-<keystroke action="debug_tree" Control="1" AltMeta="1" key="q" />
-<keystroke action="regions_on_screen" Control="1" AltMeta="1" key="a" />
-<keystroke action="test_input" Control="1" AltMeta="1" key="x" />
-<keystroke action="deactivate_input_devices_grab" Control="1" AltMeta="1" key="y" />
+<keystroke action="resize" Control="1" AltMeta="1" key="r" />
<keystroke action="viewport_move_left" Control="1" Shift="1" AltMeta="1" key="Left" />
+<keystroke action="viewport_move_left" Control="1" Shift="1" AltMeta="1" key="KP_Left" />
<keystroke action="viewport_move_up" Control="1" AltMeta="1" key="Up" />
+<keystroke action="viewport_move_up" Control="1" AltMeta="1" key="KP_Up" />
<keystroke action="viewport_move_right" Control="1" AltMeta="1" key="Right" />
+<keystroke action="viewport_move_right" Control="1" AltMeta="1" key="KP_Right" />
<keystroke action="viewport_move_down" Control="1" AltMeta="1" key="Down" />
+<keystroke action="viewport_move_down" Control="1" AltMeta="1" key="KP_Down" />
+<keystroke action="viewport_scroll_left" Control="1" AltMeta="1" key="Left" />
+<keystroke action="viewport_scroll_left" Control="1" AltMeta="1" key="KP_Left" />
+<keystroke action="viewport_scroll_up" Control="1" AltMeta="1" key="Up" />
+<keystroke action="viewport_scroll_up" Control="1" AltMeta="1" key="KP_Up" />
+<keystroke action="viewport_scroll_right" Control="1" AltMeta="1" key="Right" />
+<keystroke action="viewport_scroll_right" Control="1" AltMeta="1" key="KP_Right" />
+<keystroke action="viewport_scroll_down" Control="1" AltMeta="1" key="Down" />
+<keystroke action="viewport_scroll_down" Control="1" AltMeta="1" key="KP_Down" />
<keystroke action="reread_keystrokes" Control="1" AltMeta="1" key="k" />
</keystrokes>
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c
index 2bc12a3b4..6896d7212 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c
@@ -2103,6 +2103,8 @@ void ddxUseMsg()
ErrorF("-nokbreset don't reset keyboard device if the session is resumed\n");
ErrorF("-noxkblock always allow applications to change layout through XKEYBOARD\n");
ErrorF("-tile WxH size of image tiles (minimum allowed: 32x32)\n");
+ ErrorF("-keystrokefile file file with keyboard shortcut definitions\n");
+ ErrorF("-verbose print more warning and error messages\n");
ErrorF("-D enable desktop mode\n");
ErrorF("-R enable rootless mode\n");
ErrorF("-S enable shadow mode\n");
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index d8512b548..e4d031e06 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -180,6 +180,10 @@ static int viewportLastX;
static int viewportLastY;
static Cursor viewportCursor;
+#define MAX_INC 200
+#define INC_STEP 5
+#define nextinc(x) ((x) < MAX_INC ? (x) += INC_STEP : (x))
+
/*
* Keyboard and pointer are handled as they were real devices by
* Xnest and we inherit this behaviour. The following mask will
@@ -193,10 +197,6 @@ static Mask defaultEventMask;
static int lastEventSerial = 0;
-#define MAX_INC 200
-#define INC_STEP 5
-#define nextinc(x) ((x) < MAX_INC ? (x) += INC_STEP : (x))
-
/*
* Used to mask the appropriate bits in
* the state reported by XkbStateNotify
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.c b/nx-X11/programs/Xserver/hw/nxagent/Init.c
index f15f2cb0a..014ab17f9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Init.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.c
@@ -69,6 +69,7 @@ is" without express or implied warranty.
#include "Font.h"
#include "Millis.h"
#include "Error.h"
+#include "Keystroke.h"
#include <nx/NX.h>
#include "compext/Compext.h"
@@ -406,6 +407,8 @@ FIXME: These variables, if not removed at all because have probably
*/
blackRoot = TRUE;
+
+ nxagentInitKeystrokes(False);
}
void
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
index d4f30fa6c..ba95a3a22 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
@@ -126,6 +126,9 @@ CARD8 nxagentConvertKeycode(CARD8 k);
extern CARD8 nxagentCapsLockKeycode;
extern CARD8 nxagentNumLockKeycode;
+extern unsigned int nxagentAltMetaMask;
+extern unsigned int nxagentAltMask;
+extern unsigned int nxagentMetaMask;
extern unsigned int nxagentCapsMask;
extern unsigned int nxagentNumlockMask;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
index 69b07dfe5..ef7b0b27f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
@@ -33,10 +33,10 @@
#include "Display.h"
#include "Events.h"
#include "Options.h"
-#include "Keystroke.h"
#include "Keyboard.h"
#include "Drawable.h"
#include "Init.h" /* extern int nxagentX2go */
+#include "Utils.h"
#include <unistd.h>
@@ -48,7 +48,7 @@ extern Bool nxagentIpaq;
extern char *nxagentKeystrokeFile;
#ifdef NX_DEBUG_INPUT
-int nxagentDebugInputDevices = 0;
+int nxagentDebugInputDevices = False;
unsigned long nxagentLastInputDevicesDumpTime = 0;
extern void nxagentDeactivateInputDevicesGrabs();
#endif
@@ -63,6 +63,9 @@ extern void nxagentDeactivateInputDevicesGrabs();
#undef DEBUG
#undef DUMP
+/* must be included _after_ DUMP */
+#include "Keystroke.h"
+
/* 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 */
@@ -72,24 +75,29 @@ char * nxagentSpecialKeystrokeNames[] = {
"switch_all_screens",
"fullscreen",
"minimize",
- "left",
- "up",
- "right",
- "down",
- "resize",
"defer",
"ignore",
"force_synchronization",
+#ifdef DEBUG_TREE
"debug_tree",
+#endif
+#ifdef DUMP
"regions_on_screen",
+#endif
+#ifdef NX_DEBUG_INPUT
"test_input",
"deactivate_input_devices_grab",
-
+#endif
+ "resize",
"viewport_move_left",
"viewport_move_up",
"viewport_move_right",
"viewport_move_down",
+ "viewport_scroll_left",
+ "viewport_scroll_up",
+ "viewport_scroll_right",
+ "viewport_scroll_down",
"reread_keystrokes",
NULL,
@@ -97,27 +105,25 @@ char * nxagentSpecialKeystrokeNames[] = {
struct nxagentSpecialKeystrokeMap default_map[] = {
/* stroke, modifierMask, modifierAltMeta, keysym */
+#ifdef DEBUG_TREE
{KEYSTROKE_DEBUG_TREE, ControlMask, True, XK_q},
+#endif
{KEYSTROKE_CLOSE_SESSION, ControlMask, True, XK_t},
{KEYSTROKE_SWITCH_ALL_SCREENS, ControlMask, True, XK_f},
{KEYSTROKE_FULLSCREEN, ControlMask | ShiftMask, True, XK_f},
{KEYSTROKE_MINIMIZE, ControlMask, True, XK_m},
- {KEYSTROKE_LEFT, ControlMask, True, XK_Left},
- {KEYSTROKE_LEFT, ControlMask, True, XK_KP_Left},
- {KEYSTROKE_UP, ControlMask, True, XK_Up},
- {KEYSTROKE_UP, ControlMask, True, XK_KP_Up},
- {KEYSTROKE_RIGHT, ControlMask, True, XK_Right},
- {KEYSTROKE_RIGHT, ControlMask, True, XK_KP_Right},
- {KEYSTROKE_DOWN, ControlMask, True, XK_Down},
- {KEYSTROKE_DOWN, ControlMask, True, XK_KP_Down},
- {KEYSTROKE_RESIZE, ControlMask, True, XK_r},
{KEYSTROKE_DEFER, ControlMask, True, XK_e},
{KEYSTROKE_IGNORE, ControlMask, True, XK_BackSpace},
{KEYSTROKE_IGNORE, 0, False, XK_Terminate_Server},
{KEYSTROKE_FORCE_SYNCHRONIZATION, ControlMask, True, XK_j},
+#ifdef DUMP
{KEYSTROKE_REGIONS_ON_SCREEN, ControlMask, True, XK_a},
+#endif
+#ifdef NX_DEBUG_INPUT
{KEYSTROKE_TEST_INPUT, ControlMask, True, XK_x},
{KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB, ControlMask, True, XK_y},
+#endif
+ {KEYSTROKE_RESIZE, ControlMask, True, XK_r},
{KEYSTROKE_VIEWPORT_MOVE_LEFT, ControlMask | ShiftMask, True, XK_Left},
{KEYSTROKE_VIEWPORT_MOVE_LEFT, ControlMask | ShiftMask, True, XK_KP_Left},
{KEYSTROKE_VIEWPORT_MOVE_UP, ControlMask | ShiftMask, True, XK_Up},
@@ -126,6 +132,14 @@ struct nxagentSpecialKeystrokeMap default_map[] = {
{KEYSTROKE_VIEWPORT_MOVE_RIGHT, ControlMask | ShiftMask, True, XK_KP_Right},
{KEYSTROKE_VIEWPORT_MOVE_DOWN, ControlMask | ShiftMask, True, XK_Down},
{KEYSTROKE_VIEWPORT_MOVE_DOWN, ControlMask | ShiftMask, True, XK_KP_Down},
+ {KEYSTROKE_VIEWPORT_SCROLL_LEFT, ControlMask, True, XK_Left},
+ {KEYSTROKE_VIEWPORT_SCROLL_LEFT, ControlMask, True, XK_KP_Left},
+ {KEYSTROKE_VIEWPORT_SCROLL_UP, ControlMask, True, XK_Up},
+ {KEYSTROKE_VIEWPORT_SCROLL_UP, ControlMask, True, XK_KP_Up},
+ {KEYSTROKE_VIEWPORT_SCROLL_RIGHT, ControlMask, True, XK_Right},
+ {KEYSTROKE_VIEWPORT_SCROLL_RIGHT, ControlMask, True, XK_KP_Right},
+ {KEYSTROKE_VIEWPORT_SCROLL_DOWN, ControlMask, True, XK_Down},
+ {KEYSTROKE_VIEWPORT_SCROLL_DOWN, ControlMask, True, XK_KP_Down},
{KEYSTROKE_REREAD_KEYSTROKES, ControlMask, True, XK_k},
{KEYSTROKE_END_MARKER, 0, False, NoSymbol},
};
@@ -171,14 +185,13 @@ static Bool read_binding_from_xmlnode(xmlNode *node, struct nxagentSpecialKeystr
{
/* init the struct to have proper values in case not all attributes are found */
struct nxagentSpecialKeystrokeMap newkm = {
- .stroke = KEYSTROKE_END_MARKER,
+ .stroke = KEYSTROKE_NOTHING,
.modifierMask = 0,
.modifierAltMeta = False,
.keysym = NoSymbol
};
- xmlAttr *attr;
- for (attr = node->properties; attr; attr = attr->next)
+ for (xmlAttr *attr = node->properties; attr; attr = attr->next)
{
/* ignore attributes without data (which should never happen anyways) */
if (attr->children->content == NULL)
@@ -192,7 +205,7 @@ static Bool read_binding_from_xmlnode(xmlNode *node, struct nxagentSpecialKeystr
if (strcmp((char *)attr->name, "action") == 0)
{
- newkm.stroke = KEYSTROKE_END_MARKER;
+ newkm.stroke = KEYSTROKE_NOTHING;
for (int i = 0; nxagentSpecialKeystrokeNames[i] != NULL; i++)
{
if (strcmp(nxagentSpecialKeystrokeNames[i], (char *)attr->children->content) == 0)
@@ -203,6 +216,8 @@ static Bool read_binding_from_xmlnode(xmlNode *node, struct nxagentSpecialKeystr
break;
}
}
+ if (newkm.stroke == KEYSTROKE_NOTHING)
+ fprintf(stderr, "Info: ignoring unknown keystroke action '%s'.\n", (char *)attr->children->content);
continue;
}
else if (strcmp((char *)attr->name, "key") == 0)
@@ -228,7 +243,7 @@ static Bool read_binding_from_xmlnode(xmlNode *node, struct nxagentSpecialKeystr
}
}
- if (newkm.stroke != KEYSTROKE_END_MARKER && newkm.keysym != NoSymbol)
+ if (newkm.stroke != KEYSTROKE_NOTHING && newkm.keysym != NoSymbol)
{
/* keysym and stroke are required, everything else is optional */
memcpy(ret, &newkm, sizeof(struct nxagentSpecialKeystrokeMap));
@@ -249,7 +264,7 @@ static Bool read_binding_from_xmlnode(xmlNode *node, struct nxagentSpecialKeystr
* - hardcoded traditional NX default settings
* If run in x2go flavour different filenames and varnames are used.
*/
-static void parse_keystroke_file(Bool force)
+void nxagentInitKeystrokes(Bool force)
{
char *filename = NULL;
@@ -267,7 +282,7 @@ static void parse_keystroke_file(Bool force)
free(map);
map = default_map;
}
- fprintf(stderr, "re-reading keystroke config\n");
+ fprintf(stderr, "Info: re-reading keystrokes configuration\n");
}
else
{
@@ -295,37 +310,12 @@ static void parse_keystroke_file(Bool force)
exit(EXIT_FAILURE);
}
}
- else if ((filename = getenv(envvar)) && access(filename, R_OK) == 0)
- {
- if (!(filename = strdup(filename)))
- {
- fprintf(stderr, "malloc failed");
- exit(EXIT_FAILURE);
- }
- }
- else
+ else if (nxagentKeystrokeFile)
{
- char *homedir = getenv("HOME");
- filename = NULL;
- if (homedir)
+ fprintf(stderr, "Warning: Cannot read keystroke file '%s'.\n", nxagentKeystrokeFile);
+ if ((filename = getenv(envvar)) && access(filename, R_OK) == 0)
{
- if (!(filename = calloc(1, strlen(homefile) + strlen(homedir) + 1)))
- {
- fprintf(stderr, "malloc failed");
- exit(EXIT_FAILURE);
- }
- strcpy(filename, homedir);
- strcpy(filename + strlen(homedir), homefile);
- }
-
- if (access(filename, R_OK) == 0)
- {
- /* empty */
- }
- else if (access(etcfile, R_OK) == 0)
- {
- free(filename);
- if (!(filename = strdup(etcfile)))
+ if (!(filename = strdup(filename)))
{
fprintf(stderr, "malloc failed");
exit(EXIT_FAILURE);
@@ -333,8 +323,37 @@ static void parse_keystroke_file(Bool force)
}
else
{
- free(filename);
+ char *homedir = getenv("HOME");
filename = NULL;
+ if (homedir)
+ {
+ if (!(filename = calloc(1, strlen(homefile) + strlen(homedir) + 1)))
+ {
+ fprintf(stderr, "malloc failed");
+ exit(EXIT_FAILURE);
+ }
+ strcpy(filename, homedir);
+ strcpy(filename + strlen(homedir), homefile);
+ }
+
+ if (access(filename, R_OK) == 0)
+ {
+ /* empty */
+ }
+ else if (access(etcfile, R_OK) == 0)
+ {
+ free(filename);
+ if (!(filename = strdup(etcfile)))
+ {
+ fprintf(stderr, "malloc failed");
+ exit(EXIT_FAILURE);
+ }
+ }
+ else
+ {
+ free(filename);
+ filename = NULL;
+ }
}
}
@@ -345,6 +364,7 @@ static void parse_keystroke_file(Bool force)
xmlDoc *doc = xmlReadFile(filename, NULL, 0);
if (doc)
{
+ fprintf(stderr, "Info: using keystrokes file '%s'\n", filename);
for (xmlNode *cur = xmlDocGetRootElement(doc); cur; cur = cur->next)
{
if (cur->type == XML_ELEMENT_NODE && strcmp((char *)cur->name, "keystrokes") == 0)
@@ -375,7 +395,29 @@ static void parse_keystroke_file(Bool force)
if (bindings->type == XML_ELEMENT_NODE &&
strcmp((char *)bindings->name, "keystroke") == 0 &&
read_binding_from_xmlnode(bindings, &(map[idx])))
+ {
+ Bool store = True;
+ for (int j = 0; j < idx; j++)
+ {
+ if (map[j].stroke != KEYSTROKE_NOTHING &&
+ map[idx].keysym != NoSymbol &&
+ map[j].keysym == map[idx].keysym &&
+ map[j].modifierMask == map[idx].modifierMask &&
+ map[j].modifierAltMeta == map[idx].modifierAltMeta)
+ {
+ fprintf(stderr, "Warning: ignoring keystroke '%s' (already in use by '%s')\n",
+ nxagentSpecialKeystrokeNames[map[idx].stroke],
+ nxagentSpecialKeystrokeNames[map[j].stroke]);
+ store = False;
+ break;
+ }
+ }
+
+ if (store)
idx++;
+ else
+ map[idx].stroke = KEYSTROKE_NOTHING;
+ }
}
#ifdef DEBUG
fprintf(stderr, "%s: read %d keystrokes", __func__, idx);
@@ -390,26 +432,55 @@ static void parse_keystroke_file(Bool force)
}
else
{
- #ifdef DEBUG
- fprintf(stderr, "XML parsing for %s failed\n", filename);
- #endif
+ fprintf(stderr, "Warning: could not read/parse keystrokes file '%s'\n", filename);
}
free(filename);
filename = NULL;
}
+
+ if (map == default_map)
+ {
+ fprintf(stderr, "Info: Using builtin keystrokes.\n");
+ }
+
+ nxagentDumpKeystrokes();
+}
+
+void nxagentDumpKeystrokes(void)
+{
+ int maxlen = 0;
+ for (int i = 0; nxagentSpecialKeystrokeNames[i]; i++)
+ maxlen = MAX(maxlen, strlen(nxagentSpecialKeystrokeNames[i]));
+
+ fprintf(stderr, "Current 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));
+ }
}
static enum nxagentSpecialKeystroke find_keystroke(XKeyEvent *X)
{
enum nxagentSpecialKeystroke ret = KEYSTROKE_NOTHING;
int keysyms_per_keycode_return;
- struct nxagentSpecialKeystrokeMap *cur;
-
- /* FIXME: we do late parsing here, this should be done at startup,
- not at first keypress! */
- parse_keystroke_file(False);
-
- cur = map;
XlibKeySym *keysym = XGetKeyboardMapping(nxagentDisplay,
X->keycode,
@@ -419,7 +490,7 @@ static enum nxagentSpecialKeystroke find_keystroke(XKeyEvent *X)
#ifdef DEBUG
fprintf(stderr, "%s: got keysym '%c' (%d)\n", __func__, keysym[0], keysym[0]);
#endif
- while (cur->stroke != KEYSTROKE_END_MARKER) {
+ for (struct nxagentSpecialKeystrokeMap *cur = map; cur->stroke != KEYSTROKE_END_MARKER; cur++) {
#ifdef DEBUG
fprintf(stderr, "%s: checking keysym '%c' (%d)\n", __func__, cur->keysym, cur->keysym);
#endif
@@ -430,7 +501,6 @@ static enum nxagentSpecialKeystroke find_keystroke(XKeyEvent *X)
free(keysym);
return cur->stroke;
}
- cur++;
}
free(keysym);
@@ -471,53 +541,24 @@ Bool nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
}
switch (stroke) {
+#ifdef DEBUG_TREE
case KEYSTROKE_DEBUG_TREE:
- #ifdef DEBUG_TREE
*result = doDebugTree;
- #endif
break;
+#endif
case KEYSTROKE_CLOSE_SESSION:
*result = doCloseSession;
break;
case KEYSTROKE_SWITCH_ALL_SCREENS:
- if (nxagentOption(Rootless) == False) {
+ if (!nxagentOption(Rootless)) {
*result = doSwitchAllScreens;
}
break;
case KEYSTROKE_MINIMIZE:
- if (nxagentOption(Rootless) == False) {
+ if (!nxagentOption(Rootless)) {
*result = doMinimize;
}
break;
- case KEYSTROKE_LEFT:
- if (nxagentOption(Rootless) == False &&
- nxagentOption(DesktopResize) == False) {
- *result = doViewportLeft;
- }
- break;
- case KEYSTROKE_UP:
- if (nxagentOption(Rootless) == False &&
- nxagentOption(DesktopResize) == False) {
- *result = doViewportUp;
- }
- break;
- case KEYSTROKE_RIGHT:
- if (nxagentOption(Rootless) == False &&
- nxagentOption(DesktopResize) == False) {
- *result = doViewportRight;
- }
- break;
- case KEYSTROKE_DOWN:
- if (nxagentOption(Rootless) == False &&
- nxagentOption(DesktopResize) == False) {
- *result = doViewportDown;
- }
- break;
- case KEYSTROKE_RESIZE:
- if (nxagentOption(Rootless) == False) {
- *result = doSwitchResizeMode;
- }
- break;
case KEYSTROKE_DEFER:
*result = doSwitchDeferMode;
break;
@@ -528,66 +569,85 @@ Bool nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
case KEYSTROKE_FORCE_SYNCHRONIZATION:
nxagentForceSynchronization = 1;
break;
+#ifdef DUMP
case KEYSTROKE_REGIONS_ON_SCREEN:
- #ifdef DUMP
nxagentRegionsOnScreen();
- #endif
break;
+#endif
+#ifdef NX_DEBUG_INPUT
case KEYSTROKE_TEST_INPUT:
/*
* Used to test the input devices state.
*/
- #ifdef NX_DEBUG_INPUT
if (X -> type == KeyPress) {
- if (nxagentDebugInputDevices == 0) {
+ if (!nxagentDebugInputDevices) {
fprintf(stderr, "Info: Turning input devices debug ON.\n");
- nxagentDebugInputDevices = 1;
+ nxagentDebugInputDevices = True;
} else {
fprintf(stderr, "Info: Turning input devices debug OFF.\n");
- nxagentDebugInputDevices = 0;
+ nxagentDebugInputDevices = False;
nxagentLastInputDevicesDumpTime = 0;
}
}
return True;
- #endif
break;
case KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB:
- #ifdef NX_DEBUG_INPUT
if (X->type == KeyPress) {
nxagentDeactivateInputDevicesGrab();
}
return True;
- #endif
break;
+#endif
case KEYSTROKE_FULLSCREEN:
- if (nxagentOption(Rootless) == 0) {
+ if (!nxagentOption(Rootless)) {
*result = doSwitchFullscreen;
}
break;
+ case KEYSTROKE_RESIZE:
+ if (!nxagentOption(Rootless)) {
+ *result = doSwitchResizeMode;
+ }
+ break;
case KEYSTROKE_VIEWPORT_MOVE_LEFT:
- if (nxagentOption(Rootless) == 0 &&
- nxagentOption(DesktopResize) == 0) {
+ if (!nxagentOption(Rootless) && !nxagentOption(DesktopResize)) {
*result = doViewportMoveLeft;
}
break;
case KEYSTROKE_VIEWPORT_MOVE_UP:
- if (nxagentOption(Rootless) == 0 &&
- nxagentOption(DesktopResize) == 0) {
+ if (!nxagentOption(Rootless) && !nxagentOption(DesktopResize)) {
*result = doViewportMoveUp;
}
break;
case KEYSTROKE_VIEWPORT_MOVE_RIGHT:
- if (nxagentOption(Rootless) == 0 &&
- nxagentOption(DesktopResize) == 0) {
+ if (!nxagentOption(Rootless) && !nxagentOption(DesktopResize)) {
*result = doViewportMoveRight;
}
break;
case KEYSTROKE_VIEWPORT_MOVE_DOWN:
- if (nxagentOption(Rootless) == 0 &&
- nxagentOption(DesktopResize) == 0) {
+ if (!nxagentOption(Rootless) && !nxagentOption(DesktopResize)) {
*result = doViewportMoveDown;
}
break;
+ case KEYSTROKE_VIEWPORT_SCROLL_LEFT:
+ if (!nxagentOption(Rootless) && !nxagentOption(DesktopResize)) {
+ *result = doViewportLeft;
+ }
+ break;
+ case KEYSTROKE_VIEWPORT_SCROLL_UP:
+ if (!nxagentOption(Rootless) && !nxagentOption(DesktopResize)) {
+ *result = doViewportUp;
+ }
+ break;
+ case KEYSTROKE_VIEWPORT_SCROLL_RIGHT:
+ if (!nxagentOption(Rootless) && !nxagentOption(DesktopResize)) {
+ *result = doViewportRight;
+ }
+ break;
+ case KEYSTROKE_VIEWPORT_SCROLL_DOWN:
+ if (!nxagentOption(Rootless) && !nxagentOption(DesktopResize)) {
+ *result = doViewportDown;
+ }
+ break;
case KEYSTROKE_REREAD_KEYSTROKES:
/* two reasons to check on KeyRelease:
- this code is called for KeyPress and KeyRelease, so we
@@ -596,7 +656,7 @@ Bool nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
might lead to unexpected behaviour
*/
if (X->type == KeyRelease)
- parse_keystroke_file(True);
+ nxagentInitKeystrokes(True);
break;
case KEYSTROKE_NOTHING: /* do nothing. difference to KEYSTROKE_IGNORE is the return value */
case KEYSTROKE_END_MARKER: /* just to make gcc STFU */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
index 48ed65b35..13a83d0fe 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
@@ -29,8 +29,8 @@
#include "Events.h"
extern Bool nxagentCheckSpecialKeystroke(XKeyEvent*, enum HandleEventResult*);
-
-unsigned int nxagentAltMetaMask;
+extern void nxagentDumpKeystrokes(void);
+extern void nxagentInitKeystrokes(Bool force);
/* 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 */
@@ -39,39 +39,45 @@ unsigned int nxagentAltMetaMask;
* 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_FULLSCREEN = 3,
- KEYSTROKE_MINIMIZE = 4,
- KEYSTROKE_LEFT = 5,
- KEYSTROKE_UP = 6,
- KEYSTROKE_RIGHT = 7,
- KEYSTROKE_DOWN = 8,
- KEYSTROKE_RESIZE = 9,
- KEYSTROKE_DEFER = 10,
- KEYSTROKE_IGNORE = 11,
- KEYSTROKE_FORCE_SYNCHRONIZATION = 12,
+ KEYSTROKE_END_MARKER,
+ KEYSTROKE_CLOSE_SESSION,
+ KEYSTROKE_SWITCH_ALL_SCREENS,
+ KEYSTROKE_FULLSCREEN,
+ KEYSTROKE_MINIMIZE,
+ KEYSTROKE_DEFER,
+ KEYSTROKE_IGNORE,
+ KEYSTROKE_FORCE_SYNCHRONIZATION,
/* stuff used for debugging, probably not useful for most people */
- KEYSTROKE_DEBUG_TREE = 13,
- KEYSTROKE_REGIONS_ON_SCREEN = 14,
- KEYSTROKE_TEST_INPUT = 15,
- KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB = 16,
+#ifdef DEBUG_TREE
+ KEYSTROKE_DEBUG_TREE,
+#endif
+#ifdef DUMP
+ KEYSTROKE_REGIONS_ON_SCREEN,
+#endif
+#ifdef NX_DEBUG_INPUT
+ KEYSTROKE_TEST_INPUT,
+ KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB,
+#endif
- KEYSTROKE_VIEWPORT_MOVE_LEFT = 17,
- KEYSTROKE_VIEWPORT_MOVE_UP = 18,
- KEYSTROKE_VIEWPORT_MOVE_RIGHT = 19,
- KEYSTROKE_VIEWPORT_MOVE_DOWN = 20,
+ /* all the viewport stuff */
+ KEYSTROKE_RESIZE,
+ KEYSTROKE_VIEWPORT_MOVE_LEFT,
+ KEYSTROKE_VIEWPORT_MOVE_UP,
+ KEYSTROKE_VIEWPORT_MOVE_RIGHT,
+ KEYSTROKE_VIEWPORT_MOVE_DOWN,
+ KEYSTROKE_VIEWPORT_SCROLL_LEFT,
+ KEYSTROKE_VIEWPORT_SCROLL_UP,
+ KEYSTROKE_VIEWPORT_SCROLL_RIGHT,
+ KEYSTROKE_VIEWPORT_SCROLL_DOWN,
- KEYSTROKE_REREAD_KEYSTROKES = 21,
+ KEYSTROKE_REREAD_KEYSTROKES,
- KEYSTROKE_NOTHING = 22,
+ KEYSTROKE_NOTHING,
- /* insert more here, increment KEYSTROKE_MAX accordingly.
- * then update string translation below */
+ /* insert more here and in the string translation */
- KEYSTROKE_MAX = 23,
+ KEYSTROKE_MAX,
};
struct nxagentSpecialKeystrokeMap {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
index ee21bff69..fb2303549 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
@@ -52,6 +52,7 @@
#include "Millis.h"
#include "Splash.h"
#include "Error.h"
+#include "Keystroke.h"
#ifdef XKB
#include "XKBsrv.h"
@@ -646,6 +647,10 @@ Bool nxagentReconnectSession(void)
goto nxagentReconnectError;
}
+ /* Re-read keystrokes definitions in case the keystrokes file has
+ changed while being supended */
+ nxagentInitKeystrokes(True);
+
#ifdef NX_DEBUG_INPUT
fprintf(stderr, "Session: Session resumed at '%s' timestamp [%lu].\n", GetTimeAsString(), GetTimeInMillis());
#else