aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Keyboard.c213
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Keyboard.h1
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Reconnect.c3
3 files changed, 106 insertions, 111 deletions
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
index d264d1c96..20b68b563 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
@@ -78,10 +78,9 @@ is" without express or implied warranty.
#include <errno.h>
-static int nxagentXkbGetNames(char **rules, char **model, char **layout,
- char **variant, char **options);
+void nxagentXkbGetNames(void);
-static void nxagentKeycodeConversionSetup(char *rules, char *model);
+void nxagentKeycodeConversionSetup(void);
void nxagentWriteKeyboardFile(char *rules, char *model, char *layout, char *variant, char *options);
@@ -140,6 +139,13 @@ extern Status XkbGetControls(
extern int XkbDfltRepeatDelay;
extern int XkbDfltRepeatInterval;
+/* xkb configuration of the real X server */
+static char *nxagentRemoteRules = NULL;
+static char *nxagentRemoteModel = NULL;
+static char *nxagentRemoteLayout = NULL;
+static char *nxagentRemoteVariant = NULL;
+static char *nxagentRemoteOptions = NULL;
+
#endif /* XKB */
/*
@@ -571,8 +577,10 @@ int nxagentKeyboardProc(DeviceIntPtr pDev, int onoff)
CARD8 modmap[MAP_LENGTH];
int i, j;
XKeyboardState values;
+#ifdef XKB
char *model = NULL, *layout = NULL;
XkbDescPtr xkb = NULL;
+#endif
switch (onoff)
{
@@ -694,20 +702,13 @@ N/A
keySyms.mapWidth = mapWidth;
keySyms.map = keymap;
- if (XkbQueryExtension(nxagentDisplay,
- &nxagentXkbInfo.Opcode,
- &nxagentXkbInfo.EventBase,
- &nxagentXkbInfo.ErrorBase,
- &nxagentXkbInfo.MajorVersion,
- &nxagentXkbInfo.MinorVersion) == 0)
+#ifdef XKB
+ if (!nxagentGetRemoteXkbExtension())
{
- ErrorF("Unable to initialize XKEYBOARD extension.\n");
- goto XkbError;
+ ErrorF("Unable to query XKEYBOARD extension.\n");
+ goto XkbError;
}
-
-#ifdef XKB
-
if (noXkbExtension) {
#ifdef TEST
fprintf(stderr, "nxagentKeyboardProc: No XKB extension.\n");
@@ -838,63 +839,47 @@ XkbError:
fprintf(stderr, "nxagentKeyboardProc: Init XKB extension.\n");
#endif
+ if (nxagentRemoteRules && nxagentRemoteModel)
{
- char *remoterules = NULL;
- char *remotemodel = NULL;
- char *remotelayout = NULL;
- char *remotevariant = NULL;
- char *remoteoptions = NULL;
+ #ifdef DEBUG
+ fprintf(stderr, "%s: Remote: [rules='%s',model='%s',layout='%s',variant='%s',options='%s'].\n",
+ __func__, nxagentRemoteRules, nxagentRemoteModel, nxagentRemoteLayout, nxagentRemoteVariant, nxagentRemoteOptions);
+ #endif
- unsigned int remoteruleslen = nxagentXkbGetNames(&remoterules, &remotemodel, &remotelayout,
- &remotevariant, &remoteoptions);
+ /*
+ * Keyboard has always been tricky with nxagent. For that
+ * reason X2Go offers "auto" keyboard configuration. You can
+ * specify it in the client side session configuration. In
+ * "auto" mode x2goserver expects nxagent to write the
+ * remote keyboard config to a file on startup and
+ * x2goserver would then pick that file and pass it to
+ * setxkbmap. This functionality is obsoleted by the "clone"
+ * stuff but we still need it because x2goserver does not
+ * know about that yet. Once x2go starts using clone
+ * we can drop this here.
+ */
+ nxagentWriteKeyboardFile(nxagentRemoteRules, nxagentRemoteModel, nxagentRemoteLayout, nxagentRemoteVariant, nxagentRemoteOptions);
- if (remoteruleslen && remoterules && remotemodel)
+ /* Only setup keycode conversion if we are NOT in clone mode */
+ if (nxagentKeyboard && (strcmp(nxagentKeyboard, "clone") == 0))
{
- #ifdef DEBUG
- fprintf(stderr, "%s: Remote: [rules='%s',model='%s',layout='%s',variant='%s',options='%s'].\n",
- __func__, remoterules, remotemodel, remotelayout, remotevariant, remoteoptions);
- #endif
-
- /*
- * Keyboard has always been tricky with nxagent. For that
- * reason X2Go offers "auto" keyboard configuration. You can
- * specify it in the client side session configuration. In
- * "auto" mode x2goserver expects nxagent to write the
- * remote keyboard config to a file on startup and
- * x2goserver would then pick that file and pass it to
- * setxkbmap. This functionality is obsoleted by the "clone"
- * stuff but we still need it because x2goserver does not
- * know about that yet. Once x2go starts using clone we can
- * drop this here.
- */
- nxagentWriteKeyboardFile(remoteruleslen, remoterules, remotemodel, remotelayout, remotevariant, remoteoptions);
-
- /* Only setup keycode conversion if we are NOT in clone mode */
- if (nxagentKeyboard && (strcmp(nxagentKeyboard, "clone") == 0))
- {
- free(rules); rules = strdup(remoterules);
- free(model); model = strdup(remotemodel);
- free(layout); layout = strdup(remotelayout);
- free(variant); variant = strdup(remotevariant);
- free(options); options = strdup(remoteoptions);
- }
- else
- {
- nxagentKeycodeConversionSetup(remoterules, remotemodel);
- }
+ free(rules); rules = strdup(nxagentRemoteRules);
+ free(model); model = strdup(nxagentRemoteModel);
+ free(layout); layout = strdup(nxagentRemoteLayout);
+ free(variant); variant = strdup(nxagentRemoteVariant);
+ free(options); options = strdup(nxagentRemoteOptions);
}
- #ifdef DEBUG
else
{
- fprintf(stderr, "%s: Failed to retrieve remote rules.\n", __func__);
- }
- #endif
-
- if (remoterules)
- {
- XFree(remoterules);
+ nxagentKeycodeConversionSetup();
}
}
+ #ifdef DEBUG
+ else
+ {
+ fprintf(stderr, "%s: Failed to retrieve remote rules.\n", __func__);
+ }
+ #endif
xkb = XkbGetKeyboard(nxagentDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
@@ -1551,8 +1536,16 @@ void nxagentTuneXkbWrapper(void)
}
}
-static int nxagentXkbGetNames(char **rules, char **model, char **layout,
- char **variant, char **options)
+void nxagentXkbClearNames(void)
+{
+ free(nxagentRemoteRules); nxagentRemoteRules = NULL;
+ free(nxagentRemoteModel); nxagentRemoteModel = NULL;
+ free(nxagentRemoteLayout); nxagentRemoteLayout = NULL;
+ free(nxagentRemoteVariant); nxagentRemoteVariant = NULL;
+ free(nxagentRemoteOptions); nxagentRemoteOptions = NULL;
+}
+
+void nxagentXkbGetNames(void)
{
Atom atom;
#ifdef _XSERVER64
@@ -1567,28 +1560,25 @@ static int nxagentXkbGetNames(char **rules, char **model, char **layout,
char *name;
Status result;
- data = name = NULL;
-
- *rules = NULL;
- *model = NULL;
- *layout = NULL;
- *variant = NULL;
- *options = NULL;
+ if (nxagentRemoteRules)
+ return;
atom = XInternAtom(nxagentDisplay, "_XKB_RULES_NAMES", 1);
if (atom == 0)
{
- return 0;
+ return;
}
+ data = name = NULL;
+
result = XGetWindowProperty(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
atom, 0, 256, 0, XA_STRING, &type, &format,
&n, &after, (unsigned char **)&data);
if (result != Success || !data)
{
- return 0;
+ return;
}
if ((after > 0) || (type != XA_STRING) || (format != 8))
@@ -1596,7 +1586,7 @@ static int nxagentXkbGetNames(char **rules, char **model, char **layout,
if (data)
{
XFree(data);
- return 0;
+ return;
}
}
@@ -1604,35 +1594,37 @@ static int nxagentXkbGetNames(char **rules, char **model, char **layout,
if (name < data + n)
{
- *rules = name;
+ nxagentRemoteRules = strdup(name);
name += strlen(name) + 1;
}
if (name < data + n)
{
- *model = name;
+ nxagentRemoteModel = strdup(name);
name += strlen(name) + 1;
}
if (name < data + n)
{
- *layout = name;
+ nxagentRemoteLayout = strdup(name);
name += strlen(name) + 1;
}
if (name < data + n)
{
- *variant = name;
+ nxagentRemoteVariant = strdup(name);
name += strlen(name) + 1;
}
if (name < data + n)
{
- *options = name;
+ nxagentRemoteOptions = strdup(name);
name += strlen(name) + 1;
}
- return n;
+ XFree(data);
+
+ return;
}
void writeKeyboardfileData(FILE *out, char *rules, char *model, char *layout, char *variant, char *options)
@@ -1697,7 +1689,7 @@ void nxagentWriteKeyboardFile(char *rules, char *model, char *layout, char *vari
}
}
-void nxagentKeycodeConversionSetup(char * rules, char * model)
+void nxagentKeycodeConversionSetup(void)
{
if (nxagentOption(KeycodeConversion) == KeycodeConversionOff)
{
@@ -1711,9 +1703,9 @@ void nxagentKeycodeConversionSetup(char * rules, char * model)
}
else
{
- if (rules && model &&
- (strcmp(rules, "evdev") == 0 ||
- strcmp(model, "evdev") == 0))
+ if (nxagentRemoteRules && nxagentRemoteModel &&
+ (strcmp(nxagentRemoteRules, "evdev") == 0 ||
+ strcmp(nxagentRemoteModel, "evdev") == 0))
{
#ifdef DEBUG
fprintf(stderr, "%s: Activating KeyCode conversion.\n", __func__);
@@ -1736,40 +1728,39 @@ void nxagentKeycodeConversionSetup(char * rules, char * model)
void nxagentResetKeycodeConversion(void)
{
- int result;
- XkbAgentInfoRec info;
-
- result = XkbQueryExtension(nxagentDisplay, &info.Opcode, &info.EventBase,
- &info.ErrorBase, &info.MajorVersion,
- &info.MinorVersion);
-
- if (result != 0)
+ if (nxagentXkbInfo.Opcode != -1)
{
- char *remoterules = NULL;
- char *remotemodel = NULL;
- char *remotelayout = NULL;
- char *remotevariant = NULL;
- char *remoteoptions = NULL;
- unsigned int remoteruleslen;
+ nxagentKeycodeConversionSetup();
+ }
+ else
+ {
+ nxagentKeycodeConversion = False;
+ }
+}
- remoteruleslen = nxagentXkbGetNames(&remoterules, &remotemodel, &remotelayout,
- &remotevariant, &remoteoptions);
+Bool nxagentGetRemoteXkbExtension(void)
+{
+ Bool result;
- if (remoteruleslen && remoterules && remotemodel)
- nxagentKeycodeConversionSetup(remoterules, remotemodel);
+ nxagentXkbInfo.Opcode = nxagentXkbInfo.EventBase = nxagentXkbInfo.ErrorBase = nxagentXkbInfo.MajorVersion = nxagentXkbInfo.MinorVersion = -1;
+ nxagentXkbClearNames();
- if (remoterules)
- XFree(remoterules);
+ if ((result = XkbQueryExtension(nxagentDisplay,
+ &nxagentXkbInfo.Opcode,
+ &nxagentXkbInfo.EventBase,
+ &nxagentXkbInfo.ErrorBase,
+ &nxagentXkbInfo.MajorVersion,
+ &nxagentXkbInfo.MinorVersion)))
+ {
+ nxagentXkbGetNames();
}
+ #ifdef WARNING
else
{
- #ifdef WARNING
- fprintf(stderr, "nxagentResetKeycodeConversion: "
- "WARNING! Failed to query XKB extension.\n");
- #endif
-
- nxagentKeycodeConversion = False;
+ fprintf(stderr, "%s: WARNING! Failed to query XKB extension.\n", __func__);
}
-}
+ #endif
+ return result;
+}
#endif /* XKB */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
index ba95a3a22..b6ec51e99 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
@@ -119,6 +119,7 @@ void nxagentTuneXkbWrapper(void);
void nxagentResetKeycodeConversion(void);
+Bool nxagentGetRemoteXkbExtension(void);
#endif
CARD8 nxagentConvertKeycode(CARD8 k);
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
index a61b42530..bd4fccdce 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
@@ -584,6 +584,9 @@ Bool nxagentReconnectSession(void)
goto nxagentReconnectError;
}
+ /* Update remote XKB information */
+ nxagentGetRemoteXkbExtension();
+
/* if there's no keyboard definition in the options file
restore the previous value. */
#ifdef DEBUG