Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nx-libs
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
dimbor
nx-libs
Commits
a8c65ab6
Unverified
Commit
a8c65ab6
authored
Dec 19, 2018
by
Mike Gabriel
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'uli42-pr/improve_keyboard2' into 3.6.x
Attributes GH PR #743:
https://github.com/ArcticaProject/nx-libs/pull/743
parents
ab3e1485
a70ec920
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
151 additions
and
99 deletions
+151
-99
Keyboard.c
nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
+127
-92
Keyboard.h
nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
+2
-1
Reconnect.c
nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
+6
-2
nxagent.1
nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1
+16
-4
No files found.
nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
View file @
a8c65ab6
...
...
@@ -78,12 +78,11 @@ is" without express or implied warranty.
#include <errno.h>
static
int
nxagentXkbGetNames
(
char
**
rules
,
char
**
model
,
char
**
layout
,
char
**
variant
,
char
**
options
);
static
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
);
static
void
nxagentWriteKeyboardFile
(
char
*
rules
,
char
*
model
,
char
*
layout
,
char
*
variant
,
char
*
options
);
#endif
/* XKB */
...
...
@@ -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
"
);
ErrorF
(
"Unable to query
XKEYBOARD extension.
\n
"
);
goto
XkbError
;
}
#ifdef XKB
if
(
noXkbExtension
)
{
#ifdef TEST
fprintf
(
stderr
,
"nxagentKeyboardProc: No XKB extension.
\n
"
);
...
...
@@ -761,7 +762,9 @@ XkbError:
layout.
*/
if
(
nxagentKeyboard
&&
(
strcmp
(
nxagentKeyboard
,
"query"
)
!=
0
))
if
(
nxagentKeyboard
&&
(
strcmp
(
nxagentKeyboard
,
"query"
)
!=
0
)
&&
(
strcmp
(
nxagentKeyboard
,
"clone"
)
!=
0
))
{
for
(
i
=
0
;
nxagentKeyboard
[
i
]
!=
'/'
&&
nxagentKeyboard
[
i
]
!=
0
;
i
++
);
...
...
@@ -772,8 +775,33 @@ XkbError:
goto
XkbError
;
}
/*
The original nxagent only supports model/layout values
here. It uses these values together with the default rules
and empty variant and options. We use a more or less
compatible hack here: The special keyword rlmvo for model
means that the layout part of the string will contain a
full RMLVO config, separated by #, e.g.
rlmvo/base#pc105#de,us#nodeadkeys#lv3:rwin_switch
*/
if
(
strncmp
(
nxagentKeyboard
,
"rlmvo/"
,
6
)
==
0
)
{
const
char
*
sep
=
"#"
;
char
*
rmlvo
=
strdup
(
&
nxagentKeyboard
[
i
+
1
]);
char
*
tmp
=
rmlvo
;
/* strtok cannot handle empty fields, so use strsep */
rules
=
strdup
(
strsep
(
&
tmp
,
sep
));
model
=
strdup
(
strsep
(
&
tmp
,
sep
));
layout
=
strdup
(
strsep
(
&
tmp
,
sep
));
variant
=
strdup
(
strsep
(
&
tmp
,
sep
));
options
=
strdup
(
strsep
(
&
tmp
,
sep
));
free
(
rmlvo
);
}
else
{
model
=
strndup
(
nxagentKeyboard
,
i
);
layout
=
strdup
(
&
nxagentKeyboard
[
i
+
1
]);
}
/*
* There is no description for pc105 on Solaris.
...
...
@@ -781,8 +809,8 @@ XkbError:
*/
#ifdef TEST
fprintf
(
stderr
,
"
nxagentKeyboardProc: Using keyboard model [%s] with layout [%s
].
\n
"
,
model
,
layout
);
fprintf
(
stderr
,
"
%s: Using [rules='%s',model='%s',layout='%s',variant='%s',options='%s'
].
\n
"
,
__func__
,
rules
,
model
,
layout
,
variant
,
options
);
#endif
#ifdef __sun
...
...
@@ -791,7 +819,6 @@ XkbError:
{
#ifdef TEST
fprintf
(
stderr
,
"nxagentKeyboardProc: WARNING! Keyboard model 'pc105' unsupported on Solaris.
\n
"
);
fprintf
(
stderr
,
"nxagentKeyboardProc: WARNING! Forcing keyboard model to 'pc104'.
\n
"
);
#endif
...
...
@@ -812,36 +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
);
#ifdef DEBUG
if
(
remoteruleslen
&&
remoterules
&&
remotemodel
)
/* Only setup keycode conversion if we are NOT in clone mode */
if
(
nxagentKeyboard
&&
(
strcmp
(
nxagentKeyboard
,
"clone"
)
==
0
)
)
{
fprintf
(
stderr
,
"%s: Remote: [rules='%s',model='%s',layout='%s',variant='%s',options='%s'].
\n
"
,
__func__
,
remoterules
,
remotemodel
,
remotelayout
,
remotevariant
,
remoteoptions
);
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
);
}
else
{
fprintf
(
stderr
,
"%s: Failed to retrieve remote rules.
\n
"
,
__func__
);
nxagentKeycodeConversionSetup
(
);
}
#endif
nxagentWriteKeyboardFile
(
remoterules
,
remotemodel
,
remotelayout
,
remotevariant
,
remoteoptions
);
nxagentKeycodeConversionSetup
(
remoterules
,
remotemodel
);
if
(
remoterules
)
{
XFree
(
remoterules
);
}
#ifdef DEBUG
else
{
fprintf
(
stderr
,
"%s: Failed to retrieve remote rules.
\n
"
,
__func__
);
}
#endif
xkb
=
XkbGetKeyboard
(
nxagentDisplay
,
XkbGBN_AllComponentsMask
,
XkbUseCoreKbd
);
...
...
@@ -1498,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
;
}
static
void
nxagentXkbGetNames
(
void
)
{
Atom
atom
;
#ifdef _XSERVER64
...
...
@@ -1514,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
))
...
...
@@ -1543,7 +1586,7 @@ static int nxagentXkbGetNames(char **rules, char **model, char **layout,
if
(
data
)
{
XFree
(
data
);
return
0
;
return
;
}
}
...
...
@@ -1551,38 +1594,40 @@ 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
)
static
void
writeKeyboardfileData
(
FILE
*
out
,
char
*
rules
,
char
*
model
,
char
*
layout
,
char
*
variant
,
char
*
options
)
{
/*
How to set "empty" values with setxkbmap, result of trial and error:
...
...
@@ -1600,7 +1645,7 @@ void writeKeyboardfileData(FILE *out, char *rules, char *model, char *layout, ch
fprintf
(
out
,
"options=
\"
,%s
\"\n
"
,
options
?
options
:
""
);
}
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
)
{
if
(
rules
&&
rules
[
0
]
!=
'\0'
)
{
...
...
@@ -1644,12 +1689,16 @@ void nxagentWriteKeyboardFile(char *rules, char *model, char *layout, char *vari
}
}
void
nxagentKeycodeConversionSetup
(
char
*
rules
,
char
*
model
)
void
nxagentKeycodeConversionSetup
(
void
)
{
nxagentKeycodeConversion
=
False
;
if
(
nxagentXkbInfo
.
Opcode
==
-
1
)
return
;
if
(
nxagentOption
(
KeycodeConversion
)
==
KeycodeConversionOff
)
{
fprintf
(
stderr
,
"Info: Keycode conversion is off
\n
"
);
nxagentKeycodeConversion
=
False
;
}
else
if
(
nxagentOption
(
KeycodeConversion
)
==
KeycodeConversionOn
)
{
...
...
@@ -1658,9 +1707,9 @@ void nxagentKeycodeConversionSetup(char * rules, char * model)
}
else
{
if
(
rules
&&
m
odel
&&
(
strcmp
(
r
ules
,
"evdev"
)
==
0
||
strcmp
(
m
odel
,
"evdev"
)
==
0
))
if
(
nxagentRemoteRules
&&
nxagentRemoteM
odel
&&
(
strcmp
(
nxagentRemoteR
ules
,
"evdev"
)
==
0
||
strcmp
(
nxagentRemoteM
odel
,
"evdev"
)
==
0
))
{
#ifdef DEBUG
fprintf
(
stderr
,
"%s: Activating KeyCode conversion.
\n
"
,
__func__
);
...
...
@@ -1676,47 +1725,33 @@ void nxagentKeycodeConversionSetup(char * rules, char * model)
#endif
fprintf
(
stderr
,
"Info: Keycode conversion auto-determined as off
\n
"
);
nxagentKeycodeConversion
=
False
;
}
}
}
void
nxagentResetKeycodeConver
sion
(
void
)
Bool
nxagentGetRemoteXkbExten
sion
(
void
)
{
int
result
;
XkbAgentInfoRec
info
;
Bool
result
;
result
=
XkbQueryExtension
(
nxagentDisplay
,
&
info
.
Opcode
,
&
info
.
EventBase
,
&
info
.
ErrorBase
,
&
info
.
MajorVersion
,
&
info
.
MinorVersion
);
nxagentXkbInfo
.
Opcode
=
nxagentXkbInfo
.
EventBase
=
nxagentXkbInfo
.
ErrorBase
=
nxagentXkbInfo
.
MajorVersion
=
nxagentXkbInfo
.
MinorVersion
=
-
1
;
nxagentXkbClearNames
();
if
(
result
!=
0
)
if
((
result
=
XkbQueryExtension
(
nxagentDisplay
,
&
nxagentXkbInfo
.
Opcode
,
&
nxagentXkbInfo
.
EventBase
,
&
nxagentXkbInfo
.
ErrorBase
,
&
nxagentXkbInfo
.
MajorVersion
,
&
nxagentXkbInfo
.
MinorVersion
)))
{
char
*
remoterules
=
NULL
;
char
*
remotemodel
=
NULL
;
char
*
remotelayout
=
NULL
;
char
*
remotevariant
=
NULL
;
char
*
remoteoptions
=
NULL
;
unsigned
int
remoteruleslen
;
remoteruleslen
=
nxagentXkbGetNames
(
&
remoterules
,
&
remotemodel
,
&
remotelayout
,
&
remotevariant
,
&
remoteoptions
);
if
(
remoteruleslen
&&
remoterules
&&
remotemodel
)
nxagentKeycodeConversionSetup
(
remoterules
,
remotemodel
);
if
(
remoterules
)
XFree
(
remoterules
);
nxagentXkbGetNames
();
}
#ifdef WARNING
else
{
#ifdef WARNING
fprintf
(
stderr
,
"nxagentResetKeycodeConversion: "
"WARNING! Failed to query XKB extension.
\n
"
);
fprintf
(
stderr
,
"%s: WARNING! Failed to query XKB extension.
\n
"
,
__func__
);
}
#endif
nxagentKeycodeConversion
=
False
;
}
return
result
;
}
#endif
/* XKB */
nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
View file @
a8c65ab6
...
...
@@ -117,8 +117,9 @@ void nxagentEnableXkbExtension(void);
void
nxagentTuneXkbWrapper
(
void
);
void
nxagent
ResetKeycodeConversion
(
void
);
void
nxagent
KeycodeConversionSetup
(
void
);
Bool
nxagentGetRemoteXkbExtension
(
void
);
#endif
CARD8
nxagentConvertKeycode
(
CARD8
k
);
...
...
nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
View file @
a8c65ab6
...
...
@@ -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
...
...
@@ -598,7 +601,8 @@ Bool nxagentReconnectSession(void)
if
(
nxagentOption
(
ResetKeyboardAtResume
)
==
1
&&
(
nxagentKeyboard
==
NULL
||
nxagentOldKeyboard
==
NULL
||
strcmp
(
nxagentKeyboard
,
nxagentOldKeyboard
)
!=
0
||
strcmp
(
nxagentKeyboard
,
"query"
)
==
0
))
strcmp
(
nxagentKeyboard
,
"query"
)
==
0
||
strcmp
(
nxagentKeyboard
,
"clone"
)
==
0
))
{
if
(
nxagentResetKeyboard
()
==
0
)
{
...
...
@@ -616,7 +620,7 @@ Bool nxagentReconnectSession(void)
}
else
{
nxagent
ResetKeycodeConversion
();
nxagent
KeycodeConversionSetup
();
}
nxagentXkbState
.
Initialized
=
0
;
...
...
nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1
View file @
a8c65ab6
...
...
@@ -525,8 +525,8 @@ don't reset keyboard device if the session is resumed
this is only relevant if you also specify \-keyboard=query. In that
case \fBnxagent\fR will lock the keyboard settings and clients will
get an error when trying to change keyboard settings via
XKEYBOARD. With \-noxkblock the lock is not applied and clients
can
change the keyboard settings through XKEYBOARD.
XKEYBOARD. With \-noxkblock the lock is not applied and clients
are
allowed
change the keyboard settings through XKEYBOARD.
.TP 8
.B \-tile WxH
size of image tiles (minimum allowed: 32x32)
...
...
@@ -603,7 +603,7 @@ start or resume a session in fullscreen mode (default: off)
.TP 8
.B keyboard=<string> or kbtype=<string>
.BR query |
<model>/<layout
>
.BR query |
clone | <model>/<layout> | rmlvo/<rules>#<model>#<layout>#<variant>#<options
>
.RS 8
.TP 8
...
...
@@ -617,10 +617,22 @@ this platform. Note that in this case XKEYBOARD will always report
the default layout which will most likely not match the experienced
settings.
.TP 8
.I clone
ask the real X server for the keyboard settings using XKEYBOARD
protocol functions and clone them. This is the recommended setting. For
compatibility reasons it is not the default.
.TP 8
.I <model>/<layout>
use the given model and layout. You can not modify keyboard rules,
variant or options. 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.
.TP 8
.I rmlvo/<rules>#<model>#<layout>#<variant>#<options>
configure the keyboard according to the rmlvo
(Rules+Model+Layout+Variant+Options) description given after the / and
separated by #. This can be used to fully pass the keyboard
configuration of \fBnxagent\fR right after the start. Example:
rmlvo/base#pc105#de,us#nodeadkeys#lv3:rwin_switch
.RE
.TP 8
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment