Commit 522106e2 authored by Ulrich Sibiller's avatar Ulrich Sibiller Committed by Mike Gabriel

nxagent: bypass X2go's keyboard configuration hack

If X2go runs in auto keyboard mode it will pass keyboard=null/null to the agent and set the keyboard afterwards with setxkbmap. This patch lets nxagent handle that situation internally (null/null will be interpreted as clone) and disables X2go's mechanism (by creating a dir that effectively blocks it; see x2gosetkeyboard) This is only activated if the agent is run as "x2goagent". Fixes ArcticaProject/nx-libs#368
parent a8c65ab6
...@@ -57,6 +57,7 @@ is" without express or implied warranty. ...@@ -57,6 +57,7 @@ is" without express or implied warranty.
#include "Events.h" #include "Events.h"
#include "Options.h" #include "Options.h"
#include "Error.h" #include "Error.h"
#include "Init.h"
#include "compext/Compext.h" #include "compext/Compext.h"
...@@ -82,6 +83,7 @@ static void nxagentXkbGetNames(void); ...@@ -82,6 +83,7 @@ static void nxagentXkbGetNames(void);
void nxagentKeycodeConversionSetup(void); void nxagentKeycodeConversionSetup(void);
static void nxagentWriteKeyboardDir(void);
static void nxagentWriteKeyboardFile(char *rules, char *model, char *layout, char *variant, char *options); static void nxagentWriteKeyboardFile(char *rules, char *model, char *layout, char *variant, char *options);
#endif /* XKB */ #endif /* XKB */
...@@ -751,6 +753,15 @@ XkbError: ...@@ -751,6 +753,15 @@ XkbError:
fprintf(stderr, "nxagentKeyboardProc: nxagentKeyboard is [%s].\n", nxagentKeyboard ? nxagentKeyboard : "NULL"); fprintf(stderr, "nxagentKeyboardProc: nxagentKeyboard is [%s].\n", nxagentKeyboard ? nxagentKeyboard : "NULL");
#endif #endif
if (nxagentX2go == 1 && nxagentKeyboard && (strcmp(nxagentKeyboard, "null/null") == 0))
{
#ifdef TEST
fprintf(stderr, "%s: changing nxagentKeyboard from [null/null] to [clone].\n", __func__);
#endif
free(nxagentKeyboard);
nxagentKeyboard = strdup("clone");
}
/* /*
from nxagent changelog: from nxagent changelog:
2.0.22: 2.0.22:
...@@ -846,19 +857,6 @@ XkbError: ...@@ -846,19 +857,6 @@ XkbError:
__func__, nxagentRemoteRules, nxagentRemoteModel, nxagentRemoteLayout, nxagentRemoteVariant, nxagentRemoteOptions); __func__, nxagentRemoteRules, nxagentRemoteModel, nxagentRemoteLayout, nxagentRemoteVariant, nxagentRemoteOptions);
#endif #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(nxagentRemoteRules, nxagentRemoteModel, nxagentRemoteLayout, nxagentRemoteVariant, nxagentRemoteOptions);
/* Only setup keycode conversion if we are NOT in clone mode */ /* Only setup keycode conversion if we are NOT in clone mode */
if (nxagentKeyboard && (strcmp(nxagentKeyboard, "clone") == 0)) if (nxagentKeyboard && (strcmp(nxagentKeyboard, "clone") == 0))
...@@ -868,10 +866,33 @@ XkbError: ...@@ -868,10 +866,33 @@ XkbError:
free(layout); layout = strdup(nxagentRemoteLayout); free(layout); layout = strdup(nxagentRemoteLayout);
free(variant); variant = strdup(nxagentRemoteVariant); free(variant); variant = strdup(nxagentRemoteVariant);
free(options); options = strdup(nxagentRemoteOptions); free(options); options = strdup(nxagentRemoteOptions);
/*
* when cloning we do not want X2Go to set the keyboard
* via a keyboard file generated by nxagent. The defined
* method for switching that off is the creation of a dir
* instead of a file. Which is achieved by passing NULL to
* nxagentWriteKeyboardFile.
*/
if (nxagentX2go == 1)
nxagentWriteKeyboardDir();
} }
else else
{ {
nxagentKeycodeConversionSetup(); nxagentKeycodeConversionSetup();
/*
* 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.
*/
if (nxagentX2go == 1)
nxagentWriteKeyboardFile(nxagentRemoteRules, nxagentRemoteModel, nxagentRemoteLayout, nxagentRemoteVariant, nxagentRemoteOptions);
} }
} }
#ifdef DEBUG #ifdef DEBUG
...@@ -1645,29 +1666,65 @@ static void writeKeyboardfileData(FILE *out, char *rules, char *model, char *lay ...@@ -1645,29 +1666,65 @@ static void writeKeyboardfileData(FILE *out, char *rules, char *model, char *lay
fprintf(out, "options=\",%s\"\n", options ? options : ""); fprintf(out, "options=\",%s\"\n", options ? options : "");
} }
static void nxagentWriteKeyboardFile(char *rules, char *model, char *layout, char *variant, char *options) static char* getKeyboardFilePath(void)
{ {
if (rules && rules[0] != '\0') char *keyboard_file_path = NULL;
{
#ifdef DEBUG
writeKeyboardfileData(stderr, rules, model, layout, variant, options);
#endif
char *sessionpath = nxagentGetSessionPath(); char *sessionpath = nxagentGetSessionPath();
if (sessionpath) if (sessionpath)
{ {
char *keyboard_file_path = NULL;
FILE *keyboard_file;
if ((asprintf(&keyboard_file_path, "%s/keyboard", sessionpath) == -1)) if ((asprintf(&keyboard_file_path, "%s/keyboard", sessionpath) == -1))
{ {
free(sessionpath); free(sessionpath);
FatalError("malloc for keyboard file path failed."); FatalError("malloc for keyboard file path failed.");
} }
free(sessionpath); free(sessionpath);
}
else
{
fprintf(stderr, "Warning: Failed to determine keyboard file path: SessionPath not defined\n");
}
return keyboard_file_path;
}
static void nxagentWriteKeyboardDir(void)
{
char *keyboard_file_path = getKeyboardFilePath();
if (keyboard_file_path)
{
/*
* special case: if rules is NULL create a directory insteas of
* a file. This is the defined method to disable x2gosetkeyboard.
*/
if (mkdir(keyboard_file_path, 0555) < 0)
{
int save_err = errno;
fprintf(stderr, "Warning: Failed to create keyboard blocking directory '%s': %s\n", keyboard_file_path, strerror(save_err));
}
else
{
fprintf(stderr, "Info: keyboard blocking directory created: '%s'\n", keyboard_file_path);
}
free(keyboard_file_path);
}
}
static void nxagentWriteKeyboardFile(char *rules, char *model, char *layout, char *variant, char *options)
{
if (rules && rules[0] != '\0')
{
#ifdef DEBUG
writeKeyboardfileData(stderr, rules, model, layout, variant, options);
#endif
char *keyboard_file_path = getKeyboardFilePath();
if (keyboard_file_path)
{
FILE *keyboard_file;
if ((keyboard_file = fopen(keyboard_file_path, "w"))) if ((keyboard_file = fopen(keyboard_file_path, "w")))
{ {
writeKeyboardfileData(keyboard_file, rules, model, layout, variant, options); writeKeyboardfileData(keyboard_file, rules, model, layout, variant, options);
fclose(keyboard_file); fclose(keyboard_file);
fprintf(stderr, "Info: keyboard file created: '%s'\n", keyboard_file_path); fprintf(stderr, "Info: keyboard file created: '%s'\n", keyboard_file_path);
} }
...@@ -1678,14 +1735,6 @@ static void nxagentWriteKeyboardFile(char *rules, char *model, char *layout, cha ...@@ -1678,14 +1735,6 @@ static void nxagentWriteKeyboardFile(char *rules, char *model, char *layout, cha
} }
free(keyboard_file_path); free(keyboard_file_path);
} }
else
{
fprintf(stderr, "Warning: Failed to create keyboard file: SessionPath not defined\n");
}
}
else
{
fprintf(stderr, "Warning: Failed to create the keyboard file\n");
} }
} }
......
...@@ -458,6 +458,16 @@ Bool nxagentReconnectSession(void) ...@@ -458,6 +458,16 @@ Bool nxagentReconnectSession(void)
nxagentProcessOptions(nxagentOptionsFilenameOrString); nxagentProcessOptions(nxagentOptionsFilenameOrString);
if (nxagentKeyboard && (strcmp(nxagentKeyboard, "null/null") == 0))
{
#ifdef TEST
fprintf(stderr, "nxagentReconnect: changing nxagentKeyboard from [null/null] to [clone].\n");
#endif
free(nxagentKeyboard);
nxagentKeyboard = strdup("clone");
}
if (nxagentReconnectDisplay(reconnectLossyLevel[DISPLAY_STEP]) == 0) if (nxagentReconnectDisplay(reconnectLossyLevel[DISPLAY_STEP]) == 0)
{ {
failedStep = DISPLAY_STEP; failedStep = DISPLAY_STEP;
......
...@@ -623,7 +623,8 @@ protocol functions and clone them. This is the recommended setting. For ...@@ -623,7 +623,8 @@ protocol functions and clone them. This is the recommended setting. For
compatibility reasons it is not the default. compatibility reasons it is not the default.
.TP 8 .TP 8
.I <model>/<layout> .I <model>/<layout>
use the given model and layout. You can not modify keyboard rules, use the given model and layout. A value of \fInull/null\fR is equivalent to
\fIclone\fR. You can not modify keyboard rules,
variant or options this way. Instead preset values are used. These are variant or options this way. Instead preset values are used. These are
\fIbase\fR for rules and empty strings for variant and options. \fIbase\fR for rules and empty strings for variant and options.
.TP 8 .TP 8
......
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