From a9bab8eca4be617e3088454f70629ebcf79f857a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincas=20Mili=C5=ABnas?= Date: Tue, 5 Jul 2011 23:16:34 +0300 Subject: [PATCH 11/20] user32/tests: Added raw input simulation tests (try 16) --- dlls/user32/tests/input.c | 316 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 316 insertions(+), 0 deletions(-) diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 8b9a516..1720fda 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -2467,6 +2467,321 @@ static void test_get_raw_input_buffer(void) "expected 0, got %u\n", size); } +static BOOL wm_input_recieved; +static BOOL legacy_mouse_message_recieved; +static BOOL legacy_keyboard_message_recieved; + +static LRESULT CALLBACK get_raw_input_data_wnd_proc(HWND hWnd, UINT msg, + WPARAM wParam, LPARAM lParam) +{ + UINT dwSize, ret2; + RAWINPUT *raw; + BOOL ret; + LRESULT ret3; + DWORD error; + + legacy_mouse_message_recieved |= msg >= WM_MOUSEFIRST && msg <= WM_MOUSELAST; + legacy_keyboard_message_recieved |= msg >= WM_KEYFIRST && msg <= WM_KEYLAST; + + switch (msg) + { + case WM_INPUT: + /* Now that we have a valid HRAWINPUT handle, + let's test the case, when &dwSize is NULL */ + SetLastError(0xdeadbeef); + ret = pGetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, NULL, + sizeof(RAWINPUTHEADER)); + error = GetLastError(); + ok(ret == (UINT)-1, "GetRawInputData returned wrong value: " + "expected (UINT)-1, got %u\n", ret); + ok(error == ERROR_NOACCESS, "GetRawInputData returned " + "wrong error code: %u\n", error); + + /* Test retrieving of RAWINPUT data */ + ret2 = pGetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, + sizeof(RAWINPUTHEADER)); + ok(ret2 == 0, "GetRawInputData failed to retrieve raw input data size\n"); + + if (!(raw = HeapAlloc(GetProcessHeap(), 0, dwSize))) + break; + ret2 = pGetRawInputData((HRAWINPUT)lParam, RID_INPUT, raw, &dwSize, + sizeof(RAWINPUTHEADER)); + ok(ret2 == dwSize, "GetRawInputData failed to retrieve raw input data\n"); + ok(raw->header.dwType == RIM_TYPEMOUSE || raw->header.dwType == RIM_TYPEKEYBOARD, + "Raw input data entry was not from mouse or keyboard, expected otherwise\n"); + + ret3 = pDefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER)); + ok(ret3 == S_OK, "DefRawInputProc failed\n"); + + ret2 = pGetRawInputData((HRAWINPUT)lParam, RID_INPUT, raw, &dwSize, + sizeof(RAWINPUTHEADER)); + ok(ret2 == dwSize, "GetRawInputData failed to reretrieve raw input data after " + "calling DefRawInputProc\n"); + + HeapFree(GetProcessHeap(), 0, raw); + wm_input_recieved = TRUE; + return ret3; + } + return DefWindowProcA(hWnd, msg, wParam, lParam); +} + +#define ID_TIMER 1 + +static void timer_proc(HWND hParent, UINT uMsg, UINT uEventID, DWORD dwTimer) +{ + PostQuitMessage(0); +} + +static HWND test_get_raw_input_data_simulation_setup(HANDLE hInstance, const char *class_name, + RAWINPUTDEVICE *device, INPUT *input, UINT input_count) +{ + MSG msg; + BOOL ret; + UINT ret2, size, ret3, i; + RAWINPUT *raw, *raw2; + + HWND hWnd = CreateWindowA(class_name, "GetRawInputDataTest", WS_OVERLAPPEDWINDOW, + 10, 10, 200, 200, NULL, NULL, hInstance, NULL); + assert(hWnd); + + ShowWindow(hWnd, SW_SHOW); + SetWindowPos(hWnd, HWND_TOPMOST, 10, 10, 200, 200, SWP_NOSIZE|SWP_NOMOVE); + SetForegroundWindow(hWnd); + UpdateWindow(hWnd); + SetFocus(hWnd); + + /* Flush queued messages */ + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessageA(&msg); + } + + wm_input_recieved = FALSE; + legacy_mouse_message_recieved = FALSE; + legacy_keyboard_message_recieved = FALSE; + + device->hwndTarget = hWnd; + ret = pRegisterRawInputDevices(device, 1, sizeof(RAWINPUTDEVICE)); + ok(ret, "RegisterRawInputDevices failed to subscribe to " + "a raw input device: %u\n", GetLastError()); + + ok(!GetInputState(), "GetInputState returned that there are mouse or keyboard " + "messages queued, expected otherwise\n"); + size = 0xdeadbeef; + ret2 = pGetRawInputBuffer(NULL, &size, sizeof(RAWINPUTHEADER)); + ok(ret2 == 0, "GetRawInputBuffer returned wrong value: expected 0, got %u\n", ret2); + todo_wine ok(size == 0, "GetRawInputBuffer returned incorrect minimum buffer size: " + "expected 0, got %u\n", size); + + /* First send input to test raw input buffer */ + pSendInput(input_count, input, sizeof(INPUT)); + + todo_wine ok(GetQueueStatus(QS_RAWINPUT), "GetQueueStatus returned that the queue was " + "not marked as containing raw input messages, expected otherwise\n"); + size = 0; + ret2 = pGetRawInputBuffer(NULL, &size, sizeof(RAWINPUTHEADER)); + ok(ret2 == 0, "GetRawInputBuffer returned wrong value: expected 0, got %u\n", ret2); + todo_wine ok(size > 0, "GetRawInputBuffer returned incorrect minimum buffer size: " + "expected x > 0, got %u\n", size); + + /* Size variable is the size of a single entry of what GetRawInputBuffer will return, + therefore we will allocate enough space to accommodate 16 entries */ + size *= 16; + raw = HeapAlloc(GetProcessHeap(), 0, size * sizeof(RAWINPUT)); + ok(raw != NULL, "HeapAlloc failed to allocate memory for raw input buffer data\n"); + if (raw) + { + ret3 = pGetRawInputBuffer(raw, &size, sizeof(RAWINPUTHEADER)); + todo_wine ok(ret3 > 0 && ret3 != (UINT)-1, + "GetRawInputBuffer failed to read raw input buffer\n"); + for (i = 0, raw2 = raw; ret3 != (UINT)-1 && i < ret3; i++) + { + ok(raw2->header.dwType == RIM_TYPEMOUSE || raw2->header.dwType == RIM_TYPEKEYBOARD, + "Raw input event was not from mouse or keyboard, expected otherwise\n"); + ok( + (raw2->header.dwType == RIM_TYPEMOUSE && + raw2->header.dwSize == sizeof(RAWINPUTHEADER) + sizeof(RAWMOUSE)) || + (raw2->header.dwType == RIM_TYPEKEYBOARD && + raw2->header.dwSize == sizeof(RAWINPUTHEADER) + sizeof(RAWKEYBOARD)), + "Raw input event size didn't match the one expected for mouse or keyboard\n"); + raw2 = NEXTRAWINPUTBLOCK(raw2); + } + HeapFree(GetProcessHeap(), 0, raw); + } + ret2 = pGetRawInputBuffer(NULL, &size, sizeof(RAWINPUTHEADER)); + ok(ret2 == 0, "GetRawInputBuffer returned wrong value: expected 0, got %u\n", ret2); + ok(size == 0, "GetRawInputBuffer returned incorrect minimum buffer size: " + "expected 0, got %u\n", size); + + /* Proceed with testing other functionality */ + pSendInput(input_count, input, sizeof(INPUT)); + + todo_wine ok(GetQueueStatus(QS_RAWINPUT), "GetQueueStatus returned that the queue was " + "not marked as containing raw input messages, expected otherwise\n"); + ret2 = pGetRawInputBuffer(NULL, &size, sizeof(RAWINPUTHEADER)); + ok(ret2 == 0, "GetRawInputBuffer returned wrong value: expected 0, got %u\n", ret2); + todo_wine ok(size > 0, "GetRawInputBuffer returned incorrect minimum buffer size: " + "expected x > 0, got %u\n", size); + + /* Give half a second of running time for each test to be sure all messages are processed */ + SetTimer(hWnd, ID_TIMER, 500, (TIMERPROC)timer_proc); + + while (1 == 1) + { + ret = GetMessageA(&msg, NULL, 0, 0); + if (!ret || ret == (BOOL)-1) + break; + TranslateMessage(&msg); + DispatchMessageA(&msg); + } + + ok(ret != -1, "Error getting window message: %u\n", GetLastError()); + todo_wine ok(wm_input_recieved, "WM_INPUT was not received\n"); + ok(!GetQueueStatus(QS_RAWINPUT), "GetQueueStatus returned that the queue was " + "marked as containing raw input messages, expected otherwise\n"); + + return hWnd; +} + +static void test_get_raw_input_data_simulation_teardown(HWND hWnd, RAWINPUTDEVICE *device) +{ + BOOL ret; + UINT ret2; + DWORD count; + + KillTimer(hWnd, ID_TIMER); + + device->dwFlags = RIDEV_REMOVE | (device->usUsage == 0 ? RIDEV_PAGEONLY : 0); + device->hwndTarget = NULL; + ret = pRegisterRawInputDevices(device, 1, sizeof(RAWINPUTDEVICE)); + ok(ret, "RegisterRawInputDevices failed to unsubscribe from " + "a raw input device: %u\n", GetLastError()); + + count = 0xdeadbeef; + ret2 = pGetRegisteredRawInputDevices(NULL, &count, sizeof(RAWINPUTDEVICE)); + ok(ret2 == 0, "GetRegisteredRawInputDevices returned wrong value: " + "expected 0, got %u\n", ret2); + todo_wine ok(count == 0, "GetRegisteredRawInputDevices returned incorrect registration count: " + "expected 0, got %u\n", count); + + DestroyWindow(hWnd); +} + +static void test_get_raw_input_data_simulation(void) +{ + HWND hWnd; + WNDCLASSA wclass; + HANDLE hInstance = GetModuleHandleA( NULL ); + INPUT mouse_input[5], keyboard_input; + ATOM registration; + RAWINPUTDEVICE device; + unsigned int i; + + if (!pRegisterRawInputDevices || !pGetRawInputData || !pDefRawInputProc || + !pGetRawInputBuffer || !pSendInput) + { + win_skip("Functions required to perform raw input simulation are not available\n"); + return; + } + + wclass.lpszClassName = "GetRawInputDataTestClass"; + wclass.style = CS_HREDRAW | CS_VREDRAW; + wclass.lpfnWndProc = get_raw_input_data_wnd_proc; + wclass.hInstance = hInstance; + wclass.hIcon = LoadIconA(0, IDI_APPLICATION); + wclass.hCursor = LoadCursorA(NULL, IDC_ARROW); + wclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wclass.lpszMenuName = NULL; + wclass.cbClsExtra = 0; + wclass.cbWndExtra = 0; + registration = RegisterClassA(&wclass); + assert(registration); + + /* Setup fixtures */ + device.usUsagePage = HID_USAGE_PAGE_GENERIC; + + memset(&keyboard_input, 0, sizeof(keyboard_input)); + keyboard_input.type = INPUT_KEYBOARD; + keyboard_input.ki.wVk = VK_SPACE; + + /* Be sure to move over the window, because the absolute window position on the screen + depends on how desktop widgets are placed */ + memset(&mouse_input, 0, sizeof(mouse_input)); + mouse_input[0].type = INPUT_MOUSE; + mouse_input[0].mi.dx = mouse_input[0].mi.dy = 15; + mouse_input[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; + mouse_input[1].type = INPUT_MOUSE; + mouse_input[1].mi.mouseData = 0x0078; + mouse_input[1].mi.dwFlags = MOUSEEVENTF_WHEEL; + for (i = 2; i < sizeof(mouse_input) / sizeof(mouse_input[0]); i++) + { + mouse_input[i].type = INPUT_MOUSE; + mouse_input[i].mi.dx = mouse_input[i].mi.dy = 30; + mouse_input[i].mi.dwFlags = MOUSEEVENTF_MOVE; + } + + /* Test WM_INPUT for mouse */ + device.usUsage = HID_USAGE_GENERIC_MOUSE; + device.dwFlags = 0; + + hWnd = test_get_raw_input_data_simulation_setup(hInstance, wclass.lpszClassName, &device, + mouse_input, 5); + ok(legacy_mouse_message_recieved, + "Didn't receive legacy mouse messages, while was expecting to\n"); + test_get_raw_input_data_simulation_teardown(hWnd, &device); + + /* Test WM_INPUT for keyboard */ + device.usUsage = HID_USAGE_GENERIC_KEYBOARD; + device.dwFlags = 0; + + hWnd = test_get_raw_input_data_simulation_setup(hInstance, wclass.lpszClassName, &device, + &keyboard_input, 1); + ok(legacy_keyboard_message_recieved, + "Didn't receive keyboard messages, while was expecting to\n"); + test_get_raw_input_data_simulation_teardown(hWnd, &device); + + /* Test RIDEV_PAGEONLY using mouse */ + device.usUsage = 0; + device.dwFlags = RIDEV_PAGEONLY; + + hWnd = test_get_raw_input_data_simulation_setup(hInstance, wclass.lpszClassName, &device, + mouse_input, 5); + ok(legacy_mouse_message_recieved, + "Didn't receive legacy mouse messages, while was expecting to\n"); + test_get_raw_input_data_simulation_teardown(hWnd, &device); + + /* Test RIDEV_PAGEONLY using keyboard */ + device.usUsage = 0; + device.dwFlags = RIDEV_PAGEONLY; + + hWnd = test_get_raw_input_data_simulation_setup(hInstance, wclass.lpszClassName, &device, + &keyboard_input, 1); + ok(legacy_keyboard_message_recieved, + "Didn't receive legacy keyboard messages, while was expecting to\n"); + test_get_raw_input_data_simulation_teardown(hWnd, &device); + + /* Test RIDEV_NOLEGACY for mouse */ + device.usUsage = HID_USAGE_GENERIC_MOUSE; + device.dwFlags = RIDEV_NOLEGACY; + + hWnd = test_get_raw_input_data_simulation_setup(hInstance, wclass.lpszClassName, &device, + mouse_input, 5); + todo_wine ok(!legacy_mouse_message_recieved, + "Did receive legacy mouse messages, while was expecting not to\n"); + test_get_raw_input_data_simulation_teardown(hWnd, &device); + + /* Test RIDEV_NOLEGACY for keyboard */ + device.usUsage = HID_USAGE_GENERIC_KEYBOARD; + device.dwFlags = RIDEV_NOLEGACY; + + hWnd = test_get_raw_input_data_simulation_setup(hInstance, wclass.lpszClassName, &device, + &keyboard_input, 1); + todo_wine ok(!legacy_keyboard_message_recieved, + "Did receive legacy mouse messages, while was expecting not to\n"); + test_get_raw_input_data_simulation_teardown(hWnd, &device); +} + START_TEST(input) { init_function_pointers(); @@ -2496,6 +2811,7 @@ START_TEST(input) test_extended_register_raw_input_devices(); test_get_raw_input_data(); test_get_raw_input_buffer(); + test_get_raw_input_data_simulation(); if(pGetMouseMovePointsEx) test_GetMouseMovePointsEx(); -- 1.7.3.4