Commit c2bc0e21 authored by Ken Thomases's avatar Ken Thomases Committed by Alexandre Julliard

winex11: Bias MapVirtualKeyEx(MAPVK_VSC_TO_VK) against numpad vkeys.

The scan codes for the numeric keypad keys and those for the arrow keys and keys like Home, End, etc. often match (ignoring the extended key bit). However, if you map from one of those scan codes to a vkey, Windows reliably prefers the non-numpad vkey.
parent 1dcaddee
...@@ -1115,6 +1115,18 @@ static void test_key_map(void) ...@@ -1115,6 +1115,18 @@ static void test_key_map(void)
{ {
HKL kl = GetKeyboardLayout(0); HKL kl = GetKeyboardLayout(0);
UINT kL, kR, s, sL; UINT kL, kR, s, sL;
int i;
static const UINT numpad_collisions[][2] = {
{ VK_NUMPAD0, VK_INSERT },
{ VK_NUMPAD1, VK_END },
{ VK_NUMPAD2, VK_DOWN },
{ VK_NUMPAD3, VK_NEXT },
{ VK_NUMPAD4, VK_LEFT },
{ VK_NUMPAD6, VK_RIGHT },
{ VK_NUMPAD7, VK_HOME },
{ VK_NUMPAD8, VK_UP },
{ VK_NUMPAD9, VK_PRIOR },
};
s = MapVirtualKeyEx(VK_SHIFT, MAPVK_VK_TO_VSC, kl); s = MapVirtualKeyEx(VK_SHIFT, MAPVK_VK_TO_VSC, kl);
ok(s != 0, "MapVirtualKeyEx(VK_SHIFT) should return non-zero\n"); ok(s != 0, "MapVirtualKeyEx(VK_SHIFT) should return non-zero\n");
...@@ -1130,6 +1142,22 @@ static void test_key_map(void) ...@@ -1130,6 +1142,22 @@ static void test_key_map(void)
ok(kL == VK_LSHIFT, "Scan code -> vKey = %x (not VK_LSHIFT)\n", kL); ok(kL == VK_LSHIFT, "Scan code -> vKey = %x (not VK_LSHIFT)\n", kL);
kR = MapVirtualKeyEx(0x36, MAPVK_VSC_TO_VK_EX, kl); kR = MapVirtualKeyEx(0x36, MAPVK_VSC_TO_VK_EX, kl);
ok(kR == VK_RSHIFT, "Scan code -> vKey = %x (not VK_RSHIFT)\n", kR); ok(kR == VK_RSHIFT, "Scan code -> vKey = %x (not VK_RSHIFT)\n", kR);
/* test that MAPVK_VSC_TO_VK prefers the non-numpad vkey if there's ambiguity */
for (i = 0; i < sizeof(numpad_collisions)/sizeof(numpad_collisions[0]); i++)
{
UINT numpad_scan = MapVirtualKeyEx(numpad_collisions[i][0], MAPVK_VK_TO_VSC, kl);
UINT other_scan = MapVirtualKeyEx(numpad_collisions[i][1], MAPVK_VK_TO_VSC, kl);
/* do they really collide for this layout? */
if (numpad_scan && other_scan == numpad_scan)
{
UINT vkey = MapVirtualKeyEx(numpad_scan, MAPVK_VSC_TO_VK, kl);
ok(vkey != numpad_collisions[i][0],
"Got numpad vKey %x for scan code %x when there was another choice\n",
vkey, numpad_scan);
}
}
} }
START_TEST(input) START_TEST(input)
......
...@@ -2082,19 +2082,25 @@ UINT X11DRV_MapVirtualKeyEx(UINT wCode, UINT wMapType, HKL hkl) ...@@ -2082,19 +2082,25 @@ UINT X11DRV_MapVirtualKeyEx(UINT wCode, UINT wMapType, HKL hkl)
case MAPVK_VSC_TO_VK_EX: case MAPVK_VSC_TO_VK_EX:
{ {
int keyc; int keyc;
UINT vkey; UINT vkey = 0;
/* let's do scan -> keycode -> vkey */ /* let's do scan -> keycode -> vkey */
for (keyc = min_keycode; keyc <= max_keycode; keyc++) for (keyc = min_keycode; keyc <= max_keycode; keyc++)
if ((keyc2scan[keyc] & 0xFF) == (wCode & 0xFF)) break; if ((keyc2scan[keyc] & 0xFF) == (wCode & 0xFF))
{
vkey = keyc2vkey[keyc] & 0xFF;
/* Only stop if it's not a numpad vkey; otherwise keep
looking for a potential better vkey. */
if (vkey && (vkey < VK_NUMPAD0 || VK_DIVIDE < vkey))
break;
}
if (keyc > max_keycode) if (vkey == 0)
{ {
TRACE("returning no vkey-code.\n"); TRACE("returning no vkey-code.\n");
return 0; return 0;
} }
vkey = keyc2vkey[keyc] & 0xFF;
if (wMapType == MAPVK_VSC_TO_VK) if (wMapType == MAPVK_VSC_TO_VK)
switch (vkey) switch (vkey)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment