Commit 1d6c241d authored by Ulrich Sibiller's avatar Ulrich Sibiller Committed by Mike Gabriel

nxagent: store remote keyboard in global variables

This avoids some roundtrips.
parent 161515d2
...@@ -78,10 +78,9 @@ is" without express or implied warranty. ...@@ -78,10 +78,9 @@ is" without express or implied warranty.
#include <errno.h> #include <errno.h>
static int nxagentXkbGetNames(char **rules, char **model, char **layout, void nxagentXkbGetNames(void);
char **variant, char **options);
static void nxagentKeycodeConversionSetup(char *rules, char *model); void nxagentKeycodeConversionSetup(void);
void nxagentWriteKeyboardFile(char *rules, char *model, char *layout, char *variant, char *options); void nxagentWriteKeyboardFile(char *rules, char *model, char *layout, char *variant, char *options);
...@@ -140,6 +139,13 @@ extern Status XkbGetControls( ...@@ -140,6 +139,13 @@ extern Status XkbGetControls(
extern int XkbDfltRepeatDelay; extern int XkbDfltRepeatDelay;
extern int XkbDfltRepeatInterval; 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 */ #endif /* XKB */
/* /*
...@@ -571,8 +577,10 @@ int nxagentKeyboardProc(DeviceIntPtr pDev, int onoff) ...@@ -571,8 +577,10 @@ int nxagentKeyboardProc(DeviceIntPtr pDev, int onoff)
CARD8 modmap[MAP_LENGTH]; CARD8 modmap[MAP_LENGTH];
int i, j; int i, j;
XKeyboardState values; XKeyboardState values;
#ifdef XKB
char *model = NULL, *layout = NULL; char *model = NULL, *layout = NULL;
XkbDescPtr xkb = NULL; XkbDescPtr xkb = NULL;
#endif
switch (onoff) switch (onoff)
{ {
...@@ -694,20 +702,13 @@ N/A ...@@ -694,20 +702,13 @@ N/A
keySyms.mapWidth = mapWidth; keySyms.mapWidth = mapWidth;
keySyms.map = keymap; keySyms.map = keymap;
if (XkbQueryExtension(nxagentDisplay, #ifdef XKB
&nxagentXkbInfo.Opcode, if (!nxagentGetRemoteXkbExtension())
&nxagentXkbInfo.EventBase,
&nxagentXkbInfo.ErrorBase,
&nxagentXkbInfo.MajorVersion,
&nxagentXkbInfo.MinorVersion) == 0)
{ {
ErrorF("Unable to initialize XKEYBOARD extension.\n"); ErrorF("Unable to query XKEYBOARD extension.\n");
goto XkbError; goto XkbError;
} }
#ifdef XKB
if (noXkbExtension) { if (noXkbExtension) {
#ifdef TEST #ifdef TEST
fprintf(stderr, "nxagentKeyboardProc: No XKB extension.\n"); fprintf(stderr, "nxagentKeyboardProc: No XKB extension.\n");
...@@ -838,63 +839,47 @@ XkbError: ...@@ -838,63 +839,47 @@ XkbError:
fprintf(stderr, "nxagentKeyboardProc: Init XKB extension.\n"); fprintf(stderr, "nxagentKeyboardProc: Init XKB extension.\n");
#endif #endif
if (nxagentRemoteRules && nxagentRemoteModel)
{ {
char *remoterules = NULL; #ifdef DEBUG
char *remotemodel = NULL; fprintf(stderr, "%s: Remote: [rules='%s',model='%s',layout='%s',variant='%s',options='%s'].\n",
char *remotelayout = NULL; __func__, nxagentRemoteRules, nxagentRemoteModel, nxagentRemoteLayout, nxagentRemoteVariant, nxagentRemoteOptions);
char *remotevariant = NULL; #endif
char *remoteoptions = NULL;
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 free(rules); rules = strdup(nxagentRemoteRules);
fprintf(stderr, "%s: Remote: [rules='%s',model='%s',layout='%s',variant='%s',options='%s'].\n", free(model); model = strdup(nxagentRemoteModel);
__func__, remoterules, remotemodel, remotelayout, remotevariant, remoteoptions); free(layout); layout = strdup(nxagentRemoteLayout);
#endif free(variant); variant = strdup(nxagentRemoteVariant);
free(options); options = strdup(nxagentRemoteOptions);
/*
* 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);
}
} }
#ifdef DEBUG
else else
{ {
fprintf(stderr, "%s: Failed to retrieve remote rules.\n", __func__); nxagentKeycodeConversionSetup();
}
#endif
if (remoterules)
{
XFree(remoterules);
} }
} }
#ifdef DEBUG
else
{
fprintf(stderr, "%s: Failed to retrieve remote rules.\n", __func__);
}
#endif
xkb = XkbGetKeyboard(nxagentDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd); xkb = XkbGetKeyboard(nxagentDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
...@@ -1551,8 +1536,16 @@ void nxagentTuneXkbWrapper(void) ...@@ -1551,8 +1536,16 @@ void nxagentTuneXkbWrapper(void)
} }
} }
static int nxagentXkbGetNames(char **rules, char **model, char **layout, void nxagentXkbClearNames(void)
char **variant, char **options) {
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; Atom atom;
#ifdef _XSERVER64 #ifdef _XSERVER64
...@@ -1567,28 +1560,25 @@ static int nxagentXkbGetNames(char **rules, char **model, char **layout, ...@@ -1567,28 +1560,25 @@ static int nxagentXkbGetNames(char **rules, char **model, char **layout,
char *name; char *name;
Status result; Status result;
data = name = NULL; if (nxagentRemoteRules)
return;
*rules = NULL;
*model = NULL;
*layout = NULL;
*variant = NULL;
*options = NULL;
atom = XInternAtom(nxagentDisplay, "_XKB_RULES_NAMES", 1); atom = XInternAtom(nxagentDisplay, "_XKB_RULES_NAMES", 1);
if (atom == 0) if (atom == 0)
{ {
return 0; return;
} }
data = name = NULL;
result = XGetWindowProperty(nxagentDisplay, DefaultRootWindow(nxagentDisplay), result = XGetWindowProperty(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
atom, 0, 256, 0, XA_STRING, &type, &format, atom, 0, 256, 0, XA_STRING, &type, &format,
&n, &after, (unsigned char **)&data); &n, &after, (unsigned char **)&data);
if (result != Success || !data) if (result != Success || !data)
{ {
return 0; return;
} }
if ((after > 0) || (type != XA_STRING) || (format != 8)) if ((after > 0) || (type != XA_STRING) || (format != 8))
...@@ -1596,7 +1586,7 @@ static int nxagentXkbGetNames(char **rules, char **model, char **layout, ...@@ -1596,7 +1586,7 @@ static int nxagentXkbGetNames(char **rules, char **model, char **layout,
if (data) if (data)
{ {
XFree(data); XFree(data);
return 0; return;
} }
} }
...@@ -1604,35 +1594,37 @@ static int nxagentXkbGetNames(char **rules, char **model, char **layout, ...@@ -1604,35 +1594,37 @@ static int nxagentXkbGetNames(char **rules, char **model, char **layout,
if (name < data + n) if (name < data + n)
{ {
*rules = name; nxagentRemoteRules = strdup(name);
name += strlen(name) + 1; name += strlen(name) + 1;
} }
if (name < data + n) if (name < data + n)
{ {
*model = name; nxagentRemoteModel = strdup(name);
name += strlen(name) + 1; name += strlen(name) + 1;
} }
if (name < data + n) if (name < data + n)
{ {
*layout = name; nxagentRemoteLayout = strdup(name);
name += strlen(name) + 1; name += strlen(name) + 1;
} }
if (name < data + n) if (name < data + n)
{ {
*variant = name; nxagentRemoteVariant = strdup(name);
name += strlen(name) + 1; name += strlen(name) + 1;
} }
if (name < data + n) if (name < data + n)
{ {
*options = name; nxagentRemoteOptions = strdup(name);
name += strlen(name) + 1; name += strlen(name) + 1;
} }
return n; XFree(data);
return;
} }
void writeKeyboardfileData(FILE *out, char *rules, char *model, char *layout, char *variant, char *options) 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 ...@@ -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) if (nxagentOption(KeycodeConversion) == KeycodeConversionOff)
{ {
...@@ -1711,9 +1703,9 @@ void nxagentKeycodeConversionSetup(char * rules, char * model) ...@@ -1711,9 +1703,9 @@ void nxagentKeycodeConversionSetup(char * rules, char * model)
} }
else else
{ {
if (rules && model && if (nxagentRemoteRules && nxagentRemoteModel &&
(strcmp(rules, "evdev") == 0 || (strcmp(nxagentRemoteRules, "evdev") == 0 ||
strcmp(model, "evdev") == 0)) strcmp(nxagentRemoteModel, "evdev") == 0))
{ {
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "%s: Activating KeyCode conversion.\n", __func__); fprintf(stderr, "%s: Activating KeyCode conversion.\n", __func__);
...@@ -1736,40 +1728,39 @@ void nxagentKeycodeConversionSetup(char * rules, char * model) ...@@ -1736,40 +1728,39 @@ void nxagentKeycodeConversionSetup(char * rules, char * model)
void nxagentResetKeycodeConversion(void) void nxagentResetKeycodeConversion(void)
{ {
int result; if (nxagentXkbInfo.Opcode != -1)
XkbAgentInfoRec info;
result = XkbQueryExtension(nxagentDisplay, &info.Opcode, &info.EventBase,
&info.ErrorBase, &info.MajorVersion,
&info.MinorVersion);
if (result != 0)
{ {
char *remoterules = NULL; nxagentKeycodeConversionSetup();
char *remotemodel = NULL; }
char *remotelayout = NULL; else
char *remotevariant = NULL; {
char *remoteoptions = NULL; nxagentKeycodeConversion = False;
unsigned int remoteruleslen; }
}
remoteruleslen = nxagentXkbGetNames(&remoterules, &remotemodel, &remotelayout, Bool nxagentGetRemoteXkbExtension(void)
&remotevariant, &remoteoptions); {
Bool result;
if (remoteruleslen && remoterules && remotemodel) nxagentXkbInfo.Opcode = nxagentXkbInfo.EventBase = nxagentXkbInfo.ErrorBase = nxagentXkbInfo.MajorVersion = nxagentXkbInfo.MinorVersion = -1;
nxagentKeycodeConversionSetup(remoterules, remotemodel); nxagentXkbClearNames();
if (remoterules) if ((result = XkbQueryExtension(nxagentDisplay,
XFree(remoterules); &nxagentXkbInfo.Opcode,
&nxagentXkbInfo.EventBase,
&nxagentXkbInfo.ErrorBase,
&nxagentXkbInfo.MajorVersion,
&nxagentXkbInfo.MinorVersion)))
{
nxagentXkbGetNames();
} }
#ifdef WARNING
else else
{ {
#ifdef WARNING fprintf(stderr, "%s: WARNING! Failed to query XKB extension.\n", __func__);
fprintf(stderr, "nxagentResetKeycodeConversion: "
"WARNING! Failed to query XKB extension.\n");
#endif
nxagentKeycodeConversion = False;
} }
} #endif
return result;
}
#endif /* XKB */ #endif /* XKB */
...@@ -119,6 +119,7 @@ void nxagentTuneXkbWrapper(void); ...@@ -119,6 +119,7 @@ void nxagentTuneXkbWrapper(void);
void nxagentResetKeycodeConversion(void); void nxagentResetKeycodeConversion(void);
Bool nxagentGetRemoteXkbExtension(void);
#endif #endif
CARD8 nxagentConvertKeycode(CARD8 k); CARD8 nxagentConvertKeycode(CARD8 k);
......
...@@ -584,6 +584,9 @@ Bool nxagentReconnectSession(void) ...@@ -584,6 +584,9 @@ Bool nxagentReconnectSession(void)
goto nxagentReconnectError; goto nxagentReconnectError;
} }
/* Update remote XKB information */
nxagentGetRemoteXkbExtension();
/* if there's no keyboard definition in the options file /* if there's no keyboard definition in the options file
restore the previous value. */ restore the previous value. */
#ifdef DEBUG #ifdef DEBUG
......
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