user32-rawinput-*: Replace with new patches from Rémi Bernon.

This commit is contained in:
Zebediah Figura 2021-04-09 17:39:38 -05:00
parent 64ea26c0cb
commit 661df7b889
40 changed files with 3294 additions and 1296 deletions

View File

@ -240,6 +240,9 @@ patch_enable_all ()
enable_user32_ScrollWindowEx="$1"
enable_user32_message_order="$1"
enable_user32_msgbox_Support_WM_COPY_mesg="$1"
enable_user32_rawinput_hid="$1"
enable_user32_rawinput_mouse="$1"
enable_user32_rawinput_mouse_experimental="$1"
enable_user32_recursive_activation="$1"
enable_uxtheme_CloseThemeClass="$1"
enable_version_VerQueryValue="$1"
@ -777,6 +780,15 @@ patch_enable ()
user32-msgbox-Support-WM_COPY-mesg)
enable_user32_msgbox_Support_WM_COPY_mesg="$2"
;;
user32-rawinput-hid)
enable_user32_rawinput_hid="$2"
;;
user32-rawinput-mouse)
enable_user32_rawinput_mouse="$2"
;;
user32-rawinput-mouse-experimental)
enable_user32_rawinput_mouse_experimental="$2"
;;
user32-recursive-activation)
enable_user32_recursive_activation="$2"
;;
@ -1320,6 +1332,27 @@ if test "$enable_wineboot_ProxySettings" -eq 1; then
enable_wineboot_drivers_etc_Stubs=1
fi
if test "$enable_user32_rawinput_mouse_experimental" -eq 1; then
if test "$enable_user32_rawinput_mouse" -gt 1; then
abort "Patchset user32-rawinput-mouse disabled, but user32-rawinput-mouse-experimental depends on that."
fi
enable_user32_rawinput_mouse=1
fi
if test "$enable_user32_rawinput_mouse" -eq 1; then
if test "$enable_user32_rawinput_hid" -gt 1; then
abort "Patchset user32-rawinput-hid disabled, but user32-rawinput-mouse depends on that."
fi
enable_user32_rawinput_hid=1
fi
if test "$enable_user32_rawinput_hid" -eq 1; then
if test "$enable_loader_KeyboardLayouts" -gt 1; then
abort "Patchset loader-KeyboardLayouts disabled, but user32-rawinput-hid depends on that."
fi
enable_loader_KeyboardLayouts=1
fi
if test "$enable_stdole32_tlb_SLTG_Typelib" -eq 1; then
if test "$enable_widl_SLTG_Typelib_Support" -gt 1; then
abort "Patchset widl-SLTG_Typelib_Support disabled, but stdole32.tlb-SLTG_Typelib depends on that."
@ -3864,6 +3897,89 @@ if test "$enable_user32_msgbox_Support_WM_COPY_mesg" -eq 1; then
patch_apply user32-msgbox-Support-WM_COPY-mesg/0002-user32-msgbox-Use-a-windows-hook-to-trap-Ctrl-C.patch
fi
# Patchset user32-rawinput-hid
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * loader-KeyboardLayouts
# |
# | This patchset fixes the following Wine bugs:
# | * [#50506] WM_INPUT messages are not received for HID devices registered with RegisterRawInputDevices
# |
# | Modified files:
# | * dlls/hidclass.sys/Makefile.in, dlls/hidclass.sys/device.c, dlls/hidclass.sys/hid.h, dlls/hidclass.sys/pnp.c,
# | dlls/ntoskrnl.exe/ntoskrnl.exe.spec, dlls/ntoskrnl.exe/pnp.c, dlls/user32/input.c, dlls/user32/message.c,
# | dlls/user32/rawinput.c, dlls/user32/tests/input.c, dlls/user32/user32.spec, dlls/user32/user_private.h,
# | dlls/wineandroid.drv/keyboard.c, dlls/wineandroid.drv/window.c, dlls/winemac.drv/ime.c, dlls/winemac.drv/keyboard.c,
# | dlls/winemac.drv/mouse.c, dlls/winex11.drv/keyboard.c, dlls/winex11.drv/mouse.c, include/ddk/wdm.h, include/winuser.h,
# | server/protocol.def, server/queue.c, server/trace.c
# |
if test "$enable_user32_rawinput_hid" -eq 1; then
patch_apply user32-rawinput-hid/0001-user32-tests-Add-more-SendInput-tests.patch
patch_apply user32-rawinput-hid/0002-user32-Implement-SendInput-INPUT_HARDWARE-check.patch
patch_apply user32-rawinput-hid/0003-user32-Add-RAWINPUT-parameter-to-__wine_send_input.patch
patch_apply user32-rawinput-hid/0004-hidclass.sys-Assign-rawinput-device-handle-in-HID_Li.patch
patch_apply user32-rawinput-hid/0005-hidclass.sys-Use-__wine_send_input-to-send-device-no.patch
patch_apply user32-rawinput-hid/0006-server-Implement-desktop-broadcast-in-queue_rawinput.patch
patch_apply user32-rawinput-hid/0007-server-Add-rawinput-union-to-hw_input_t-INPUT_HARDWA.patch
patch_apply user32-rawinput-hid/0008-server-Add-RIM_TYPEHID-type-hid-member-to-rawinput-u.patch
patch_apply user32-rawinput-hid/0009-user32-Send-WM_INPUT_DEVICE_CHANGE-RAWINPUT-to-the-s.patch
patch_apply user32-rawinput-hid/0010-server-Track-known-HID-rawinput-devices-on-addition-.patch
patch_apply user32-rawinput-hid/0011-server-Add-process-argument-to-find_rawinput_device.patch
patch_apply user32-rawinput-hid/0012-server-Implement-WM_INPUT_DEVICE_CHANGE-message-disp.patch
patch_apply user32-rawinput-hid/0013-hidclass.sys-Send-rawinput-messages-with-HID-report.patch
patch_apply user32-rawinput-hid/0014-server-Add-extra-data-to-hardware_msg_data.patch
patch_apply user32-rawinput-hid/0015-server-Implement-WM_INPUT-RIM_TYPEHID-message-dispat.patch
patch_apply user32-rawinput-hid/0016-ntoskrnl-Implement-IoSetDevicePropertyData.patch
patch_apply user32-rawinput-hid/0017-hidclass.sys-Assign-rawinput-handles-through-device-.patch
patch_apply user32-rawinput-hid/0018-user32-Enumerate-mouse-rawinput-device-before-HID-de.patch
patch_apply user32-rawinput-hid/0019-user32-Use-device-handles-assigned-by-hidclass.sys.patch
fi
# Patchset user32-rawinput-mouse
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * loader-KeyboardLayouts, user32-rawinput-hid
# |
# | This patchset fixes the following Wine bugs:
# | * [#42631] Mouse drift, jump or don't react to small slow movements in Unity-engine games and Fallout 4 (partly fixed in
# | Unity games, have walkaround in Fallout4 )
# | * [#42675] Overwatch: Phantom mouse input / view pulled up to ceiling
# |
# | Modified files:
# | * dlls/user32/input.c, dlls/user32/message.c, dlls/wineandroid.drv/keyboard.c, dlls/wineandroid.drv/window.c,
# | dlls/winemac.drv/ime.c, dlls/winemac.drv/keyboard.c, dlls/winemac.drv/mouse.c, dlls/winex11.drv/desktop.c,
# | dlls/winex11.drv/event.c, dlls/winex11.drv/keyboard.c, dlls/winex11.drv/mouse.c, dlls/winex11.drv/window.c,
# | dlls/winex11.drv/x11drv.h, dlls/winex11.drv/x11drv_main.c, server/protocol.def, server/queue.c
# |
if test "$enable_user32_rawinput_mouse" -eq 1; then
patch_apply user32-rawinput-mouse/0001-winex11.drv-Split-XInput2-thread-initialization.patch
patch_apply user32-rawinput-mouse/0002-winex11.drv-Support-XInput2-events-for-individual-wi.patch
patch_apply user32-rawinput-mouse/0003-winex11.drv-Advertise-XInput2-version-2.1-support.patch
patch_apply user32-rawinput-mouse/0004-winex11.drv-Keep-track-of-pointer-and-device-button-.patch
patch_apply user32-rawinput-mouse/0005-server-Add-send_hardware_message-flags-for-rawinput-.patch
patch_apply user32-rawinput-mouse/0006-user32-Set-SEND_HWMSG_RAWINPUT-flags-only-when-RAWIN.patch
patch_apply user32-rawinput-mouse/0007-user32-Support-sending-RIM_TYPEMOUSE-through-__wine_.patch
patch_apply user32-rawinput-mouse/0008-winex11.drv-Listen-to-RawMotion-and-RawButton-events.patch
fi
# Patchset user32-rawinput-mouse-experimental
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * loader-KeyboardLayouts, user32-rawinput-hid, user32-rawinput-mouse
# |
# | This patchset fixes the following Wine bugs:
# | * [#45882] - Raw Input should use untransformed mouse values (affects Overwatch, several Source games).
# |
# | Modified files:
# | * dlls/user32/rawinput.c, dlls/winex11.drv/mouse.c, dlls/winex11.drv/window.c, dlls/winex11.drv/x11drv.h,
# | dlls/winex11.drv/x11drv_main.c, server/queue.c
# |
if test "$enable_user32_rawinput_mouse_experimental" -eq 1; then
patch_apply user32-rawinput-mouse-experimental/0001-winex11.drv-Add-support-for-absolute-RawMotion-event.patch
patch_apply user32-rawinput-mouse-experimental/0002-winex11.drv-Send-relative-RawMotion-events-unprocess.patch
patch_apply user32-rawinput-mouse-experimental/0003-winex11.drv-Accumulate-mouse-movement-to-avoid-round.patch
fi
# Patchset user32-recursive-activation
# |
# | This patchset fixes the following Wine bugs:

View File

@ -0,0 +1,185 @@
From ce4894689736dc2e49b2b7550802ab1f2a4eb462 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 9 Mar 2021 12:02:18 +0100
Subject: [PATCH] user32/tests: Add more SendInput tests.
Validating that SendInput with INPUT_HARDWARE type should be no-op.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
---
dlls/user32/input.c | 18 ++++++
dlls/user32/tests/input.c | 122 ++++++++++++++++++++++++++++++++++++++
2 files changed, 140 insertions(+)
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 8992c463c48..22e53585f00 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -182,6 +182,24 @@ UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size )
UINT i;
NTSTATUS status;
+ if (size != sizeof(INPUT))
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return 0;
+ }
+
+ if (!count)
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return 0;
+ }
+
+ if (!inputs)
+ {
+ SetLastError( ERROR_NOACCESS );
+ return 0;
+ }
+
for (i = 0; i < count; i++)
{
if (inputs[i].type == INPUT_MOUSE)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
index 06f90291fd1..0584f89f55a 100644
--- a/dlls/user32/tests/input.c
+++ b/dlls/user32/tests/input.c
@@ -4246,6 +4246,127 @@ static void test_GetKeyboardLayoutList(void)
}
}
+static void test_SendInput(void)
+{
+ INPUT input[16];
+ UINT res, i;
+ HWND hwnd;
+ MSG msg;
+
+ hwnd = CreateWindowW( L"static", L"test", WS_OVERLAPPED, 0, 0, 100, 100, 0, 0, 0, 0 );
+ ok( hwnd != 0, "CreateWindowW failed\n" );
+
+ ShowWindow( hwnd, SW_SHOWNORMAL );
+ UpdateWindow( hwnd );
+ SetForegroundWindow( hwnd );
+ SetFocus( hwnd );
+ empty_message_queue();
+
+ SetLastError( 0xdeadbeef );
+ res = SendInput( 0, NULL, 0 );
+ ok( res == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "SendInput returned %u, error %#x\n", res, GetLastError() );
+ SetLastError( 0xdeadbeef );
+ res = SendInput( 1, NULL, 0 );
+ ok( res == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "SendInput returned %u, error %#x\n", res, GetLastError() );
+ SetLastError( 0xdeadbeef );
+ res = SendInput( 1, NULL, sizeof(*input) );
+ ok( res == 0 && (GetLastError() == ERROR_NOACCESS || GetLastError() == ERROR_INVALID_PARAMETER),
+ "SendInput returned %u, error %#x\n", res, GetLastError() );
+ SetLastError( 0xdeadbeef );
+ res = SendInput( 0, input, sizeof(*input) );
+ ok( res == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "SendInput returned %u, error %#x\n", res, GetLastError() );
+ SetLastError( 0xdeadbeef );
+ res = SendInput( 0, NULL, sizeof(*input) );
+ ok( res == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "SendInput returned %u, error %#x\n", res, GetLastError() );
+
+ memset( input, 0, sizeof(input) );
+ SetLastError( 0xdeadbeef );
+ res = SendInput( 1, input, sizeof(*input) );
+ ok( res == 1 && GetLastError() == 0xdeadbeef, "SendInput returned %u, error %#x\n", res, GetLastError() );
+ SetLastError( 0xdeadbeef );
+ res = SendInput( 16, input, sizeof(*input) );
+ ok( res == 16 && GetLastError() == 0xdeadbeef, "SendInput returned %u, error %#x\n", res, GetLastError() );
+
+ SetLastError( 0xdeadbeef );
+ res = SendInput( 1, input, 0 );
+ ok( res == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "SendInput returned %u, error %#x\n", res, GetLastError() );
+ SetLastError( 0xdeadbeef );
+ res = SendInput( 1, input, sizeof(*input) + 1 );
+ ok( res == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "SendInput returned %u, error %#x\n", res, GetLastError() );
+ SetLastError( 0xdeadbeef );
+ res = SendInput( 1, input, sizeof(*input) - 1 );
+ ok( res == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "SendInput returned %u, error %#x\n", res, GetLastError() );
+
+ for (i = 0; i < ARRAY_SIZE(input); ++i) input[i].type = INPUT_KEYBOARD;
+ SetLastError( 0xdeadbeef );
+ res = SendInput( 16, input, offsetof( INPUT, ki ) + sizeof(KEYBDINPUT) );
+ ok( res == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "SendInput returned %u, error %#x\n", res, GetLastError() );
+ SetLastError( 0xdeadbeef );
+ res = SendInput( 16, input, sizeof(*input) );
+ ok( res == 16 && GetLastError() == 0xdeadbeef, "SendInput returned %u, error %#x\n", res, GetLastError() );
+ empty_message_queue();
+
+ for (i = 0; i < ARRAY_SIZE(input); ++i) input[i].type = INPUT_HARDWARE;
+ SetLastError( 0xdeadbeef );
+ res = SendInput( 16, input, offsetof( INPUT, hi ) + sizeof(HARDWAREINPUT) );
+ ok( res == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "SendInput returned %u, error %#x\n", res, GetLastError() );
+
+ input[0].hi.uMsg = WM_KEYDOWN;
+ input[0].hi.wParamL = 0;
+ input[0].hi.wParamH = 'A';
+ input[1].hi.uMsg = WM_KEYUP;
+ input[1].hi.wParamL = 0;
+ input[1].hi.wParamH = 'A' | 0xc000;
+ SetLastError( 0xdeadbeef );
+ res = SendInput( 16, input, sizeof(*input) );
+#ifdef _WIN64
+ todo_wine
+ ok( res == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, "SendInput returned %u, error %#x\n", res, GetLastError() );
+#else
+ ok( res == 16 && GetLastError() == 0xdeadbeef, "SendInput returned %u, error %#x\n", res, GetLastError() );
+#endif
+ while ((res = wait_for_message(&msg)) && msg.message == WM_TIMER) DispatchMessageA(&msg);
+ todo_wine ok( !res, "SendInput triggered unexpected message %#x\n", msg.message );
+ empty_message_queue();
+
+ memset( input, 0, sizeof(input) );
+ input[0].type = INPUT_HARDWARE;
+ input[1].type = INPUT_KEYBOARD;
+ input[1].ki.wVk = 'A';
+ input[1].ki.dwFlags = 0;
+ input[2].type = INPUT_KEYBOARD;
+ input[2].ki.wVk = 'A';
+ input[2].ki.dwFlags = KEYEVENTF_KEYUP;
+ SetLastError( 0xdeadbeef );
+ res = SendInput( 16, input, sizeof(*input) );
+#ifdef _WIN64
+ todo_wine ok( res == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, "SendInput returned %u, error %#x\n", res, GetLastError() );
+ while ((res = wait_for_message(&msg)) && msg.message == WM_TIMER) DispatchMessageA(&msg);
+ todo_wine ok( !res, "SendInput triggered unexpected message %#x\n", msg.message );
+ empty_message_queue();
+#else
+ ok( res == 16 && GetLastError() == 0xdeadbeef, "SendInput returned %u, error %#x\n", res, GetLastError() );
+ while ((res = wait_for_message(&msg)) && msg.message == WM_TIMER) DispatchMessageA(&msg);
+ ok( !!res, "SendInput did not trigger any message\n" );
+ todo_wine ok( msg.message == WM_KEYDOWN, "SendInput triggered unexpected message %#x\n", msg.message );
+ while ((res = wait_for_message(&msg)) && msg.message == WM_TIMER) DispatchMessageA(&msg);
+ ok( !!res, "SendInput did not trigger any message\n" );
+ todo_wine ok( msg.message == WM_KEYUP, "SendInput triggered unexpected message %#x\n", msg.message );
+ empty_message_queue();
+#endif
+
+ for (i = 0; i < ARRAY_SIZE(input); ++i) input[i].type = INPUT_HARDWARE + 1;
+ SetLastError( 0xdeadbeef );
+ res = SendInput( 16, input, sizeof(*input) );
+ todo_wine ok( res == 16 && GetLastError() == 0xdeadbeef, "SendInput returned %u, error %#x\n", res, GetLastError() );
+ while ((res = wait_for_message(&msg)) && msg.message == WM_TIMER) DispatchMessageA(&msg);
+ todo_wine ok( !res, "SendInput triggered unexpected message %#x\n", msg.message );
+ empty_message_queue();
+
+ trace( "done\n" );
+ DestroyWindow( hwnd );
+}
+
START_TEST(input)
{
char **argv;
@@ -4268,6 +4389,7 @@ START_TEST(input)
return;
}
+ test_SendInput();
test_Input_blackbox();
test_Input_whitebox();
test_Input_unicode();
--
2.30.2

View File

@ -0,0 +1,106 @@
From d9554c180611116398e700ed7f2d8f021bd06924 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Wed, 7 Apr 2021 10:34:23 +0200
Subject: [PATCH] user32: Implement SendInput INPUT_HARDWARE check.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
---
dlls/user32/input.c | 16 ++++++++++++----
dlls/user32/tests/input.c | 15 +++++++--------
2 files changed, 19 insertions(+), 12 deletions(-)
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 22e53585f00..e97264960ea 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -180,7 +180,7 @@ static void update_mouse_coords( INPUT *input )
UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size )
{
UINT i;
- NTSTATUS status;
+ NTSTATUS status = STATUS_SUCCESS;
if (size != sizeof(INPUT))
{
@@ -202,14 +202,22 @@ UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size )
for (i = 0; i < count; i++)
{
- if (inputs[i].type == INPUT_MOUSE)
+ INPUT input = inputs[i];
+ switch (input.type)
{
+ case INPUT_MOUSE:
/* we need to update the coordinates to what the server expects */
- INPUT input = inputs[i];
update_mouse_coords( &input );
+ /* fallthrough */
+ case INPUT_KEYBOARD:
status = send_hardware_message( 0, &input, SEND_HWMSG_INJECTED );
+ break;
+#ifdef _WIN64
+ case INPUT_HARDWARE:
+ SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
+ return 0;
+#endif
}
- else status = send_hardware_message( 0, &inputs[i], SEND_HWMSG_INJECTED );
if (status)
{
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
index f48807a27a0..564ab2e1ba0 100644
--- a/dlls/user32/tests/input.c
+++ b/dlls/user32/tests/input.c
@@ -4286,13 +4286,12 @@ static void test_SendInput(void)
SetLastError( 0xdeadbeef );
res = SendInput( 16, input, sizeof(*input) );
#ifdef _WIN64
- todo_wine
ok( res == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, "SendInput returned %u, error %#x\n", res, GetLastError() );
#else
ok( res == 16 && GetLastError() == 0xdeadbeef, "SendInput returned %u, error %#x\n", res, GetLastError() );
#endif
while ((res = wait_for_message(&msg)) && msg.message == WM_TIMER) DispatchMessageA(&msg);
- todo_wine ok( !res, "SendInput triggered unexpected message %#x\n", msg.message );
+ ok( !res, "SendInput triggered unexpected message %#x\n", msg.message );
empty_message_queue();
memset( input, 0, sizeof(input) );
@@ -4306,27 +4305,27 @@ static void test_SendInput(void)
SetLastError( 0xdeadbeef );
res = SendInput( 16, input, sizeof(*input) );
#ifdef _WIN64
- todo_wine ok( res == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, "SendInput returned %u, error %#x\n", res, GetLastError() );
+ ok( res == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, "SendInput returned %u, error %#x\n", res, GetLastError() );
while ((res = wait_for_message(&msg)) && msg.message == WM_TIMER) DispatchMessageA(&msg);
- todo_wine ok( !res, "SendInput triggered unexpected message %#x\n", msg.message );
+ ok( !res, "SendInput triggered unexpected message %#x\n", msg.message );
empty_message_queue();
#else
ok( res == 16 && GetLastError() == 0xdeadbeef, "SendInput returned %u, error %#x\n", res, GetLastError() );
while ((res = wait_for_message(&msg)) && msg.message == WM_TIMER) DispatchMessageA(&msg);
ok( !!res, "SendInput did not trigger any message\n" );
- todo_wine ok( msg.message == WM_KEYDOWN, "SendInput triggered unexpected message %#x\n", msg.message );
+ ok( msg.message == WM_KEYDOWN, "SendInput triggered unexpected message %#x\n", msg.message );
while ((res = wait_for_message(&msg)) && msg.message == WM_TIMER) DispatchMessageA(&msg);
ok( !!res, "SendInput did not trigger any message\n" );
- todo_wine ok( msg.message == WM_KEYUP, "SendInput triggered unexpected message %#x\n", msg.message );
+ ok( msg.message == WM_KEYUP, "SendInput triggered unexpected message %#x\n", msg.message );
empty_message_queue();
#endif
for (i = 0; i < ARRAY_SIZE(input); ++i) input[i].type = INPUT_HARDWARE + 1;
SetLastError( 0xdeadbeef );
res = SendInput( 16, input, sizeof(*input) );
- todo_wine ok( res == 16 && GetLastError() == 0xdeadbeef, "SendInput returned %u, error %#x\n", res, GetLastError() );
+ ok( res == 16 && GetLastError() == 0xdeadbeef, "SendInput returned %u, error %#x\n", res, GetLastError() );
while ((res = wait_for_message(&msg)) && msg.message == WM_TIMER) DispatchMessageA(&msg);
- todo_wine ok( !res, "SendInput triggered unexpected message %#x\n", msg.message );
+ ok( !res, "SendInput triggered unexpected message %#x\n", msg.message );
empty_message_queue();
trace( "done\n" );
--
2.30.2

View File

@ -1,64 +0,0 @@
From eee5ecbed5c813be03d4b540675f1c4792101567 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 11 Nov 2019 18:35:18 +0100
Subject: [PATCH] server: Make it possible to queue rawinput message on all
desktops.
---
server/queue.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/server/queue.c b/server/queue.c
index f5d19031485..59c6cbb6921 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1658,8 +1658,8 @@ static int queue_rawinput_message( struct process* process, void *arg )
{
const struct rawinput_message* raw_msg = arg;
const struct rawinput_device *device = NULL;
- struct desktop *target_desktop = NULL;
- struct thread *target_thread = NULL;
+ struct desktop *target_desktop = NULL, *desktop = NULL;
+ struct thread *target_thread = NULL, *foreground = NULL;
struct message *msg;
struct hardware_msg_data *msg_data;
int wparam = RIM_INPUT;
@@ -1670,12 +1670,18 @@ static int queue_rawinput_message( struct process* process, void *arg )
device = process->rawinput_kbd;
if (!device) return 0;
- if (process != raw_msg->foreground->process)
+ if (raw_msg->desktop) desktop = (struct desktop *)grab_object( raw_msg->desktop );
+ else if (!(desktop = get_desktop_obj( process, process->desktop, 0 ))) goto done;
+
+ if (raw_msg->foreground) foreground = (struct thread *)grab_object( raw_msg->foreground );
+ else if (!(foreground = get_foreground_thread( desktop, 0 ))) goto done;
+
+ if (process != foreground->process)
{
if (!(device->flags & RIDEV_INPUTSINK)) goto done;
if (!(target_thread = get_window_thread( device->target ))) goto done;
if (!(target_desktop = get_thread_desktop( target_thread, 0 ))) goto done;
- if (target_desktop != raw_msg->desktop) goto done;
+ if (target_desktop != desktop) goto done;
wparam = RIM_INPUTSINK;
}
@@ -1692,11 +1698,13 @@ static int queue_rawinput_message( struct process* process, void *arg )
if (raw_msg->extra_len && raw_msg->extra)
memcpy( msg_data + 1, raw_msg->extra, raw_msg->extra_len );
- queue_hardware_message( raw_msg->desktop, msg, 1 );
+ queue_hardware_message( desktop, msg, 1 );
done:
if (target_thread) release_object( target_thread );
if (target_desktop) release_object( target_desktop );
+ if (foreground) release_object( foreground );
+ if (desktop) release_object( desktop );
return 0;
}
--
2.27.0

View File

@ -1,51 +1,94 @@
From c74a22af02a816e81bf84b2f80fcd05582e01187 Mon Sep 17 00:00:00 2001
From 1d4f802b393ca552ec262f359794277c9ecf2c7f 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] user32: Add __wine_send_input flags to hint raw input
translation.
Date: Wed, 7 Apr 2021 14:52:00 +0200
Subject: [PATCH] user32: Add RAWINPUT parameter to __wine_send_input.
And send_hardware_message.
This makes it possible to use __wine_send_input to send extended input
data, such as HID device notifications and WM_INPUT messages carrying
HID reports.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
---
dlls/user32/input.c | 4 ++--
dlls/user32/input.c | 6 +++---
dlls/user32/message.c | 2 +-
dlls/user32/user32.spec | 2 +-
dlls/user32/user_private.h | 2 +-
dlls/wineandroid.drv/keyboard.c | 2 +-
dlls/wineandroid.drv/window.c | 4 ++--
dlls/winemac.drv/ime.c | 5 +++--
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, 17 insertions(+), 16 deletions(-)
12 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index f0b95c7fc6c..150b7de9704 100644
index e97264960ea..3fc818a2510 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -123,9 +123,9 @@ BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret )
@@ -119,9 +119,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 )
+BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input, const RAWINPUT *rawinput )
{
- NTSTATUS status = send_hardware_message( hwnd, input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
+ NTSTATUS status = send_hardware_message( hwnd, input, flags );
- NTSTATUS status = send_hardware_message( hwnd, input, 0 );
+ NTSTATUS status = send_hardware_message( hwnd, input, rawinput, 0 );
if (status) SetLastError( RtlNtStatusToDosError(status) );
return !status;
}
@@ -210,7 +210,7 @@ UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size )
update_mouse_coords( &input );
/* fallthrough */
case INPUT_KEYBOARD:
- status = send_hardware_message( 0, &input, SEND_HWMSG_INJECTED );
+ status = send_hardware_message( 0, &input, NULL, SEND_HWMSG_INJECTED );
break;
#ifdef _WIN64
case INPUT_HARDWARE:
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index def59998a52..f87ef9fb3af 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -3227,7 +3227,7 @@ static BOOL send_message( struct send_message_info *info, DWORD_PTR *res_ptr, BO
/***********************************************************************
* send_hardware_message
*/
-NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
+NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *rawinput, UINT flags )
{
struct user_key_state_info *key_state_info = get_user_thread_info()->key_state;
struct send_message_info info;
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec
index d2a14879714..6ffc7d44096 100644
index 4ef75247d71..190ee74fd6c 100644
--- a/dlls/user32/user32.spec
+++ b/dlls/user32/user32.spec
@@ -833,5 +833,5 @@
@@ -834,5 +834,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_send_input(long ptr ptr)
@ cdecl __wine_set_pixel_format(long long)
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 7761a1ceb4f..dfd52421e66 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -263,7 +263,7 @@ extern RECT get_virtual_screen_rect(void) DECLSPEC_HIDDEN;
extern LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN;
extern DWORD get_input_codepage( void ) DECLSPEC_HIDDEN;
extern BOOL map_wparam_AtoW( UINT message, WPARAM *wparam, enum wm_char_mapping mapping ) DECLSPEC_HIDDEN;
-extern NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags ) DECLSPEC_HIDDEN;
+extern NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *rawinput, UINT flags ) DECLSPEC_HIDDEN;
extern LRESULT MSG_SendInternalMessageTimeout( DWORD dest_pid, DWORD dest_tid,
UINT msg, WPARAM wparam, LPARAM lparam,
UINT flags, UINT timeout, PDWORD_PTR res_ptr ) DECLSPEC_HIDDEN;
diff --git a/dlls/wineandroid.drv/keyboard.c b/dlls/wineandroid.drv/keyboard.c
index a0f3257f74b..1af8a98f1f9 100644
index 1c8a1e4f68f..0a6ede0ec5f 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 )
@ -53,12 +96,12 @@ index a0f3257f74b..1af8a98f1f9 100644
input.u.ki.dwExtraInfo = 0;
- __wine_send_input( hwnd, &input );
+ __wine_send_input( hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
+ __wine_send_input( hwnd, &input, NULL );
}
/***********************************************************************
diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c
index eb05aaf2832..c1e7b000a8f 100644
index 79bc471a984..1cb1bbbadc9 100644
--- a/dlls/wineandroid.drv/window.c
+++ b/dlls/wineandroid.drv/window.c
@@ -521,7 +521,7 @@ static int process_events( DWORD mask )
@ -66,7 +109,7 @@ index eb05aaf2832..c1e7b000a8f 100644
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 );
+ __wine_send_input( capture ? capture : event->data.motion.hwnd, &event->data.motion.input, NULL );
}
break;
@ -75,37 +118,29 @@ index eb05aaf2832..c1e7b000a8f 100644
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 );
+ __wine_send_input( 0, &event->data.kbd.input, NULL );
break;
default:
diff --git a/dlls/winemac.drv/ime.c b/dlls/winemac.drv/ime.c
index dabe6654f98..3593374a613 100644
index dabe6654f98..f2368c10743 100644
--- a/dlls/winemac.drv/ime.c
+++ b/dlls/winemac.drv/ime.c
@@ -42,6 +42,7 @@
#include "winuser.h"
#include "imm.h"
#include "ddk/imm.h"
+#include "wine/server.h"
WINE_DEFAULT_DEBUG_CHANNEL(imm);
@@ -1427,10 +1428,10 @@ void macdrv_im_set_text(const macdrv_event *event)
@@ -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);
+ __wine_send_input(hwnd, &input, NULL);
input.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
- __wine_send_input(hwnd, &input);
+ __wine_send_input(hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW);
+ __wine_send_input(hwnd, &input, NULL);
}
}
diff --git a/dlls/winemac.drv/keyboard.c b/dlls/winemac.drv/keyboard.c
index bb408cb20c5..41919baafc7 100644
index 1b74300e93a..1ea15f59341 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
@ -113,12 +148,12 @@ index bb408cb20c5..41919baafc7 100644
input.ki.dwExtraInfo = 0;
- __wine_send_input(hwnd, &input);
+ __wine_send_input(hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW);
+ __wine_send_input(hwnd, &input, NULL);
}
diff --git a/dlls/winemac.drv/mouse.c b/dlls/winemac.drv/mouse.c
index dd6443fe1ba..91cafdf1362 100644
index dd6443fe1ba..d2278ae0e4c 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,
@ -126,12 +161,12 @@ index dd6443fe1ba..91cafdf1362 100644
input.mi.dwExtraInfo = 0;
- __wine_send_input(top_level_hwnd, &input);
+ __wine_send_input(top_level_hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW);
+ __wine_send_input(top_level_hwnd, &input, NULL);
}
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index 48da12c0292..2a3bed787ab 100644
index 35a801fc895..01620c5e4a4 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1148,7 +1148,7 @@ static void X11DRV_send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD f
@ -139,52 +174,52 @@ index 48da12c0292..2a3bed787ab 100644
input.u.ki.dwExtraInfo = 0;
- __wine_send_input( hwnd, &input );
+ __wine_send_input( hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
+ __wine_send_input( hwnd, &input, NULL );
}
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 7f11ba86e49..aaa34d8ff0f 100644
index 94dece652b6..42bac332664 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -657,7 +657,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
@@ -659,7 +659,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
sync_window_cursor( window );
last_cursor_change = input->u.mi.time;
}
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 );
+ __wine_send_input( hwnd, input, NULL );
return;
}
@@ -697,7 +697,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
@@ -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 );
+ __wine_send_input( hwnd, input, NULL );
}
#ifdef SONAME_LIBXCURSOR
@@ -1643,7 +1643,7 @@ void move_resize_window( HWND hwnd, int dir )
@@ -1669,7 +1669,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 );
+ __wine_send_input( hwnd, &input, NULL );
}
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
@@ -1882,7 +1882,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
@@ -1900,7 +1900,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 );
+ __wine_send_input( 0, &input, NULL );
return TRUE;
}
diff --git a/include/winuser.h b/include/winuser.h
index 311b1481be4..4bc18a63e31 100644
index 53661f6c788..0b1571c0a95 100644
--- a/include/winuser.h
+++ b/include/winuser.h
@@ -4406,7 +4406,7 @@ static inline BOOL WINAPI SetRectEmpty(LPRECT rect)
@ -192,10 +227,10 @@ index 311b1481be4..4bc18a63e31 100644
#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 );
+WINUSERAPI BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input, const RAWINPUT *rawinput );
#endif
#ifdef __cplusplus
--
2.27.0
2.30.2

View File

@ -0,0 +1,69 @@
From 1da5b77304f9ef71340692a9d3d6e95526101ea6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 22 Mar 2021 18:41:55 +0100
Subject: [PATCH] hidclass.sys: Assign rawinput device handle in
HID_LinkDevice.
The handles are just numeric values and not real object handles, they
are used in the hDevice field of the RAWINPUTHEADER struct.
They will also be used as an HID rawinput device array index on the
server side.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
---
dlls/hidclass.sys/device.c | 17 +++++++++++++++++
dlls/hidclass.sys/hid.h | 1 +
2 files changed, 18 insertions(+)
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c
index fc1dfd07db1..9a3c92b3576 100644
--- a/dlls/hidclass.sys/device.c
+++ b/dlls/hidclass.sys/device.c
@@ -71,6 +71,17 @@ NTSTATUS HID_CreateDevice(DEVICE_OBJECT *native_device, HID_MINIDRIVER_REGISTRAT
return STATUS_SUCCESS;
}
+/* user32 reserves 1 & 2 for winemouse and winekeyboard,
+ * keep this in sync with user_private.h */
+#define WINE_MOUSE_HANDLE 1
+#define WINE_KEYBOARD_HANDLE 2
+
+static UINT32 alloc_rawinput_handle(void)
+{
+ static LONG counter = WINE_KEYBOARD_HANDLE + 1;
+ return InterlockedIncrement(&counter);
+}
+
NTSTATUS HID_LinkDevice(DEVICE_OBJECT *device)
{
WCHAR device_instance_id[MAX_DEVICE_ID_LEN];
@@ -125,7 +136,13 @@ NTSTATUS HID_LinkDevice(DEVICE_OBJECT *device)
{
if (!IoRegisterDeviceInterface(device, &GUID_DEVINTERFACE_MOUSE, NULL, &ext->mouse_link_name))
ext->is_mouse = TRUE;
+ ext->rawinput_handle = WINE_MOUSE_HANDLE;
}
+ else if (ext->preparseData->caps.UsagePage == HID_USAGE_PAGE_GENERIC
+ && ext->preparseData->caps.Usage == HID_USAGE_GENERIC_KEYBOARD)
+ ext->rawinput_handle = WINE_KEYBOARD_HANDLE;
+ else
+ ext->rawinput_handle = alloc_rawinput_handle();
return STATUS_SUCCESS;
diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h
index 889b8c625c0..41f3766a535 100644
--- a/dlls/hidclass.sys/hid.h
+++ b/dlls/hidclass.sys/hid.h
@@ -51,6 +51,7 @@ typedef struct _BASE_DEVICE_EXTENSION {
struct ReportRingBuffer *ring_buffer;
HANDLE halt_event;
HANDLE thread;
+ UINT32 rawinput_handle;
KSPIN_LOCK irp_queue_lock;
LIST_ENTRY irp_queue;
--
2.30.2

View File

@ -1,426 +0,0 @@
From 3d61d04751da0d7267d83ddc374e0f7be550348e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 11 Nov 2019 18:35:18 +0100
Subject: [PATCH] server: Add HID input message type to send_hardware_message
request.
---
dlls/user32/message.c | 4 ++-
dlls/user32/rawinput.c | 60 ++++++++++++++++++++++++++++++++++++--
dlls/user32/user_private.h | 2 ++
server/protocol.def | 26 +++++++++++++++--
server/queue.c | 60 ++++++++++++++++++++++++++++++++------
server/trace.c | 10 +++++--
6 files changed, 144 insertions(+), 18 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index f7ce262f90d..01d1a0eed97 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -3240,10 +3240,10 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
{
req->win = wine_server_user_handle( hwnd );
req->flags = flags;
- req->input.type = input->type;
switch (input->type)
{
case INPUT_MOUSE:
+ req->input.type = HW_INPUT_MOUSE;
req->input.mouse.x = input->u.mi.dx;
req->input.mouse.y = input->u.mi.dy;
req->input.mouse.data = input->u.mi.mouseData;
@@ -3252,6 +3252,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
req->input.mouse.info = input->u.mi.dwExtraInfo;
break;
case INPUT_KEYBOARD:
+ req->input.type = HW_INPUT_KEYBOARD;
req->input.kbd.vkey = input->u.ki.wVk;
req->input.kbd.scan = input->u.ki.wScan;
req->input.kbd.flags = input->u.ki.dwFlags;
@@ -3259,6 +3260,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
req->input.kbd.info = input->u.ki.dwExtraInfo;
break;
case INPUT_HARDWARE:
+ req->input.type = HW_INPUT_HARDWARE;
req->input.hw.msg = input->u.hi.uMsg;
req->input.hw.lparam = MAKELONG( input->u.hi.wParamL, input->u.hi.wParamH );
break;
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index ba11a121bc5..a6327b06422 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -46,6 +46,7 @@ struct device
{
WCHAR *path;
HANDLE file;
+ HANDLE handle;
RID_DEVICE_INFO info;
PHIDP_PREPARSED_DATA data;
};
@@ -62,6 +63,8 @@ static CRITICAL_SECTION_DEBUG rawinput_devices_cs_debug =
};
static CRITICAL_SECTION rawinput_devices_cs = { &rawinput_devices_cs_debug, -1, 0, 0, 0, 0 };
+extern DWORD WINAPI GetFinalPathNameByHandleW(HANDLE file, LPWSTR path, DWORD charcount, DWORD flags);
+
static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size)
{
unsigned int new_capacity, max_capacity;
@@ -143,10 +146,43 @@ static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
device->path = path;
device->file = file;
device->info.cbSize = sizeof(RID_DEVICE_INFO);
+ device->handle = INVALID_HANDLE_VALUE;
return device;
}
+HANDLE rawinput_handle_from_device_handle(HANDLE device)
+{
+ WCHAR buffer[sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH + 1];
+ OBJECT_NAME_INFORMATION *info = (OBJECT_NAME_INFORMATION*)&buffer;
+ ULONG dummy;
+ unsigned int i;
+
+ for (i = 0; i < rawinput_devices_count; ++i)
+ {
+ if (rawinput_devices[i].handle == device)
+ return &rawinput_devices[i];
+ }
+
+ if (NtQueryObject( device, ObjectNameInformation, &buffer, sizeof(buffer) - sizeof(WCHAR), &dummy ) || !info->Name.Buffer)
+ return NULL;
+
+ /* replace \??\ with \\?\ to match rawinput_devices paths */
+ if (info->Name.Length > 1 && info->Name.Buffer[0] == '\\' && info->Name.Buffer[1] == '?')
+ info->Name.Buffer[1] = '\\';
+
+ for (i = 0; i < rawinput_devices_count; ++i)
+ {
+ if (!wcscmp(rawinput_devices[i].path, info->Name.Buffer))
+ {
+ rawinput_devices[i].handle = device;
+ return &rawinput_devices[i];
+ }
+ }
+
+ return NULL;
+}
+
static void find_devices(void)
{
static ULONGLONG last_check;
@@ -326,6 +362,22 @@ BOOL rawinput_from_hardware_message(RAWINPUT *rawinput, const struct hardware_ms
rawinput->data.keyboard.Message = msg_data->rawinput.kbd.message;
rawinput->data.keyboard.ExtraInformation = msg_data->info;
}
+ else if (msg_data->rawinput.type == RIM_TYPEHID)
+ {
+ if (sizeof(*rawinput) + msg_data->rawinput.hid.length > RAWINPUT_BUFFER_SIZE)
+ {
+ ERR("unexpectedly large hardware message dropped\n");
+ return FALSE;
+ }
+
+ rawinput->header.dwSize = FIELD_OFFSET(RAWINPUT, data.hid.bRawData) + msg_data->rawinput.hid.length;
+ rawinput->header.hDevice = rawinput_handle_from_device_handle(wine_server_ptr_handle(msg_data->rawinput.hid.device));
+ rawinput->header.wParam = 0;
+
+ rawinput->data.hid.dwSizeHid = msg_data->rawinput.hid.length;
+ rawinput->data.hid.dwCount = 1;
+ memcpy(rawinput->data.hid.bRawData, msg_data + 1, msg_data->rawinput.hid.length);
+ }
else
{
FIXME("Unhandled rawinput type %#x.\n", msg_data->rawinput.type);
@@ -524,7 +576,7 @@ UINT WINAPI DECLSPEC_HOTPATCH GetRawInputBuffer(RAWINPUT *data, UINT *data_size,
struct hardware_msg_data *msg_data;
struct rawinput_thread_data *thread_data;
RAWINPUT *rawinput;
- UINT count = 0, rawinput_size, next_size, overhead;
+ UINT count = 0, rawinput_size, msg_size, next_size, overhead;
BOOL is_wow64;
int i;
@@ -584,7 +636,10 @@ UINT WINAPI DECLSPEC_HOTPATCH GetRawInputBuffer(RAWINPUT *data, UINT *data_size,
data->header.dwSize - sizeof(RAWINPUTHEADER));
data->header.dwSize += overhead;
data = NEXTRAWINPUTBLOCK(data);
- msg_data++;
+ msg_size = sizeof(*msg_data);
+ if (msg_data->rawinput.type == RIM_TYPEHID)
+ msg_size += msg_data->rawinput.hid.length;
+ msg_data = (struct hardware_msg_data *)((char *)msg_data + msg_size);
}
if (count == 0 && next_size == 0) *data_size = 0;
@@ -657,6 +712,7 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT
handle, command, data, data_size);
if (!data_size) return ~0U;
+ if (!device) return ~0U;
/* each case below must set:
* *data_size: length (meaning defined by command) of data we want to copy
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 7761a1ceb4f..bf13e81762a 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -391,4 +391,6 @@ static inline WCHAR *heap_strdupW(const WCHAR *src)
return dst;
}
+extern HANDLE rawinput_handle_from_device_handle(HANDLE device);
+
#endif /* __WINE_USER_PRIVATE_H */
diff --git a/server/protocol.def b/server/protocol.def
index 140d94ea036..a032f9aa507 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -312,6 +312,13 @@ struct hardware_msg_data
int y; /* y coordinate */
unsigned int data; /* mouse data */
} mouse;
+ struct
+ {
+ int type; /* RIM_TYPEHID */
+ obj_handle_t device;
+ unsigned int length; /* HID report length */
+ /* followed by length bytes of HID report data */
+ } hid;
} rawinput;
};
@@ -335,7 +342,7 @@ typedef union
int type;
struct
{
- int type; /* INPUT_KEYBOARD */
+ int type; /* HW_INPUT_KEYBOARD */
unsigned short vkey; /* virtual key code */
unsigned short scan; /* scan code */
unsigned int flags; /* event flags */
@@ -344,7 +351,7 @@ typedef union
} kbd;
struct
{
- int type; /* INPUT_MOUSE */
+ int type; /* HW_INPUT_MOUSE */
int x; /* coordinates */
int y;
unsigned int data; /* mouse data */
@@ -354,11 +361,23 @@ typedef union
} mouse;
struct
{
- int type; /* INPUT_HARDWARE */
+ int type; /* HW_INPUT_HARDWARE */
unsigned int msg; /* message code */
lparam_t lparam; /* message param */
} hw;
+ struct
+ {
+ int type; /* HW_INPUT_HID */
+ obj_handle_t device;
+ unsigned char usage_page;
+ unsigned char usage;
+ unsigned int length;
+ } hid;
} hw_input_t;
+#define HW_INPUT_MOUSE 0
+#define HW_INPUT_KEYBOARD 1
+#define HW_INPUT_HARDWARE 2
+#define HW_INPUT_HID 3
typedef union
{
@@ -2044,6 +2063,7 @@ enum message_type
user_handle_t win; /* window handle */
hw_input_t input; /* input data */
unsigned int flags; /* flags (see below) */
+ VARARG(data,bytes); /* hid report data */
@REPLY
int wait; /* do we need to wait for a reply? */
int prev_x; /* previous cursor position */
diff --git a/server/queue.c b/server/queue.c
index f39cf19ecd7..1b9d66b847e 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1608,7 +1608,7 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa
struct msg_queue *queue;
struct message *msg;
timeout_t timeout = 2000 * -10000; /* FIXME: load from registry */
- int id = (input->type == INPUT_MOUSE) ? WH_MOUSE_LL : WH_KEYBOARD_LL;
+ int id = (input->type == HW_INPUT_MOUSE) ? WH_MOUSE_LL : WH_KEYBOARD_LL;
if (!(hook_thread = get_first_global_hook( id ))) return 0;
if (!(queue = hook_thread->queue)) return 0;
@@ -1626,7 +1626,7 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa
msg->data_size = hardware_msg->data_size;
msg->result = NULL;
- if (input->type == INPUT_KEYBOARD)
+ if (input->type == HW_INPUT_KEYBOARD)
{
unsigned short vkey = input->kbd.vkey;
if (input->kbd.flags & KEYEVENTF_UNICODE) vkey = VK_PACKET;
@@ -1662,6 +1662,8 @@ struct rawinput_message
struct desktop *desktop;
struct hw_msg_source source;
unsigned int time;
+ unsigned char usage_page;
+ unsigned char usage;
struct hardware_msg_data data;
const void *extra;
data_size_t extra_len;
@@ -1671,6 +1673,7 @@ struct rawinput_message
static int queue_rawinput_message( struct process* process, void *arg )
{
const struct rawinput_message* raw_msg = arg;
+ const struct rawinput_device_entry *entry;
const struct rawinput_device *device = NULL;
struct desktop *target_desktop = NULL, *desktop = NULL;
struct thread *target_thread = NULL, *foreground = NULL;
@@ -1682,6 +1685,8 @@ static int queue_rawinput_message( struct process* process, void *arg )
device = process->rawinput_mouse;
else if (raw_msg->data.rawinput.type == RIM_TYPEKEYBOARD)
device = process->rawinput_kbd;
+ else if ((entry = find_rawinput_device( process, raw_msg->usage_page, raw_msg->usage )))
+ device = &entry->device;
if (!device) return 0;
if (raw_msg->desktop) desktop = (struct desktop *)grab_object( raw_msg->desktop );
@@ -2000,6 +2005,37 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_
queue_hardware_message( desktop, msg, 1 );
}
+/* queue a hardware message for an hid event */
+static void queue_hid_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 void *report, data_size_t report_len )
+{
+ struct hw_msg_source source = { IMDT_UNAVAILABLE, origin };
+ struct hardware_msg_data *msg_data;
+ struct rawinput_message raw_msg;
+
+ if (!(req_flags & SEND_HWMSG_RAWINPUT))
+ return;
+
+ /* send to all desktops */
+ raw_msg.foreground = NULL;
+ raw_msg.desktop = NULL;
+ raw_msg.source = source;
+ raw_msg.time = get_tick_count();
+ raw_msg.usage_page = input->hid.usage_page;
+ raw_msg.usage = input->hid.usage;
+ raw_msg.extra = report;
+ raw_msg.extra_len = report_len;
+
+ msg_data = &raw_msg.data;
+ msg_data->flags = 0;
+ msg_data->rawinput.type = RIM_TYPEHID;
+ msg_data->rawinput.hid.device = input->hid.device;
+ msg_data->rawinput.hid.length = report_len;
+
+ enum_processes( queue_rawinput_message, &raw_msg );
+}
+
/* check message filter for a hardware message */
static int check_hw_message_filter( user_handle_t win, unsigned int msg_code,
user_handle_t filter_win, unsigned int first, unsigned int last )
@@ -2505,15 +2541,18 @@ DECL_HANDLER(send_hardware_message)
switch (req->input.type)
{
- case INPUT_MOUSE:
+ case HW_INPUT_MOUSE:
reply->wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender, req->flags );
break;
- case INPUT_KEYBOARD:
+ case HW_INPUT_KEYBOARD:
reply->wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender, req->flags );
break;
- case INPUT_HARDWARE:
+ case HW_INPUT_HARDWARE:
queue_custom_hardware_message( desktop, req->win, origin, &req->input );
break;
+ case HW_INPUT_HID:
+ queue_hid_message( desktop, req->win, &req->input, origin, sender, req->flags, get_req_data(), get_req_data_size() );
+ break;
default:
set_error( STATUS_INVALID_PARAMETER );
}
@@ -3295,14 +3334,17 @@ DECL_HANDLER(get_rawinput_buffer)
{
struct message *msg = LIST_ENTRY( ptr, struct message, entry );
struct hardware_msg_data *data = msg->data;
+ data_size_t msg_size = sizeof(*data);
+ if (data->rawinput.type == RIM_TYPEHID)
+ msg_size += data->rawinput.hid.length;
ptr = list_next( &input->msg_list, ptr );
if (msg->msg != WM_INPUT) continue;
next_size = req->rawinput_size;
if (size + next_size > req->buffer_size) break;
- if (cur + sizeof(*data) > buf + get_reply_max_size()) break;
- if (cur + sizeof(*data) > buf + buf_size)
+ if (cur + msg_size > buf + get_reply_max_size()) break;
+ if (cur + msg_size > buf + buf_size)
{
buf_size += buf_size / 2;
if (!(tmp = realloc( buf, buf_size )))
@@ -3314,12 +3356,12 @@ DECL_HANDLER(get_rawinput_buffer)
buf = tmp;
}
- memcpy(cur, data, sizeof(*data));
+ memcpy(cur, data, msg_size);
list_remove( &msg->entry );
free_message( msg );
size += next_size;
- cur += sizeof(*data);
+ cur += msg_size;
count++;
}
diff --git a/server/trace.c b/server/trace.c
index c6ef3fb9773..4434bb1893f 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -398,24 +398,28 @@ static void dump_hw_input( const char *prefix, const hw_input_t *input )
{
switch (input->type)
{
- case INPUT_MOUSE:
+ case HW_INPUT_MOUSE:
fprintf( stderr, "%s{type=MOUSE,x=%d,y=%d,data=%08x,flags=%08x,time=%u",
prefix, input->mouse.x, input->mouse.y, input->mouse.data, input->mouse.flags,
input->mouse.time );
dump_uint64( ",info=", &input->mouse.info );
fputc( '}', stderr );
break;
- case INPUT_KEYBOARD:
+ case HW_INPUT_KEYBOARD:
fprintf( stderr, "%s{type=KEYBOARD,vkey=%04hx,scan=%04hx,flags=%08x,time=%u",
prefix, input->kbd.vkey, input->kbd.scan, input->kbd.flags, input->kbd.time );
dump_uint64( ",info=", &input->kbd.info );
fputc( '}', stderr );
break;
- case INPUT_HARDWARE:
+ case HW_INPUT_HARDWARE:
fprintf( stderr, "%s{type=HARDWARE,msg=%04x", prefix, input->hw.msg );
dump_uint64( ",lparam=", &input->hw.lparam );
fputc( '}', stderr );
break;
+ case HW_INPUT_HID:
+ fprintf( stderr, "%s{type=HID,device=%04x,usage_page=%02x,usage=%02x,length=%04x}",
+ prefix, input->hid.device, input->hid.usage_page, input->hid.usage, input->hid.length );
+ break;
default:
fprintf( stderr, "%s{type=%04x}", prefix, input->type );
break;
--
2.20.1

View File

@ -1,139 +0,0 @@
From 8f7a0c92c370cb4bf1ee6e6d7c51a3d90fe4cd48 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Wed, 18 Sep 2019 21:04:25 +0200
Subject: [PATCH] hidclass.sys: Send input message to server when HID report is
received.
---
dlls/hidclass.sys/device.c | 30 ++++++++++++++++++++++++++++++
dlls/hidclass.sys/hid.h | 1 +
dlls/hidclass.sys/pnp.c | 16 ++++++++++++++++
3 files changed, 47 insertions(+)
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c
index 0e905c8322f..369d847e3c1 100644
--- a/dlls/hidclass.sys/device.c
+++ b/dlls/hidclass.sys/device.c
@@ -26,9 +26,11 @@
#include "winuser.h"
#include "setupapi.h"
+#include "wine/server.h"
#include "wine/debug.h"
#include "ddk/hidsdi.h"
#include "ddk/hidtypes.h"
+#include "ddk/ntifs.h"
#include "ddk/wdm.h"
#include "initguid.h"
@@ -123,6 +125,8 @@ NTSTATUS HID_LinkDevice(DEVICE_OBJECT *device)
return status;
}
+ ext->link_handle = INVALID_HANDLE_VALUE;
+
/* FIXME: This should probably be done in mouhid.sys. */
if (ext->preparseData->caps.UsagePage == HID_USAGE_PAGE_GENERIC
&& ext->preparseData->caps.Usage == HID_USAGE_GENERIC_MOUSE)
@@ -207,6 +211,8 @@ void HID_DeleteDevice(DEVICE_OBJECT *device)
IoCompleteRequest(irp, IO_NO_INCREMENT);
}
+ CloseHandle(ext->link_handle);
+
TRACE("Delete device(%p) %s\n", device, debugstr_w(ext->device_name));
HeapFree(GetProcessHeap(), 0, ext->device_name);
RtlFreeUnicodeString(&ext->link_name);
@@ -241,6 +247,28 @@ static NTSTATUS copy_packet_into_buffer(HID_XFER_PACKET *packet, BYTE* buffer, U
return STATUS_BUFFER_OVERFLOW;
}
+static void HID_Device_sendRawInput(DEVICE_OBJECT *device, HID_XFER_PACKET *packet)
+{
+ BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
+
+ if (ext->link_handle == INVALID_HANDLE_VALUE)
+ return;
+
+ SERVER_START_REQ(send_hardware_message)
+ {
+ req->win = 0;
+ req->flags = SEND_HWMSG_RAWINPUT;
+ req->input.type = HW_INPUT_HID;
+ req->input.hid.device = wine_server_obj_handle(ext->link_handle);
+ req->input.hid.usage_page = ext->preparseData->caps.UsagePage;
+ req->input.hid.usage = ext->preparseData->caps.Usage;
+ req->input.hid.length = packet->reportBufferLen;
+ wine_server_add_data(req, packet->reportBuffer, packet->reportBufferLen);
+ wine_server_call(req);
+ }
+ SERVER_END_REQ;
+}
+
static void HID_Device_processQueue(DEVICE_OBJECT *device)
{
IRP *irp;
@@ -324,6 +352,7 @@ static DWORD CALLBACK hid_device_thread(void *args)
if (irp->IoStatus.u.Status == STATUS_SUCCESS)
{
RingBuffer_Write(ext->ring_buffer, packet);
+ HID_Device_sendRawInput(device, packet);
HID_Device_processQueue(device);
}
@@ -370,6 +399,7 @@ static DWORD CALLBACK hid_device_thread(void *args)
else
packet->reportId = 0;
RingBuffer_Write(ext->ring_buffer, packet);
+ HID_Device_sendRawInput(device, packet);
HID_Device_processQueue(device);
}
diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h
index 36d13c009d7..f12e04d7898 100644
--- a/dlls/hidclass.sys/hid.h
+++ b/dlls/hidclass.sys/hid.h
@@ -46,6 +46,7 @@ typedef struct _BASE_DEVICE_EXTENSION {
ULONG poll_interval;
WCHAR *device_name;
UNICODE_STRING link_name;
+ HANDLE link_handle;
WCHAR device_id[MAX_DEVICE_ID_LEN];
WCHAR instance_id[MAX_DEVICE_ID_LEN];
struct ReportRingBuffer *ring_buffer;
diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c
index 1c130e8dd80..b84a358dba4 100644
--- a/dlls/hidclass.sys/pnp.c
+++ b/dlls/hidclass.sys/pnp.c
@@ -299,12 +299,28 @@ NTSTATUS WINAPI HID_PNP_Dispatch(DEVICE_OBJECT *device, IRP *irp)
case IRP_MN_START_DEVICE:
{
BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
+ OBJECT_ATTRIBUTES attr;
rc = minidriver->PNPDispatch(device, irp);
IoSetDeviceInterfaceState(&ext->link_name, TRUE);
if (ext->is_mouse)
IoSetDeviceInterfaceState(&ext->mouse_link_name, TRUE);
+
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = 0;
+ attr.Attributes = OBJ_CASE_INSENSITIVE;
+ attr.ObjectName = &ext->link_name;
+ attr.SecurityDescriptor = NULL;
+ attr.SecurityQualityOfService = NULL;
+ NtOpenSymbolicLinkObject(&ext->link_handle, SYMBOLIC_LINK_QUERY, &attr);
+ ext->link_handle = ConvertToGlobalHandle(ext->link_handle);
+
+ if (ext->link_handle == INVALID_HANDLE_VALUE)
+ ERR("Failed to open link %s, error %u.\n", debugstr_w(ext->link_name.Buffer), GetLastError());
+ else
+ TRACE("Opened link handle: %p for %s\n", ext->link_handle, debugstr_w(ext->link_name.Buffer));
+
return rc;
}
case IRP_MN_REMOVE_DEVICE:
--
2.27.0

View File

@ -0,0 +1,118 @@
From 4b24ceb11c3b77ecd1e00d7145be370f7192bbbb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Fri, 19 Mar 2021 14:16:16 +0100
Subject: [PATCH] hidclass.sys: Use __wine_send_input to send device
notifications.
This currently does nothing, because winedevice.exe isn't associated
with any desktop, and the INPUT_HARDWARE messages are dropped.
In this specific case, when INPUT type is INPUT_HARDWARE and hi.uMsg is
WM_INPUT_DEVICE_CHANGE, the RAWINPUT structure usage is a non-standard
extension for Wine internal usage:
* header.wParam contains the message GIDC_ARRIVAL / GIDC_REMOVAL wparam,
* hid.bRawData contains two bytes, which are the HID device UsagePage
and Usage bytes, instead of a real HID report.
This will let us use the same entry point and structures to send device
notifications as for the HID reports in the future (which will be sent
with INPUT_HARDWARE type / WM_INPUT uMsg instead).
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
---
dlls/hidclass.sys/Makefile.in | 2 +-
dlls/hidclass.sys/pnp.c | 36 +++++++++++++++++++++++++++++++++++
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/dlls/hidclass.sys/Makefile.in b/dlls/hidclass.sys/Makefile.in
index be4af747853..2f9f30f8bef 100644
--- a/dlls/hidclass.sys/Makefile.in
+++ b/dlls/hidclass.sys/Makefile.in
@@ -1,6 +1,6 @@
MODULE = hidclass.sys
IMPORTLIB = hidclass
-IMPORTS = hal ntoskrnl
+IMPORTS = hal ntoskrnl user32
DELAYIMPORTS = setupapi hid
EXTRADLLFLAGS = -mno-cygwin
diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c
index a499aec93bb..8e539dfe6b7 100644
--- a/dlls/hidclass.sys/pnp.c
+++ b/dlls/hidclass.sys/pnp.c
@@ -25,6 +25,7 @@
#include "ddk/hidtypes.h"
#include "ddk/wdm.h"
#include "regstr.h"
+#include "winuser.h"
#include "wine/debug.h"
#include "wine/list.h"
@@ -69,6 +70,9 @@ static NTSTATUS get_device_id(DEVICE_OBJECT *device, BUS_QUERY_ID_TYPE type, WCH
return status;
}
+/* make sure bRawData can hold two bytes without requiring additional allocation */
+C_ASSERT(offsetof(RAWINPUT, data.hid.bRawData[2]) < sizeof(RAWINPUT));
+
NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
{
WCHAR device_id[MAX_DEVICE_ID_LEN], instance_id[MAX_DEVICE_ID_LEN];
@@ -79,6 +83,8 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
BASE_DEVICE_EXTENSION *ext = NULL;
HID_DESCRIPTOR descriptor;
BYTE *reportDescriptor;
+ RAWINPUT rawinput;
+ INPUT input;
INT i;
if ((status = get_device_id(PDO, BusQueryDeviceID, device_id)))
@@ -187,6 +193,21 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
HID_StartDeviceThread(device);
+ rawinput.header.dwType = RIM_TYPEHID;
+ rawinput.header.dwSize = offsetof(RAWINPUT, data.hid.bRawData[2]);
+ rawinput.header.hDevice = ULongToHandle(ext->rawinput_handle);
+ rawinput.header.wParam = GIDC_ARRIVAL;
+ rawinput.data.hid.dwCount = 1;
+ rawinput.data.hid.dwSizeHid = 2;
+ rawinput.data.hid.bRawData[0] = ext->preparseData->caps.UsagePage;
+ rawinput.data.hid.bRawData[1] = ext->preparseData->caps.Usage;
+
+ input.type = INPUT_HARDWARE;
+ input.u.hi.uMsg = WM_INPUT_DEVICE_CHANGE;
+ input.u.hi.wParamH = (WORD)(rawinput.header.dwSize >> 16);
+ input.u.hi.wParamL = (WORD)(rawinput.header.dwSize >> 0);
+ __wine_send_input(0, &input, &rawinput);
+
return STATUS_SUCCESS;
}
@@ -194,6 +215,21 @@ static NTSTATUS remove_device(minidriver *minidriver, DEVICE_OBJECT *device, IRP
{
BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
NTSTATUS rc = STATUS_NOT_SUPPORTED;
+ RAWINPUT rawinput;
+ INPUT input;
+
+ rawinput.header.dwType = RIM_TYPEHID;
+ rawinput.header.dwSize = offsetof(RAWINPUT, data.hid.bRawData[0]);
+ rawinput.header.hDevice = ULongToHandle(ext->rawinput_handle);
+ rawinput.header.wParam = GIDC_REMOVAL;
+ rawinput.data.hid.dwCount = 0;
+ rawinput.data.hid.dwSizeHid = 0;
+
+ input.type = INPUT_HARDWARE;
+ input.u.hi.uMsg = WM_INPUT_DEVICE_CHANGE;
+ input.u.hi.wParamH = (WORD)(rawinput.header.dwSize >> 16);
+ input.u.hi.wParamL = (WORD)(rawinput.header.dwSize >> 0);
+ __wine_send_input(0, &input, &rawinput);
rc = IoSetDeviceInterfaceState(&ext->link_name, FALSE);
if (rc)
--
2.30.2

View File

@ -0,0 +1,140 @@
From 84aab96026febc4d222733b5ecc2919047ac549b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 22 Mar 2021 22:46:36 +0100
Subject: [PATCH] server: Implement desktop broadcast in
queue_rawinput_message.
HID rawinput hardware messages will be sent from winedevice.exe, which
is not attached to any desktop. We need to broadcast the messages to all
desktops in that case.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
---
server/queue.c | 45 +++++++++++++++++++++++++++++++--------------
1 file changed, 31 insertions(+), 14 deletions(-)
diff --git a/server/queue.c b/server/queue.c
index b026c03e13d..ca2f898492b 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1670,8 +1670,8 @@ static int queue_rawinput_message( struct process* process, void *arg )
{
const struct rawinput_message* raw_msg = arg;
const struct rawinput_device *device = NULL;
- struct desktop *target_desktop = NULL;
- struct thread *target_thread = NULL;
+ struct desktop *target_desktop = NULL, *desktop = NULL;
+ struct thread *target_thread = NULL, *foreground = NULL;
struct message *msg;
int wparam = RIM_INPUT;
@@ -1681,12 +1681,18 @@ static int queue_rawinput_message( struct process* process, void *arg )
device = process->rawinput_kbd;
if (!device) return 0;
- if (process != raw_msg->foreground->process)
+ if (raw_msg->desktop) desktop = (struct desktop *)grab_object( raw_msg->desktop );
+ else if (!(desktop = get_desktop_obj( process, process->desktop, 0 ))) goto done;
+
+ if (raw_msg->foreground) foreground = (struct thread *)grab_object( raw_msg->foreground );
+ else if (!(foreground = get_foreground_thread( desktop, 0 ))) goto done;
+
+ if (process != foreground->process)
{
if (!(device->flags & RIDEV_INPUTSINK)) goto done;
if (!(target_thread = get_window_thread( device->target ))) goto done;
if (!(target_desktop = get_thread_desktop( target_thread, 0 ))) goto done;
- if (target_desktop != raw_msg->desktop) goto done;
+ if (target_desktop != desktop) goto done;
wparam = RIM_INPUTSINK;
}
@@ -1699,11 +1705,13 @@ static int queue_rawinput_message( struct process* process, void *arg )
msg->lparam = 0;
memcpy( msg->data, &raw_msg->data, sizeof(raw_msg->data) );
- queue_hardware_message( raw_msg->desktop, msg, 1 );
+ queue_hardware_message( desktop, msg, 1 );
done:
if (target_thread) release_object( target_thread );
if (target_desktop) release_object( target_desktop );
+ if (foreground) release_object( foreground );
+ if (desktop) release_object( desktop );
return 0;
}
@@ -1961,6 +1969,7 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_
struct hw_msg_source source = { IMDT_UNAVAILABLE, origin };
struct message *msg;
+ if (!desktop) return;
if (!(msg = alloc_hardware_message( 0, source, get_tick_count() ))) return;
msg->win = get_user_full_handle( win );
@@ -2455,15 +2464,14 @@ DECL_HANDLER(send_message)
DECL_HANDLER(send_hardware_message)
{
struct thread *thread = NULL;
- struct desktop *desktop;
+ struct desktop *desktop = get_thread_desktop( current, 0 );
unsigned int origin = (req->flags & SEND_HWMSG_INJECTED ? IMO_INJECTED : IMO_HARDWARE);
struct msg_queue *sender = get_current_queue();
data_size_t size = min( 256, get_reply_max_size() );
- if (!(desktop = get_thread_desktop( current, 0 ))) return;
-
if (req->win)
{
+ if (!desktop) return;
if (!(thread = get_window_thread( req->win ))) return;
if (desktop != thread->queue->input->desktop)
{
@@ -2473,18 +2481,24 @@ DECL_HANDLER(send_hardware_message)
}
}
- reply->prev_x = desktop->cursor.x;
- reply->prev_y = desktop->cursor.y;
+ if (desktop)
+ {
+ reply->prev_x = desktop->cursor.x;
+ reply->prev_y = desktop->cursor.y;
+ }
switch (req->input.type)
{
case INPUT_MOUSE:
+ if (!desktop) return;
reply->wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender );
break;
case INPUT_KEYBOARD:
+ if (!desktop) return;
reply->wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender );
break;
case INPUT_HARDWARE:
+ if (!desktop) set_error( STATUS_SUCCESS );
queue_custom_hardware_message( desktop, req->win, origin, &req->input );
break;
default:
@@ -2492,10 +2506,13 @@ DECL_HANDLER(send_hardware_message)
}
if (thread) release_object( thread );
- reply->new_x = desktop->cursor.x;
- reply->new_y = desktop->cursor.y;
- set_reply_data( desktop->keystate, size );
- release_object( desktop );
+ if (desktop)
+ {
+ reply->new_x = desktop->cursor.x;
+ reply->new_y = desktop->cursor.y;
+ set_reply_data( desktop->keystate, size );
+ release_object( desktop );
+ }
}
/* post a quit message to the current queue */
--
2.30.2

View File

@ -0,0 +1,123 @@
From 281b7628ea550071eab3b0c933b02ff67a3b215d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 22 Mar 2021 17:55:50 +0100
Subject: [PATCH] server: Add rawinput union to hw_input_t / INPUT_HARDWARE.
When msg is WM_INPUT_DEVICE_CHANGE.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
---
server/protocol.def | 42 ++++++++++++++++++++++++------------------
server/trace.c | 23 +++++++++++++++++++++++
2 files changed, 47 insertions(+), 18 deletions(-)
diff --git a/server/protocol.def b/server/protocol.def
index 617818f622d..9539169f1ff 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -289,30 +289,32 @@ struct hw_msg_source
unsigned int origin; /* source origin (IMO_* values) */
};
+union rawinput
+{
+ int type;
+ struct
+ {
+ int type; /* RIM_TYPEKEYBOARD */
+ unsigned int message; /* message generated by this rawinput event */
+ unsigned short vkey; /* virtual key code */
+ unsigned short scan; /* scan code */
+ } kbd;
+ struct
+ {
+ int type; /* RIM_TYPEMOUSE */
+ int x; /* x coordinate */
+ int y; /* y coordinate */
+ unsigned int data; /* mouse data */
+ } mouse;
+};
+
struct hardware_msg_data
{
lparam_t info; /* extra info */
unsigned int hw_id; /* unique id */
unsigned int flags; /* hook flags */
struct hw_msg_source source; /* message source */
- union
- {
- int type;
- struct
- {
- int type; /* RIM_TYPEKEYBOARD */
- unsigned int message; /* message generated by this rawinput event */
- unsigned short vkey; /* virtual key code */
- unsigned short scan; /* scan code */
- } kbd;
- struct
- {
- int type; /* RIM_TYPEMOUSE */
- int x; /* x coordinate */
- int y; /* y coordinate */
- unsigned int data; /* mouse data */
- } mouse;
- } rawinput;
+ union rawinput rawinput; /* rawinput message data */
};
struct callback_msg_data
@@ -357,6 +359,10 @@ typedef union
int type; /* INPUT_HARDWARE */
unsigned int msg; /* message code */
lparam_t lparam; /* message param */
+ union
+ {
+ union rawinput rawinput; /* WM_INPUT_DEVICE_CHANGE msg */
+ } data;
} hw;
} hw_input_t;
diff --git a/server/trace.c b/server/trace.c
index 44bc8d8ee6f..ce21ae4fe4f 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -409,6 +409,24 @@ static void dump_irp_params( const char *prefix, const irp_params_t *data )
}
}
+static void dump_rawinput( const char *prefix, const union rawinput *rawinput )
+{
+ switch (rawinput->type)
+ {
+ case RIM_TYPEMOUSE:
+ fprintf( stderr, "%s{type=MOUSE,x=%d,y=%d,data=%08x}", prefix, rawinput->mouse.x,
+ rawinput->mouse.y, rawinput->mouse.data );
+ break;
+ case RIM_TYPEKEYBOARD:
+ fprintf( stderr, "%s{type=KEYBOARD,message=%04x,vkey=%04hx,scan=%04hx}", prefix,
+ rawinput->kbd.message, rawinput->kbd.vkey, rawinput->kbd.scan );
+ break;
+ default:
+ fprintf( stderr, "%s{type=%04x}", prefix, rawinput->type );
+ break;
+ }
+}
+
static void dump_hw_input( const char *prefix, const hw_input_t *input )
{
switch (input->type)
@@ -429,6 +447,11 @@ static void dump_hw_input( const char *prefix, const hw_input_t *input )
case INPUT_HARDWARE:
fprintf( stderr, "%s{type=HARDWARE,msg=%04x", prefix, input->hw.msg );
dump_uint64( ",lparam=", &input->hw.lparam );
+ switch (input->hw.msg)
+ {
+ case WM_INPUT_DEVICE_CHANGE:
+ dump_rawinput( ",rawinput=", &input->hw.data.rawinput );
+ }
fputc( '}', stderr );
break;
default:
--
2.30.2

View File

@ -0,0 +1,96 @@
From 6b794622488eb83f6ede9d62a14f413660a2623a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 22 Mar 2021 18:28:38 +0100
Subject: [PATCH] server: Add RIM_TYPEHID type / hid member to rawinput union.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
---
server/protocol.def | 8 ++++++++
server/trace.c | 38 ++++++++++++++++++++++----------------
2 files changed, 30 insertions(+), 16 deletions(-)
diff --git a/server/protocol.def b/server/protocol.def
index 9539169f1ff..f97b966719c 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -306,6 +306,14 @@ union rawinput
int y; /* y coordinate */
unsigned int data; /* mouse data */
} mouse;
+ struct
+ {
+ int type; /* RIM_TYPEHID */
+ unsigned int device; /* rawinput device index */
+ unsigned int param; /* rawinput message param */
+ unsigned int length; /* HID report length */
+ /* followed by length bytes of HID report data */
+ } hid;
};
struct hardware_msg_data
diff --git a/server/trace.c b/server/trace.c
index ce21ae4fe4f..3d24cec0133 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -409,6 +409,22 @@ static void dump_irp_params( const char *prefix, const irp_params_t *data )
}
}
+static void dump_varargs_bytes( const char *prefix, data_size_t size )
+{
+ const unsigned char *data = cur_data;
+ data_size_t len = min( 1024, size );
+
+ fprintf( stderr, "%s{", prefix );
+ while (len > 0)
+ {
+ fprintf( stderr, "%02x", *data++ );
+ if (--len) fputc( ',', stderr );
+ }
+ if (size > 1024) fprintf( stderr, "...(total %u)", size );
+ fputc( '}', stderr );
+ remove_data( size );
+}
+
static void dump_rawinput( const char *prefix, const union rawinput *rawinput )
{
switch (rawinput->type)
@@ -421,6 +437,12 @@ static void dump_rawinput( const char *prefix, const union rawinput *rawinput )
fprintf( stderr, "%s{type=KEYBOARD,message=%04x,vkey=%04hx,scan=%04hx}", prefix,
rawinput->kbd.message, rawinput->kbd.vkey, rawinput->kbd.scan );
break;
+ case RIM_TYPEHID:
+ fprintf( stderr, "%s{type=HID,device=%04x,param=%04x,length=%u", prefix,
+ rawinput->hid.device, rawinput->hid.param, rawinput->hid.length );
+ dump_varargs_bytes( ",report=", rawinput->hid.length );
+ fputc( '}', stderr );
+ break;
default:
fprintf( stderr, "%s{type=%04x}", prefix, rawinput->type );
break;
@@ -580,22 +602,6 @@ static void dump_varargs_user_handles( const char *prefix, data_size_t size )
remove_data( size );
}
-static void dump_varargs_bytes( const char *prefix, data_size_t size )
-{
- const unsigned char *data = cur_data;
- data_size_t len = min( 1024, size );
-
- fprintf( stderr,"%s{", prefix );
- while (len > 0)
- {
- fprintf( stderr, "%02x", *data++ );
- if (--len) fputc( ',', stderr );
- }
- if (size > 1024) fprintf( stderr, "...(total %u)", size );
- fputc( '}', stderr );
- remove_data( size );
-}
-
static void dump_varargs_string( const char *prefix, data_size_t size )
{
fprintf( stderr, "%s\"%.*s\"", prefix, (int)size, (const char *)cur_data );
--
2.30.2

View File

@ -0,0 +1,47 @@
From dcd1d9ab1462b49093465e3e4117419b63778799 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 22 Mar 2021 18:11:27 +0100
Subject: [PATCH] user32: Send WM_INPUT_DEVICE_CHANGE / RAWINPUT to the server.
Expect INPUT/INPUT_HARDWARE to be followed with RAWINPUT, when uMsg is
WM_INPUT_DEVICE_CHANGE. This is for internal __wine_send_input calls
only, as we ignore INPUT_HARDWARE in SendInput.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
---
dlls/user32/message.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index f87ef9fb3af..f11aaa4144d 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -3267,6 +3267,25 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r
case INPUT_HARDWARE:
req->input.hw.msg = input->u.hi.uMsg;
req->input.hw.lparam = MAKELONG( input->u.hi.wParamL, input->u.hi.wParamH );
+ switch (input->u.hi.uMsg)
+ {
+ case WM_INPUT_DEVICE_CHANGE:
+ req->input.hw.data.rawinput.type = rawinput->header.dwType;
+ switch (rawinput->header.dwType)
+ {
+ case RIM_TYPEHID:
+ assert( rawinput->data.hid.dwCount <= 1 );
+ req->input.hw.data.rawinput.hid.device = HandleToUlong( rawinput->header.hDevice );
+ req->input.hw.data.rawinput.hid.param = rawinput->header.wParam;
+ req->input.hw.data.rawinput.hid.length = rawinput->data.hid.dwSizeHid;
+ if (rawinput->data.hid.dwSizeHid)
+ wine_server_add_data( req, rawinput->data.hid.bRawData, rawinput->data.hid.dwSizeHid );
+ break;
+ default:
+ assert( 0 );
+ break;
+ }
+ }
break;
}
if (key_state_info) wine_server_set_reply( req, key_state_info->state,
--
2.30.2

View File

@ -0,0 +1,83 @@
From cb2f3ed7057e769dda746b65464b364edb447c32 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Wed, 7 Apr 2021 12:17:09 +0200
Subject: [PATCH] server: Track known HID rawinput devices on addition and
removal.
To track their usage page and usage bytes.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
---
server/queue.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/server/queue.c b/server/queue.c
index ca2f898492b..033e4e30b66 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1656,6 +1656,42 @@ static struct thread *get_foreground_thread( struct desktop *desktop, user_handl
return NULL;
}
+static struct rawinput_device *hid_rawinput_devices;
+static unsigned int hid_rawinput_device_count;
+
+static void insert_hid_rawinput_device( unsigned int index, const char *data, unsigned int data_len )
+{
+ unsigned int new_count;
+
+ if (data_len < 2) return;
+
+ if (!hid_rawinput_device_count)
+ {
+ hid_rawinput_device_count = 64;
+ while (hid_rawinput_device_count < index) hid_rawinput_device_count *= 2;
+ hid_rawinput_devices = mem_alloc( hid_rawinput_device_count * sizeof(*hid_rawinput_devices) );
+ memset( hid_rawinput_devices, 0, hid_rawinput_device_count * sizeof(*hid_rawinput_devices) );
+ }
+ else if (hid_rawinput_device_count < index)
+ {
+ new_count = hid_rawinput_device_count;
+ while (new_count < index) new_count *= 2;
+ hid_rawinput_devices = realloc( hid_rawinput_devices, new_count * sizeof(*hid_rawinput_devices) );
+ memset( hid_rawinput_devices + hid_rawinput_device_count, 0, (new_count - hid_rawinput_device_count) * sizeof(*hid_rawinput_devices) );
+ hid_rawinput_device_count = new_count;
+ }
+
+ hid_rawinput_devices[index].usage_page = data[0];
+ hid_rawinput_devices[index].usage = data[1];
+}
+
+static void remove_hid_rawinput_device( unsigned int index )
+{
+ if (hid_rawinput_device_count < index) return;
+ hid_rawinput_devices[index].usage_page = 0;
+ hid_rawinput_devices[index].usage = 0;
+}
+
struct rawinput_message
{
struct thread *foreground;
@@ -1969,6 +2005,19 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_
struct hw_msg_source source = { IMDT_UNAVAILABLE, origin };
struct message *msg;
+ switch (input->hw.msg)
+ {
+ case WM_INPUT_DEVICE_CHANGE:
+ if (input->hw.data.rawinput.type == RIM_TYPEHID &&
+ input->hw.data.rawinput.hid.param == GIDC_ARRIVAL)
+ insert_hid_rawinput_device( input->hw.data.rawinput.hid.device, get_req_data(), get_req_data_size() );
+
+ if (input->hw.data.rawinput.type == RIM_TYPEHID &&
+ input->hw.data.rawinput.hid.param == GIDC_REMOVAL)
+ remove_hid_rawinput_device( input->hw.data.rawinput.hid.device );
+ return;
+ }
+
if (!desktop) return;
if (!(msg = alloc_hardware_message( 0, source, get_tick_count() ))) return;
--
2.30.2

View File

@ -1,19 +1,21 @@
From 1851c55f41d14e03c927b0e5220f9c00b1d05f6e Mon Sep 17 00:00:00 2001
From 3c71ae18955c39a1e85532175de76068597010d4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 12 Sep 2019 14:14:08 +0200
Date: Wed, 10 Feb 2021 13:23:31 +0100
Subject: [PATCH] server: Add process argument to find_rawinput_device.
We need to be able to iterate all registered rawinput devices for
foreign processes, not only the current one.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
---
server/queue.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/server/queue.c b/server/queue.c
index 46ace52f004..810612c5167 100644
index 033e4e30b66..e71d9207e1a 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1490,11 +1490,11 @@ static user_handle_t find_hardware_message_window( struct desktop *desktop, stru
@@ -1489,11 +1489,11 @@ static user_handle_t find_hardware_message_window( struct desktop *desktop, stru
return win;
}
@ -27,7 +29,7 @@ index 46ace52f004..810612c5167 100644
{
if (e->device.usage_page != usage_page || e->device.usage != usage) continue;
return e;
@@ -1507,7 +1507,7 @@ static void update_rawinput_device(const struct rawinput_device *device)
@@ -1506,7 +1506,7 @@ static void update_rawinput_device(const struct rawinput_device *device)
{
struct rawinput_device_entry *e;
@ -36,7 +38,7 @@ index 46ace52f004..810612c5167 100644
{
if (!(e = mem_alloc( sizeof(*e) ))) return;
list_add_tail( &current->process->rawinput_devices, &e->entry );
@@ -3286,9 +3286,9 @@ DECL_HANDLER(update_rawinput_devices)
@@ -3362,9 +3362,9 @@ DECL_HANDLER(update_rawinput_devices)
update_rawinput_device(&devices[i]);
}
@ -49,5 +51,5 @@ index 46ace52f004..810612c5167 100644
}
--
2.27.0
2.30.2

View File

@ -0,0 +1,225 @@
From aec62828c1b4daee79e452e749eb215deb40425a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Wed, 7 Apr 2021 12:17:40 +0200
Subject: [PATCH] server: Implement WM_INPUT_DEVICE_CHANGE message dispatch.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
---
dlls/user32/message.c | 13 +++++++----
dlls/user32/rawinput.c | 2 +-
server/queue.c | 53 +++++++++++++++++++++++++++++++++++++-----
3 files changed, 56 insertions(+), 12 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index f11aaa4144d..54fcdc4588c 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -2288,11 +2288,14 @@ static void accept_hardware_message( UINT hw_id )
static BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data )
{
struct rawinput_thread_data *thread_data = rawinput_thread_data();
- if (!rawinput_from_hardware_message( thread_data->buffer, msg_data ))
- return FALSE;
- thread_data->hw_id = hw_id;
- msg->lParam = (LPARAM)hw_id;
+ if (msg->message == WM_INPUT)
+ {
+ if (!rawinput_from_hardware_message( thread_data->buffer, msg_data )) return FALSE;
+ thread_data->hw_id = hw_id;
+ msg->lParam = (LPARAM)hw_id;
+ }
+
msg->pt = point_phys_to_win_dpi( msg->hwnd, msg->pt );
return TRUE;
}
@@ -2612,7 +2615,7 @@ static BOOL process_hardware_message( MSG *msg, UINT hw_id, const struct hardwar
/* hardware messages are always in physical coords */
context = SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
- if (msg->message == WM_INPUT)
+ if (msg->message == WM_INPUT || msg->message == WM_INPUT_DEVICE_CHANGE)
ret = process_rawinput_message( msg, hw_id, msg_data );
else if (is_keyboard_message( msg->message ))
ret = process_keyboard_message( msg, hw_id, hwnd_filter, first, last, remove );
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index ba11a121bc5..99481ffae3d 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -428,7 +428,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH RegisterRawInputDevices(RAWINPUTDEVICE *devices, U
TRACE("device %u: page %#x, usage %#x, flags %#x, target %p.\n",
i, devices[i].usUsagePage, devices[i].usUsage,
devices[i].dwFlags, devices[i].hwndTarget);
- if (devices[i].dwFlags & ~(RIDEV_REMOVE|RIDEV_NOLEGACY|RIDEV_INPUTSINK))
+ if (devices[i].dwFlags & ~(RIDEV_REMOVE|RIDEV_NOLEGACY|RIDEV_INPUTSINK|RIDEV_DEVNOTIFY))
FIXME("Unhandled flags %#x for device %u.\n", devices[i].dwFlags, i);
d[i].usage_page = devices[i].usUsagePage;
diff --git a/server/queue.c b/server/queue.c
index e71d9207e1a..9fe009b5cfe 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1464,7 +1464,7 @@ static user_handle_t find_hardware_message_window( struct desktop *desktop, stru
*thread = NULL;
*msg_code = msg->msg;
- if (msg->msg == WM_INPUT)
+ if (msg->msg == WM_INPUT || msg->msg == WM_INPUT_DEVICE_CHANGE)
{
if (!(win = msg->win) && input) win = input->focus;
}
@@ -1553,7 +1553,7 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg
if (msg->wparam == VK_SHIFT || msg->wparam == VK_LSHIFT || msg->wparam == VK_RSHIFT)
msg->lparam &= ~(KF_EXTENDED << 16);
}
- else if (msg->msg != WM_INPUT)
+ else if (msg->msg != WM_INPUT && msg->msg != WM_INPUT_DEVICE_CHANGE)
{
if (msg->msg == WM_MOUSEMOVE)
{
@@ -1651,7 +1651,7 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa
static struct thread *get_foreground_thread( struct desktop *desktop, user_handle_t window )
{
/* if desktop has no foreground process, assume the receiving window is */
- if (desktop->foreground_input) return get_window_thread( desktop->foreground_input->focus );
+ if (desktop && desktop->foreground_input) return get_window_thread( desktop->foreground_input->focus );
if (window) return get_window_thread( window );
return NULL;
}
@@ -1692,12 +1692,23 @@ static void remove_hid_rawinput_device( unsigned int index )
hid_rawinput_devices[index].usage = 0;
}
+static struct rawinput_device_entry *find_hid_rawinput_device( struct process *process, const union rawinput *rawinput )
+{
+ unsigned int index;
+ if (rawinput->type != RIM_TYPEHID) return NULL;
+ if (!(index = rawinput->hid.device)) return NULL;
+ if (hid_rawinput_device_count < index) return NULL;
+ if (!hid_rawinput_devices[index].usage_page) return NULL;
+ return find_rawinput_device( process, hid_rawinput_devices[index].usage_page, hid_rawinput_devices[index].usage );
+}
+
struct rawinput_message
{
struct thread *foreground;
struct desktop *desktop;
struct hw_msg_source source;
unsigned int time;
+ unsigned int message;
struct hardware_msg_data data;
};
@@ -1705,6 +1716,7 @@ struct rawinput_message
static int queue_rawinput_message( struct process* process, void *arg )
{
const struct rawinput_message* raw_msg = arg;
+ const struct rawinput_device_entry *entry;
const struct rawinput_device *device = NULL;
struct desktop *target_desktop = NULL, *desktop = NULL;
struct thread *target_thread = NULL, *foreground = NULL;
@@ -1715,8 +1727,12 @@ static int queue_rawinput_message( struct process* process, void *arg )
device = process->rawinput_mouse;
else if (raw_msg->data.rawinput.type == RIM_TYPEKEYBOARD)
device = process->rawinput_kbd;
+ else if ((entry = find_hid_rawinput_device( process, &raw_msg->data.rawinput )))
+ device = &entry->device;
if (!device) return 0;
+ if (raw_msg->message == WM_INPUT_DEVICE_CHANGE && !(device->flags & RIDEV_DEVNOTIFY)) return 0;
+
if (raw_msg->desktop) desktop = (struct desktop *)grab_object( raw_msg->desktop );
else if (!(desktop = get_desktop_obj( process, process->desktop, 0 ))) goto done;
@@ -1725,7 +1741,7 @@ static int queue_rawinput_message( struct process* process, void *arg )
if (process != foreground->process)
{
- if (!(device->flags & RIDEV_INPUTSINK)) goto done;
+ if (raw_msg->message == WM_INPUT && !(device->flags & RIDEV_INPUTSINK)) goto done;
if (!(target_thread = get_window_thread( device->target ))) goto done;
if (!(target_desktop = get_thread_desktop( target_thread, 0 ))) goto done;
if (target_desktop != desktop) goto done;
@@ -1736,11 +1752,17 @@ static int queue_rawinput_message( struct process* process, void *arg )
goto done;
msg->win = device->target;
- msg->msg = WM_INPUT;
+ msg->msg = raw_msg->message;
msg->wparam = wparam;
msg->lparam = 0;
memcpy( msg->data, &raw_msg->data, sizeof(raw_msg->data) );
+ if (raw_msg->message == WM_INPUT_DEVICE_CHANGE && raw_msg->data.rawinput.type == RIM_TYPEHID)
+ {
+ msg->wparam = raw_msg->data.rawinput.hid.param;
+ msg->lparam = raw_msg->data.rawinput.hid.device;
+ }
+
queue_hardware_message( desktop, msg, 1 );
done:
@@ -1814,6 +1836,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
raw_msg.desktop = desktop;
raw_msg.source = source;
raw_msg.time = time;
+ raw_msg.message = WM_INPUT;
msg_data = &raw_msg.data;
msg_data->info = input->mouse.info;
@@ -1948,6 +1971,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
raw_msg.desktop = desktop;
raw_msg.source = source;
raw_msg.time = time;
+ raw_msg.message = WM_INPUT;
msg_data = &raw_msg.data;
msg_data->info = input->kbd.info;
@@ -2003,18 +2027,35 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_
unsigned int origin, const hw_input_t *input )
{
struct hw_msg_source source = { IMDT_UNAVAILABLE, origin };
+ struct hardware_msg_data *msg_data;
+ struct rawinput_message raw_msg;
struct message *msg;
switch (input->hw.msg)
{
case WM_INPUT_DEVICE_CHANGE:
+ raw_msg.foreground = get_foreground_thread( desktop, win );
+ raw_msg.desktop = desktop;
+ raw_msg.source = source;
+ raw_msg.time = get_tick_count();
+ raw_msg.message = input->hw.msg;
+
+ msg_data = &raw_msg.data;
+ msg_data->info = 0;
+ msg_data->flags = 0;
+ msg_data->rawinput = input->hw.data.rawinput;
+
if (input->hw.data.rawinput.type == RIM_TYPEHID &&
input->hw.data.rawinput.hid.param == GIDC_ARRIVAL)
insert_hid_rawinput_device( input->hw.data.rawinput.hid.device, get_req_data(), get_req_data_size() );
+ enum_processes( queue_rawinput_message, &raw_msg );
+
if (input->hw.data.rawinput.type == RIM_TYPEHID &&
input->hw.data.rawinput.hid.param == GIDC_REMOVAL)
remove_hid_rawinput_device( input->hw.data.rawinput.hid.device );
+
+ if (raw_msg.foreground) release_object( raw_msg.foreground );
return;
}
@@ -2151,7 +2192,7 @@ static int get_hardware_message( struct thread *thread, unsigned int hw_id, user
data->hw_id = msg->unique_id;
set_reply_data( msg->data, msg->data_size );
- if (msg->msg == WM_INPUT && (flags & PM_REMOVE))
+ if ((msg->msg == WM_INPUT || msg->msg == WM_INPUT_DEVICE_CHANGE) && (flags & PM_REMOVE))
release_hardware_message( current->queue, data->hw_id );
return 1;
}
--
2.30.2

View File

@ -0,0 +1,73 @@
From 7819fe251e3f12eda8ee615aa735b1870a49e3b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Fri, 5 Mar 2021 10:41:20 +0100
Subject: [PATCH] hidclass.sys: Send rawinput messages with HID report.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
---
dlls/hidclass.sys/device.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c
index 9a3c92b3576..551816aa4fe 100644
--- a/dlls/hidclass.sys/device.c
+++ b/dlls/hidclass.sys/device.c
@@ -254,6 +254,39 @@ static NTSTATUS copy_packet_into_buffer(HID_XFER_PACKET *packet, BYTE* buffer, U
return STATUS_BUFFER_OVERFLOW;
}
+static void HID_Device_sendRawInput(DEVICE_OBJECT *device, HID_XFER_PACKET *packet)
+{
+ BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
+ RAWINPUT *rawinput;
+ UCHAR *report, id;
+ ULONG data_size;
+ INPUT input;
+
+ data_size = offsetof(RAWINPUT, data.hid.bRawData) + packet->reportBufferLen;
+ if (!(id = ext->preparseData->reports[0].reportID)) data_size += 1;
+
+ rawinput = HeapAlloc(GetProcessHeap(), 0, data_size);
+
+ rawinput->header.dwType = RIM_TYPEHID;
+ rawinput->header.dwSize = data_size;
+ rawinput->header.hDevice = ULongToHandle(ext->rawinput_handle);
+ rawinput->header.wParam = RIM_INPUT;
+ rawinput->data.hid.dwCount = 1;
+ rawinput->data.hid.dwSizeHid = data_size - offsetof(RAWINPUT, data.hid.bRawData);
+
+ report = rawinput->data.hid.bRawData;
+ if (!id) *report++ = 0;
+ memcpy(report, packet->reportBuffer, packet->reportBufferLen);
+
+ input.type = INPUT_HARDWARE;
+ input.u.hi.uMsg = WM_INPUT;
+ input.u.hi.wParamH = (WORD)(rawinput->header.dwSize >> 16);
+ input.u.hi.wParamL = (WORD)(rawinput->header.dwSize >> 0);
+ __wine_send_input(0, &input, rawinput);
+
+ HeapFree(GetProcessHeap(), 0, rawinput);
+}
+
static void HID_Device_processQueue(DEVICE_OBJECT *device)
{
IRP *irp;
@@ -337,6 +370,7 @@ static DWORD CALLBACK hid_device_thread(void *args)
if (irp->IoStatus.u.Status == STATUS_SUCCESS)
{
RingBuffer_Write(ext->ring_buffer, packet);
+ HID_Device_sendRawInput(device, packet);
HID_Device_processQueue(device);
}
@@ -383,6 +417,7 @@ static DWORD CALLBACK hid_device_thread(void *args)
else
packet->reportId = 0;
RingBuffer_Write(ext->ring_buffer, packet);
+ HID_Device_sendRawInput(device, packet);
HID_Device_processQueue(device);
}
--
2.30.2

View File

@ -1,19 +1,21 @@
From ea854d200d2fb243dc898a1ef4e2a1a6f127a329 Mon Sep 17 00:00:00 2001
From 9b9134b94879a1e501d0337cdf6f607ebe2ff84f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 19 Sep 2019 09:20:44 +0200
Subject: [PATCH] server: Allow extra data for hardware_msg_data message.
Date: Tue, 23 Mar 2021 10:11:07 +0100
Subject: [PATCH] server: Add extra data to hardware_msg_data.
The RIM_TYPEHID messages will have to carry the variable length HID
report.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
---
server/queue.c | 31 +++++++++++++++++++++----------
1 file changed, 21 insertions(+), 10 deletions(-)
server/queue.c | 33 +++++++++++++++++++++++----------
1 file changed, 23 insertions(+), 10 deletions(-)
diff --git a/server/queue.c b/server/queue.c
index 810612c5167..f5d19031485 100644
index 9fe009b5cfe..248157ca7da 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -343,13 +343,13 @@ static int assign_thread_input( struct thread *thread, struct thread_input *new_
@@ -348,13 +348,13 @@ static int assign_thread_input( struct thread *thread, struct thread_input *new_
/* allocate a hardware message and its data */
static struct message *alloc_hardware_message( lparam_t info, struct hw_msg_source source,
@ -29,7 +31,7 @@ index 810612c5167..f5d19031485 100644
{
free( msg );
return NULL;
@@ -358,9 +358,9 @@ static struct message *alloc_hardware_message( lparam_t info, struct hw_msg_sour
@@ -363,9 +363,9 @@ static struct message *alloc_hardware_message( lparam_t info, struct hw_msg_sour
msg->type = MSG_HARDWARE;
msg->time = time;
msg->data = msg_data;
@ -41,7 +43,7 @@ index 810612c5167..f5d19031485 100644
msg_data->info = info;
msg_data->source = source;
return msg;
@@ -393,7 +393,7 @@ static void set_cursor_pos( struct desktop *desktop, int x, int y )
@@ -398,7 +398,7 @@ static void set_cursor_pos( struct desktop *desktop, int x, int y )
return;
}
@ -50,24 +52,24 @@ index 810612c5167..f5d19031485 100644
msg->msg = WM_MOUSEMOVE;
msg->x = x;
@@ -1649,6 +1649,8 @@ struct rawinput_message
struct hw_msg_source source;
@@ -1710,6 +1710,8 @@ struct rawinput_message
unsigned int time;
unsigned int message;
struct hardware_msg_data data;
+ const void *extra;
+ data_size_t extra_len;
};
/* check if process is supposed to receive a WM_INPUT message and eventually queue it */
@@ -1659,6 +1661,7 @@ static int queue_rawinput_message( struct process* process, void *arg )
struct desktop *target_desktop = NULL;
struct thread *target_thread = NULL;
@@ -1721,6 +1723,7 @@ static int queue_rawinput_message( struct process* process, void *arg )
struct desktop *target_desktop = NULL, *desktop = NULL;
struct thread *target_thread = NULL, *foreground = NULL;
struct message *msg;
+ struct hardware_msg_data *msg_data;
int wparam = RIM_INPUT;
if (raw_msg->data.rawinput.type == RIM_TYPEMOUSE)
@@ -1676,14 +1679,18 @@ static int queue_rawinput_message( struct process* process, void *arg )
@@ -1748,14 +1751,18 @@ static int queue_rawinput_message( struct process* process, void *arg )
wparam = RIM_INPUTSINK;
}
@ -77,7 +79,7 @@ index 810612c5167..f5d19031485 100644
+ msg_data = msg->data;
msg->win = device->target;
msg->msg = WM_INPUT;
msg->msg = raw_msg->message;
msg->wparam = wparam;
msg->lparam = 0;
- memcpy( msg->data, &raw_msg->data, sizeof(raw_msg->data) );
@ -86,18 +88,18 @@ index 810612c5167..f5d19031485 100644
+ if (raw_msg->extra_len && raw_msg->extra)
+ memcpy( msg_data + 1, raw_msg->extra, raw_msg->extra_len );
queue_hardware_message( raw_msg->desktop, msg, 1 );
@@ -1756,6 +1763,8 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
raw_msg.desktop = desktop;
if (raw_msg->message == WM_INPUT_DEVICE_CHANGE && raw_msg->data.rawinput.type == RIM_TYPEHID)
{
@@ -1837,6 +1844,8 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
raw_msg.source = source;
raw_msg.time = time;
raw_msg.message = WM_INPUT;
+ raw_msg.extra = NULL;
+ raw_msg.extra_len = 0;
msg_data = &raw_msg.data;
msg_data->info = input->mouse.info;
@@ -1785,7 +1794,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
@@ -1862,7 +1871,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
if (!(flags & (1 << i))) continue;
flags &= ~(1 << i);
@ -106,33 +108,42 @@ index 810612c5167..f5d19031485 100644
msg_data = msg->data;
msg->win = get_user_full_handle( win );
@@ -1894,6 +1903,8 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
raw_msg.desktop = desktop;
@@ -1972,6 +1981,8 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
raw_msg.source = source;
raw_msg.time = time;
raw_msg.message = WM_INPUT;
+ raw_msg.extra = NULL;
+ raw_msg.extra_len = 0;
msg_data = &raw_msg.data;
msg_data->info = input->kbd.info;
@@ -1917,7 +1928,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
if (!(req_flags & SEND_HWMSG_WINDOW))
@@ -1991,7 +2002,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
return 0;
}
- if (!(msg = alloc_hardware_message( input->kbd.info, source, time ))) return 0;
+ if (!(msg = alloc_hardware_message( input->kbd.info, source, time, 0 ))) return 0;
msg_data = msg->data;
msg->win = get_user_full_handle( win );
@@ -1955,7 +1966,7 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_
struct hw_msg_source source = { IMDT_UNAVAILABLE, origin };
struct message *msg;
@@ -2039,6 +2050,8 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_
raw_msg.source = source;
raw_msg.time = get_tick_count();
raw_msg.message = input->hw.msg;
+ raw_msg.extra = NULL;
+ raw_msg.extra_len = 0;
msg_data = &raw_msg.data;
msg_data->info = 0;
@@ -2060,7 +2073,7 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_
}
if (!desktop) return;
- if (!(msg = alloc_hardware_message( 0, source, get_tick_count() ))) return;
+ if (!(msg = alloc_hardware_message( 0, source, get_tick_count(), 0 ))) return;
msg->win = get_user_full_handle( win );
msg->msg = input->hw.msg;
--
2.27.0
2.30.2

View File

@ -0,0 +1,185 @@
From d394cc092108c710ad2cccbcec1919a084037910 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 23 Mar 2021 10:42:07 +0100
Subject: [PATCH] server: Implement WM_INPUT / RIM_TYPEHID message dispatch.
The messages are of variable size and carry the corresponding HID report
data after each RAWINPUT struct.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
---
dlls/user32/message.c | 1 +
dlls/user32/rawinput.c | 23 +++++++++++++++++++++--
server/protocol.def | 2 +-
server/queue.c | 25 ++++++++++++++++++-------
server/trace.c | 1 +
5 files changed, 42 insertions(+), 10 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index 54fcdc4588c..f986b71953a 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -3272,6 +3272,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r
req->input.hw.lparam = MAKELONG( input->u.hi.wParamL, input->u.hi.wParamH );
switch (input->u.hi.uMsg)
{
+ case WM_INPUT:
case WM_INPUT_DEVICE_CHANGE:
req->input.hw.data.rawinput.type = rawinput->header.dwType;
switch (rawinput->header.dwType)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index 99481ffae3d..c69393d9ed2 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -326,6 +326,22 @@ BOOL rawinput_from_hardware_message(RAWINPUT *rawinput, const struct hardware_ms
rawinput->data.keyboard.Message = msg_data->rawinput.kbd.message;
rawinput->data.keyboard.ExtraInformation = msg_data->info;
}
+ else if (msg_data->rawinput.type == RIM_TYPEHID)
+ {
+ if (sizeof(*rawinput) + msg_data->rawinput.hid.length > RAWINPUT_BUFFER_SIZE)
+ {
+ ERR( "unexpectedly large hardware message dropped\n" );
+ return FALSE;
+ }
+
+ rawinput->header.dwSize = FIELD_OFFSET( RAWINPUT, data.hid.bRawData ) + msg_data->rawinput.hid.length;
+ rawinput->header.hDevice = ULongToHandle( msg_data->rawinput.hid.device );
+ rawinput->header.wParam = 0;
+
+ rawinput->data.hid.dwSizeHid = msg_data->rawinput.hid.length;
+ rawinput->data.hid.dwCount = 1;
+ memcpy( rawinput->data.hid.bRawData, msg_data + 1, msg_data->rawinput.hid.length );
+ }
else
{
FIXME("Unhandled rawinput type %#x.\n", msg_data->rawinput.type);
@@ -524,7 +540,7 @@ UINT WINAPI DECLSPEC_HOTPATCH GetRawInputBuffer(RAWINPUT *data, UINT *data_size,
struct hardware_msg_data *msg_data;
struct rawinput_thread_data *thread_data;
RAWINPUT *rawinput;
- UINT count = 0, rawinput_size, next_size, overhead;
+ UINT count = 0, rawinput_size, msg_size, next_size, overhead;
BOOL is_wow64;
int i;
@@ -584,7 +600,9 @@ UINT WINAPI DECLSPEC_HOTPATCH GetRawInputBuffer(RAWINPUT *data, UINT *data_size,
data->header.dwSize - sizeof(RAWINPUTHEADER));
data->header.dwSize += overhead;
data = NEXTRAWINPUTBLOCK(data);
- msg_data++;
+ msg_size = sizeof(*msg_data);
+ if (msg_data->rawinput.type == RIM_TYPEHID) msg_size += msg_data->rawinput.hid.length;
+ msg_data = (struct hardware_msg_data *)((char *)msg_data + msg_size);
}
if (count == 0 && next_size == 0) *data_size = 0;
@@ -657,6 +675,7 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT
handle, command, data, data_size);
if (!data_size) return ~0U;
+ if (!device) return ~0U;
/* each case below must set:
* *data_size: length (meaning defined by command) of data we want to copy
diff --git a/server/protocol.def b/server/protocol.def
index f97b966719c..829216b58c1 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -369,7 +369,7 @@ typedef union
lparam_t lparam; /* message param */
union
{
- union rawinput rawinput; /* WM_INPUT_DEVICE_CHANGE msg */
+ union rawinput rawinput; /* WM_INPUT and WM_INPUT_DEVICE_CHANGE msg */
} data;
} hw;
} hw_input_t;
diff --git a/server/queue.c b/server/queue.c
index 248157ca7da..a411d0af8d2 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -2044,6 +2044,7 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_
switch (input->hw.msg)
{
+ case WM_INPUT:
case WM_INPUT_DEVICE_CHANGE:
raw_msg.foreground = get_foreground_thread( desktop, win );
raw_msg.desktop = desktop;
@@ -2053,18 +2054,26 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_
raw_msg.extra = NULL;
raw_msg.extra_len = 0;
+ if (input->hw.msg == WM_INPUT)
+ {
+ raw_msg.extra = get_req_data();
+ raw_msg.extra_len = get_req_data_size();
+ }
+
msg_data = &raw_msg.data;
msg_data->info = 0;
msg_data->flags = 0;
msg_data->rawinput = input->hw.data.rawinput;
- if (input->hw.data.rawinput.type == RIM_TYPEHID &&
+ if (input->hw.msg == WM_INPUT_DEVICE_CHANGE &&
+ input->hw.data.rawinput.type == RIM_TYPEHID &&
input->hw.data.rawinput.hid.param == GIDC_ARRIVAL)
insert_hid_rawinput_device( input->hw.data.rawinput.hid.device, get_req_data(), get_req_data_size() );
enum_processes( queue_rawinput_message, &raw_msg );
- if (input->hw.data.rawinput.type == RIM_TYPEHID &&
+ if (input->hw.msg == WM_INPUT_DEVICE_CHANGE &&
+ input->hw.data.rawinput.type == RIM_TYPEHID &&
input->hw.data.rawinput.hid.param == GIDC_REMOVAL)
remove_hid_rawinput_device( input->hw.data.rawinput.hid.device );
@@ -3371,16 +3380,18 @@ DECL_HANDLER(get_rawinput_buffer)
{
struct message *msg = LIST_ENTRY( ptr, struct message, entry );
struct hardware_msg_data *data = msg->data;
+ data_size_t hid_size = data->rawinput.type != RIM_TYPEHID ? 0 : data->rawinput.hid.length;
+ data_size_t data_size = sizeof(*data) + hid_size;
ptr = list_next( &input->msg_list, ptr );
if (msg->msg != WM_INPUT) continue;
- next_size = req->rawinput_size;
+ next_size = req->rawinput_size + hid_size;
if (size + next_size > req->buffer_size) break;
- if (cur + sizeof(*data) > buf + get_reply_max_size()) break;
- if (cur + sizeof(*data) > buf + buf_size)
+ if (cur + data_size > buf + get_reply_max_size()) break;
+ if (cur + data_size > buf + buf_size)
{
- buf_size += buf_size / 2;
+ buf_size += buf_size / 2 + hid_size;
if (!(tmp = realloc( buf, buf_size )))
{
set_error( STATUS_NO_MEMORY );
@@ -3390,7 +3401,7 @@ DECL_HANDLER(get_rawinput_buffer)
buf = tmp;
}
- memcpy(cur, data, sizeof(*data));
+ memcpy( cur, data, data_size );
list_remove( &msg->entry );
free_message( msg );
diff --git a/server/trace.c b/server/trace.c
index 3d24cec0133..f50a0367683 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -471,6 +471,7 @@ static void dump_hw_input( const char *prefix, const hw_input_t *input )
dump_uint64( ",lparam=", &input->hw.lparam );
switch (input->hw.msg)
{
+ case WM_INPUT:
case WM_INPUT_DEVICE_CHANGE:
dump_rawinput( ",rawinput=", &input->hw.data.rawinput );
}
--
2.30.2

View File

@ -0,0 +1,124 @@
From 2e8dd5065ba659d6f5f5c5bedadbec4e06a98a6a Mon Sep 17 00:00:00 2001
From: Arkadiusz Hiler <ahiler@codeweavers.com>
Date: Tue, 23 Feb 2021 14:41:58 +0200
Subject: [PATCH] ntoskrnl: Implement IoSetDevicePropertyData().
---
dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 1 +
dlls/ntoskrnl.exe/pnp.c | 51 +++++++++++++++++++++++++++++
include/ddk/wdm.h | 4 +++
3 files changed, 56 insertions(+)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
index 2e5e2e6e11b..4eb08faec2e 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
+++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
@@ -465,6 +465,7 @@
@ stdcall IoReuseIrp(ptr long)
@ stub IoSetCompletionRoutineEx
@ stdcall IoSetDeviceInterfaceState(ptr long)
+@ stdcall IoSetDevicePropertyData(ptr ptr long long long long ptr)
@ stub IoSetDeviceToVerify
@ stub IoSetFileOrigin
@ stub IoSetHardErrorOrVerifyDevice
diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c
index 7994a8b85b9..0d5d0d721d4 100644
--- a/dlls/ntoskrnl.exe/pnp.c
+++ b/dlls/ntoskrnl.exe/pnp.c
@@ -38,6 +38,12 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
+static inline const char *debugstr_propkey( const DEVPROPKEY *id )
+{
+ if (!id) return "(null)";
+ return wine_dbg_sprintf( "{%s,%04x}", wine_dbgstr_guid( &id->fmtid ), id->pid );
+}
+
#define MAX_SERVICE_NAME 260
struct device_interface
@@ -770,6 +776,51 @@ NTSTATUS WINAPI IoSetDeviceInterfaceState( UNICODE_STRING *name, BOOLEAN enable
return ret;
}
+/***********************************************************************
+ * IoSetDevicePropertyData (NTOSKRNL.EXE.@)
+ */
+NTSTATUS WINAPI IoSetDevicePropertyData( DEVICE_OBJECT *device, const DEVPROPKEY *property_key, LCID lcid,
+ ULONG flags, DEVPROPTYPE type, ULONG size, void *data )
+{
+ SP_DEVINFO_DATA sp_device = {sizeof(sp_device)};
+ WCHAR device_instance_id[MAX_DEVICE_ID_LEN];
+ NTSTATUS status;
+ HDEVINFO set;
+
+ TRACE( "device %p, property_key %s, lcid %#x, flags %#x, type %#x, size %u, data %p.\n",
+ device, debugstr_propkey(property_key), lcid, flags, type, size, data );
+
+ /* flags is always treated as PLUGPLAY_PROPERTY_PERSISTENT starting with Win 8 / 2012 */
+
+ if (lcid != LOCALE_NEUTRAL) FIXME( "only LOCALE_NEUTRAL is supported\n" );
+
+ if ((status = get_device_instance_id( device, device_instance_id ))) return status;
+
+ if ((set = SetupDiCreateDeviceInfoList( &GUID_NULL, NULL )) == INVALID_HANDLE_VALUE)
+ {
+ ERR( "Failed to create device list, error %#x.\n", GetLastError() );
+ return GetLastError();
+ }
+
+ if (!SetupDiOpenDeviceInfoW( set, device_instance_id, NULL, 0, &sp_device ))
+ {
+ ERR( "Failed to open device, error %#x.\n", GetLastError() );
+ SetupDiDestroyDeviceInfoList( set );
+ return GetLastError();
+ }
+
+ if (!SetupDiSetDevicePropertyW( set, &sp_device, property_key, type, data, size, 0 ))
+ {
+ ERR( "Failed to set property, error %#x.\n", GetLastError() );
+ SetupDiDestroyDeviceInfoList( set );
+ return GetLastError();
+ }
+
+ SetupDiDestroyDeviceInfoList( set );
+
+ return STATUS_SUCCESS;
+}
+
/***********************************************************************
* IoRegisterDeviceInterface (NTOSKRNL.EXE.@)
*/
diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h
index 3b9af7d52b2..3d0f810c2f0 100644
--- a/include/ddk/wdm.h
+++ b/include/ddk/wdm.h
@@ -21,6 +21,7 @@
#define _NTDDK_
#include <ntstatus.h>
+#include <devpropdef.h>
#ifdef _WIN64
#define POINTER_ALIGNMENT DECLSPEC_ALIGN(8)
@@ -1677,6 +1678,8 @@ void WINAPI ExReleaseResourceForThreadLite(ERESOURCE*,ERESOURCE_THREAD);
ULONG WINAPI ExSetTimerResolution(ULONG,BOOLEAN);
void WINAPI ExUnregisterCallback(void*);
+#define PLUGPLAY_PROPERTY_PERSISTENT 0x0001
+
void WINAPI IoAcquireCancelSpinLock(KIRQL*);
NTSTATUS WINAPI IoAcquireRemoveLockEx(IO_REMOVE_LOCK*,void*,const char*,ULONG, ULONG);
NTSTATUS WINAPI IoAllocateDriverObjectExtension(PDRIVER_OBJECT,PVOID,ULONG,PVOID*);
@@ -1724,6 +1727,7 @@ void WINAPI IoReleaseRemoveLockAndWaitEx(IO_REMOVE_LOCK*,void*,ULONG);
void WINAPI IoReleaseRemoveLockEx(IO_REMOVE_LOCK*,void*,ULONG);
void WINAPI IoReuseIrp(IRP*,NTSTATUS);
NTSTATUS WINAPI IoSetDeviceInterfaceState(UNICODE_STRING*,BOOLEAN);
+NTSTATUS WINAPI IoSetDevicePropertyData(DEVICE_OBJECT*,const DEVPROPKEY*,LCID,ULONG,DEVPROPTYPE,ULONG,void*);
NTSTATUS WINAPI IoWMIRegistrationControl(PDEVICE_OBJECT,ULONG);
void FASTCALL KeAcquireInStackQueuedSpinLockAtDpcLevel(KSPIN_LOCK*,KLOCK_QUEUE_HANDLE*);
--
2.30.2

View File

@ -0,0 +1,48 @@
From 613004e02a06a93598c45f323fe5b4cd9c989194 Mon Sep 17 00:00:00 2001
From: Arkadiusz Hiler <ahiler@codeweavers.com>
Date: Wed, 10 Feb 2021 13:23:33 +0100
Subject: [PATCH] hidclass.sys: Assign rawinput handles through device
properties.
---
dlls/hidclass.sys/device.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c
index 551816aa4fe..fb571bea314 100644
--- a/dlls/hidclass.sys/device.c
+++ b/dlls/hidclass.sys/device.c
@@ -33,11 +33,14 @@
#include "initguid.h"
#include "devguid.h"
+#include "devpkey.h"
#include "ntddmou.h"
WINE_DEFAULT_DEBUG_CHANNEL(hid);
WINE_DECLARE_DEBUG_CHANNEL(hid_report);
+DEFINE_DEVPROPKEY(DEVPROPKEY_HID_HANDLE, 0xbc62e415, 0xf4fe, 0x405c, 0x8e, 0xda, 0x63, 0x6f, 0xb5, 0x9f, 0x08, 0x98, 2);
+
NTSTATUS HID_CreateDevice(DEVICE_OBJECT *native_device, HID_MINIDRIVER_REGISTRATION *driver, DEVICE_OBJECT **device)
{
WCHAR dev_name[255];
@@ -144,6 +147,15 @@ NTSTATUS HID_LinkDevice(DEVICE_OBJECT *device)
else
ext->rawinput_handle = alloc_rawinput_handle();
+ status = IoSetDevicePropertyData(device, &DEVPROPKEY_HID_HANDLE, LOCALE_NEUTRAL,
+ PLUGPLAY_PROPERTY_PERSISTENT, DEVPROP_TYPE_UINT32,
+ sizeof(ext->rawinput_handle), &ext->rawinput_handle);
+ if (status != STATUS_SUCCESS)
+ {
+ FIXME("failed to set device property %x\n", status);
+ return status;
+ }
+
return STATUS_SUCCESS;
error:
--
2.30.2

View File

@ -0,0 +1,61 @@
From c28c0feaa804d97e3d105d402f12430e6cee054e Mon Sep 17 00:00:00 2001
From: Arkadiusz Hiler <ahiler@codeweavers.com>
Date: Mon, 22 Feb 2021 15:41:46 +0200
Subject: [PATCH] user32: Enumerate mouse rawinput device before HID devices.
---
dlls/user32/rawinput.c | 31 ++++++++++++++++---------------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index c69393d9ed2..ea8d15ac97b 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -175,6 +175,22 @@ static void find_devices(void)
}
rawinput_devices_count = 0;
+ set = SetupDiGetClassDevsW(&GUID_DEVINTERFACE_MOUSE, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
+
+ /* add mice first so we won't add the duplicated HID devices */
+ for (idx = 0; SetupDiEnumDeviceInterfaces(set, NULL, &GUID_DEVINTERFACE_MOUSE, idx, &iface); ++idx)
+ {
+ static const RID_DEVICE_INFO_MOUSE mouse_info = {1, 5, 0, FALSE};
+
+ if (!(device = add_device(set, &iface)))
+ continue;
+
+ device->info.dwType = RIM_TYPEMOUSE;
+ device->info.u.mouse = mouse_info;
+ }
+
+ SetupDiDestroyDeviceInfoList(set);
+
set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
for (idx = 0; SetupDiEnumDeviceInterfaces(set, NULL, &hid_guid, idx, &iface); ++idx)
@@ -203,21 +219,6 @@ static void find_devices(void)
SetupDiDestroyDeviceInfoList(set);
- set = SetupDiGetClassDevsW(&GUID_DEVINTERFACE_MOUSE, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
-
- for (idx = 0; SetupDiEnumDeviceInterfaces(set, NULL, &GUID_DEVINTERFACE_MOUSE, idx, &iface); ++idx)
- {
- static const RID_DEVICE_INFO_MOUSE mouse_info = {1, 5, 0, FALSE};
-
- if (!(device = add_device(set, &iface)))
- continue;
-
- device->info.dwType = RIM_TYPEMOUSE;
- device->info.u.mouse = mouse_info;
- }
-
- SetupDiDestroyDeviceInfoList(set);
-
LeaveCriticalSection(&rawinput_devices_cs);
}
--
2.30.2

View File

@ -0,0 +1,153 @@
From f7bb329873ec91a2ed7adbca8b5fac5f774e324d Mon Sep 17 00:00:00 2001
From: Arkadiusz Hiler <ahiler@codeweavers.com>
Date: Mon, 22 Feb 2021 15:41:46 +0200
Subject: [PATCH] user32: Use device handles assigned by hidclass.sys.
This allows us to avoid racy handle mapping for messages from the WM_INPUT
family.
---
dlls/user32/rawinput.c | 61 +++++++++++++++++++++++++++++++++++-------
1 file changed, 51 insertions(+), 10 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index ea8d15ac97b..91315692ac5 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -38,14 +38,18 @@
#include "user_private.h"
#include "initguid.h"
+#include "devpkey.h"
#include "ntddmou.h"
WINE_DEFAULT_DEBUG_CHANNEL(rawinput);
+DEFINE_DEVPROPKEY(DEVPROPKEY_HID_HANDLE, 0xbc62e415, 0xf4fe, 0x405c, 0x8e, 0xda, 0x63, 0x6f, 0xb5, 0x9f, 0x08, 0x98, 2);
+
struct device
{
WCHAR *path;
HANDLE file;
+ HANDLE handle;
RID_DEVICE_INFO info;
PHIDP_PREPARSED_DATA data;
};
@@ -91,11 +95,13 @@ static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int
static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
{
+ SP_DEVINFO_DATA device_data = {sizeof(device_data)};
SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail;
+ UINT32 handle;
struct device *device;
HANDLE file;
WCHAR *path;
- DWORD size;
+ DWORD idx, size, type;
SetupDiGetDeviceInterfaceDetailW(set, iface, NULL, 0, &size, NULL);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
@@ -109,7 +115,27 @@ static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
return FALSE;
}
detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
- SetupDiGetDeviceInterfaceDetailW(set, iface, detail, size, NULL, NULL);
+ SetupDiGetDeviceInterfaceDetailW(set, iface, detail, size, NULL, &device_data);
+
+ if (!SetupDiGetDevicePropertyW(set, &device_data, &DEVPROPKEY_HID_HANDLE, &type, (BYTE *)&handle, sizeof(handle), NULL, 0))
+ {
+ ERR("Failed to get handle for %s, skipping HID device.\n", debugstr_w(detail->DevicePath));
+ heap_free(detail);
+ return NULL;
+ }
+
+ if (type != DEVPROP_TYPE_UINT32)
+ ERR("Wrong prop type for HANDLE.\n");
+
+ for (idx = 0; idx < rawinput_devices_count; ++idx)
+ {
+ if (rawinput_devices[idx].handle == ULongToHandle(handle))
+ {
+ TRACE("Discarding %s as it's a duplicate of %s.\n", debugstr_w(detail->DevicePath), debugstr_w(rawinput_devices[idx].path));
+ heap_free(detail);
+ return NULL;
+ }
+ }
TRACE("Found HID device %s.\n", debugstr_w(detail->DevicePath));
@@ -143,14 +169,13 @@ static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
device->path = path;
device->file = file;
device->info.cbSize = sizeof(RID_DEVICE_INFO);
+ device->handle = ULongToHandle(handle);
return device;
}
static void find_devices(void)
{
- static ULONGLONG last_check;
-
SP_DEVICE_INTERFACE_DATA iface = { sizeof(iface) };
struct device *device;
HIDD_ATTRIBUTES attr;
@@ -159,10 +184,6 @@ static void find_devices(void)
HDEVINFO set;
DWORD idx;
- if (GetTickCount64() - last_check < 2000)
- return;
- last_check = GetTickCount64();
-
HidD_GetHidGuid(&hid_guid);
EnterCriticalSection(&rawinput_devices_cs);
@@ -223,6 +244,26 @@ static void find_devices(void)
}
+static struct device *rawinput_device_from_handle(HANDLE handle)
+{
+ unsigned int i;
+
+ if (!handle) return NULL;
+
+ for (i = 0; i < rawinput_devices_count; ++i)
+ if (rawinput_devices[i].handle == handle)
+ return &rawinput_devices[i];
+
+ find_devices();
+
+ for (i = 0; i < rawinput_devices_count; ++i)
+ if (rawinput_devices[i].handle == handle)
+ return &rawinput_devices[i];
+
+ return NULL;
+}
+
+
struct rawinput_thread_data *rawinput_thread_data(void)
{
struct user_thread_info *thread_info = get_user_thread_info();
@@ -396,7 +437,7 @@ UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_coun
for (i = 0; i < rawinput_devices_count; ++i)
{
- devices[2 + i].hDevice = &rawinput_devices[i];
+ devices[2 + i].hDevice = rawinput_devices[i].handle;
devices[2 + i].dwType = rawinput_devices[i].info.dwType;
}
@@ -668,7 +709,7 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT
static const RID_DEVICE_INFO_MOUSE mouse_info = {1, 5, 0, FALSE};
RID_DEVICE_INFO info;
- struct device *device = handle;
+ struct device *device = rawinput_device_from_handle(handle);
const void *to_copy;
UINT to_copy_bytes, avail_bytes;
--
2.30.2

View File

@ -1,2 +1,2 @@
# Depends: user32-rawinput-mouse
Disabled: true
Fixes: [50506] WM_INPUT messages are not received for HID devices registered with RegisterRawInputDevices
Depends: loader-KeyboardLayouts

View File

@ -1,4 +1,4 @@
From 45bb2783e35fd9d20acc88bac151af3a57662edf Mon Sep 17 00:00:00 2001
From c6fffd9e7e10b3ac95aed8165ecffd1e1da30f61 Mon Sep 17 00:00:00 2001
From: Derek Lesho <dereklesho52@Gmail.com>
Date: Tue, 25 Jun 2019 22:37:34 -0400
Subject: [PATCH] winex11.drv: Add support for absolute RawMotion events.
@ -20,16 +20,17 @@ and absolute position events.
---
dlls/user32/rawinput.c | 7 ++-
dlls/winex11.drv/mouse.c | 96 +++++++++++++++++++++-------------
dlls/winex11.drv/window.c | 3 +-
dlls/winex11.drv/x11drv.h | 18 +++----
dlls/winex11.drv/x11drv_main.c | 2 +
server/queue.c | 4 +-
5 files changed, 79 insertions(+), 48 deletions(-)
6 files changed, 81 insertions(+), 49 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index 90dc911397d..d6dc377ddc3 100644
index 91315692ac5..2e3f4301a4d 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -289,7 +289,12 @@ BOOL rawinput_from_hardware_message(RAWINPUT *rawinput, const struct hardware_ms
@@ -296,7 +296,12 @@ BOOL rawinput_from_hardware_message(RAWINPUT *rawinput, const struct hardware_ms
rawinput->header.hDevice = WINE_MOUSE_HANDLE;
rawinput->header.wParam = 0;
@ -44,7 +45,7 @@ index 90dc911397d..d6dc377ddc3 100644
rawinput->data.mouse.u.s.usButtonData = 0;
for (i = 1; i < ARRAY_SIZE(button_flags); ++i)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index ded877a140f..84a47f1e522 100644
index 0558467a805..dcc9fe82fd1 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -331,32 +331,40 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
@ -78,16 +79,17 @@ index ded877a140f..84a47f1e522 100644
- {
- valuator_data = &thread_data->y_rel_valuator;
- }
+ class->label == x11drv_atom( Abs_Y ) ||
+ (!class->label && class->number == 1))
+ thread_data->y_pos_valuator = *class;
+ }
-
- if (valuator_data) {
- valuator_data->number = class->number;
- valuator_data->min = class->min;
- valuator_data->max = class->max;
- }
+ class->label == x11drv_atom( Abs_Y ) ||
+ (!class->label && class->number == 1))
+ thread_data->y_pos_valuator = *class;
}
+
+ if (thread_data->x_pos_valuator.number < 0 || thread_data->y_pos_valuator.number < 0)
+ {
+ WARN("Only one X/Y axis found, ignoring RawMotion events\n");
@ -97,7 +99,7 @@ index ded877a140f..84a47f1e522 100644
+ WARN("Relative/Absolute mismatch between X/Y axis, ignoring RawMotion events\n");
+ thread_data->y_pos_valuator.number = -1;
+ thread_data->y_pos_valuator.number = -1;
}
+ }
+
+ if (thread_data->x_pos_valuator.min >= thread_data->x_pos_valuator.max)
+ thread_data->x_pos_valuator.min = thread_data->x_pos_valuator.max = 0;
@ -106,18 +108,18 @@ index ded877a140f..84a47f1e522 100644
}
#endif
@@ -441,8 +449,8 @@ void X11DRV_XInput2_Disable(void)
mask.deviceid = XIAllMasterDevices;
@@ -478,8 +486,8 @@ void x11drv_xinput_disable( Display *display, Window window, long event_mask )
pXISelectEvents( display, DefaultRootWindow( display ), &mask, 1 );
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
if (!data) return;
- data->x_rel_valuator.number = -1;
- data->y_rel_valuator.number = -1;
+ data->x_pos_valuator.number = -1;
+ data->y_pos_valuator.number = -1;
data->xi2_core_pointer = 0;
data->xi2_state = xi_disabled;
#endif
}
@@ -1893,16 +1901,22 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
@@ -1950,16 +1958,22 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
INPUT input;
int i;
double dx = 0, dy = 0, val;
@ -144,19 +146,18 @@ index ded877a140f..84a47f1e522 100644
input.type = INPUT_MOUSE;
input.u.mi.mouseData = 0;
@@ -1913,24 +1927,34 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
@@ -1970,24 +1984,34 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
input.u.mi.dy = 0;
virtual_rect = get_virtual_screen_rect();
-
- for (i = 0; i <= max ( x_rel->number, y_rel->number ); i++)
+ if (x_pos->min < x_pos->max)
+ x_scale = (x_pos->mode == XIModeAbsolute ? 65535 : (virtual_rect.right - virtual_rect.left)) /
+ (x_pos->max - x_pos->min);
+ if (y_pos->min < y_pos->max)
+ y_scale = (y_pos->mode == XIModeAbsolute ? 65535 : (virtual_rect.bottom - virtual_rect.top)) /
+ (y_pos->max - y_pos->min);
+
- for (i = 0; i <= max ( x_rel->number, y_rel->number ); i++)
+ for (i = 0; i <= max( x_pos->number, y_pos->number ); i++)
{
if (!XIMaskIsSet( event->valuators.mask, i )) continue;
@ -191,8 +192,29 @@ index ded877a140f..84a47f1e522 100644
}
}
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 4005e3df387..13ab69ec0ef 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -37,6 +37,8 @@
#include <X11/extensions/shape.h>
#endif /* HAVE_LIBXSHAPE */
+#include "x11drv.h"
+
/* avoid conflict with field names in included win32 headers */
#undef Status
#include "windef.h"
@@ -45,7 +47,6 @@
#include "winuser.h"
#include "wine/unicode.h"
-#include "x11drv.h"
#include "wine/debug.h"
#include "wine/server.h"
#include "mwm.h"
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 6febdc18b0a..396056464a7 100644
index 910a6c6cc18..3155d23baf0 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -32,6 +32,9 @@
@ -205,7 +227,7 @@ index 6febdc18b0a..396056464a7 100644
#define BOOL X_BOOL
#define BYTE X_BYTE
@@ -318,13 +321,6 @@ struct x11drv_escape_flush_gl_drawable
@@ -319,13 +322,6 @@ struct x11drv_escape_flush_gl_drawable
* X11 USER driver
*/
@ -216,15 +238,15 @@ index 6febdc18b0a..396056464a7 100644
- int number;
-};
-
struct x11drv_thread_data
enum xi2_state
{
Display *display;
@@ -340,11 +336,13 @@ struct x11drv_thread_data
xi_unavailable = -1,
@@ -349,11 +345,13 @@ struct x11drv_thread_data
HWND clip_hwnd; /* message window stored in desktop while clipping is active */
DWORD clip_reset; /* time when clipping was last reset */
HKL kbd_layout; /* active keyboard layout */
+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled } xi2_state; /* XInput2 state */
enum xi2_state xi2_state; /* XInput2 state */
- struct x11drv_valuator_data x_rel_valuator;
- struct x11drv_valuator_data y_rel_valuator;
+ XIValuatorClassInfo x_pos_valuator;
@ -235,7 +257,7 @@ index 6febdc18b0a..396056464a7 100644
};
extern struct x11drv_thread_data *x11drv_init_thread_data(void) DECLSPEC_HIDDEN;
@@ -429,6 +427,8 @@ enum x11drv_atoms
@@ -438,6 +436,8 @@ enum x11drv_atoms
XATOM_RAW_CAP_HEIGHT,
XATOM_Rel_X,
XATOM_Rel_Y,
@ -245,7 +267,7 @@ index 6febdc18b0a..396056464a7 100644
XATOM_WM_DELETE_WINDOW,
XATOM_WM_STATE,
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 4eaedd1c556..f08ac92e36f 100644
index d8576949aea..5a1c672b143 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -142,6 +142,8 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
@ -258,10 +280,10 @@ index 4eaedd1c556..f08ac92e36f 100644
"WM_DELETE_WINDOW",
"WM_STATE",
diff --git a/server/queue.c b/server/queue.c
index fbed47d6951..161b48e888f 100644
index 9008f8e90ff..4c68da8f737 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1783,8 +1783,8 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
@@ -1851,8 +1851,8 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
msg_data->info = input->mouse.info;
msg_data->flags = flags;
msg_data->rawinput.type = RIM_TYPEMOUSE;
@ -271,7 +293,7 @@ index fbed47d6951..161b48e888f 100644
+ msg_data->rawinput.mouse.y = input->mouse.y;
msg_data->rawinput.mouse.data = input->mouse.data;
if ((req_flags & SEND_HWMSG_RAWINPUT))
enum_processes( queue_rawinput_message, &raw_msg );
--
2.27.0
2.30.2

View File

@ -1,4 +1,4 @@
From ddb1995ab864885e9ab683a16f3594e712efa669 Mon Sep 17 00:00:00 2001
From fff35d809015ea53a7195122482e80a2dd366b9e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 10 Sep 2019 12:24:22 +0200
Subject: [PATCH] winex11.drv: Send relative RawMotion events unprocessed.
@ -9,19 +9,20 @@ virtual desktop space, and cursor speed is meaningless in this case.
This does not support mixed relative/absolute X/Y axis.
---
dlls/winex11.drv/mouse.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
dlls/winex11.drv/mouse.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 84a47f1e522..2fcacaee95c 100644
index dcc9fe82fd1..44e9786cd9f 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -1897,20 +1897,17 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
@@ -1953,21 +1953,18 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
{
XIRawEvent *event = xev->data;
const double *values = event->valuators.values;
+ const double *raw_values = event->raw_values;
RECT virtual_rect;
RAWINPUT rawinput;
INPUT input;
int i;
double dx = 0, dy = 0, val;
@ -39,7 +40,7 @@ index 84a47f1e522..2fcacaee95c 100644
if (!event->valuators.mask_len) return FALSE;
if (thread_data->xi2_state != xi_enabled) return FALSE;
if (event->deviceid != thread_data->xi2_core_pointer) return FALSE;
@@ -1938,9 +1935,11 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
@@ -1995,9 +1992,11 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
{
if (!XIMaskIsSet( event->valuators.mask, i )) continue;
val = *values++;
@ -51,7 +52,7 @@ index 84a47f1e522..2fcacaee95c 100644
input.u.mi.dwFlags |= (x_pos->mode == XIModeAbsolute ? MOUSEEVENTF_ABSOLUTE : 0);
if (x_pos->mode == XIModeAbsolute)
input.u.mi.dx = (dx - x_pos->min) * x_scale;
@@ -1950,6 +1949,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
@@ -2007,6 +2006,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
if (i == y_pos->number)
{
dy = val;
@ -59,28 +60,19 @@ index 84a47f1e522..2fcacaee95c 100644
input.u.mi.dwFlags |= (y_pos->mode == XIModeAbsolute ? MOUSEEVENTF_ABSOLUTE : 0);
if (y_pos->mode == XIModeAbsolute)
input.u.mi.dy = (dy - y_pos->min) * y_scale;
@@ -1964,13 +1964,20 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
return FALSE;
}
- if (!thread_data->xi2_rawinput_only)
+ if (x_pos->mode == XIModeAbsolute)
+ {
+ 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_RAWINPUT );
+ }
+ else 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 );
@@ -2028,6 +2028,12 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
}
else
{
+ input.u.mi.dx = raw_dx;
+ input.u.mi.dy = raw_dy;
+ if (x_pos->mode != XIModeAbsolute)
+ {
+ input.u.mi.dx = raw_dx;
+ input.u.mi.dy = raw_dy;
+ }
+
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 );
}
rawinput.header.dwType = RIM_TYPEMOUSE;
--
2.27.0
2.30.2

View File

@ -1,6 +1,6 @@
From fd61f237db287d30a26fc6724103c871cff57bd2 Mon Sep 17 00:00:00 2001
From: Jordan Galby <gravemind2a+wine@gmail.com>
Date: Tue, 16 Jul 2019 00:34:38 -0400
From 8ec7d7199eb28051e8403867a16257f8974414f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 25 Mar 2021 14:40:26 +0100
Subject: [PATCH] winex11.drv: Accumulate mouse movement to avoid rounding
losses.
@ -11,7 +11,7 @@ From: Jordan Galby <gravemind2a+wine@gmail.com>
1 file changed, 33 insertions(+), 7 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 2fcacaee95c..e3c5f8d122e 100644
index 44e9786cd9f..0e1559a88f3 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -365,6 +365,9 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
@ -24,7 +24,7 @@ index 2fcacaee95c..e3c5f8d122e 100644
}
#endif
@@ -1904,6 +1907,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
@@ -1961,6 +1964,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
double dx = 0, dy = 0, val;
double raw_dx = 0, raw_dy = 0, raw_val;
double x_scale = 1, y_scale = 1;
@ -32,7 +32,7 @@ index 2fcacaee95c..e3c5f8d122e 100644
struct x11drv_thread_data *thread_data = x11drv_thread_data();
XIValuatorClassInfo *x_pos, *y_pos;
@@ -1915,6 +1919,9 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
@@ -1972,6 +1976,9 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
x_pos = &thread_data->x_pos_valuator;
y_pos = &thread_data->y_pos_valuator;
@ -42,7 +42,7 @@ index 2fcacaee95c..e3c5f8d122e 100644
input.type = INPUT_MOUSE;
input.u.mi.mouseData = 0;
input.u.mi.dwFlags = MOUSEEVENTF_MOVE;
@@ -1942,9 +1949,9 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
@@ -1999,9 +2006,9 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
raw_dx = raw_val;
input.u.mi.dwFlags |= (x_pos->mode == XIModeAbsolute ? MOUSEEVENTF_ABSOLUTE : 0);
if (x_pos->mode == XIModeAbsolute)
@ -54,7 +54,7 @@ index 2fcacaee95c..e3c5f8d122e 100644
}
if (i == y_pos->number)
{
@@ -1952,18 +1959,30 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
@@ -2009,22 +2016,41 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
raw_dy = raw_val;
input.u.mi.dwFlags |= (y_pos->mode == XIModeAbsolute ? MOUSEEVENTF_ABSOLUTE : 0);
if (y_pos->mode == XIModeAbsolute)
@ -84,15 +84,10 @@ index 2fcacaee95c..e3c5f8d122e 100644
+ x_pos->value = x_accum - input.u.mi.dx;
+ y_pos->value = y_accum - input.u.mi.dy;
+
if (x_pos->mode == XIModeAbsolute)
{
TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
@@ -1971,14 +1990,21 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
}
else if (!thread_data->xi2_rawinput_only)
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 );
- __wine_send_input( 0, &input, NULL );
+ if ((dy || dy) && !(input.u.mi.dx || input.u.mi.dy))
+ {
+ TRACE( "accumulating raw motion (event %f,%f accum %f,%f)\n", dx, dy, x_pos->value, y_pos->value );
@ -100,18 +95,20 @@ index 2fcacaee95c..e3c5f8d122e 100644
+ else
+ {
+ 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 );
+ __wine_send_input( 0, &input, NULL );
+ }
}
else
{
input.u.mi.dx = raw_dx;
input.u.mi.dy = raw_dy;
@@ -2034,7 +2060,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
input.u.mi.dy = raw_dy;
}
- TRACE( "raw pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
+ TRACE( "raw pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, raw_dx, raw_dy );
__wine_send_input( 0, &input, SEND_HWMSG_RAWINPUT );
}
return TRUE;
rawinput.header.dwType = RIM_TYPEMOUSE;
rawinput.header.dwSize = offsetof(RAWINPUT, data) + sizeof(RAWMOUSE);
--
2.27.0
2.30.2

View File

@ -1,3 +1,2 @@
Fixes: [45882] - Raw Input should use untransformed mouse values (affects Overwatch, several Source games).
# Depends: user32-rawinput-mouse
Disabled: true
Depends: user32-rawinput-mouse

View File

@ -0,0 +1,133 @@
From 8016a35cf5771858b2b6245ee22e60c23a1bafd6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Fri, 17 Jan 2020 16:33:11 +0100
Subject: [PATCH] winex11.drv: Split XInput2 thread initialization.
And rename the library and function loader to x11drv_xinput_load.
---
dlls/winex11.drv/mouse.c | 46 +++++++++++++++++++++++-----------
dlls/winex11.drv/x11drv.h | 3 ++-
dlls/winex11.drv/x11drv_main.c | 4 ++-
3 files changed, 36 insertions(+), 17 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 42bac332664..ce77c7e5985 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -286,6 +286,32 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
#endif
+/***********************************************************************
+ * x11drv_xinput_init
+ */
+void x11drv_xinput_init(void)
+{
+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
+ struct x11drv_thread_data *data = x11drv_thread_data();
+ int major = 2, minor = 0;
+
+ if (data->xi2_state != xi_unknown) return;
+
+ if (xinput2_available &&
+ !pXIQueryVersion( data->display, &major, &minor ))
+ {
+ TRACE( "XInput2 %d.%d available\n", major, minor );
+ data->xi2_state = xi_disabled;
+ }
+ else
+ {
+ data->xi2_state = xi_unavailable;
+ WARN( "XInput 2.0 not available\n" );
+ }
+#endif
+}
+
+
/***********************************************************************
* enable_xinput2
*/
@@ -298,19 +324,9 @@ static void enable_xinput2(void)
unsigned char mask_bits[XIMaskLen(XI_LASTEVENT)];
int count;
- if (!xinput2_available) return;
+ TRACE( "state:%d\n", data->xi2_state );
+ if (data->xi2_state != xi_disabled) return;
- if (data->xi2_state == xi_unknown)
- {
- int major = 2, minor = 0;
- if (!pXIQueryVersion( data->display, &major, &minor )) data->xi2_state = xi_disabled;
- else
- {
- data->xi2_state = xi_unavailable;
- WARN( "X Input 2 not available\n" );
- }
- }
- if (data->xi2_state == xi_unavailable) return;
if (!pXIGetClientPointer( data->display, None, &data->xi2_core_pointer )) return;
mask.mask = mask_bits;
@@ -350,9 +366,9 @@ static void disable_xinput2(void)
struct x11drv_thread_data *data = x11drv_thread_data();
XIEventMask mask;
+ TRACE( "state:%d\n", data->xi2_state );
if (data->xi2_state != xi_enabled) return;
- TRACE( "disabling\n" );
data->xi2_state = xi_disabled;
mask.mask = NULL;
@@ -1908,9 +1924,9 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
/***********************************************************************
- * X11DRV_XInput2_Init
+ * x11drv_xinput_load
*/
-void X11DRV_XInput2_Init(void)
+void x11drv_xinput_load(void)
{
#if defined(SONAME_LIBXI) && defined(HAVE_X11_EXTENSIONS_XINPUT2_H)
int event, error;
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 45855976607..16a8a6be2be 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -195,7 +195,8 @@ extern BOOL CDECL X11DRV_UnrealizePalette( HPALETTE hpal ) DECLSPEC_HIDDEN;
/* X11 driver internal functions */
extern void X11DRV_Xcursor_Init(void) DECLSPEC_HIDDEN;
-extern void X11DRV_XInput2_Init(void) DECLSPEC_HIDDEN;
+extern void x11drv_xinput_load(void) DECLSPEC_HIDDEN;
+extern void x11drv_xinput_init(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,
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 9ec4c7a98f6..43c30ab369c 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -610,7 +610,7 @@ static BOOL process_attach(void)
#ifdef SONAME_LIBXCOMPOSITE
X11DRV_XComposite_Init();
#endif
- X11DRV_XInput2_Init();
+ x11drv_xinput_load();
#ifdef HAVE_XKB
if (use_xkb) use_xkb = XkbUseExtension( gdi_display, NULL, NULL );
@@ -702,6 +702,8 @@ struct x11drv_thread_data *x11drv_init_thread_data(void)
if (use_xim) X11DRV_SetupXIM();
+ x11drv_xinput_init();
+
return data;
}
--
2.30.2

View File

@ -0,0 +1,254 @@
From a5bff960bdb07ad110189c2ea7394370ac28b512 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 23 Jan 2020 11:00:19 +0100
Subject: [PATCH] winex11.drv: Support XInput2 events for individual windows.
This will allow us to listen to the XInput version of several events,
which can bring additional information.
---
dlls/winex11.drv/desktop.c | 1 +
dlls/winex11.drv/event.c | 7 +++++
dlls/winex11.drv/mouse.c | 59 +++++++++++++++++++++++++++-----------
dlls/winex11.drv/window.c | 3 ++
dlls/winex11.drv/x11drv.h | 12 +++++++-
5 files changed, 65 insertions(+), 17 deletions(-)
diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c
index b517e44e150..6f46ef505c9 100644
--- a/dlls/winex11.drv/desktop.c
+++ b/dlls/winex11.drv/desktop.c
@@ -356,6 +356,7 @@ BOOL CDECL X11DRV_create_desktop( UINT width, UINT height )
0, 0, width, height, 0, default_visual.depth, InputOutput, default_visual.visual,
CWEventMask | CWCursor | CWColormap, &win_attr );
if (!win) return FALSE;
+ x11drv_xinput_enable( display, win, win_attr.event_mask );
if (!create_desktop_win_data( win )) return FALSE;
X11DRV_init_desktop( win, width, height );
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 99943478729..217c1eca857 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -245,6 +245,13 @@ static Bool filter_event( Display *display, XEvent *event, char *arg )
return (mask & QS_MOUSEBUTTON) != 0;
#ifdef GenericEvent
case GenericEvent:
+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
+ if (event->xcookie.extension == xinput2_opcode &&
+ (event->xcookie.evtype == XI_RawMotion ||
+ event->xcookie.evtype == XI_DeviceChanged))
+ return (mask & QS_MOUSEMOVE) != 0;
+#endif
+ return (mask & QS_SENDMESSAGE) != 0;
#endif
case MotionNotify:
case EnterNotify:
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index ce77c7e5985..2550af3cb9c 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -313,21 +313,33 @@ void x11drv_xinput_init(void)
/***********************************************************************
- * enable_xinput2
+ * x11drv_xinput_enable
*/
-static void enable_xinput2(void)
+void x11drv_xinput_enable( Display *display, Window window, long event_mask )
{
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
struct x11drv_thread_data *data = x11drv_thread_data();
XIEventMask mask;
XIDeviceInfo *pointer_info;
unsigned char mask_bits[XIMaskLen(XI_LASTEVENT)];
+ enum xi2_state xi2_state = data ? data->xi2_state : xi_unknown;
int count;
- TRACE( "state:%d\n", data->xi2_state );
- if (data->xi2_state != xi_disabled) return;
+ TRACE( "state:%d window:%lx event_mask:%lx\n", xi2_state, window, event_mask );
- if (!pXIGetClientPointer( data->display, None, &data->xi2_core_pointer )) return;
+ if (xi2_state == xi_unavailable) return;
+
+ if (window != DefaultRootWindow( display ))
+ {
+ mask.mask = mask_bits;
+ mask.mask_len = sizeof(mask_bits);
+ mask.deviceid = XIAllMasterDevices;
+ memset( mask_bits, 0, sizeof(mask_bits) );
+
+ pXISelectEvents( display, window, &mask, 1 );
+ XSelectInput( display, window, event_mask );
+ return;
+ }
mask.mask = mask_bits;
mask.mask_len = sizeof(mask_bits);
@@ -337,8 +349,9 @@ static void enable_xinput2(void)
XISetMask( mask_bits, XI_RawMotion );
XISetMask( mask_bits, XI_ButtonPress );
- pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
+ pXISelectEvents( display, DefaultRootWindow( display ), &mask, 1 );
+ if (!data || !pXIGetClientPointer( data->display, None, &data->xi2_core_pointer )) return;
pointer_info = pXIQueryDevice( data->display, data->xi2_core_pointer, &count );
update_relative_valuators( pointer_info->classes, pointer_info->num_classes );
pXIFreeDeviceInfo( pointer_info );
@@ -347,7 +360,7 @@ static void enable_xinput2(void)
* 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.
+ * safe to be obtained statically at x11drv_xinput_enable() time.
*/
if (data->xi2_devices) pXIFreeDeviceInfo( data->xi2_devices );
data->xi2_devices = pXIQueryDevice( data->display, XIAllDevices, &data->xi2_device_count );
@@ -358,30 +371,44 @@ static void enable_xinput2(void)
}
/***********************************************************************
- * disable_xinput2
+ * x11drv_xinput_disable
*/
-static void disable_xinput2(void)
+void x11drv_xinput_disable( Display *display, Window window, long event_mask )
{
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
struct x11drv_thread_data *data = x11drv_thread_data();
+ enum xi2_state xi2_state = data ? data->xi2_state : xi_unknown;
XIEventMask mask;
- TRACE( "state:%d\n", data->xi2_state );
- if (data->xi2_state != xi_enabled) return;
+ TRACE( "state:%d window:%lx event_mask:%lx\n", xi2_state, window, event_mask );
- data->xi2_state = xi_disabled;
+ if (xi2_state == xi_unavailable) return;
+
+ if (window != DefaultRootWindow( display ))
+ {
+ mask.mask = NULL;
+ mask.mask_len = 0;
+ mask.deviceid = XIAllMasterDevices;
+
+ pXISelectEvents( display, window, &mask, 1 );
+ XSelectInput( display, window, event_mask );
+ return;
+ }
mask.mask = NULL;
mask.mask_len = 0;
mask.deviceid = XIAllDevices;
- pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
+ pXISelectEvents( display, DefaultRootWindow( display ), &mask, 1 );
+
+ if (!data) return;
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;
+ data->xi2_state = xi_disabled;
#endif
}
@@ -423,7 +450,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_xinput_enable( data->display, DefaultRootWindow( data->display ), PointerMotionMask );
if (data->xi2_state != xi_enabled)
{
@@ -453,7 +480,7 @@ static BOOL grab_clipping_window( const RECT *clip )
if (!clipping_cursor)
{
- disable_xinput2();
+ x11drv_xinput_disable( data->display, DefaultRootWindow( data->display ), PointerMotionMask );
DestroyWindow( msg_hwnd );
return FALSE;
}
@@ -532,7 +559,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_xinput_disable( data->display, DefaultRootWindow( data->display ), PointerMotionMask );
DestroyWindow( hwnd );
}
else if (prev_clip_hwnd)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index baaa30d74e3..4005e3df387 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -375,6 +375,7 @@ static void sync_window_style( struct x11drv_win_data *data )
int mask = get_window_attributes( data, &attr );
XChangeWindowAttributes( data->display, data->whole_window, mask, &attr );
+ x11drv_xinput_enable( data->display, data->whole_window, attr.event_mask );
}
}
@@ -1573,6 +1574,7 @@ static void create_whole_window( struct x11drv_win_data *data )
data->vis.visual, mask, &attr );
if (!data->whole_window) goto done;
+ x11drv_xinput_enable( data->display, data->whole_window, attr.event_mask );
set_initial_wm_hints( data->display, data->whole_window );
set_wm_hints( data );
@@ -1879,6 +1881,7 @@ BOOL CDECL X11DRV_CreateWindow( HWND hwnd )
data->clip_window = XCreateWindow( data->display, root_window, 0, 0, 1, 1, 0, 0,
InputOnly, default_visual.visual,
CWOverrideRedirect | CWEventMask, &attr );
+ x11drv_xinput_enable( data->display, data->clip_window, attr.event_mask );
XFlush( data->display );
SetPropA( hwnd, clip_window_prop, (HANDLE)data->clip_window );
X11DRV_InitClipboard();
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 16a8a6be2be..7ea60fa495a 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -197,6 +197,8 @@ extern BOOL CDECL X11DRV_UnrealizePalette( HPALETTE hpal ) DECLSPEC_HIDDEN;
extern void X11DRV_Xcursor_Init(void) DECLSPEC_HIDDEN;
extern void x11drv_xinput_load(void) DECLSPEC_HIDDEN;
extern void x11drv_xinput_init(void) DECLSPEC_HIDDEN;
+extern void x11drv_xinput_enable( Display *display, Window window, long event_mask ) DECLSPEC_HIDDEN;
+extern void x11drv_xinput_disable( Display *display, Window window, long event_mask ) 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,
@@ -324,6 +326,14 @@ struct x11drv_valuator_data
int number;
};
+enum xi2_state
+{
+ xi_unavailable = -1,
+ xi_unknown,
+ xi_disabled,
+ xi_enabled
+};
+
struct x11drv_thread_data
{
Display *display;
@@ -339,7 +349,7 @@ struct x11drv_thread_data
HWND clip_hwnd; /* message window stored in desktop while clipping is active */
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 */
+ enum xi2_state 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;
--
2.30.2

View File

@ -1,4 +1,4 @@
From 7440b3f974b66631ee71fa9acafc333e39543174 Mon Sep 17 00:00:00 2001
From 3addef6ede746e418be37c5f288027bb0247f37c 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] winex11.drv: Advertise XInput2 version 2.1 support.
@ -17,35 +17,33 @@ 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/mouse.c | 43 +++++----------------------------------
dlls/winex11.drv/x11drv.h | 3 ---
2 files changed, 10 insertions(+), 42 deletions(-)
2 files changed, 5 insertions(+), 41 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index aaa34d8ff0f..3a4b1198829 100644
index 2550af3cb9c..0d41438c5c7 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -302,12 +302,16 @@ static void enable_xinput2(void)
@@ -293,7 +293,7 @@ void x11drv_xinput_init(void)
{
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
struct x11drv_thread_data *data = x11drv_thread_data();
- int major = 2, minor = 0;
+ int major = 2, minor = 1;
if (data->xi2_state == xi_unknown)
if (data->xi2_state != xi_unknown) return;
@@ -306,7 +306,7 @@ void x11drv_xinput_init(void)
else
{
- 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" );
}
data->xi2_state = xi_unavailable;
- WARN( "XInput 2.0 not available\n" );
+ WARN( "XInput 2.1 not available\n" );
}
if (data->xi2_state == xi_unavailable) return;
@@ -315,7 +319,7 @@ static void enable_xinput2(void)
#endif
}
@@ -343,7 +343,7 @@ void x11drv_xinput_enable( Display *display, Window window, long event_mask )
mask.mask = mask_bits;
mask.mask_len = sizeof(mask_bits);
@ -54,7 +52,7 @@ index aaa34d8ff0f..3a4b1198829 100644
memset( mask_bits, 0, sizeof(mask_bits) );
XISetMask( mask_bits, XI_DeviceChanged );
XISetMask( mask_bits, XI_RawMotion );
@@ -327,16 +331,6 @@ static void enable_xinput2(void)
@@ -356,16 +356,6 @@ void x11drv_xinput_enable( Display *display, Window window, long event_mask )
update_relative_valuators( pointer_info->classes, pointer_info->num_classes );
pXIFreeDeviceInfo( pointer_info );
@ -62,7 +60,7 @@ index aaa34d8ff0f..3a4b1198829 100644
- * 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.
- * safe to be obtained statically at x11drv_xinput_enable() time.
- */
- if (data->xi2_devices) pXIFreeDeviceInfo( data->xi2_devices );
- data->xi2_devices = pXIQueryDevice( data->display, XIAllDevices, &data->xi2_device_count );
@ -71,24 +69,26 @@ index aaa34d8ff0f..3a4b1198829 100644
data->xi2_state = xi_enabled;
#endif
}
@@ -357,15 +351,12 @@ static void disable_xinput2(void)
@@ -397,17 +387,14 @@ void x11drv_xinput_disable( Display *display, Window window, long event_mask )
mask.mask = NULL;
mask.mask_len = 0;
- mask.deviceid = XIAllDevices;
+ mask.deviceid = XIAllMasterDevices;
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
pXISelectEvents( display, DefaultRootWindow( display ), &mask, 1 );
if (!data) return;
- 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;
data->xi2_state = xi_disabled;
#endif
}
@@ -1799,7 +1790,6 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev )
@@ -1860,7 +1847,6 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev )
if (event->reason != XISlaveSwitch) return FALSE;
update_relative_valuators( event->classes, event->num_classes );
@ -96,7 +96,7 @@ index aaa34d8ff0f..3a4b1198829 100644
return TRUE;
}
@@ -1820,26 +1810,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
@@ -1881,26 +1867,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;
@ -125,13 +125,13 @@ index aaa34d8ff0f..3a4b1198829 100644
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 cfce09bf11d..8a02a6ebf94 100644
index 7ea60fa495a..df8a53bb228 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -339,12 +339,9 @@ struct x11drv_thread_data
@@ -350,12 +350,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 */
enum xi2_state 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;
@ -142,5 +142,5 @@ index cfce09bf11d..8a02a6ebf94 100644
extern struct x11drv_thread_data *x11drv_init_thread_data(void) DECLSPEC_HIDDEN;
--
2.27.0
2.30.2

