From: Alexandros Frantzis alexandros.frantzis@collabora.com
--- dlls/user32/tests/input.c | 122 ++++++++++++++++++++++++++++++++++---- 1 file changed, 112 insertions(+), 10 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 527ee6d8785..66a6c63f625 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -707,11 +707,13 @@ static void get_test_scan( WORD vkey, WORD *scan, WCHAR *wch, WCHAR *wch_shift ) ok_ret( 1, ToUnicodeEx( vkey, *scan, state, wch_shift, 1, 0, hkl ) );
/* zh_CN returns a different WM_(SYS)CHAR, possibly coming from IME */ + /* if (HIWORD(hkl) == 0x0804) { *wch = 0x430; *wch_shift = 0x410; } + */ }
static void test_SendInput_keyboard_messages( WORD vkey, WORD scan, WCHAR wch, WCHAR wch_shift, WCHAR wch_control ) @@ -1072,10 +1074,7 @@ static void test_SendInput_keyboard_messages( WORD vkey, WORD scan, WCHAR wch, W {.scan = 0x36, .flags = KEYEVENTF_SCANCODE, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80}, .expect = {KEY_HOOK(WM_KEYDOWN, 0x36, VK_RSHIFT), KEY_MSG(WM_KEYDOWN, 0x36, VK_SHIFT), {0}}}, {.scan = scan, .flags = KEYEVENTF_SCANCODE, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80, /*[vkey] = 0x80*/}, - /* TODO: Remove the WM_CHAR todo once the Win10 Chinese testbot works properly. - * We only mark this as todo because for zh_CN we use custom wch/wch_shift values - * (see get_test_scan()) to appease the Win10 testbot, causing failure on Linux. */ - .expect = {KEY_HOOK(WM_KEYDOWN, scan, vkey), KEY_MSG(WM_KEYDOWN, scan, vkey), WIN_MSG(WM_CHAR, wch_shift, MAKELONG(1, scan), .todo_value = TRUE), {0}}}, + .expect = {KEY_HOOK(WM_KEYDOWN, scan, vkey), KEY_MSG(WM_KEYDOWN, scan, vkey), WIN_MSG(WM_CHAR, wch_shift, MAKELONG(1, scan)), {0}}}, {.scan = scan, .flags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80}, .expect = {KEY_HOOK(WM_KEYUP, scan, vkey), KEY_MSG(WM_KEYUP, scan, vkey), {0}}}, {.scan = 0x36, .flags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP, @@ -1169,11 +1168,12 @@ static void test_SendInput_keyboard_messages( WORD vkey, WORD scan, WCHAR wch, W HHOOK hook; HWND hwnd;
+ trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); /* on 32-bit with ALTGR keyboard, the CONTROL key is sent to the hooks without the * LLKHF_INJECTED flag, skip the tests to keep it simple */ if (altgr && sizeof(void *) == 4 && !is_wow64) skip_altgr = TRUE;
- hwnd = CreateWindowW( L"static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL ); + hwnd = CreateWindowW( L"test_ignore_langchange", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL ); ok_ne( NULL, hwnd, HWND, "%p" ); wait_messages( 100, FALSE );
@@ -1193,38 +1193,63 @@ static void test_SendInput_keyboard_messages( WORD vkey, WORD scan, WCHAR wch, W
/* test peeked messages */ winetest_push_context( "peek" ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( lmenu_vkey_peeked, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( lcontrol_vkey, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( lmenu_lcontrol_vkey, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( shift_vkey, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( rshift, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( lshift_ext, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( rshift_ext, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( shift, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( shift_ext, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( rcontrol, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( lcontrol_ext, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( rcontrol_ext, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( control, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( control_ext, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); if (skip_altgr) skip( "skipping rmenu_altgr test\n" ); else if (altgr) check_send_input_keyboard_test( rmenu_altgr, TRUE ); else check_send_input_keyboard_test( rmenu_peeked, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( lmenu_ext_peeked, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); if (skip_altgr) skip( "skipping rmenu_ext_altgr test\n" ); else if (altgr) check_send_input_keyboard_test( rmenu_ext_altgr, TRUE ); else check_send_input_keyboard_test( rmenu_ext_peeked, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( menu_peeked, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); if (skip_altgr) skip( "skipping menu_ext_altgr test\n" ); else if (altgr) check_send_input_keyboard_test( menu_ext_altgr, TRUE ); else check_send_input_keyboard_test( menu_ext_peeked, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( lrshift_ext, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( rshift_scan, TRUE ); - /* TODO: The Win10 Japanese testbot setup is misbehaving, skip for now. */ - if (LOWORD(hkl) != 0x0411) check_send_input_keyboard_test( rctrl_scan, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); + check_send_input_keyboard_test( rctrl_scan, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( unicode, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( lmenu_unicode_peeked, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); check_send_input_keyboard_test( unicode_vkey, TRUE ); + trace( "hkl=%p\n", GetKeyboardLayout( 0 ) ); winetest_pop_context();
wait_messages( 100, FALSE ); @@ -1262,8 +1287,7 @@ static void test_SendInput_keyboard_messages( WORD vkey, WORD scan, WCHAR wch, W else check_send_input_keyboard_test( menu_ext, FALSE ); check_send_input_keyboard_test( lrshift_ext, FALSE ); check_send_input_keyboard_test( rshift_scan, FALSE ); - /* TODO: The Win10 Japanese testbot setup is misbehaving, skip for now. */ - if (LOWORD(hkl) != 0x0411) check_send_input_keyboard_test( rctrl_scan, FALSE ); + check_send_input_keyboard_test( rctrl_scan, FALSE ); check_send_input_keyboard_test( unicode, FALSE ); check_send_input_keyboard_test( lmenu_unicode, FALSE ); check_send_input_keyboard_test( unicode_vkey, FALSE ); @@ -4885,31 +4909,40 @@ static void test_SendInput( WORD vkey, WCHAR wch ) UINT res, i; HWND hwnd;
- hwnd = CreateWindowW( L"static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL ); + trace( "hkl=%p before create window\n", GetKeyboardLayout ( 0 ) ); + hwnd = CreateWindowW( L"test_ignore_langchange", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL ); + trace( "hkl=%p after create window\n", GetKeyboardLayout ( 0 ) ); ok_ne( NULL, hwnd, HWND, "%p" ); wait_messages( 100, FALSE ); + trace( "hkl=%p after create window messages\n", GetKeyboardLayout ( 0 ) );
SetLastError( 0xdeadbeef ); ok_ret( 0, SendInput( 0, NULL, 0 ) ); ok_ret( ERROR_INVALID_PARAMETER, GetLastError() ); + trace( "hkl=%p\n", GetKeyboardLayout ( 0 ) ); SetLastError( 0xdeadbeef ); ok_ret( 0, SendInput( 1, NULL, 0 ) ); ok_ret( ERROR_INVALID_PARAMETER, GetLastError() ); + trace( "hkl=%p\n", GetKeyboardLayout ( 0 ) ); SetLastError( 0xdeadbeef ); ok_ret( 0, SendInput( 1, NULL, sizeof(*input) ) ); ok( GetLastError() == ERROR_NOACCESS || GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError returned %#lx\n", GetLastError() ); + trace( "hkl=%p\n", GetKeyboardLayout ( 0 ) ); SetLastError( 0xdeadbeef ); ok_ret( 0, SendInput( 0, input, sizeof(*input) ) ); ok_ret( ERROR_INVALID_PARAMETER, GetLastError() ); + trace( "hkl=%p\n", GetKeyboardLayout ( 0 ) ); SetLastError( 0xdeadbeef ); ok_ret( 0, SendInput( 0, NULL, sizeof(*input) ) ); ok_ret( ERROR_INVALID_PARAMETER, GetLastError() );
+ trace( "hkl=%p\n", GetKeyboardLayout ( 0 ) ); memset( input, 0, sizeof(input) ); SetLastError( 0xdeadbeef ); ok_ret( 1, SendInput( 1, input, sizeof(*input) ) ); ok_ret( 0xdeadbeef, GetLastError() ); + trace( "hkl=%p\n", GetKeyboardLayout ( 0 ) ); SetLastError( 0xdeadbeef ); ok_ret( 16, SendInput( 16, input, sizeof(*input) ) ); ok_ret( 0xdeadbeef, GetLastError() ); @@ -4917,17 +4950,21 @@ static void test_SendInput( WORD vkey, WCHAR wch ) SetLastError( 0xdeadbeef ); ok_ret( 0, SendInput( 1, input, 0 ) ); ok_ret( ERROR_INVALID_PARAMETER, GetLastError() ); + trace( "hkl=%p\n", GetKeyboardLayout ( 0 ) ); SetLastError( 0xdeadbeef ); ok_ret( 0, SendInput( 1, input, sizeof(*input) + 1 ) ); ok_ret( ERROR_INVALID_PARAMETER, GetLastError() ); + trace( "hkl=%p\n", GetKeyboardLayout ( 0 ) ); SetLastError( 0xdeadbeef ); ok_ret( 0, SendInput( 1, input, sizeof(*input) - 1 ) ); ok_ret( ERROR_INVALID_PARAMETER, GetLastError() );
+ trace( "hkl=%p\n", GetKeyboardLayout ( 0 ) ); for (i = 0; i < ARRAY_SIZE(input); ++i) input[i].type = INPUT_KEYBOARD; SetLastError( 0xdeadbeef ); ok_ret( 0, SendInput( 16, input, offsetof( INPUT, ki ) + sizeof(KEYBDINPUT) ) ); ok_ret( ERROR_INVALID_PARAMETER, GetLastError() ); + trace( "hkl=%p\n", GetKeyboardLayout ( 0 ) ); SetLastError( 0xdeadbeef ); ok_ret( 16, SendInput( 16, input, sizeof(*input) ) ); ok_ret( 0xdeadbeef, GetLastError() ); @@ -4940,6 +4977,7 @@ static void test_SendInput( WORD vkey, WCHAR wch ) wait_messages( 100, FALSE ); ok_seq( empty_sequence ); p_accept_message = is_keyboard_message; + trace( "hkl=%p\n", GetKeyboardLayout ( 0 ) );
input[0].hi.uMsg = WM_KEYDOWN; input[0].hi.wParamL = 0; @@ -4955,6 +4993,7 @@ static void test_SendInput( WORD vkey, WCHAR wch ) wait_messages( 100, TRUE ); ok_seq( empty_sequence );
+ trace( "hkl=%p\n", GetKeyboardLayout ( 0 ) ); memset( input, 0, sizeof(input) ); input[0].type = INPUT_HARDWARE; input[1].type = INPUT_KEYBOARD; @@ -4972,6 +5011,7 @@ static void test_SendInput( WORD vkey, WCHAR wch ) if (broken(res == 16)) ok_seq( broken_sequence ); else ok_seq( empty_sequence );
+ trace( "hkl=%p\n", GetKeyboardLayout ( 0 ) ); for (i = 0; i < ARRAY_SIZE(input); ++i) input[i].type = INPUT_HARDWARE + 1; SetLastError( 0xdeadbeef ); ok_ret( 16, SendInput( 16, input, sizeof(*input) ) ); @@ -4983,6 +5023,7 @@ static void test_SendInput( WORD vkey, WCHAR wch ) wait_messages( 100, FALSE ); ok_seq( empty_sequence ); p_accept_message = NULL; + trace( "hkl=%p\n", GetKeyboardLayout ( 0 ) ); }
#define check_pointer_info( a, b ) check_pointer_info_( __LINE__, a, b ) @@ -5697,6 +5738,32 @@ static void test_LoadKeyboardLayoutEx(void) ok_eq( old_hkl, GetKeyboardLayout( 0 ), HKL, "%p" ); }
+static LRESULT WINAPI ignore_langchange_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + LRESULT res; + HKL hkl = GetKeyboardLayout ( 0 ); + trace( "hwnd %p msg 0x%04x wp %p lp %p\n", hwnd, message, (void*)wParam, (void*)lParam); + if (message == WM_INPUTLANGCHANGEREQUEST) + { + trace( "hwnd %p got langchange_request hkl=%08x, ignoring\n", hwnd, (int)lParam); + return 0; + } + if (message == WM_INPUTLANGCHANGE) + { + trace( "hwnd %p got langchange hkl=%08x, ignoring\n", hwnd, (int)lParam); + return 0; + } + + res = DefWindowProcA(hwnd, message, wParam, lParam); + + if (hkl != GetKeyboardLayout ( 0 )) + { + trace( "hwnd %p msg 0x%04x wp %p lp %p: changed layout %p -> %p\n", + hwnd, message, (void*)wParam, (void*)lParam, hkl, GetKeyboardLayout ( 0 )); + } + + return res; +} /* run the tests in a separate desktop to avoid interaction with other * tests, current desktop state, or user actions. */ static void test_input_desktop( char **argv ) @@ -5705,13 +5772,38 @@ static void test_input_desktop( char **argv ) WCHAR wch, wch_shift; POINT pos; WORD scan; + BYTE prefmask[8] = {0}; + DWORD prefmask_size = 8; + WNDCLASSW cls = + { + .lpfnWndProc = ignore_langchange_wndproc, + .hInstance = GetModuleHandleW( NULL ), + .hbrBackground = GetStockObject( WHITE_BRUSH ), + .lpszClassName = L"test_ignore_langchange", + }; + ATOM class; + BOOL ret; + + class = RegisterClassW( &cls ); + ok( class, "RegisterClassW failed: %lu\n", GetLastError() );
trace( "hkl %p\n", hkl ); ok_ret( 1, GetCursorPos( &pos ) ); test_SetCursorPos();
+ RegGetValueW(HKEY_CURRENT_USER, L"Control Panel\Desktop", + L"UserPreferencesMask", RRF_RT_REG_BINARY, NULL, + (void *)prefmask, &prefmask_size); + trace( "mask=%02x %02x %02x %02x %02x %02x %02x %02x\n", + prefmask[0], prefmask[1], prefmask[2], prefmask[3], + prefmask[4], prefmask[5], prefmask[6], prefmask[7]); + trace( "per-window-layout=%d\n", !!(prefmask[4] & 0x80)); + + trace( "hkl=%p\n", GetKeyboardLayout ( 0 ) ); get_test_scan( 'F', &scan, &wch, &wch_shift ); + trace( "hkl=%p\n", GetKeyboardLayout ( 0 ) ); test_SendInput( 'F', wch ); + trace( "hkl=%p\n", GetKeyboardLayout ( 0 ) ); test_SendInput_keyboard_messages( 'F', scan, wch, wch_shift, '\x06' ); test_SendInput_mouse_messages();
@@ -5724,6 +5816,9 @@ static void test_input_desktop( char **argv ) test_LoadKeyboardLayoutEx();
ok_ret( 1, SetCursorPos( pos.x, pos.y ) ); + + ret = UnregisterClassW( L"test_ignore_langchange", GetModuleHandleW( NULL ) ); + ok( ret, "UnregisterClassW failed: %lu\n", GetLastError() ); }
static void test_keyboard_layout(void) @@ -5756,10 +5851,16 @@ START_TEST(input) char **argv; int argc; POINT pos; + HKL layouts[32] = {0}; + int i;
init_function_pointers(); GetCursorPos( &pos );
+ GetKeyboardLayoutList(31, layouts); + trace("pid=%lx\n", (LONG)GetCurrentProcessId()); + for (i = 0; i < 32 && layouts[i]; ++i) trace("hkl[%d]=%p\n", i, layouts[i]); + argc = winetest_get_mainargs(&argv); if (argc >= 3 && !strcmp( argv[2], "rawinput_test" )) return rawinput_test_process(); @@ -5776,6 +5877,7 @@ START_TEST(input) if (argc >= 3 && !strcmp( argv[2], "test_input_desktop" )) return test_input_desktop( argv );
+ run_in_desktop( argv, "test_input_desktop", 1 ); test_keynames(); test_key_map();