[PATCH 1/8] user32/tests: Add basic rawinput message tests.
Rémi Bernon
rbernon at codeweavers.com
Sun Jun 7 10:50:08 CDT 2020
On 2020-06-07 17:11, Zebediah Figura wrote:
> On 6/7/20 6:21 AM, Rémi Bernon wrote:
>> This tests basic functionality by injecting mouse event and checking
>> the number of each messages received.
>>
>> Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
>> ---
>> dlls/user32/tests/input.c | 136 ++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 136 insertions(+)
>>
>> diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
>> index 913fabfbd85..4d1a1c062ab 100644
>> --- a/dlls/user32/tests/input.c
>> +++ b/dlls/user32/tests/input.c
>> @@ -1819,6 +1819,141 @@ static void test_RegisterRawInputDevices(void)
>> DestroyWindow(hwnd);
>> }
>> +static int rawinput_test_count_legacy;
>> +static int rawinput_test_count_raw;
>> +static int rawinput_test_count_rawfg;
>> +
>> +static LRESULT CALLBACK rawinput_wndproc(HWND hwnd, UINT msg, WPARAM
>> wparam, LPARAM lparam)
>> +{
>> + UINT ret, raw_size;
>> + RAWINPUT raw;
>> +
>> + if (msg == WM_INPUT)
>> + {
>> + todo_wine_if(rawinput_test_count_raw)
>> + ok(rawinput_test_count_raw == 0, "Unexpected spurious
>> WM_INPUT message.\n");
>> + ok(wparam == RIM_INPUT || wparam == RIM_INPUTSINK,
>> "Unexpected wparam: %lu\n", wparam);
>> +
>> + rawinput_test_count_raw++;
>> + if (wparam == RIM_INPUT) rawinput_test_count_rawfg++;
>
> If you can't reliably check what the actual count is, maybe it makes
> more sense to have this as a boolean flag...?
It is indeed a remain of a previous version of the test, the message
count isn't currently correct in wine (hence the todo above), and I was
initially checking the actual count.
As it's not going to be fixed until we change winex11, I then opted for
a boolean "expectation" and this todo here
I think it's still valuable to count the messages, to expose the fact
that wine has some spurious messages. It doesn't make the test much more
complex either.
>
>> +
>> + ret = GetRawInputData((HRAWINPUT)lparam, RID_INPUT, NULL,
>> &raw_size, sizeof(RAWINPUTHEADER));
>> + ok(ret == 0, "GetRawInputData failed\n");
>> + ok(raw_size <= sizeof(raw), "Unexpected rawinput data size:
>> %u", raw_size);
>> + if (raw_size > sizeof(raw))
>> + return DefWindowProcA(hwnd, msg, wparam, lparam);
>> +
>> + ret = GetRawInputData((HRAWINPUT)lparam, RID_INPUT, &raw,
>> &raw_size, sizeof(RAWINPUTHEADER));
>> + ok(ret > 0 && ret != (UINT)-1, "GetRawInputData failed\n");
>> + ok(raw.header.dwType == RIM_TYPEMOUSE, "Unexpected rawinput
>> type: %u\n", raw.header.dwType);
>> + if (raw.header.dwType != RIM_TYPEMOUSE)
>> + return DefWindowProcA(hwnd, msg, wparam, lparam);
>> +
>
> I've never much seen the point of doing this (and similarly above). If
> the test fails, you'll know due to the failure message, and it's not
> particularly like we care about different degrees of failure—if it
> fails, it still needs to be fixed. I don't feel strongly about it,
> though...
You mean the early returns? The first one will prevent possible buffer
overrun, which is probably not a nice failure. The second one is a bit
overkill indeed.
>
>> + ok(!(raw.data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE),
>> "Unexpected absolute rawinput motion\n");
>> + ok(!(raw.data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP),
>> "Unexpected virtual desktop rawinput motion\n");
>> + }
>> +
>> + if (msg == WM_MOUSEMOVE) rawinput_test_count_legacy++;
>> +
>> + return DefWindowProcA(hwnd, msg, wparam, lparam);
>> +}
>> +
>> +struct rawinput_test
>> +{
>> + BOOL register_device;
>> + BOOL register_window;
>> + DWORD register_flags;
>> + int expect_legacy;
>> + int expect_raw;
>> + int expect_rawfg;
>> + BOOL todo_legacy;
>> + BOOL todo_raw;
>> + BOOL todo_rawfg;
>> +};
>> +
>> +struct rawinput_test rawinput_tests[] =
>> +{
>> + { FALSE, FALSE, 0, TRUE, FALSE, FALSE, /* todos:
>> */ FALSE, FALSE, FALSE },
>> + { TRUE, FALSE, 0, TRUE, TRUE, TRUE, /* todos:
>> */ FALSE, FALSE, FALSE },
>> + { TRUE, TRUE, 0, TRUE, TRUE, TRUE, /* todos:
>> */ FALSE, FALSE, FALSE },
>> + { TRUE, TRUE, RIDEV_NOLEGACY, FALSE, TRUE, TRUE, /* todos:
>> */ TRUE, FALSE, FALSE },
>> +};
>> +
>> +static void test_rawinput(void)
>> +{
>> + RAWINPUTDEVICE raw_devices[1];
>> + DWORD ret;
>> + POINT pt, newpt;
>> + HWND hwnd;
>> + int i;
>> +
>> + SetCursorPos(100, 100);
>> + empty_message_queue();
>> +
>> + for (i = 0; i < ARRAY_SIZE(rawinput_tests); ++i)
>> + {
>> + GetCursorPos(&pt);
>> +
>> + hwnd = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP,
>> + pt.x - 50, pt.y - 50, 100, 100, 0, NULL,
>> NULL, NULL);
>> + ok(hwnd != 0, "CreateWindow failed\n");
>> + SetWindowLongPtrA(hwnd, GWLP_WNDPROC,
>> (LONG_PTR)rawinput_wndproc);
>> + empty_message_queue();
>> +
>> + ShowWindow(hwnd, SW_SHOW);
>> + SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
>> + SetForegroundWindow(hwnd);
>> + UpdateWindow(hwnd);
>
> Wait, what's the point of all these calls? In particular, why
> ShowWindow() and UpdateWindow()? Perhaps they deserve a comment in the
> code.
>
It's mostly copy-pasted from the other tests in the same source.
The point is to try as much as possible to get the window in visible and
in front and make the Win32 state as consistent as possible with the X11
state, which is hard. Even a small change can make it fail spuriously
otherwise.
--
Rémi Bernon <rbernon at codeweavers.com>
More information about the wine-devel
mailing list