View File

@ -1,4 +1,4 @@
From e0245cae5151eddb30eeaed3116697257ce65f22 Mon Sep 17 00:00:00 2001
From a88aed6df65592b55fde5ecee55b090149c362bb 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] winex11.drv: Keep track of pointer and device button
@ -16,10 +16,10 @@ Original patch by Andrew Eikum <aeikum@codeweavers.com>.
4 files changed, 106 insertions(+), 8 deletions(-)
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index 2a3bed787ab..37c96c926f4 100644
index 01620c5e4a4..272f728def9 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1977,13 +1977,24 @@ BOOL X11DRV_MappingNotify( HWND dummy, XEvent *event )
@@ -1976,13 +1976,24 @@ BOOL X11DRV_MappingNotify( HWND dummy, XEvent *event )
{
HWND hwnd;
@ -51,7 +51,7 @@ index 2a3bed787ab..37c96c926f4 100644
}
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 3a4b1198829..26e8b4eea92 100644
index 0d41438c5c7..fc5fd29d7b6 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -25,6 +25,9 @@
@ -150,7 +150,7 @@ index 3a4b1198829..26e8b4eea92 100644
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
/***********************************************************************
* update_relative_valuators
@@ -1790,6 +1865,8 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev )
@@ -1847,6 +1922,8 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev )
if (event->reason != XISlaveSwitch) return FALSE;
update_relative_valuators( event->classes, event->num_classes );
@ -159,22 +159,22 @@ index 3a4b1198829..26e8b4eea92 100644
return TRUE;
}
@@ -1859,13 +1936,12 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
@@ -1916,13 +1993,12 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
#endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */
-
/***********************************************************************
* X11DRV_XInput2_Init
* x11drv_xinput_load
*/
void X11DRV_XInput2_Init(void)
void x11drv_xinput_load(void)
{
-#if defined(SONAME_LIBXI) && defined(HAVE_X11_EXTENSIONS_XINPUT2_H)
+#if defined(SONAME_LIBXI)
int event, error;
void *libxi_handle = dlopen( SONAME_LIBXI, RTLD_NOW );
@@ -1881,11 +1957,20 @@ void X11DRV_XInput2_Init(void)
@@ -1938,11 +2014,20 @@ void x11drv_xinput_load(void)
return; \
}
@ -196,10 +196,10 @@ index 3a4b1198829..26e8b4eea92 100644
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 8a02a6ebf94..73b1e90f12e 100644
index df8a53bb228..afa990b7e68 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -629,6 +629,7 @@ extern void retry_grab_clipping_window(void) DECLSPEC_HIDDEN;
@@ -643,6 +643,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;
@ -208,10 +208,10 @@ index 8a02a6ebf94..73b1e90f12e 100644
DWORD mask, DWORD flags ) DECLSPEC_HIDDEN;
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index e6e61e801e1..20e829ba64f 100644
index 43c30ab369c..d8576949aea 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -615,6 +615,7 @@ static BOOL process_attach(void)
@@ -616,6 +616,7 @@ static BOOL process_attach(void)
if (use_xkb) use_xkb = XkbUseExtension( gdi_display, NULL, NULL );
#endif
X11DRV_InitKeyboard( gdi_display );
@ -220,5 +220,5 @@ index e6e61e801e1..20e829ba64f 100644
X11DRV_DisplayDevices_Init(FALSE);
--
2.27.0
2.30.2

