winex11.drv: Fix X11DRV_KeymapNotify when multiple keycodes map to same vkey.

This commit is contained in:
Ken Thomases 2011-07-13 06:03:43 -05:00 committed by Alexandre Julliard
parent c7a8ff26d3
commit c4daf28186
1 changed files with 35 additions and 11 deletions

View File

@ -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 )