From 1d6c241d3c0b10db19476b3f018cc24f2024fa30 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Mon, 3 Dec 2018 21:54:15 +0100 Subject: nxagent: store remote keyboard in global variables This avoids some roundtrips. --- nx-X11/programs/Xserver/hw/nxagent/Keyboard.c | 213 ++++++++++++------------- nx-X11/programs/Xserver/hw/nxagent/Keyboard.h | 1 + nx-X11/programs/Xserver/hw/nxagent/Reconnect.c | 3 + 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 -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 -- cgit v1.2.3