View File

@ -0,0 +1,101 @@
From ce3b572e3b0ac1b19e9d032039435044e51929de 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] server: Add send_hardware_message flags for rawinput
translation.
---
dlls/user32/message.c | 2 ++
server/protocol.def | 1 +
server/queue.c | 12 ++++++------
3 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index f986b71953a..98f6c2730e0 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -3259,6 +3259,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r
req->input.mouse.flags = input->u.mi.dwFlags;
req->input.mouse.time = input->u.mi.time;
req->input.mouse.info = input->u.mi.dwExtraInfo;
+ req->flags |= SEND_HWMSG_RAWINPUT;
break;
case INPUT_KEYBOARD:
req->input.kbd.vkey = input->u.ki.wVk;
@@ -3266,6 +3267,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r
req->input.kbd.flags = input->u.ki.dwFlags;
req->input.kbd.time = input->u.ki.time;
req->input.kbd.info = input->u.ki.dwExtraInfo;
+ req->flags |= SEND_HWMSG_RAWINPUT;
break;
case INPUT_HARDWARE:
req->input.hw.msg = input->u.hi.uMsg;
diff --git a/server/protocol.def b/server/protocol.def
index 829216b58c1..90379955ecd 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2054,6 +2054,7 @@ enum message_type
VARARG(keystate,bytes); /* global state array for all the keys */
@END
#define SEND_HWMSG_INJECTED 0x01
+#define SEND_HWMSG_RAWINPUT 0x02
/* Get a message from the current queue */
diff --git a/server/queue.c b/server/queue.c
index a411d0af8d2..a928f4d7fad 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1782,7 +1782,7 @@ done:
/* 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;
@@ -1837,7 +1837,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
y = desktop->cursor.y;
}
- if ((foreground = get_foreground_thread( desktop, win )))
+ if ((req_flags & SEND_HWMSG_RAWINPUT) && (foreground = get_foreground_thread( desktop, win )))
{
raw_msg.foreground = foreground;
raw_msg.desktop = desktop;
@@ -1896,7 +1896,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;
@@ -1974,7 +1974,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
break;
}
- if ((foreground = get_foreground_thread( desktop, win )))
+ if ((req_flags & SEND_HWMSG_RAWINPUT) && (foreground = get_foreground_thread( desktop, win )))
{
raw_msg.foreground = foreground;
raw_msg.desktop = desktop;
@@ -2603,11 +2603,11 @@ DECL_HANDLER(send_hardware_message)
{
case INPUT_MOUSE:
if (!desktop) return;
- 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:
if (!desktop) return;
- 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:
if (!desktop) set_error( STATUS_SUCCESS );
--
2.30.2

View File

@ -1,128 +0,0 @@
From 7a3a5195d932de5bc6291458f15fa5400c9777f0 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] 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 1dd43a36a11..f0b95c7fc6c 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -125,7 +125,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;
}
@@ -193,9 +193,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 56fda14932d..21de849e5d8 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2339,6 +2339,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 ff9e703d1ff..46ace52f004 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1695,7 +1695,7 @@ done:
/* 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;
@@ -1765,7 +1765,8 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
msg_data->rawinput.mouse.y = y - desktop->cursor.y;
msg_data->rawinput.mouse.data = input->mouse.data;
- enum_processes( queue_rawinput_message, &raw_msg );
+ if ((req_flags & SEND_HWMSG_RAWINPUT))
+ enum_processes( queue_rawinput_message, &raw_msg );
release_object( foreground );
}
@@ -1775,6 +1776,9 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
return 0;
}
+ if (!(req_flags & SEND_HWMSG_WINDOW))
+ return 0;
+
for (i = 0; i < ARRAY_SIZE( messages ); i++)
{
if (!messages[i]) continue;
@@ -1806,7 +1810,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;
@@ -1899,7 +1903,8 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
msg_data->rawinput.kbd.vkey = vkey;
msg_data->rawinput.kbd.scan = input->kbd.scan;
- enum_processes( queue_rawinput_message, &raw_msg );
+ if ((req_flags & SEND_HWMSG_RAWINPUT))
+ enum_processes( queue_rawinput_message, &raw_msg );
release_object( foreground );
}
@@ -1909,6 +1914,9 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
return 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;
@@ -2465,10 +2473,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.27.0

View File

@ -0,0 +1,278 @@
From acd309726a5ca6ac94a7ea13c92382ae637e21ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Wed, 24 Mar 2021 23:29:28 +0100
Subject: [PATCH] user32: Set SEND_HWMSG_RAWINPUT flags only when RAWINPUT is
set.
So we can generate legacy messages only by calling __wine_send_input
with NULL rawinput, and generate WM_INPUT messages only by calling
__wine_send_input with INPUT_HARDWARE input type and a rawinput.
---
dlls/user32/input.c | 3 ++-
dlls/user32/message.c | 4 ++--
dlls/wineandroid.drv/keyboard.c | 3 ++-
dlls/wineandroid.drv/window.c | 5 +++--
dlls/winemac.drv/ime.c | 6 ++++--
dlls/winemac.drv/keyboard.c | 3 ++-
dlls/winemac.drv/mouse.c | 3 ++-
dlls/winex11.drv/keyboard.c | 3 ++-
dlls/winex11.drv/mouse.c | 11 +++++++----
9 files changed, 26 insertions(+), 15 deletions(-)
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 3fc818a2510..af1ad797102 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -181,6 +181,7 @@ UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size )
{
UINT i;
NTSTATUS status = STATUS_SUCCESS;
+ RAWINPUT rawinput;
if (size != sizeof(INPUT))
{
@@ -210,7 +211,7 @@ UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size )
update_mouse_coords( &input );
/* fallthrough */
case INPUT_KEYBOARD:
- status = send_hardware_message( 0, &input, NULL, SEND_HWMSG_INJECTED );
+ status = send_hardware_message( 0, &input, &rawinput, SEND_HWMSG_INJECTED );
break;
#ifdef _WIN64
case INPUT_HARDWARE:
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index 98f6c2730e0..43c6adad033 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -3259,7 +3259,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r
req->input.mouse.flags = input->u.mi.dwFlags;
req->input.mouse.time = input->u.mi.time;
req->input.mouse.info = input->u.mi.dwExtraInfo;
- req->flags |= SEND_HWMSG_RAWINPUT;
+ if (rawinput) req->flags |= SEND_HWMSG_RAWINPUT;
break;
case INPUT_KEYBOARD:
req->input.kbd.vkey = input->u.ki.wVk;
@@ -3267,7 +3267,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r
req->input.kbd.flags = input->u.ki.dwFlags;
req->input.kbd.time = input->u.ki.time;
req->input.kbd.info = input->u.ki.dwExtraInfo;
- req->flags |= SEND_HWMSG_RAWINPUT;
+ if (rawinput) req->flags |= SEND_HWMSG_RAWINPUT;
break;
case INPUT_HARDWARE:
req->input.hw.msg = input->u.hi.uMsg;
diff --git a/dlls/wineandroid.drv/keyboard.c b/dlls/wineandroid.drv/keyboard.c
index 0a6ede0ec5f..df85188fbbb 100644
--- a/dlls/wineandroid.drv/keyboard.c
+++ b/dlls/wineandroid.drv/keyboard.c
@@ -671,6 +671,7 @@ static BOOL get_async_key_state( BYTE state[256] )
static void send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD flags )
{
+ RAWINPUT rawinput;
INPUT input;
input.type = INPUT_KEYBOARD;
@@ -680,7 +681,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, NULL );
+ __wine_send_input( hwnd, &input, &rawinput );
}
/***********************************************************************
diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c
index 1cb1bbbadc9..92a1c5012a0 100644
--- a/dlls/wineandroid.drv/window.c
+++ b/dlls/wineandroid.drv/window.c
@@ -428,6 +428,7 @@ static int process_events( DWORD mask )
DPI_AWARENESS_CONTEXT context;
struct java_event *event, *next, *previous;
unsigned int count = 0;
+ RAWINPUT rawinput;
assert( GetCurrentThreadId() == desktop_tid );
@@ -521,7 +522,7 @@ static int process_events( DWORD mask )
}
SERVER_END_REQ;
}
- __wine_send_input( capture ? capture : event->data.motion.hwnd, &event->data.motion.input, NULL );
+ __wine_send_input( capture ? capture : event->data.motion.hwnd, &event->data.motion.input, &rawinput );
}
break;
@@ -535,7 +536,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, NULL );
+ __wine_send_input( 0, &event->data.kbd.input, &rawinput );
break;
default:
diff --git a/dlls/winemac.drv/ime.c b/dlls/winemac.drv/ime.c
index f2368c10743..89f6d9c617d 100644
--- a/dlls/winemac.drv/ime.c
+++ b/dlls/winemac.drv/ime.c
@@ -42,6 +42,7 @@
#include "winuser.h"
#include "imm.h"
#include "ddk/imm.h"
+#include "wine/server.h"
WINE_DEFAULT_DEBUG_CHANNEL(imm);
@@ -1415,6 +1416,7 @@ void macdrv_im_set_text(const macdrv_event *event)
event->im_set_text.cursor_pos, !event->im_set_text.complete);
else
{
+ RAWINPUT rawinput;
INPUT input;
CFIndex i;
@@ -1427,10 +1429,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, NULL);
+ __wine_send_input(hwnd, &input, &rawinput);
input.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
- __wine_send_input(hwnd, &input, NULL);
+ __wine_send_input(hwnd, &input, &rawinput);
}
}
diff --git a/dlls/winemac.drv/keyboard.c b/dlls/winemac.drv/keyboard.c
index 1ea15f59341..b4d50058d4e 100644
--- a/dlls/winemac.drv/keyboard.c
+++ b/dlls/winemac.drv/keyboard.c
@@ -918,6 +918,7 @@ void macdrv_compute_keyboard_layout(struct macdrv_thread_data *thread_data)
*/
static void macdrv_send_keyboard_input(HWND hwnd, WORD vkey, WORD scan, DWORD flags, DWORD time)
{
+ RAWINPUT rawinput;
INPUT input;
TRACE_(key)("hwnd %p vkey=%04x scan=%04x flags=%04x\n", hwnd, vkey, scan, flags);
@@ -929,7 +930,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, NULL);
+ __wine_send_input(hwnd, &input, &rawinput);
}
diff --git a/dlls/winemac.drv/mouse.c b/dlls/winemac.drv/mouse.c
index d2278ae0e4c..d6598617456 100644
--- a/dlls/winemac.drv/mouse.c
+++ b/dlls/winemac.drv/mouse.c
@@ -136,6 +136,7 @@ static const CFStringRef cocoa_cursor_names[] =
static void send_mouse_input(HWND hwnd, macdrv_window cocoa_window, UINT flags, int x, int y,
DWORD mouse_data, BOOL drag, unsigned long time)
{
+ RAWINPUT rawinput;
INPUT input;
HWND top_level_hwnd;
@@ -165,7 +166,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, NULL);
+ __wine_send_input(top_level_hwnd, &input, &rawinput);
}
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index 272f728def9..2e87eeede99 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1137,6 +1137,7 @@ static WORD EVENT_event_to_vkey( XIC xic, XKeyEvent *e)
*/
static void X11DRV_send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD flags, DWORD time )
{
+ RAWINPUT rawinput;
INPUT input;
TRACE_(key)( "hwnd %p vkey=%04x scan=%04x flags=%04x\n", hwnd, vkey, scan, flags );
@@ -1148,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, NULL );
+ __wine_send_input( hwnd, &input, &rawinput );
}
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index fc5fd29d7b6..6b6512521f4 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -748,6 +748,7 @@ static void map_event_coords( HWND hwnd, Window window, Window event_root, int x
static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPUT *input )
{
struct x11drv_win_data *data;
+ RAWINPUT rawinput;
input->type = INPUT_MOUSE;
@@ -764,7 +765,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
sync_window_cursor( window );
last_cursor_change = input->u.mi.time;
}
- __wine_send_input( hwnd, input, NULL );
+ __wine_send_input( hwnd, input, &rawinput );
return;
}
@@ -804,7 +805,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
SERVER_END_REQ;
}
- __wine_send_input( hwnd, input, NULL );
+ __wine_send_input( hwnd, input, &rawinput );
}
#ifdef SONAME_LIBXCURSOR
@@ -1759,6 +1760,7 @@ void move_resize_window( HWND hwnd, int dir )
{
MSG msg;
INPUT input;
+ RAWINPUT rawinput;
int x, y, rootX, rootY;
if (!XQueryPointer( display, root_window, &root, &child, &rootX, &rootY, &x, &y, &xstate )) break;
@@ -1774,7 +1776,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, NULL );
+ __wine_send_input( hwnd, &input, &rawinput );
}
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
@@ -1935,6 +1937,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
XIRawEvent *event = xev->data;
const double *values = event->valuators.values;
RECT virtual_rect;
+ RAWINPUT rawinput;
INPUT input;
int i;
double dx = 0, dy = 0, val;
@@ -1987,7 +1990,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, NULL );
+ __wine_send_input( 0, &input, &rawinput );
return TRUE;
}
--
2.30.2

