[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