[PATCH 3/8] user32/tests: Add inter-process rawinput message tests.

Rémi Bernon rbernon at codeweavers.com
Sun Jun 7 06:21:15 CDT 2020


Rawinput messages are not received anymore if the foreground window is
from another process. Using RIDEV_INPUTSINK makes it possible to receive
them again, but with RIM_INPUTSINK flag.

Currently the messages may be received correctly, but that depends on
where the input events are generated, so add another test case with
messages sent from the test process, and validate that nothing should
be received.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/user32/tests/input.c | 113 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 109 insertions(+), 4 deletions(-)

diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
index af44d3e8b4d..ac6a2476785 100644
--- a/dlls/user32/tests/input.c
+++ b/dlls/user32/tests/input.c
@@ -1881,8 +1881,70 @@ struct rawinput_test rawinput_tests[] =
     /* same-process foreground tests */
     { TRUE,  FALSE, 0,               FALSE, FALSE, FALSE, /* todos: */ FALSE, FALSE, FALSE },
     { TRUE,  TRUE,  0,               FALSE,  TRUE,  TRUE, /* todos: */ FALSE, FALSE, FALSE },
+
+    /* cross-process foreground tests */
+    { TRUE,  TRUE,  0,               FALSE, FALSE, FALSE, /* todos: */ FALSE, FALSE, FALSE },
+    { TRUE,  TRUE,  RIDEV_INPUTSINK, FALSE,  TRUE, FALSE, /* todos: */ FALSE,  TRUE, FALSE },
+    { TRUE,  TRUE,  0,               FALSE, FALSE, FALSE, /* todos: */ FALSE,  TRUE,  TRUE },
 };
 
+static void rawinput_test_process(void)
+{
+    HANDLE ready, start, done;
+    POINT pt;
+    HWND hwnd = NULL;
+    int i;
+
+    ready = OpenEventA(EVENT_ALL_ACCESS, FALSE, "rawinput_test_process_ready");
+    ok(ready != 0, "OpenEventA failed, error: %u\n", GetLastError());
+
+    start = OpenEventA(EVENT_ALL_ACCESS, FALSE, "rawinput_test_process_start");
+    ok(start != 0, "OpenEventA failed, error: %u\n", GetLastError());
+
+    done = OpenEventA(EVENT_ALL_ACCESS, FALSE, "rawinput_test_process_done");
+    ok(done != 0, "OpenEventA failed, error: %u\n", GetLastError());
+
+    for (i = 0; i < ARRAY_SIZE(rawinput_tests); ++i)
+    {
+        WaitForSingleObject(ready, INFINITE);
+        ResetEvent(ready);
+
+        switch (i)
+        {
+        case 6:
+        case 7:
+        case 8:
+            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");
+            empty_message_queue();
+
+            ShowWindow(hwnd, SW_SHOW);
+            SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
+            SetForegroundWindow(hwnd);
+            UpdateWindow(hwnd);
+            empty_message_queue();
+
+            if (i != 8) mouse_event(MOUSEEVENTF_MOVE, 5, 0, 0, 0);
+            empty_message_queue();
+            break;
+        }
+
+        SetEvent(start);
+
+        WaitForSingleObject(done, INFINITE);
+        ResetEvent(done);
+        if (hwnd) DestroyWindow(hwnd);
+    }
+
+    WaitForSingleObject(ready, INFINITE);
+    CloseHandle(done);
+    CloseHandle(start);
+    CloseHandle(ready);
+}
+
 struct rawinput_test_thread_params
 {
     HANDLE ready;
@@ -1934,14 +1996,17 @@ static DWORD WINAPI rawinput_test_thread(void *arg)
     return 0;
 }
 
