forked from pool/xorg-x11-server
132 lines
4.6 KiB
Diff
132 lines
4.6 KiB
Diff
|
This patch fixes keycode lookup (not using any static keyboard layout any more)
|
||
|
and ISO-Level3-Shift handling (enabling the use of keyboard layouts that use
|
||
|
AltGr for reaching certain characters).
|
||
|
|
||
|
Note that the implementation is still imperfect. Keyboard layouts that use a
|
||
|
different key than AltGr for ISO-Level3-Shift will show some weird behavior.
|
||
|
Mode_Switch is also not supported, so keyboard switching via Mode_Switch might
|
||
|
not work as intended either. Suggesting the use of input methods in these cases
|
||
|
(they will hopefully work).
|
||
|
|
||
|
mhopf - 21/04/2011
|
||
|
|
||
|
Index: xorg-server-1.9.3/hw/vnc/kbdptr.c
|
||
|
===================================================================
|
||
|
--- xorg-server-1.9.3.orig/hw/vnc/kbdptr.c
|
||
|
+++ xorg-server-1.9.3/hw/vnc/kbdptr.c
|
||
|
@@ -142,6 +142,10 @@ KbdAddEvent(Bool down, KeySym keySym, rf
|
||
|
Bool fakeShiftRRelease = FALSE;
|
||
|
Bool shiftMustBeReleased = FALSE;
|
||
|
Bool shiftMustBePressed = FALSE;
|
||
|
+ Bool fakeLevel3Press = FALSE;
|
||
|
+ Bool fakeLevel3Release = FALSE;
|
||
|
+ Bool level3MustBeReleased = FALSE;
|
||
|
+ Bool level3MustBePressed = FALSE;
|
||
|
|
||
|
keySyms = XkbGetCoreMap(inputInfo.keyboard);
|
||
|
|
||
|
@@ -161,6 +165,12 @@ KbdAddEvent(Bool down, KeySym keySym, rf
|
||
|
*
|
||
|
* Alan.
|
||
|
*/
|
||
|
+ /* Never use predefined keys.
|
||
|
+ * This is inherently incapable of dealing with changing
|
||
|
+ * keyboard layouts. Not being able to work with non-local xmodmaps
|
||
|
+ * is a nuisance at worst, and probably even preferred.
|
||
|
+ * 2011-04-15 mhopf@suse.de */
|
||
|
+#if 0
|
||
|
#if !XFREE86VNC
|
||
|
/* First check if it's one of our predefined keys. If so then we can make
|
||
|
some attempt at allowing an xmodmap inside a VNC desktop behave
|
||
|
@@ -187,6 +197,7 @@ KbdAddEvent(Bool down, KeySym keySym, rf
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
+#endif
|
||
|
|
||
|
if (!keyCode) {
|
||
|
|
||
|
@@ -201,18 +212,27 @@ KbdAddEvent(Bool down, KeySym keySym, rf
|
||
|
|
||
|
for (i = 0; i < NO_OF_KEYS * keySyms->mapWidth; i++) {
|
||
|
if (keySym == keySyms->map[i]) {
|
||
|
+ int j, numSyms = 0;
|
||
|
keyCode = MIN_KEY_CODE + i / keySyms->mapWidth;
|
||
|
|
||
|
- if (keySyms->map[(i / keySyms->mapWidth)
|
||
|
- * keySyms->mapWidth + 1] != NoSymbol) {
|
||
|
-
|
||
|
+ for (j = 0; j < keySyms->mapWidth; j++)
|
||
|
+ if (keySyms->map[(i / keySyms->mapWidth)
|
||
|
+ * keySyms->mapWidth + j] != NoSymbol)
|
||
|
+ numSyms++;
|
||
|
+ if (numSyms > 1) {
|
||
|
/* this keycode has more than one symbol associated with
|
||
|
- it, so shift state is important */
|
||
|
+ it, so shift/Level3_shift state is important */
|
||
|
|
||
|
- if ((i % keySyms->mapWidth) == 0)
|
||
|
+ if (((i % keySyms->mapWidth) & 1) == 0)
|
||
|
shiftMustBeReleased = TRUE;
|
||
|
else
|
||
|
shiftMustBePressed = TRUE;
|
||
|
+ /* Does NOT consider Mode_shift (entries 2-3) */
|
||
|
+ if (((i % keySyms->mapWidth) & 4) == 0)
|
||
|
+ level3MustBeReleased = TRUE;
|
||
|
+ else {
|
||
|
+ level3MustBePressed = TRUE;
|
||
|
+ }
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
@@ -252,6 +272,7 @@ KbdAddEvent(Bool down, KeySym keySym, rf
|
||
|
shiftMustBeReleased = TRUE;
|
||
|
else
|
||
|
shiftMustBePressed = TRUE;
|
||
|
+ level3MustBeReleased = TRUE;
|
||
|
}
|
||
|
|
||
|
XkbApplyMappingChange(inputInfo.keyboard, keySyms, keyCode, 1, NULL, serverClient);
|
||
|
@@ -262,6 +283,16 @@ KbdAddEvent(Bool down, KeySym keySym, rf
|
||
|
|
||
|
xkb = &inputInfo.keyboard->key->xkbInfo->state;
|
||
|
if (down) {
|
||
|
+ // TODO: would require to check which keycodes are actually
|
||
|
+ // bound to ISO_Level3_Shift and/or Shift_L
|
||
|
+ if (level3MustBePressed && !KEY_IS_PRESSED(ISO_LEVEL3_KEY_CODE)) {
|
||
|
+ fakeLevel3Press = TRUE;
|
||
|
+ EnqueueKey(inputInfo.keyboard, KeyPress, ISO_LEVEL3_KEY_CODE);
|
||
|
+ }
|
||
|
+ if (level3MustBeReleased && KEY_IS_PRESSED(ISO_LEVEL3_KEY_CODE)) {
|
||
|
+ fakeLevel3Release = TRUE;
|
||
|
+ EnqueueKey(inputInfo.keyboard, KeyRelease, ISO_LEVEL3_KEY_CODE);
|
||
|
+ }
|
||
|
if (shiftMustBePressed && !(XkbStateFieldFromRec(xkb) & ShiftMask)) {
|
||
|
fakeShiftPress = TRUE;
|
||
|
EnqueueKey(inputInfo.keyboard, KeyPress, SHIFT_L_KEY_CODE);
|
||
|
@@ -289,6 +320,12 @@ KbdAddEvent(Bool down, KeySym keySym, rf
|
||
|
if (fakeShiftRRelease) {
|
||
|
EnqueueKey(inputInfo.keyboard, KeyPress, SHIFT_R_KEY_CODE);
|
||
|
}
|
||
|
+ if (fakeLevel3Press) {
|
||
|
+ EnqueueKey(inputInfo.keyboard, KeyRelease, ISO_LEVEL3_KEY_CODE);
|
||
|
+ }
|
||
|
+ if (fakeLevel3Release) {
|
||
|
+ EnqueueKey(inputInfo.keyboard, KeyPress, ISO_LEVEL3_KEY_CODE);
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
|
||
|
Index: xorg-server-1.9.3/hw/vnc/keyboard.h
|
||
|
===================================================================
|
||
|
--- xorg-server-1.9.3.orig/hw/vnc/keyboard.h
|
||
|
+++ xorg-server-1.9.3/hw/vnc/keyboard.h
|
||
|
@@ -32,6 +32,7 @@
|
||
|
#define META_R_KEY_CODE (MIN_KEY_CODE + 108)
|
||
|
#define ALT_L_KEY_CODE (MIN_KEY_CODE + 56)
|
||
|
#define ALT_R_KEY_CODE (MIN_KEY_CODE + 105)
|
||
|
+#define ISO_LEVEL3_KEY_CODE ALT_R_KEY_CODE
|
||
|
|
||
|
static KeySym map[MAX_KEY_CODE * GLYPHS_PER_KEY] = {
|
||
|
/* 0x00 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
|