View File

@ -0,0 +1,54 @@
From ba34a1671d177a18391e3bf8619cea68eead6e34 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 25 Mar 2021 14:26:35 +0100
Subject: [PATCH] user32: Support sending RIM_TYPEMOUSE through
__wine_send_input.
---
dlls/user32/message.c | 6 ++++++
server/queue.c | 5 ++++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index 43c6adad033..d62da5de16f 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -3279,6 +3279,12 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r
req->input.hw.data.rawinput.type = rawinput->header.dwType;
switch (rawinput->header.dwType)
{
+ case RIM_TYPEMOUSE:
+ req->input.hw.data.rawinput.mouse.x = rawinput->data.mouse.lLastX;
+ req->input.hw.data.rawinput.mouse.y = rawinput->data.mouse.lLastY;
+ req->input.hw.data.rawinput.mouse.data = rawinput->data.mouse.u.ulButtons;
+ req->input.hw.lparam = rawinput->data.mouse.ulRawButtons;
+ break;
case RIM_TYPEHID:
assert( rawinput->data.hid.dwCount <= 1 );
req->input.hw.data.rawinput.hid.device = HandleToUlong( rawinput->header.hDevice );
diff --git a/server/queue.c b/server/queue.c
index a928f4d7fad..9008f8e90ff 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -2054,7 +2054,7 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_
raw_msg.extra = NULL;
raw_msg.extra_len = 0;
- if (input->hw.msg == WM_INPUT)
+ if (input->hw.msg == WM_INPUT && input->hw.data.rawinput.type == RIM_TYPEHID)
{
raw_msg.extra = get_req_data();
raw_msg.extra_len = get_req_data_size();
@@ -2065,6 +2065,9 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_
msg_data->flags = 0;
msg_data->rawinput = input->hw.data.rawinput;
+ if (input->hw.msg == WM_INPUT && input->hw.data.rawinput.type == RIM_TYPEMOUSE)
+ msg_data->flags = input->hw.lparam;
+
if (input->hw.msg == WM_INPUT_DEVICE_CHANGE &&
input->hw.data.rawinput.type == RIM_TYPEHID &&
input->hw.data.rawinput.hid.param == GIDC_ARRIVAL)
--
2.30.2

View File

@ -0,0 +1,244 @@
From a385e325b7fda81327d4e4d41363d20e98b3171f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 25 Mar 2021 16:12:58 +0100
Subject: [PATCH] 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/winex11.drv/event.c | 10 +++-
dlls/winex11.drv/mouse.c | 107 ++++++++++++++++++++++++++++++++++----
dlls/winex11.drv/x11drv.h | 1 +
3 files changed, 107 insertions(+), 11 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 217c1eca857..8685ce9536b 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -328,6 +328,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:
@@ -359,19 +363,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 6b6512521f4..0558467a805 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -422,7 +422,18 @@ void x11drv_xinput_enable( Display *display, Window window, long event_mask )
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( display, DefaultRootWindow( display ), &mask, 1 );
@@ -748,7 +759,6 @@ static void map_event_coords( HWND hwnd, Window window, Window event_root, int x
static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPUT *input )
{
struct x11drv_win_data *data;
- RAWINPUT rawinput;
input->type = INPUT_MOUSE;
@@ -765,7 +775,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
sync_window_cursor( window );
last_cursor_change = input->u.mi.time;
}
- __wine_send_input( hwnd, input, &rawinput );
+ __wine_send_input( hwnd, input, NULL );
return;
}
@@ -805,7 +815,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
SERVER_END_REQ;
}
- __wine_send_input( hwnd, input, &rawinput );
+ __wine_send_input( hwnd, input, NULL );
}
#ifdef SONAME_LIBXCURSOR
@@ -1760,7 +1770,6 @@ void move_resize_window( HWND hwnd, int dir )
{
MSG msg;
INPUT input;
- RAWINPUT rawinput;
int x, y, rootX, rootY;
if (!XQueryPointer( display, root_window, &root, &child, &rootX, &rootY, &x, &y, &xstate )) break;
@@ -1776,7 +1785,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, &rawinput );
+ __wine_send_input( hwnd, &input, NULL );
}
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
@@ -1952,6 +1961,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 );
@@ -1987,10 +1997,85 @@ 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, NULL );
+ }
+ else
+ {
+ TRACE( "raw 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, &rawinput );
+ rawinput.header.dwType = RIM_TYPEMOUSE;
+ rawinput.header.dwSize = offsetof(RAWINPUT, data) + sizeof(RAWMOUSE);
+ rawinput.header.hDevice = ULongToHandle(1); /* WINE_MOUSE_HANDLE */
+ rawinput.header.wParam = RIM_INPUT;
+ rawinput.data.mouse.ulRawButtons = input.u.mi.dwFlags;
+ rawinput.data.mouse.u.ulButtons = input.u.mi.mouseData;
+ rawinput.data.mouse.lLastX = input.u.mi.dx;
+ rawinput.data.mouse.lLastY = input.u.mi.dy;
+ rawinput.data.mouse.ulExtraInformation = 0;
+
+ input.type = INPUT_HARDWARE;
+ input.u.hi.uMsg = WM_INPUT;
+ input.u.hi.wParamH = (WORD)(rawinput.header.dwSize >> 16);
+ input.u.hi.wParamL = (WORD)(rawinput.header.dwSize >> 0);
+ if (rawinput.data.mouse.lLastX || rawinput.data.mouse.lLastY)
+ __wine_send_input( 0, &input, &rawinput );
+ }
+ return TRUE;
+}
+
+/***********************************************************************
+ * 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;
+ RAWINPUT rawinput;
+ 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" );
+
+ rawinput.header.dwType = RIM_TYPEMOUSE;
+ rawinput.header.dwSize = offsetof(RAWINPUT, data) + sizeof(RAWMOUSE);
+ rawinput.header.hDevice = ULongToHandle(1); /* WINE_MOUSE_HANDLE */
+ rawinput.header.wParam = RIM_INPUT;
+ if (event->evtype == XI_RawButtonRelease)
+ {
+ rawinput.data.mouse.ulRawButtons = button_up_flags[button];
+ rawinput.data.mouse.u.ulButtons = button_up_data[button];
+ }
+ else
+ {
+ rawinput.data.mouse.ulRawButtons = button_down_flags[button];
+ rawinput.data.mouse.u.ulButtons = button_down_data[button];
+ }
+ rawinput.data.mouse.lLastX = 0;
+ rawinput.data.mouse.lLastY = 0;
+ rawinput.data.mouse.ulExtraInformation = 0;
+
+ input.type = INPUT_HARDWARE;
+ input.u.hi.uMsg = WM_INPUT;
+ input.u.hi.wParamH = (WORD)(rawinput.header.dwSize >> 16);
+ input.u.hi.wParamL = (WORD)(rawinput.header.dwSize >> 0);
+ if (rawinput.data.mouse.ulRawButtons || rawinput.data.mouse.u.ulButtons)
+ __wine_send_input( 0, &input, &rawinput );
return TRUE;
}
@@ -2066,6 +2151,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 afa990b7e68..910a6c6cc18 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -353,6 +353,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;
--
2.30.2

