Stefan Dirsch
ebb11289e1
- VNC patches completely redone by Egbert Eich (N-VNC-*) - Xvnc-pthread.diff: small buildfix required for factory - removed obsolete patches * EXA-mixed-ModifyPixmapHeader-pitch-fixes.-bug-33929.patch * Replace-malloc-with-calloc-to-initialize-the-buffers.patch * U_xserver_fix-pixmaps-lifetime-tracking.patch * commit-5c6a2f9.diff * pad-size-of-system-memory-copy-for-1x1-pixmaps * record-avoid-crash-when-calling-RecordFlushReplyBuff.patch * xorg-server-stop-cpu-eating.diff - adjusted patches * bug534768-prefer_local_symbols.patch * zap_warning_xserver.diff - disabled patches for now * 0001-Xinput-Catch-missing-configlayout-when-deleting-dev.patch * cache-xkbcomp-output-for-fast-start-up.patch * xserver-bg-none-root.patch * 0001-Prevent-XSync-Alarms-from-senslessly-calling-CheckTr.patch OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/xorg-x11-server?expand=0&rev=352
475 lines
16 KiB
Diff
475 lines
16 KiB
Diff
From: Matthias Hopf <mhopf@suse.de>
|
|
Date: Tue, 6 Sep 2011 08:35:57 +0200
|
|
Subject: [PATCH 5/6] VNC: Enable use of all keyboard layouts, independent of remotely set layout
|
|
Patch-Mainline: Currently no upstream project.
|
|
Git-commit: 6885b927a6065e6379cfaa3ebbf6c51445a015d9
|
|
Signed-off: Egbert Eich <eich@suse.de>
|
|
References: bnc #400520, #605015, #660797
|
|
|
|
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).
|
|
|
|
Signed-off-by: Egbert Eich <eich@freedesktop.org>
|
|
---
|
|
hw/vnc/kbdptr.c | 289 +++++++++++++++++++++++++++++++++++++++++------------
|
|
hw/vnc/keyboard.h | 1 +
|
|
2 files changed, 228 insertions(+), 62 deletions(-)
|
|
|
|
diff --git a/hw/vnc/kbdptr.c b/hw/vnc/kbdptr.c
|
|
index f306022..b3b0e68 100644
|
|
--- a/hw/vnc/kbdptr.c
|
|
+++ b/hw/vnc/kbdptr.c
|
|
@@ -34,6 +34,8 @@
|
|
#include "X11/Xproto.h"
|
|
#include "inputstr.h"
|
|
#include "inpututils.h"
|
|
+#include "xkbsrv.h"
|
|
+#include "xkbstr.h"
|
|
#define XK_CYRILLIC
|
|
#include <X11/keysym.h>
|
|
#include <X11/Xatom.h>
|
|
@@ -46,6 +48,7 @@
|
|
#include "dmxinput.h"
|
|
#endif
|
|
|
|
+#if 0
|
|
#if !XFREE86VNC
|
|
|
|
#define MIN_KEY_CODE 8
|
|
@@ -196,21 +199,20 @@ static KeySym map[MAX_KEY_CODE * GLYPHS_PER_KEY] = {
|
|
#define N_PREDEFINED_KEYS (sizeof(map) / (sizeof(KeySym) * GLYPHS_PER_KEY))
|
|
|
|
#endif
|
|
+#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
|
|
}
|
|
|
|
|
|
@@ -280,6 +282,29 @@ EnqueueKey(DeviceIntPtr kbdDev, int type, int detail)
|
|
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 ((kc<xkb->min_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.
|
|
@@ -288,21 +313,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);
|
|
+#ifdef DEBUG
|
|
+ ErrorF ("VNCkbd:\t%s Sym %04x\n", down ? "+":"-", (int)keySym);
|
|
+#endif
|
|
|
|
#ifdef CORBA
|
|
if (cl) {
|
|
@@ -320,6 +359,12 @@ KbdAddEvent(Bool down, KeySym keySym, rfbClientPtr cl)
|
|
*
|
|
* 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 */
|
|
+#ifdef NOTANYMORE
|
|
#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
|
|
@@ -346,107 +391,227 @@ KbdAddEvent(Bool down, KeySym keySym, rfbClientPtr cl)
|
|
}
|
|
}
|
|
#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 (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 */
|
|
+ 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 */
|
|
+
|
|
+#ifdef DEBUG
|
|
+ int j;
|
|
+ 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");
|
|
+ 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
|
|
|
|
- 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;
|
|
+#ifdef NOTANYMORE
|
|
+ /* 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 */
|
|
+#ifdef NOTANYMORE
|
|
+ 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;
|
|
+#ifdef DEBUG
|
|
+ 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
|
|
+#ifdef NOTANYMORE
|
|
+ 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);
|
|
}
|
|
}
|
|
|
|
@@ -497,15 +662,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/hw/vnc/keyboard.h b/hw/vnc/keyboard.h
|
|
index d223b6b..beb948a 100644
|
|
--- a/hw/vnc/keyboard.h
|
|
+++ b/hw/vnc/keyboard.h
|
|
@@ -32,3 +32,4 @@
|
|
#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
|
|
--
|
|
1.7.3.4
|
|
|