You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-09-12 18:50:20 -07:00
Updated rawinput patchsets
This is a completely updated rawinput patchsets from Rémi Bernon, replacing the current user32-rawinput.
This commit is contained in:
@@ -0,0 +1,262 @@
|
||||
From fe1ae8a2e1ee05143a9a0b7248420edada9bc09d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 14 Nov 2019 16:41:43 +0100
|
||||
Subject: [PATCH 01/12] user32/tests: Add rawinput test for ClipCursor
|
||||
interactions.
|
||||
|
||||
This shows unexpected rawinput messages triggered from cursor clipping.
|
||||
|
||||
The sleeps are required to let native cursor clipping time to activate.
|
||||
We also repeat the clipping multiple times to be increase the chances
|
||||
that the counts will be wrong as it doesn't always trigger.
|
||||
---
|
||||
dlls/user32/tests/input.c | 226 ++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 226 insertions(+)
|
||||
|
||||
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
|
||||
index 478c269017a..bf9d19906a8 100644
|
||||
--- a/dlls/user32/tests/input.c
|
||||
+++ b/dlls/user32/tests/input.c
|
||||
@@ -1826,6 +1826,231 @@ static void test_RegisterRawInputDevices(void)
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
+static int rawinput_received;
|
||||
+static int rawinput_received_foreground;
|
||||
+static int rawinput_motion_x;
|
||||
+static int rawinput_motion_y;
|
||||
+static HANDLE rawinput_wndproc_done;
|
||||
+
|
||||
+static LRESULT CALLBACK rawinput_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
+{
|
||||
+ UINT ret, raw_size;
|
||||
+ RAWINPUT raw;
|
||||
+
|
||||
+ if (msg == WM_INPUT)
|
||||
+ {
|
||||
+ rawinput_received++;
|
||||
+
|
||||
+ ok(wparam == RIM_INPUT || wparam == RIM_INPUTSINK, "Unexpected wparam: %lu\n", wparam);
|
||||
+ if (wparam == RIM_INPUT)
|
||||
+ rawinput_received_foreground++;
|
||||
+
|
||||
+ 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))
|
||||
+ {
|
||||
+ 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)
|
||||
+ {
|
||||
+ 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");
|
||||
+ rawinput_motion_x += raw.data.mouse.lLastX;
|
||||
+ rawinput_motion_y += raw.data.mouse.lLastY;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (msg == WM_USER)
|
||||
+ SetEvent(rawinput_wndproc_done);
|
||||
+
|
||||
+ return DefWindowProcA(hwnd, msg, wparam, lparam);
|
||||
+}
|
||||
+
|
||||
+struct rawinput_mouse_thread_params
|
||||
+{
|
||||
+ int step;
|
||||
+ HWND window;
|
||||
+ HANDLE ready;
|
||||
+ HANDLE start;
|
||||
+};
|
||||
+
|
||||
+static DWORD WINAPI rawinput_mouse_thread(void *arg)
|
||||
+{
|
||||
+ struct rawinput_mouse_thread_params *params = arg;
|
||||
+ RECT rect_105 = { 105, 105, 105, 105 };
|
||||
+ RECT rect_110 = { 110, 110, 110, 110 };
|
||||
+ int i;
|
||||
+
|
||||
+ while (WaitForSingleObject(params->ready, INFINITE) == 0)
|
||||
+ {
|
||||
+ ResetEvent(params->ready);
|
||||
+ SetEvent(params->start);
|
||||
+
|
||||
+ switch (params->step)
|
||||
+ {
|
||||
+ case 0:
|
||||
+ case 1:
|
||||
+ case 2:
|
||||
+ mouse_event(MOUSEEVENTF_MOVE, -1, 0, 0, 0);
|
||||
+ mouse_event(MOUSEEVENTF_MOVE, 0, -1, 0, 0);
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ for (i = 0; i < 10; ++i)
|
||||
+ {
|
||||
+ ClipCursor(&rect_105);
|
||||
+ Sleep(5);
|
||||
+ ClipCursor(&rect_110);
|
||||
+ Sleep(5);
|
||||
+ ClipCursor(NULL);
|
||||
+ Sleep(5);
|
||||
+ }
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ for (i = 0; i < 10; ++i)
|
||||
+ {
|
||||
+ ClipCursor(&rect_110);
|
||||
+ Sleep(5);
|
||||
+ mouse_event(MOUSEEVENTF_MOVE, 1, 1, 0, 0);
|
||||
+ ClipCursor(NULL);
|
||||
+ Sleep(5);
|
||||
+ mouse_event(MOUSEEVENTF_MOVE, 1, 1, 0, 0);
|
||||
+ ClipCursor(&rect_110);
|
||||
+ ClipCursor(NULL);
|
||||
+ Sleep(5);
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ PostMessageA(params->window, WM_USER, 0, 0);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+struct rawinput_mouse_test
|
||||
+{
|
||||
+ BOOL register_device;
|
||||
+ BOOL register_window;
|
||||
+ DWORD register_flags;
|
||||
+ int expect_received;
|
||||
+ int expect_received_foreground;
|
||||
+ int expect_motion_x;
|
||||
+ int expect_motion_y;
|
||||
+ BOOL todo;
|
||||
+};
|
||||
+
|
||||
+static void test_rawinput_mouse(void)
|
||||
+{
|
||||
+ struct rawinput_mouse_thread_params params;
|
||||
+ RAWINPUTDEVICE raw_devices[1];
|
||||
+ HANDLE thread;
|
||||
+ DWORD ret;
|
||||
+ int i;
|
||||
+
|
||||
+ struct rawinput_mouse_test tests[] =
|
||||
+ {
|
||||
+ { FALSE, FALSE, 0, 0, 0, 0, 0, FALSE },
|
||||
+ { TRUE, FALSE, 0, 2, 2, -1, -1, FALSE },
|
||||
+ { TRUE, TRUE, 0, 2, 2, -1, -1, FALSE },
|
||||
+ { TRUE, TRUE, 0, 0, 0, 0, 0, TRUE },
|
||||
+ { TRUE, TRUE, 0, 20, 20, 20, 20, TRUE },
|
||||
+ };
|
||||
+
|
||||
+ mouse_event(MOUSEEVENTF_ABSOLUTE, 100, 100, 0, 0);
|
||||
+ SetCursorPos(100, 100);
|
||||
+
|
||||
+ rawinput_wndproc_done = CreateEventA(NULL, FALSE, FALSE, NULL);
|
||||
+ ok(rawinput_wndproc_done != NULL, "CreateEvent failed\n");
|
||||
+
|
||||
+ params.window = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP, 100, 100, 100, 100, 0, NULL, NULL, NULL);
|
||||
+ ok(params.window != 0, "CreateWindow failed\n");
|
||||
+
|
||||
+ ShowWindow(params.window, SW_SHOW);
|
||||
+ SetWindowPos(params.window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
|
||||
+ SetForegroundWindow(params.window);
|
||||
+ UpdateWindow(params.window);
|
||||
+ empty_message_queue();
|
||||
+
|
||||
+ SetWindowLongPtrA(params.window, GWLP_WNDPROC, (LONG_PTR)rawinput_wndproc);
|
||||
+
|
||||
+ params.step = 0;
|
||||
+ params.ready = CreateEventA(NULL, FALSE, FALSE, NULL);
|
||||
+ ok(params.ready != NULL, "CreateEvent failed\n");
|
||||
+
|
||||
+ params.start = CreateEventA(NULL, FALSE, FALSE, NULL);
|
||||
+ ok(params.start != NULL, "CreateEvent failed\n");
|
||||
+
|
||||
+ thread = CreateThread(NULL, 0, rawinput_mouse_thread, ¶ms, 0, NULL);
|
||||
+ ok(thread != NULL, "CreateThread failed\n");
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(tests); ++i)
|
||||
+ {
|
||||
+ rawinput_received = 0;
|
||||
+ rawinput_received_foreground = 0;
|
||||
+ rawinput_motion_x = 0;
|
||||
+ rawinput_motion_y = 0;
|
||||
+
|
||||
+ raw_devices[0].usUsagePage = 0x01;
|
||||
+ raw_devices[0].usUsage = 0x02;
|
||||
+ raw_devices[0].dwFlags = tests[i].register_flags;
|
||||
+ raw_devices[0].hwndTarget = tests[i].register_window ? params.window : 0;
|
||||
+
|
||||
+ if (tests[i].register_device)
|
||||
+ {
|
||||
+ SetLastError(0xdeadbeef);
|
||||
+ ret = RegisterRawInputDevices(raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE));
|
||||
+ ok(ret, "%d: RegisterRawInputDevices failed\n", i);
|
||||
+ ok(GetLastError() == 0xdeadbeef, "%d: RegisterRawInputDevices returned %08x\n", i, GetLastError());
|
||||
+ }
|
||||
+
|
||||
+ params.step = i;
|
||||
+ SetEvent(params.ready);
|
||||
+
|
||||
+ WaitForSingleObject(params.start, INFINITE);
|
||||
+ ResetEvent(params.start);
|
||||
+
|
||||
+ while (MsgWaitForMultipleObjects(1, &rawinput_wndproc_done, FALSE, INFINITE, QS_ALLINPUT) != WAIT_OBJECT_0)
|
||||
+ empty_message_queue();
|
||||
+ ResetEvent(rawinput_wndproc_done);
|
||||
+
|
||||
+ /* Wine is sometimes passing some of the conditions, but not always, let's test
|
||||
+ * all at once in the todo block, there should be at least one that fails. */
|
||||
+ todo_wine_if(tests[i].todo)
|
||||
+ ok(rawinput_received == tests[i].expect_received &&
|
||||
+ rawinput_received_foreground == tests[i].expect_received_foreground &&
|
||||
+ rawinput_motion_x == tests[i].expect_motion_x &&
|
||||
+ rawinput_motion_y == tests[i].expect_motion_y,
|
||||
+ "%d: Unexpected rawinput results: received %d, %d in foreground, motion is %dx%d\n",
|
||||
+ i, rawinput_received, rawinput_received_foreground, rawinput_motion_x, rawinput_motion_y);
|
||||
+
|
||||
+ if (tests[i].register_device)
|
||||
+ {
|
||||
+ raw_devices[0].dwFlags = RIDEV_REMOVE;
|
||||
+ raw_devices[0].hwndTarget = 0;
|
||||
+
|
||||
+ SetLastError(0xdeadbeef);
|
||||
+ ret = RegisterRawInputDevices(raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE));
|
||||
+ ok(ret, "%d: RegisterRawInputDevices failed\n", i);
|
||||
+ ok(GetLastError() == 0xdeadbeef, "%d: RegisterRawInputDevices returned %08x\n", i, GetLastError());
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ params.step = -1;
|
||||
+ SetEvent(params.ready);
|
||||
+ WaitForSingleObject(thread, INFINITE);
|
||||
+
|
||||
+ CloseHandle(params.start);
|
||||
+ CloseHandle(params.ready);
|
||||
+ CloseHandle(thread);
|
||||
+}
|
||||
+
|
||||
static void test_key_map(void)
|
||||
{
|
||||
HKL kl = GetKeyboardLayout(0);
|
||||
@@ -3326,6 +3551,7 @@ START_TEST(input)
|
||||
test_GetRawInputData();
|
||||
test_GetKeyboardLayoutList();
|
||||
test_RegisterRawInputDevices();
|
||||
+ test_rawinput_mouse();
|
||||
|
||||
if(pGetMouseMovePointsEx)
|
||||
test_GetMouseMovePointsEx();
|
||||
--
|
||||
2.24.1
|
||||
|
@@ -0,0 +1,70 @@
|
||||
From d407a40a11f0cbf3e61faded5e6e7e1e2e63ef9c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 14 Nov 2019 17:03:38 +0100
|
||||
Subject: [PATCH 02/12] user32/tests: Add rawinput test for cross-thread
|
||||
interactions.
|
||||
|
||||
The rawinput messages are received on the target window if is from the
|
||||
same process as the foreground window, it doesn't need to be the
|
||||
foreground window itself.
|
||||
---
|
||||
dlls/user32/tests/input.c | 27 +++++++++++++++++++++++++++
|
||||
1 file changed, 27 insertions(+)
|
||||
|
||||
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
|
||||
index bf9d19906a8..bdcc6834d9d 100644
|
||||
--- a/dlls/user32/tests/input.c
|
||||
+++ b/dlls/user32/tests/input.c
|
||||
@@ -1884,6 +1884,7 @@ static DWORD WINAPI rawinput_mouse_thread(void *arg)
|
||||
struct rawinput_mouse_thread_params *params = arg;
|
||||
RECT rect_105 = { 105, 105, 105, 105 };
|
||||
RECT rect_110 = { 110, 110, 110, 110 };
|
||||
+ HWND window;
|
||||
int i;
|
||||
|
||||
while (WaitForSingleObject(params->ready, INFINITE) == 0)
|
||||
@@ -1924,6 +1925,26 @@ static DWORD WINAPI rawinput_mouse_thread(void *arg)
|
||||
Sleep(5);
|
||||
}
|
||||
break;
|
||||
+ case 5:
|
||||
+ case 6:
|
||||
+ window = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP, 100, 100, 100, 100, 0, NULL, NULL, NULL);
|
||||
+ ok(window != 0, "%d: CreateWindow failed\n", params->step);
|
||||
+
|
||||
+ ShowWindow(window, SW_SHOW);
|
||||
+ SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
|
||||
+ SetForegroundWindow(window);
|
||||
+ UpdateWindow(window);
|
||||
+ empty_message_queue();
|
||||
+
|
||||
+ mouse_event(MOUSEEVENTF_MOVE, 1, 1, 0, 0);
|
||||
+ SendMessageA(GetForegroundWindow(), WM_USER, 0, 0);
|
||||
+ mouse_event(MOUSEEVENTF_MOVE, -1, -1, 0, 0);
|
||||
+ SendMessageA(GetForegroundWindow(), WM_USER, 0, 0);
|
||||
+
|
||||
+ empty_message_queue();
|
||||
+
|
||||
+ DestroyWindow(window);
|
||||
+ break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -1959,8 +1980,14 @@ static void test_rawinput_mouse(void)
|
||||
{ FALSE, FALSE, 0, 0, 0, 0, 0, FALSE },
|
||||
{ TRUE, FALSE, 0, 2, 2, -1, -1, FALSE },
|
||||
{ TRUE, TRUE, 0, 2, 2, -1, -1, FALSE },
|
||||
+
|
||||
+ /* clip cursor tests */
|
||||
{ TRUE, TRUE, 0, 0, 0, 0, 0, TRUE },
|
||||
{ TRUE, TRUE, 0, 20, 20, 20, 20, TRUE },
|
||||
+
|
||||
+ /* same-process foreground tests */
|
||||
+ { TRUE, TRUE, 0, 2, 2, 0, 0, TRUE },
|
||||
+ { TRUE, TRUE, RIDEV_INPUTSINK, 2, 2, 0, 0, TRUE },
|
||||
};
|
||||
|
||||
mouse_event(MOUSEEVENTF_ABSOLUTE, 100, 100, 0, 0);
|
||||
--
|
||||
2.24.1
|
||||
|
@@ -0,0 +1,173 @@
|
||||
From 35e259f69a7c5a6a065833eaeaca28d92591056b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 14 Nov 2019 18:44:28 +0100
|
||||
Subject: [PATCH 03/12] user32/tests: Add rawinput test for cross-process
|
||||
interactions.
|
||||
|
||||
Validating the rest of the assumption, rawinput messages are not
|
||||
received anymore if the foreground window is from another process.
|
||||
---
|
||||
dlls/user32/tests/input.c | 86 ++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 84 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
|
||||
index bdcc6834d9d..cc7babd1af4 100644
|
||||
--- a/dlls/user32/tests/input.c
|
||||
+++ b/dlls/user32/tests/input.c
|
||||
@@ -49,6 +49,7 @@
|
||||
#define _WIN32_IE 0x0500
|
||||
|
||||
#include <stdarg.h>
|
||||
+#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "windef.h"
|
||||
@@ -1877,8 +1878,36 @@ struct rawinput_mouse_thread_params
|
||||
HWND window;
|
||||
HANDLE ready;
|
||||
HANDLE start;
|
||||
+ const char *argv0;
|
||||
};
|
||||
|
||||
+static void rawinput_mouse_process(void)
|
||||
+{
|
||||
+ HWND window;
|
||||
+ HANDLE start_event, stop_event;
|
||||
+
|
||||
+ start_event = OpenEventA(EVENT_ALL_ACCESS, FALSE, "test_rawinput_mouse_start");
|
||||
+ ok(start_event != 0, "OpenEventA failed, error: %u\n", GetLastError());
|
||||
+
|
||||
+ stop_event = OpenEventA(EVENT_ALL_ACCESS, FALSE, "test_rawinput_mouse_stop");
|
||||
+ ok(stop_event != 0, "OpenEventA failed, error: %u\n", GetLastError());
|
||||
+
|
||||
+ window = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP, 200, 100, 100, 100, 0, NULL, NULL, NULL);
|
||||
+ ok(window != 0, "CreateWindow failed\n");
|
||||
+
|
||||
+ ShowWindow(window, SW_SHOW);
|
||||
+ SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
|
||||
+ SetForegroundWindow(window);
|
||||
+ UpdateWindow(window);
|
||||
+ empty_message_queue();
|
||||
+
|
||||
+ SetEvent(start_event);
|
||||
+ while (MsgWaitForMultipleObjects(1, &stop_event, FALSE, INFINITE, QS_ALLINPUT) != WAIT_OBJECT_0)
|
||||
+ empty_message_queue();
|
||||
+
|
||||
+ DestroyWindow(window);
|
||||
+}
|
||||
+
|
||||
static DWORD WINAPI rawinput_mouse_thread(void *arg)
|
||||
{
|
||||
struct rawinput_mouse_thread_params *params = arg;
|
||||
@@ -1886,6 +1915,11 @@ static DWORD WINAPI rawinput_mouse_thread(void *arg)
|
||||
RECT rect_110 = { 110, 110, 110, 110 };
|
||||
HWND window;
|
||||
int i;
|
||||
+ char path[MAX_PATH];
|
||||
+ PROCESS_INFORMATION process_info;
|
||||
+ STARTUPINFOA startup_info;
|
||||
+ HANDLE start_event, stop_event;
|
||||
+ BOOL ret;
|
||||
|
||||
while (WaitForSingleObject(params->ready, INFINITE) == 0)
|
||||
{
|
||||
@@ -1945,6 +1979,39 @@ static DWORD WINAPI rawinput_mouse_thread(void *arg)
|
||||
|
||||
DestroyWindow(window);
|
||||
break;
|
||||
+ case 7:
|
||||
+ case 8:
|
||||
+ start_event = CreateEventA(NULL, 0, 0, "test_rawinput_mouse_start");
|
||||
+ ok(start_event != 0, "%d: CreateEventA failed, error %u\n", params->step, GetLastError());
|
||||
+
|
||||
+ stop_event = CreateEventA(NULL, 0, 0, "test_rawinput_mouse_stop");
|
||||
+ ok(stop_event != 0, "%d: CreateEventA failed, error %u\n", params->step, GetLastError());
|
||||
+
|
||||
+ 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 test_rawinput_mouse", params->argv0);
|
||||
+ ret = CreateProcessA(NULL, path, NULL, NULL, TRUE, 0, NULL, NULL, &startup_info, &process_info );
|
||||
+ ok(ret, "%d: CreateProcess '%s' failed err %u.\n", params->step, path, GetLastError());
|
||||
+
|
||||
+ ret = WaitForSingleObject(start_event, 5000);
|
||||
+ ok(ret == WAIT_OBJECT_0, "%d: WaitForSingleObject failed\n", params->step);
|
||||
+
|
||||
+ mouse_event(MOUSEEVENTF_MOVE, 1, 1, 0, 0);
|
||||
+ SendMessageA(GetForegroundWindow(), WM_USER, 0, 0);
|
||||
+ mouse_event(MOUSEEVENTF_MOVE, -1, -1, 0, 0);
|
||||
+ SendMessageA(GetForegroundWindow(), WM_USER, 0, 0);
|
||||
+
|
||||
+ SetEvent(stop_event);
|
||||
+
|
||||
+ winetest_wait_child_process(process_info.hProcess);
|
||||
+ CloseHandle(process_info.hProcess);
|
||||
+ CloseHandle(process_info.hThread);
|
||||
+ CloseHandle(start_event);
|
||||
+ CloseHandle(stop_event);
|
||||
+ break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -1967,7 +2034,7 @@ struct rawinput_mouse_test
|
||||
BOOL todo;
|
||||
};
|
||||
|
||||
-static void test_rawinput_mouse(void)
|
||||
+static void test_rawinput_mouse(const char *argv0)
|
||||
{
|
||||
struct rawinput_mouse_thread_params params;
|
||||
RAWINPUTDEVICE raw_devices[1];
|
||||
@@ -1988,11 +2055,17 @@ static void test_rawinput_mouse(void)
|
||||
/* same-process foreground tests */
|
||||
{ TRUE, TRUE, 0, 2, 2, 0, 0, TRUE },
|
||||
{ TRUE, TRUE, RIDEV_INPUTSINK, 2, 2, 0, 0, TRUE },
|
||||
+
|
||||
+ /* cross-process foreground tests */
|
||||
+ { TRUE, TRUE, 0, 0, 0, 0, 0, TRUE },
|
||||
+ { TRUE, TRUE, RIDEV_INPUTSINK, 2, 0, 0, 0, TRUE },
|
||||
};
|
||||
|
||||
mouse_event(MOUSEEVENTF_ABSOLUTE, 100, 100, 0, 0);
|
||||
SetCursorPos(100, 100);
|
||||
|
||||
+ params.argv0 = argv0;
|
||||
+
|
||||
rawinput_wndproc_done = CreateEventA(NULL, FALSE, FALSE, NULL);
|
||||
ok(rawinput_wndproc_done != NULL, "CreateEvent failed\n");
|
||||
|
||||
@@ -3555,11 +3628,20 @@ static void test_GetKeyboardLayoutList(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], "test_rawinput_mouse") == 0)
|
||||
+ {
|
||||
+ rawinput_mouse_process();
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
test_Input_blackbox();
|
||||
test_Input_whitebox();
|
||||
test_Input_unicode();
|
||||
@@ -3578,7 +3660,7 @@ START_TEST(input)
|
||||
test_GetRawInputData();
|
||||
test_GetKeyboardLayoutList();
|
||||
test_RegisterRawInputDevices();
|
||||
- test_rawinput_mouse();
|
||||
+ test_rawinput_mouse(argv[0]);
|
||||
|
||||
if(pGetMouseMovePointsEx)
|
||||
test_GetMouseMovePointsEx();
|
||||
--
|
||||
2.24.1
|
||||
|
@@ -0,0 +1,128 @@
|
||||
From 430580824e975bbda41884affd3e5fbf104ac6fe Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Mon, 26 Aug 2019 14:37:20 +0200
|
||||
Subject: [PATCH 04/12] server: Add send_hardware_message flags for rawinput
|
||||
translation.
|
||||
|
||||
---
|
||||
dlls/user32/input.c | 6 +++---
|
||||
server/protocol.def | 2 ++
|
||||
server/queue.c | 20 ++++++++++++++------
|
||||
3 files changed, 19 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
|
||||
index 340d20e58f9..7d947a98d0f 100644
|
||||
--- a/dlls/user32/input.c
|
||||
+++ b/dlls/user32/input.c
|
||||
@@ -124,7 +124,7 @@ BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret )
|
||||
*/
|
||||
BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input )
|
||||
{
|
||||
- NTSTATUS status = send_hardware_message( hwnd, input, 0 );
|
||||
+ NTSTATUS status = send_hardware_message( hwnd, input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
if (status) SetLastError( RtlNtStatusToDosError(status) );
|
||||
return !status;
|
||||
}
|
||||
@@ -192,9 +192,9 @@ UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size )
|
||||
/* we need to update the coordinates to what the server expects */
|
||||
INPUT input = inputs[i];
|
||||
update_mouse_coords( &input );
|
||||
- status = send_hardware_message( 0, &input, SEND_HWMSG_INJECTED );
|
||||
+ status = send_hardware_message( 0, &input, SEND_HWMSG_INJECTED|SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
}
|
||||
- else status = send_hardware_message( 0, &inputs[i], SEND_HWMSG_INJECTED );
|
||||
+ else status = send_hardware_message( 0, &inputs[i], SEND_HWMSG_INJECTED|SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
|
||||
if (status)
|
||||
{
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index ae3702b150f..9f9f9197134 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -2370,6 +2370,8 @@ enum message_type
|
||||
VARARG(keystate,bytes); /* global state array for all the keys */
|
||||
@END
|
||||
#define SEND_HWMSG_INJECTED 0x01
|
||||
+#define SEND_HWMSG_RAWINPUT 0x02
|
||||
+#define SEND_HWMSG_WINDOW 0x04
|
||||
|
||||
|
||||
/* Get a message from the current queue */
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index af65b5f6b4c..9528453b190 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -1736,7 +1736,7 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa
|
||||
|
||||
/* queue a hardware message for a mouse event */
|
||||
static int queue_mouse_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
|
||||
- unsigned int origin, struct msg_queue *sender )
|
||||
+ unsigned int origin, struct msg_queue *sender, unsigned int req_flags )
|
||||
{
|
||||
const struct rawinput_device *device;
|
||||
struct hardware_msg_data *msg_data;
|
||||
@@ -1789,7 +1789,8 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
y = desktop->cursor.y;
|
||||
}
|
||||
|
||||
- if ((device = current->process->rawinput_mouse))
|
||||
+ if ((device = current->process->rawinput_mouse) &&
|
||||
+ (req_flags & SEND_HWMSG_RAWINPUT))
|
||||
{
|
||||
if (!(msg = alloc_hardware_message( input->mouse.info, source, time ))) return 0;
|
||||
msg_data = msg->data;
|
||||
@@ -1808,6 +1809,9 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
queue_hardware_message( desktop, msg, 0 );
|
||||
}
|
||||
|
||||
+ if (!(req_flags & SEND_HWMSG_WINDOW))
|
||||
+ return 0;
|
||||
+
|
||||
for (i = 0; i < ARRAY_SIZE( messages ); i++)
|
||||
{
|
||||
if (!messages[i]) continue;
|
||||
@@ -1839,7 +1843,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
|
||||
/* queue a hardware message for a keyboard event */
|
||||
static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
|
||||
- unsigned int origin, struct msg_queue *sender )
|
||||
+ unsigned int origin, struct msg_queue *sender, unsigned int req_flags )
|
||||
{
|
||||
struct hw_msg_source source = { IMDT_KEYBOARD, origin };
|
||||
const struct rawinput_device *device;
|
||||
@@ -1915,7 +1919,8 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
break;
|
||||
}
|
||||
|
||||
- if ((device = current->process->rawinput_kbd))
|
||||
+ if ((device = current->process->rawinput_kbd) &&
|
||||
+ (req_flags & SEND_HWMSG_RAWINPUT))
|
||||
{
|
||||
if (!(msg = alloc_hardware_message( input->kbd.info, source, time ))) return 0;
|
||||
msg_data = msg->data;
|
||||
@@ -1933,6 +1938,9 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
queue_hardware_message( desktop, msg, 0 );
|
||||
}
|
||||
|
||||
+ if (!(req_flags & SEND_HWMSG_WINDOW))
|
||||
+ return 0;
|
||||
+
|
||||
if (!(msg = alloc_hardware_message( input->kbd.info, source, time ))) return 0;
|
||||
msg_data = msg->data;
|
||||
|
||||
@@ -2494,10 +2502,10 @@ DECL_HANDLER(send_hardware_message)
|
||||
switch (req->input.type)
|
||||
{
|
||||
case INPUT_MOUSE:
|
||||
- reply->wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender );
|
||||
+ reply->wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender, req->flags );
|
||||
break;
|
||||
case INPUT_KEYBOARD:
|
||||
- reply->wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender );
|
||||
+ reply->wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender, req->flags );
|
||||
break;
|
||||
case INPUT_HARDWARE:
|
||||
queue_custom_hardware_message( desktop, req->win, origin, &req->input );
|
||||
--
|
||||
2.24.1
|
||||
|
@@ -0,0 +1,182 @@
|
||||
From 9a0c9443ada9bccc1d10270398dbf9bddb483d53 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Tue, 12 Nov 2019 12:41:55 +0100
|
||||
Subject: [PATCH 05/12] server: Broadcast rawinput message if request flag is
|
||||
SEND_HWMSG_RAWINPUT.
|
||||
|
||||
If the request flag is equal to SEND_HWMSG_RAWINPUT, we broadcast the
|
||||
message to all listening processes -or at least to the foreground
|
||||
process until RIDEV_INPUTSINK is supported.
|
||||
---
|
||||
dlls/user32/tests/input.c | 2 +-
|
||||
server/queue.c | 98 ++++++++++++++++++++++++++++++---------
|
||||
2 files changed, 78 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
|
||||
index cc7babd1af4..d18ccfebcaf 100644
|
||||
--- a/dlls/user32/tests/input.c
|
||||
+++ b/dlls/user32/tests/input.c
|
||||
@@ -2057,7 +2057,7 @@ static void test_rawinput_mouse(const char *argv0)
|
||||
{ TRUE, TRUE, RIDEV_INPUTSINK, 2, 2, 0, 0, TRUE },
|
||||
|
||||
/* cross-process foreground tests */
|
||||
- { TRUE, TRUE, 0, 0, 0, 0, 0, TRUE },
|
||||
+ { TRUE, TRUE, 0, 0, 0, 0, 0, FALSE },
|
||||
{ TRUE, TRUE, RIDEV_INPUTSINK, 2, 0, 0, 0, TRUE },
|
||||
};
|
||||
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index 9528453b190..2bdd099d1bb 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -1734,12 +1734,67 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa
|
||||
return 1;
|
||||
}
|
||||
|
||||
+struct rawinput_message
|
||||
+{
|
||||
+ struct desktop *desktop;
|
||||
+ struct hw_msg_source source;
|
||||
+ unsigned int time;
|
||||
+ struct hardware_msg_data data;
|
||||
+};
|
||||
+
|
||||
+static int queue_rawinput_message( struct process* process, void* user )
|
||||
+{
|
||||
+ const struct rawinput_message* raw_msg = user;
|
||||
+ const struct rawinput_device *device = NULL;
|
||||
+ struct desktop *desktop = NULL;
|
||||
+ struct thread *thread = NULL, *foreground = NULL;
|
||||
+ struct message *msg;
|
||||
+
|
||||
+ if (raw_msg->data.rawinput.type == RIM_TYPEMOUSE)
|
||||
+ device = process->rawinput_mouse;
|
||||
+ else if (raw_msg->data.rawinput.type == RIM_TYPEKEYBOARD)
|
||||
+ device = process->rawinput_kbd;
|
||||
+
|
||||
+ if (!device)
|
||||
+ goto done;
|
||||
+
|
||||
+ if (!(desktop = get_desktop_obj( process, process->desktop, 0 )) ||
|
||||
+ (raw_msg->desktop && desktop != raw_msg->desktop))
|
||||
+ goto done;
|
||||
+
|
||||
+ if (!(thread = get_window_thread( device->target ? device->target : desktop->foreground_input->active )) ||
|
||||
+ process != thread->process)
|
||||
+ goto done;
|
||||
+
|
||||
+ /* FIXME: Implement RIDEV_INPUTSINK */
|
||||
+ if (!(foreground = get_window_thread( desktop->foreground_input->active )) ||
|
||||
+ thread->process != foreground->process)
|
||||
+ goto done;
|
||||
+
|
||||
+ if (!(msg = alloc_hardware_message( raw_msg->data.info, raw_msg->source, raw_msg->time )))
|
||||
+ goto done;
|
||||
+
|
||||
+ msg->win = device->target;
|
||||
+ msg->msg = WM_INPUT;
|
||||
+ msg->wparam = RIM_INPUT;
|
||||
+ msg->lparam = 0;
|
||||
+ memcpy( msg->data, &raw_msg->data, sizeof(raw_msg->data) );
|
||||
+
|
||||
+ queue_hardware_message( desktop, msg, 0 );
|
||||
+
|
||||
+done:
|
||||
+ if (foreground) release_object( foreground );
|
||||
+ if (thread) release_object( thread );
|
||||
+ if (desktop) release_object( desktop );
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* queue a hardware message for a mouse event */
|
||||
static int queue_mouse_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
|
||||
unsigned int origin, struct msg_queue *sender, unsigned int req_flags )
|
||||
{
|
||||
- const struct rawinput_device *device;
|
||||
struct hardware_msg_data *msg_data;
|
||||
+ struct rawinput_message raw_msg;
|
||||
struct message *msg;
|
||||
unsigned int i, time, flags;
|
||||
struct hw_msg_source source = { IMDT_MOUSE, origin };
|
||||
@@ -1789,24 +1844,24 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
y = desktop->cursor.y;
|
||||
}
|
||||
|
||||
- if ((device = current->process->rawinput_mouse) &&
|
||||
- (req_flags & SEND_HWMSG_RAWINPUT))
|
||||
+ if (req_flags & SEND_HWMSG_RAWINPUT)
|
||||
{
|
||||
- if (!(msg = alloc_hardware_message( input->mouse.info, source, time ))) return 0;
|
||||
- msg_data = msg->data;
|
||||
-
|
||||
- msg->win = device->target;
|
||||
- msg->msg = WM_INPUT;
|
||||
- msg->wparam = RIM_INPUT;
|
||||
- msg->lparam = 0;
|
||||
+ raw_msg.desktop = desktop;
|
||||
+ raw_msg.source = source;
|
||||
+ raw_msg.time = time;
|
||||
|
||||
+ msg_data = &raw_msg.data;
|
||||
+ msg_data->info = input->mouse.info;
|
||||
msg_data->flags = flags;
|
||||
msg_data->rawinput.type = RIM_TYPEMOUSE;
|
||||
msg_data->rawinput.mouse.x = x - desktop->cursor.x;
|
||||
msg_data->rawinput.mouse.y = y - desktop->cursor.y;
|
||||
msg_data->rawinput.mouse.data = input->mouse.data;
|
||||
|
||||
- queue_hardware_message( desktop, msg, 0 );
|
||||
+ if (req_flags == SEND_HWMSG_RAWINPUT)
|
||||
+ enum_processes( queue_rawinput_message, &raw_msg );
|
||||
+ else
|
||||
+ queue_rawinput_message( current->process, &raw_msg );
|
||||
}
|
||||
|
||||
if (!(req_flags & SEND_HWMSG_WINDOW))
|
||||
@@ -1846,8 +1901,8 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
unsigned int origin, struct msg_queue *sender, unsigned int req_flags )
|
||||
{
|
||||
struct hw_msg_source source = { IMDT_KEYBOARD, origin };
|
||||
- const struct rawinput_device *device;
|
||||
struct hardware_msg_data *msg_data;
|
||||
+ struct rawinput_message raw_msg;
|
||||
struct message *msg;
|
||||
unsigned char vkey = input->kbd.vkey;
|
||||
unsigned int message_code, time;
|
||||
@@ -1919,23 +1974,24 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
break;
|
||||
}
|
||||
|
||||
- if ((device = current->process->rawinput_kbd) &&
|
||||
- (req_flags & SEND_HWMSG_RAWINPUT))
|
||||
+ if (req_flags & SEND_HWMSG_RAWINPUT)
|
||||
{
|
||||
- if (!(msg = alloc_hardware_message( input->kbd.info, source, time ))) return 0;
|
||||
- msg_data = msg->data;
|
||||
-
|
||||
- msg->win = device->target;
|
||||
- msg->msg = WM_INPUT;
|
||||
- msg->wparam = RIM_INPUT;
|
||||
+ raw_msg.desktop = desktop;
|
||||
+ raw_msg.source = source;
|
||||
+ raw_msg.time = time;
|
||||
|
||||
+ msg_data = &raw_msg.data;
|
||||
+ msg_data->info = input->kbd.info;
|
||||
msg_data->flags = input->kbd.flags;
|
||||
msg_data->rawinput.type = RIM_TYPEKEYBOARD;
|
||||
msg_data->rawinput.kbd.message = message_code;
|
||||
msg_data->rawinput.kbd.vkey = vkey;
|
||||
msg_data->rawinput.kbd.scan = input->kbd.scan;
|
||||
|
||||
- queue_hardware_message( desktop, msg, 0 );
|
||||
+ if (req_flags == SEND_HWMSG_RAWINPUT)
|
||||
+ enum_processes( queue_rawinput_message, &raw_msg );
|
||||
+ else
|
||||
+ queue_rawinput_message( current->process, &raw_msg );
|
||||
}
|
||||
|
||||
if (!(req_flags & SEND_HWMSG_WINDOW))
|
||||
--
|
||||
2.24.1
|
||||
|
@@ -0,0 +1,193 @@
|
||||
From 8304a54fbb8d34bf4278155624464d2b47ce37cf Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Mon, 26 Aug 2019 15:20:32 +0200
|
||||
Subject: [PATCH 06/12] user32: Add __wine_send_input flags to hint raw input
|
||||
translation.
|
||||
|
||||
---
|
||||
dlls/user32/input.c | 4 ++--
|
||||
dlls/user32/user32.spec | 2 +-
|
||||
dlls/wineandroid.drv/keyboard.c | 2 +-
|
||||
dlls/wineandroid.drv/window.c | 4 ++--
|
||||
dlls/winemac.drv/ime.c | 4 ++--
|
||||
dlls/winemac.drv/keyboard.c | 2 +-
|
||||
dlls/winemac.drv/mouse.c | 2 +-
|
||||
dlls/winex11.drv/keyboard.c | 2 +-
|
||||
dlls/winex11.drv/mouse.c | 8 ++++----
|
||||
include/winuser.h | 2 +-
|
||||
10 files changed, 16 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
|
||||
index 7d947a98d0f..97a5ada922e 100644
|
||||
--- a/dlls/user32/input.c
|
||||
+++ b/dlls/user32/input.c
|
||||
@@ -122,9 +122,9 @@ BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret )
|
||||
*
|
||||
* Internal SendInput function to allow the graphics driver to inject real events.
|
||||
*/
|
||||
-BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input )
|
||||
+BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input, UINT flags )
|
||||
{
|
||||
- NTSTATUS status = send_hardware_message( hwnd, input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
+ NTSTATUS status = send_hardware_message( hwnd, input, flags );
|
||||
if (status) SetLastError( RtlNtStatusToDosError(status) );
|
||||
return !status;
|
||||
}
|
||||
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec
|
||||
index c08ad5ff4f9..b59ba381334 100644
|
||||
--- a/dlls/user32/user32.spec
|
||||
+++ b/dlls/user32/user32.spec
|
||||
@@ -833,5 +833,5 @@
|
||||
# All functions must be prefixed with '__wine_' (for internal functions)
|
||||
# or 'wine_' (for user-visible functions) to avoid namespace conflicts.
|
||||
#
|
||||
-@ cdecl __wine_send_input(long ptr)
|
||||
+@ cdecl __wine_send_input(long ptr long)
|
||||
@ cdecl __wine_set_pixel_format(long long)
|
||||
diff --git a/dlls/wineandroid.drv/keyboard.c b/dlls/wineandroid.drv/keyboard.c
|
||||
index a0f3257f74b..1af8a98f1f9 100644
|
||||
--- a/dlls/wineandroid.drv/keyboard.c
|
||||
+++ b/dlls/wineandroid.drv/keyboard.c
|
||||
@@ -680,7 +680,7 @@ static void send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD flags )
|
||||
input.u.ki.time = 0;
|
||||
input.u.ki.dwExtraInfo = 0;
|
||||
|
||||
- __wine_send_input( hwnd, &input );
|
||||
+ __wine_send_input( hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c
|
||||
index 2fc258dfd90..d96f001432d 100644
|
||||
--- a/dlls/wineandroid.drv/window.c
|
||||
+++ b/dlls/wineandroid.drv/window.c
|
||||
@@ -524,7 +524,7 @@ static int process_events( DWORD mask )
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
- __wine_send_input( capture ? capture : event->data.motion.hwnd, &event->data.motion.input );
|
||||
+ __wine_send_input( capture ? capture : event->data.motion.hwnd, &event->data.motion.input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -538,7 +538,7 @@ static int process_events( DWORD mask )
|
||||
event->data.kbd.input.u.ki.wVk, event->data.kbd.input.u.ki.wVk,
|
||||
event->data.kbd.input.u.ki.wScan );
|
||||
update_keyboard_lock_state( event->data.kbd.input.u.ki.wVk, event->data.kbd.lock_state );
|
||||
- __wine_send_input( 0, &event->data.kbd.input );
|
||||
+ __wine_send_input( 0, &event->data.kbd.input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
break;
|
||||
|
||||
default:
|
||||
diff --git a/dlls/winemac.drv/ime.c b/dlls/winemac.drv/ime.c
|
||||
index dabe6654f98..2ed6e6f66a3 100644
|
||||
--- a/dlls/winemac.drv/ime.c
|
||||
+++ b/dlls/winemac.drv/ime.c
|
||||
@@ -1427,10 +1427,10 @@ void macdrv_im_set_text(const macdrv_event *event)
|
||||
{
|
||||
input.ki.wScan = chars[i];
|
||||
input.ki.dwFlags = KEYEVENTF_UNICODE;
|
||||
- __wine_send_input(hwnd, &input);
|
||||
+ __wine_send_input(hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW);
|
||||
|
||||
input.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
|
||||
- __wine_send_input(hwnd, &input);
|
||||
+ __wine_send_input(hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/dlls/winemac.drv/keyboard.c b/dlls/winemac.drv/keyboard.c
|
||||
index bb408cb20c5..41919baafc7 100644
|
||||
--- a/dlls/winemac.drv/keyboard.c
|
||||
+++ b/dlls/winemac.drv/keyboard.c
|
||||
@@ -929,7 +929,7 @@ static void macdrv_send_keyboard_input(HWND hwnd, WORD vkey, WORD scan, DWORD fl
|
||||
input.ki.time = time;
|
||||
input.ki.dwExtraInfo = 0;
|
||||
|
||||
- __wine_send_input(hwnd, &input);
|
||||
+ __wine_send_input(hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW);
|
||||
}
|
||||
|
||||
|
||||
diff --git a/dlls/winemac.drv/mouse.c b/dlls/winemac.drv/mouse.c
|
||||
index dd6443fe1ba..91cafdf1362 100644
|
||||
--- a/dlls/winemac.drv/mouse.c
|
||||
+++ b/dlls/winemac.drv/mouse.c
|
||||
@@ -165,7 +165,7 @@ static void send_mouse_input(HWND hwnd, macdrv_window cocoa_window, UINT flags,
|
||||
input.mi.time = time;
|
||||
input.mi.dwExtraInfo = 0;
|
||||
|
||||
- __wine_send_input(top_level_hwnd, &input);
|
||||
+ __wine_send_input(top_level_hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW);
|
||||
}
|
||||
|
||||
|
||||
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
|
||||
index 3c38784ebf9..7856b04c8f5 100644
|
||||
--- a/dlls/winex11.drv/keyboard.c
|
||||
+++ b/dlls/winex11.drv/keyboard.c
|
||||
@@ -1149,7 +1149,7 @@ static void X11DRV_send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD f
|
||||
input.u.ki.time = time;
|
||||
input.u.ki.dwExtraInfo = 0;
|
||||
|
||||
- __wine_send_input( hwnd, &input );
|
||||
+ __wine_send_input( hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
}
|
||||
|
||||
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index 8e1eb6d5e0e..96e04509e73 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -659,7 +659,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
|
||||
}
|
||||
input->u.mi.dx += clip_rect.left;
|
||||
input->u.mi.dy += clip_rect.top;
|
||||
- __wine_send_input( hwnd, input );
|
||||
+ __wine_send_input( hwnd, input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -699,7 +699,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
|
||||
- __wine_send_input( hwnd, input );
|
||||
+ __wine_send_input( hwnd, input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
}
|
||||
|
||||
#ifdef SONAME_LIBXCURSOR
|
||||
@@ -1645,7 +1645,7 @@ void move_resize_window( HWND hwnd, int dir )
|
||||
input.u.mi.dwFlags = button_up_flags[button - 1] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
|
||||
input.u.mi.time = GetTickCount();
|
||||
input.u.mi.dwExtraInfo = 0;
|
||||
- __wine_send_input( hwnd, &input );
|
||||
+ __wine_send_input( hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
}
|
||||
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
|
||||
@@ -1884,7 +1884,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
|
||||
|
||||
input.type = INPUT_MOUSE;
|
||||
- __wine_send_input( 0, &input );
|
||||
+ __wine_send_input( 0, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
diff --git a/include/winuser.h b/include/winuser.h
|
||||
index 51c73d25c2f..10cebfa97d0 100644
|
||||
--- a/include/winuser.h
|
||||
+++ b/include/winuser.h
|
||||
@@ -4389,7 +4389,7 @@ static inline BOOL WINAPI SetRectEmpty(LPRECT rect)
|
||||
WORD WINAPI SYSTEM_KillSystemTimer( WORD );
|
||||
|
||||
#ifdef __WINESRC__
|
||||
-WINUSERAPI BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input );
|
||||
+WINUSERAPI BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input, UINT flags );
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
--
|
||||
2.24.1
|
||||
|
@@ -0,0 +1,146 @@
|
||||
From 9038e4871284e636f277be8fc8a2a901049bcaf6 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Fri, 2 Aug 2019 02:24:32 -0400
|
||||
Subject: [PATCH 07/12] winex11.drv: Advertise XInput2 version 2.1 support.
|
||||
|
||||
Under XInput2 protocol version < 2.1, RawEvents are not supposed to be
|
||||
sent if a pointer grab is active. However slave device events are still
|
||||
received regardless of this specification and Wine implemented a
|
||||
workaround to receive RawEvents during pointer grabs by listening to
|
||||
these slave device events. Then, as soon as a mouse button is pressed
|
||||
only the grabbing client will receive the raw motion events.
|
||||
|
||||
By advertising the support of XInput2 version >= 2.1, where RawEvents
|
||||
are sent even during pointer grabs, we ensure to receive the RawMotion
|
||||
events from the desktop window thread, even if a mouse grab is active.
|
||||
|
||||
It is now also possible to simplify the code by listening to master
|
||||
device events only and get rid of slave device id tracking.
|
||||
---
|
||||
dlls/winex11.drv/mouse.c | 49 ++++++++-------------------------------
|
||||
dlls/winex11.drv/x11drv.h | 3 ---
|
||||
2 files changed, 10 insertions(+), 42 deletions(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index 96e04509e73..105db08a78a 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -304,12 +304,16 @@ static void enable_xinput2(void)
|
||||
|
||||
if (data->xi2_state == xi_unknown)
|
||||
{
|
||||
- int major = 2, minor = 0;
|
||||
- if (!pXIQueryVersion( data->display, &major, &minor )) data->xi2_state = xi_disabled;
|
||||
+ int major = 2, minor = 1;
|
||||
+ if (!pXIQueryVersion( data->display, &major, &minor ) && major == 2 && minor > 0)
|
||||
+ {
|
||||
+ TRACE( "XInput2 v%d.%d available\n", major, minor );
|
||||
+ data->xi2_state = xi_disabled;
|
||||
+ }
|
||||
else
|
||||
{
|
||||
data->xi2_state = xi_unavailable;
|
||||
- WARN( "X Input 2 not available\n" );
|
||||
+ WARN( "XInput v2.1 not available\n" );
|
||||
}
|
||||
}
|
||||
if (data->xi2_state == xi_unavailable) return;
|
||||
@@ -317,7 +321,7 @@ static void enable_xinput2(void)
|
||||
|
||||
mask.mask = mask_bits;
|
||||
mask.mask_len = sizeof(mask_bits);
|
||||
- mask.deviceid = XIAllDevices;
|
||||
+ mask.deviceid = XIAllMasterDevices;
|
||||
memset( mask_bits, 0, sizeof(mask_bits) );
|
||||
XISetMask( mask_bits, XI_DeviceChanged );
|
||||
XISetMask( mask_bits, XI_RawMotion );
|
||||
@@ -329,16 +333,6 @@ static void enable_xinput2(void)
|
||||
update_relative_valuators( pointer_info->classes, pointer_info->num_classes );
|
||||
pXIFreeDeviceInfo( pointer_info );
|
||||
|
||||
- /* This device info list is only used to find the initial current slave if
|
||||
- * no XI_DeviceChanged events happened. If any hierarchy change occurred that
|
||||
- * might be relevant here (eg. user switching mice after (un)plugging), a
|
||||
- * XI_DeviceChanged event will point us to the right slave. So this list is
|
||||
- * safe to be obtained statically at enable_xinput2() time.
|
||||
- */
|
||||
- if (data->xi2_devices) pXIFreeDeviceInfo( data->xi2_devices );
|
||||
- data->xi2_devices = pXIQueryDevice( data->display, XIAllDevices, &data->xi2_device_count );
|
||||
- data->xi2_current_slave = 0;
|
||||
-
|
||||
data->xi2_state = xi_enabled;
|
||||
#endif
|
||||
}
|
||||
@@ -359,15 +353,12 @@ static void disable_xinput2(void)
|
||||
|
||||
mask.mask = NULL;
|
||||
mask.mask_len = 0;
|
||||
- mask.deviceid = XIAllDevices;
|
||||
+ mask.deviceid = XIAllMasterDevices;
|
||||
|
||||
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
|
||||
- pXIFreeDeviceInfo( data->xi2_devices );
|
||||
data->x_rel_valuator.number = -1;
|
||||
data->y_rel_valuator.number = -1;
|
||||
- data->xi2_devices = NULL;
|
||||
data->xi2_core_pointer = 0;
|
||||
- data->xi2_current_slave = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1801,7 +1792,6 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev )
|
||||
if (event->reason != XISlaveSwitch) return FALSE;
|
||||
|
||||
update_relative_valuators( event->classes, event->num_classes );
|
||||
- data->xi2_current_slave = event->sourceid;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1822,26 +1812,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
if (thread_data->x_rel_valuator.number < 0 || thread_data->y_rel_valuator.number < 0) return FALSE;
|
||||
if (!event->valuators.mask_len) return FALSE;
|
||||
if (thread_data->xi2_state != xi_enabled) return FALSE;
|
||||
-
|
||||
- /* If there is no slave currently detected, no previous motion nor device
|
||||
- * change events were received. Look it up now on the device list in this
|
||||
- * case.
|
||||
- */
|
||||
- if (!thread_data->xi2_current_slave)
|
||||
- {
|
||||
- XIDeviceInfo *devices = thread_data->xi2_devices;
|
||||
-
|
||||
- for (i = 0; i < thread_data->xi2_device_count; i++)
|
||||
- {
|
||||
- if (devices[i].use != XISlavePointer) continue;
|
||||
- if (devices[i].deviceid != event->deviceid) continue;
|
||||
- if (devices[i].attachment != thread_data->xi2_core_pointer) continue;
|
||||
- thread_data->xi2_current_slave = event->deviceid;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (event->deviceid != thread_data->xi2_current_slave) return FALSE;
|
||||
+ if (event->deviceid != thread_data->xi2_core_pointer) return FALSE;
|
||||
|
||||
x_rel = &thread_data->x_rel_valuator;
|
||||
y_rel = &thread_data->y_rel_valuator;
|
||||
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
|
||||
index cca87433264..432dd5909ca 100644
|
||||
--- a/dlls/winex11.drv/x11drv.h
|
||||
+++ b/dlls/winex11.drv/x11drv.h
|
||||
@@ -340,12 +340,9 @@ struct x11drv_thread_data
|
||||
DWORD clip_reset; /* time when clipping was last reset */
|
||||
HKL kbd_layout; /* active keyboard layout */
|
||||
enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled } xi2_state; /* XInput2 state */
|
||||
- void *xi2_devices; /* list of XInput2 devices (valid when state is enabled) */
|
||||
- int xi2_device_count;
|
||||
struct x11drv_valuator_data x_rel_valuator;
|
||||
struct x11drv_valuator_data y_rel_valuator;
|
||||
int xi2_core_pointer; /* XInput2 core pointer id */
|
||||
- int xi2_current_slave; /* Current slave driving the Core pointer */
|
||||
};
|
||||
|
||||
extern struct x11drv_thread_data *x11drv_init_thread_data(void) DECLSPEC_HIDDEN;
|
||||
--
|
||||
2.24.1
|
||||
|
@@ -0,0 +1,224 @@
|
||||
From ef0b82046445fe430ab85bb8069f3e4536b11f7a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 19 Dec 2019 22:34:44 +0100
|
||||
Subject: [PATCH 08/12] winex11.drv: Keep track of pointer and device button
|
||||
mappings.
|
||||
|
||||
We are going to receive raw button events and we will need to apply the
|
||||
correct button mappings ourselves.
|
||||
|
||||
Original patch by Andrew Eikum <aeikum@codeweavers.com>.
|
||||
---
|
||||
dlls/winex11.drv/keyboard.c | 23 ++++++---
|
||||
dlls/winex11.drv/mouse.c | 89 +++++++++++++++++++++++++++++++++-
|
||||
dlls/winex11.drv/x11drv.h | 1 +
|
||||
dlls/winex11.drv/x11drv_main.c | 1 +
|
||||
4 files changed, 106 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
|
||||
index 7856b04c8f5..3f5d76be57b 100644
|
||||
--- a/dlls/winex11.drv/keyboard.c
|
||||
+++ b/dlls/winex11.drv/keyboard.c
|
||||
@@ -2010,13 +2010,24 @@ BOOL X11DRV_MappingNotify( HWND dummy, XEvent *event )
|
||||
{
|
||||
HWND hwnd;
|
||||
|
||||
- XRefreshKeyboardMapping(&event->xmapping);
|
||||
- X11DRV_InitKeyboard( event->xmapping.display );
|
||||
+ switch (event->xmapping.request)
|
||||
+ {
|
||||
+ case MappingModifier:
|
||||
+ case MappingKeyboard:
|
||||
+ XRefreshKeyboardMapping( &event->xmapping );
|
||||
+ X11DRV_InitKeyboard( event->xmapping.display );
|
||||
+
|
||||
+ hwnd = GetFocus();
|
||||
+ if (!hwnd) hwnd = GetActiveWindow();
|
||||
+ PostMessageW(hwnd, WM_INPUTLANGCHANGEREQUEST,
|
||||
+ 0 /*FIXME*/, (LPARAM)X11DRV_GetKeyboardLayout(0));
|
||||
+ break;
|
||||
+
|
||||
+ case MappingPointer:
|
||||
+ X11DRV_InitMouse( event->xmapping.display );
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- hwnd = GetFocus();
|
||||
- if (!hwnd) hwnd = GetActiveWindow();
|
||||
- PostMessageW(hwnd, WM_INPUTLANGCHANGEREQUEST,
|
||||
- 0 /*FIXME*/, (LPARAM)X11DRV_GetKeyboardLayout(0));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index 105db08a78a..19ed2a29287 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -25,6 +25,9 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/cursorfont.h>
|
||||
#include <stdarg.h>
|
||||
+#ifdef HAVE_X11_EXTENSIONS_XINPUT_H
|
||||
+#include <X11/extensions/XInput.h>
|
||||
+#endif
|
||||
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
@@ -143,6 +146,14 @@ MAKE_FUNCPTR(XISelectEvents);
|
||||
#undef MAKE_FUNCPTR
|
||||
#endif
|
||||
|
||||
+#ifdef HAVE_X11_EXTENSIONS_XINPUT_H
|
||||
+#define MAKE_FUNCPTR(f) static typeof(f) * p##f
|
||||
+MAKE_FUNCPTR(XOpenDevice);
|
||||
+MAKE_FUNCPTR(XCloseDevice);
|
||||
+MAKE_FUNCPTR(XGetDeviceButtonMapping);
|
||||
+#undef MAKE_FUNCPTR
|
||||
+#endif
|
||||
+
|
||||
/***********************************************************************
|
||||
* X11DRV_Xcursor_Init
|
||||
*
|
||||
@@ -249,6 +260,70 @@ void sync_window_cursor( Window window )
|
||||
set_window_cursor( window, cursor );
|
||||
}
|
||||
|
||||
+struct mouse_button_mapping
|
||||
+{
|
||||
+ int deviceid;
|
||||
+ unsigned int button_count;
|
||||
+ unsigned char buttons[256];
|
||||
+};
|
||||
+
|
||||
+static struct mouse_button_mapping *pointer_mapping;
|
||||
+static struct mouse_button_mapping *device_mapping;
|
||||
+
|
||||
+static void update_pointer_mapping( Display *display )
|
||||
+{
|
||||
+ struct mouse_button_mapping *tmp;
|
||||
+
|
||||
+ if (!(tmp = HeapAlloc( GetProcessHeap(), 0, sizeof(*tmp) )))
|
||||
+ {
|
||||
+ WARN("Unable to allocate device mapping.\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ tmp->button_count = ARRAY_SIZE( tmp->buttons );
|
||||
+ tmp->button_count = XGetPointerMapping( display, tmp->buttons, tmp->button_count );
|
||||
+
|
||||
+ tmp = InterlockedExchangePointer( (void**)&pointer_mapping, tmp );
|
||||
+
|
||||
+ HeapFree( GetProcessHeap(), 0, tmp );
|
||||
+}
|
||||
+
|
||||
+static void update_device_mapping( Display *display, int deviceid )
|
||||
+{
|
||||
+#ifdef HAVE_X11_EXTENSIONS_XINPUT_H
|
||||
+ struct mouse_button_mapping *tmp;
|
||||
+ XDevice *device;
|
||||
+
|
||||
+ if (!(device = pXOpenDevice( display, deviceid )))
|
||||
+ {
|
||||
+ WARN( "Unable to open cursor device %d\n", deviceid );
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!(tmp = HeapAlloc( GetProcessHeap(), 0, sizeof(*tmp) )))
|
||||
+ {
|
||||
+ WARN( "Unable to allocate device mapping.\n" );
|
||||
+ pXCloseDevice( display, device );
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ tmp->deviceid = deviceid;
|
||||
+ tmp->button_count = ARRAY_SIZE( tmp->buttons );
|
||||
+ tmp->button_count = pXGetDeviceButtonMapping( display, device, tmp->buttons, tmp->button_count );
|
||||
+
|
||||
+ tmp = InterlockedExchangePointer( (void**)&device_mapping, tmp );
|
||||
+
|
||||
+ HeapFree( GetProcessHeap(), 0, tmp );
|
||||
+
|
||||
+ pXCloseDevice( display, device );
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+void X11DRV_InitMouse( Display *display )
|
||||
+{
|
||||
+ update_pointer_mapping( display );
|
||||
+}
|
||||
+
|
||||
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
/***********************************************************************
|
||||
* update_relative_valuators
|
||||
@@ -1792,6 +1867,8 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev )
|
||||
if (event->reason != XISlaveSwitch) return FALSE;
|
||||
|
||||
update_relative_valuators( event->classes, event->num_classes );
|
||||
+ update_device_mapping( event->display, event->sourceid );
|
||||
+
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1861,13 +1938,12 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
|
||||
#endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */
|
||||
|
||||
-
|
||||
/***********************************************************************
|
||||
* X11DRV_XInput2_Init
|
||||
*/
|
||||
void X11DRV_XInput2_Init(void)
|
||||
{
|
||||
-#if defined(SONAME_LIBXI) && defined(HAVE_X11_EXTENSIONS_XINPUT2_H)
|
||||
+#if defined(SONAME_LIBXI)
|
||||
int event, error;
|
||||
void *libxi_handle = wine_dlopen( SONAME_LIBXI, RTLD_NOW, NULL, 0 );
|
||||
|
||||
@@ -1883,11 +1959,20 @@ void X11DRV_XInput2_Init(void)
|
||||
return; \
|
||||
}
|
||||
|
||||
+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
LOAD_FUNCPTR(XIGetClientPointer);
|
||||
LOAD_FUNCPTR(XIFreeDeviceInfo);
|
||||
LOAD_FUNCPTR(XIQueryDevice);
|
||||
LOAD_FUNCPTR(XIQueryVersion);
|
||||
LOAD_FUNCPTR(XISelectEvents);
|
||||
+#endif
|
||||
+
|
||||
+#ifdef HAVE_X11_EXTENSIONS_XINPUT_H
|
||||
+ LOAD_FUNCPTR(XOpenDevice);
|
||||
+ LOAD_FUNCPTR(XCloseDevice);
|
||||
+ LOAD_FUNCPTR(XGetDeviceButtonMapping);
|
||||
+#endif
|
||||
+
|
||||
#undef LOAD_FUNCPTR
|
||||
|
||||
xinput2_available = XQueryExtension( gdi_display, "XInputExtension", &xinput2_opcode, &event, &error );
|
||||
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
|
||||
index 432dd5909ca..7145fec74e7 100644
|
||||
--- a/dlls/winex11.drv/x11drv.h
|
||||
+++ b/dlls/winex11.drv/x11drv.h
|
||||
@@ -632,6 +632,7 @@ extern void retry_grab_clipping_window(void) DECLSPEC_HIDDEN;
|
||||
extern BOOL clip_fullscreen_window( HWND hwnd, BOOL reset ) DECLSPEC_HIDDEN;
|
||||
extern void move_resize_window( HWND hwnd, int dir ) DECLSPEC_HIDDEN;
|
||||
extern void X11DRV_InitKeyboard( Display *display ) DECLSPEC_HIDDEN;
|
||||
+extern void X11DRV_InitMouse( Display *display ) DECLSPEC_HIDDEN;
|
||||
extern DWORD CDECL X11DRV_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, DWORD timeout,
|
||||
DWORD mask, DWORD flags ) DECLSPEC_HIDDEN;
|
||||
|
||||
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
|
||||
index 11e4ee29155..ff9185a523c 100644
|
||||
--- a/dlls/winex11.drv/x11drv_main.c
|
||||
+++ b/dlls/winex11.drv/x11drv_main.c
|
||||
@@ -623,6 +623,7 @@ static BOOL process_attach(void)
|
||||
if (use_xkb) use_xkb = XkbUseExtension( gdi_display, NULL, NULL );
|
||||
#endif
|
||||
X11DRV_InitKeyboard( gdi_display );
|
||||
+ X11DRV_InitMouse( gdi_display );
|
||||
if (use_xim) use_xim = X11DRV_InitXIM( input_style );
|
||||
|
||||
X11DRV_DisplayDevices_Init(FALSE);
|
||||
--
|
||||
2.24.1
|
||||
|
@@ -0,0 +1,304 @@
|
||||
From e8b90f221774d70fb9510b6de18378ab3abdcad2 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Wed, 11 Sep 2019 10:15:20 +0200
|
||||
Subject: [PATCH 09/12] winex11.drv: Listen to RawMotion and RawButton* events
|
||||
in the desktop thread.
|
||||
|
||||
We still need to send "normal" input from the clipping window thread
|
||||
to trigger low-level hooks callbacks when clipping cursor. This is for
|
||||
instance used in our dinput implementation.
|
||||
---
|
||||
dlls/user32/tests/input.c | 8 ++--
|
||||
dlls/winex11.drv/event.c | 10 +++-
|
||||
dlls/winex11.drv/mouse.c | 88 ++++++++++++++++++++++++++++------
|
||||
dlls/winex11.drv/x11drv.h | 3 ++
|
||||
dlls/winex11.drv/x11drv_main.c | 4 ++
|
||||
5 files changed, 93 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
|
||||
index d18ccfebcaf..a1f983f1960 100644
|
||||
--- a/dlls/user32/tests/input.c
|
||||
+++ b/dlls/user32/tests/input.c
|
||||
@@ -2049,12 +2049,12 @@ static void test_rawinput_mouse(const char *argv0)
|
||||
{ TRUE, TRUE, 0, 2, 2, -1, -1, FALSE },
|
||||
|
||||
/* clip cursor tests */
|
||||
- { TRUE, TRUE, 0, 0, 0, 0, 0, TRUE },
|
||||
- { TRUE, TRUE, 0, 20, 20, 20, 20, TRUE },
|
||||
+ { TRUE, TRUE, 0, 0, 0, 0, 0, FALSE },
|
||||
+ { TRUE, TRUE, 0, 20, 20, 20, 20, FALSE },
|
||||
|
||||
/* same-process foreground tests */
|
||||
- { TRUE, TRUE, 0, 2, 2, 0, 0, TRUE },
|
||||
- { TRUE, TRUE, RIDEV_INPUTSINK, 2, 2, 0, 0, TRUE },
|
||||
+ { TRUE, TRUE, 0, 2, 2, 0, 0, FALSE },
|
||||
+ { TRUE, TRUE, RIDEV_INPUTSINK, 2, 2, 0, 0, FALSE },
|
||||
|
||||
/* cross-process foreground tests */
|
||||
{ TRUE, TRUE, 0, 0, 0, 0, 0, FALSE },
|
||||
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
|
||||
index 87ba808956f..b3faf3f7cc5 100644
|
||||
--- a/dlls/winex11.drv/event.c
|
||||
+++ b/dlls/winex11.drv/event.c
|
||||
@@ -321,6 +321,10 @@ static enum event_merge_action merge_raw_motion_events( XIRawEvent *prev, XIRawE
|
||||
*/
|
||||
static enum event_merge_action merge_events( XEvent *prev, XEvent *next )
|
||||
{
|
||||
+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
+ struct x11drv_thread_data *thread_data = x11drv_thread_data();
|
||||
+#endif
|
||||
+
|
||||
switch (prev->type)
|
||||
{
|
||||
case ConfigureNotify:
|
||||
@@ -352,19 +356,21 @@ static enum event_merge_action merge_events( XEvent *prev, XEvent *next )
|
||||
case GenericEvent:
|
||||
if (next->xcookie.extension != xinput2_opcode) break;
|
||||
if (next->xcookie.evtype != XI_RawMotion) break;
|
||||
- if (x11drv_thread_data()->warp_serial) break;
|
||||
+ if (thread_data->xi2_rawinput_only) break;
|
||||
+ if (thread_data->warp_serial) break;
|
||||
return MERGE_KEEP;
|
||||
}
|
||||
break;
|
||||
case GenericEvent:
|
||||
if (prev->xcookie.extension != xinput2_opcode) break;
|
||||
if (prev->xcookie.evtype != XI_RawMotion) break;
|
||||
+ if (thread_data->xi2_rawinput_only) break;
|
||||
switch (next->type)
|
||||
{
|
||||
case GenericEvent:
|
||||
if (next->xcookie.extension != xinput2_opcode) break;
|
||||
if (next->xcookie.evtype != XI_RawMotion) break;
|
||||
- if (x11drv_thread_data()->warp_serial) break;
|
||||
+ if (thread_data->warp_serial) break;
|
||||
return merge_raw_motion_events( prev->xcookie.data, next->xcookie.data );
|
||||
#endif
|
||||
}
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index 19ed2a29287..d331ed5aef8 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -364,9 +364,9 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
- * enable_xinput2
|
||||
+ * X11DRV_XInput2_Enable
|
||||
*/
|
||||
-static void enable_xinput2(void)
|
||||
+void X11DRV_XInput2_Enable(void)
|
||||
{
|
||||
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
struct x11drv_thread_data *data = x11drv_thread_data();
|
||||
@@ -398,9 +398,21 @@ static void enable_xinput2(void)
|
||||
mask.mask_len = sizeof(mask_bits);
|
||||
mask.deviceid = XIAllMasterDevices;
|
||||
memset( mask_bits, 0, sizeof(mask_bits) );
|
||||
+
|
||||
XISetMask( mask_bits, XI_DeviceChanged );
|
||||
XISetMask( mask_bits, XI_RawMotion );
|
||||
- XISetMask( mask_bits, XI_ButtonPress );
|
||||
+
|
||||
+ if (GetWindowThreadProcessId( GetDesktopWindow(), NULL ) == GetCurrentThreadId())
|
||||
+ {
|
||||
+ XISetMask( mask_bits, XI_RawButtonPress );
|
||||
+ XISetMask( mask_bits, XI_RawButtonRelease );
|
||||
+ data->xi2_rawinput_only = TRUE;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ XISetMask( mask_bits, XI_ButtonPress );
|
||||
+ data->xi2_rawinput_only = FALSE;
|
||||
+ }
|
||||
|
||||
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
|
||||
|
||||
@@ -413,9 +425,9 @@ static void enable_xinput2(void)
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
- * disable_xinput2
|
||||
+ * X11DRV_XInput2_Disable
|
||||
*/
|
||||
-static void disable_xinput2(void)
|
||||
+void X11DRV_XInput2_Disable(void)
|
||||
{
|
||||
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
struct x11drv_thread_data *data = x11drv_thread_data();
|
||||
@@ -475,7 +487,7 @@ static BOOL grab_clipping_window( const RECT *clip )
|
||||
}
|
||||
|
||||
/* enable XInput2 unless we are already clipping */
|
||||
- if (!data->clip_hwnd) enable_xinput2();
|
||||
+ if (!data->clip_hwnd) X11DRV_XInput2_Enable();
|
||||
|
||||
if (data->xi2_state != xi_enabled)
|
||||
{
|
||||
@@ -505,7 +517,7 @@ static BOOL grab_clipping_window( const RECT *clip )
|
||||
|
||||
if (!clipping_cursor)
|
||||
{
|
||||
- disable_xinput2();
|
||||
+ X11DRV_XInput2_Disable();
|
||||
DestroyWindow( msg_hwnd );
|
||||
return FALSE;
|
||||
}
|
||||
@@ -586,7 +598,7 @@ LRESULT clip_cursor_notify( HWND hwnd, HWND prev_clip_hwnd, HWND new_clip_hwnd )
|
||||
TRACE( "clip hwnd reset from %p\n", hwnd );
|
||||
data->clip_hwnd = 0;
|
||||
data->clip_reset = GetTickCount();
|
||||
- disable_xinput2();
|
||||
+ X11DRV_XInput2_Disable();
|
||||
DestroyWindow( hwnd );
|
||||
}
|
||||
else if (hwnd == GetForegroundWindow()) /* request to clip */
|
||||
@@ -725,7 +737,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
|
||||
}
|
||||
input->u.mi.dx += clip_rect.left;
|
||||
input->u.mi.dy += clip_rect.top;
|
||||
- __wine_send_input( hwnd, input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
+ __wine_send_input( hwnd, input, SEND_HWMSG_WINDOW );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -765,7 +777,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
|
||||
- __wine_send_input( hwnd, input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
+ __wine_send_input( hwnd, input, SEND_HWMSG_WINDOW );
|
||||
}
|
||||
|
||||
#ifdef SONAME_LIBXCURSOR
|
||||
@@ -1711,7 +1723,7 @@ void move_resize_window( HWND hwnd, int dir )
|
||||
input.u.mi.dwFlags = button_up_flags[button - 1] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
|
||||
input.u.mi.time = GetTickCount();
|
||||
input.u.mi.dwExtraInfo = 0;
|
||||
- __wine_send_input( hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
+ __wine_send_input( hwnd, &input, SEND_HWMSG_WINDOW );
|
||||
}
|
||||
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
|
||||
@@ -1894,6 +1906,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
x_rel = &thread_data->x_rel_valuator;
|
||||
y_rel = &thread_data->y_rel_valuator;
|
||||
|
||||
+ input.type = INPUT_MOUSE;
|
||||
input.u.mi.mouseData = 0;
|
||||
input.u.mi.dwFlags = MOUSEEVENTF_MOVE;
|
||||
input.u.mi.time = EVENT_x11_time_to_win32_time( event->time );
|
||||
@@ -1929,10 +1942,53 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
|
||||
+ if (!thread_data->xi2_rawinput_only)
|
||||
+ {
|
||||
+ TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
|
||||
+ __wine_send_input( 0, &input, SEND_HWMSG_WINDOW );
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TRACE( "raw pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
|
||||
+ __wine_send_input( 0, &input, SEND_HWMSG_RAWINPUT );
|
||||
+ }
|
||||
+ return TRUE;
|
||||
+}
|
||||
|
||||
- input.type = INPUT_MOUSE;
|
||||
- __wine_send_input( 0, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
+/***********************************************************************
|
||||
+ * X11DRV_RawButtonEvent
|
||||
+ */
|
||||
+static BOOL X11DRV_RawButtonEvent( XGenericEventCookie *cookie )
|
||||
+{
|
||||
+ struct x11drv_thread_data *thread_data = x11drv_thread_data();
|
||||
+ XIRawEvent *event = cookie->data;
|
||||
+ int button = event->detail - 1;
|
||||
+ INPUT input;
|
||||
+
|
||||
+ if (!device_mapping || device_mapping->deviceid != event->sourceid)
|
||||
+ update_device_mapping( event->display, event->sourceid );
|
||||
+
|
||||
+ if (button >= 0 && device_mapping)
|
||||
+ button = device_mapping->buttons[button] - 1;
|
||||
+
|
||||
+ if (button >= 0 && pointer_mapping)
|
||||
+ button = pointer_mapping->buttons[button] - 1;
|
||||
+
|
||||
+ if (button < 0 || button >= NB_BUTTONS) return FALSE;
|
||||
+ if (thread_data->xi2_state != xi_enabled) return FALSE;
|
||||
+ if (event->deviceid != thread_data->xi2_core_pointer) return FALSE;
|
||||
+
|
||||
+ TRACE( "raw button %u (raw: %u) %s\n", button, event->detail, event->evtype == XI_RawButtonRelease ? "up" : "down" );
|
||||
+
|
||||
+ input.type = INPUT_MOUSE;
|
||||
+ input.u.mi.dx = 0;
|
||||
+ input.u.mi.dy = 0;
|
||||
+ input.u.mi.mouseData = event->evtype == XI_RawButtonRelease ? button_up_data[button] : button_down_data[button];
|
||||
+ input.u.mi.dwFlags = event->evtype == XI_RawButtonRelease ? button_up_flags[button] : button_down_flags[button];
|
||||
+ input.u.mi.time = EVENT_x11_time_to_win32_time(event->time);
|
||||
+ input.u.mi.dwExtraInfo = 0;
|
||||
+
|
||||
+ __wine_send_input( 0, &input, SEND_HWMSG_RAWINPUT );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -2008,6 +2064,10 @@ BOOL X11DRV_GenericEvent( HWND hwnd, XEvent *xev )
|
||||
case XI_RawMotion:
|
||||
ret = X11DRV_RawMotion( event );
|
||||
break;
|
||||
+ case XI_RawButtonPress:
|
||||
+ case XI_RawButtonRelease:
|
||||
+ ret = X11DRV_RawButtonEvent( event );
|
||||
+ break;
|
||||
|
||||
default:
|
||||
TRACE( "Unhandled event %#x\n", event->evtype );
|
||||
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
|
||||
index 7145fec74e7..4a7cab67ada 100644
|
||||
--- a/dlls/winex11.drv/x11drv.h
|
||||
+++ b/dlls/winex11.drv/x11drv.h
|
||||
@@ -196,6 +196,8 @@ extern BOOL CDECL X11DRV_UnrealizePalette( HPALETTE hpal ) DECLSPEC_HIDDEN;
|
||||
|
||||
extern void X11DRV_Xcursor_Init(void) DECLSPEC_HIDDEN;
|
||||
extern void X11DRV_XInput2_Init(void) DECLSPEC_HIDDEN;
|
||||
+extern void X11DRV_XInput2_Enable(void) DECLSPEC_HIDDEN;
|
||||
+extern void X11DRV_XInput2_Disable(void) DECLSPEC_HIDDEN;
|
||||
|
||||
extern DWORD copy_image_bits( BITMAPINFO *info, BOOL is_r8g8b8, XImage *image,
|
||||
const struct gdi_image_bits *src_bits, struct gdi_image_bits *dst_bits,
|
||||
@@ -343,6 +345,7 @@ struct x11drv_thread_data
|
||||
struct x11drv_valuator_data x_rel_valuator;
|
||||
struct x11drv_valuator_data y_rel_valuator;
|
||||
int xi2_core_pointer; /* XInput2 core pointer id */
|
||||
+ int xi2_rawinput_only;
|
||||
};
|
||||
|
||||
extern struct x11drv_thread_data *x11drv_init_thread_data(void) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
|
||||
index ff9185a523c..f33a79d98bf 100644
|
||||
--- a/dlls/winex11.drv/x11drv_main.c
|
||||
+++ b/dlls/winex11.drv/x11drv_main.c
|
||||
@@ -640,6 +640,8 @@ void CDECL X11DRV_ThreadDetach(void)
|
||||
|
||||
if (data)
|
||||
{
|
||||
+ if (GetWindowThreadProcessId( GetDesktopWindow(), NULL ) == GetCurrentThreadId())
|
||||
+ X11DRV_XInput2_Disable();
|
||||
if (data->xim) XCloseIM( data->xim );
|
||||
if (data->font_set) XFreeFontSet( data->display, data->font_set );
|
||||
XCloseDisplay( data->display );
|
||||
@@ -712,6 +714,8 @@ struct x11drv_thread_data *x11drv_init_thread_data(void)
|
||||
TlsSetValue( thread_data_tls_index, data );
|
||||
|
||||
if (use_xim) X11DRV_SetupXIM();
|
||||
+ if (GetWindowThreadProcessId( GetDesktopWindow(), NULL ) == GetCurrentThreadId())
|
||||
+ X11DRV_XInput2_Enable();
|
||||
|
||||
return data;
|
||||
}
|
||||
--
|
||||
2.24.1
|
||||
|
@@ -0,0 +1,204 @@
|
||||
From d4dd0d48cec74bd2185eae5a6020c026040c1319 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Mon, 26 Aug 2019 16:06:58 +0200
|
||||
Subject: [PATCH 10/12] user32: Implement GetRegisteredRawInputDevices.
|
||||
|
||||
---
|
||||
dlls/dinput8/tests/device.c | 13 ---------
|
||||
dlls/user32/rawinput.c | 55 +++++++++++++++++++++++++++++++++++--
|
||||
server/protocol.def | 6 ++++
|
||||
server/queue.c | 24 ++++++++++++++++
|
||||
4 files changed, 83 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c
|
||||
index bec2a6b863c..45fc2889066 100644
|
||||
--- a/dlls/dinput8/tests/device.c
|
||||
+++ b/dlls/dinput8/tests/device.c
|
||||
@@ -652,7 +652,6 @@ static void test_mouse_keyboard(void)
|
||||
|
||||
raw_devices_count = ARRAY_SIZE(raw_devices);
|
||||
GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
|
||||
- todo_wine
|
||||
ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
|
||||
|
||||
hr = IDirectInputDevice8_Acquire(di_keyboard);
|
||||
@@ -674,7 +673,6 @@ static void test_mouse_keyboard(void)
|
||||
ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
|
||||
raw_devices_count = ARRAY_SIZE(raw_devices);
|
||||
GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
|
||||
- todo_wine
|
||||
ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
|
||||
|
||||
if (raw_devices[0].hwndTarget != NULL)
|
||||
@@ -712,7 +710,6 @@ static void test_mouse_keyboard(void)
|
||||
ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
|
||||
raw_devices_count = ARRAY_SIZE(raw_devices);
|
||||
GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
|
||||
- todo_wine
|
||||
ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
|
||||
|
||||
/* expect dinput8 to take over any activated raw input devices */
|
||||
@@ -739,26 +736,18 @@ static void test_mouse_keyboard(void)
|
||||
raw_devices_count = ARRAY_SIZE(raw_devices);
|
||||
memset(raw_devices, 0, sizeof(raw_devices));
|
||||
hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
|
||||
- todo_wine
|
||||
ok(hr == 3, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].usUsage == 2, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage);
|
||||
todo_wine
|
||||
ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
|
||||
todo_wine
|
||||
ok(raw_devices[0].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
|
||||
- todo_wine
|
||||
ok(raw_devices[1].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage);
|
||||
- todo_wine
|
||||
ok(raw_devices[1].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage);
|
||||
ok(raw_devices[1].dwFlags == 0, "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags);
|
||||
- todo_wine
|
||||
ok(raw_devices[1].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[1].hwndTarget);
|
||||
- todo_wine
|
||||
ok(raw_devices[2].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage);
|
||||
- todo_wine
|
||||
ok(raw_devices[2].usUsage == 6, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage);
|
||||
todo_wine
|
||||
ok(raw_devices[2].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags);
|
||||
@@ -777,12 +766,10 @@ static void test_mouse_keyboard(void)
|
||||
hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
|
||||
todo_wine
|
||||
ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage);
|
||||
todo_wine
|
||||
ok(raw_devices[0].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage);
|
||||
ok(raw_devices[0].dwFlags == 0, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
|
||||
|
||||
IDirectInputDevice8_Release(di_mouse);
|
||||
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
|
||||
index 85ff0c5e809..3792360b057 100644
|
||||
--- a/dlls/user32/rawinput.c
|
||||
+++ b/dlls/user32/rawinput.c
|
||||
@@ -501,14 +501,65 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT
|
||||
return *data_size;
|
||||
}
|
||||
|
||||
+static int compare_raw_input_devices(const void *ap, const void *bp)
|
||||
+{
|
||||
+ const RAWINPUTDEVICE a = *(const RAWINPUTDEVICE *)ap;
|
||||
+ const RAWINPUTDEVICE b = *(const RAWINPUTDEVICE *)bp;
|
||||
+
|
||||
+ if (a.usUsagePage != b.usUsagePage) return a.usUsagePage - b.usUsagePage;
|
||||
+ if (a.usUsage != b.usUsage) return a.usUsage - b.usUsage;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/***********************************************************************
|
||||
* GetRegisteredRawInputDevices (USER32.@)
|
||||
*/
|
||||
UINT WINAPI DECLSPEC_HOTPATCH GetRegisteredRawInputDevices(RAWINPUTDEVICE *devices, UINT *device_count, UINT size)
|
||||
{
|
||||
- FIXME("devices %p, device_count %p, size %u stub!\n", devices, device_count, size);
|
||||
+ struct rawinput_device *d = NULL;
|
||||
+ unsigned int count = ~0U;
|
||||
|
||||
- return 0;
|
||||
+ TRACE("devices %p, device_count %p, size %u\n", devices, device_count, size);
|
||||
+
|
||||
+ if (!device_count)
|
||||
+ {
|
||||
+ SetLastError(ERROR_INVALID_PARAMETER);
|
||||
+ return ~0U;
|
||||
+ }
|
||||
+
|
||||
+ if (devices && !(d = HeapAlloc( GetProcessHeap(), 0, *device_count * sizeof(*d) )))
|
||||
+ return ~0U;
|
||||
+
|
||||
+ SERVER_START_REQ( get_rawinput_devices )
|
||||
+ {
|
||||
+ if (d)
|
||||
+ wine_server_set_reply( req, d, *device_count * sizeof(*d) );
|
||||
+
|
||||
+ if (wine_server_call( req ))
|
||||
+ goto done;
|
||||
+
|
||||
+ if (!d || reply->device_count > *device_count)
|
||||
+ {
|
||||
+ *device_count = reply->device_count;
|
||||
+ SetLastError( ERROR_INSUFFICIENT_BUFFER );
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ for (count = 0; count < reply->device_count; ++count)
|
||||
+ {
|
||||
+ devices[count].usUsagePage = d[count].usage_page;
|
||||
+ devices[count].usUsage = d[count].usage;
|
||||
+ devices[count].dwFlags = d[count].flags;
|
||||
+ devices[count].hwndTarget = wine_server_ptr_handle(d[count].target);
|
||||
+ }
|
||||
+ }
|
||||
+ SERVER_END_REQ;
|
||||
+
|
||||
+ qsort(devices, count, sizeof(*devices), compare_raw_input_devices);
|
||||
+
|
||||
+done:
|
||||
+ if (d) HeapFree( GetProcessHeap(), 0, d );
|
||||
+ return count;
|
||||
}
|
||||
|
||||
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index 9f9f9197134..d37dceba40c 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -3986,6 +3986,12 @@ struct handle_info
|
||||
VARARG(devices,rawinput_devices);
|
||||
@END
|
||||
|
||||
+/* Retrieve the list of registered rawinput devices */
|
||||
+@REQ(get_rawinput_devices)
|
||||
+@REPLY
|
||||
+ unsigned int device_count;
|
||||
+ VARARG(devices,rawinput_devices);
|
||||
+@END
|
||||
|
||||
/* Retrieve the suspended context of a thread */
|
||||
@REQ(get_suspend_context)
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index 2bdd099d1bb..8a1bbfff5aa 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -3382,3 +3382,27 @@ DECL_HANDLER(esync_msgwait)
|
||||
if (current->process->idle_event && !(queue->wake_mask & QS_SMRESULT))
|
||||
set_event( current->process->idle_event );
|
||||
}
|
||||
+
|
||||
+DECL_HANDLER(get_rawinput_devices)
|
||||
+{
|
||||
+ unsigned int device_count = list_count(¤t->process->rawinput_devices);
|
||||
+ struct rawinput_device *devices;
|
||||
+ struct rawinput_device_entry *e;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ reply->device_count = device_count;
|
||||
+ if (get_reply_max_size() / sizeof (*devices) < device_count)
|
||||
+ return;
|
||||
+
|
||||
+ if (!(devices = mem_alloc( device_count * sizeof (*devices) )))
|
||||
+ {
|
||||
+ set_error( STATUS_NO_MEMORY );
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ i = 0;
|
||||
+ LIST_FOR_EACH_ENTRY( e, ¤t->process->rawinput_devices, struct rawinput_device_entry, entry )
|
||||
+ devices[i++] = e->device;
|
||||
+
|
||||
+ set_reply_data_ptr( devices, device_count * sizeof (*devices) );
|
||||
+}
|
||||
--
|
||||
2.24.1
|
||||
|
@@ -0,0 +1,174 @@
|
||||
From 7f814cd77f1766b98318bbc8ea5fff241c20ec4b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Mon, 26 Aug 2019 16:06:59 +0200
|
||||
Subject: [PATCH 11/12] dinput8: Add support for dinput devices that use raw
|
||||
input interface.
|
||||
|
||||
This adds a global message window that will receive WM_INPUT messages,
|
||||
dispatched to every raw input device event_proc.
|
||||
|
||||
Devices that use raw input interface will not register low-level hooks
|
||||
anymore. They will also conflict with any raw input device registered
|
||||
outside of dinput, as exposed by the unit tests.
|
||||
---
|
||||
dlls/dinput/device_private.h | 3 ++
|
||||
dlls/dinput/dinput_main.c | 84 +++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 86 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
|
||||
index 114e3971ed8..9116aaeab66 100644
|
||||
--- a/dlls/dinput/device_private.h
|
||||
+++ b/dlls/dinput/device_private.h
|
||||
@@ -70,6 +70,9 @@ struct IDirectInputDeviceImpl
|
||||
int acquired;
|
||||
DI_EVENT_PROC event_proc; /* function to receive mouse & keyboard events */
|
||||
|
||||
+ BOOL use_raw_input; /* use raw input instead of low-level messages */
|
||||
+ RAWINPUTDEVICE raw_device; /* raw device to (un)register */
|
||||
+
|
||||
LPDIDEVICEOBJECTDATA data_queue; /* buffer for 'GetDeviceData'. */
|
||||
int queue_len; /* size of the queue - set in 'SetProperty' */
|
||||
int queue_head; /* position to write new event into queue */
|
||||
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
|
||||
index 4d2d4afe106..9e3b9f48250 100644
|
||||
--- a/dlls/dinput/dinput_main.c
|
||||
+++ b/dlls/dinput/dinput_main.c
|
||||
@@ -98,6 +98,10 @@ static const struct dinput_device *dinput_devices[] =
|
||||
|
||||
HINSTANCE DINPUT_instance;
|
||||
|
||||
+static ATOM di_em_win_class;
|
||||
+static const WCHAR di_em_winW[] = {'D','I','E','m','W','i','n',0};
|
||||
+static HWND di_em_win;
|
||||
+
|
||||
static BOOL check_hook_thread(void);
|
||||
static CRITICAL_SECTION dinput_hook_crit;
|
||||
static struct list direct_input_list = LIST_INIT( direct_input_list );
|
||||
@@ -626,6 +630,59 @@ static HRESULT WINAPI IDirectInputWImpl_QueryInterface(LPDIRECTINPUT7W iface, RE
|
||||
return IDirectInputAImpl_QueryInterface( &This->IDirectInput7A_iface, riid, ppobj );
|
||||
}
|
||||
|
||||
+static LRESULT WINAPI di_em_win_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
+{
|
||||
+ IDirectInputImpl *dinput;
|
||||
+
|
||||
+ TRACE( "%p %d %lx %lx\n", hwnd, msg, wparam, lparam );
|
||||
+
|
||||
+ if (msg == WM_INPUT)
|
||||
+ {
|
||||
+ EnterCriticalSection( &dinput_hook_crit );
|
||||
+ LIST_FOR_EACH_ENTRY( dinput, &direct_input_list, IDirectInputImpl, entry )
|
||||
+ {
|
||||
+ IDirectInputDeviceImpl *dev;
|
||||
+
|
||||
+ EnterCriticalSection( &dinput->crit );
|
||||
+ LIST_FOR_EACH_ENTRY( dev, &dinput->devices_list, IDirectInputDeviceImpl, entry )
|
||||
+ {
|
||||
+ if (dev->acquired && dev->event_proc && dev->use_raw_input)
|
||||
+ {
|
||||
+ TRACE("calling %p->%p (%lx %lx)\n", dev, dev->event_proc, wparam, lparam);
|
||||
+ dev->event_proc( &dev->IDirectInputDevice8A_iface, GET_RAWINPUT_CODE_WPARAM(wparam), lparam );
|
||||
+ }
|
||||
+ }
|
||||
+ LeaveCriticalSection( &dinput->crit );
|
||||
+ }
|
||||
+ LeaveCriticalSection( &dinput_hook_crit );
|
||||
+ }
|
||||
+
|
||||
+ return DefWindowProcW(hwnd, msg, wparam, lparam);
|
||||
+}
|
||||
+
|
||||
+static void register_di_em_win_class(void)
|
||||
+{
|
||||
+ static WNDCLASSEXW class;
|
||||
+
|
||||
+ ZeroMemory(&class, sizeof(class));
|
||||
+ class.cbSize = sizeof(class);
|
||||
+ class.lpfnWndProc = di_em_win_wndproc;
|
||||
+ class.hInstance = DINPUT_instance;
|
||||
+ class.lpszClassName = di_em_winW;
|
||||
+
|
||||
+ if (!(di_em_win_class = RegisterClassExW( &class )))
|
||||
+ WARN( "Unable to register message window class\n" );
|
||||
+}
|
||||
+
|
||||
+static void unregister_di_em_win_class(void)
|
||||
+{
|
||||
+ if (!di_em_win_class)
|
||||
+ return;
|
||||
+
|
||||
+ if (!UnregisterClassW( MAKEINTRESOURCEW( di_em_win_class ), DINPUT_instance ))
|
||||
+ WARN( "Unable to unregister message window class\n" );
|
||||
+}
|
||||
+
|
||||
static HRESULT initialize_directinput_instance(IDirectInputImpl *This, DWORD dwVersion)
|
||||
{
|
||||
if (!This->initialized)
|
||||
@@ -1695,7 +1752,7 @@ static LRESULT CALLBACK LL_hook_proc( int code, WPARAM wparam, LPARAM lparam )
|
||||
|
||||
EnterCriticalSection( &dinput->crit );
|
||||
LIST_FOR_EACH_ENTRY( dev, &dinput->devices_list, IDirectInputDeviceImpl, entry )
|
||||
- if (dev->acquired && dev->event_proc)
|
||||
+ if (dev->acquired && dev->event_proc && !dev->use_raw_input)
|
||||
{
|
||||
TRACE("calling %p->%p (%lx %lx)\n", dev, dev->event_proc, wparam, lparam);
|
||||
skip |= dev->event_proc( &dev->IDirectInputDevice8A_iface, wparam, lparam );
|
||||
@@ -1748,6 +1805,9 @@ static DWORD WINAPI hook_thread_proc(void *param)
|
||||
static HHOOK kbd_hook, mouse_hook;
|
||||
MSG msg;
|
||||
|
||||
+ di_em_win = CreateWindowW( MAKEINTRESOURCEW(di_em_win_class), di_em_winW,
|
||||
+ 0, 0, 0, 0, 0, HWND_MESSAGE, 0, DINPUT_instance, NULL );
|
||||
+
|
||||
/* Force creation of the message queue */
|
||||
PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE );
|
||||
SetEvent(param);
|
||||
@@ -1812,6 +1872,9 @@ static DWORD WINAPI hook_thread_proc(void *param)
|
||||
DispatchMessageW(&msg);
|
||||
}
|
||||
|
||||
+ DestroyWindow( di_em_win );
|
||||
+ di_em_win = NULL;
|
||||
+
|
||||
FreeLibraryAndExitThread(DINPUT_instance, 0);
|
||||
}
|
||||
|
||||
@@ -1893,6 +1956,23 @@ void check_dinput_hooks(LPDIRECTINPUTDEVICE8W iface, BOOL acquired)
|
||||
hook_thread_event = NULL;
|
||||
}
|
||||
|
||||
+ if (dev->use_raw_input)
|
||||
+ {
|
||||
+ if (acquired)
|
||||
+ {
|
||||
+ dev->raw_device.dwFlags = RIDEV_INPUTSINK;
|
||||
+ dev->raw_device.hwndTarget = di_em_win;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ dev->raw_device.dwFlags = RIDEV_REMOVE;
|
||||
+ dev->raw_device.hwndTarget = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (!RegisterRawInputDevices( &dev->raw_device, 1, sizeof(RAWINPUTDEVICE) ))
|
||||
+ WARN( "Unable to (un)register raw device %x:%x\n", dev->raw_device.usUsagePage, dev->raw_device.usUsage );
|
||||
+ }
|
||||
+
|
||||
PostThreadMessageW( hook_thread_id, WM_USER+0x10, 1, 0 );
|
||||
|
||||
LeaveCriticalSection(&dinput_hook_crit);
|
||||
@@ -1919,9 +1999,11 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved)
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(inst);
|
||||
DINPUT_instance = inst;
|
||||
+ register_di_em_win_class();
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
if (reserved) break;
|
||||
+ unregister_di_em_win_class();
|
||||
DeleteCriticalSection(&dinput_hook_crit);
|
||||
break;
|
||||
}
|
||||
--
|
||||
2.24.1
|
||||
|
@@ -0,0 +1,195 @@
|
||||
From 4994e308b4f1e21c0d84de23df8c655c4bc5bf9f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Mon, 26 Aug 2019 14:08:20 +0200
|
||||
Subject: [PATCH 12/12] dinput8: Use raw input interface for dinput8 mouse
|
||||
device.
|
||||
|
||||
---
|
||||
dlls/dinput/mouse.c | 117 +++++++++++++++++++++++++++++++++++-
|
||||
dlls/dinput8/tests/device.c | 10 +--
|
||||
2 files changed, 119 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c
|
||||
index 2e0101facec..b8b88f38c15 100644
|
||||
--- a/dlls/dinput/mouse.c
|
||||
+++ b/dlls/dinput/mouse.c
|
||||
@@ -246,6 +246,13 @@ static SysMouseImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
|
||||
list_add_tail(&dinput->devices_list, &newDevice->base.entry);
|
||||
LeaveCriticalSection(&dinput->crit);
|
||||
|
||||
+ if (dinput->dwVersion >= 0x0800)
|
||||
+ {
|
||||
+ newDevice->base.use_raw_input = TRUE;
|
||||
+ newDevice->base.raw_device.usUsagePage = 1; /* HID generic device page */
|
||||
+ newDevice->base.raw_device.usUsage = 2; /* HID generic mouse */
|
||||
+ }
|
||||
+
|
||||
return newDevice;
|
||||
|
||||
failed:
|
||||
@@ -318,7 +325,115 @@ static int dinput_mouse_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM
|
||||
{
|
||||
MSLLHOOKSTRUCT *hook = (MSLLHOOKSTRUCT *)lparam;
|
||||
SysMouseImpl* This = impl_from_IDirectInputDevice8A(iface);
|
||||
- int wdata = 0, inst_id = -1, ret = 0;
|
||||
+ int wdata = 0, inst_id = -1, ret = 0, i;
|
||||
+
|
||||
+ if (wparam == RIM_INPUT || wparam == RIM_INPUTSINK)
|
||||
+ {
|
||||
+ RAWINPUTHEADER raw_header;
|
||||
+ RAWINPUT raw_input;
|
||||
+ UINT size;
|
||||
+ POINT rel, pt;
|
||||
+
|
||||
+ static const USHORT mouse_button_flags[] =
|
||||
+ {
|
||||
+ RI_MOUSE_BUTTON_1_DOWN, RI_MOUSE_BUTTON_1_UP,
|
||||
+ RI_MOUSE_BUTTON_2_DOWN, RI_MOUSE_BUTTON_2_UP,
|
||||
+ RI_MOUSE_BUTTON_3_DOWN, RI_MOUSE_BUTTON_3_UP,
|
||||
+ RI_MOUSE_BUTTON_4_DOWN, RI_MOUSE_BUTTON_4_UP,
|
||||
+ RI_MOUSE_BUTTON_5_DOWN, RI_MOUSE_BUTTON_5_UP
|
||||
+ };
|
||||
+
|
||||
+ TRACE("(%p) wp %08lx, lp %08lx\n", iface, wparam, lparam);
|
||||
+
|
||||
+ size = sizeof(raw_header);
|
||||
+ if (GetRawInputData( (HRAWINPUT)lparam, RID_HEADER, &raw_header, &size, sizeof(RAWINPUTHEADER) ) != sizeof(raw_header))
|
||||
+ {
|
||||
+ WARN( "Unable to read raw input data header\n" );
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (raw_header.dwType != RIM_TYPEMOUSE)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (raw_header.dwSize > sizeof(raw_input))
|
||||
+ {
|
||||
+ WARN( "Unexpected size for mouse raw input data\n" );
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ size = raw_header.dwSize;
|
||||
+ if (GetRawInputData( (HRAWINPUT)lparam, RID_INPUT, &raw_input, &size, sizeof(RAWINPUTHEADER) ) != raw_header.dwSize )
|
||||
+ {
|
||||
+ WARN( "Unable to read raw input data\n" );
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (raw_input.data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP)
|
||||
+ FIXME( "Unimplemented MOUSE_VIRTUAL_DESKTOP flag\n" );
|
||||
+ if (raw_input.data.mouse.usFlags & MOUSE_ATTRIBUTES_CHANGED)
|
||||
+ FIXME( "Unimplemented MOUSE_ATTRIBUTES_CHANGED flag\n" );
|
||||
+
|
||||
+ EnterCriticalSection(&This->base.crit);
|
||||
+
|
||||
+ rel.x = raw_input.data.mouse.lLastX;
|
||||
+ rel.y = raw_input.data.mouse.lLastY;
|
||||
+ if (raw_input.data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE)
|
||||
+ {
|
||||
+ GetCursorPos(&pt);
|
||||
+ rel.x -= pt.x;
|
||||
+ rel.y -= pt.y;
|
||||
+ }
|
||||
+
|
||||
+ This->m_state.lX += rel.x;
|
||||
+ This->m_state.lY += rel.y;
|
||||
+
|
||||
+ if (This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS)
|
||||
+ {
|
||||
+ pt.x = This->m_state.lX;
|
||||
+ pt.y = This->m_state.lY;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ pt = rel;
|
||||
+ }
|
||||
+
|
||||
+ if (rel.x)
|
||||
+ queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS,
|
||||
+ pt.x, GetCurrentTime(), This->base.dinput->evsequence);
|
||||
+
|
||||
+ if (rel.y)
|
||||
+ queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS,
|
||||
+ pt.y, GetCurrentTime(), This->base.dinput->evsequence);
|
||||
+
|
||||
+ if (rel.x || rel.y)
|
||||
+ {
|
||||
+ if ((This->warp_override == WARP_FORCE_ON) ||
|
||||
+ (This->warp_override != WARP_DISABLE && (This->base.dwCoopLevel & DISCL_EXCLUSIVE)))
|
||||
+ This->need_warp = TRUE;
|
||||
+ }
|
||||
+
|
||||
+ if (raw_input.data.mouse.usButtonFlags & RI_MOUSE_WHEEL)
|
||||
+ {
|
||||
+ This->m_state.lZ += (wdata = (SHORT)raw_input.data.mouse.usButtonData);
|
||||
+ queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_Z_AXIS_INSTANCE) | DIDFT_RELAXIS,
|
||||
+ wdata, GetCurrentTime(), This->base.dinput->evsequence);
|
||||
+ ret = This->clipped;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(mouse_button_flags); ++i)
|
||||
+ {
|
||||
+ if (raw_input.data.mouse.usButtonFlags & mouse_button_flags[i])
|
||||
+ {
|
||||
+ This->m_state.rgbButtons[i / 2] = 0x80 - (i % 2) * 0x80;
|
||||
+ queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + (i / 2)) | DIDFT_PSHBUTTON,
|
||||
+ This->m_state.rgbButtons[i / 2], GetCurrentTime(), This->base.dinput->evsequence);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ LeaveCriticalSection(&This->base.crit);
|
||||
+
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
TRACE("msg %lx @ (%d %d)\n", wparam, hook->pt.x, hook->pt.y);
|
||||
|
||||
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c
|
||||
index 45fc2889066..42ba78707c6 100644
|
||||
--- a/dlls/dinput8/tests/device.c
|
||||
+++ b/dlls/dinput8/tests/device.c
|
||||
@@ -696,13 +696,9 @@ static void test_mouse_keyboard(void)
|
||||
raw_devices_count = ARRAY_SIZE(raw_devices);
|
||||
memset(raw_devices, 0, sizeof(raw_devices));
|
||||
hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
|
||||
- todo_wine
|
||||
ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].usUsage == 2, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
|
||||
todo_wine
|
||||
ok(raw_devices[0].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
|
||||
@@ -712,6 +708,9 @@ static void test_mouse_keyboard(void)
|
||||
GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
|
||||
ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
|
||||
|
||||
+ if (raw_devices[0].hwndTarget != NULL)
|
||||
+ di_hwnd = raw_devices[0].hwndTarget;
|
||||
+
|
||||
/* expect dinput8 to take over any activated raw input devices */
|
||||
raw_devices[0].usUsagePage = 0x01;
|
||||
raw_devices[0].usUsage = 0x05;
|
||||
@@ -739,9 +738,7 @@ static void test_mouse_keyboard(void)
|
||||
ok(hr == 3, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
|
||||
ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage);
|
||||
ok(raw_devices[0].usUsage == 2, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
|
||||
ok(raw_devices[1].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage);
|
||||
ok(raw_devices[1].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage);
|
||||
@@ -767,7 +764,6 @@ static void test_mouse_keyboard(void)
|
||||
todo_wine
|
||||
ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
|
||||
ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage);
|
||||
ok(raw_devices[0].dwFlags == 0, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
|
||||
ok(raw_devices[0].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
|
||||
--
|
||||
2.24.1
|
||||
|
2
patches/user32-rawinput-mouse/definition
Normal file
2
patches/user32-rawinput-mouse/definition
Normal file
@@ -0,0 +1,2 @@
|
||||
Fixes: [42631] - user32: Add Raw Input support.
|
||||
Depends: winex11.drv-mouse-coorrds
|
Reference in New Issue
Block a user