aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/programs/Xserver/hw/nxagent/Keystroke.c')
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Keystroke.c699
1 files changed, 231 insertions, 468 deletions
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
index 694781c7e..6c6e477ab 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
@@ -28,15 +28,8 @@
#include "Keystroke.h"
#include "Drawable.h"
-#include <unistd.h>
-
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-
extern Bool nxagentWMIsRunning;
extern Bool nxagentIpaq;
-extern char *nxagentKeystrokeFile;
-Bool nxagentKeystrokeFileParsed = False;
#ifdef NX_DEBUG_INPUT
int nxagentDebugInputDevices = 0;
@@ -54,369 +47,10 @@ extern void nxagentDeactivateInputDevicesGrabs();
#undef DEBUG
#undef DUMP
-
-/* this table is used to parse actions given on the command line or in the
- * config file, therefore indices have to match the enum in Keystroke.h */
-char * nxagentSpecialKeystrokeNames[] = {
- "end_marker",
- "close_session",
- "switch_all_screens",
- "minimize",
- "left",
- "up",
- "right",
- "down",
- "resize",
- "defer",
- "ignore",
- "force_synchronization",
-
- "debug_tree",
- "regions_on_screen",
- "test_input",
- "deactivate_input_devices_grab",
-
- "fullscreen",
- "viewport_move_left",
- "viewport_move_up",
- "viewport_move_right",
- "viewport_move_down",
- NULL,
-};
-
-struct nxagentSpecialKeystrokeMap default_map[] = {
- /* stroke, modifierMask, modifierAltMeta, keysym */
- {KEYSTROKE_DEBUG_TREE, ControlMask, 1, XK_q},
- {KEYSTROKE_DEBUG_TREE, ControlMask, 1, XK_Q},
- {KEYSTROKE_CLOSE_SESSION, ControlMask, 1, XK_t},
- {KEYSTROKE_CLOSE_SESSION, ControlMask, 1, XK_T},
- {KEYSTROKE_SWITCH_ALL_SCREENS, ControlMask, 1, XK_f},
- {KEYSTROKE_SWITCH_ALL_SCREENS, ControlMask, 1, XK_F},
- {KEYSTROKE_MINIMIZE, ControlMask, 1, XK_m},
- {KEYSTROKE_MINIMIZE, ControlMask, 1, XK_M},
- {KEYSTROKE_LEFT, ControlMask, 1, XK_Left},
- {KEYSTROKE_LEFT, ControlMask, 1, XK_KP_Left},
- {KEYSTROKE_UP, ControlMask, 1, XK_Up},
- {KEYSTROKE_UP, ControlMask, 1, XK_KP_Up},
- {KEYSTROKE_RIGHT, ControlMask, 1, XK_Right},
- {KEYSTROKE_RIGHT, ControlMask, 1, XK_KP_Right},
- {KEYSTROKE_DOWN, ControlMask, 1, XK_Down},
- {KEYSTROKE_DOWN, ControlMask, 1, XK_KP_Down},
- {KEYSTROKE_RESIZE, ControlMask, 1, XK_r},
- {KEYSTROKE_RESIZE, ControlMask, 1, XK_R},
- {KEYSTROKE_DEFER, ControlMask, 1, XK_e},
- {KEYSTROKE_DEFER, ControlMask, 1, XK_E},
- {KEYSTROKE_IGNORE, ControlMask, 1, XK_BackSpace},
- {KEYSTROKE_IGNORE, 0, 0, XK_Terminate_Server},
- {KEYSTROKE_FORCE_SYNCHRONIZATION, ControlMask, 1, XK_j},
- {KEYSTROKE_FORCE_SYNCHRONIZATION, ControlMask, 1, XK_J},
- {KEYSTROKE_REGIONS_ON_SCREEN, ControlMask, 1, XK_a},
- {KEYSTROKE_REGIONS_ON_SCREEN, ControlMask, 1, XK_A},
- {KEYSTROKE_TEST_INPUT, ControlMask, 1, XK_x},
- {KEYSTROKE_TEST_INPUT, ControlMask, 1, XK_X},
- {KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB, ControlMask, 1, XK_y},
- {KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB, ControlMask, 1, XK_Y},
- {KEYSTROKE_FULLSCREEN, ControlMask | ShiftMask, 1, XK_f},
- {KEYSTROKE_FULLSCREEN, ControlMask | ShiftMask, 1, XK_F},
- {KEYSTROKE_VIEWPORT_MOVE_LEFT, ControlMask | ShiftMask, 1, XK_Left},
- {KEYSTROKE_VIEWPORT_MOVE_LEFT, ControlMask | ShiftMask, 1, XK_KP_Left},
- {KEYSTROKE_VIEWPORT_MOVE_UP, ControlMask | ShiftMask, 1, XK_Up},
- {KEYSTROKE_VIEWPORT_MOVE_UP, ControlMask | ShiftMask, 1, XK_KP_Up},
- {KEYSTROKE_VIEWPORT_MOVE_RIGHT, ControlMask | ShiftMask, 1, XK_Right},
- {KEYSTROKE_VIEWPORT_MOVE_RIGHT, ControlMask | ShiftMask, 1, XK_KP_Right},
- {KEYSTROKE_VIEWPORT_MOVE_DOWN, ControlMask | ShiftMask, 1, XK_Down},
- {KEYSTROKE_VIEWPORT_MOVE_DOWN, ControlMask | ShiftMask, 1, XK_KP_Down},
- {KEYSTROKE_END_MARKER, 0, 0, 0},
-};
-struct nxagentSpecialKeystrokeMap *map = default_map;
-
-static int modifier_matches(unsigned int mask, int compare_alt_meta, unsigned int state)
-{
- /* nxagentAltMetaMask needs special handling
- * it seems to me its an and-ed mask of all possible meta and alt keys
- * somehow...
- *
- * otherwise this function would be just a simple bitop
- */
- int ret = 1;
-
- if (compare_alt_meta) {
- if (! (state & nxagentAltMetaMask)) {
- ret = 0;
- }
-
- mask &= ~nxagentAltMetaMask;
- }
-
- /* all modifiers except meta/alt have to match exactly, extra bits are evil */
- if ((mask & state) != mask) {
- ret = 0;
- }
-
- return ret;
-}
-
-static int read_binding_from_xmlnode(xmlNode *node, struct nxagentSpecialKeystrokeMap *ret)
-{
- int successful = 0;
- struct nxagentSpecialKeystrokeMap new = {0, 0, 0, 0};
- xmlAttr *attr;
-
- for (attr = node->properties; attr; attr = attr->next)
- {
- /* ignore attributes without data (which should never happen anyways) */
- if (attr->children->content == NULL)
- {
- char *aname = (attr->name)?(attr->name):"unknown";
- fprintf(stderr, "attribute %s with NULL value", aname);
- continue;
- }
- if (strcmp((char *)attr->name, "action") == 0)
- {
- int i;
- for (i = 0; nxagentSpecialKeystrokeNames[i] != NULL; i++)
- {
- if (strcmp(nxagentSpecialKeystrokeNames[i],(char *)attr->children->content) == 0)
- {
- /* this relies on the values of enum nxagentSpecialKeystroke and the
- * indices of nxagentSpecialKeystrokeNames being in sync */
- new.stroke = i;
- break;
- }
- }
- continue;
- }
- else if (strcmp((char *)attr->name, "key") == 0)
- {
- new.keysym = XStringToKeysym((char *)attr->children->content);
- /* NoSymbol is usually 0, but could there be weird implementations? */
- if (new.keysym == NoSymbol)
- {
- new.keysym = 0;
- }
- continue;
- }
-
- /* ignore attributes with value="0" or "false", everything else is interpreted as true */
- if (strcmp((char *)attr->children->content, "0") == 0 || strcmp((char *)attr->children->content, "false") == 0)
- continue;
-
- if (strcmp((char *)attr->name, "Mod1") == 0)
- {
- new.modifierMask |= Mod1Mask;
- }
- else if (strcmp((char *)attr->name, "Mod2") == 0)
- {
- new.modifierMask |= Mod2Mask;
- }
- else if (strcmp((char *)attr->name, "Mod3") == 0)
- {
- new.modifierMask |= Mod3Mask;
- }
- else if (strcmp((char *)attr->name, "Mod4") == 0)
- {
- new.modifierMask |= Mod4Mask;
- }
- else if (strcmp((char *)attr->name, "Control") == 0)
- {
- new.modifierMask |= ControlMask;
- }
- else if (strcmp((char *)attr->name, "Shift") == 0)
- {
- new.modifierMask |= ShiftMask;
- }
- else if (strcmp((char *)attr->name, "Lock") == 0)
- {
- new.modifierMask |= LockMask;
- }
- else if (strcmp((char *)attr->name, "AltMeta") == 0)
- {
- new.modifierAltMeta = 1;
- }
- }
-
- if (new.stroke != 0 && new.keysym != 0)
- {
- /* keysym and stroke are required, everything else is optional */
- successful = 1;
- memcpy(ret, &new, sizeof(struct nxagentSpecialKeystrokeMap));
- }
- return successful;
-}
-
-/*
- * searches a keystroke xml file
- *
- * search order:
- * - '-keystrokefile' commandline parameter
- * - $NXAGENT_KEYSTROKEFILE environment variable
- * - $HOME/.nx/config/keystroke.cfg
- * - /etc/nx/keystroke.cfg
- * - hardcoded traditional NX default settings
- */
-static void parse_keystroke_file(void)
-{
- char *filename = NULL;
-
- char *homefile = "/.nx/config/keystroke.cfg";
- char *etcfile = "/etc/nx/keystroke.cfg";
-
- if (nxagentKeystrokeFile != NULL && access(nxagentKeystrokeFile, R_OK) == 0)
- {
- filename = strdup(nxagentKeystrokeFile);
- if (filename == NULL)
- {
- fprintf(stderr, "malloc failed");
- exit(EXIT_FAILURE);
- }
- }
- else if ((filename = getenv("NXAGENT_KEYSTROKEFILE")) != NULL && access(filename, R_OK) == 0)
- {
- filename = strdup(filename);
- if (filename == NULL)
- {
- fprintf(stderr, "malloc failed");
- exit(EXIT_FAILURE);
- }
- }
- else
- {
- char *homedir = getenv("HOME");
- filename = NULL;
- if (homedir != NULL)
- {
- homedir = strdup(homedir);
- if (homedir == NULL)
- {
- fprintf(stderr, "malloc failed");
-exit(EXIT_FAILURE);
- }
- filename = calloc(1, strlen(homefile) + strlen(homedir) + 1);
- if (filename == NULL)
- {
- fprintf(stderr, "malloc failed");
- exit(EXIT_FAILURE);
- }
- strcpy(filename, homedir);
- strcpy(filename + strlen(homedir), homefile);
- if (homedir)
- {
- free(homedir);
- }
- }
-
- if (access(filename, R_OK) == 0)
- {
- /* empty */
- }
- else if (access(etcfile, R_OK == 0))
- {
- if (filename)
- free(filename);
- filename = strdup(etcfile);
- if (filename == NULL)
- {
- fprintf(stderr, "malloc failed");
- exit(EXIT_FAILURE);
- }
- }
- else
- {
- if (filename)
-free(filename);
- filename = NULL;
- }
- }
-
- /* now we know which file to read, if any */
- if (filename)
- {
- xmlDoc *doc = NULL;
- xmlNode *root = NULL;
- LIBXML_TEST_VERSION
- doc = xmlReadFile(filename, NULL, 0);
- if (doc != NULL)
- {
- xmlNode *cur = NULL;
- root = xmlDocGetRootElement(doc);
-
- for (cur = root; cur; cur = cur->next)
- {
- if (cur->type == XML_ELEMENT_NODE && strcmp((char *)cur->name, "keystrokes") == 0)
-{
- xmlNode *bindings = NULL;
- int num = 0;
- int idx = 0;
-
- for (bindings = cur->children; bindings; bindings = bindings->next)
- {
- if (bindings->type == XML_ELEMENT_NODE && strcmp((char *)bindings->name, "keystroke") == 0)
- {
- num++;
- }
- }
- map = calloc((num + 1), sizeof(struct nxagentSpecialKeystrokeMap));
- if (map == NULL)
- {
- fprintf(stderr, "malloc failed");
- exit(EXIT_FAILURE);
- }
-
- for (bindings = cur->children; bindings; bindings = bindings->next)
- {
- if (bindings->type == XML_ELEMENT_NODE && strcmp((char *)bindings->name, "keystroke") == 0)
- {
- int res = 0;
- res = read_binding_from_xmlnode(bindings, &(map[idx]));
- if (res)
- idx++;
- }
- }
-
- map[idx].stroke = KEYSTROKE_END_MARKER;
- }
- }
-
- xmlFreeDoc(doc);
- xmlCleanupParser();
- }
- else
- {
- #ifdef DEBUG
- fprintf("XML parsing for %s failed\n", filename);
- #endif
- }
- free(filename);
- }
-}
-
-static enum nxagentSpecialKeystroke find_keystroke(XKeyEvent *X)
-{
- KeySym keysym = XKeycodeToKeysym(nxagentDisplay, X->keycode, 0);
- struct nxagentSpecialKeystrokeMap *cur = map;
-
- if (! nxagentKeystrokeFileParsed)
- {
- parse_keystroke_file();
- nxagentKeystrokeFileParsed = True;
- }
-
- enum nxagentSpecialKeystroke ret = KEYSTROKE_NOTHING;
-
- while ((cur++)->stroke != KEYSTROKE_END_MARKER) {
- if (cur->keysym == keysym && modifier_matches(cur->modifierMask, cur->modifierAltMeta, X->state)) {
- return cur->stroke;
- }
- }
-
- return ret;
-}
-
int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
{
KeySym sym;
int index = 0;
- enum nxagentSpecialKeystroke stroke = find_keystroke(X);
*result = doNothing;
@@ -453,128 +87,257 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
return 1;
}
- switch (stroke) {
- case KEYSTROKE_DEBUG_TREE:
+ if ((X -> state & nxagentAltMetaMask) &&
+ ((X -> state & (ControlMask | ShiftMask)) == ControlMask))
+ {
+ switch (sym)
+ {
#ifdef DEBUG_TREE
- *result = doDebugTree;
- #endif
- break;
- case KEYSTROKE_CLOSE_SESSION:
- *result = doCloseSession;
- break;
- case KEYSTROKE_SWITCH_ALL_SCREENS:
- if (nxagentOption(Rootless) == False) {
- *result = doSwitchAllScreens;
+
+ case XK_q:
+ case XK_Q:
+ {
+ *result = doDebugTree;
+
+ break;
+ }
+
+ #endif /* DEBUG_TREE */
+
+ case XK_t:
+ case XK_T:
+ {
+ *result = doCloseSession;
+
+ break;
+ }
+ case XK_f:
+ case XK_F:
+ {
+ if (nxagentOption(Rootless) == False)
+ {
+ *result = doSwitchAllScreens;
+ }
+
+ break;
+ }
+ case XK_m:
+ case XK_M:
+ {
+ if (nxagentOption(Rootless) == False)
+ {
+ *result = doMinimize;
+ }
+
+ break;
+ }
+ case XK_Left:
+ case XK_KP_Left:
+ {
+ if (nxagentOption(Rootless) == False &&
+ nxagentOption(DesktopResize) == False)
+ {
+ *result = doViewportLeft;
+ }
+
+ break;
}
- break;
- case KEYSTROKE_MINIMIZE:
- if (nxagentOption(Rootless) == False) {
- *result = doMinimize;
+ case XK_Up:
+ case XK_KP_Up:
+ {
+ if (nxagentOption(Rootless) == False &&
+ nxagentOption(DesktopResize) == False)
+ {
+ *result = doViewportUp;
+ }
+
+ break;
+ }
+ case XK_Right:
+ case XK_KP_Right:
+ {
+ if (nxagentOption(Rootless) == False &&
+ nxagentOption(DesktopResize) == False)
+ {
+ *result = doViewportRight;
+ }
+
+ break;
}
- break;
- case KEYSTROKE_LEFT:
- if (nxagentOption(Rootless) == False &&
- nxagentOption(DesktopResize) == False) {
- *result = doViewportLeft;
+ case XK_Down:
+ case XK_KP_Down:
+ {
+ if (nxagentOption(Rootless) == 0 &&
+ nxagentOption(DesktopResize) == 0)
+ {
+ *result = doViewportDown;
+ }
+
+ break;
}
- break;
- case KEYSTROKE_UP:
- if (nxagentOption(Rootless) == False &&
- nxagentOption(DesktopResize) == False) {
- *result = doViewportUp;
+ case XK_R:
+ case XK_r:
+ {
+ if (nxagentOption(Rootless) == 0)
+ {
+ *result = doSwitchResizeMode;
+ }
+
+ break;
}
- break;
- case KEYSTROKE_RIGHT:
- if (nxagentOption(Rootless) == False &&
- nxagentOption(DesktopResize) == False) {
- *result = doViewportRight;
+ case XK_E:
+ case XK_e:
+ {
+ *result = doSwitchDeferMode;
+
+ break;
}
- break;
- case KEYSTROKE_DOWN:
- if (nxagentOption(Rootless) == False &&
- nxagentOption(DesktopResize) == False) {
- *result = doViewportDown;
+ case XK_BackSpace:
+ case XK_Terminate_Server:
+ {
+ /*
+ * Discard Ctrl-Alt-BackSpace key.
+ */
+
+ return 1;
+
+ break;
}
- break;
- case KEYSTROKE_RESIZE:
- if (nxagentOption(Rootless) == False) {
- *result = doSwitchResizeMode;
+
+ case XK_J:
+ case XK_j:
+ {
+ nxagentForceSynchronization = 1;
+
+ return 1;
}
- break;
- case KEYSTROKE_DEFER:
- *result = doSwitchDeferMode;
- break;
- case KEYSTROKE_IGNORE:
- /* this is used e.g. to ignore C-A-Backspace aka XK_Terminate_Server */
- return 1;
- break;
- case KEYSTROKE_FORCE_SYNCHRONIZATION:
- nxagentForceSynchronization = 1;
- break;
- case KEYSTROKE_REGIONS_ON_SCREEN:
+
#ifdef DUMP
- nxagentRegionsOnScreen();
+
+ case XK_A:
+ case XK_a:
+ {
+ /*
+ * Used to test the lazy encoding.
+ */
+
+ nxagentRegionsOnScreen();
+
+ return 1;
+ }
+
#endif
- break;
- case KEYSTROKE_TEST_INPUT:
- /*
- * Used to test the input devices state.
- */
+
#ifdef NX_DEBUG_INPUT
- if (X -> type == KeyPress) {
- if (nxagentDebugInputDevices == 0) {
- fprintf(stderr, "Info: Turning input devices debug ON.\n");
- nxagentDebugInputDevices = 1;
- } else {
- fprintf(stderr, "Info: Turning input devices debug OFF.\n");
- nxagentDebugInputDevices = 0;
- nxagentLastInputDevicesDumpTime = 0;
+
+ case XK_X:
+ case XK_x:
+ {
+ /*
+ * Used to test the input devices state.
+ */
+
+ if (X -> type == KeyPress)
+ {
+ if (nxagentDebugInputDevices == 0)
+ {
+ fprintf(stderr, "Info: Turning input devices debug ON.\n");
+
+ nxagentDebugInputDevices = 1;
+ }
+ else
+ {
+ fprintf(stderr, "Info: Turning input devices debug OFF.\n");
+
+ nxagentDebugInputDevices = 0;
+
+ nxagentLastInputDevicesDumpTime = 0;
+ }
}
+
+ return 1;
}
- return 1;
- #endif
- break;
- case KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB:
- #ifdef NX_DEBUG_INPUT
- if (X->type == KeyPress) {
- nxagentDeactivateInputDevicesGrab();
+
+ case XK_Y:
+ case XK_y:
+ {
+ /*
+ * Used to deactivate input devices grab.
+ */
+
+ if (X -> type == KeyPress)
+ {
+ nxagentDeactivateInputDevicesGrabs();
+ }
+
+ return 1;
}
- return 1;
+
#endif
- break;
- case KEYSTROKE_FULLSCREEN:
- if (nxagentOption(Rootless) == 0) {
- *result = doSwitchFullscreen;
+ }
+ }
+ else if ((X -> state & nxagentAltMetaMask) &&
+ ((X -> state & (ControlMask | ShiftMask)) == (ControlMask |
+ ShiftMask)))
+ {
+ switch (sym)
+ {
+ case XK_f:
+ case XK_F:
+ {
+ if (nxagentOption(Rootless) == 0)
+ {
+ *result = doSwitchFullscreen;
+ }
+
+ break;
}
- break;
- case KEYSTROKE_VIEWPORT_MOVE_LEFT:
- if (nxagentOption(Rootless) == 0 &&
- nxagentOption(DesktopResize) == 0) {
- *result = doViewportMoveLeft;
+ case XK_Left:
+ case XK_KP_Left:
+ {
+ if (nxagentOption(Rootless) == 0 &&
+ nxagentOption(DesktopResize) == 0)
+ {
+ *result = doViewportMoveLeft;
+ }
+
+ break;
}
- break;
- case KEYSTROKE_VIEWPORT_MOVE_UP:
- if (nxagentOption(Rootless) == 0 &&
- nxagentOption(DesktopResize) == 0) {
- *result = doViewportMoveUp;
+ case XK_Up:
+ case XK_KP_Up:
+ {
+ if (nxagentOption(Rootless) == 0 &&
+ nxagentOption(DesktopResize) == 0)
+ {
+ *result = doViewportMoveUp;
+ }
+
+ break;
}
- break;
- case KEYSTROKE_VIEWPORT_MOVE_RIGHT:
- if (nxagentOption(Rootless) == 0 &&
- nxagentOption(DesktopResize) == 0) {
- *result = doViewportMoveRight;
+ case XK_Right:
+ case XK_KP_Right:
+ {
+ if (nxagentOption(Rootless) == 0 &&
+ nxagentOption(DesktopResize) == 0)
+ {
+ *result = doViewportMoveRight;
+ }
+
+ break;
}
- break;
- case KEYSTROKE_VIEWPORT_MOVE_DOWN:
- if (nxagentOption(Rootless) == 0 &&
- nxagentOption(DesktopResize) == 0) {
- *result = doViewportMoveDown;
+ case XK_Down:
+ case XK_KP_Down:
+ {
+ if (nxagentOption(Rootless) == 0 &&
+ nxagentOption(DesktopResize) == 0)
+ {
+ *result = doViewportMoveDown;
+ }
+
+ break;
}
- break;
- case KEYSTROKE_NOTHING: /* do nothing. difference to KEYSTROKE_IGNORE is the return value */
- case KEYSTROKE_END_MARKER: /* just to make gcc STFU */
- case KEYSTROKE_MAX:
- break;
+ }
}
+
return (*result == doNothing) ? 0 : 1;
}