View File

@ -1,282 +0,0 @@
From b1139be0f5b7cc4c682f382655a6b58e5087a711 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] 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/winex11.drv/event.c | 10 +++-
dlls/winex11.drv/mouse.c | 88 ++++++++++++++++++++++++++++------
dlls/winex11.drv/x11drv.h | 3 ++
dlls/winex11.drv/x11drv_main.c | 4 ++
4 files changed, 89 insertions(+), 16 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 07f7a1ad502..d722ba9d7cc 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 a1f2d4262e1..74598a3a85b 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -362,9 +362,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();
@@ -396,9 +396,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 );
@@ -411,9 +423,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();
@@ -473,7 +485,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)
{
@@ -503,7 +515,7 @@ static BOOL grab_clipping_window( const RECT *clip )
if (!clipping_cursor)
{
- disable_xinput2();
+ X11DRV_XInput2_Disable();
DestroyWindow( msg_hwnd );
return FALSE;
}
@@ -582,7 +594,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 (prev_clip_hwnd)
@@ -719,7 +731,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;
}
@@ -759,7 +771,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
@@ -1729,7 +1741,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 ))
@@ -1912,6 +1924,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 );
@@ -1947,10 +1960,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;
}
@@ -2026,6 +2082,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 6c2a8978eb5..92bd23c93ea 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 6b32f3fd118..a7855a3245b 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -633,6 +633,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 );
@@ -702,6 +704,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.28.0

