Unverified Commit 6ac805ab authored by Mike Gabriel's avatar Mike Gabriel

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

parents 320cece2 6f4eb154
...@@ -16,7 +16,7 @@ If nxagent is called without branding, it searches: ...@@ -16,7 +16,7 @@ If nxagent is called without branding, it searches:
If nxagent is called with X2Go branding (i.e., as x2goagent), it searches: If nxagent is called with X2Go branding (i.e., as x2goagent), it searches:
- in the location given by the '-keystrokefile' command line parameter - in the location given by the '-keystrokefile' command line parameter
- in the location given by the NXAGENT_KEYSTROKEFILE environment variable - in the location given by the X2GO_KEYSTROKEFILE environment variable
- in ~/.x2go/config/keystrokes.cfg - in ~/.x2go/config/keystrokes.cfg
- in /etc/x2go/keystrokes.cfg - in /etc/x2go/keystrokes.cfg
...@@ -52,7 +52,7 @@ XStringToKeysym function. A list of possible keys can be found in ...@@ -52,7 +52,7 @@ XStringToKeysym function. A list of possible keys can be found in
'Space' and 'escape' won't. 'Space' and 'escape' won't.
Modifiers are given as boolean attributes, possible modifiers are Mod1, Mod2, Modifiers are given as boolean attributes, possible modifiers are Mod1, Mod2,
Mod3, Mod4, Control, Shift, Lock. Sensible combinations strongly depend on your Mod3, Mod4, Mod5, Control, Shift, Lock. Sensible combinations strongly depend on your
keyboard configuration, but usually you will need Mod1 and Control. Boolean in keyboard configuration, but usually you will need Mod1 and Control. Boolean in
this context means '0', 'false' and an unspecified attribute are false, anything this context means '0', 'false' and an unspecified attribute are false, anything
else is considered true. else is considered true.
...@@ -64,12 +64,17 @@ default keybindings, and only one file is read, no merging between different ...@@ -64,12 +64,17 @@ 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 configuration files is done. This also means that an empty or invalid configuration
file deactivates all keybindings. file deactivates all keybindings.
If an attribute occurs more than once in a line the last one wins.
List of possible 'action' attributes: List of possible 'action' attributes:
------------------------------------- -------------------------------------
close_session close_session
This terminates the session. This terminates the session.
fullscreen
Switches the client window into or out of fullscreen mode, using only the current head.
switch_all_screens switch_all_screens
Switches the client window into or out of fullscreen mode, using all available heads.
minimize minimize
This will minimize the client window (even for fullscreen sessions.) This will minimize the client window (even for fullscreen sessions.)
left left
...@@ -77,13 +82,15 @@ up ...@@ -77,13 +82,15 @@ up
right right
down down
resize 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 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.
defer defer
Works like 'ignore' to make some keys be ignored/defunct inside the session. activate/deactivate deferred screen updates.
ignore ignore
Makes it possible to add 'ignore', as in nothing happens when certain keys are pressed. Makes it possible to add 'ignore', as in nothing happens when certain keys are pressed.
fullscreen
Switches the client window into or out of fullscreen mode.
viewport_move_left viewport_move_left
Moves the image viewport to the left. Moves the image viewport to the left.
viewport_move_up viewport_move_up
...@@ -92,6 +99,10 @@ viewport_move_right ...@@ -92,6 +99,10 @@ viewport_move_right
Moves the image viewport to the right. Moves the image viewport to the right.
viewport_move_down viewport_move_down
Moves the image viewport down. Moves the image viewport down.
reread_keystrokes
forces nxagent to re-read the keystroke
configuration. Useful to add/changes keystrokes for a running
session.
Only in builds with certain debugging options enabled, ignored otherwise: Only in builds with certain debugging options enabled, ignored otherwise:
force_synchronization force_synchronization
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
<keystrokes> <keystrokes>
<keystroke action="close_session" Control="1" AltMeta="1" key="t" /> <keystroke action="close_session" Control="1" AltMeta="1" key="t" />
<keystroke action="switch_all_screens" Control="1" AltMeta="1" key="f" /> <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="minimize" Control="1" AltMeta="1" key="m" />
<keystroke action="resize" Control="1" AltMeta="1" key="r" /> <keystroke action="resize" Control="1" AltMeta="1" key="r" />
<keystroke action="defer" Control="1" AltMeta="1" key="e" /> <keystroke action="defer" Control="1" AltMeta="1" key="e" />
...@@ -11,9 +12,9 @@ ...@@ -11,9 +12,9 @@
<keystroke action="regions_on_screen" Control="1" AltMeta="1" key="a" /> <keystroke action="regions_on_screen" Control="1" AltMeta="1" key="a" />
<keystroke action="test_input" Control="1" AltMeta="1" key="x" /> <keystroke action="test_input" Control="1" AltMeta="1" key="x" />
<keystroke action="deactivate_input_devices_grab" Control="1" AltMeta="1" key="y" /> <keystroke action="deactivate_input_devices_grab" Control="1" AltMeta="1" key="y" />
<keystroke action="fullscreen" Control="1" Shift="1" AltMeta="1" key="f" />
<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="Left" />
<keystroke action="viewport_move_up" Control="1" AltMeta="1" key="Up" /> <keystroke action="viewport_move_up" Control="1" AltMeta="1" key="Up" />
<keystroke action="viewport_move_right" Control="1" AltMeta="1" key="Right" /> <keystroke action="viewport_move_right" Control="1" AltMeta="1" key="Right" />
<keystroke action="viewport_move_down" Control="1" AltMeta="1" key="Down" /> <keystroke action="viewport_move_down" Control="1" AltMeta="1" key="Down" />
<keystroke action="reread_keystrokes" Control="1" AltMeta="1" key="k" />
</keystrokes> </keystrokes>
...@@ -202,6 +202,8 @@ extern char *nxagentKeyboard; ...@@ -202,6 +202,8 @@ extern char *nxagentKeyboard;
static char *nxagentXkbGetRules(void); static char *nxagentXkbGetRules(void);
unsigned int nxagentAltMetaMask; unsigned int nxagentAltMetaMask;
unsigned int nxagentAltMask;
unsigned int nxagentMetaMask;
static void nxagentCheckAltMetaKeys(CARD8, int); static void nxagentCheckAltMetaKeys(CARD8, int);
...@@ -788,6 +790,8 @@ N/A ...@@ -788,6 +790,8 @@ N/A
#endif /* #ifdef _XSERVER64 */ #endif /* #ifdef _XSERVER64 */
nxagentAltMetaMask = 0; nxagentAltMetaMask = 0;
nxagentAltMask = 0;
nxagentMetaMask = 0;
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
modmap[i] = 0; modmap[i] = 0;
...@@ -1378,21 +1382,25 @@ void nxagentCheckAltMetaKeys(CARD8 keycode, int j) ...@@ -1378,21 +1382,25 @@ void nxagentCheckAltMetaKeys(CARD8 keycode, int j)
if (keycode == XKeysymToKeycode(nxagentDisplay, XK_Meta_L)) if (keycode == XKeysymToKeycode(nxagentDisplay, XK_Meta_L))
{ {
nxagentAltMetaMask |= 1 << j; nxagentAltMetaMask |= 1 << j;
nxagentMetaMask |= 1 << j;
} }
if (keycode == XKeysymToKeycode(nxagentDisplay, XK_Meta_R)) if (keycode == XKeysymToKeycode(nxagentDisplay, XK_Meta_R))
{ {
nxagentAltMetaMask |= 1 << j; nxagentAltMetaMask |= 1 << j;
nxagentMetaMask |= 1 << j;
} }
if (keycode == XKeysymToKeycode(nxagentDisplay, XK_Alt_L)) if (keycode == XKeysymToKeycode(nxagentDisplay, XK_Alt_L))
{ {
nxagentAltMetaMask |= 1 << j; nxagentAltMetaMask |= 1 << j;
nxagentAltMask |= 1 << j;
} }
if (keycode == XKeysymToKeycode(nxagentDisplay, XK_Alt_R)) if (keycode == XKeysymToKeycode(nxagentDisplay, XK_Alt_R))
{ {
nxagentAltMetaMask |= 1 << j; nxagentAltMetaMask |= 1 << j;
nxagentAltMask |= 1 << j;
} }
} }
......
...@@ -45,7 +45,6 @@ ...@@ -45,7 +45,6 @@
extern Bool nxagentWMIsRunning; extern Bool nxagentWMIsRunning;
extern Bool nxagentIpaq; extern Bool nxagentIpaq;
extern char *nxagentKeystrokeFile; extern char *nxagentKeystrokeFile;
Bool nxagentKeystrokeFileParsed = False;
#ifdef NX_DEBUG_INPUT #ifdef NX_DEBUG_INPUT
int nxagentDebugInputDevices = 0; int nxagentDebugInputDevices = 0;
...@@ -70,6 +69,7 @@ char * nxagentSpecialKeystrokeNames[] = { ...@@ -70,6 +69,7 @@ char * nxagentSpecialKeystrokeNames[] = {
"end_marker", "end_marker",
"close_session", "close_session",
"switch_all_screens", "switch_all_screens",
"fullscreen",
"minimize", "minimize",
"left", "left",
"up", "up",
...@@ -85,61 +85,52 @@ char * nxagentSpecialKeystrokeNames[] = { ...@@ -85,61 +85,52 @@ char * nxagentSpecialKeystrokeNames[] = {
"test_input", "test_input",
"deactivate_input_devices_grab", "deactivate_input_devices_grab",
"fullscreen",
"viewport_move_left", "viewport_move_left",
"viewport_move_up", "viewport_move_up",
"viewport_move_right", "viewport_move_right",
"viewport_move_down", "viewport_move_down",
"reread_keystrokes",
NULL, NULL,
}; };
struct nxagentSpecialKeystrokeMap default_map[] = { struct nxagentSpecialKeystrokeMap default_map[] = {
/* stroke, modifierMask, modifierAltMeta, keysym */ /* stroke, modifierMask, modifierAltMeta, keysym */
{KEYSTROKE_DEBUG_TREE, ControlMask, 1, XK_q}, {KEYSTROKE_DEBUG_TREE, ControlMask, True, XK_q},
{KEYSTROKE_DEBUG_TREE, ControlMask, 1, XK_Q}, {KEYSTROKE_CLOSE_SESSION, ControlMask, True, XK_t},
{KEYSTROKE_CLOSE_SESSION, ControlMask, 1, XK_t}, {KEYSTROKE_SWITCH_ALL_SCREENS, ControlMask, True, XK_f},
{KEYSTROKE_CLOSE_SESSION, ControlMask, 1, XK_T}, {KEYSTROKE_FULLSCREEN, ControlMask | ShiftMask, True, XK_f},
{KEYSTROKE_SWITCH_ALL_SCREENS, ControlMask, 1, XK_f}, {KEYSTROKE_MINIMIZE, ControlMask, True, XK_m},
{KEYSTROKE_SWITCH_ALL_SCREENS, ControlMask, 1, XK_F}, {KEYSTROKE_LEFT, ControlMask, True, XK_Left},
{KEYSTROKE_MINIMIZE, ControlMask, 1, XK_m}, {KEYSTROKE_LEFT, ControlMask, True, XK_KP_Left},
{KEYSTROKE_MINIMIZE, ControlMask, 1, XK_M}, {KEYSTROKE_UP, ControlMask, True, XK_Up},
{KEYSTROKE_LEFT, ControlMask, 1, XK_Left}, {KEYSTROKE_UP, ControlMask, True, XK_KP_Up},
{KEYSTROKE_LEFT, ControlMask, 1, XK_KP_Left}, {KEYSTROKE_RIGHT, ControlMask, True, XK_Right},
{KEYSTROKE_UP, ControlMask, 1, XK_Up}, {KEYSTROKE_RIGHT, ControlMask, True, XK_KP_Right},
{KEYSTROKE_UP, ControlMask, 1, XK_KP_Up}, {KEYSTROKE_DOWN, ControlMask, True, XK_Down},
{KEYSTROKE_RIGHT, ControlMask, 1, XK_Right}, {KEYSTROKE_DOWN, ControlMask, True, XK_KP_Down},
{KEYSTROKE_RIGHT, ControlMask, 1, XK_KP_Right}, {KEYSTROKE_RESIZE, ControlMask, True, XK_r},
{KEYSTROKE_DOWN, ControlMask, 1, XK_Down}, {KEYSTROKE_DEFER, ControlMask, True, XK_e},
{KEYSTROKE_DOWN, ControlMask, 1, XK_KP_Down}, {KEYSTROKE_IGNORE, ControlMask, True, XK_BackSpace},
{KEYSTROKE_RESIZE, ControlMask, 1, XK_r}, {KEYSTROKE_IGNORE, 0, False, XK_Terminate_Server},
{KEYSTROKE_RESIZE, ControlMask, 1, XK_R}, {KEYSTROKE_FORCE_SYNCHRONIZATION, ControlMask, True, XK_j},
{KEYSTROKE_DEFER, ControlMask, 1, XK_e}, {KEYSTROKE_REGIONS_ON_SCREEN, ControlMask, True, XK_a},
{KEYSTROKE_DEFER, ControlMask, 1, XK_E}, {KEYSTROKE_TEST_INPUT, ControlMask, True, XK_x},
{KEYSTROKE_IGNORE, ControlMask, 1, XK_BackSpace}, {KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB, ControlMask, True, XK_y},
{KEYSTROKE_IGNORE, 0, 0, XK_Terminate_Server}, {KEYSTROKE_VIEWPORT_MOVE_LEFT, ControlMask | ShiftMask, True, XK_Left},
{KEYSTROKE_FORCE_SYNCHRONIZATION, ControlMask, 1, XK_j}, {KEYSTROKE_VIEWPORT_MOVE_LEFT, ControlMask | ShiftMask, True, XK_KP_Left},
{KEYSTROKE_FORCE_SYNCHRONIZATION, ControlMask, 1, XK_J}, {KEYSTROKE_VIEWPORT_MOVE_UP, ControlMask | ShiftMask, True, XK_Up},
{KEYSTROKE_REGIONS_ON_SCREEN, ControlMask, 1, XK_a}, {KEYSTROKE_VIEWPORT_MOVE_UP, ControlMask | ShiftMask, True, XK_KP_Up},
{KEYSTROKE_REGIONS_ON_SCREEN, ControlMask, 1, XK_A}, {KEYSTROKE_VIEWPORT_MOVE_RIGHT, ControlMask | ShiftMask, True, XK_Right},
{KEYSTROKE_TEST_INPUT, ControlMask, 1, XK_x}, {KEYSTROKE_VIEWPORT_MOVE_RIGHT, ControlMask | ShiftMask, True, XK_KP_Right},
{KEYSTROKE_TEST_INPUT, ControlMask, 1, XK_X}, {KEYSTROKE_VIEWPORT_MOVE_DOWN, ControlMask | ShiftMask, True, XK_Down},
{KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB, ControlMask, 1, XK_y}, {KEYSTROKE_VIEWPORT_MOVE_DOWN, ControlMask | ShiftMask, True, XK_KP_Down},
{KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB, ControlMask, 1, XK_Y}, {KEYSTROKE_REREAD_KEYSTROKES, ControlMask, True, XK_k},
{KEYSTROKE_FULLSCREEN, ControlMask | ShiftMask, 1, XK_f}, {KEYSTROKE_END_MARKER, 0, False, NoSymbol},
{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; struct nxagentSpecialKeystrokeMap *map = default_map;
static int modifier_matches(unsigned int mask, int compare_alt_meta, unsigned int state) static Bool modifier_matches(unsigned int mask, int compare_alt_meta, unsigned int state)
{ {
/* nxagentAltMetaMask needs special handling /* nxagentAltMetaMask needs special handling
* it seems to me its an and-ed mask of all possible meta and alt keys * it seems to me its an and-ed mask of all possible meta and alt keys
...@@ -147,28 +138,34 @@ static int modifier_matches(unsigned int mask, int compare_alt_meta, unsigned in ...@@ -147,28 +138,34 @@ static int modifier_matches(unsigned int mask, int compare_alt_meta, unsigned in
* *
* otherwise this function would be just a simple bitop * otherwise this function would be just a simple bitop
*/ */
int ret = 1; Bool ret = True;
if (compare_alt_meta) { if (compare_alt_meta) {
if (! (state & nxagentAltMetaMask)) { if (! (state & nxagentAltMetaMask)) {
ret = 0; ret = False;
} }
mask &= ~nxagentAltMetaMask; mask &= ~nxagentAltMetaMask;
state &= ~nxagentAltMetaMask;
} }
/* all modifiers except meta/alt have to match exactly, extra bits are evil */ /* all modifiers except meta/alt have to match exactly, extra bits are evil */
if ((mask & state) != mask) { if (mask != state) {
ret = 0; ret = False;
} }
return ret; return ret;
} }
static int read_binding_from_xmlnode(xmlNode *node, struct nxagentSpecialKeystrokeMap *ret) static Bool read_binding_from_xmlnode(xmlNode *node, struct nxagentSpecialKeystrokeMap *ret)
{ {
int successful = 0; /* init the struct to have proper values in case not all attributes are found */
struct nxagentSpecialKeystrokeMap new = {0, 0, 0, 0}; struct nxagentSpecialKeystrokeMap newkm = {
.stroke = KEYSTROKE_END_MARKER,
.modifierMask = 0,
.modifierAltMeta = False,
.keysym = NoSymbol
};
xmlAttr *attr; xmlAttr *attr;
for (attr = node->properties; attr; attr = attr->next) for (attr = node->properties; attr; attr = attr->next)
...@@ -176,20 +173,23 @@ static int read_binding_from_xmlnode(xmlNode *node, struct nxagentSpecialKeystro ...@@ -176,20 +173,23 @@ static int read_binding_from_xmlnode(xmlNode *node, struct nxagentSpecialKeystro
/* ignore attributes without data (which should never happen anyways) */ /* ignore attributes without data (which should never happen anyways) */
if (attr->children->content == NULL) if (attr->children->content == NULL)
{ {
#ifdef DEBUG
char *aname = (attr->name)?((char *)attr->name):"unknown"; char *aname = (attr->name)?((char *)attr->name):"unknown";
fprintf(stderr, "attribute %s with NULL value", aname); fprintf(stderr, "attribute %s with NULL value", aname);
#endif
continue; continue;
} }
if (strcmp((char *)attr->name, "action") == 0) if (strcmp((char *)attr->name, "action") == 0)
{ {
int i; newkm.stroke = KEYSTROKE_END_MARKER;
for (i = 0; nxagentSpecialKeystrokeNames[i] != NULL; i++) for (int i = 0; nxagentSpecialKeystrokeNames[i] != NULL; i++)
{ {
if (strcmp(nxagentSpecialKeystrokeNames[i],(char *)attr->children->content) == 0) if (strcmp(nxagentSpecialKeystrokeNames[i], (char *)attr->children->content) == 0)
{ {
/* this relies on the values of enum nxagentSpecialKeystroke and the /* this relies on the values of enum nxagentSpecialKeystroke and the
* indices of nxagentSpecialKeystrokeNames being in sync */ * indices of nxagentSpecialKeystrokeNames being in sync */
new.stroke = i; newkm.stroke = i;
break; break;
} }
} }
...@@ -197,60 +197,35 @@ static int read_binding_from_xmlnode(xmlNode *node, struct nxagentSpecialKeystro ...@@ -197,60 +197,35 @@ static int read_binding_from_xmlnode(xmlNode *node, struct nxagentSpecialKeystro
} }
else if (strcmp((char *)attr->name, "key") == 0) else if (strcmp((char *)attr->name, "key") == 0)
{ {
new.keysym = XStringToKeysym((char *)attr->children->content); newkm.keysym = XStringToKeysym((char *)attr->children->content);
/* NoSymbol is usually 0, but could there be weird implementations? */
if (new.keysym == NoSymbol)
{
new.keysym = 0;
}
continue; continue;
} }
else
/* 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; /* 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) { newkm.modifierMask |= Mod1Mask; }
else if (strcmp((char *)attr->name, "Mod2") == 0) { newkm.modifierMask |= Mod2Mask; }
else if (strcmp((char *)attr->name, "Mod3") == 0) { newkm.modifierMask |= Mod3Mask; }
else if (strcmp((char *)attr->name, "Mod4") == 0) { newkm.modifierMask |= Mod4Mask; }
else if (strcmp((char *)attr->name, "Mod5") == 0) { newkm.modifierMask |= Mod5Mask; }
else if (strcmp((char *)attr->name, "Control") == 0) { newkm.modifierMask |= ControlMask; }
else if (strcmp((char *)attr->name, "Shift") == 0) { newkm.modifierMask |= ShiftMask; }
else if (strcmp((char *)attr->name, "Lock") == 0) { newkm.modifierMask |= LockMask; }
else if (strcmp((char *)attr->name, "AltMeta") == 0) { newkm.modifierAltMeta = True; }
} }
} }
if (new.stroke != 0 && new.keysym != 0) if (newkm.stroke != KEYSTROKE_END_MARKER && newkm.keysym != NoSymbol)
{ {
/* keysym and stroke are required, everything else is optional */ /* keysym and stroke are required, everything else is optional */
successful = 1; memcpy(ret, &newkm, sizeof(struct nxagentSpecialKeystrokeMap));
memcpy(ret, &new, sizeof(struct nxagentSpecialKeystrokeMap)); return True;
} }
return successful; else
return False;
} }
/* /*
...@@ -262,32 +237,57 @@ static int read_binding_from_xmlnode(xmlNode *node, struct nxagentSpecialKeystro ...@@ -262,32 +237,57 @@ static int read_binding_from_xmlnode(xmlNode *node, struct nxagentSpecialKeystro
* - $HOME/.nx/config/keystrokes.cfg * - $HOME/.nx/config/keystrokes.cfg
* - /etc/nxagent/keystrokes.cfg * - /etc/nxagent/keystrokes.cfg
* - hardcoded traditional NX default settings * - hardcoded traditional NX default settings
* If run in x2go flavour different filenames and varnames are used.
*/ */
static void parse_keystroke_file(void) static void parse_keystroke_file(Bool force)
{ {
char *filename = NULL; char *filename = NULL;
char *homefile = "/.nx/config/keystrokes.cfg"; char *homefile;
char *etcfile = "/etc/nxagent/keystrokes.cfg"; char *etcfile;
char *envvar;
/* used for tracking if the config file parsing has already been
done (regardless of the result) */
static Bool done = False;
if (force) {
if (map != default_map)
{
free(map);
map = default_map;
}
fprintf(stderr, "re-reading keystroke config\n");
}
else
{
if (done)
return;
}
done = True;
if (nxagentX2go) { if (nxagentX2go) {
homefile = "/.x2go/config/keystrokes.cfg"; homefile = "/.x2go/config/keystrokes.cfg";
etcfile = "/etc/x2go/keystrokes.cfg"; etcfile = "/etc/x2go/keystrokes.cfg";
envvar = "X2GO_KEYSTROKEFILE";
} else {
homefile = "/.nx/config/keystrokes.cfg";
etcfile = "/etc/nxagent/keystrokes.cfg";
envvar = "NXAGENT_KEYSTROKEFILE";
} }
if (nxagentKeystrokeFile != NULL && access(nxagentKeystrokeFile, R_OK) == 0) if (nxagentKeystrokeFile && access(nxagentKeystrokeFile, R_OK) == 0)
{ {
filename = strdup(nxagentKeystrokeFile); if (!(filename = strdup(nxagentKeystrokeFile)))
if (filename == NULL)
{ {
fprintf(stderr, "malloc failed"); fprintf(stderr, "malloc failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
else if ((filename = getenv("NXAGENT_KEYSTROKEFILE")) != NULL && access(filename, R_OK) == 0) else if ((filename = getenv(envvar)) && access(filename, R_OK) == 0)
{ {
filename = strdup(filename); if (!(filename = strdup(filename)))
if (filename == NULL)
{ {
fprintf(stderr, "malloc failed"); fprintf(stderr, "malloc failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
...@@ -297,26 +297,15 @@ static void parse_keystroke_file(void) ...@@ -297,26 +297,15 @@ static void parse_keystroke_file(void)
{ {
char *homedir = getenv("HOME"); char *homedir = getenv("HOME");
filename = NULL; filename = NULL;
if (homedir != NULL) if (homedir)
{ {
homedir = strdup(homedir); if (!(filename = calloc(1, strlen(homefile) + strlen(homedir) + 1)))
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"); fprintf(stderr, "malloc failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
strcpy(filename, homedir); strcpy(filename, homedir);
strcpy(filename + strlen(homedir), homefile); strcpy(filename + strlen(homedir), homefile);
if (homedir)
{
free(homedir);
}
} }
if (access(filename, R_OK) == 0) if (access(filename, R_OK) == 0)
...@@ -325,10 +314,8 @@ exit(EXIT_FAILURE); ...@@ -325,10 +314,8 @@ exit(EXIT_FAILURE);
} }
else if (access(etcfile, R_OK) == 0) else if (access(etcfile, R_OK) == 0)
{ {
if (filename) free(filename);
free(filename); if (!(filename = strdup(etcfile)))
filename = strdup(etcfile);
if (filename == NULL)
{ {
fprintf(stderr, "malloc failed"); fprintf(stderr, "malloc failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
...@@ -336,8 +323,7 @@ exit(EXIT_FAILURE); ...@@ -336,8 +323,7 @@ exit(EXIT_FAILURE);
} }
else else
{ {
if (filename) free(filename);
free(filename);
filename = NULL; filename = NULL;
} }
} }
...@@ -345,20 +331,15 @@ free(filename); ...@@ -345,20 +331,15 @@ free(filename);
/* now we know which file to read, if any */ /* now we know which file to read, if any */
if (filename) if (filename)
{ {
xmlDoc *doc = NULL;
xmlNode *root = NULL;
LIBXML_TEST_VERSION LIBXML_TEST_VERSION
doc = xmlReadFile(filename, NULL, 0); xmlDoc *doc = xmlReadFile(filename, NULL, 0);
if (doc != NULL) if (doc)
{ {
xmlNode *cur = NULL; for (xmlNode *cur = xmlDocGetRootElement(doc); cur; cur = cur->next)
root = xmlDocGetRootElement(doc);
for (cur = root; cur; cur = cur->next)
{ {
if (cur->type == XML_ELEMENT_NODE && strcmp((char *)cur->name, "keystrokes") == 0) if (cur->type == XML_ELEMENT_NODE && strcmp((char *)cur->name, "keystrokes") == 0)
{ {
xmlNode *bindings = NULL; xmlNode *bindings;
int num = 0; int num = 0;
int idx = 0; int idx = 0;
...@@ -369,23 +350,26 @@ free(filename); ...@@ -369,23 +350,26 @@ free(filename);
num++; num++;
} }
} }
map = calloc((num + 1), sizeof(struct nxagentSpecialKeystrokeMap)); #ifdef DEBUG
if (map == NULL) fprintf(stderr, "%s: found %d keystrokes in %s\n", __func__, num, filename);
#endif
if (!(map = calloc(num+1, sizeof(struct nxagentSpecialKeystrokeMap))))
{ {
fprintf(stderr, "malloc failed"); fprintf(stderr, "calloc failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
for (bindings = cur->children; bindings; bindings = bindings->next) for (bindings = cur->children; bindings; bindings = bindings->next)
{ {
if (bindings->type == XML_ELEMENT_NODE && strcmp((char *)bindings->name, "keystroke") == 0) map[idx].stroke = KEYSTROKE_NOTHING;
{ if (bindings->type == XML_ELEMENT_NODE &&
int res = 0; strcmp((char *)bindings->name, "keystroke") == 0 &&
res = read_binding_from_xmlnode(bindings, &(map[idx])); read_binding_from_xmlnode(bindings, &(map[idx])))
if (res) idx++;
idx++;
}
} }
#ifdef DEBUG
fprintf(stderr, "%s: read %d keystrokes", __func__, idx);
#endif
map[idx].stroke = KEYSTROKE_END_MARKER; map[idx].stroke = KEYSTROKE_END_MARKER;
} }
...@@ -397,35 +381,42 @@ free(filename); ...@@ -397,35 +381,42 @@ free(filename);
else else
{ {
#ifdef DEBUG #ifdef DEBUG
fprintf("XML parsing for %s failed\n", filename); fprintf(stderr, "XML parsing for %s failed\n", filename);
#endif #endif
} }
free(filename); free(filename);
filename = NULL;
} }
} }
static enum nxagentSpecialKeystroke find_keystroke(XKeyEvent *X) static enum nxagentSpecialKeystroke find_keystroke(XKeyEvent *X)
{ {
enum nxagentSpecialKeystroke ret = KEYSTROKE_NOTHING;
int keysyms_per_keycode_return; 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, XlibKeySym *keysym = XGetKeyboardMapping(nxagentDisplay,
X->keycode, X->keycode,
1, 1,
&keysyms_per_keycode_return); &keysyms_per_keycode_return);
#ifdef DEBUG
struct nxagentSpecialKeystrokeMap *cur = map; fprintf(stderr, "%s: got keysym '%c' (%d)\n", __func__, keysym[0], keysym[0]);
#endif
if (! nxagentKeystrokeFileParsed)
{
parse_keystroke_file();
nxagentKeystrokeFileParsed = True;
}
enum nxagentSpecialKeystroke ret = KEYSTROKE_NOTHING;
while (cur->stroke != KEYSTROKE_END_MARKER) { while (cur->stroke != KEYSTROKE_END_MARKER) {
#ifdef DEBUG
fprintf(stderr, "%s: checking keysym '%c' (%d)\n", __func__, cur->keysym, cur->keysym);
#endif
if (cur->keysym == keysym[0] && modifier_matches(cur->modifierMask, cur->modifierAltMeta, X->state)) { if (cur->keysym == keysym[0] && modifier_matches(cur->modifierMask, cur->modifierAltMeta, X->state)) {
#ifdef DEBUG
fprintf(stderr, "%s: match including modifiers for keysym '%c' (%d), stroke %d (%s)\n", __func__, cur->keysym, cur->keysym, cur->stroke, nxagentSpecialKeystrokeNames[cur->stroke]);
#endif
free(keysym); free(keysym);
return cur->stroke; return cur->stroke;
} }
...@@ -436,34 +427,22 @@ static enum nxagentSpecialKeystroke find_keystroke(XKeyEvent *X) ...@@ -436,34 +427,22 @@ static enum nxagentSpecialKeystroke find_keystroke(XKeyEvent *X)
return ret; return ret;
} }
int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result) Bool nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
{ {
enum nxagentSpecialKeystroke stroke = find_keystroke(X); enum nxagentSpecialKeystroke stroke = find_keystroke(X);
*result = doNothing; *result = doNothing;
/*
* I don't know how much hard work is doing this operation.
* Do we need a cache ?
*/
int keysyms_per_keycode_return;
XlibKeySym *sym = XGetKeyboardMapping(nxagentDisplay,
X->keycode,
1,
&keysyms_per_keycode_return);
if (sym[0] == XK_VoidSymbol || sym[0] == NoSymbol)
{
free(sym);
return 0;
}
#ifdef TEST #ifdef TEST
fprintf(stderr, "nxagentCheckSpecialKeystroke: got code %x - state %x - sym %lx\n", if (stroke != KEYSTROKE_NOTHING && stroke != KEYSTROKE_END_MARKER)
X -> keycode, X -> state, sym[0]); fprintf(stderr, "nxagentCheckSpecialKeystroke: got code %x - state %x - stroke %d (%s)\n",
X -> keycode, X -> state, stroke, nxagentSpecialKeystrokeNames[stroke]);
else
fprintf(stderr, "nxagentCheckSpecialKeystroke: got code %x - state %x - stroke %d (unused)\n",
X -> keycode, X -> state, stroke);
#endif #endif
free(sym);
if (stroke == KEYSTROKE_NOTHING)
return False;
/* /*
* Check special keys. * Check special keys.
...@@ -478,7 +457,7 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result) ...@@ -478,7 +457,7 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
{ {
*result = doStartKbd; *result = doStartKbd;
return 1; return True;
} }
switch (stroke) { switch (stroke) {
...@@ -534,7 +513,7 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result) ...@@ -534,7 +513,7 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
break; break;
case KEYSTROKE_IGNORE: case KEYSTROKE_IGNORE:
/* this is used e.g. to ignore C-A-Backspace aka XK_Terminate_Server */ /* this is used e.g. to ignore C-A-Backspace aka XK_Terminate_Server */
return 1; return True;
break; break;
case KEYSTROKE_FORCE_SYNCHRONIZATION: case KEYSTROKE_FORCE_SYNCHRONIZATION:
nxagentForceSynchronization = 1; nxagentForceSynchronization = 1;
...@@ -559,7 +538,7 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result) ...@@ -559,7 +538,7 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
nxagentLastInputDevicesDumpTime = 0; nxagentLastInputDevicesDumpTime = 0;
} }
} }
return 1; return True;
#endif #endif
break; break;
case KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB: case KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB:
...@@ -567,7 +546,7 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result) ...@@ -567,7 +546,7 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
if (X->type == KeyPress) { if (X->type == KeyPress) {
nxagentDeactivateInputDevicesGrab(); nxagentDeactivateInputDevicesGrab();
} }
return 1; return True;
#endif #endif
break; break;
case KEYSTROKE_FULLSCREEN: case KEYSTROKE_FULLSCREEN:
...@@ -599,10 +578,20 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result) ...@@ -599,10 +578,20 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
*result = doViewportMoveDown; *result = doViewportMoveDown;
} }
break; break;
case KEYSTROKE_REREAD_KEYSTROKES:
/* two reasons to check on KeyRelease:
- this code is called for KeyPress and KeyRelease, so we
would read the keystroke file twice
- if the keystroke file changes settings for this key this
might lead to unexpected behaviour
*/
if (X->type == KeyRelease)
parse_keystroke_file(True);
break;
case KEYSTROKE_NOTHING: /* do nothing. difference to KEYSTROKE_IGNORE is the return value */ case KEYSTROKE_NOTHING: /* do nothing. difference to KEYSTROKE_IGNORE is the return value */
case KEYSTROKE_END_MARKER: /* just to make gcc STFU */ case KEYSTROKE_END_MARKER: /* just to make gcc STFU */
case KEYSTROKE_MAX: case KEYSTROKE_MAX:
break; break;
} }
return (*result == doNothing) ? 0 : 1; return (*result == doNothing);
} }
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include "Events.h" #include "Events.h"
extern int nxagentCheckSpecialKeystroke(XKeyEvent*, enum HandleEventResult*); extern Bool nxagentCheckSpecialKeystroke(XKeyEvent*, enum HandleEventResult*);
unsigned int nxagentAltMetaMask; unsigned int nxagentAltMetaMask;
...@@ -42,40 +42,42 @@ enum nxagentSpecialKeystroke { ...@@ -42,40 +42,42 @@ enum nxagentSpecialKeystroke {
KEYSTROKE_END_MARKER = 0, KEYSTROKE_END_MARKER = 0,
KEYSTROKE_CLOSE_SESSION = 1, KEYSTROKE_CLOSE_SESSION = 1,
KEYSTROKE_SWITCH_ALL_SCREENS = 2, KEYSTROKE_SWITCH_ALL_SCREENS = 2,
KEYSTROKE_MINIMIZE = 3, KEYSTROKE_FULLSCREEN = 3,
KEYSTROKE_LEFT = 4, KEYSTROKE_MINIMIZE = 4,
KEYSTROKE_UP = 5, KEYSTROKE_LEFT = 5,
KEYSTROKE_RIGHT = 6, KEYSTROKE_UP = 6,
KEYSTROKE_DOWN = 7, KEYSTROKE_RIGHT = 7,
KEYSTROKE_RESIZE = 8, KEYSTROKE_DOWN = 8,
KEYSTROKE_DEFER = 9, KEYSTROKE_RESIZE = 9,
KEYSTROKE_IGNORE = 10, KEYSTROKE_DEFER = 10,
KEYSTROKE_FORCE_SYNCHRONIZATION = 11, KEYSTROKE_IGNORE = 11,
KEYSTROKE_FORCE_SYNCHRONIZATION = 12,
/* stuff used for debugging, probably not useful for most people */ /* stuff used for debugging, probably not useful for most people */
KEYSTROKE_DEBUG_TREE = 12, KEYSTROKE_DEBUG_TREE = 13,
KEYSTROKE_REGIONS_ON_SCREEN = 13, KEYSTROKE_REGIONS_ON_SCREEN = 14,
KEYSTROKE_TEST_INPUT = 14, KEYSTROKE_TEST_INPUT = 15,
KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB = 15, KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB = 16,
KEYSTROKE_FULLSCREEN = 16,
KEYSTROKE_VIEWPORT_MOVE_LEFT = 17, KEYSTROKE_VIEWPORT_MOVE_LEFT = 17,
KEYSTROKE_VIEWPORT_MOVE_UP = 18, KEYSTROKE_VIEWPORT_MOVE_UP = 18,
KEYSTROKE_VIEWPORT_MOVE_RIGHT = 19, KEYSTROKE_VIEWPORT_MOVE_RIGHT = 19,
KEYSTROKE_VIEWPORT_MOVE_DOWN = 20, KEYSTROKE_VIEWPORT_MOVE_DOWN = 20,
KEYSTROKE_NOTHING = 21, KEYSTROKE_REREAD_KEYSTROKES = 21,
KEYSTROKE_NOTHING = 22,
/* insert more here, increment KEYSTROKE_MAX accordingly. /* insert more here, increment KEYSTROKE_MAX accordingly.
* then update string translation below */ * then update string translation below */
KEYSTROKE_MAX=22, KEYSTROKE_MAX = 23,
}; };
struct nxagentSpecialKeystrokeMap { struct nxagentSpecialKeystrokeMap {
enum nxagentSpecialKeystroke stroke; enum nxagentSpecialKeystroke stroke;
unsigned int modifierMask; /* everything except alt/meta */ unsigned int modifierMask; /* everything except alt/meta */
int modifierAltMeta; /* modifier combination should include alt/meta */ Bool modifierAltMeta; /* modifier combination should include alt/meta */
KeySym keysym; KeySym keysym;
}; };
......
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