Module: wine Branch: master Commit: 10556c25e468768d1422e872f16dbc1ae85ef968 URL: http://source.winehq.org/git/wine.git/?a=commit;h=10556c25e468768d1422e872f1...
Author: Huw Davies huw@codeweavers.com Date: Thu May 28 11:35:05 2015 +0100
winex11: Fix ctrl-<symbol> to generate codes below 0x20 where necessary.
---
dlls/user32/tests/input.c | 94 +++++++++++++++++++++++++++++++++++---------- dlls/winex11.drv/keyboard.c | 16 ++++++-- 2 files changed, 85 insertions(+), 25 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 29b655c..cb130e8 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -1587,6 +1587,56 @@ static void test_key_map(void) } }
+#define shift 1 +#define ctrl 2 + +static const struct tounicode_tests +{ + UINT vk; + DWORD modifiers; + WCHAR chr; /* if vk is 0, lookup vk using this char */ + int expect_ret; + WCHAR expect_buf[4]; +} utests[] = +{ + { 'A', 0, 0, 1, {'a',0}}, + { 'A', ctrl, 0, 1, {1, 0}}, + { 'A', shift|ctrl, 0, 1, {1, 0}}, + { VK_TAB, ctrl, 0, 0, {}}, + { VK_TAB, shift|ctrl, 0, 0, {}}, + { VK_RETURN, ctrl, 0, 1, {'\n', 0}}, + { VK_RETURN, shift|ctrl, 0, 0, {}}, + { '4', ctrl, 0, 0, {}}, + { '4', shift|ctrl, 0, 0, {}}, + { 0, ctrl, '!', 0, {}}, + { 0, ctrl, '"', 0, {}}, + { 0, ctrl, '#', 0, {}}, + { 0, ctrl, '$', 0, {}}, + { 0, ctrl, '%', 0, {}}, + { 0, ctrl, ''', 0, {}}, + { 0, ctrl, '(', 0, {}}, + { 0, ctrl, ')', 0, {}}, + { 0, ctrl, '*', 0, {}}, + { 0, ctrl, '+', 0, {}}, + { 0, ctrl, ',', 0, {}}, + { 0, ctrl, '-', 0, {}}, + { 0, ctrl, '.', 0, {}}, + { 0, ctrl, '/', 0, {}}, + { 0, ctrl, ':', 0, {}}, + { 0, ctrl, ';', 0, {}}, + { 0, ctrl, '<', 0, {}}, + { 0, ctrl, '=', 0, {}}, + { 0, ctrl, '>', 0, {}}, + { 0, ctrl, '?', 0, {}}, + { 0, ctrl, '@', 1, {0}}, + { 0, ctrl, '[', 1, {0x1b}}, + { 0, ctrl, '\', 1, {0x1c}}, + { 0, ctrl, ']', 1, {0x1d}}, + { 0, ctrl, '^', 1, {0x1e}}, + { 0, ctrl, '_', 1, {0x1f}}, + { 0, ctrl, '`', 0, {}}, +}; + static void test_ToUnicode(void) { WCHAR wStr[4]; @@ -1614,30 +1664,32 @@ static void test_ToUnicode(void) "ToUnicode didn't null-terminate the buffer when there was room.\n"); }
- ret = ToUnicode('A', SC_A, state, wStr, 4, 0); - ok(ret == 1, "ToUnicode for character A didn't return 1 (was %i)\n", ret); - ok(wStr[0] == 'a', "ToUnicode for character 'A' was %i (expected %i)\n", wStr[0], 'a'); + for (i = 0; i < sizeof(utests) / sizeof(utests[0]); i++) + { + UINT vk = utests[i].vk, mod = utests[i].modifiers, scan;
- state[VK_CONTROL] |= HIGHEST_BIT; - state[VK_LCONTROL] |= HIGHEST_BIT; - ret = ToUnicode(VK_TAB, SC_TAB, state, wStr, 2, 0); - ok(ret == 0, "ToUnicode for CTRL + Tab didn't return 0 (was %i)\n", ret); + if(!vk) + { + short vk_ret = VkKeyScanW(utests[i].chr); + if (vk_ret == -1) continue; + vk = vk_ret & 0xff; + if (vk_ret & 0x100) mod |= shift; + if (vk_ret & 0x200) mod |= ctrl; + } + scan = MapVirtualKeyW(vk, MAPVK_VK_TO_VSC);
- ret = ToUnicode(VK_RETURN, SC_RETURN, state, wStr, 2, 0); - ok(ret == 1, "ToUnicode for CTRL + Return didn't return 1 (was %i)\n", ret); - if(ret == 1) - ok(wStr[0]=='\n', "ToUnicode for CTRL + Return was %i (expected 10)\n", wStr[0]); + state[VK_SHIFT] = state[VK_LSHIFT] = (mod & shift) ? HIGHEST_BIT : 0; + state[VK_CONTROL] = state[VK_LCONTROL] = (mod & ctrl) ? HIGHEST_BIT : 0;
- ret = ToUnicode('A', SC_A, state, wStr, 4, 0); - ok(ret == 1, "ToUnicode for CTRL + character A didn't return 1 (was %i)\n", ret); - ok(wStr[0] == 1, "ToUnicode for CTRL + character 'A' was %i (expected 1)\n", wStr[0]); + ret = ToUnicode(vk, scan, state, wStr, 4, 0); + ok(ret == utests[i].expect_ret, "%d: got %d expected %d\n", i, ret, utests[i].expect_ret); + if (ret) + ok(!lstrcmpW(wStr, utests[i].expect_buf), "%d: got %s expected %s\n", i, wine_dbgstr_w(wStr), + wine_dbgstr_w(utests[i].expect_buf));
- state[VK_SHIFT] |= HIGHEST_BIT; - state[VK_LSHIFT] |= HIGHEST_BIT; - ret = ToUnicode(VK_TAB, SC_TAB, state, wStr, 2, 0); - ok(ret == 0, "ToUnicode for CTRL + SHIFT + Tab didn't return 0 (was %i)\n", ret); - ret = ToUnicode(VK_RETURN, SC_RETURN, state, wStr, 2, 0); - todo_wine ok(ret == 0, "ToUnicode for CTRL + SHIFT + Return didn't return 0 (was %i)\n", ret); + } + state[VK_SHIFT] = state[VK_LSHIFT] = 0; + state[VK_CONTROL] = state[VK_LCONTROL] = 0;
ret = ToUnicode(VK_TAB, SC_TAB, NULL, wStr, 4, 0); ok(ret == 0, "ToUnicode with NULL keystate didn't return 0 (was %i)\n", ret); @@ -1688,7 +1740,7 @@ static void test_ToAscii(void) state[VK_SHIFT] |= HIGHEST_BIT; state[VK_LSHIFT] |= HIGHEST_BIT; ret = ToAscii(VK_RETURN, SC_RETURN, state, &character, 0); - todo_wine ok(ret == 0, "ToAscii for CTRL + Shift + Return key didn't return 0 (was %i)\n", ret); + ok(ret == 0, "ToAscii for CTRL + Shift + Return key didn't return 0 (was %i)\n", ret);
ret = ToAscii(VK_RETURN, SC_RETURN, NULL, &character, 0); ok(ret == 0, "ToAscii for NULL keystate didn't return 0 (was %i)\n", ret); diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index 1323e19..b0f5b95 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c @@ -2664,8 +2664,8 @@ INT CDECL X11DRV_ToUnicodeEx(UINT virtKey, UINT scanCode, const BYTE *lpKeyState CTRL + number or CTRL + symbol */ if (e.state & ControlMask) { - if (((keysym>=33) && (keysym < 'A')) || - ((keysym > 'Z') && (keysym < 'a')) || + if (((keysym>=33) && (keysym < '@')) || + (keysym == '`') || (keysym == XK_Tab)) { lpChar[0] = 0; @@ -2689,8 +2689,16 @@ INT CDECL X11DRV_ToUnicodeEx(UINT virtKey, UINT scanCode, const BYTE *lpKeyState else if((lpKeyState[VK_CONTROL] & 0x80) /* Control is pressed */ && (keysym == XK_Return || keysym == XK_KP_Enter)) { - lpChar[0] = '\n'; - ret = 1; + if (lpKeyState[VK_SHIFT] & 0x80) + { + lpChar[0] = 0; + ret = 0; + } + else + { + lpChar[0] = '\n'; + ret = 1; + } }
/* Hack to detect an XLookupString hard-coded to Latin1 */