Ken Thomases : winex11.drv: Fix X11DRV_KeymapNotify when multiple keycodes map to same vkey.
Alexandre Julliard
julliard at winehq.org
Wed Jul 13 12:16:33 CDT 2011
Module: wine
Branch: master
Commit: c4daf281865c494c7e7dba0901eeebacef4cae29
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c4daf281865c494c7e7dba0901eeebacef4cae29
Author: Ken Thomases <ken at codeweavers.com>
Date: Wed Jul 13 06:03:43 2011 -0500
winex11.drv: Fix X11DRV_KeymapNotify when multiple keycodes map to same vkey.
---
dlls/winex11.drv/keyboard.c | 46 ++++++++++++++++++++++++++++++++----------
1 files changed, 35 insertions(+), 11 deletions(-)
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index 42ca462..5648d79 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1189,9 +1189,17 @@ void X11DRV_KeymapNotify( HWND hwnd, XEvent *event )
int i, j;
DWORD time = GetCurrentTime();
BYTE keystate[256];
+ WORD vkey;
+ struct {
+ WORD vkey;
+ WORD scan;
+ BOOL pressed;
+ } modifiers[6]; /* VK_LSHIFT through VK_RMENU are contiguous */
if (!get_async_key_state( keystate )) return;
+ memset(modifiers, 0, sizeof(modifiers));
+
/* the minimum keycode is always greater or equal to 8, so we can
* skip the first 8 values, hence start at 1
*/
@@ -1199,7 +1207,9 @@ void X11DRV_KeymapNotify( HWND hwnd, XEvent *event )
{
for (j = 0; j < 8; j++)
{
- WORD vkey = keyc2vkey[(i * 8) + j];
+ int m;
+
+ vkey = keyc2vkey[(i * 8) + j];
switch(vkey & 0xff)
{
@@ -1209,22 +1219,36 @@ void X11DRV_KeymapNotify( HWND hwnd, XEvent *event )
case VK_RCONTROL:
case VK_LSHIFT:
case VK_RSHIFT:
- if (!(keystate[vkey & 0xff] & 0x80) != !(event->xkeymap.key_vector[i] & (1<<j)))
+ m = (vkey & 0xff) - VK_LSHIFT;
+ /* Take the vkey and scan from the first keycode we encounter
+ for this modifier. */
+ if (!modifiers[m].vkey)
{
- WORD scan = keyc2scan[(i * 8) + j];
- DWORD flags = vkey & 0x100 ? KEYEVENTF_EXTENDEDKEY : 0;
- if (!(event->xkeymap.key_vector[i] & (1<<j))) flags |= KEYEVENTF_KEYUP;
-
- TRACE( "Adjusting state for vkey %#.2x. State before %#.2x\n",
- vkey, keystate[vkey & 0xff]);
-
- /* Fake key being pressed inside wine */
- X11DRV_send_keyboard_input( hwnd, vkey & 0xff, scan & 0xff, flags, time );
+ modifiers[m].vkey = vkey;
+ modifiers[m].scan = keyc2scan[(i * 8) + j];
}
+ if (event->xkeymap.key_vector[i] & (1<<j))
+ modifiers[m].pressed = TRUE;
break;
}
}
}
+
+ for (vkey = VK_LSHIFT; vkey <= VK_RMENU; vkey++)
+ {
+ int m = vkey - VK_LSHIFT;
+ if (modifiers[m].vkey && !(keystate[vkey] & 0x80) != !modifiers[m].pressed)
+ {
+ DWORD flags = modifiers[m].vkey & 0x100 ? KEYEVENTF_EXTENDEDKEY : 0;
+ if (!modifiers[m].pressed) flags |= KEYEVENTF_KEYUP;
+
+ TRACE( "Adjusting state for vkey %#.2x. State before %#.2x\n",
+ modifiers[m].vkey, keystate[vkey]);
+
+ /* Fake key being pressed inside wine */
+ X11DRV_send_keyboard_input( hwnd, vkey, modifiers[m].scan & 0xff, flags, time );
+ }
+ }
}
static void update_lock_state( HWND hwnd, WORD vkey, UINT state, DWORD time )
More information about the wine-cvs
mailing list