mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
user32-rawinput-*: Replace with new patches from Rémi Bernon.
This commit is contained in:
parent
64ea26c0cb
commit
661df7b889
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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( ¤t->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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user