From: Alexandros Frantzis alexandros.frantzis@collabora.com
--- dlls/user32/tests/input.c | 129 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 9196e67c15b..31d7f1fad35 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -3165,6 +3165,132 @@ static void test_rawinput(const char* argv0) CloseDesktop(params.desk); }
+static void rawinput_test_keyboard_process(void) +{ + HANDLE start, done; + INPUT input = {.type = INPUT_KEYBOARD, .ki.wVk = 'A', .ki.wScan = 1}; + int i; + + start = OpenEventA( EVENT_ALL_ACCESS, FALSE, "rawinput_test_keyboard_process_start" ); + ok( start != 0, "OpenEventA failed, error: %lu\n", GetLastError() ); + done = OpenEventA( EVENT_ALL_ACCESS, FALSE, "rawinput_test_keyboard_process_done" ); + ok( done != 0, "OpenEventA failed, error: %lu\n", GetLastError() ); + + for (i = 0; i < 3; ++i) + { + WaitForSingleObject( start, INFINITE ); + input.ki.dwFlags = 0; + ok_ret( 1, SendInput( 1, &input, sizeof(input) ) ); + SetEvent( done ); + + WaitForSingleObject( start, INFINITE ); + input.ki.dwFlags = KEYEVENTF_KEYUP; + ok_ret( 1, SendInput( 1, &input, sizeof(input) ) ); + SetEvent( done ); + } +} + +static void test_rawinput_keyboard( const char* argv0 ) +{ +#define RAW_KEY(s, f, v, m, ...) {.func = RAW_INPUT_KEYBOARD, .raw_input.kbd = {.MakeCode = s, .Flags = f, .VKey = v, .Message = m}, ## __VA_ARGS__} + struct send_input_keyboard_test raw_test[] = + { + {.expect = {RAW_KEY(1, RI_KEY_MAKE, 'A', WM_KEYDOWN), {0, .todo = TRUE}}, .expect_async = {['A'] = 0x80}}, + {.expect = {RAW_KEY(1, RI_KEY_BREAK, 'A', WM_KEYUP), {0, .todo = TRUE}}}, + }; + struct send_input_keyboard_test raw_test_no_focus[] = + { + {.expect = {RAW_KEY(1, RI_KEY_MAKE, 'A', WM_KEYDOWN, .todo = TRUE), {0, .todo = TRUE}}, .expect_async = {['A'] = 0x80}}, + {.expect = {RAW_KEY(1, RI_KEY_BREAK, 'A', WM_KEYUP, .todo = TRUE), {0, .todo = TRUE}}}, + }; + struct send_input_keyboard_test raw_test_no_fg[] = {{.expect_async = {['A'] = 0x80}}, {}}; +#undef RAW_KEY + + STARTUPINFOA startup_info = {.cb = sizeof(STARTUPINFOA)}; + PROCESS_INFORMATION process_info; + RAWINPUTDEVICE raw_devices[1]; + HANDLE process_start, process_done; + DWORD ret; + HWND hwnd; + int i; + char path[MAX_PATH]; + + process_start = CreateEventA( NULL, FALSE, FALSE, "rawinput_test_keyboard_process_start" ); + ok( process_start != NULL, "CreateEventA failed\n"); + process_done = CreateEventA( NULL, FALSE, FALSE, "rawinput_test_keyboard_process_done" ); + ok( process_done != NULL, "CreateEventA failed\n" ); + + sprintf( path, "%s input rawinput_test_keyboard", argv0 ); + ret = CreateProcessA( NULL, path, NULL, NULL, TRUE, 0, NULL, NULL, &startup_info, &process_info ); + ok( ret, "CreateProcess "%s" failed err %lu.\n", path, GetLastError() ); + empty_message_queue(); + + hwnd = CreateWindowA( "static", "static", WS_VISIBLE | WS_POPUP, 100, 100, 100, 100, 0, NULL, NULL, NULL ); + ok( hwnd != 0, "CreateWindow failed\n" ); + SetWindowLongPtrA( hwnd, GWLP_WNDPROC, (LONG_PTR)append_message_wndproc ); + p_accept_message = accept_keyboard_messages_raw; + empty_message_queue(); + + /* FIXME: Try to workaround X11/Win32 focus inconsistencies and + * make the window visible and foreground as hard as possible. */ + ShowWindow( hwnd, SW_SHOW ); + SetWindowPos( hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE ); + SetForegroundWindow( hwnd ); + UpdateWindow( hwnd ); + empty_message_queue(); + + raw_devices[0].usUsagePage = HID_USAGE_PAGE_GENERIC; + raw_devices[0].usUsage = HID_USAGE_GENERIC_KEYBOARD; + raw_devices[0].dwFlags = RIDEV_NOLEGACY; + raw_devices[0].hwndTarget = 0; + + SetLastError( 0xdeadbeef ); + ret = RegisterRawInputDevices( raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE) ); + ok( ret, "RegisterRawInputDevices failed: %lu\n", GetLastError() ); + + for (i = 0; i < ARRAY_SIZE(raw_test); ++i) + { + SetEvent( process_start ); + WaitForSingleObject( process_done, INFINITE ); + wait_messages( 5, FALSE ); + ok_seq( raw_test[i].expect ); + check_keyboard_async( raw_test[i].expect_async, raw_test[i].todo_async ); + } + + SetFocus( NULL ); + empty_message_queue(); + + for (i = 0; i < ARRAY_SIZE(raw_test_no_focus); ++i) + { + SetEvent( process_start ); + WaitForSingleObject( process_done, INFINITE ); + wait_messages( 5, FALSE ); + ok_seq( raw_test_no_focus[i].expect ); + check_keyboard_async( raw_test_no_focus[i].expect_async, raw_test_no_focus[i].todo_async ); + } + + SetForegroundWindow( GetDesktopWindow() ); + empty_message_queue(); + + for (i = 0; i < ARRAY_SIZE(raw_test_no_fg); ++i) + { + SetEvent( process_start ); + WaitForSingleObject( process_done, INFINITE ); + wait_messages( 5, FALSE ); + ok_seq( raw_test_no_fg[i].expect ); + check_keyboard_async( raw_test_no_fg[i].expect_async, raw_test_no_fg[i].todo_async ); + } + + DestroyWindow( hwnd ); + + winetest_wait_child_process( process_info.hProcess ); + CloseHandle( process_info.hProcess ); + CloseHandle( process_info.hThread ); + CloseHandle( process_done ); + CloseHandle( process_start ); + p_accept_message = NULL; +} + static void test_DefRawInputProc(void) { LRESULT ret; @@ -6155,6 +6281,8 @@ START_TEST(input) argc = winetest_get_mainargs(&argv); if (argc >= 3 && !strcmp( argv[2], "rawinput_test" )) return rawinput_test_process(); + if (argc >= 3 && !strcmp( argv[2], "rawinput_test_keyboard" )) + return rawinput_test_keyboard_process(); if (argc >= 3 && !strcmp( argv[2], "test_GetMouseMovePointsEx_process" )) return test_GetMouseMovePointsEx_process(); if (argc >= 4 && !strcmp( argv[2], "test_EnableMouseInPointer" )) @@ -6182,6 +6310,7 @@ START_TEST(input) test_GetKeyState(); test_OemKeyScan(); test_rawinput(argv[0]); + test_rawinput_keyboard( argv[0] ); test_DefRawInputProc();
if(pGetMouseMovePointsEx)