Unverified Commit 25d38bf3 authored by Mike Gabriel's avatar Mike Gabriel

Merge branch 'uli42-pr/cleanup_keystroke' into 3.6.x

parents 147371a2 ee18cd43
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.
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" />
......@@ -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>
......@@ -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");
......
......@@ -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
......
......@@ -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
......
......@@ -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;
......
......@@ -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 */
......
......@@ -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 {
......
......@@ -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
......
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