diff --git a/xorg-server-xf4vnc-bug605015-fix-keyboard-handling-xinput.diff b/xorg-server-xf4vnc-bug605015-fix-keyboard-handling-xinput.diff deleted file mode 100644 index fa45b33..0000000 --- a/xorg-server-xf4vnc-bug605015-fix-keyboard-handling-xinput.diff +++ /dev/null @@ -1,117 +0,0 @@ -This patch fixes keyboard handling for XInput enabled servers. W/o this patch -the wrong keyboard was used for adding new KeyCodes. - -This should basically already enable the use of other keyboards, if the remote -keyboard stays at US. - -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 -@@ -46,19 +46,17 @@ - #endif - - #define KEY_IS_PRESSED(keycode) \ -- (kbdDevice->key->down[(keycode) >> 3] & (1 << ((keycode) & 7))) -+ (inputInfo.keyboard->key->down[(keycode) >> 3] & (1 << ((keycode) & 7))) - - static void vncXConvertCase(KeySym sym, KeySym *lower, KeySym *upper); - --static DeviceIntPtr ptrDevice = NULL, kbdDevice = NULL; -+static DeviceIntPtr ptrDevice = NULL; - - - void - vncSetKeyboardDevice(DeviceIntPtr kbd) - { -- if (kbdDevice && kbd) -- return; /* set once */ -- kbdDevice = kbd; -+ // obsoleted by inputInfo - } - - -@@ -145,10 +143,7 @@ KbdAddEvent(Bool down, KeySym keySym, rf - Bool shiftMustBeReleased = FALSE; - Bool shiftMustBePressed = FALSE; - -- if (!kbdDevice) -- return; -- -- keySyms = XkbGetCoreMap(kbdDevice); -+ keySyms = XkbGetCoreMap(inputInfo.keyboard); - - #ifdef CORBA - if (cl) { -@@ -259,40 +254,40 @@ KbdAddEvent(Bool down, KeySym keySym, rf - shiftMustBePressed = TRUE; - } - -- XkbApplyMappingChange(kbdDevice, keySyms, keyCode, 1, NULL, serverClient); -+ XkbApplyMappingChange(inputInfo.keyboard, keySyms, keyCode, 1, NULL, serverClient); - - ErrorF("KbdAddEvent: unknown KeySym 0x%x - allocating KeyCode %d\n", - (int)keySym, keyCode); - } - -- xkb = &kbdDevice->key->xkbInfo->state; -+ xkb = &inputInfo.keyboard->key->xkbInfo->state; - if (down) { - if (shiftMustBePressed && !(XkbStateFieldFromRec(xkb) & ShiftMask)) { - fakeShiftPress = TRUE; -- EnqueueKey(kbdDevice, KeyPress, SHIFT_L_KEY_CODE); -+ EnqueueKey(inputInfo.keyboard, KeyPress, SHIFT_L_KEY_CODE); - } - if (shiftMustBeReleased && (XkbStateFieldFromRec(xkb) & ShiftMask)) { - if (KEY_IS_PRESSED(SHIFT_L_KEY_CODE)) { - fakeShiftLRelease = TRUE; -- EnqueueKey(kbdDevice, KeyRelease, SHIFT_L_KEY_CODE); -+ EnqueueKey(inputInfo.keyboard, KeyRelease, SHIFT_L_KEY_CODE); - } - if (KEY_IS_PRESSED(SHIFT_R_KEY_CODE)) { - fakeShiftRRelease = TRUE; -- EnqueueKey(kbdDevice, KeyRelease, SHIFT_R_KEY_CODE); -+ EnqueueKey(inputInfo.keyboard, KeyRelease, SHIFT_R_KEY_CODE); - } - } - } - -- EnqueueKey(kbdDevice, type, keyCode); -+ EnqueueKey(inputInfo.keyboard, type, keyCode); - - if (fakeShiftPress) { -- EnqueueKey(kbdDevice, KeyRelease, SHIFT_L_KEY_CODE); -+ EnqueueKey(inputInfo.keyboard, KeyRelease, SHIFT_L_KEY_CODE); - } - if (fakeShiftLRelease) { -- EnqueueKey(kbdDevice, KeyPress, SHIFT_L_KEY_CODE); -+ EnqueueKey(inputInfo.keyboard, KeyPress, SHIFT_L_KEY_CODE); - } - if (fakeShiftRRelease) { -- EnqueueKey(kbdDevice, KeyPress, SHIFT_R_KEY_CODE); -+ EnqueueKey(inputInfo.keyboard, KeyPress, SHIFT_R_KEY_CODE); - } - } - -@@ -343,15 +338,15 @@ KbdReleaseAllKeys(void) - { - int i, j; - -- if (!kbdDevice) -+ if (!inputInfo.keyboard) - return; - - for (i = 0; i < DOWN_LENGTH; i++) { -- if (kbdDevice->key->down[i] != 0) { -+ if (inputInfo.keyboard->key->down[i] != 0) { - for (j = 0; j < 8; j++) { -- if (kbdDevice->key->down[i] & (1 << j)) { -+ if (inputInfo.keyboard->key->down[i] & (1 << j)) { - int detail = (i << 3) | j; -- EnqueueKey(kbdDevice, KeyRelease, detail); -+ EnqueueKey(inputInfo.keyboard, KeyRelease, detail); - } - } - } diff --git a/xorg-server-xf4vnc-bug605015-fix-keycode-lookup-and-isolevel3shift.diff b/xorg-server-xf4vnc-bug605015-fix-keycode-lookup-and-isolevel3shift.diff deleted file mode 100644 index 48b6419..0000000 --- a/xorg-server-xf4vnc-bug605015-fix-keycode-lookup-and-isolevel3shift.diff +++ /dev/null @@ -1,131 +0,0 @@ -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, diff --git a/xorg-server-xf4vnc-fix-keyboard-layout-handling.diff b/xorg-server-xf4vnc-fix-keyboard-layout-handling.diff new file mode 100644 index 0000000..a48ad53 --- /dev/null +++ b/xorg-server-xf4vnc-fix-keyboard-layout-handling.diff @@ -0,0 +1,456 @@ +bnc #660797,#605015,#400520 +Enable use of all keyboard layouts, independent of remotely set layout + +Changes: + +- Use virtual core keyboard for events and key state lookup: + Make layout changes work again - see discussion on + https://defect.opensolaris.org/bz/show_bug.cgi?id=8687 +- keycode lookup: + Don't use any static keyboard layout any more. +- ISO-Level3-Shift handling: + Enable the use of keyboard layouts that use AltGr for 3rd and 4th level. +- Make keyboard handling more XKB aware: + Previous code was e.g. not multi-group aware. +- Nuke use of legacy keymap as far as possible: + Creating legacy keymap takes time, and it has to be freed again afterwards. +- Free index lookup: + Make XKB aware. +- Ignore calls for NoSymbol: + This destroys otherwise valid entries. +- Fix analysis for shift/level3 event faking: + Previous broken version lead to e.g. Shift+PgUp not being recognized. +- Add tons of debug output (disabled). + +mhopf@suse.de + +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 +@@ -33,6 +33,8 @@ + #define NEED_EVENTS + #include "X11/Xproto.h" + #include "inputstr.h" ++#include "xkbsrv.h" ++#include "xkbstr.h" + #define XK_CYRILLIC + #include + #include +@@ -46,19 +48,17 @@ + #endif + + #define KEY_IS_PRESSED(keycode) \ +- (kbdDevice->key->down[(keycode) >> 3] & (1 << ((keycode) & 7))) ++ (inputInfo.keyboard->key->down[(keycode) >> 3] & (1 << ((keycode) & 7))) + + static void vncXConvertCase(KeySym sym, KeySym *lower, KeySym *upper); + +-static DeviceIntPtr ptrDevice = NULL, kbdDevice = NULL; ++static DeviceIntPtr ptrDevice = NULL; + + + void + vncSetKeyboardDevice(DeviceIntPtr kbd) + { +- if (kbdDevice && kbd) +- return; /* set once */ +- kbdDevice = kbd; ++ // obsoleted by inputInfo + } + + +@@ -126,6 +126,29 @@ EnqueueKey(DeviceIntPtr kbdDev, int type + mieqEnqueue(kbdDev, (InternalEvent*)(events + i)->event); + } + ++/* In-server and highly changed version of XkbKeycodeToKeysym */ ++static KeySym ++_XkbKeycodeToKeysym(XkbDescPtr xkb, KeyCode kc, int group, int level) ++{ ++ KeySym ks; ++ ++ if ((kcmin_key_code)||(kc>xkb->max_key_code)) ++ return NoSymbol; ++ /* Treat single group elements as present in all groups */ ++ if (XkbKeyNumGroups (xkb,kc) == 1) ++ group = 0; ++ if ((group<0)||(level<0)||(group>=XkbKeyNumGroups(xkb,kc))) ++ return NoSymbol; ++ if (level < XkbKeyGroupWidth(xkb, kc, group)) ++ ks = XkbKeySymEntry(xkb, kc, level, group); ++ else ++ ks = NoSymbol; ++ /* Treat 'K' as 'K K', */ ++ if (ks == NoSymbol && (level & 1) && level-1 < XkbKeyGroupWidth(xkb, kc, group)) ++ ks = XkbKeySymEntry(xkb, kc, level-1, group); ++ return ks; ++} ++ + /* + * Called when the rfbserver receives a rfbKeyEvent event from a client. + * Put an X keyboard event into the event queue. +@@ -134,21 +157,35 @@ void + KbdAddEvent(Bool down, KeySym keySym, rfbClientPtr cl) + { + const int type = down ? KeyPress : KeyRelease; +- KeySymsPtr keySyms; +- XkbStateRec *xkb; +- int i; ++ XkbSrvInfoPtr xkbInfo; ++ int i, group, level; + int keyCode = 0; +- int freeIndex = -1; + Bool fakeShiftPress = FALSE; + Bool fakeShiftLRelease = FALSE; + Bool fakeShiftRRelease = FALSE; + Bool shiftMustBeReleased = FALSE; + Bool shiftMustBePressed = FALSE; ++ Bool fakeLevel3Press = FALSE; ++ Bool fakeLevel3Release = FALSE; ++ Bool level3MustBeReleased = FALSE; ++ Bool level3MustBePressed = FALSE; ++ ++ /* Incomplete maps may create NoSymbol - which lets us ++ * select and/or overwrite otherwise valid entries. ++ * E.g Level3+a in serbian layout creates NoSymbol on os11.4 ++ * 2011-05-24 mhopf@suse.de */ ++ if (keySym == NoSymbol) { ++ ErrorF("KbdAddEvent: ignoring illegal NoSymbol\n"); ++ return; ++ } + +- if (!kbdDevice) +- return; +- +- keySyms = XkbGetCoreMap(kbdDevice); ++ xkbInfo = inputInfo.keyboard->key->xkbInfo; ++ group = xkbInfo->state.group; ++ level = (KEY_IS_PRESSED(ISO_LEVEL3_KEY_CODE) ? 2 : 0) | ++ (XkbStateFieldFromRec(&xkbInfo->state) & ShiftMask ? 1 : 0); ++#if 0 ++ ErrorF ("VNCkbd:\t%s Sym %04x\n", down ? "+":"-", (int)keySym); ++#endif + + #ifdef CORBA + if (cl) { +@@ -166,6 +203,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 +@@ -192,107 +235,229 @@ KbdAddEvent(Bool down, KeySym keySym, rf + } + } + #endif ++#endif + + if (!keyCode) { + + /* not one of our predefined keys - see if it's in the current keyboard + mapping (i.e. we've already allocated an extra keycode for it) */ + +- if (keySyms->mapWidth < 2) { +- ErrorF("KbdAddEvent: Sanity check failed - Keyboard mapping has " +- "less than 2 keysyms per keycode (KeySym 0x%x)\n", (int)keySym); +- return; +- } ++ for (keyCode = MIN_KEY_CODE; keyCode < MIN_KEY_CODE + NO_OF_KEYS; keyCode++) { ++ /* Check all keycodes, but only continue on those where ++ * backconversion results in keySym. ++ * 2011-05-20 mhopf@suse.de */ ++ int j; ++ ++#if 0 ++ ErrorF (" keyCode %3d map# %4d++ level %d of %d: keySyms", ++ keyCode, (i / keySyms->mapWidth) * keySyms->mapWidth, ++ i % keySyms->mapWidth, keySyms->mapWidth); ++ for (j = 0; j < keySyms->mapWidth; j++) ++ ErrorF (" %02x", (int)keySyms->map[(i / keySyms->mapWidth) * keySyms->mapWidth + j]); ++ ErrorF ("\n"); ++#endif ++#if 0 ++ ErrorF (" group %d of %d width %d: keySyms", ++ group, XkbKeyNumGroups(xkbInfo->desc, keyCode), ++ XkbKeyGroupWidth(xkbInfo->desc, keyCode, group)); ++ if (XkbKeyNumGroups(xkbInfo->desc, keyCode) > group) ++ for (j = 0; j < XkbKeyGroupWidth(xkbInfo->desc, keyCode, group); j++) ++ ErrorF (" %02x", (int) XkbKeySymEntry(xkbInfo->desc, keyCode, j, group)); ++ ErrorF ("\n"); ++#endif + +- for (i = 0; i < NO_OF_KEYS * keySyms->mapWidth; i++) { +- if (keySym == keySyms->map[i]) { +- keyCode = MIN_KEY_CODE + i / keySyms->mapWidth; +- +- if (keySyms->map[(i / keySyms->mapWidth) +- * keySyms->mapWidth + 1] != NoSymbol) { +- +- /* this keycode has more than one symbol associated with +- it, so shift state is important */ +- +- if ((i % keySyms->mapWidth) == 0) +- shiftMustBeReleased = TRUE; +- else +- shiftMustBePressed = TRUE; +- } ++ /* Check whether keySym is reachable in current group ++ * by any shift/Level3_shift state (preferrable w/o change). ++ * This doesn't do real modifyer analysis, only Shift and Level3_Shift. ++ * 2011-05-23 mhopf@suse.de */ ++ if (_XkbKeycodeToKeysym(xkbInfo->desc, keyCode, group, level) == keySym) ++ break; ++ if (_XkbKeycodeToKeysym(xkbInfo->desc, keyCode, group, level ^ 2) == keySym) { ++ if (level & 2) ++ level3MustBeReleased = TRUE; ++ else ++ level3MustBePressed = TRUE; + break; + } +- if ((freeIndex == -1) && (keySyms->map[i] == NoSymbol) +- && (i % keySyms->mapWidth) == 0) +- { +- freeIndex = i; ++ if (_XkbKeycodeToKeysym(xkbInfo->desc, keyCode, group, level ^ 1) == keySym) { ++ if (level & 1) ++ shiftMustBeReleased = TRUE; ++ else ++ shiftMustBePressed = TRUE; ++ break; ++ } ++ if (_XkbKeycodeToKeysym(xkbInfo->desc, keyCode, group, level ^ 3) == keySym) { ++ if (level & 2) ++ level3MustBeReleased = TRUE; ++ else ++ level3MustBePressed = TRUE; ++ if (level & 1) ++ shiftMustBeReleased = TRUE; ++ else ++ shiftMustBePressed = TRUE; ++ break; + } + } ++ if (keyCode == MIN_KEY_CODE + NO_OF_KEYS) ++ keyCode = 0; + } + + if (!keyCode) { + KeySym lower, upper; ++ KeySymsPtr keySyms = XkbGetCoreMap(inputInfo.keyboard); + + /* we don't have an existing keycode - make one up on the fly and add + it to the keyboard mapping. Thanks to Vlad Harchev for pointing + out problems with non-ascii capitalisation. */ + +- if (freeIndex == -1) { ++ /* Find free index for current group. */ ++ for (keyCode = MIN_KEY_CODE; keyCode < MIN_KEY_CODE + NO_OF_KEYS; keyCode++) { ++ /* A keyCode is free if no groups are assigned at all */ ++ if (XkbKeyNumGroups(xkbInfo->desc, keyCode) == 0) ++ break; ++#if 0 ++ /* We can use exact map positions for group 1+2, but only partially ++ * filling out xkb legacy maps may suddenly change the # of groups. ++ * Reason for that is unknown yet. Might be related to (fixed) NoSymbol issue. ++ * 2011-05-24 mhopf@suse.de */ ++ /* For primary groups: A keyCode is free if current group is empty */ ++ if (XkbKeyGroupWidth(xkbInfo->desc, keyCode, group) < 1 && group < 2) ++ break; ++ /* Never touch groups that have a single level only (weird group?!?) */ ++ if (XkbKeyGroupWidth(xkbInfo->desc, keyCode, group) < 2) ++ continue; ++ /* For primary groups: A keyCode is free if only NoSymbol is assigned ++ * to available levels (only validating levels 0-3) */ ++ if (group < 2 && ++ XkbKeySymEntry(xkbInfo->desc, keyCode, 0, group) == NoSymbol && ++ XkbKeySymEntry(xkbInfo->desc, keyCode, 1, group) == NoSymbol && ++ (XkbKeyGroupWidth(xkbInfo->desc, keyCode, group) < 3 || ++ (XkbKeySymEntry(xkbInfo->desc, keyCode, 2, group) == NoSymbol && ++ (XkbKeyGroupWidth(xkbInfo->desc, keyCode, group) < 4 || ++ XkbKeySymEntry(xkbInfo->desc, keyCode, 3, group) == NoSymbol)))) ++ break; ++#endif ++ } ++ ++ if (keyCode == MIN_KEY_CODE + NO_OF_KEYS) { + ErrorF("KbdAddEvent: ignoring KeySym 0x%x - no free KeyCodes\n", + (int)keySym); ++ free (keySyms->map); ++ free (keySyms); + return; + } + +- keyCode = MIN_KEY_CODE + freeIndex / keySyms->mapWidth; +- + vncXConvertCase(keySym, &lower, &upper); + +- if (lower == upper) { +- keySyms->map[freeIndex] = keySym; +- +- } else { +- keySyms->map[freeIndex] = lower; +- keySyms->map[freeIndex+1] = upper; +- ++ /* Adding keys is not using xkb mechanisms yet, but relying on support ++ * for changing keys in the legacy map. Should be changed, eventually. ++ * 2011-05-19 mhopf@suse.de */ ++#if 0 ++ if (group < 2) { ++ /* Only set mapping for active group. Will only work with dual layouts. ++ * 2011-05-23 mhopf@suse.de */ ++ int active_group_offset = group ? 2 : 0; ++ ++ if (lower == upper) { ++ keySyms->map[(keyCode - MIN_KEY_CODE) * keySyms->mapWidth + active_group_offset] = keySym; ++ keySyms->map[(keyCode - MIN_KEY_CODE) * keySyms->mapWidth + active_group_offset + 1] = NoSymbol; ++ } else { ++ keySyms->map[(keyCode - MIN_KEY_CODE) * keySyms->mapWidth + active_group_offset] = lower; ++ keySyms->map[(keyCode - MIN_KEY_CODE) * keySyms->mapWidth + active_group_offset + 1] = upper; ++ } ++ } ++#endif ++ /* Generic layouts needs to set the full map width. ++ * Weird enough, mapWidth seems too big... ++ * 2011-05-23 mhopf@suse.de */ ++ for (i = 0; i < (keySyms->mapWidth & ~1); i += 2) { ++ if (lower == upper) { ++ keySyms->map[(keyCode - MIN_KEY_CODE) * keySyms->mapWidth + i] = keySym; ++ keySyms->map[(keyCode - MIN_KEY_CODE) * keySyms->mapWidth + i + 1] = NoSymbol; ++ } else { ++ keySyms->map[(keyCode - MIN_KEY_CODE) * keySyms->mapWidth + i] = lower; ++ keySyms->map[(keyCode - MIN_KEY_CODE) * keySyms->mapWidth + i + 1] = upper; ++ } ++ } ++ if (lower != upper) { + if (keySym == lower) + shiftMustBeReleased = TRUE; + else + shiftMustBePressed = TRUE; + } ++ level3MustBeReleased = TRUE; + +- XkbApplyMappingChange(kbdDevice, keySyms, keyCode, 1, NULL, serverClient); ++ XkbApplyMappingChange(inputInfo.keyboard, keySyms, keyCode, 1, NULL, serverClient); + + ErrorF("KbdAddEvent: unknown KeySym 0x%x - allocating KeyCode %d\n", + (int)keySym, keyCode); ++ free (keySyms->map); ++ free (keySyms); + } + +- xkb = &kbdDevice->key->xkbInfo->state; ++#if 0 ++ ErrorF ("\t%s Sym %04x Code%3d\tState x%02x %s%s%s\tSh %s%s\tL3 %s%s\n", ++ down ? "+":"-", (int)keySym, keyCode, XkbStateFieldFromRec(&xkbInfo->state), ++ KEY_IS_PRESSED(SHIFT_L_KEY_CODE) ? "Sl":"", ++ KEY_IS_PRESSED(SHIFT_R_KEY_CODE) ? "Sr":"", ++ KEY_IS_PRESSED(ISO_LEVEL3_KEY_CODE) ? "L3":"", ++ shiftMustBePressed ? "+":"", shiftMustBeReleased ? "-":"", ++ level3MustBePressed ? "+":"", level3MustBeReleased ? "-":""); ++#endif ++#if 0 ++ int back = _XkbKeycodeToKeysym (xkbInfo->desc, keyCode, group, ++ ((level3MustBePressed || (!level3MustBeReleased && (level & 2))) ? 2 : 0) | ++ ((shiftMustBePressed || (!shiftMustBeReleased && (level & 1))) ? 1 : 0)); ++ ErrorF ("\tvalidate code %d %-2s%-2s -> sym %04x %s\n\n", keyCode, ++ (shiftMustBePressed || (!shiftMustBeReleased && (level & 1))) ? "Sh" : "", ++ (level3MustBePressed || (!level3MustBeReleased && (level & 2))) ? "L3" : "", ++ back, (back == keySym ? "ok" : "FAILED")); ++#endif ++ + if (down) { +- if (shiftMustBePressed && !(XkbStateFieldFromRec(xkb) & ShiftMask)) { ++ /* TODO: would require to check which keycodes are actually ++ * bound to ISO_Level3_Shift and/or Shift_L. ++ * 2011-04-18 mhopf@suse.de */ ++ if (level3MustBePressed && !(level & 2)) { ++ fakeLevel3Press = TRUE; ++ EnqueueKey(inputInfo.keyboard, KeyPress, ISO_LEVEL3_KEY_CODE); ++ } ++ if (level3MustBeReleased && (level & 2)) { ++ fakeLevel3Release = TRUE; ++ EnqueueKey(inputInfo.keyboard, KeyRelease, ISO_LEVEL3_KEY_CODE); ++ } ++ if (shiftMustBePressed && !(level & 1)) { + fakeShiftPress = TRUE; +- EnqueueKey(kbdDevice, KeyPress, SHIFT_L_KEY_CODE); ++ EnqueueKey(inputInfo.keyboard, KeyPress, SHIFT_L_KEY_CODE); + } +- if (shiftMustBeReleased && (XkbStateFieldFromRec(xkb) & ShiftMask)) { ++ if (shiftMustBeReleased && (level & 1)) { + if (KEY_IS_PRESSED(SHIFT_L_KEY_CODE)) { + fakeShiftLRelease = TRUE; +- EnqueueKey(kbdDevice, KeyRelease, SHIFT_L_KEY_CODE); ++ EnqueueKey(inputInfo.keyboard, KeyRelease, SHIFT_L_KEY_CODE); + } + if (KEY_IS_PRESSED(SHIFT_R_KEY_CODE)) { + fakeShiftRRelease = TRUE; +- EnqueueKey(kbdDevice, KeyRelease, SHIFT_R_KEY_CODE); ++ EnqueueKey(inputInfo.keyboard, KeyRelease, SHIFT_R_KEY_CODE); + } + } + } + +- EnqueueKey(kbdDevice, type, keyCode); ++ EnqueueKey(inputInfo.keyboard, type, keyCode); + + if (fakeShiftPress) { +- EnqueueKey(kbdDevice, KeyRelease, SHIFT_L_KEY_CODE); ++ EnqueueKey(inputInfo.keyboard, KeyRelease, SHIFT_L_KEY_CODE); + } + if (fakeShiftLRelease) { +- EnqueueKey(kbdDevice, KeyPress, SHIFT_L_KEY_CODE); ++ EnqueueKey(inputInfo.keyboard, KeyPress, SHIFT_L_KEY_CODE); + } + if (fakeShiftRRelease) { +- EnqueueKey(kbdDevice, KeyPress, SHIFT_R_KEY_CODE); ++ 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); + } + } + +@@ -343,15 +508,15 @@ KbdReleaseAllKeys(void) + { + int i, j; + +- if (!kbdDevice) ++ if (!inputInfo.keyboard) + return; + + for (i = 0; i < DOWN_LENGTH; i++) { +- if (kbdDevice->key->down[i] != 0) { ++ if (inputInfo.keyboard->key->down[i] != 0) { + for (j = 0; j < 8; j++) { +- if (kbdDevice->key->down[i] & (1 << j)) { ++ if (inputInfo.keyboard->key->down[i] & (1 << j)) { + int detail = (i << 3) | j; +- EnqueueKey(kbdDevice, KeyRelease, detail); ++ EnqueueKey(inputInfo.keyboard, KeyRelease, detail); + } + } + } +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, diff --git a/xorg-x11-server.changes b/xorg-x11-server.changes index a5f0fc3..60bf471 100644 --- a/xorg-x11-server.changes +++ b/xorg-x11-server.changes @@ -1,3 +1,30 @@ +------------------------------------------------------------------- +Thu May 26 14:47:53 UTC 2011 - mhopf@novell.com + +- xorg-server-xf4vnc-fix-keyboard-layout-handling.diff + Consolidate adapted patches for bugs 400520, 605015, and 660797 into + single patch: + - xorg-server-xf4vnc-bug660797-fix-keycode-lookup-and-isolevel3shift.diff + - xorg-server-xf4vnc-bug660797-multilayout.diff + - xorg-server-xf4vnc-bug605015-fix-keyboard-handling-xinput.diff +- Fix *major* memory leak introduced by original 1.9 enabling patch + +------------------------------------------------------------------- +Tue May 24 18:31:46 UTC 2011 - mhopf@novell.com + +- xorg-server-xf4vnc-bug660797-multilayout.diff + - bnc #605015, 660797, fallout of fix from May 10: + Keyboard handling was not XKB aware, which lead to a multitude of issues. + Situation with this patch is not perfect, but way better. + +------------------------------------------------------------------- +Thu May 19 17:46:39 UTC 2011 - mhopf@novell.com + +- xorg-server-xf4vnc-bug660797-fix-keycode-lookup-and-isolevel3shift.diff + - bnc #400520, fallout of previous fix: + Analysis for shift/level3 event faking was broken, leading to e.g + Shift+PgUp not being recognized correctly. + ------------------------------------------------------------------- Thu Apr 21 14:16:01 UTC 2011 - mhopf@novell.com diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec index d88eb3c..e4c7fed 100644 --- a/xorg-x11-server.spec +++ b/xorg-x11-server.spec @@ -79,8 +79,7 @@ Patch47: xorg-server-xf4vnc-clientTimeout.diff Patch48: xorg-server-xf4vnc-fix.diff Patch49: xorg-server-xf4vnc-fixes_1_8.diff Patch50: xorg-server-xf4vnc-fixes_1_9.diff -Patch51: xorg-server-xf4vnc-bug605015-fix-keyboard-handling-xinput.diff -Patch52: xorg-server-xf4vnc-bug605015-fix-keycode-lookup-and-isolevel3shift.diff +Patch51: xorg-server-xf4vnc-fix-keyboard-layout-handling.diff %endif Patch45: bug-197858_dpms.diff Patch67: xorg-docs.diff @@ -211,7 +210,6 @@ An X Window System server for Virtual Network Computing (VNC). %patch49 -p0 %patch50 -p1 %patch51 -p1 -%patch52 -p1 chmod 755 hw/vnc/symlink-vnc.sh %endif %patch45 -p0