View File

@ -1,36 +0,0 @@
From b8cfcfa8e3b7694102462b6d3d59ee7919897a00 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Tue, 1 Dec 2020 10:19:00 +1100
Subject: [PATCH] winex11.drv: Move header order
The HAVE_X11_EXTENSIONS_XINPUT2_H needs to be moved into each of the files
to avoid a compile error with Status being undefined.
---
dlls/winex11.drv/window.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 1e9d63ae808..22a330b3f88 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -37,6 +37,8 @@
#include <X11/extensions/shape.h>
#endif /* HAVE_LIBXSHAPE */
+#include "x11drv.h"
+
/* avoid conflict with field names in included win32 headers */
#undef Status
#include "windef.h"
@@ -45,7 +47,7 @@
#include "winuser.h"
#include "wine/unicode.h"
-#include "x11drv.h"
+
#include "wine/debug.h"
#include "wine/server.h"
#include "mwm.h"
--
2.29.2

View File

@ -1,4 +1,3 @@
Fixes: [42631] Mouse drift, jump or don't react to small slow movements in Unity-engine games and Fallout 4 (partly fixed in Unity games, have walkaround in Fallout4 )
Fixes: [42675] Overwatch: Phantom mouse input / view pulled up to ceiling
# In the process of upstreaming.
Disabled: true
Depends: user32-rawinput-hid