-static void test_rawinput(void)
+static void test_rawinput(const char* argv0)
 {
     struct rawinput_test_thread_params params;
+    PROCESS_INFORMATION process_info;
     RAWINPUTDEVICE raw_devices[1];
-    HANDLE thread;
+    STARTUPINFOA startup_info;
+    HANDLE thread, process_ready, process_start, process_done;
     DWORD ret;
     POINT pt, newpt;
     HWND hwnd;
+    char path[MAX_PATH];
     int i;
 
     params.ready = CreateEventA(NULL, FALSE, FALSE, NULL);
@@ -1956,6 +2021,24 @@ static void test_rawinput(void)
     thread = CreateThread(NULL, 0, rawinput_test_thread, &params, 0, NULL);
     ok(thread != NULL, "CreateThread failed\n");
 
+    process_ready = CreateEventA(NULL, FALSE, FALSE, "rawinput_test_process_ready");
+    ok(process_ready != NULL, "CreateEventA failed\n");
+
+    process_start = CreateEventA(NULL, FALSE, FALSE, "rawinput_test_process_start");
+    ok(process_start != NULL, "CreateEventA failed\n");
+
+    process_done = CreateEventA(NULL, FALSE, FALSE, "rawinput_test_process_done");
+    ok(process_done != NULL, "CreateEventA failed\n");
+
+    memset(&startup_info, 0, sizeof(startup_info));
+    startup_info.cb = sizeof(startup_info);
+    startup_info.dwFlags = STARTF_USESHOWWINDOW;
+    startup_info.wShowWindow = SW_SHOWNORMAL;
+
+    sprintf(path, "%s input rawinput_test", argv0);
+    ret = CreateProcessA(NULL, path, NULL, NULL, TRUE, 0, NULL, NULL, &startup_info, &process_info );
+    ok(ret, "CreateProcess \"%s\" failed err %u.\n", path, GetLastError());
+
     SetCursorPos(100, 100);
     empty_message_queue();
 
@@ -1992,13 +2075,18 @@ static void test_rawinput(void)
             ok(GetLastError() == 0xdeadbeef, "%d: RegisterRawInputDevices returned %08x\n", i, GetLastError());
         }
 
+        SetEvent(process_ready);
+        WaitForSingleObject(process_start, INFINITE);
+        ResetEvent(process_start);
+
         SetEvent(params.ready);
         WaitForSingleObject(params.start, INFINITE);
         ResetEvent(params.start);
 
-        if (i <= 3) mouse_event(MOUSEEVENTF_MOVE, 5, 0, 0, 0);
+        if (i <= 3 || i == 8) mouse_event(MOUSEEVENTF_MOVE, 5, 0, 0, 0);
         empty_message_queue();
 
+        SetEvent(process_done);
         SetEvent(params.done);
 
         todo_wine_if(rawinput_tests[i].todo_legacy)
@@ -2028,6 +2116,14 @@ static void test_rawinput(void)
         DestroyWindow(hwnd);
     }
 
+    SetEvent(process_ready);
+    winetest_wait_child_process(process_info.hProcess);
+    CloseHandle(process_info.hProcess);
+    CloseHandle(process_info.hThread);
+    CloseHandle(process_done);
+    CloseHandle(process_start);
+    CloseHandle(process_ready);
+
     WaitForSingleObject(thread, INFINITE);
 
     CloseHandle(params.done);
@@ -3229,11 +3325,20 @@ static void test_UnregisterDeviceNotification(void)
 
 START_TEST(input)
 {
+    char **argv;
+    int argc;
     POINT pos;
 
     init_function_pointers();
     GetCursorPos( &pos );
 
+    argc = winetest_get_mainargs(&argv);
+    if (argc >= 3 && strcmp(argv[2], "rawinput_test") == 0)
+    {
+        rawinput_test_process();
+        return;
+    }
+
     test_Input_blackbox();
     test_Input_whitebox();
     test_Input_unicode();
@@ -3251,7 +3356,7 @@ START_TEST(input)
     test_OemKeyScan();
     test_GetRawInputData();
     test_RegisterRawInputDevices();
-    test_rawinput();
+    test_rawinput(argv[0]);
 
     if(pGetMouseMovePointsEx)
         test_GetMouseMovePointsEx();
-- 
2.27.0




More information about the wine-devel mailing list