mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
Updated rawinput patchsets
This is a completely updated rawinput patchsets from Rémi Bernon, replacing the current user32-rawinput.
This commit is contained in:
parent
a8cb853708
commit
8218a78955
@ -304,6 +304,11 @@ patch_enable_all ()
|
||||
enable_user32_ScrollWindowEx="$1"
|
||||
enable_user32_ShowWindow="$1"
|
||||
enable_user32_msgbox_Support_WM_COPY_mesg="$1"
|
||||
enable_user32_rawinput_hid="$1"
|
||||
enable_user32_rawinput_keyboard="$1"
|
||||
enable_user32_rawinput_mouse="$1"
|
||||
enable_user32_rawinput_mouse_experimental="$1"
|
||||
enable_user32_rawinput_nolegacy="$1"
|
||||
enable_user32_recursive_activation="$1"
|
||||
enable_user32_window_activation="$1"
|
||||
enable_uxtheme_CloseThemeClass="$1"
|
||||
@ -1041,6 +1046,21 @@ 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-keyboard)
|
||||
enable_user32_rawinput_keyboard="$2"
|
||||
;;
|
||||
user32-rawinput-mouse)
|
||||
enable_user32_rawinput_mouse="$2"
|
||||
;;
|
||||
user32-rawinput-mouse-experimental)
|
||||
enable_user32_rawinput_mouse_experimental="$2"
|
||||
;;
|
||||
user32-rawinput-nolegacy)
|
||||
enable_user32_rawinput_nolegacy="$2"
|
||||
;;
|
||||
user32-recursive-activation)
|
||||
enable_user32_recursive_activation="$2"
|
||||
;;
|
||||
@ -1671,6 +1691,41 @@ if test "$enable_user32_window_activation" -eq 1; then
|
||||
enable_user32_recursive_activation=1
|
||||
fi
|
||||
|
||||
if test "$enable_user32_rawinput_mouse_experimental" -eq 1; then
|
||||
if test "$enable_user32_rawinput_nolegacy" -gt 1; then
|
||||
abort "Patchset user32-rawinput-nolegacy disabled, but user32-rawinput-mouse-experimental depends on that."
|
||||
fi
|
||||
enable_user32_rawinput_nolegacy=1
|
||||
fi
|
||||
|
||||
if test "$enable_user32_rawinput_keyboard" -eq 1; then
|
||||
if test "$enable_user32_rawinput_hid" -gt 1; then
|
||||
abort "Patchset user32-rawinput-hid disabled, but user32-rawinput-keyboard depends on that."
|
||||
fi
|
||||
enable_user32_rawinput_hid=1
|
||||
fi
|
||||
|
||||
if test "$enable_user32_rawinput_hid" -eq 1; then
|
||||
if test "$enable_user32_rawinput_nolegacy" -gt 1; then
|
||||
abort "Patchset user32-rawinput-nolegacy disabled, but user32-rawinput-hid depends on that."
|
||||
fi
|
||||
enable_user32_rawinput_nolegacy=1
|
||||
fi
|
||||
|
||||
if test "$enable_user32_rawinput_nolegacy" -eq 1; then
|
||||
if test "$enable_user32_rawinput_mouse" -gt 1; then
|
||||
abort "Patchset user32-rawinput-mouse disabled, but user32-rawinput-nolegacy depends on that."
|
||||
fi
|
||||
enable_user32_rawinput_mouse=1
|
||||
fi
|
||||
|
||||
if test "$enable_user32_rawinput_mouse" -eq 1; then
|
||||
if test "$enable_winex11_drv_mouse_coorrds" -gt 1; then
|
||||
abort "Patchset winex11.drv-mouse-coorrds disabled, but user32-rawinput-mouse depends on that."
|
||||
fi
|
||||
enable_winex11_drv_mouse_coorrds=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."
|
||||
@ -6450,6 +6505,158 @@ if test "$enable_user32_msgbox_Support_WM_COPY_mesg" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset winex11.drv-mouse-coorrds
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#46309] winex11.drv: Use root-relative coordinates for events, if possible.
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/winex11.drv/mouse.c
|
||||
# |
|
||||
if test "$enable_winex11_drv_mouse_coorrds" -eq 1; then
|
||||
patch_apply winex11.drv-mouse-coorrds/0001-winex11.drv-mouse-Use-root-relative-coordinates-for-ev.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Gabriel Ivăncescu", "winex11.drv/mouse: Use root-relative coordinates for events, if possible.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset user32-rawinput-mouse
|
||||
# |
|
||||
# | This patchset has the following (direct or indirect) dependencies:
|
||||
# | * winex11.drv-mouse-coorrds
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#42631] - user32: Add Raw Input support.
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/dinput/device_private.h, dlls/dinput/dinput_main.c, dlls/dinput/mouse.c, dlls/dinput8/tests/device.c,
|
||||
# | dlls/user32/input.c, dlls/user32/rawinput.c, dlls/user32/tests/input.c, dlls/user32/user32.spec,
|
||||
# | 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/event.c, dlls/winex11.drv/keyboard.c, dlls/winex11.drv/mouse.c,
|
||||
# | dlls/winex11.drv/x11drv.h, dlls/winex11.drv/x11drv_main.c, include/winuser.h, server/protocol.def, server/queue.c
|
||||
# |
|
||||
if test "$enable_user32_rawinput_mouse" -eq 1; then
|
||||
patch_apply user32-rawinput-mouse/0001-user32-tests-Add-rawinput-test-for-ClipCursor-intera.patch
|
||||
patch_apply user32-rawinput-mouse/0002-user32-tests-Add-rawinput-test-for-cross-thread-inte.patch
|
||||
patch_apply user32-rawinput-mouse/0003-user32-tests-Add-rawinput-test-for-cross-process-int.patch
|
||||
patch_apply user32-rawinput-mouse/0004-server-Add-send_hardware_message-flags-for-rawinput-.patch
|
||||
patch_apply user32-rawinput-mouse/0005-server-Broadcast-rawinput-message-if-request-flag-is.patch
|
||||
patch_apply user32-rawinput-mouse/0006-user32-Add-__wine_send_input-flags-to-hint-raw-input.patch
|
||||
patch_apply user32-rawinput-mouse/0007-winex11.drv-Advertise-XInput2-version-2.1-support.patch
|
||||
patch_apply user32-rawinput-mouse/0008-winex11.drv-Keep-track-of-pointer-and-device-button-.patch
|
||||
patch_apply user32-rawinput-mouse/0009-winex11.drv-Listen-to-RawMotion-and-RawButton-events.patch
|
||||
patch_apply user32-rawinput-mouse/0010-user32-Implement-GetRegisteredRawInputDevices.patch
|
||||
patch_apply user32-rawinput-mouse/0011-dinput8-Add-support-for-dinput-devices-that-use-raw-.patch
|
||||
patch_apply user32-rawinput-mouse/0012-dinput8-Use-raw-input-interface-for-dinput8-mouse-de.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Rémi Bernon", "user32/tests: Add rawinput test for ClipCursor interactions.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "user32/tests: Add rawinput test for cross-thread interactions.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "user32/tests: Add rawinput test for cross-process interactions.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "server: Add send_hardware_message flags for rawinput translation.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "server: Broadcast rawinput message if request flag is SEND_HWMSG_RAWINPUT.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "user32: Add __wine_send_input flags to hint raw input translation.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "winex11.drv: Advertise XInput2 version 2.1 support.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "winex11.drv: Keep track of pointer and device button mappings.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "winex11.drv: Listen to RawMotion and RawButton* events in the desktop thread.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "user32: Implement GetRegisteredRawInputDevices.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "dinput8: Add support for dinput devices that use raw input interface.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "dinput8: Use raw input interface for dinput8 mouse device.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset user32-rawinput-nolegacy
|
||||
# |
|
||||
# | This patchset has the following (direct or indirect) dependencies:
|
||||
# | * winex11.drv-mouse-coorrds, user32-rawinput-mouse
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/dinput/dinput_main.c, dlls/dinput8/tests/device.c, dlls/user32/rawinput.c, server/queue.c
|
||||
# |
|
||||
if test "$enable_user32_rawinput_nolegacy" -eq 1; then
|
||||
patch_apply user32-rawinput-nolegacy/0001-dinput8-tests-Add-test-for-DISCL_EXCLUSIVE-flag-inte.patch
|
||||
patch_apply user32-rawinput-nolegacy/0002-user32-Add-support-for-RIDEV_NOLEGACY-flag-in-Regist.patch
|
||||
patch_apply user32-rawinput-nolegacy/0003-dinput-Set-RIDEV_INPUTSINK-flag-only-when-DISCL_BACK.patch
|
||||
patch_apply user32-rawinput-nolegacy/0004-dinput-Set-correct-rawinput-flags-for-DISCL_EXCLUSIV.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Rémi Bernon", "dinput8/tests: Add test for DISCL_EXCLUSIVE flag interaction with rawinput.", 1 },';
|
||||
printf '%s\n' '+ { "Derek Lesho", "user32: Add support for RIDEV_NOLEGACY flag in RegisterRawInputDevices.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "dinput: Set RIDEV_INPUTSINK flag only when DISCL_BACKGROUND is requested.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "dinput: Set correct rawinput flags for DISCL_EXCLUSIVE.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset user32-rawinput-hid
|
||||
# |
|
||||
# | This patchset has the following (direct or indirect) dependencies:
|
||||
# | * winex11.drv-mouse-coorrds, user32-rawinput-mouse, user32-rawinput-nolegacy
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/hidclass.sys/device.c, dlls/hidclass.sys/hid.h, dlls/hidclass.sys/pnp.c, dlls/user32/message.c,
|
||||
# | dlls/user32/rawinput.c, dlls/user32/user_private.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-server-Add-process-argument-to-find_rawinput_device.patch
|
||||
patch_apply user32-rawinput-hid/0002-server-Allow-extra-data-for-hardware_msg_data-messag.patch
|
||||
patch_apply user32-rawinput-hid/0003-server-Add-HID-input-message-type-to-send_hardware_m.patch
|
||||
patch_apply user32-rawinput-hid/0004-user32-Implement-WM_INPUT-RIM_TYPEHID-message-handli.patch
|
||||
patch_apply user32-rawinput-hid/0005-hidclass.sys-Send-input-message-to-server-when-HID-r.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Rémi Bernon", "server: Add process argument to find_rawinput_device.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "server: Allow extra data for hardware_msg_data message.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "server: Add HID input message type to send_hardware_message request.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "user32: Implement WM_INPUT/RIM_TYPEHID message handling.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "hidclass.sys: Send input message to server when HID report is received.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset user32-rawinput-keyboard
|
||||
# |
|
||||
# | This patchset has the following (direct or indirect) dependencies:
|
||||
# | * winex11.drv-mouse-coorrds, user32-rawinput-mouse, user32-rawinput-nolegacy, user32-rawinput-hid
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/dinput/device.c, dlls/dinput/device_private.h, dlls/dinput/keyboard.c, dlls/dinput/mouse.c,
|
||||
# | dlls/dinput8/tests/device.c, dlls/user32/rawinput.c, dlls/user32/tests/input.c, dlls/winex11.drv/keyboard.c,
|
||||
# | dlls/winex11.drv/mouse.c, dlls/winex11.drv/x11drv.h, server/queue.c
|
||||
# |
|
||||
if test "$enable_user32_rawinput_keyboard" -eq 1; then
|
||||
patch_apply user32-rawinput-keyboard/0001-dinput-Add-DIERR_INPUTLOST-error-code-support-for-DI.patch
|
||||
patch_apply user32-rawinput-keyboard/0002-dinput8-Use-raw-input-interface-for-dinput8-keyboard.patch
|
||||
patch_apply user32-rawinput-keyboard/0003-user32-Add-support-for-RIDEV_INPUTSINK-flag-in-Regis.patch
|
||||
patch_apply user32-rawinput-keyboard/0004-winex11.drv-Listen-to-RawKey-events-in-the-desktop-t.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Rémi Bernon", "dinput: Add DIERR_INPUTLOST error code support for DISCL_FOREGROUND cooperative level.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "dinput8: Use raw input interface for dinput8 keyboard device.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "user32: Add support for RIDEV_INPUTSINK flag in RegisterRawInputDevices.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "winex11.drv: Listen to RawKey* events in the desktop thread.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset user32-rawinput-mouse-experimental
|
||||
# |
|
||||
# | This patchset has the following (direct or indirect) dependencies:
|
||||
# | * winex11.drv-mouse-coorrds, user32-rawinput-mouse, user32-rawinput-nolegacy
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#45882] - Raw Input should use untransformed mouse values (affects Overwatch, several Source games).
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/user32/message.c, dlls/winex11.drv/mouse.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-Implement-relative-wheel-input-from-RawM.patch
|
||||
patch_apply user32-rawinput-mouse-experimental/0004-winex11.drv-Accumulate-mouse-movement-to-avoid-round.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Derek Lesho", "winex11.drv: Add support for absolute RawMotion events.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "winex11.drv: Send relative RawMotion events unprocessed.", 1 },';
|
||||
printf '%s\n' '+ { "Derek Lesho", "winex11.drv: Implement relative wheel input from RawMotion events.", 1 },';
|
||||
printf '%s\n' '+ { "Jordan Galby", "winex11.drv: Accumulate mouse movement to avoid rounding losses.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset user32-recursive-activation
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
@ -7304,21 +7511,6 @@ if test "$enable_winex11_drv_Query_server_position" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset winex11.drv-mouse-coorrds
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#46309] winex11.drv: Use root-relative coordinates for events, if possible.
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/winex11.drv/mouse.c
|
||||
# |
|
||||
if test "$enable_winex11_drv_mouse_coorrds" -eq 1; then
|
||||
patch_apply winex11.drv-mouse-coorrds/0001-winex11.drv-mouse-Use-root-relative-coordinates-for-ev.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Gabriel Ivăncescu", "winex11.drv/mouse: Use root-relative coordinates for events, if possible.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset wininet-Cleanup
|
||||
# |
|
||||
# | Modified files:
|
||||
|
@ -0,0 +1,53 @@
|
||||
From 694ff514bfce59c2590668e3e812d501b713acdb 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
|
||||
Subject: [PATCH 1/5] 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.
|
||||
---
|
||||
server/queue.c | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index f5dc06100d1..3ed7e82a906 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -1576,11 +1576,11 @@ static user_handle_t find_hardware_message_window( struct desktop *desktop, stru
|
||||
return win;
|
||||
}
|
||||
|
||||
-static struct rawinput_device_entry *find_rawinput_device( unsigned short usage_page, unsigned short usage )
|
||||
+static struct rawinput_device_entry *find_rawinput_device( struct process *process, unsigned short usage_page, unsigned short usage )
|
||||
{
|
||||
struct rawinput_device_entry *e;
|
||||
|
||||
- LIST_FOR_EACH_ENTRY( e, ¤t->process->rawinput_devices, struct rawinput_device_entry, entry )
|
||||
+ LIST_FOR_EACH_ENTRY( e, &process->rawinput_devices, struct rawinput_device_entry, entry )
|
||||
{
|
||||
if (e->device.usage_page != usage_page || e->device.usage != usage) continue;
|
||||
return e;
|
||||
@@ -1593,7 +1593,7 @@ static void update_rawinput_device(const struct rawinput_device *device)
|
||||
{
|
||||
struct rawinput_device_entry *e;
|
||||
|
||||
- if (!(e = find_rawinput_device( device->usage_page, device->usage )))
|
||||
+ if (!(e = find_rawinput_device( current->process, device->usage_page, device->usage )))
|
||||
{
|
||||
if (!(e = mem_alloc( sizeof(*e) ))) return;
|
||||
list_add_tail( ¤t->process->rawinput_devices, &e->entry );
|
||||
@@ -3375,9 +3375,9 @@ DECL_HANDLER(update_rawinput_devices)
|
||||
update_rawinput_device(&devices[i]);
|
||||
}
|
||||
|
||||
- e = find_rawinput_device( 1, 2 );
|
||||
+ e = find_rawinput_device( current->process, 1, 2 );
|
||||
current->process->rawinput_mouse = e ? &e->device : NULL;
|
||||
- e = find_rawinput_device( 1, 6 );
|
||||
+ e = find_rawinput_device( current->process, 1, 6 );
|
||||
current->process->rawinput_kbd = e ? &e->device : NULL;
|
||||
}
|
||||
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,150 @@
|
||||
From 56609fdaab139ec8718cf0c4963e6990c9b88003 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 2/5] server: Allow extra data for hardware_msg_data message.
|
||||
|
||||
The RIM_TYPEHID messages will have to carry the variable length HID
|
||||
report.
|
||||
---
|
||||
server/queue.c | 43 +++++++++++++++++++++++++++----------------
|
||||
1 file changed, 27 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index 3ed7e82a906..feff00e2b9f 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -398,13 +398,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,
|
||||
- unsigned int time )
|
||||
+ unsigned int time, data_size_t extra_len )
|
||||
{
|
||||
struct hardware_msg_data *msg_data;
|
||||
struct message *msg;
|
||||
|
||||
if (!(msg = mem_alloc( sizeof(*msg) ))) return NULL;
|
||||
- if (!(msg_data = mem_alloc( sizeof(*msg_data) )))
|
||||
+ if (!(msg_data = mem_alloc( sizeof(*msg_data) + extra_len )))
|
||||
{
|
||||
free( msg );
|
||||
return NULL;
|
||||
@@ -413,9 +413,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;
|
||||
- msg->data_size = sizeof(*msg_data);
|
||||
+ msg->data_size = sizeof(*msg_data) + extra_len;
|
||||
|
||||
- memset( msg_data, 0, sizeof(*msg_data) );
|
||||
+ memset( msg_data, 0, sizeof(*msg_data) + extra_len );
|
||||
msg_data->info = info;
|
||||
msg_data->source = source;
|
||||
return msg;
|
||||
@@ -430,7 +430,7 @@ static void set_cursor_pos( struct desktop *desktop, int x, int y )
|
||||
if (current->process->rawinput_mouse &&
|
||||
current->process->rawinput_mouse->flags & RIDEV_NOLEGACY) 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->msg = WM_MOUSEMOVE;
|
||||
msg->x = x;
|
||||
@@ -1743,6 +1743,8 @@ struct rawinput_message
|
||||
struct hw_msg_source source;
|
||||
unsigned int time;
|
||||
struct hardware_msg_data data;
|
||||
+ const void *extra;
|
||||
+ data_size_t extra_len;
|
||||
};
|
||||
|
||||
static int queue_rawinput_message( struct process* process, void* user )
|
||||
@@ -1752,6 +1754,7 @@ static int queue_rawinput_message( struct process* process, void* user )
|
||||
struct desktop *desktop = NULL;
|
||||
struct thread *thread = NULL, *foreground = NULL;
|
||||
struct message *msg;
|
||||
+ struct hardware_msg_data *msg_data;
|
||||
|
||||
if (raw_msg->data.rawinput.type == RIM_TYPEMOUSE)
|
||||
device = process->rawinput_mouse;
|
||||
@@ -1774,14 +1777,18 @@ static int queue_rawinput_message( struct process* process, void* user )
|
||||
thread->process != foreground->process)
|
||||
goto done;
|
||||
|
||||
- if (!(msg = alloc_hardware_message( raw_msg->data.info, raw_msg->source, raw_msg->time )))
|
||||
+ if (!(msg = alloc_hardware_message( raw_msg->data.info, raw_msg->source, raw_msg->time, raw_msg->extra_len )))
|
||||
goto done;
|
||||
+ msg_data = msg->data;
|
||||
|
||||
msg->win = device->target;
|
||||
msg->msg = WM_INPUT;
|
||||
msg->wparam = RIM_INPUT;
|
||||
msg->lparam = 0;
|
||||
- memcpy( msg->data, &raw_msg->data, sizeof(raw_msg->data) );
|
||||
+
|
||||
+ memcpy( msg_data, &raw_msg->data, sizeof(*msg_data) );
|
||||
+ if (raw_msg->extra_len && raw_msg->extra)
|
||||
+ memcpy( msg_data + 1, raw_msg->extra, raw_msg->extra_len );
|
||||
|
||||
queue_hardware_message( desktop, msg, 0 );
|
||||
|
||||
@@ -1850,9 +1857,11 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
|
||||
if (req_flags & SEND_HWMSG_RAWINPUT)
|
||||
{
|
||||
- raw_msg.desktop = desktop;
|
||||
- raw_msg.source = source;
|
||||
- raw_msg.time = time;
|
||||
+ raw_msg.desktop = desktop;
|
||||
+ raw_msg.source = source;
|
||||
+ raw_msg.time = time;
|
||||
+ raw_msg.extra = NULL;
|
||||
+ raw_msg.extra_len = 0;
|
||||
|
||||
msg_data = &raw_msg.data;
|
||||
msg_data->info = input->mouse.info;
|
||||
@@ -1879,7 +1888,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
if (!(flags & (1 << i))) continue;
|
||||
flags &= ~(1 << i);
|
||||
|
||||
- if (!(msg = alloc_hardware_message( input->mouse.info, source, time ))) return 0;
|
||||
+ if (!(msg = alloc_hardware_message( input->mouse.info, source, time, 0 ))) return 0;
|
||||
msg_data = msg->data;
|
||||
|
||||
msg->win = get_user_full_handle( win );
|
||||
@@ -1983,9 +1992,11 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
|
||||
if (req_flags & SEND_HWMSG_RAWINPUT)
|
||||
{
|
||||
- raw_msg.desktop = desktop;
|
||||
- raw_msg.source = source;
|
||||
- raw_msg.time = time;
|
||||
+ raw_msg.desktop = desktop;
|
||||
+ raw_msg.source = source;
|
||||
+ raw_msg.time = time;
|
||||
+ raw_msg.extra = NULL;
|
||||
+ raw_msg.extra_len = 0;
|
||||
|
||||
msg_data = &raw_msg.data;
|
||||
msg_data->info = input->kbd.info;
|
||||
@@ -2006,7 +2017,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
if ((device = current->process->rawinput_kbd) && (device->flags & RIDEV_NOLEGACY))
|
||||
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 );
|
||||
@@ -2044,7 +2055,7 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_
|
||||
struct hw_msg_source source = { IMDT_UNAVAILABLE, origin };
|
||||
struct message *msg;
|
||||
|
||||
- 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.24.1
|
||||
|
@ -0,0 +1,262 @@
|
||||
From d0347613c7149144d4339109b641901537c4c326 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 3/5] server: Add HID input message type to
|
||||
send_hardware_message request.
|
||||
|
||||
---
|
||||
dlls/user32/message.c | 4 +++-
|
||||
server/protocol.def | 26 +++++++++++++++++++---
|
||||
server/queue.c | 50 ++++++++++++++++++++++++++++++++++++++-----
|
||||
server/trace.c | 10 ++++++---
|
||||
4 files changed, 78 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
|
||||
index cc25d2f6c2f..55bbe409c9e 100644
|
||||
--- a/dlls/user32/message.c
|
||||
+++ b/dlls/user32/message.c
|
||||
@@ -3354,10 +3354,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;
|
||||
@@ -3366,6 +3366,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;
|
||||
@@ -3373,6 +3374,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/server/protocol.def b/server/protocol.def
|
||||
index d37dceba40c..85cc2ac6937 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -321,6 +321,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;
|
||||
};
|
||||
|
||||
@@ -344,7 +351,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 */
|
||||
@@ -353,7 +360,7 @@ typedef union
|
||||
} kbd;
|
||||
struct
|
||||
{
|
||||
- int type; /* INPUT_MOUSE */
|
||||
+ int type; /* HW_INPUT_MOUSE */
|
||||
int x; /* coordinates */
|
||||
int y;
|
||||
unsigned int data; /* mouse data */
|
||||
@@ -363,11 +370,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
|
||||
{
|
||||
@@ -2361,6 +2380,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 feff00e2b9f..85aa896c7bd 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -1698,7 +1698,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;
|
||||
@@ -1716,7 +1716,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;
|
||||
@@ -1742,6 +1742,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;
|
||||
@@ -1750,6 +1752,7 @@ struct rawinput_message
|
||||
static int queue_rawinput_message( struct process* process, void* user )
|
||||
{
|
||||
const struct rawinput_message* raw_msg = user;
|
||||
+ const struct rawinput_device_entry *entry;
|
||||
const struct rawinput_device *device = NULL;
|
||||
struct desktop *desktop = NULL;
|
||||
struct thread *thread = NULL, *foreground = NULL;
|
||||
@@ -1760,6 +1763,8 @@ static int queue_rawinput_message( struct process* process, void* user )
|
||||
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)
|
||||
goto done;
|
||||
@@ -2067,6 +2072,38 @@ 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;
|
||||
+
|
||||
+ raw_msg.desktop = NULL; /* send to all desktops */
|
||||
+ 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;
|
||||
+
|
||||
+ if (req_flags == SEND_HWMSG_RAWINPUT)
|
||||
+ enum_processes( queue_rawinput_message, &raw_msg );
|
||||
+ else
|
||||
+ queue_rawinput_message( current->process, &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 )
|
||||
@@ -2577,15 +2614,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 );
|
||||
}
|
||||
diff --git a/server/trace.c b/server/trace.c
|
||||
index 18b56c729e4..c39c56087c1 100644
|
||||
--- a/server/trace.c
|
||||
+++ b/server/trace.c
|
||||
@@ -381,24 +381,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.24.1
|
||||
|
@ -0,0 +1,138 @@
|
||||
From bbb38b3c009d47aced1ba746549fdc51e34cbaf4 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 12 Sep 2019 14:48:23 +0200
|
||||
Subject: [PATCH 4/5] user32: Implement WM_INPUT/RIM_TYPEHID message handling.
|
||||
|
||||
---
|
||||
dlls/user32/message.c | 19 ++++++++++++++++++-
|
||||
dlls/user32/rawinput.c | 37 +++++++++++++++++++++++++++++++++++++
|
||||
dlls/user32/user_private.h | 2 ++
|
||||
3 files changed, 57 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
|
||||
index 55bbe409c9e..ae081cd6eb1 100644
|
||||
--- a/dlls/user32/message.c
|
||||
+++ b/dlls/user32/message.c
|
||||
@@ -2285,10 +2285,17 @@ static BOOL process_rawinput_message( MSG *msg, const struct hardware_msg_data *
|
||||
{
|
||||
struct user_thread_info *thread_info = get_user_thread_info();
|
||||
RAWINPUT *rawinput = thread_info->rawinput;
|
||||
+ SIZE_T data_len = 0;
|
||||
+
|
||||
+ if (msg_data->rawinput.type == RIM_TYPEHID)
|
||||
+ {
|
||||
+ data_len = msg_data->rawinput.hid.length;
|
||||
+ rawinput = thread_info->rawinput = HeapReAlloc( GetProcessHeap(), 0, rawinput, sizeof(*rawinput) + data_len );
|
||||
+ }
|
||||
|
||||
if (!rawinput)
|
||||
{
|
||||
- thread_info->rawinput = HeapAlloc( GetProcessHeap(), 0, sizeof(*rawinput) );
|
||||
+ thread_info->rawinput = HeapAlloc( GetProcessHeap(), 0, sizeof(*rawinput) + data_len );
|
||||
if (!(rawinput = thread_info->rawinput)) return FALSE;
|
||||
}
|
||||
|
||||
@@ -2383,6 +2390,16 @@ static BOOL process_rawinput_message( MSG *msg, const struct hardware_msg_data *
|
||||
rawinput->data.keyboard.Message = msg_data->rawinput.kbd.message;
|
||||
rawinput->data.keyboard.ExtraInformation = msg_data->info;
|
||||
}
|
||||
+ else if (msg_data->rawinput.type == RIM_TYPEHID)
|
||||
+ {
|
||||
+ rawinput->header.dwSize = FIELD_OFFSET(RAWINPUT, data.hid.bRawData) + data_len;
|
||||
+ 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 = data_len;
|
||||
+ rawinput->data.hid.dwCount = 1;
|
||||
+ memcpy(rawinput->data.hid.bRawData, msg_data + 1, data_len);
|
||||
+ }
|
||||
else
|
||||
{
|
||||
FIXME("Unhandled rawinput type %#x.\n", msg_data->rawinput.type);
|
||||
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
|
||||
index 8cf9f8ebf62..72ae91cfcb5 100644
|
||||
--- a/dlls/user32/rawinput.c
|
||||
+++ b/dlls/user32/rawinput.c
|
||||
@@ -43,6 +43,7 @@ struct hid_device
|
||||
{
|
||||
WCHAR *path;
|
||||
HANDLE file;
|
||||
+ HANDLE handle;
|
||||
RID_DEVICE_INFO_HID info;
|
||||
PHIDP_PREPARSED_DATA data;
|
||||
};
|
||||
@@ -59,6 +60,8 @@ static CRITICAL_SECTION_DEBUG hid_devices_cs_debug =
|
||||
};
|
||||
static CRITICAL_SECTION hid_devices_cs = { &hid_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;
|
||||
@@ -138,10 +141,43 @@ static struct hid_device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *ifa
|
||||
device = &hid_devices[hid_devices_count++];
|
||||
device->path = path;
|
||||
device->file = file;
|
||||
+ 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 < hid_devices_count; ++i)
|
||||
+ {
|
||||
+ if (hid_devices[i].handle == device)
|
||||
+ return &hid_devices[i];
|
||||
+ }
|
||||
+
|
||||
+ if (NtQueryObject( device, ObjectNameInformation, &buffer, sizeof(buffer) - sizeof(WCHAR), &dummy ) || !info->Name.Buffer)
|
||||
+ return NULL;
|
||||
+
|
||||
+ /* replace \??\ with \\?\ to match hid_devices paths */
|
||||
+ if (info->Name.Length > 1 && info->Name.Buffer[0] == '\\' && info->Name.Buffer[1] == '?')
|
||||
+ info->Name.Buffer[1] = '\\';
|
||||
+
|
||||
+ for (i = 0; i < hid_devices_count; ++i)
|
||||
+ {
|
||||
+ if (strcmpW(hid_devices[i].path, info->Name.Buffer) == 0)
|
||||
+ {
|
||||
+ hid_devices[i].handle = device;
|
||||
+ return &hid_devices[i];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static void find_hid_devices(void)
|
||||
{
|
||||
static ULONGLONG last_check;
|
||||
@@ -415,6 +451,7 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT
|
||||
device, 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 e8f6abb6813..0c3d52fca5b 100644
|
||||
--- a/dlls/user32/user_private.h
|
||||
+++ b/dlls/user32/user_private.h
|
||||
@@ -378,4 +378,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 */
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,139 @@
|
||||
From 249548cff4ae17da6731e28a5fafe277a7b3d6ea 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 5/5] 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.24.1
|
||||
|
1
patches/user32-rawinput-hid/definition
Normal file
1
patches/user32-rawinput-hid/definition
Normal file
@ -0,0 +1 @@
|
||||
Depends: user32-rawinput-nolegacy
|
@ -0,0 +1,82 @@
|
||||
From 3f8031f89ca79ef5c4dd46666cda2304aa647083 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Mon, 4 Nov 2019 23:33:09 +0100
|
||||
Subject: [PATCH 1/4] dinput: Add DIERR_INPUTLOST error code support for
|
||||
DISCL_FOREGROUND cooperative level.
|
||||
|
||||
---
|
||||
dlls/dinput/device.c | 2 ++
|
||||
dlls/dinput/device_private.h | 1 +
|
||||
dlls/dinput/keyboard.c | 6 ++++++
|
||||
dlls/dinput/mouse.c | 6 ++++++
|
||||
4 files changed, 15 insertions(+)
|
||||
|
||||
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
|
||||
index df7a22a303b..51a536f0892 100644
|
||||
--- a/dlls/dinput/device.c
|
||||
+++ b/dlls/dinput/device.c
|
||||
@@ -1087,6 +1087,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_Acquire(LPDIRECTINPUTDEVICE8W iface)
|
||||
EnterCriticalSection(&This->crit);
|
||||
res = This->acquired ? S_FALSE : DI_OK;
|
||||
This->acquired = 1;
|
||||
+ This->inputlost = 0;
|
||||
LeaveCriticalSection(&This->crit);
|
||||
if (res == DI_OK)
|
||||
check_dinput_hooks(iface, TRUE);
|
||||
@@ -1115,6 +1116,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_Unacquire(LPDIRECTINPUTDEVICE8W iface)
|
||||
EnterCriticalSection(&This->crit);
|
||||
res = !This->acquired ? DI_NOEFFECT : DI_OK;
|
||||
This->acquired = 0;
|
||||
+ This->inputlost = 0;
|
||||
LeaveCriticalSection(&This->crit);
|
||||
if (res == DI_OK)
|
||||
check_dinput_hooks(iface, FALSE);
|
||||
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
|
||||
index 9116aaeab66..70b4ae1ef69 100644
|
||||
--- a/dlls/dinput/device_private.h
|
||||
+++ b/dlls/dinput/device_private.h
|
||||
@@ -68,6 +68,7 @@ struct IDirectInputDeviceImpl
|
||||
DWORD dwCoopLevel;
|
||||
HWND win;
|
||||
int acquired;
|
||||
+ int inputlost;
|
||||
DI_EVENT_PROC event_proc; /* function to receive mouse & keyboard events */
|
||||
|
||||
BOOL use_raw_input; /* use raw input instead of low-level messages */
|
||||
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
|
||||
index 1ec8003897a..2c62d3eab09 100644
|
||||
--- a/dlls/dinput/keyboard.c
|
||||
+++ b/dlls/dinput/keyboard.c
|
||||
@@ -371,6 +371,12 @@ static HRESULT WINAPI SysKeyboardWImpl_GetDeviceState(LPDIRECTINPUTDEVICE8W ifac
|
||||
|
||||
check_dinput_events();
|
||||
|
||||
+ if ((This->base.dwCoopLevel & DISCL_FOREGROUND) && This->base.win != GetForegroundWindow())
|
||||
+ {
|
||||
+ This->base.acquired = 0;
|
||||
+ return DIERR_INPUTLOST;
|
||||
+ }
|
||||
+
|
||||
EnterCriticalSection(&This->base.crit);
|
||||
|
||||
if (TRACE_ON(dinput)) {
|
||||
diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c
|
||||
index b8b88f38c15..06cf78de13a 100644
|
||||
--- a/dlls/dinput/mouse.c
|
||||
+++ b/dlls/dinput/mouse.c
|
||||
@@ -672,6 +672,12 @@ static HRESULT WINAPI SysMouseWImpl_GetDeviceState(LPDIRECTINPUTDEVICE8W iface,
|
||||
|
||||
check_dinput_events();
|
||||
|
||||
+ if ((This->base.dwCoopLevel & DISCL_FOREGROUND) && This->base.win != GetForegroundWindow())
|
||||
+ {
|
||||
+ This->base.acquired = 0;
|
||||
+ return DIERR_INPUTLOST;
|
||||
+ }
|
||||
+
|
||||
EnterCriticalSection(&This->base.crit);
|
||||
_dump_mouse_state(&This->m_state);
|
||||
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,146 @@
|
||||
From 87087e7d92d5cbbaf8e63cdfadead60701d0b360 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Mon, 26 Aug 2019 15:32:07 +0200
|
||||
Subject: [PATCH 2/4] dinput8: Use raw input interface for dinput8 keyboard
|
||||
device.
|
||||
|
||||
---
|
||||
dlls/dinput/keyboard.c | 69 +++++++++++++++++++++++++++++++++----
|
||||
dlls/dinput8/tests/device.c | 7 ----
|
||||
2 files changed, 62 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
|
||||
index 2c62d3eab09..fb0f273bdbe 100644
|
||||
--- a/dlls/dinput/keyboard.c
|
||||
+++ b/dlls/dinput/keyboard.c
|
||||
@@ -107,17 +107,65 @@ static int KeyboardCallback( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM
|
||||
{
|
||||
SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface);
|
||||
int dik_code, ret = This->base.dwCoopLevel & DISCL_EXCLUSIVE;
|
||||
- KBDLLHOOKSTRUCT *hook = (KBDLLHOOKSTRUCT *)lparam;
|
||||
BYTE new_diks;
|
||||
+ DWORD vkey_code, scan_code;
|
||||
+ BOOL is_key_ext, is_key_up;
|
||||
|
||||
if (wparam != WM_KEYDOWN && wparam != WM_KEYUP &&
|
||||
- wparam != WM_SYSKEYDOWN && wparam != WM_SYSKEYUP)
|
||||
+ wparam != WM_SYSKEYDOWN && wparam != WM_SYSKEYUP &&
|
||||
+ wparam != RIM_INPUT && wparam != RIM_INPUTSINK)
|
||||
return 0;
|
||||
|
||||
+ if (wparam == RIM_INPUT || wparam == RIM_INPUTSINK)
|
||||
+ {
|
||||
+ RAWINPUTHEADER raw_header;
|
||||
+ RAWINPUT raw_input;
|
||||
+ UINT size;
|
||||
+
|
||||
+ TRACE("(%p) wp %08lx, lp %08lx\n", iface, wparam, lparam);
|
||||
+
|
||||
+ size = sizeof(raw_header);
|
||||
+ if (GetRawInputData( (HRAWINPUT)lparam, RID_HEADER, &raw_header, &size, sizeof(RAWINPUTHEADER) ) != sizeof(raw_header))
|
||||
+ {
|
||||
+ WARN( "Unable to read raw input data header\n" );
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (raw_header.dwType != RIM_TYPEKEYBOARD)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (raw_header.dwSize > sizeof(raw_input))
|
||||
+ {
|
||||
+ WARN( "Unexpected size for keyboard raw input data\n" );
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ size = raw_header.dwSize;
|
||||
+ if (GetRawInputData( (HRAWINPUT)lparam, RID_INPUT, &raw_input, &size, sizeof(RAWINPUTHEADER) ) != raw_header.dwSize )
|
||||
+ {
|
||||
+ WARN( "Unable to read raw input data\n" );
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ vkey_code = raw_input.data.keyboard.VKey;
|
||||
+ scan_code = raw_input.data.keyboard.MakeCode;
|
||||
+ is_key_ext = (raw_input.data.keyboard.Flags & RI_KEY_E0);
|
||||
+ is_key_up = (raw_input.data.keyboard.Flags & RI_KEY_BREAK);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ KBDLLHOOKSTRUCT *hook = (KBDLLHOOKSTRUCT *)lparam;
|
||||
+
|
||||
+ vkey_code = hook->vkCode;
|
||||
+ scan_code = hook->scanCode;
|
||||
+ is_key_ext = (hook->flags & LLKHF_EXTENDED);
|
||||
+ is_key_up = (hook->flags & LLKHF_UP);
|
||||
+ }
|
||||
+
|
||||
TRACE("(%p) wp %08lx, lp %08lx, vk %02x, scan %02x\n",
|
||||
- iface, wparam, lparam, hook->vkCode, hook->scanCode);
|
||||
+ iface, wparam, lparam, vkey_code, scan_code);
|
||||
|
||||
- switch (hook->vkCode)
|
||||
+ switch (vkey_code)
|
||||
{
|
||||
/* R-Shift is special - it is an extended key with separate scan code */
|
||||
case VK_RSHIFT : dik_code = DIK_RSHIFT; break;
|
||||
@@ -125,10 +173,10 @@ static int KeyboardCallback( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM
|
||||
case VK_NUMLOCK : dik_code = DIK_NUMLOCK; break;
|
||||
case VK_SUBTRACT: dik_code = DIK_SUBTRACT; break;
|
||||
default:
|
||||
- dik_code = map_dik_code(hook->scanCode & 0xff, hook->vkCode, This->subtype);
|
||||
- if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80;
|
||||
+ dik_code = map_dik_code(scan_code & 0xff, vkey_code, This->subtype);
|
||||
+ if (is_key_ext) dik_code |= 0x80;
|
||||
}
|
||||
- new_diks = hook->flags & LLKHF_UP ? 0 : 0x80;
|
||||
+ new_diks = is_key_up ? 0 : 0x80;
|
||||
|
||||
/* returns now if key event already known */
|
||||
if (new_diks == This->DInputKeyState[dik_code])
|
||||
@@ -295,6 +343,13 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
|
||||
list_add_tail(&dinput->devices_list, &newDevice->base.entry);
|
||||
LeaveCriticalSection(&dinput->crit);
|
||||
|
||||
+ if (dinput->dwVersion >= 0x800)
|
||||
+ {
|
||||
+ newDevice->base.use_raw_input = TRUE;
|
||||
+ newDevice->base.raw_device.usUsagePage = 1; /* HID generic device page */
|
||||
+ newDevice->base.raw_device.usUsage = 6; /* HID generic keyboard */
|
||||
+ }
|
||||
+
|
||||
return newDevice;
|
||||
|
||||
failed:
|
||||
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c
|
||||
index 31220db220a..8a6d1997b67 100644
|
||||
--- a/dlls/dinput8/tests/device.c
|
||||
+++ b/dlls/dinput8/tests/device.c
|
||||
@@ -659,15 +659,10 @@ static void test_mouse_keyboard(void)
|
||||
raw_devices_count = ARRAY_SIZE(raw_devices);
|
||||
memset(raw_devices, 0, sizeof(raw_devices));
|
||||
hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
|
||||
- todo_wine
|
||||
ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].usUsage == 6, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].hwndTarget != NULL, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
|
||||
hr = IDirectInputDevice8_Unacquire(di_keyboard);
|
||||
ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
|
||||
@@ -746,9 +741,7 @@ static void test_mouse_keyboard(void)
|
||||
ok(raw_devices[1].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[1].hwndTarget);
|
||||
ok(raw_devices[2].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage);
|
||||
ok(raw_devices[2].usUsage == 6, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage);
|
||||
- todo_wine
|
||||
ok(raw_devices[2].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags);
|
||||
- todo_wine
|
||||
ok(raw_devices[2].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[1].hwndTarget);
|
||||
hr = IDirectInputDevice8_Unacquire(di_keyboard);
|
||||
ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,95 @@
|
||||
From 31d4d9619c14a37522b99917deae40273f6e3654 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Sat, 7 Sep 2019 09:41:59 +0200
|
||||
Subject: [PATCH 3/4] user32: Add support for RIDEV_INPUTSINK flag in
|
||||
RegisterRawInputDevices.
|
||||
|
||||
This flag allows applications to receive rawinput messages while in
|
||||
background. They have to specify a target hwnd in which queue to receive
|
||||
them and the messages will carry a RIM_INPUTSINK wparam in this case.
|
||||
---
|
||||
dlls/user32/rawinput.c | 9 ++++++++-
|
||||
dlls/user32/tests/input.c | 2 --
|
||||
server/queue.c | 9 ++++++---
|
||||
3 files changed, 14 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
|
||||
index 72ae91cfcb5..5a238928b24 100644
|
||||
--- a/dlls/user32/rawinput.c
|
||||
+++ b/dlls/user32/rawinput.c
|
||||
@@ -304,6 +304,13 @@ BOOL WINAPI DECLSPEC_HOTPATCH RegisterRawInputDevices(RAWINPUTDEVICE *devices, U
|
||||
|
||||
for (i = 0; i < device_count; ++i)
|
||||
{
|
||||
+ if ((devices[i].dwFlags & RIDEV_INPUTSINK) &&
|
||||
+ (devices[i].hwndTarget == NULL))
|
||||
+ {
|
||||
+ SetLastError(ERROR_INVALID_PARAMETER);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
if ((devices[i].dwFlags & RIDEV_REMOVE) &&
|
||||
(devices[i].hwndTarget != NULL))
|
||||
{
|
||||
@@ -319,7 +326,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))
|
||||
+ if (devices[i].dwFlags & ~(RIDEV_REMOVE|RIDEV_NOLEGACY|RIDEV_INPUTSINK))
|
||||
FIXME("Unhandled flags %#x for device %u.\n", devices[i].dwFlags, i);
|
||||
|
||||
d[i].usage_page = devices[i].usUsagePage;
|
||||
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
|
||||
index a1f983f1960..68d6731551a 100644
|
||||
--- a/dlls/user32/tests/input.c
|
||||
+++ b/dlls/user32/tests/input.c
|
||||
@@ -1812,9 +1812,7 @@ static void test_RegisterRawInputDevices(void)
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
res = RegisterRawInputDevices(raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE));
|
||||
- todo_wine
|
||||
ok(res == FALSE, "RegisterRawInputDevices failed\n");
|
||||
- todo_wine
|
||||
ok(GetLastError() == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned %08x\n", GetLastError());
|
||||
|
||||
raw_devices[0].hwndTarget = hwnd;
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index 85aa896c7bd..145b9c110b1 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -1758,6 +1758,7 @@ static int queue_rawinput_message( struct process* process, void* user )
|
||||
struct thread *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)
|
||||
device = process->rawinput_mouse;
|
||||
@@ -1777,10 +1778,12 @@ static int queue_rawinput_message( struct process* process, void* user )
|
||||
process != thread->process)
|
||||
goto done;
|
||||
|
||||
- /* FIXME: Implement RIDEV_INPUTSINK */
|
||||
if (!(foreground = get_window_thread( desktop->foreground_input->active )) ||
|
||||
thread->process != foreground->process)
|
||||
- goto done;
|
||||
+ {
|
||||
+ if (!(device->flags & RIDEV_INPUTSINK)) goto done;
|
||||
+ wparam = RIM_INPUTSINK;
|
||||
+ }
|
||||
|
||||
if (!(msg = alloc_hardware_message( raw_msg->data.info, raw_msg->source, raw_msg->time, raw_msg->extra_len )))
|
||||
goto done;
|
||||
@@ -1788,7 +1791,7 @@ static int queue_rawinput_message( struct process* process, void* user )
|
||||
|
||||
msg->win = device->target;
|
||||
msg->msg = WM_INPUT;
|
||||
- msg->wparam = RIM_INPUT;
|
||||
+ msg->wparam = wparam;
|
||||
msg->lparam = 0;
|
||||
|
||||
memcpy( msg_data, &raw_msg->data, sizeof(*msg_data) );
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,119 @@
|
||||
From 18e2112beb69c8499cdd90b133348ec52502dc6d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Wed, 21 Aug 2019 16:37:57 +0200
|
||||
Subject: [PATCH] winex11.drv: Listen to RawKey* events in the desktop thread.
|
||||
|
||||
This adds keyboard input support while Wine windows are in background,
|
||||
so the events can be translated to raw input messages as on Windows,
|
||||
which are required to keep dinput8 keyboard state up-to-date when
|
||||
Alt+Tab is used to switch to a non-Wine window.
|
||||
---
|
||||
dlls/winex11.drv/keyboard.c | 40 ++++++++++++++++++++++++++++++++++++-
|
||||
dlls/winex11.drv/mouse.c | 6 ++++++
|
||||
dlls/winex11.drv/x11drv.h | 1 +
|
||||
3 files changed, 46 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
|
||||
index 37c96c926f4..4d113d8c184 100644
|
||||
--- a/dlls/winex11.drv/keyboard.c
|
||||
+++ b/dlls/winex11.drv/keyboard.c
|
||||
@@ -33,6 +33,9 @@
|
||||
#ifdef HAVE_X11_XKBLIB_H
|
||||
#include <X11/XKBlib.h>
|
||||
#endif
|
||||
+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
+#include <X11/extensions/XInput2.h>
|
||||
+#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
@@ -1148,7 +1151,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, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
+ __wine_send_input( hwnd, &input, SEND_HWMSG_WINDOW );
|
||||
}
|
||||
|
||||
|
||||
@@ -1417,6 +1420,41 @@ BOOL X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
+/***********************************************************************
|
||||
+ * X11DRV_KeyEvent
|
||||
+ *
|
||||
+ * Handle a raw XInput2 key event for background windows
|
||||
+ */
|
||||
+BOOL X11DRV_RawKeyEvent( XGenericEventCookie *cookie )
|
||||
+{
|
||||
+ XIRawEvent *event = cookie->data;
|
||||
+ DWORD flags;
|
||||
+ WORD vkey, scan;
|
||||
+ INPUT input;
|
||||
+
|
||||
+ vkey = keyc2vkey[event->detail];
|
||||
+ scan = keyc2scan[event->detail];
|
||||
+
|
||||
+ flags = 0;
|
||||
+ if ( event->evtype == XI_RawKeyRelease ) flags |= KEYEVENTF_KEYUP;
|
||||
+ if ( vkey & 0x100 ) flags |= KEYEVENTF_EXTENDEDKEY;
|
||||
+
|
||||
+ TRACE_(key)( "vkey=%04x scan=%04x flags=%04x\n", vkey, scan, flags );
|
||||
+
|
||||
+ input.type = INPUT_KEYBOARD;
|
||||
+ input.u.ki.wVk = vkey & 0xff;
|
||||
+ input.u.ki.wScan = scan & 0xff;
|
||||
+ input.u.ki.dwFlags = flags;
|
||||
+ input.u.ki.time = EVENT_x11_time_to_win32_time(event->time);
|
||||
+ input.u.ki.dwExtraInfo = 0;
|
||||
+
|
||||
+ __wine_send_input( 0, &input, SEND_HWMSG_RAWINPUT );
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
/**********************************************************************
|
||||
* X11DRV_KEYBOARD_DetectLayout
|
||||
*
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index bc23b9cbba1..2e9b39fcff7 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -406,6 +406,8 @@ void X11DRV_XInput2_Enable(void)
|
||||
{
|
||||
XISetMask( mask_bits, XI_RawButtonPress );
|
||||
XISetMask( mask_bits, XI_RawButtonRelease );
|
||||
+ XISetMask( mask_bits, XI_RawKeyPress );
|
||||
+ XISetMask( mask_bits, XI_RawKeyRelease );
|
||||
data->xi2_rawinput_only = TRUE;
|
||||
}
|
||||
else
|
||||
@@ -2038,6 +2040,10 @@ BOOL X11DRV_GenericEvent( HWND hwnd, XEvent *xev )
|
||||
case XI_RawButtonRelease:
|
||||
ret = X11DRV_RawButtonEvent( event );
|
||||
break;
|
||||
+ case XI_RawKeyPress:
|
||||
+ case XI_RawKeyRelease:
|
||||
+ ret = X11DRV_RawKeyEvent( 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 c843cd74ace..f89538a1755 100644
|
||||
--- a/dlls/winex11.drv/x11drv.h
|
||||
+++ b/dlls/winex11.drv/x11drv.h
|
||||
@@ -518,6 +518,7 @@ extern BOOL X11DRV_ButtonRelease( HWND hwnd, XEvent *event ) DECLSPEC_HIDDEN;
|
||||
extern BOOL X11DRV_MotionNotify( HWND hwnd, XEvent *event ) DECLSPEC_HIDDEN;
|
||||
extern BOOL X11DRV_EnterNotify( HWND hwnd, XEvent *event ) DECLSPEC_HIDDEN;
|
||||
extern BOOL X11DRV_KeyEvent( HWND hwnd, XEvent *event ) DECLSPEC_HIDDEN;
|
||||
+extern BOOL X11DRV_RawKeyEvent( XGenericEventCookie *cookie ) DECLSPEC_HIDDEN;
|
||||
extern BOOL X11DRV_KeymapNotify( HWND hwnd, XEvent *event ) DECLSPEC_HIDDEN;
|
||||
extern BOOL X11DRV_DestroyNotify( HWND hwnd, XEvent *event ) DECLSPEC_HIDDEN;
|
||||
extern BOOL X11DRV_SelectionRequest( HWND hWnd, XEvent *event ) DECLSPEC_HIDDEN;
|
||||
--
|
||||
2.24.0
|
||||
|
1
patches/user32-rawinput-keyboard/definition
Normal file
1
patches/user32-rawinput-keyboard/definition
Normal file
@ -0,0 +1 @@
|
||||
Depends: user32-rawinput-hid
|
@ -0,0 +1,277 @@
|
||||
From c227552d313a51f625b741c330ce4509dff99cb5 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dereklesho52@Gmail.com>
|
||||
Date: Tue, 25 Jun 2019 22:37:34 -0400
|
||||
Subject: [PATCH 1/4] winex11.drv: Add support for absolute RawMotion events.
|
||||
|
||||
When running Xwayland, or using pointing devices, the valuators may
|
||||
provide absolute values only. In which case, we should translate the
|
||||
events to the corresponding absolute rawinput messages.
|
||||
|
||||
The server side was trying to convert all rawinput messages to relative
|
||||
positions, but it may not be correct as the desktop cursor position may
|
||||
not be initialized yet. Keeping the values absolute if we received them
|
||||
this way seems more reliable.
|
||||
|
||||
Note that we cannot really trust valuator names, as it is possible to
|
||||
configure a pointing device to work in relative mode - wacom tablets for
|
||||
example - while their axis valuators keep their "Abs X/Y" name. We can
|
||||
however use the valuator mode to distinguish between relative movements
|
||||
and absolute position events.
|
||||
---
|
||||
dlls/user32/message.c | 7 ++-
|
||||
dlls/winex11.drv/mouse.c | 96 +++++++++++++++++++++-------------
|
||||
dlls/winex11.drv/x11drv.h | 18 +++----
|
||||
dlls/winex11.drv/x11drv_main.c | 2 +
|
||||
server/queue.c | 4 +-
|
||||
5 files changed, 79 insertions(+), 48 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
|
||||
index cc25d2f6c2f..26c3aa91421 100644
|
||||
--- a/dlls/user32/message.c
|
||||
+++ b/dlls/user32/message.c
|
||||
@@ -2311,7 +2311,12 @@ static BOOL process_rawinput_message( MSG *msg, const struct hardware_msg_data *
|
||||
rawinput->header.hDevice = WINE_MOUSE_HANDLE;
|
||||
rawinput->header.wParam = 0;
|
||||
|
||||
- rawinput->data.mouse.usFlags = MOUSE_MOVE_RELATIVE;
|
||||
+ if (msg_data->flags & MOUSEEVENTF_ABSOLUTE)
|
||||
+ rawinput->data.mouse.usFlags = MOUSE_MOVE_ABSOLUTE;
|
||||
+ else
|
||||
+ rawinput->data.mouse.usFlags = MOUSE_MOVE_RELATIVE;
|
||||
+ if (msg_data->flags & MOUSEEVENTF_VIRTUALDESK)
|
||||
+ rawinput->data.mouse.usFlags |= MOUSE_VIRTUAL_DESKTOP;
|
||||
rawinput->data.mouse.u.s.usButtonFlags = 0;
|
||||
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 d331ed5aef8..3474a176003 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -333,32 +333,40 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
|
||||
struct x11drv_thread_data *thread_data = x11drv_thread_data();
|
||||
int i;
|
||||
|
||||
- thread_data->x_rel_valuator.number = -1;
|
||||
- thread_data->y_rel_valuator.number = -1;
|
||||
+ thread_data->x_pos_valuator.number = -1;
|
||||
+ thread_data->y_pos_valuator.number = -1;
|
||||
|
||||
for (i = 0; i < n_valuators; i++)
|
||||
{
|
||||
XIValuatorClassInfo *class = (XIValuatorClassInfo *)valuators[i];
|
||||
- struct x11drv_valuator_data *valuator_data = NULL;
|
||||
|
||||
- if (valuators[i]->type != XIValuatorClass) continue;
|
||||
- if (class->label == x11drv_atom( Rel_X ) ||
|
||||
- (!class->label && class->number == 0 && class->mode == XIModeRelative))
|
||||
- {
|
||||
- valuator_data = &thread_data->x_rel_valuator;
|
||||
- }
|
||||
+ if (valuators[i]->type != XIValuatorClass)
|
||||
+ continue;
|
||||
+ else if (class->label == x11drv_atom( Rel_X ) ||
|
||||
+ class->label == x11drv_atom( Abs_X ) ||
|
||||
+ (!class->label && class->number == 0))
|
||||
+ thread_data->x_pos_valuator = *class;
|
||||
else if (class->label == x11drv_atom( Rel_Y ) ||
|
||||
- (!class->label && class->number == 1 && class->mode == XIModeRelative))
|
||||
- {
|
||||
- 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;
|
||||
- }
|
||||
+ 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");
|
||||
+ }
|
||||
+ else if (thread_data->x_pos_valuator.mode != thread_data->y_pos_valuator.mode)
|
||||
+ {
|
||||
+ 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;
|
||||
+ if (thread_data->y_pos_valuator.min >= thread_data->y_pos_valuator.max)
|
||||
+ thread_data->y_pos_valuator.min = thread_data->y_pos_valuator.max = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -443,8 +451,8 @@ void X11DRV_XInput2_Disable(void)
|
||||
mask.deviceid = XIAllMasterDevices;
|
||||
|
||||
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
|
||||
- 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;
|
||||
#endif
|
||||
}
|
||||
@@ -1895,16 +1903,22 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
INPUT input;
|
||||
int i;
|
||||
double dx = 0, dy = 0, val;
|
||||
+ double x_scale = 1, y_scale = 1;
|
||||
struct x11drv_thread_data *thread_data = x11drv_thread_data();
|
||||
- struct x11drv_valuator_data *x_rel, *y_rel;
|
||||
+ XIValuatorClassInfo *x_pos, *y_pos;
|
||||
|
||||
- if (thread_data->x_rel_valuator.number < 0 || thread_data->y_rel_valuator.number < 0) return FALSE;
|
||||
+ if (thread_data->x_pos_valuator.number < 0 || thread_data->y_pos_valuator.number < 0) return FALSE;
|
||||
+ if (thread_data->x_pos_valuator.mode != thread_data->y_pos_valuator.mode)
|
||||
+ {
|
||||
+ FIXME("Unsupported relative/absolute X/Y axis mismatch\n.");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
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;
|
||||
|
||||
- x_rel = &thread_data->x_rel_valuator;
|
||||
- y_rel = &thread_data->y_rel_valuator;
|
||||
+ x_pos = &thread_data->x_pos_valuator;
|
||||
+ y_pos = &thread_data->y_pos_valuator;
|
||||
|
||||
input.type = INPUT_MOUSE;
|
||||
input.u.mi.mouseData = 0;
|
||||
@@ -1915,24 +1929,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_pos->number, y_pos->number ); i++)
|
||||
{
|
||||
if (!XIMaskIsSet( event->valuators.mask, i )) continue;
|
||||
val = *values++;
|
||||
- if (i == x_rel->number)
|
||||
+ if (i == x_pos->number)
|
||||
{
|
||||
- input.u.mi.dx = dx = val;
|
||||
- if (x_rel->min < x_rel->max)
|
||||
- input.u.mi.dx = val * (virtual_rect.right - virtual_rect.left)
|
||||
- / (x_rel->max - x_rel->min);
|
||||
+ dx = val;
|
||||
+ 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;
|
||||
+ else
|
||||
+ input.u.mi.dx = dx * x_scale;
|
||||
}
|
||||
- if (i == y_rel->number)
|
||||
+ if (i == y_pos->number)
|
||||
{
|
||||
- input.u.mi.dy = dy = val;
|
||||
- if (y_rel->min < y_rel->max)
|
||||
- input.u.mi.dy = val * (virtual_rect.bottom - virtual_rect.top)
|
||||
- / (y_rel->max - y_rel->min);
|
||||
+ dy = val;
|
||||
+ 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;
|
||||
+ else
|
||||
+ input.u.mi.dy = dy * y_scale;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
|
||||
index 4a7cab67ada..c4218699034 100644
|
||||
--- a/dlls/winex11.drv/x11drv.h
|
||||
+++ b/dlls/winex11.drv/x11drv.h
|
||||
@@ -32,6 +32,9 @@
|
||||
#include <X11/Xresource.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
+#include <X11/extensions/XInput2.h>
|
||||
+#endif
|
||||
|
||||
#define BOOL X_BOOL
|
||||
#define BYTE X_BYTE
|
||||
@@ -318,13 +321,6 @@ struct x11drv_escape_flush_gl_drawable
|
||||
* X11 USER driver
|
||||
*/
|
||||
|
||||
-struct x11drv_valuator_data
|
||||
-{
|
||||
- double min;
|
||||
- double max;
|
||||
- int number;
|
||||
-};
|
||||
-
|
||||
struct x11drv_thread_data
|
||||
{
|
||||
Display *display;
|
||||
@@ -341,11 +337,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 */
|
||||
- struct x11drv_valuator_data x_rel_valuator;
|
||||
- struct x11drv_valuator_data y_rel_valuator;
|
||||
+ XIValuatorClassInfo x_pos_valuator;
|
||||
+ XIValuatorClassInfo y_pos_valuator;
|
||||
int xi2_core_pointer; /* XInput2 core pointer id */
|
||||
int xi2_rawinput_only;
|
||||
+#endif
|
||||
};
|
||||
|
||||
extern struct x11drv_thread_data *x11drv_init_thread_data(void) DECLSPEC_HIDDEN;
|
||||
@@ -431,6 +429,8 @@ enum x11drv_atoms
|
||||
XATOM_RAW_CAP_HEIGHT,
|
||||
XATOM_Rel_X,
|
||||
XATOM_Rel_Y,
|
||||
+ XATOM_Abs_X,
|
||||
+ XATOM_Abs_Y,
|
||||
XATOM_WM_PROTOCOLS,
|
||||
XATOM_WM_DELETE_WINDOW,
|
||||
XATOM_WM_STATE,
|
||||
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
|
||||
index f33a79d98bf..3e8dd82654a 100644
|
||||
--- a/dlls/winex11.drv/x11drv_main.c
|
||||
+++ b/dlls/winex11.drv/x11drv_main.c
|
||||
@@ -144,6 +144,8 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
|
||||
"RAW_CAP_HEIGHT",
|
||||
"Rel X",
|
||||
"Rel Y",
|
||||
+ "Abs X",
|
||||
+ "Abs Y",
|
||||
"WM_PROTOCOLS",
|
||||
"WM_DELETE_WINDOW",
|
||||
"WM_STATE",
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index f5dc06100d1..b369f0cdb78 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -1858,8 +1858,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;
|
||||
- msg_data->rawinput.mouse.x = x - desktop->cursor.x;
|
||||
- msg_data->rawinput.mouse.y = y - desktop->cursor.y;
|
||||
+ msg_data->rawinput.mouse.x = input->mouse.x;
|
||||
+ msg_data->rawinput.mouse.y = input->mouse.y;
|
||||
msg_data->rawinput.mouse.data = input->mouse.data;
|
||||
|
||||
if (req_flags == SEND_HWMSG_RAWINPUT)
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,86 @@
|
||||
From 108f1467e2d2712b5fb8956e69d481a033cbcbfe 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 2/4] winex11.drv: Send relative RawMotion events unprocessed.
|
||||
|
||||
This makes relative raw input independent from cursor speed, as it is
|
||||
the case on Windows. Absolute raw input is already translated to
|
||||
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(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index 3474a176003..a2310297ff9 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -1899,20 +1899,17 @@ 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;
|
||||
INPUT input;
|
||||
int i;
|
||||
double dx = 0, dy = 0, val;
|
||||
+ double raw_dx = 0, raw_dy = 0, raw_val;
|
||||
double x_scale = 1, y_scale = 1;
|
||||
struct x11drv_thread_data *thread_data = x11drv_thread_data();
|
||||
XIValuatorClassInfo *x_pos, *y_pos;
|
||||
|
||||
if (thread_data->x_pos_valuator.number < 0 || thread_data->y_pos_valuator.number < 0) return FALSE;
|
||||
- if (thread_data->x_pos_valuator.mode != thread_data->y_pos_valuator.mode)
|
||||
- {
|
||||
- FIXME("Unsupported relative/absolute X/Y axis mismatch\n.");
|
||||
- return FALSE;
|
||||
- }
|
||||
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;
|
||||
@@ -1940,9 +1937,11 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
{
|
||||
if (!XIMaskIsSet( event->valuators.mask, i )) continue;
|
||||
val = *values++;
|
||||
+ raw_val = *raw_values++;
|
||||
if (i == x_pos->number)
|
||||
{
|
||||
dx = val;
|
||||
+ raw_dx = raw_val;
|
||||
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;
|
||||
@@ -1952,6 +1951,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
if (i == y_pos->number)
|
||||
{
|
||||
dy = val;
|
||||
+ raw_dy = raw_val;
|
||||
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;
|
||||
@@ -1966,13 +1966,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 );
|
||||
}
|
||||
else
|
||||
{
|
||||
+ 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 );
|
||||
}
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,166 @@
|
||||
From f4b6ceb3c008b73dfdb89acc601da3be83c47f86 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dereklesho52@Gmail.com>
|
||||
Date: Fri, 26 Jul 2019 17:37:19 -0400
|
||||
Subject: [PATCH 3/4] winex11.drv: Implement relative wheel input from
|
||||
RawMotion events.
|
||||
|
||||
---
|
||||
dlls/winex11.drv/mouse.c | 33 +++++++++++++++++++++++++++------
|
||||
dlls/winex11.drv/x11drv.h | 3 +++
|
||||
dlls/winex11.drv/x11drv_main.c | 1 +
|
||||
3 files changed, 31 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index a2310297ff9..49734ba195b 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -335,11 +335,17 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
|
||||
|
||||
thread_data->x_pos_valuator.number = -1;
|
||||
thread_data->y_pos_valuator.number = -1;
|
||||
+ thread_data->wheel_valuator.number = -1;
|
||||
+ thread_data->wheel_scale = 1;
|
||||
|
||||
for (i = 0; i < n_valuators; i++)
|
||||
{
|
||||
XIValuatorClassInfo *class = (XIValuatorClassInfo *)valuators[i];
|
||||
+ XIScrollClassInfo *scroll_class = (XIScrollClassInfo *)valuators[i];
|
||||
|
||||
+ if (valuators[i]->type == XIScrollClass &&
|
||||
+ scroll_class->scroll_type == XIScrollTypeVertical)
|
||||
+ thread_data->wheel_scale = WHEEL_DELTA / scroll_class->increment;
|
||||
if (valuators[i]->type != XIValuatorClass)
|
||||
continue;
|
||||
else if (class->label == x11drv_atom( Rel_X ) ||
|
||||
@@ -350,6 +356,9 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
|
||||
class->label == x11drv_atom( Abs_Y ) ||
|
||||
(!class->label && class->number == 1))
|
||||
thread_data->y_pos_valuator = *class;
|
||||
+ else if (class->label == x11drv_atom( Rel_Vert_Scroll ) ||
|
||||
+ (!class->label && class->number == 3 && class->mode == XIModeRelative))
|
||||
+ thread_data->wheel_valuator = *class;
|
||||
}
|
||||
|
||||
if (thread_data->x_pos_valuator.number < 0 || thread_data->y_pos_valuator.number < 0)
|
||||
@@ -453,6 +462,8 @@ void X11DRV_XInput2_Disable(void)
|
||||
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
|
||||
data->x_pos_valuator.number = -1;
|
||||
data->y_pos_valuator.number = -1;
|
||||
+ data->wheel_valuator.number = -1;
|
||||
+ data->wheel_scale = 1;
|
||||
data->xi2_core_pointer = 0;
|
||||
#endif
|
||||
}
|
||||
@@ -1903,11 +1914,11 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
RECT virtual_rect;
|
||||
INPUT input;
|
||||
int i;
|
||||
- double dx = 0, dy = 0, val;
|
||||
+ double dx = 0, dy = 0, dw = 0, val;
|
||||
double raw_dx = 0, raw_dy = 0, raw_val;
|
||||
double x_scale = 1, y_scale = 1;
|
||||
struct x11drv_thread_data *thread_data = x11drv_thread_data();
|
||||
- XIValuatorClassInfo *x_pos, *y_pos;
|
||||
+ XIValuatorClassInfo *x_pos, *y_pos, *wheel;
|
||||
|
||||
if (thread_data->x_pos_valuator.number < 0 || thread_data->y_pos_valuator.number < 0) return FALSE;
|
||||
if (!event->valuators.mask_len) return FALSE;
|
||||
@@ -1916,6 +1927,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
|
||||
x_pos = &thread_data->x_pos_valuator;
|
||||
y_pos = &thread_data->y_pos_valuator;
|
||||
+ wheel = &thread_data->wheel_valuator;
|
||||
|
||||
input.type = INPUT_MOUSE;
|
||||
input.u.mi.mouseData = 0;
|
||||
@@ -1933,7 +1945,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
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_pos->number, y_pos->number ); i++)
|
||||
+ for (i = 0; i <= max( max( x_pos->number, y_pos->number ), wheel->number ); i++)
|
||||
{
|
||||
if (!XIMaskIsSet( event->valuators.mask, i )) continue;
|
||||
val = *values++;
|
||||
@@ -1958,6 +1970,12 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
else
|
||||
input.u.mi.dy = dy * y_scale;
|
||||
}
|
||||
+ if (i == wheel->number)
|
||||
+ {
|
||||
+ dw = val;
|
||||
+ input.u.mi.dwFlags |= MOUSEEVENTF_WHEEL;
|
||||
+ input.u.mi.mouseData = dw * thread_data->wheel_scale;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (broken_rawevents && is_old_motion_event( xev->serial ))
|
||||
@@ -1968,19 +1986,19 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
|
||||
if (x_pos->mode == XIModeAbsolute)
|
||||
{
|
||||
- TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
|
||||
+ TRACE( "pos %d,%d w:%d (event %f,%f,%f)\n", input.u.mi.dx, input.u.mi.dy, input.u.mi.mouseData, dx, dy, dw );
|
||||
__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 );
|
||||
+ TRACE( "pos %d,%d w:%d (event %f,%f,%f)\n", input.u.mi.dx, input.u.mi.dy, input.u.mi.mouseData, dx, dy, dw );
|
||||
__wine_send_input( 0, &input, SEND_HWMSG_WINDOW );
|
||||
}
|
||||
else
|
||||
{
|
||||
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 );
|
||||
+ TRACE( "raw pos %d,%d w:%d (event %f,%f,%f)\n", input.u.mi.dx, input.u.mi.dy, input.u.mi.mouseData, raw_dx, raw_dy, dw );
|
||||
__wine_send_input( 0, &input, SEND_HWMSG_RAWINPUT );
|
||||
}
|
||||
return TRUE;
|
||||
@@ -2009,6 +2027,9 @@ static BOOL X11DRV_RawButtonEvent( XGenericEventCookie *cookie )
|
||||
if (thread_data->xi2_state != xi_enabled) return FALSE;
|
||||
if (event->deviceid != thread_data->xi2_core_pointer) return FALSE;
|
||||
|
||||
+ /* mouse wheel is already handled by RawMotion events */
|
||||
+ if (button == 3 || button == 4) return TRUE;
|
||||
+
|
||||
TRACE( "raw button %u (raw: %u) %s\n", button, event->detail, event->evtype == XI_RawButtonRelease ? "up" : "down" );
|
||||
|
||||
input.type = INPUT_MOUSE;
|
||||
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
|
||||
index c4218699034..47c19a83175 100644
|
||||
--- a/dlls/winex11.drv/x11drv.h
|
||||
+++ b/dlls/winex11.drv/x11drv.h
|
||||
@@ -341,6 +341,8 @@ struct x11drv_thread_data
|
||||
enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled } xi2_state; /* XInput2 state */
|
||||
XIValuatorClassInfo x_pos_valuator;
|
||||
XIValuatorClassInfo y_pos_valuator;
|
||||
+ XIValuatorClassInfo wheel_valuator;
|
||||
+ double wheel_scale;
|
||||
int xi2_core_pointer; /* XInput2 core pointer id */
|
||||
int xi2_rawinput_only;
|
||||
#endif
|
||||
@@ -429,6 +431,7 @@ enum x11drv_atoms
|
||||
XATOM_RAW_CAP_HEIGHT,
|
||||
XATOM_Rel_X,
|
||||
XATOM_Rel_Y,
|
||||
+ XATOM_Rel_Vert_Scroll,
|
||||
XATOM_Abs_X,
|
||||
XATOM_Abs_Y,
|
||||
XATOM_WM_PROTOCOLS,
|
||||
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
|
||||
index 3e8dd82654a..3ed8058fc50 100644
|
||||
--- a/dlls/winex11.drv/x11drv_main.c
|
||||
+++ b/dlls/winex11.drv/x11drv_main.c
|
||||
@@ -144,6 +144,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
|
||||
"RAW_CAP_HEIGHT",
|
||||
"Rel X",
|
||||
"Rel Y",
|
||||
+ "Rel Vert Scroll",
|
||||
"Abs X",
|
||||
"Abs Y",
|
||||
"WM_PROTOCOLS",
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,121 @@
|
||||
From cf8668ffad406a26dde59993b81619c966446975 Mon Sep 17 00:00:00 2001
|
||||
From: Jordan Galby <gravemind2a+wine@gmail.com>
|
||||
Date: Tue, 16 Jul 2019 00:34:38 -0400
|
||||
Subject: [PATCH 4/4] winex11.drv: Accumulate mouse movement to avoid rounding
|
||||
losses.
|
||||
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=42631
|
||||
From: Jordan Galby <gravemind2a+wine@gmail.com>
|
||||
---
|
||||
dlls/winex11.drv/mouse.c | 44 +++++++++++++++++++++++++++++++++-------
|
||||
1 file changed, 37 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index 49734ba195b..b5cba492d7e 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -376,6 +376,10 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
|
||||
thread_data->x_pos_valuator.min = thread_data->x_pos_valuator.max = 0;
|
||||
if (thread_data->y_pos_valuator.min >= thread_data->y_pos_valuator.max)
|
||||
thread_data->y_pos_valuator.min = thread_data->y_pos_valuator.max = 0;
|
||||
+
|
||||
+ thread_data->x_pos_valuator.value = 0;
|
||||
+ thread_data->y_pos_valuator.value = 0;
|
||||
+ thread_data->wheel_valuator.value = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1917,6 +1921,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
double dx = 0, dy = 0, dw = 0, val;
|
||||
double raw_dx = 0, raw_dy = 0, raw_val;
|
||||
double x_scale = 1, y_scale = 1;
|
||||
+ double x_accum = 0, y_accum = 0, w_accum = 0;
|
||||
struct x11drv_thread_data *thread_data = x11drv_thread_data();
|
||||
XIValuatorClassInfo *x_pos, *y_pos, *wheel;
|
||||
|
||||
@@ -1929,6 +1934,10 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
y_pos = &thread_data->y_pos_valuator;
|
||||
wheel = &thread_data->wheel_valuator;
|
||||
|
||||
+ x_accum = x_pos->value;
|
||||
+ y_accum = y_pos->value;
|
||||
+ w_accum = wheel->value;
|
||||
+
|
||||
input.type = INPUT_MOUSE;
|
||||
input.u.mi.mouseData = 0;
|
||||
input.u.mi.dwFlags = MOUSEEVENTF_MOVE;
|
||||
@@ -1956,9 +1965,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)
|
||||
- input.u.mi.dx = (dx - x_pos->min) * x_scale;
|
||||
+ x_accum = (dx - x_pos->min) * x_scale;
|
||||
else
|
||||
- input.u.mi.dx = dx * x_scale;
|
||||
+ x_accum += dx * x_scale;
|
||||
}
|
||||
if (i == y_pos->number)
|
||||
{
|
||||
@@ -1966,24 +1975,38 @@ 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)
|
||||
- input.u.mi.dy = (dy - y_pos->min) * y_scale;
|
||||
+ y_accum = (dy - y_pos->min) * y_scale;
|
||||
else
|
||||
- input.u.mi.dy = dy * y_scale;
|
||||
+ y_accum += dy * y_scale;
|
||||
}
|
||||
if (i == wheel->number)
|
||||
{
|
||||
dw = val;
|
||||
input.u.mi.dwFlags |= MOUSEEVENTF_WHEEL;
|
||||
- input.u.mi.mouseData = dw * thread_data->wheel_scale;
|
||||
+ w_accum += dw * thread_data->wheel_scale;
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Accumulate the fractional parts so they aren't lost after casting
|
||||
+ * successive motion values to integral fields.
|
||||
+ *
|
||||
+ * Note: It looks like raw_dx, raw_dy and raw_dw are already
|
||||
+ * integral values but that may be wrong.
|
||||
+ */
|
||||
+ input.u.mi.dx = (LONG)x_accum;
|
||||
+ input.u.mi.dy = (LONG)y_accum;
|
||||
+ input.u.mi.mouseData = (DWORD)w_accum;
|
||||
+
|
||||
if (broken_rawevents && is_old_motion_event( xev->serial ))
|
||||
{
|
||||
TRACE( "pos %d,%d old serial %lu, ignoring\n", input.u.mi.dx, input.u.mi.dy, xev->serial );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+ x_pos->value = x_accum - input.u.mi.dx;
|
||||
+ y_pos->value = y_accum - input.u.mi.dy;
|
||||
+ wheel->value = w_accum - input.u.mi.mouseData;
|
||||
+
|
||||
if (x_pos->mode == XIModeAbsolute)
|
||||
{
|
||||
TRACE( "pos %d,%d w:%d (event %f,%f,%f)\n", input.u.mi.dx, input.u.mi.dy, input.u.mi.mouseData, dx, dy, dw );
|
||||
@@ -1991,8 +2014,15 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
}
|
||||
else if (!thread_data->xi2_rawinput_only)
|
||||
{
|
||||
- TRACE( "pos %d,%d w:%d (event %f,%f,%f)\n", input.u.mi.dx, input.u.mi.dy, input.u.mi.mouseData, dx, dy, dw );
|
||||
- __wine_send_input( 0, &input, SEND_HWMSG_WINDOW );
|
||||
+ if ((dy || dy || dw) && !(input.u.mi.dx || input.u.mi.dy || input.u.mi.mouseData))
|
||||
+ {
|
||||
+ TRACE( "accumulating raw motion (event %f,%f,%f accum %f,%f,%f)\n", dx, dy, dw, x_pos->value, y_pos->value, wheel->value );
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TRACE( "pos %d,%d w:%d (event %f,%f,%f)\n", input.u.mi.dx, input.u.mi.dy, input.u.mi.mouseData, dx, dy, dw );
|
||||
+ __wine_send_input( 0, &input, SEND_HWMSG_WINDOW );
|
||||
+ }
|
||||
}
|
||||
else
|
||||
{
|
||||
--
|
||||
2.24.1
|
||||
|
2
patches/user32-rawinput-mouse-experimental/definition
Normal file
2
patches/user32-rawinput-mouse-experimental/definition
Normal file
@ -0,0 +1,2 @@
|
||||
Fixes: [45882] - Raw Input should use untransformed mouse values (affects Overwatch, several Source games).
|
||||
Depends: user32-rawinput-nolegacy
|
@ -0,0 +1,262 @@
|
||||
From fe1ae8a2e1ee05143a9a0b7248420edada9bc09d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 14 Nov 2019 16:41:43 +0100
|
||||
Subject: [PATCH 01/12] user32/tests: Add rawinput test for ClipCursor
|
||||
interactions.
|
||||
|
||||
This shows unexpected rawinput messages triggered from cursor clipping.
|
||||
|
||||
The sleeps are required to let native cursor clipping time to activate.
|
||||
We also repeat the clipping multiple times to be increase the chances
|
||||
that the counts will be wrong as it doesn't always trigger.
|
||||
---
|
||||
dlls/user32/tests/input.c | 226 ++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 226 insertions(+)
|
||||
|
||||
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
|
||||
index 478c269017a..bf9d19906a8 100644
|
||||
--- a/dlls/user32/tests/input.c
|
||||
+++ b/dlls/user32/tests/input.c
|
||||
@@ -1826,6 +1826,231 @@ static void test_RegisterRawInputDevices(void)
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
+static int rawinput_received;
|
||||
+static int rawinput_received_foreground;
|
||||
+static int rawinput_motion_x;
|
||||
+static int rawinput_motion_y;
|
||||
+static HANDLE rawinput_wndproc_done;
|
||||
+
|
||||
+static LRESULT CALLBACK rawinput_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
+{
|
||||
+ UINT ret, raw_size;
|
||||
+ RAWINPUT raw;
|
||||
+
|
||||
+ if (msg == WM_INPUT)
|
||||
+ {
|
||||
+ rawinput_received++;
|
||||
+
|
||||
+ ok(wparam == RIM_INPUT || wparam == RIM_INPUTSINK, "Unexpected wparam: %lu\n", wparam);
|
||||
+ if (wparam == RIM_INPUT)
|
||||
+ rawinput_received_foreground++;
|
||||
+
|
||||
+ ret = GetRawInputData((HRAWINPUT)lparam, RID_INPUT, NULL, &raw_size, sizeof(RAWINPUTHEADER));
|
||||
+ ok(ret == 0, "GetRawInputData failed\n");
|
||||
+ ok(raw_size <= sizeof(raw), "Unexpected rawinput data size: %u", raw_size);
|
||||
+
|
||||
+ if (raw_size <= sizeof(raw))
|
||||
+ {
|
||||
+ ret = GetRawInputData((HRAWINPUT)lparam, RID_INPUT, &raw, &raw_size, sizeof(RAWINPUTHEADER));
|
||||
+ ok(ret > 0 && ret != (UINT)-1, "GetRawInputData failed\n");
|
||||
+ ok(raw.header.dwType == RIM_TYPEMOUSE, "Unexpected rawinput type: %u\n", raw.header.dwType);
|
||||
+
|
||||
+ if (raw.header.dwType == RIM_TYPEMOUSE)
|
||||
+ {
|
||||
+ ok(!(raw.data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE), "Unexpected absolute rawinput motion\n");
|
||||
+ ok(!(raw.data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP), "Unexpected virtual desktop rawinput motion\n");
|
||||
+ rawinput_motion_x += raw.data.mouse.lLastX;
|
||||
+ rawinput_motion_y += raw.data.mouse.lLastY;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (msg == WM_USER)
|
||||
+ SetEvent(rawinput_wndproc_done);
|
||||
+
|
||||
+ return DefWindowProcA(hwnd, msg, wparam, lparam);
|
||||
+}
|
||||
+
|
||||
+struct rawinput_mouse_thread_params
|
||||
+{
|
||||
+ int step;
|
||||
+ HWND window;
|
||||
+ HANDLE ready;
|
||||
+ HANDLE start;
|
||||
+};
|
||||
+
|
||||
+static DWORD WINAPI rawinput_mouse_thread(void *arg)
|
||||
+{
|
||||
+ struct rawinput_mouse_thread_params *params = arg;
|
||||
+ RECT rect_105 = { 105, 105, 105, 105 };
|
||||
+ RECT rect_110 = { 110, 110, 110, 110 };
|
||||
+ int i;
|
||||
+
|
||||
+ while (WaitForSingleObject(params->ready, INFINITE) == 0)
|
||||
+ {
|
||||
+ ResetEvent(params->ready);
|
||||
+ SetEvent(params->start);
|
||||
+
|
||||
+ switch (params->step)
|
||||
+ {
|
||||
+ case 0:
|
||||
+ case 1:
|
||||
+ case 2:
|
||||
+ mouse_event(MOUSEEVENTF_MOVE, -1, 0, 0, 0);
|
||||
+ mouse_event(MOUSEEVENTF_MOVE, 0, -1, 0, 0);
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ for (i = 0; i < 10; ++i)
|
||||
+ {
|
||||
+ ClipCursor(&rect_105);
|
||||
+ Sleep(5);
|
||||
+ ClipCursor(&rect_110);
|
||||
+ Sleep(5);
|
||||
+ ClipCursor(NULL);
|
||||
+ Sleep(5);
|
||||
+ }
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ for (i = 0; i < 10; ++i)
|
||||
+ {
|
||||
+ ClipCursor(&rect_110);
|
||||
+ Sleep(5);
|
||||
+ mouse_event(MOUSEEVENTF_MOVE, 1, 1, 0, 0);
|
||||
+ ClipCursor(NULL);
|
||||
+ Sleep(5);
|
||||
+ mouse_event(MOUSEEVENTF_MOVE, 1, 1, 0, 0);
|
||||
+ ClipCursor(&rect_110);
|
||||
+ ClipCursor(NULL);
|
||||
+ Sleep(5);
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ PostMessageA(params->window, WM_USER, 0, 0);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+struct rawinput_mouse_test
|
||||
+{
|
||||
+ BOOL register_device;
|
||||
+ BOOL register_window;
|
||||
+ DWORD register_flags;
|
||||
+ int expect_received;
|
||||
+ int expect_received_foreground;
|
||||
+ int expect_motion_x;
|
||||
+ int expect_motion_y;
|
||||
+ BOOL todo;
|
||||
+};
|
||||
+
|
||||
+static void test_rawinput_mouse(void)
|
||||
+{
|
||||
+ struct rawinput_mouse_thread_params params;
|
||||
+ RAWINPUTDEVICE raw_devices[1];
|
||||
+ HANDLE thread;
|
||||
+ DWORD ret;
|
||||
+ int i;
|
||||
+
|
||||
+ struct rawinput_mouse_test tests[] =
|
||||
+ {
|
||||
+ { FALSE, FALSE, 0, 0, 0, 0, 0, FALSE },
|
||||
+ { TRUE, FALSE, 0, 2, 2, -1, -1, FALSE },
|
||||
+ { TRUE, TRUE, 0, 2, 2, -1, -1, FALSE },
|
||||
+ { TRUE, TRUE, 0, 0, 0, 0, 0, TRUE },
|
||||
+ { TRUE, TRUE, 0, 20, 20, 20, 20, TRUE },
|
||||
+ };
|
||||
+
|
||||
+ mouse_event(MOUSEEVENTF_ABSOLUTE, 100, 100, 0, 0);
|
||||
+ SetCursorPos(100, 100);
|
||||
+
|
||||
+ rawinput_wndproc_done = CreateEventA(NULL, FALSE, FALSE, NULL);
|
||||
+ ok(rawinput_wndproc_done != NULL, "CreateEvent failed\n");
|
||||
+
|
||||
+ params.window = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP, 100, 100, 100, 100, 0, NULL, NULL, NULL);
|
||||
+ ok(params.window != 0, "CreateWindow failed\n");
|
||||
+
|
||||
+ ShowWindow(params.window, SW_SHOW);
|
||||
+ SetWindowPos(params.window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
|
||||
+ SetForegroundWindow(params.window);
|
||||
+ UpdateWindow(params.window);
|
||||
+ empty_message_queue();
|
||||
+
|
||||
+ SetWindowLongPtrA(params.window, GWLP_WNDPROC, (LONG_PTR)rawinput_wndproc);
|
||||
+
|
||||
+ params.step = 0;
|
||||
+ params.ready = CreateEventA(NULL, FALSE, FALSE, NULL);
|
||||
+ ok(params.ready != NULL, "CreateEvent failed\n");
|
||||
+
|
||||
+ params.start = CreateEventA(NULL, FALSE, FALSE, NULL);
|
||||
+ ok(params.start != NULL, "CreateEvent failed\n");
|
||||
+
|
||||
+ thread = CreateThread(NULL, 0, rawinput_mouse_thread, ¶ms, 0, NULL);
|
||||
+ ok(thread != NULL, "CreateThread failed\n");
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(tests); ++i)
|
||||
+ {
|
||||
+ rawinput_received = 0;
|
||||
+ rawinput_received_foreground = 0;
|
||||
+ rawinput_motion_x = 0;
|
||||
+ rawinput_motion_y = 0;
|
||||
+
|
||||
+ raw_devices[0].usUsagePage = 0x01;
|
||||
+ raw_devices[0].usUsage = 0x02;
|
||||
+ raw_devices[0].dwFlags = tests[i].register_flags;
|
||||
+ raw_devices[0].hwndTarget = tests[i].register_window ? params.window : 0;
|
||||
+
|
||||
+ if (tests[i].register_device)
|
||||
+ {
|
||||
+ SetLastError(0xdeadbeef);
|
||||
+ ret = RegisterRawInputDevices(raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE));
|
||||
+ ok(ret, "%d: RegisterRawInputDevices failed\n", i);
|
||||
+ ok(GetLastError() == 0xdeadbeef, "%d: RegisterRawInputDevices returned %08x\n", i, GetLastError());
|
||||
+ }
|
||||
+
|
||||
+ params.step = i;
|
||||
+ SetEvent(params.ready);
|
||||
+
|
||||
+ WaitForSingleObject(params.start, INFINITE);
|
||||
+ ResetEvent(params.start);
|
||||
+
|
||||
+ while (MsgWaitForMultipleObjects(1, &rawinput_wndproc_done, FALSE, INFINITE, QS_ALLINPUT) != WAIT_OBJECT_0)
|
||||
+ empty_message_queue();
|
||||
+ ResetEvent(rawinput_wndproc_done);
|
||||
+
|
||||
+ /* Wine is sometimes passing some of the conditions, but not always, let's test
|
||||
+ * all at once in the todo block, there should be at least one that fails. */
|
||||
+ todo_wine_if(tests[i].todo)
|
||||
+ ok(rawinput_received == tests[i].expect_received &&
|
||||
+ rawinput_received_foreground == tests[i].expect_received_foreground &&
|
||||
+ rawinput_motion_x == tests[i].expect_motion_x &&
|
||||
+ rawinput_motion_y == tests[i].expect_motion_y,
|
||||
+ "%d: Unexpected rawinput results: received %d, %d in foreground, motion is %dx%d\n",
|
||||
+ i, rawinput_received, rawinput_received_foreground, rawinput_motion_x, rawinput_motion_y);
|
||||
+
|
||||
+ if (tests[i].register_device)
|
||||
+ {
|
||||
+ raw_devices[0].dwFlags = RIDEV_REMOVE;
|
||||
+ raw_devices[0].hwndTarget = 0;
|
||||
+
|
||||
+ SetLastError(0xdeadbeef);
|
||||
+ ret = RegisterRawInputDevices(raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE));
|
||||
+ ok(ret, "%d: RegisterRawInputDevices failed\n", i);
|
||||
+ ok(GetLastError() == 0xdeadbeef, "%d: RegisterRawInputDevices returned %08x\n", i, GetLastError());
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ params.step = -1;
|
||||
+ SetEvent(params.ready);
|
||||
+ WaitForSingleObject(thread, INFINITE);
|
||||
+
|
||||
+ CloseHandle(params.start);
|
||||
+ CloseHandle(params.ready);
|
||||
+ CloseHandle(thread);
|
||||
+}
|
||||
+
|
||||
static void test_key_map(void)
|
||||
{
|
||||
HKL kl = GetKeyboardLayout(0);
|
||||
@@ -3326,6 +3551,7 @@ START_TEST(input)
|
||||
test_GetRawInputData();
|
||||
test_GetKeyboardLayoutList();
|
||||
test_RegisterRawInputDevices();
|
||||
+ test_rawinput_mouse();
|
||||
|
||||
if(pGetMouseMovePointsEx)
|
||||
test_GetMouseMovePointsEx();
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,70 @@
|
||||
From d407a40a11f0cbf3e61faded5e6e7e1e2e63ef9c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 14 Nov 2019 17:03:38 +0100
|
||||
Subject: [PATCH 02/12] user32/tests: Add rawinput test for cross-thread
|
||||
interactions.
|
||||
|
||||
The rawinput messages are received on the target window if is from the
|
||||
same process as the foreground window, it doesn't need to be the
|
||||
foreground window itself.
|
||||
---
|
||||
dlls/user32/tests/input.c | 27 +++++++++++++++++++++++++++
|
||||
1 file changed, 27 insertions(+)
|
||||
|
||||
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
|
||||
index bf9d19906a8..bdcc6834d9d 100644
|
||||
--- a/dlls/user32/tests/input.c
|
||||
+++ b/dlls/user32/tests/input.c
|
||||
@@ -1884,6 +1884,7 @@ static DWORD WINAPI rawinput_mouse_thread(void *arg)
|
||||
struct rawinput_mouse_thread_params *params = arg;
|
||||
RECT rect_105 = { 105, 105, 105, 105 };
|
||||
RECT rect_110 = { 110, 110, 110, 110 };
|
||||
+ HWND window;
|
||||
int i;
|
||||
|
||||
while (WaitForSingleObject(params->ready, INFINITE) == 0)
|
||||
@@ -1924,6 +1925,26 @@ static DWORD WINAPI rawinput_mouse_thread(void *arg)
|
||||
Sleep(5);
|
||||
}
|
||||
break;
|
||||
+ case 5:
|
||||
+ case 6:
|
||||
+ window = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP, 100, 100, 100, 100, 0, NULL, NULL, NULL);
|
||||
+ ok(window != 0, "%d: CreateWindow failed\n", params->step);
|
||||
+
|
||||
+ ShowWindow(window, SW_SHOW);
|
||||
+ SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
|
||||
+ SetForegroundWindow(window);
|
||||
+ UpdateWindow(window);
|
||||
+ empty_message_queue();
|
||||
+
|
||||
+ mouse_event(MOUSEEVENTF_MOVE, 1, 1, 0, 0);
|
||||
+ SendMessageA(GetForegroundWindow(), WM_USER, 0, 0);
|
||||
+ mouse_event(MOUSEEVENTF_MOVE, -1, -1, 0, 0);
|
||||
+ SendMessageA(GetForegroundWindow(), WM_USER, 0, 0);
|
||||
+
|
||||
+ empty_message_queue();
|
||||
+
|
||||
+ DestroyWindow(window);
|
||||
+ break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -1959,8 +1980,14 @@ static void test_rawinput_mouse(void)
|
||||
{ FALSE, FALSE, 0, 0, 0, 0, 0, FALSE },
|
||||
{ TRUE, FALSE, 0, 2, 2, -1, -1, FALSE },
|
||||
{ TRUE, TRUE, 0, 2, 2, -1, -1, FALSE },
|
||||
+
|
||||
+ /* clip cursor tests */
|
||||
{ TRUE, TRUE, 0, 0, 0, 0, 0, TRUE },
|
||||
{ TRUE, TRUE, 0, 20, 20, 20, 20, TRUE },
|
||||
+
|
||||
+ /* same-process foreground tests */
|
||||
+ { TRUE, TRUE, 0, 2, 2, 0, 0, TRUE },
|
||||
+ { TRUE, TRUE, RIDEV_INPUTSINK, 2, 2, 0, 0, TRUE },
|
||||
};
|
||||
|
||||
mouse_event(MOUSEEVENTF_ABSOLUTE, 100, 100, 0, 0);
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,173 @@
|
||||
From 35e259f69a7c5a6a065833eaeaca28d92591056b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 14 Nov 2019 18:44:28 +0100
|
||||
Subject: [PATCH 03/12] user32/tests: Add rawinput test for cross-process
|
||||
interactions.
|
||||
|
||||
Validating the rest of the assumption, rawinput messages are not
|
||||
received anymore if the foreground window is from another process.
|
||||
---
|
||||
dlls/user32/tests/input.c | 86 ++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 84 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
|
||||
index bdcc6834d9d..cc7babd1af4 100644
|
||||
--- a/dlls/user32/tests/input.c
|
||||
+++ b/dlls/user32/tests/input.c
|
||||
@@ -49,6 +49,7 @@
|
||||
#define _WIN32_IE 0x0500
|
||||
|
||||
#include <stdarg.h>
|
||||
+#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "windef.h"
|
||||
@@ -1877,8 +1878,36 @@ struct rawinput_mouse_thread_params
|
||||
HWND window;
|
||||
HANDLE ready;
|
||||
HANDLE start;
|
||||
+ const char *argv0;
|
||||
};
|
||||
|
||||
+static void rawinput_mouse_process(void)
|
||||
+{
|
||||
+ HWND window;
|
||||
+ HANDLE start_event, stop_event;
|
||||
+
|
||||
+ start_event = OpenEventA(EVENT_ALL_ACCESS, FALSE, "test_rawinput_mouse_start");
|
||||
+ ok(start_event != 0, "OpenEventA failed, error: %u\n", GetLastError());
|
||||
+
|
||||
+ stop_event = OpenEventA(EVENT_ALL_ACCESS, FALSE, "test_rawinput_mouse_stop");
|
||||
+ ok(stop_event != 0, "OpenEventA failed, error: %u\n", GetLastError());
|
||||
+
|
||||
+ window = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP, 200, 100, 100, 100, 0, NULL, NULL, NULL);
|
||||
+ ok(window != 0, "CreateWindow failed\n");
|
||||
+
|
||||
+ ShowWindow(window, SW_SHOW);
|
||||
+ SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
|
||||
+ SetForegroundWindow(window);
|
||||
+ UpdateWindow(window);
|
||||
+ empty_message_queue();
|
||||
+
|
||||
+ SetEvent(start_event);
|
||||
+ while (MsgWaitForMultipleObjects(1, &stop_event, FALSE, INFINITE, QS_ALLINPUT) != WAIT_OBJECT_0)
|
||||
+ empty_message_queue();
|
||||
+
|
||||
+ DestroyWindow(window);
|
||||
+}
|
||||
+
|
||||
static DWORD WINAPI rawinput_mouse_thread(void *arg)
|
||||
{
|
||||
struct rawinput_mouse_thread_params *params = arg;
|
||||
@@ -1886,6 +1915,11 @@ static DWORD WINAPI rawinput_mouse_thread(void *arg)
|
||||
RECT rect_110 = { 110, 110, 110, 110 };
|
||||
HWND window;
|
||||
int i;
|
||||
+ char path[MAX_PATH];
|
||||
+ PROCESS_INFORMATION process_info;
|
||||
+ STARTUPINFOA startup_info;
|
||||
+ HANDLE start_event, stop_event;
|
||||
+ BOOL ret;
|
||||
|
||||
while (WaitForSingleObject(params->ready, INFINITE) == 0)
|
||||
{
|
||||
@@ -1945,6 +1979,39 @@ static DWORD WINAPI rawinput_mouse_thread(void *arg)
|
||||
|
||||
DestroyWindow(window);
|
||||
break;
|
||||
+ case 7:
|
||||
+ case 8:
|
||||
+ start_event = CreateEventA(NULL, 0, 0, "test_rawinput_mouse_start");
|
||||
+ ok(start_event != 0, "%d: CreateEventA failed, error %u\n", params->step, GetLastError());
|
||||
+
|
||||
+ stop_event = CreateEventA(NULL, 0, 0, "test_rawinput_mouse_stop");
|
||||
+ ok(stop_event != 0, "%d: CreateEventA failed, error %u\n", params->step, GetLastError());
|
||||
+
|
||||
+ memset(&startup_info, 0, sizeof(startup_info));
|
||||
+ startup_info.cb = sizeof(startup_info);
|
||||
+ startup_info.dwFlags = STARTF_USESHOWWINDOW;
|
||||
+ startup_info.wShowWindow = SW_SHOWNORMAL;
|
||||
+
|
||||
+ sprintf(path, "%s input test_rawinput_mouse", params->argv0);
|
||||
+ ret = CreateProcessA(NULL, path, NULL, NULL, TRUE, 0, NULL, NULL, &startup_info, &process_info );
|
||||
+ ok(ret, "%d: CreateProcess '%s' failed err %u.\n", params->step, path, GetLastError());
|
||||
+
|
||||
+ ret = WaitForSingleObject(start_event, 5000);
|
||||
+ ok(ret == WAIT_OBJECT_0, "%d: WaitForSingleObject failed\n", params->step);
|
||||
+
|
||||
+ mouse_event(MOUSEEVENTF_MOVE, 1, 1, 0, 0);
|
||||
+ SendMessageA(GetForegroundWindow(), WM_USER, 0, 0);
|
||||
+ mouse_event(MOUSEEVENTF_MOVE, -1, -1, 0, 0);
|
||||
+ SendMessageA(GetForegroundWindow(), WM_USER, 0, 0);
|
||||
+
|
||||
+ SetEvent(stop_event);
|
||||
+
|
||||
+ winetest_wait_child_process(process_info.hProcess);
|
||||
+ CloseHandle(process_info.hProcess);
|
||||
+ CloseHandle(process_info.hThread);
|
||||
+ CloseHandle(start_event);
|
||||
+ CloseHandle(stop_event);
|
||||
+ break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -1967,7 +2034,7 @@ struct rawinput_mouse_test
|
||||
BOOL todo;
|
||||
};
|
||||
|
||||
-static void test_rawinput_mouse(void)
|
||||
+static void test_rawinput_mouse(const char *argv0)
|
||||
{
|
||||
struct rawinput_mouse_thread_params params;
|
||||
RAWINPUTDEVICE raw_devices[1];
|
||||
@@ -1988,11 +2055,17 @@ static void test_rawinput_mouse(void)
|
||||
/* same-process foreground tests */
|
||||
{ TRUE, TRUE, 0, 2, 2, 0, 0, TRUE },
|
||||
{ TRUE, TRUE, RIDEV_INPUTSINK, 2, 2, 0, 0, TRUE },
|
||||
+
|
||||
+ /* cross-process foreground tests */
|
||||
+ { TRUE, TRUE, 0, 0, 0, 0, 0, TRUE },
|
||||
+ { TRUE, TRUE, RIDEV_INPUTSINK, 2, 0, 0, 0, TRUE },
|
||||
};
|
||||
|
||||
mouse_event(MOUSEEVENTF_ABSOLUTE, 100, 100, 0, 0);
|
||||
SetCursorPos(100, 100);
|
||||
|
||||
+ params.argv0 = argv0;
|
||||
+
|
||||
rawinput_wndproc_done = CreateEventA(NULL, FALSE, FALSE, NULL);
|
||||
ok(rawinput_wndproc_done != NULL, "CreateEvent failed\n");
|
||||
|
||||
@@ -3555,11 +3628,20 @@ static void test_GetKeyboardLayoutList(void)
|
||||
|
||||
START_TEST(input)
|
||||
{
|
||||
+ char **argv;
|
||||
+ int argc;
|
||||
POINT pos;
|
||||
|
||||
init_function_pointers();
|
||||
GetCursorPos( &pos );
|
||||
|
||||
+ argc = winetest_get_mainargs(&argv);
|
||||
+ if (argc >= 3 && strcmp(argv[2], "test_rawinput_mouse") == 0)
|
||||
+ {
|
||||
+ rawinput_mouse_process();
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
test_Input_blackbox();
|
||||
test_Input_whitebox();
|
||||
test_Input_unicode();
|
||||
@@ -3578,7 +3660,7 @@ START_TEST(input)
|
||||
test_GetRawInputData();
|
||||
test_GetKeyboardLayoutList();
|
||||
test_RegisterRawInputDevices();
|
||||
- test_rawinput_mouse();
|
||||
+ test_rawinput_mouse(argv[0]);
|
||||
|
||||
if(pGetMouseMovePointsEx)
|
||||
test_GetMouseMovePointsEx();
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,128 @@
|
||||
From 430580824e975bbda41884affd3e5fbf104ac6fe Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Mon, 26 Aug 2019 14:37:20 +0200
|
||||
Subject: [PATCH 04/12] server: Add send_hardware_message flags for rawinput
|
||||
translation.
|
||||
|
||||
---
|
||||
dlls/user32/input.c | 6 +++---
|
||||
server/protocol.def | 2 ++
|
||||
server/queue.c | 20 ++++++++++++++------
|
||||
3 files changed, 19 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
|
||||
index 340d20e58f9..7d947a98d0f 100644
|
||||
--- a/dlls/user32/input.c
|
||||
+++ b/dlls/user32/input.c
|
||||
@@ -124,7 +124,7 @@ BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret )
|
||||
*/
|
||||
BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input )
|
||||
{
|
||||
- NTSTATUS status = send_hardware_message( hwnd, input, 0 );
|
||||
+ NTSTATUS status = send_hardware_message( hwnd, input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
if (status) SetLastError( RtlNtStatusToDosError(status) );
|
||||
return !status;
|
||||
}
|
||||
@@ -192,9 +192,9 @@ UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size )
|
||||
/* we need to update the coordinates to what the server expects */
|
||||
INPUT input = inputs[i];
|
||||
update_mouse_coords( &input );
|
||||
- status = send_hardware_message( 0, &input, SEND_HWMSG_INJECTED );
|
||||
+ status = send_hardware_message( 0, &input, SEND_HWMSG_INJECTED|SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
}
|
||||
- else status = send_hardware_message( 0, &inputs[i], SEND_HWMSG_INJECTED );
|
||||
+ else status = send_hardware_message( 0, &inputs[i], SEND_HWMSG_INJECTED|SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
|
||||
if (status)
|
||||
{
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index ae3702b150f..9f9f9197134 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -2370,6 +2370,8 @@ enum message_type
|
||||
VARARG(keystate,bytes); /* global state array for all the keys */
|
||||
@END
|
||||
#define SEND_HWMSG_INJECTED 0x01
|
||||
+#define SEND_HWMSG_RAWINPUT 0x02
|
||||
+#define SEND_HWMSG_WINDOW 0x04
|
||||
|
||||
|
||||
/* Get a message from the current queue */
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index af65b5f6b4c..9528453b190 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -1736,7 +1736,7 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa
|
||||
|
||||
/* queue a hardware message for a mouse event */
|
||||
static int queue_mouse_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
|
||||
- unsigned int origin, struct msg_queue *sender )
|
||||
+ unsigned int origin, struct msg_queue *sender, unsigned int req_flags )
|
||||
{
|
||||
const struct rawinput_device *device;
|
||||
struct hardware_msg_data *msg_data;
|
||||
@@ -1789,7 +1789,8 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
y = desktop->cursor.y;
|
||||
}
|
||||
|
||||
- if ((device = current->process->rawinput_mouse))
|
||||
+ if ((device = current->process->rawinput_mouse) &&
|
||||
+ (req_flags & SEND_HWMSG_RAWINPUT))
|
||||
{
|
||||
if (!(msg = alloc_hardware_message( input->mouse.info, source, time ))) return 0;
|
||||
msg_data = msg->data;
|
||||
@@ -1808,6 +1809,9 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
queue_hardware_message( desktop, msg, 0 );
|
||||
}
|
||||
|
||||
+ if (!(req_flags & SEND_HWMSG_WINDOW))
|
||||
+ return 0;
|
||||
+
|
||||
for (i = 0; i < ARRAY_SIZE( messages ); i++)
|
||||
{
|
||||
if (!messages[i]) continue;
|
||||
@@ -1839,7 +1843,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
|
||||
/* queue a hardware message for a keyboard event */
|
||||
static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
|
||||
- unsigned int origin, struct msg_queue *sender )
|
||||
+ unsigned int origin, struct msg_queue *sender, unsigned int req_flags )
|
||||
{
|
||||
struct hw_msg_source source = { IMDT_KEYBOARD, origin };
|
||||
const struct rawinput_device *device;
|
||||
@@ -1915,7 +1919,8 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
break;
|
||||
}
|
||||
|
||||
- if ((device = current->process->rawinput_kbd))
|
||||
+ if ((device = current->process->rawinput_kbd) &&
|
||||
+ (req_flags & SEND_HWMSG_RAWINPUT))
|
||||
{
|
||||
if (!(msg = alloc_hardware_message( input->kbd.info, source, time ))) return 0;
|
||||
msg_data = msg->data;
|
||||
@@ -1933,6 +1938,9 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
queue_hardware_message( desktop, msg, 0 );
|
||||
}
|
||||
|
||||
+ if (!(req_flags & SEND_HWMSG_WINDOW))
|
||||
+ return 0;
|
||||
+
|
||||
if (!(msg = alloc_hardware_message( input->kbd.info, source, time ))) return 0;
|
||||
msg_data = msg->data;
|
||||
|
||||
@@ -2494,10 +2502,10 @@ DECL_HANDLER(send_hardware_message)
|
||||
switch (req->input.type)
|
||||
{
|
||||
case INPUT_MOUSE:
|
||||
- reply->wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender );
|
||||
+ reply->wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender, req->flags );
|
||||
break;
|
||||
case INPUT_KEYBOARD:
|
||||
- reply->wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender );
|
||||
+ reply->wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender, req->flags );
|
||||
break;
|
||||
case INPUT_HARDWARE:
|
||||
queue_custom_hardware_message( desktop, req->win, origin, &req->input );
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,182 @@
|
||||
From 9a0c9443ada9bccc1d10270398dbf9bddb483d53 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Tue, 12 Nov 2019 12:41:55 +0100
|
||||
Subject: [PATCH 05/12] server: Broadcast rawinput message if request flag is
|
||||
SEND_HWMSG_RAWINPUT.
|
||||
|
||||
If the request flag is equal to SEND_HWMSG_RAWINPUT, we broadcast the
|
||||
message to all listening processes -or at least to the foreground
|
||||
process until RIDEV_INPUTSINK is supported.
|
||||
---
|
||||
dlls/user32/tests/input.c | 2 +-
|
||||
server/queue.c | 98 ++++++++++++++++++++++++++++++---------
|
||||
2 files changed, 78 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
|
||||
index cc7babd1af4..d18ccfebcaf 100644
|
||||
--- a/dlls/user32/tests/input.c
|
||||
+++ b/dlls/user32/tests/input.c
|
||||
@@ -2057,7 +2057,7 @@ static void test_rawinput_mouse(const char *argv0)
|
||||
{ TRUE, TRUE, RIDEV_INPUTSINK, 2, 2, 0, 0, TRUE },
|
||||
|
||||
/* cross-process foreground tests */
|
||||
- { TRUE, TRUE, 0, 0, 0, 0, 0, TRUE },
|
||||
+ { TRUE, TRUE, 0, 0, 0, 0, 0, FALSE },
|
||||
{ TRUE, TRUE, RIDEV_INPUTSINK, 2, 0, 0, 0, TRUE },
|
||||
};
|
||||
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index 9528453b190..2bdd099d1bb 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -1734,12 +1734,67 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa
|
||||
return 1;
|
||||
}
|
||||
|
||||
+struct rawinput_message
|
||||
+{
|
||||
+ struct desktop *desktop;
|
||||
+ struct hw_msg_source source;
|
||||
+ unsigned int time;
|
||||
+ struct hardware_msg_data data;
|
||||
+};
|
||||
+
|
||||
+static int queue_rawinput_message( struct process* process, void* user )
|
||||
+{
|
||||
+ const struct rawinput_message* raw_msg = user;
|
||||
+ const struct rawinput_device *device = NULL;
|
||||
+ struct desktop *desktop = NULL;
|
||||
+ struct thread *thread = NULL, *foreground = NULL;
|
||||
+ struct message *msg;
|
||||
+
|
||||
+ if (raw_msg->data.rawinput.type == RIM_TYPEMOUSE)
|
||||
+ device = process->rawinput_mouse;
|
||||
+ else if (raw_msg->data.rawinput.type == RIM_TYPEKEYBOARD)
|
||||
+ device = process->rawinput_kbd;
|
||||
+
|
||||
+ if (!device)
|
||||
+ goto done;
|
||||
+
|
||||
+ if (!(desktop = get_desktop_obj( process, process->desktop, 0 )) ||
|
||||
+ (raw_msg->desktop && desktop != raw_msg->desktop))
|
||||
+ goto done;
|
||||
+
|
||||
+ if (!(thread = get_window_thread( device->target ? device->target : desktop->foreground_input->active )) ||
|
||||
+ process != thread->process)
|
||||
+ goto done;
|
||||
+
|
||||
+ /* FIXME: Implement RIDEV_INPUTSINK */
|
||||
+ if (!(foreground = get_window_thread( desktop->foreground_input->active )) ||
|
||||
+ thread->process != foreground->process)
|
||||
+ goto done;
|
||||
+
|
||||
+ if (!(msg = alloc_hardware_message( raw_msg->data.info, raw_msg->source, raw_msg->time )))
|
||||
+ goto done;
|
||||
+
|
||||
+ msg->win = device->target;
|
||||
+ msg->msg = WM_INPUT;
|
||||
+ msg->wparam = RIM_INPUT;
|
||||
+ msg->lparam = 0;
|
||||
+ memcpy( msg->data, &raw_msg->data, sizeof(raw_msg->data) );
|
||||
+
|
||||
+ queue_hardware_message( desktop, msg, 0 );
|
||||
+
|
||||
+done:
|
||||
+ if (foreground) release_object( foreground );
|
||||
+ if (thread) release_object( thread );
|
||||
+ if (desktop) release_object( desktop );
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* queue a hardware message for a mouse event */
|
||||
static int queue_mouse_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
|
||||
unsigned int origin, struct msg_queue *sender, unsigned int req_flags )
|
||||
{
|
||||
- const struct rawinput_device *device;
|
||||
struct hardware_msg_data *msg_data;
|
||||
+ struct rawinput_message raw_msg;
|
||||
struct message *msg;
|
||||
unsigned int i, time, flags;
|
||||
struct hw_msg_source source = { IMDT_MOUSE, origin };
|
||||
@@ -1789,24 +1844,24 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
y = desktop->cursor.y;
|
||||
}
|
||||
|
||||
- if ((device = current->process->rawinput_mouse) &&
|
||||
- (req_flags & SEND_HWMSG_RAWINPUT))
|
||||
+ if (req_flags & SEND_HWMSG_RAWINPUT)
|
||||
{
|
||||
- if (!(msg = alloc_hardware_message( input->mouse.info, source, time ))) return 0;
|
||||
- msg_data = msg->data;
|
||||
-
|
||||
- msg->win = device->target;
|
||||
- msg->msg = WM_INPUT;
|
||||
- msg->wparam = RIM_INPUT;
|
||||
- msg->lparam = 0;
|
||||
+ raw_msg.desktop = desktop;
|
||||
+ raw_msg.source = source;
|
||||
+ raw_msg.time = time;
|
||||
|
||||
+ msg_data = &raw_msg.data;
|
||||
+ msg_data->info = input->mouse.info;
|
||||
msg_data->flags = flags;
|
||||
msg_data->rawinput.type = RIM_TYPEMOUSE;
|
||||
msg_data->rawinput.mouse.x = x - desktop->cursor.x;
|
||||
msg_data->rawinput.mouse.y = y - desktop->cursor.y;
|
||||
msg_data->rawinput.mouse.data = input->mouse.data;
|
||||
|
||||
- queue_hardware_message( desktop, msg, 0 );
|
||||
+ if (req_flags == SEND_HWMSG_RAWINPUT)
|
||||
+ enum_processes( queue_rawinput_message, &raw_msg );
|
||||
+ else
|
||||
+ queue_rawinput_message( current->process, &raw_msg );
|
||||
}
|
||||
|
||||
if (!(req_flags & SEND_HWMSG_WINDOW))
|
||||
@@ -1846,8 +1901,8 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
unsigned int origin, struct msg_queue *sender, unsigned int req_flags )
|
||||
{
|
||||
struct hw_msg_source source = { IMDT_KEYBOARD, origin };
|
||||
- const struct rawinput_device *device;
|
||||
struct hardware_msg_data *msg_data;
|
||||
+ struct rawinput_message raw_msg;
|
||||
struct message *msg;
|
||||
unsigned char vkey = input->kbd.vkey;
|
||||
unsigned int message_code, time;
|
||||
@@ -1919,23 +1974,24 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
break;
|
||||
}
|
||||
|
||||
- if ((device = current->process->rawinput_kbd) &&
|
||||
- (req_flags & SEND_HWMSG_RAWINPUT))
|
||||
+ if (req_flags & SEND_HWMSG_RAWINPUT)
|
||||
{
|
||||
- if (!(msg = alloc_hardware_message( input->kbd.info, source, time ))) return 0;
|
||||
- msg_data = msg->data;
|
||||
-
|
||||
- msg->win = device->target;
|
||||
- msg->msg = WM_INPUT;
|
||||
- msg->wparam = RIM_INPUT;
|
||||
+ raw_msg.desktop = desktop;
|
||||
+ raw_msg.source = source;
|
||||
+ raw_msg.time = time;
|
||||
|
||||
+ msg_data = &raw_msg.data;
|
||||
+ msg_data->info = input->kbd.info;
|
||||
msg_data->flags = input->kbd.flags;
|
||||
msg_data->rawinput.type = RIM_TYPEKEYBOARD;
|
||||
msg_data->rawinput.kbd.message = message_code;
|
||||
msg_data->rawinput.kbd.vkey = vkey;
|
||||
msg_data->rawinput.kbd.scan = input->kbd.scan;
|
||||
|
||||
- queue_hardware_message( desktop, msg, 0 );
|
||||
+ if (req_flags == SEND_HWMSG_RAWINPUT)
|
||||
+ enum_processes( queue_rawinput_message, &raw_msg );
|
||||
+ else
|
||||
+ queue_rawinput_message( current->process, &raw_msg );
|
||||
}
|
||||
|
||||
if (!(req_flags & SEND_HWMSG_WINDOW))
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,193 @@
|
||||
From 8304a54fbb8d34bf4278155624464d2b47ce37cf Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Mon, 26 Aug 2019 15:20:32 +0200
|
||||
Subject: [PATCH 06/12] user32: Add __wine_send_input flags to hint raw input
|
||||
translation.
|
||||
|
||||
---
|
||||
dlls/user32/input.c | 4 ++--
|
||||
dlls/user32/user32.spec | 2 +-
|
||||
dlls/wineandroid.drv/keyboard.c | 2 +-
|
||||
dlls/wineandroid.drv/window.c | 4 ++--
|
||||
dlls/winemac.drv/ime.c | 4 ++--
|
||||
dlls/winemac.drv/keyboard.c | 2 +-
|
||||
dlls/winemac.drv/mouse.c | 2 +-
|
||||
dlls/winex11.drv/keyboard.c | 2 +-
|
||||
dlls/winex11.drv/mouse.c | 8 ++++----
|
||||
include/winuser.h | 2 +-
|
||||
10 files changed, 16 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
|
||||
index 7d947a98d0f..97a5ada922e 100644
|
||||
--- a/dlls/user32/input.c
|
||||
+++ b/dlls/user32/input.c
|
||||
@@ -122,9 +122,9 @@ BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret )
|
||||
*
|
||||
* Internal SendInput function to allow the graphics driver to inject real events.
|
||||
*/
|
||||
-BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input )
|
||||
+BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input, UINT flags )
|
||||
{
|
||||
- NTSTATUS status = send_hardware_message( hwnd, input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
+ NTSTATUS status = send_hardware_message( hwnd, input, flags );
|
||||
if (status) SetLastError( RtlNtStatusToDosError(status) );
|
||||
return !status;
|
||||
}
|
||||
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec
|
||||
index c08ad5ff4f9..b59ba381334 100644
|
||||
--- a/dlls/user32/user32.spec
|
||||
+++ b/dlls/user32/user32.spec
|
||||
@@ -833,5 +833,5 @@
|
||||
# All functions must be prefixed with '__wine_' (for internal functions)
|
||||
# or 'wine_' (for user-visible functions) to avoid namespace conflicts.
|
||||
#
|
||||
-@ cdecl __wine_send_input(long ptr)
|
||||
+@ cdecl __wine_send_input(long ptr long)
|
||||
@ cdecl __wine_set_pixel_format(long long)
|
||||
diff --git a/dlls/wineandroid.drv/keyboard.c b/dlls/wineandroid.drv/keyboard.c
|
||||
index a0f3257f74b..1af8a98f1f9 100644
|
||||
--- a/dlls/wineandroid.drv/keyboard.c
|
||||
+++ b/dlls/wineandroid.drv/keyboard.c
|
||||
@@ -680,7 +680,7 @@ static void send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD flags )
|
||||
input.u.ki.time = 0;
|
||||
input.u.ki.dwExtraInfo = 0;
|
||||
|
||||
- __wine_send_input( hwnd, &input );
|
||||
+ __wine_send_input( hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c
|
||||
index 2fc258dfd90..d96f001432d 100644
|
||||
--- a/dlls/wineandroid.drv/window.c
|
||||
+++ b/dlls/wineandroid.drv/window.c
|
||||
@@ -524,7 +524,7 @@ static int process_events( DWORD mask )
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
- __wine_send_input( capture ? capture : event->data.motion.hwnd, &event->data.motion.input );
|
||||
+ __wine_send_input( capture ? capture : event->data.motion.hwnd, &event->data.motion.input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -538,7 +538,7 @@ static int process_events( DWORD mask )
|
||||
event->data.kbd.input.u.ki.wVk, event->data.kbd.input.u.ki.wVk,
|
||||
event->data.kbd.input.u.ki.wScan );
|
||||
update_keyboard_lock_state( event->data.kbd.input.u.ki.wVk, event->data.kbd.lock_state );
|
||||
- __wine_send_input( 0, &event->data.kbd.input );
|
||||
+ __wine_send_input( 0, &event->data.kbd.input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
break;
|
||||
|
||||
default:
|
||||
diff --git a/dlls/winemac.drv/ime.c b/dlls/winemac.drv/ime.c
|
||||
index dabe6654f98..2ed6e6f66a3 100644
|
||||
--- a/dlls/winemac.drv/ime.c
|
||||
+++ b/dlls/winemac.drv/ime.c
|
||||
@@ -1427,10 +1427,10 @@ void macdrv_im_set_text(const macdrv_event *event)
|
||||
{
|
||||
input.ki.wScan = chars[i];
|
||||
input.ki.dwFlags = KEYEVENTF_UNICODE;
|
||||
- __wine_send_input(hwnd, &input);
|
||||
+ __wine_send_input(hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW);
|
||||
|
||||
input.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
|
||||
- __wine_send_input(hwnd, &input);
|
||||
+ __wine_send_input(hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/dlls/winemac.drv/keyboard.c b/dlls/winemac.drv/keyboard.c
|
||||
index bb408cb20c5..41919baafc7 100644
|
||||
--- a/dlls/winemac.drv/keyboard.c
|
||||
+++ b/dlls/winemac.drv/keyboard.c
|
||||
@@ -929,7 +929,7 @@ static void macdrv_send_keyboard_input(HWND hwnd, WORD vkey, WORD scan, DWORD fl
|
||||
input.ki.time = time;
|
||||
input.ki.dwExtraInfo = 0;
|
||||
|
||||
- __wine_send_input(hwnd, &input);
|
||||
+ __wine_send_input(hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW);
|
||||
}
|
||||
|
||||
|
||||
diff --git a/dlls/winemac.drv/mouse.c b/dlls/winemac.drv/mouse.c
|
||||
index dd6443fe1ba..91cafdf1362 100644
|
||||
--- a/dlls/winemac.drv/mouse.c
|
||||
+++ b/dlls/winemac.drv/mouse.c
|
||||
@@ -165,7 +165,7 @@ static void send_mouse_input(HWND hwnd, macdrv_window cocoa_window, UINT flags,
|
||||
input.mi.time = time;
|
||||
input.mi.dwExtraInfo = 0;
|
||||
|
||||
- __wine_send_input(top_level_hwnd, &input);
|
||||
+ __wine_send_input(top_level_hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW);
|
||||
}
|
||||
|
||||
|
||||
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
|
||||
index 3c38784ebf9..7856b04c8f5 100644
|
||||
--- a/dlls/winex11.drv/keyboard.c
|
||||
+++ b/dlls/winex11.drv/keyboard.c
|
||||
@@ -1149,7 +1149,7 @@ static void X11DRV_send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD f
|
||||
input.u.ki.time = time;
|
||||
input.u.ki.dwExtraInfo = 0;
|
||||
|
||||
- __wine_send_input( hwnd, &input );
|
||||
+ __wine_send_input( hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
}
|
||||
|
||||
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index 8e1eb6d5e0e..96e04509e73 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -659,7 +659,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
|
||||
}
|
||||
input->u.mi.dx += clip_rect.left;
|
||||
input->u.mi.dy += clip_rect.top;
|
||||
- __wine_send_input( hwnd, input );
|
||||
+ __wine_send_input( hwnd, input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -699,7 +699,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
|
||||
- __wine_send_input( hwnd, input );
|
||||
+ __wine_send_input( hwnd, input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
}
|
||||
|
||||
#ifdef SONAME_LIBXCURSOR
|
||||
@@ -1645,7 +1645,7 @@ void move_resize_window( HWND hwnd, int dir )
|
||||
input.u.mi.dwFlags = button_up_flags[button - 1] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
|
||||
input.u.mi.time = GetTickCount();
|
||||
input.u.mi.dwExtraInfo = 0;
|
||||
- __wine_send_input( hwnd, &input );
|
||||
+ __wine_send_input( hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
}
|
||||
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
|
||||
@@ -1884,7 +1884,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
|
||||
|
||||
input.type = INPUT_MOUSE;
|
||||
- __wine_send_input( 0, &input );
|
||||
+ __wine_send_input( 0, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
diff --git a/include/winuser.h b/include/winuser.h
|
||||
index 51c73d25c2f..10cebfa97d0 100644
|
||||
--- a/include/winuser.h
|
||||
+++ b/include/winuser.h
|
||||
@@ -4389,7 +4389,7 @@ static inline BOOL WINAPI SetRectEmpty(LPRECT rect)
|
||||
WORD WINAPI SYSTEM_KillSystemTimer( WORD );
|
||||
|
||||
#ifdef __WINESRC__
|
||||
-WINUSERAPI BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input );
|
||||
+WINUSERAPI BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input, UINT flags );
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,146 @@
|
||||
From 9038e4871284e636f277be8fc8a2a901049bcaf6 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Fri, 2 Aug 2019 02:24:32 -0400
|
||||
Subject: [PATCH 07/12] winex11.drv: Advertise XInput2 version 2.1 support.
|
||||
|
||||
Under XInput2 protocol version < 2.1, RawEvents are not supposed to be
|
||||
sent if a pointer grab is active. However slave device events are still
|
||||
received regardless of this specification and Wine implemented a
|
||||
workaround to receive RawEvents during pointer grabs by listening to
|
||||
these slave device events. Then, as soon as a mouse button is pressed
|
||||
only the grabbing client will receive the raw motion events.
|
||||
|
||||
By advertising the support of XInput2 version >= 2.1, where RawEvents
|
||||
are sent even during pointer grabs, we ensure to receive the RawMotion
|
||||
events from the desktop window thread, even if a mouse grab is active.
|
||||
|
||||
It is now also possible to simplify the code by listening to master
|
||||
device events only and get rid of slave device id tracking.
|
||||
---
|
||||
dlls/winex11.drv/mouse.c | 49 ++++++++-------------------------------
|
||||
dlls/winex11.drv/x11drv.h | 3 ---
|
||||
2 files changed, 10 insertions(+), 42 deletions(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index 96e04509e73..105db08a78a 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -304,12 +304,16 @@ static void enable_xinput2(void)
|
||||
|
||||
if (data->xi2_state == xi_unknown)
|
||||
{
|
||||
- int major = 2, minor = 0;
|
||||
- if (!pXIQueryVersion( data->display, &major, &minor )) data->xi2_state = xi_disabled;
|
||||
+ int major = 2, minor = 1;
|
||||
+ if (!pXIQueryVersion( data->display, &major, &minor ) && major == 2 && minor > 0)
|
||||
+ {
|
||||
+ TRACE( "XInput2 v%d.%d available\n", major, minor );
|
||||
+ data->xi2_state = xi_disabled;
|
||||
+ }
|
||||
else
|
||||
{
|
||||
data->xi2_state = xi_unavailable;
|
||||
- WARN( "X Input 2 not available\n" );
|
||||
+ WARN( "XInput v2.1 not available\n" );
|
||||
}
|
||||
}
|
||||
if (data->xi2_state == xi_unavailable) return;
|
||||
@@ -317,7 +321,7 @@ static void enable_xinput2(void)
|
||||
|
||||
mask.mask = mask_bits;
|
||||
mask.mask_len = sizeof(mask_bits);
|
||||
- mask.deviceid = XIAllDevices;
|
||||
+ mask.deviceid = XIAllMasterDevices;
|
||||
memset( mask_bits, 0, sizeof(mask_bits) );
|
||||
XISetMask( mask_bits, XI_DeviceChanged );
|
||||
XISetMask( mask_bits, XI_RawMotion );
|
||||
@@ -329,16 +333,6 @@ static void enable_xinput2(void)
|
||||
update_relative_valuators( pointer_info->classes, pointer_info->num_classes );
|
||||
pXIFreeDeviceInfo( pointer_info );
|
||||
|
||||
- /* This device info list is only used to find the initial current slave if
|
||||
- * no XI_DeviceChanged events happened. If any hierarchy change occurred that
|
||||
- * might be relevant here (eg. user switching mice after (un)plugging), a
|
||||
- * XI_DeviceChanged event will point us to the right slave. So this list is
|
||||
- * safe to be obtained statically at enable_xinput2() time.
|
||||
- */
|
||||
- if (data->xi2_devices) pXIFreeDeviceInfo( data->xi2_devices );
|
||||
- data->xi2_devices = pXIQueryDevice( data->display, XIAllDevices, &data->xi2_device_count );
|
||||
- data->xi2_current_slave = 0;
|
||||
-
|
||||
data->xi2_state = xi_enabled;
|
||||
#endif
|
||||
}
|
||||
@@ -359,15 +353,12 @@ static void disable_xinput2(void)
|
||||
|
||||
mask.mask = NULL;
|
||||
mask.mask_len = 0;
|
||||
- mask.deviceid = XIAllDevices;
|
||||
+ mask.deviceid = XIAllMasterDevices;
|
||||
|
||||
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
|
||||
- pXIFreeDeviceInfo( data->xi2_devices );
|
||||
data->x_rel_valuator.number = -1;
|
||||
data->y_rel_valuator.number = -1;
|
||||
- data->xi2_devices = NULL;
|
||||
data->xi2_core_pointer = 0;
|
||||
- data->xi2_current_slave = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1801,7 +1792,6 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev )
|
||||
if (event->reason != XISlaveSwitch) return FALSE;
|
||||
|
||||
update_relative_valuators( event->classes, event->num_classes );
|
||||
- data->xi2_current_slave = event->sourceid;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1822,26 +1812,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
if (thread_data->x_rel_valuator.number < 0 || thread_data->y_rel_valuator.number < 0) return FALSE;
|
||||
if (!event->valuators.mask_len) return FALSE;
|
||||
if (thread_data->xi2_state != xi_enabled) return FALSE;
|
||||
-
|
||||
- /* If there is no slave currently detected, no previous motion nor device
|
||||
- * change events were received. Look it up now on the device list in this
|
||||
- * case.
|
||||
- */
|
||||
- if (!thread_data->xi2_current_slave)
|
||||
- {
|
||||
- XIDeviceInfo *devices = thread_data->xi2_devices;
|
||||
-
|
||||
- for (i = 0; i < thread_data->xi2_device_count; i++)
|
||||
- {
|
||||
- if (devices[i].use != XISlavePointer) continue;
|
||||
- if (devices[i].deviceid != event->deviceid) continue;
|
||||
- if (devices[i].attachment != thread_data->xi2_core_pointer) continue;
|
||||
- thread_data->xi2_current_slave = event->deviceid;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (event->deviceid != thread_data->xi2_current_slave) return FALSE;
|
||||
+ if (event->deviceid != thread_data->xi2_core_pointer) return FALSE;
|
||||
|
||||
x_rel = &thread_data->x_rel_valuator;
|
||||
y_rel = &thread_data->y_rel_valuator;
|
||||
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
|
||||
index cca87433264..432dd5909ca 100644
|
||||
--- a/dlls/winex11.drv/x11drv.h
|
||||
+++ b/dlls/winex11.drv/x11drv.h
|
||||
@@ -340,12 +340,9 @@ struct x11drv_thread_data
|
||||
DWORD clip_reset; /* time when clipping was last reset */
|
||||
HKL kbd_layout; /* active keyboard layout */
|
||||
enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled } xi2_state; /* XInput2 state */
|
||||
- void *xi2_devices; /* list of XInput2 devices (valid when state is enabled) */
|
||||
- int xi2_device_count;
|
||||
struct x11drv_valuator_data x_rel_valuator;
|
||||
struct x11drv_valuator_data y_rel_valuator;
|
||||
int xi2_core_pointer; /* XInput2 core pointer id */
|
||||
- int xi2_current_slave; /* Current slave driving the Core pointer */
|
||||
};
|
||||
|
||||
extern struct x11drv_thread_data *x11drv_init_thread_data(void) DECLSPEC_HIDDEN;
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,224 @@
|
||||
From ef0b82046445fe430ab85bb8069f3e4536b11f7a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 19 Dec 2019 22:34:44 +0100
|
||||
Subject: [PATCH 08/12] winex11.drv: Keep track of pointer and device button
|
||||
mappings.
|
||||
|
||||
We are going to receive raw button events and we will need to apply the
|
||||
correct button mappings ourselves.
|
||||
|
||||
Original patch by Andrew Eikum <aeikum@codeweavers.com>.
|
||||
---
|
||||
dlls/winex11.drv/keyboard.c | 23 ++++++---
|
||||
dlls/winex11.drv/mouse.c | 89 +++++++++++++++++++++++++++++++++-
|
||||
dlls/winex11.drv/x11drv.h | 1 +
|
||||
dlls/winex11.drv/x11drv_main.c | 1 +
|
||||
4 files changed, 106 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
|
||||
index 7856b04c8f5..3f5d76be57b 100644
|
||||
--- a/dlls/winex11.drv/keyboard.c
|
||||
+++ b/dlls/winex11.drv/keyboard.c
|
||||
@@ -2010,13 +2010,24 @@ BOOL X11DRV_MappingNotify( HWND dummy, XEvent *event )
|
||||
{
|
||||
HWND hwnd;
|
||||
|
||||
- XRefreshKeyboardMapping(&event->xmapping);
|
||||
- X11DRV_InitKeyboard( event->xmapping.display );
|
||||
+ switch (event->xmapping.request)
|
||||
+ {
|
||||
+ case MappingModifier:
|
||||
+ case MappingKeyboard:
|
||||
+ XRefreshKeyboardMapping( &event->xmapping );
|
||||
+ X11DRV_InitKeyboard( event->xmapping.display );
|
||||
+
|
||||
+ hwnd = GetFocus();
|
||||
+ if (!hwnd) hwnd = GetActiveWindow();
|
||||
+ PostMessageW(hwnd, WM_INPUTLANGCHANGEREQUEST,
|
||||
+ 0 /*FIXME*/, (LPARAM)X11DRV_GetKeyboardLayout(0));
|
||||
+ break;
|
||||
+
|
||||
+ case MappingPointer:
|
||||
+ X11DRV_InitMouse( event->xmapping.display );
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- hwnd = GetFocus();
|
||||
- if (!hwnd) hwnd = GetActiveWindow();
|
||||
- PostMessageW(hwnd, WM_INPUTLANGCHANGEREQUEST,
|
||||
- 0 /*FIXME*/, (LPARAM)X11DRV_GetKeyboardLayout(0));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index 105db08a78a..19ed2a29287 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -25,6 +25,9 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/cursorfont.h>
|
||||
#include <stdarg.h>
|
||||
+#ifdef HAVE_X11_EXTENSIONS_XINPUT_H
|
||||
+#include <X11/extensions/XInput.h>
|
||||
+#endif
|
||||
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
@@ -143,6 +146,14 @@ MAKE_FUNCPTR(XISelectEvents);
|
||||
#undef MAKE_FUNCPTR
|
||||
#endif
|
||||
|
||||
+#ifdef HAVE_X11_EXTENSIONS_XINPUT_H
|
||||
+#define MAKE_FUNCPTR(f) static typeof(f) * p##f
|
||||
+MAKE_FUNCPTR(XOpenDevice);
|
||||
+MAKE_FUNCPTR(XCloseDevice);
|
||||
+MAKE_FUNCPTR(XGetDeviceButtonMapping);
|
||||
+#undef MAKE_FUNCPTR
|
||||
+#endif
|
||||
+
|
||||
/***********************************************************************
|
||||
* X11DRV_Xcursor_Init
|
||||
*
|
||||
@@ -249,6 +260,70 @@ void sync_window_cursor( Window window )
|
||||
set_window_cursor( window, cursor );
|
||||
}
|
||||
|
||||
+struct mouse_button_mapping
|
||||
+{
|
||||
+ int deviceid;
|
||||
+ unsigned int button_count;
|
||||
+ unsigned char buttons[256];
|
||||
+};
|
||||
+
|
||||
+static struct mouse_button_mapping *pointer_mapping;
|
||||
+static struct mouse_button_mapping *device_mapping;
|
||||
+
|
||||
+static void update_pointer_mapping( Display *display )
|
||||
+{
|
||||
+ struct mouse_button_mapping *tmp;
|
||||
+
|
||||
+ if (!(tmp = HeapAlloc( GetProcessHeap(), 0, sizeof(*tmp) )))
|
||||
+ {
|
||||
+ WARN("Unable to allocate device mapping.\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ tmp->button_count = ARRAY_SIZE( tmp->buttons );
|
||||
+ tmp->button_count = XGetPointerMapping( display, tmp->buttons, tmp->button_count );
|
||||
+
|
||||
+ tmp = InterlockedExchangePointer( (void**)&pointer_mapping, tmp );
|
||||
+
|
||||
+ HeapFree( GetProcessHeap(), 0, tmp );
|
||||
+}
|
||||
+
|
||||
+static void update_device_mapping( Display *display, int deviceid )
|
||||
+{
|
||||
+#ifdef HAVE_X11_EXTENSIONS_XINPUT_H
|
||||
+ struct mouse_button_mapping *tmp;
|
||||
+ XDevice *device;
|
||||
+
|
||||
+ if (!(device = pXOpenDevice( display, deviceid )))
|
||||
+ {
|
||||
+ WARN( "Unable to open cursor device %d\n", deviceid );
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!(tmp = HeapAlloc( GetProcessHeap(), 0, sizeof(*tmp) )))
|
||||
+ {
|
||||
+ WARN( "Unable to allocate device mapping.\n" );
|
||||
+ pXCloseDevice( display, device );
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ tmp->deviceid = deviceid;
|
||||
+ tmp->button_count = ARRAY_SIZE( tmp->buttons );
|
||||
+ tmp->button_count = pXGetDeviceButtonMapping( display, device, tmp->buttons, tmp->button_count );
|
||||
+
|
||||
+ tmp = InterlockedExchangePointer( (void**)&device_mapping, tmp );
|
||||
+
|
||||
+ HeapFree( GetProcessHeap(), 0, tmp );
|
||||
+
|
||||
+ pXCloseDevice( display, device );
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+void X11DRV_InitMouse( Display *display )
|
||||
+{
|
||||
+ update_pointer_mapping( display );
|
||||
+}
|
||||
+
|
||||
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
/***********************************************************************
|
||||
* update_relative_valuators
|
||||
@@ -1792,6 +1867,8 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev )
|
||||
if (event->reason != XISlaveSwitch) return FALSE;
|
||||
|
||||
update_relative_valuators( event->classes, event->num_classes );
|
||||
+ update_device_mapping( event->display, event->sourceid );
|
||||
+
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1861,13 +1938,12 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
|
||||
#endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */
|
||||
|
||||
-
|
||||
/***********************************************************************
|
||||
* X11DRV_XInput2_Init
|
||||
*/
|
||||
void X11DRV_XInput2_Init(void)
|
||||
{
|
||||
-#if defined(SONAME_LIBXI) && defined(HAVE_X11_EXTENSIONS_XINPUT2_H)
|
||||
+#if defined(SONAME_LIBXI)
|
||||
int event, error;
|
||||
void *libxi_handle = wine_dlopen( SONAME_LIBXI, RTLD_NOW, NULL, 0 );
|
||||
|
||||
@@ -1883,11 +1959,20 @@ void X11DRV_XInput2_Init(void)
|
||||
return; \
|
||||
}
|
||||
|
||||
+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
LOAD_FUNCPTR(XIGetClientPointer);
|
||||
LOAD_FUNCPTR(XIFreeDeviceInfo);
|
||||
LOAD_FUNCPTR(XIQueryDevice);
|
||||
LOAD_FUNCPTR(XIQueryVersion);
|
||||
LOAD_FUNCPTR(XISelectEvents);
|
||||
+#endif
|
||||
+
|
||||
+#ifdef HAVE_X11_EXTENSIONS_XINPUT_H
|
||||
+ LOAD_FUNCPTR(XOpenDevice);
|
||||
+ LOAD_FUNCPTR(XCloseDevice);
|
||||
+ LOAD_FUNCPTR(XGetDeviceButtonMapping);
|
||||
+#endif
|
||||
+
|
||||
#undef LOAD_FUNCPTR
|
||||
|
||||
xinput2_available = XQueryExtension( gdi_display, "XInputExtension", &xinput2_opcode, &event, &error );
|
||||
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
|
||||
index 432dd5909ca..7145fec74e7 100644
|
||||
--- a/dlls/winex11.drv/x11drv.h
|
||||
+++ b/dlls/winex11.drv/x11drv.h
|
||||
@@ -632,6 +632,7 @@ extern void retry_grab_clipping_window(void) DECLSPEC_HIDDEN;
|
||||
extern BOOL clip_fullscreen_window( HWND hwnd, BOOL reset ) DECLSPEC_HIDDEN;
|
||||
extern void move_resize_window( HWND hwnd, int dir ) DECLSPEC_HIDDEN;
|
||||
extern void X11DRV_InitKeyboard( Display *display ) DECLSPEC_HIDDEN;
|
||||
+extern void X11DRV_InitMouse( Display *display ) DECLSPEC_HIDDEN;
|
||||
extern DWORD CDECL X11DRV_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, DWORD timeout,
|
||||
DWORD mask, DWORD flags ) DECLSPEC_HIDDEN;
|
||||
|
||||
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
|
||||
index 11e4ee29155..ff9185a523c 100644
|
||||
--- a/dlls/winex11.drv/x11drv_main.c
|
||||
+++ b/dlls/winex11.drv/x11drv_main.c
|
||||
@@ -623,6 +623,7 @@ static BOOL process_attach(void)
|
||||
if (use_xkb) use_xkb = XkbUseExtension( gdi_display, NULL, NULL );
|
||||
#endif
|
||||
X11DRV_InitKeyboard( gdi_display );
|
||||
+ X11DRV_InitMouse( gdi_display );
|
||||
if (use_xim) use_xim = X11DRV_InitXIM( input_style );
|
||||
|
||||
X11DRV_DisplayDevices_Init(FALSE);
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,304 @@
|
||||
From e8b90f221774d70fb9510b6de18378ab3abdcad2 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Wed, 11 Sep 2019 10:15:20 +0200
|
||||
Subject: [PATCH 09/12] winex11.drv: Listen to RawMotion and RawButton* events
|
||||
in the desktop thread.
|
||||
|
||||
We still need to send "normal" input from the clipping window thread
|
||||
to trigger low-level hooks callbacks when clipping cursor. This is for
|
||||
instance used in our dinput implementation.
|
||||
---
|
||||
dlls/user32/tests/input.c | 8 ++--
|
||||
dlls/winex11.drv/event.c | 10 +++-
|
||||
dlls/winex11.drv/mouse.c | 88 ++++++++++++++++++++++++++++------
|
||||
dlls/winex11.drv/x11drv.h | 3 ++
|
||||
dlls/winex11.drv/x11drv_main.c | 4 ++
|
||||
5 files changed, 93 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
|
||||
index d18ccfebcaf..a1f983f1960 100644
|
||||
--- a/dlls/user32/tests/input.c
|
||||
+++ b/dlls/user32/tests/input.c
|
||||
@@ -2049,12 +2049,12 @@ static void test_rawinput_mouse(const char *argv0)
|
||||
{ TRUE, TRUE, 0, 2, 2, -1, -1, FALSE },
|
||||
|
||||
/* clip cursor tests */
|
||||
- { TRUE, TRUE, 0, 0, 0, 0, 0, TRUE },
|
||||
- { TRUE, TRUE, 0, 20, 20, 20, 20, TRUE },
|
||||
+ { TRUE, TRUE, 0, 0, 0, 0, 0, FALSE },
|
||||
+ { TRUE, TRUE, 0, 20, 20, 20, 20, FALSE },
|
||||
|
||||
/* same-process foreground tests */
|
||||
- { TRUE, TRUE, 0, 2, 2, 0, 0, TRUE },
|
||||
- { TRUE, TRUE, RIDEV_INPUTSINK, 2, 2, 0, 0, TRUE },
|
||||
+ { TRUE, TRUE, 0, 2, 2, 0, 0, FALSE },
|
||||
+ { TRUE, TRUE, RIDEV_INPUTSINK, 2, 2, 0, 0, FALSE },
|
||||
|
||||
/* cross-process foreground tests */
|
||||
{ TRUE, TRUE, 0, 0, 0, 0, 0, FALSE },
|
||||
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
|
||||
index 87ba808956f..b3faf3f7cc5 100644
|
||||
--- a/dlls/winex11.drv/event.c
|
||||
+++ b/dlls/winex11.drv/event.c
|
||||
@@ -321,6 +321,10 @@ static enum event_merge_action merge_raw_motion_events( XIRawEvent *prev, XIRawE
|
||||
*/
|
||||
static enum event_merge_action merge_events( XEvent *prev, XEvent *next )
|
||||
{
|
||||
+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
+ struct x11drv_thread_data *thread_data = x11drv_thread_data();
|
||||
+#endif
|
||||
+
|
||||
switch (prev->type)
|
||||
{
|
||||
case ConfigureNotify:
|
||||
@@ -352,19 +356,21 @@ static enum event_merge_action merge_events( XEvent *prev, XEvent *next )
|
||||
case GenericEvent:
|
||||
if (next->xcookie.extension != xinput2_opcode) break;
|
||||
if (next->xcookie.evtype != XI_RawMotion) break;
|
||||
- if (x11drv_thread_data()->warp_serial) break;
|
||||
+ if (thread_data->xi2_rawinput_only) break;
|
||||
+ if (thread_data->warp_serial) break;
|
||||
return MERGE_KEEP;
|
||||
}
|
||||
break;
|
||||
case GenericEvent:
|
||||
if (prev->xcookie.extension != xinput2_opcode) break;
|
||||
if (prev->xcookie.evtype != XI_RawMotion) break;
|
||||
+ if (thread_data->xi2_rawinput_only) break;
|
||||
switch (next->type)
|
||||
{
|
||||
case GenericEvent:
|
||||
if (next->xcookie.extension != xinput2_opcode) break;
|
||||
if (next->xcookie.evtype != XI_RawMotion) break;
|
||||
- if (x11drv_thread_data()->warp_serial) break;
|
||||
+ if (thread_data->warp_serial) break;
|
||||
return merge_raw_motion_events( prev->xcookie.data, next->xcookie.data );
|
||||
#endif
|
||||
}
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index 19ed2a29287..d331ed5aef8 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -364,9 +364,9 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
- * enable_xinput2
|
||||
+ * X11DRV_XInput2_Enable
|
||||
*/
|
||||
-static void enable_xinput2(void)
|
||||
+void X11DRV_XInput2_Enable(void)
|
||||
{
|
||||
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
struct x11drv_thread_data *data = x11drv_thread_data();
|
||||
@@ -398,9 +398,21 @@ static void enable_xinput2(void)
|
||||
mask.mask_len = sizeof(mask_bits);
|
||||
mask.deviceid = XIAllMasterDevices;
|
||||
memset( mask_bits, 0, sizeof(mask_bits) );
|
||||
+
|
||||
XISetMask( mask_bits, XI_DeviceChanged );
|
||||
XISetMask( mask_bits, XI_RawMotion );
|
||||
- XISetMask( mask_bits, XI_ButtonPress );
|
||||
+
|
||||
+ if (GetWindowThreadProcessId( GetDesktopWindow(), NULL ) == GetCurrentThreadId())
|
||||
+ {
|
||||
+ XISetMask( mask_bits, XI_RawButtonPress );
|
||||
+ XISetMask( mask_bits, XI_RawButtonRelease );
|
||||
+ data->xi2_rawinput_only = TRUE;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ XISetMask( mask_bits, XI_ButtonPress );
|
||||
+ data->xi2_rawinput_only = FALSE;
|
||||
+ }
|
||||
|
||||
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
|
||||
|
||||
@@ -413,9 +425,9 @@ static void enable_xinput2(void)
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
- * disable_xinput2
|
||||
+ * X11DRV_XInput2_Disable
|
||||
*/
|
||||
-static void disable_xinput2(void)
|
||||
+void X11DRV_XInput2_Disable(void)
|
||||
{
|
||||
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
struct x11drv_thread_data *data = x11drv_thread_data();
|
||||
@@ -475,7 +487,7 @@ static BOOL grab_clipping_window( const RECT *clip )
|
||||
}
|
||||
|
||||
/* enable XInput2 unless we are already clipping */
|
||||
- if (!data->clip_hwnd) enable_xinput2();
|
||||
+ if (!data->clip_hwnd) X11DRV_XInput2_Enable();
|
||||
|
||||
if (data->xi2_state != xi_enabled)
|
||||
{
|
||||
@@ -505,7 +517,7 @@ static BOOL grab_clipping_window( const RECT *clip )
|
||||
|
||||
if (!clipping_cursor)
|
||||
{
|
||||
- disable_xinput2();
|
||||
+ X11DRV_XInput2_Disable();
|
||||
DestroyWindow( msg_hwnd );
|
||||
return FALSE;
|
||||
}
|
||||
@@ -586,7 +598,7 @@ LRESULT clip_cursor_notify( HWND hwnd, HWND prev_clip_hwnd, HWND new_clip_hwnd )
|
||||
TRACE( "clip hwnd reset from %p\n", hwnd );
|
||||
data->clip_hwnd = 0;
|
||||
data->clip_reset = GetTickCount();
|
||||
- disable_xinput2();
|
||||
+ X11DRV_XInput2_Disable();
|
||||
DestroyWindow( hwnd );
|
||||
}
|
||||
else if (hwnd == GetForegroundWindow()) /* request to clip */
|
||||
@@ -725,7 +737,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
|
||||
}
|
||||
input->u.mi.dx += clip_rect.left;
|
||||
input->u.mi.dy += clip_rect.top;
|
||||
- __wine_send_input( hwnd, input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
+ __wine_send_input( hwnd, input, SEND_HWMSG_WINDOW );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -765,7 +777,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
|
||||
- __wine_send_input( hwnd, input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
+ __wine_send_input( hwnd, input, SEND_HWMSG_WINDOW );
|
||||
}
|
||||
|
||||
#ifdef SONAME_LIBXCURSOR
|
||||
@@ -1711,7 +1723,7 @@ void move_resize_window( HWND hwnd, int dir )
|
||||
input.u.mi.dwFlags = button_up_flags[button - 1] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
|
||||
input.u.mi.time = GetTickCount();
|
||||
input.u.mi.dwExtraInfo = 0;
|
||||
- __wine_send_input( hwnd, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
+ __wine_send_input( hwnd, &input, SEND_HWMSG_WINDOW );
|
||||
}
|
||||
|
||||
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
|
||||
@@ -1894,6 +1906,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
x_rel = &thread_data->x_rel_valuator;
|
||||
y_rel = &thread_data->y_rel_valuator;
|
||||
|
||||
+ input.type = INPUT_MOUSE;
|
||||
input.u.mi.mouseData = 0;
|
||||
input.u.mi.dwFlags = MOUSEEVENTF_MOVE;
|
||||
input.u.mi.time = EVENT_x11_time_to_win32_time( event->time );
|
||||
@@ -1929,10 +1942,53 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
|
||||
+ if (!thread_data->xi2_rawinput_only)
|
||||
+ {
|
||||
+ TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
|
||||
+ __wine_send_input( 0, &input, SEND_HWMSG_WINDOW );
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ TRACE( "raw pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
|
||||
+ __wine_send_input( 0, &input, SEND_HWMSG_RAWINPUT );
|
||||
+ }
|
||||
+ return TRUE;
|
||||
+}
|
||||
|
||||
- input.type = INPUT_MOUSE;
|
||||
- __wine_send_input( 0, &input, SEND_HWMSG_RAWINPUT|SEND_HWMSG_WINDOW );
|
||||
+/***********************************************************************
|
||||
+ * X11DRV_RawButtonEvent
|
||||
+ */
|
||||
+static BOOL X11DRV_RawButtonEvent( XGenericEventCookie *cookie )
|
||||
+{
|
||||
+ struct x11drv_thread_data *thread_data = x11drv_thread_data();
|
||||
+ XIRawEvent *event = cookie->data;
|
||||
+ int button = event->detail - 1;
|
||||
+ INPUT input;
|
||||
+
|
||||
+ if (!device_mapping || device_mapping->deviceid != event->sourceid)
|
||||
+ update_device_mapping( event->display, event->sourceid );
|
||||
+
|
||||
+ if (button >= 0 && device_mapping)
|
||||
+ button = device_mapping->buttons[button] - 1;
|
||||
+
|
||||
+ if (button >= 0 && pointer_mapping)
|
||||
+ button = pointer_mapping->buttons[button] - 1;
|
||||
+
|
||||
+ if (button < 0 || button >= NB_BUTTONS) return FALSE;
|
||||
+ if (thread_data->xi2_state != xi_enabled) return FALSE;
|
||||
+ if (event->deviceid != thread_data->xi2_core_pointer) return FALSE;
|
||||
+
|
||||
+ TRACE( "raw button %u (raw: %u) %s\n", button, event->detail, event->evtype == XI_RawButtonRelease ? "up" : "down" );
|
||||
+
|
||||
+ input.type = INPUT_MOUSE;
|
||||
+ input.u.mi.dx = 0;
|
||||
+ input.u.mi.dy = 0;
|
||||
+ input.u.mi.mouseData = event->evtype == XI_RawButtonRelease ? button_up_data[button] : button_down_data[button];
|
||||
+ input.u.mi.dwFlags = event->evtype == XI_RawButtonRelease ? button_up_flags[button] : button_down_flags[button];
|
||||
+ input.u.mi.time = EVENT_x11_time_to_win32_time(event->time);
|
||||
+ input.u.mi.dwExtraInfo = 0;
|
||||
+
|
||||
+ __wine_send_input( 0, &input, SEND_HWMSG_RAWINPUT );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -2008,6 +2064,10 @@ BOOL X11DRV_GenericEvent( HWND hwnd, XEvent *xev )
|
||||
case XI_RawMotion:
|
||||
ret = X11DRV_RawMotion( event );
|
||||
break;
|
||||
+ case XI_RawButtonPress:
|
||||
+ case XI_RawButtonRelease:
|
||||
+ ret = X11DRV_RawButtonEvent( event );
|
||||
+ break;
|
||||
|
||||
default:
|
||||
TRACE( "Unhandled event %#x\n", event->evtype );
|
||||
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
|
||||
index 7145fec74e7..4a7cab67ada 100644
|
||||
--- a/dlls/winex11.drv/x11drv.h
|
||||
+++ b/dlls/winex11.drv/x11drv.h
|
||||
@@ -196,6 +196,8 @@ extern BOOL CDECL X11DRV_UnrealizePalette( HPALETTE hpal ) DECLSPEC_HIDDEN;
|
||||
|
||||
extern void X11DRV_Xcursor_Init(void) DECLSPEC_HIDDEN;
|
||||
extern void X11DRV_XInput2_Init(void) DECLSPEC_HIDDEN;
|
||||
+extern void X11DRV_XInput2_Enable(void) DECLSPEC_HIDDEN;
|
||||
+extern void X11DRV_XInput2_Disable(void) DECLSPEC_HIDDEN;
|
||||
|
||||
extern DWORD copy_image_bits( BITMAPINFO *info, BOOL is_r8g8b8, XImage *image,
|
||||
const struct gdi_image_bits *src_bits, struct gdi_image_bits *dst_bits,
|
||||
@@ -343,6 +345,7 @@ struct x11drv_thread_data
|
||||
struct x11drv_valuator_data x_rel_valuator;
|
||||
struct x11drv_valuator_data y_rel_valuator;
|
||||
int xi2_core_pointer; /* XInput2 core pointer id */
|
||||
+ int xi2_rawinput_only;
|
||||
};
|
||||
|
||||
extern struct x11drv_thread_data *x11drv_init_thread_data(void) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
|
||||
index ff9185a523c..f33a79d98bf 100644
|
||||
--- a/dlls/winex11.drv/x11drv_main.c
|
||||
+++ b/dlls/winex11.drv/x11drv_main.c
|
||||
@@ -640,6 +640,8 @@ void CDECL X11DRV_ThreadDetach(void)
|
||||
|
||||
if (data)
|
||||
{
|
||||
+ if (GetWindowThreadProcessId( GetDesktopWindow(), NULL ) == GetCurrentThreadId())
|
||||
+ X11DRV_XInput2_Disable();
|
||||
if (data->xim) XCloseIM( data->xim );
|
||||
if (data->font_set) XFreeFontSet( data->display, data->font_set );
|
||||
XCloseDisplay( data->display );
|
||||
@@ -712,6 +714,8 @@ struct x11drv_thread_data *x11drv_init_thread_data(void)
|
||||
TlsSetValue( thread_data_tls_index, data );
|
||||
|
||||
if (use_xim) X11DRV_SetupXIM();
|
||||
+ if (GetWindowThreadProcessId( GetDesktopWindow(), NULL ) == GetCurrentThreadId())
|
||||
+ X11DRV_XInput2_Enable();
|
||||
|
||||
return data;
|
||||
}
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,204 @@
|
||||
From d4dd0d48cec74bd2185eae5a6020c026040c1319 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Mon, 26 Aug 2019 16:06:58 +0200
|
||||
Subject: [PATCH 10/12] user32: Implement GetRegisteredRawInputDevices.
|
||||
|
||||
---
|
||||
dlls/dinput8/tests/device.c | 13 ---------
|
||||
dlls/user32/rawinput.c | 55 +++++++++++++++++++++++++++++++++++--
|
||||
server/protocol.def | 6 ++++
|
||||
server/queue.c | 24 ++++++++++++++++
|
||||
4 files changed, 83 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c
|
||||
index bec2a6b863c..45fc2889066 100644
|
||||
--- a/dlls/dinput8/tests/device.c
|
||||
+++ b/dlls/dinput8/tests/device.c
|
||||
@@ -652,7 +652,6 @@ static void test_mouse_keyboard(void)
|
||||
|
||||
raw_devices_count = ARRAY_SIZE(raw_devices);
|
||||
GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
|
||||
- todo_wine
|
||||
ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
|
||||
|
||||
hr = IDirectInputDevice8_Acquire(di_keyboard);
|
||||
@@ -674,7 +673,6 @@ static void test_mouse_keyboard(void)
|
||||
ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
|
||||
raw_devices_count = ARRAY_SIZE(raw_devices);
|
||||
GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
|
||||
- todo_wine
|
||||
ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
|
||||
|
||||
if (raw_devices[0].hwndTarget != NULL)
|
||||
@@ -712,7 +710,6 @@ static void test_mouse_keyboard(void)
|
||||
ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
|
||||
raw_devices_count = ARRAY_SIZE(raw_devices);
|
||||
GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
|
||||
- todo_wine
|
||||
ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
|
||||
|
||||
/* expect dinput8 to take over any activated raw input devices */
|
||||
@@ -739,26 +736,18 @@ static void test_mouse_keyboard(void)
|
||||
raw_devices_count = ARRAY_SIZE(raw_devices);
|
||||
memset(raw_devices, 0, sizeof(raw_devices));
|
||||
hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
|
||||
- todo_wine
|
||||
ok(hr == 3, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].usUsage == 2, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage);
|
||||
todo_wine
|
||||
ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
|
||||
todo_wine
|
||||
ok(raw_devices[0].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
|
||||
- todo_wine
|
||||
ok(raw_devices[1].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage);
|
||||
- todo_wine
|
||||
ok(raw_devices[1].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage);
|
||||
ok(raw_devices[1].dwFlags == 0, "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags);
|
||||
- todo_wine
|
||||
ok(raw_devices[1].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[1].hwndTarget);
|
||||
- todo_wine
|
||||
ok(raw_devices[2].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage);
|
||||
- todo_wine
|
||||
ok(raw_devices[2].usUsage == 6, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage);
|
||||
todo_wine
|
||||
ok(raw_devices[2].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags);
|
||||
@@ -777,12 +766,10 @@ static void test_mouse_keyboard(void)
|
||||
hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
|
||||
todo_wine
|
||||
ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage);
|
||||
todo_wine
|
||||
ok(raw_devices[0].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage);
|
||||
ok(raw_devices[0].dwFlags == 0, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
|
||||
|
||||
IDirectInputDevice8_Release(di_mouse);
|
||||
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
|
||||
index 85ff0c5e809..3792360b057 100644
|
||||
--- a/dlls/user32/rawinput.c
|
||||
+++ b/dlls/user32/rawinput.c
|
||||
@@ -501,14 +501,65 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT
|
||||
return *data_size;
|
||||
}
|
||||
|
||||
+static int compare_raw_input_devices(const void *ap, const void *bp)
|
||||
+{
|
||||
+ const RAWINPUTDEVICE a = *(const RAWINPUTDEVICE *)ap;
|
||||
+ const RAWINPUTDEVICE b = *(const RAWINPUTDEVICE *)bp;
|
||||
+
|
||||
+ if (a.usUsagePage != b.usUsagePage) return a.usUsagePage - b.usUsagePage;
|
||||
+ if (a.usUsage != b.usUsage) return a.usUsage - b.usUsage;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/***********************************************************************
|
||||
* GetRegisteredRawInputDevices (USER32.@)
|
||||
*/
|
||||
UINT WINAPI DECLSPEC_HOTPATCH GetRegisteredRawInputDevices(RAWINPUTDEVICE *devices, UINT *device_count, UINT size)
|
||||
{
|
||||
- FIXME("devices %p, device_count %p, size %u stub!\n", devices, device_count, size);
|
||||
+ struct rawinput_device *d = NULL;
|
||||
+ unsigned int count = ~0U;
|
||||
|
||||
- return 0;
|
||||
+ TRACE("devices %p, device_count %p, size %u\n", devices, device_count, size);
|
||||
+
|
||||
+ if (!device_count)
|
||||
+ {
|
||||
+ SetLastError(ERROR_INVALID_PARAMETER);
|
||||
+ return ~0U;
|
||||
+ }
|
||||
+
|
||||
+ if (devices && !(d = HeapAlloc( GetProcessHeap(), 0, *device_count * sizeof(*d) )))
|
||||
+ return ~0U;
|
||||
+
|
||||
+ SERVER_START_REQ( get_rawinput_devices )
|
||||
+ {
|
||||
+ if (d)
|
||||
+ wine_server_set_reply( req, d, *device_count * sizeof(*d) );
|
||||
+
|
||||
+ if (wine_server_call( req ))
|
||||
+ goto done;
|
||||
+
|
||||
+ if (!d || reply->device_count > *device_count)
|
||||
+ {
|
||||
+ *device_count = reply->device_count;
|
||||
+ SetLastError( ERROR_INSUFFICIENT_BUFFER );
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ for (count = 0; count < reply->device_count; ++count)
|
||||
+ {
|
||||
+ devices[count].usUsagePage = d[count].usage_page;
|
||||
+ devices[count].usUsage = d[count].usage;
|
||||
+ devices[count].dwFlags = d[count].flags;
|
||||
+ devices[count].hwndTarget = wine_server_ptr_handle(d[count].target);
|
||||
+ }
|
||||
+ }
|
||||
+ SERVER_END_REQ;
|
||||
+
|
||||
+ qsort(devices, count, sizeof(*devices), compare_raw_input_devices);
|
||||
+
|
||||
+done:
|
||||
+ if (d) HeapFree( GetProcessHeap(), 0, d );
|
||||
+ return count;
|
||||
}
|
||||
|
||||
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index 9f9f9197134..d37dceba40c 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -3986,6 +3986,12 @@ struct handle_info
|
||||
VARARG(devices,rawinput_devices);
|
||||
@END
|
||||
|
||||
+/* Retrieve the list of registered rawinput devices */
|
||||
+@REQ(get_rawinput_devices)
|
||||
+@REPLY
|
||||
+ unsigned int device_count;
|
||||
+ VARARG(devices,rawinput_devices);
|
||||
+@END
|
||||
|
||||
/* Retrieve the suspended context of a thread */
|
||||
@REQ(get_suspend_context)
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index 2bdd099d1bb..8a1bbfff5aa 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -3382,3 +3382,27 @@ DECL_HANDLER(esync_msgwait)
|
||||
if (current->process->idle_event && !(queue->wake_mask & QS_SMRESULT))
|
||||
set_event( current->process->idle_event );
|
||||
}
|
||||
+
|
||||
+DECL_HANDLER(get_rawinput_devices)
|
||||
+{
|
||||
+ unsigned int device_count = list_count(¤t->process->rawinput_devices);
|
||||
+ struct rawinput_device *devices;
|
||||
+ struct rawinput_device_entry *e;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ reply->device_count = device_count;
|
||||
+ if (get_reply_max_size() / sizeof (*devices) < device_count)
|
||||
+ return;
|
||||
+
|
||||
+ if (!(devices = mem_alloc( device_count * sizeof (*devices) )))
|
||||
+ {
|
||||
+ set_error( STATUS_NO_MEMORY );
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ i = 0;
|
||||
+ LIST_FOR_EACH_ENTRY( e, ¤t->process->rawinput_devices, struct rawinput_device_entry, entry )
|
||||
+ devices[i++] = e->device;
|
||||
+
|
||||
+ set_reply_data_ptr( devices, device_count * sizeof (*devices) );
|
||||
+}
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,174 @@
|
||||
From 7f814cd77f1766b98318bbc8ea5fff241c20ec4b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Mon, 26 Aug 2019 16:06:59 +0200
|
||||
Subject: [PATCH 11/12] dinput8: Add support for dinput devices that use raw
|
||||
input interface.
|
||||
|
||||
This adds a global message window that will receive WM_INPUT messages,
|
||||
dispatched to every raw input device event_proc.
|
||||
|
||||
Devices that use raw input interface will not register low-level hooks
|
||||
anymore. They will also conflict with any raw input device registered
|
||||
outside of dinput, as exposed by the unit tests.
|
||||
---
|
||||
dlls/dinput/device_private.h | 3 ++
|
||||
dlls/dinput/dinput_main.c | 84 +++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 86 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
|
||||
index 114e3971ed8..9116aaeab66 100644
|
||||
--- a/dlls/dinput/device_private.h
|
||||
+++ b/dlls/dinput/device_private.h
|
||||
@@ -70,6 +70,9 @@ struct IDirectInputDeviceImpl
|
||||
int acquired;
|
||||
DI_EVENT_PROC event_proc; /* function to receive mouse & keyboard events */
|
||||
|
||||
+ BOOL use_raw_input; /* use raw input instead of low-level messages */
|
||||
+ RAWINPUTDEVICE raw_device; /* raw device to (un)register */
|
||||
+
|
||||
LPDIDEVICEOBJECTDATA data_queue; /* buffer for 'GetDeviceData'. */
|
||||
int queue_len; /* size of the queue - set in 'SetProperty' */
|
||||
int queue_head; /* position to write new event into queue */
|
||||
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
|
||||
index 4d2d4afe106..9e3b9f48250 100644
|
||||
--- a/dlls/dinput/dinput_main.c
|
||||
+++ b/dlls/dinput/dinput_main.c
|
||||
@@ -98,6 +98,10 @@ static const struct dinput_device *dinput_devices[] =
|
||||
|
||||
HINSTANCE DINPUT_instance;
|
||||
|
||||
+static ATOM di_em_win_class;
|
||||
+static const WCHAR di_em_winW[] = {'D','I','E','m','W','i','n',0};
|
||||
+static HWND di_em_win;
|
||||
+
|
||||
static BOOL check_hook_thread(void);
|
||||
static CRITICAL_SECTION dinput_hook_crit;
|
||||
static struct list direct_input_list = LIST_INIT( direct_input_list );
|
||||
@@ -626,6 +630,59 @@ static HRESULT WINAPI IDirectInputWImpl_QueryInterface(LPDIRECTINPUT7W iface, RE
|
||||
return IDirectInputAImpl_QueryInterface( &This->IDirectInput7A_iface, riid, ppobj );
|
||||
}
|
||||
|
||||
+static LRESULT WINAPI di_em_win_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
+{
|
||||
+ IDirectInputImpl *dinput;
|
||||
+
|
||||
+ TRACE( "%p %d %lx %lx\n", hwnd, msg, wparam, lparam );
|
||||
+
|
||||
+ if (msg == WM_INPUT)
|
||||
+ {
|
||||
+ EnterCriticalSection( &dinput_hook_crit );
|
||||
+ LIST_FOR_EACH_ENTRY( dinput, &direct_input_list, IDirectInputImpl, entry )
|
||||
+ {
|
||||
+ IDirectInputDeviceImpl *dev;
|
||||
+
|
||||
+ EnterCriticalSection( &dinput->crit );
|
||||
+ LIST_FOR_EACH_ENTRY( dev, &dinput->devices_list, IDirectInputDeviceImpl, entry )
|
||||
+ {
|
||||
+ if (dev->acquired && dev->event_proc && dev->use_raw_input)
|
||||
+ {
|
||||
+ TRACE("calling %p->%p (%lx %lx)\n", dev, dev->event_proc, wparam, lparam);
|
||||
+ dev->event_proc( &dev->IDirectInputDevice8A_iface, GET_RAWINPUT_CODE_WPARAM(wparam), lparam );
|
||||
+ }
|
||||
+ }
|
||||
+ LeaveCriticalSection( &dinput->crit );
|
||||
+ }
|
||||
+ LeaveCriticalSection( &dinput_hook_crit );
|
||||
+ }
|
||||
+
|
||||
+ return DefWindowProcW(hwnd, msg, wparam, lparam);
|
||||
+}
|
||||
+
|
||||
+static void register_di_em_win_class(void)
|
||||
+{
|
||||
+ static WNDCLASSEXW class;
|
||||
+
|
||||
+ ZeroMemory(&class, sizeof(class));
|
||||
+ class.cbSize = sizeof(class);
|
||||
+ class.lpfnWndProc = di_em_win_wndproc;
|
||||
+ class.hInstance = DINPUT_instance;
|
||||
+ class.lpszClassName = di_em_winW;
|
||||
+
|
||||
+ if (!(di_em_win_class = RegisterClassExW( &class )))
|
||||
+ WARN( "Unable to register message window class\n" );
|
||||
+}
|
||||
+
|
||||
+static void unregister_di_em_win_class(void)
|
||||
+{
|
||||
+ if (!di_em_win_class)
|
||||
+ return;
|
||||
+
|
||||
+ if (!UnregisterClassW( MAKEINTRESOURCEW( di_em_win_class ), DINPUT_instance ))
|
||||
+ WARN( "Unable to unregister message window class\n" );
|
||||
+}
|
||||
+
|
||||
static HRESULT initialize_directinput_instance(IDirectInputImpl *This, DWORD dwVersion)
|
||||
{
|
||||
if (!This->initialized)
|
||||
@@ -1695,7 +1752,7 @@ static LRESULT CALLBACK LL_hook_proc( int code, WPARAM wparam, LPARAM lparam )
|
||||
|
||||
EnterCriticalSection( &dinput->crit );
|
||||
LIST_FOR_EACH_ENTRY( dev, &dinput->devices_list, IDirectInputDeviceImpl, entry )
|
||||
- if (dev->acquired && dev->event_proc)
|
||||
+ if (dev->acquired && dev->event_proc && !dev->use_raw_input)
|
||||
{
|
||||
TRACE("calling %p->%p (%lx %lx)\n", dev, dev->event_proc, wparam, lparam);
|
||||
skip |= dev->event_proc( &dev->IDirectInputDevice8A_iface, wparam, lparam );
|
||||
@@ -1748,6 +1805,9 @@ static DWORD WINAPI hook_thread_proc(void *param)
|
||||
static HHOOK kbd_hook, mouse_hook;
|
||||
MSG msg;
|
||||
|
||||
+ di_em_win = CreateWindowW( MAKEINTRESOURCEW(di_em_win_class), di_em_winW,
|
||||
+ 0, 0, 0, 0, 0, HWND_MESSAGE, 0, DINPUT_instance, NULL );
|
||||
+
|
||||
/* Force creation of the message queue */
|
||||
PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE );
|
||||
SetEvent(param);
|
||||
@@ -1812,6 +1872,9 @@ static DWORD WINAPI hook_thread_proc(void *param)
|
||||
DispatchMessageW(&msg);
|
||||
}
|
||||
|
||||
+ DestroyWindow( di_em_win );
|
||||
+ di_em_win = NULL;
|
||||
+
|
||||
FreeLibraryAndExitThread(DINPUT_instance, 0);
|
||||
}
|
||||
|
||||
@@ -1893,6 +1956,23 @@ void check_dinput_hooks(LPDIRECTINPUTDEVICE8W iface, BOOL acquired)
|
||||
hook_thread_event = NULL;
|
||||
}
|
||||
|
||||
+ if (dev->use_raw_input)
|
||||
+ {
|
||||
+ if (acquired)
|
||||
+ {
|
||||
+ dev->raw_device.dwFlags = RIDEV_INPUTSINK;
|
||||
+ dev->raw_device.hwndTarget = di_em_win;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ dev->raw_device.dwFlags = RIDEV_REMOVE;
|
||||
+ dev->raw_device.hwndTarget = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (!RegisterRawInputDevices( &dev->raw_device, 1, sizeof(RAWINPUTDEVICE) ))
|
||||
+ WARN( "Unable to (un)register raw device %x:%x\n", dev->raw_device.usUsagePage, dev->raw_device.usUsage );
|
||||
+ }
|
||||
+
|
||||
PostThreadMessageW( hook_thread_id, WM_USER+0x10, 1, 0 );
|
||||
|
||||
LeaveCriticalSection(&dinput_hook_crit);
|
||||
@@ -1919,9 +1999,11 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved)
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(inst);
|
||||
DINPUT_instance = inst;
|
||||
+ register_di_em_win_class();
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
if (reserved) break;
|
||||
+ unregister_di_em_win_class();
|
||||
DeleteCriticalSection(&dinput_hook_crit);
|
||||
break;
|
||||
}
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,195 @@
|
||||
From 4994e308b4f1e21c0d84de23df8c655c4bc5bf9f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Mon, 26 Aug 2019 14:08:20 +0200
|
||||
Subject: [PATCH 12/12] dinput8: Use raw input interface for dinput8 mouse
|
||||
device.
|
||||
|
||||
---
|
||||
dlls/dinput/mouse.c | 117 +++++++++++++++++++++++++++++++++++-
|
||||
dlls/dinput8/tests/device.c | 10 +--
|
||||
2 files changed, 119 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c
|
||||
index 2e0101facec..b8b88f38c15 100644
|
||||
--- a/dlls/dinput/mouse.c
|
||||
+++ b/dlls/dinput/mouse.c
|
||||
@@ -246,6 +246,13 @@ static SysMouseImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
|
||||
list_add_tail(&dinput->devices_list, &newDevice->base.entry);
|
||||
LeaveCriticalSection(&dinput->crit);
|
||||
|
||||
+ if (dinput->dwVersion >= 0x0800)
|
||||
+ {
|
||||
+ newDevice->base.use_raw_input = TRUE;
|
||||
+ newDevice->base.raw_device.usUsagePage = 1; /* HID generic device page */
|
||||
+ newDevice->base.raw_device.usUsage = 2; /* HID generic mouse */
|
||||
+ }
|
||||
+
|
||||
return newDevice;
|
||||
|
||||
failed:
|
||||
@@ -318,7 +325,115 @@ static int dinput_mouse_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM
|
||||
{
|
||||
MSLLHOOKSTRUCT *hook = (MSLLHOOKSTRUCT *)lparam;
|
||||
SysMouseImpl* This = impl_from_IDirectInputDevice8A(iface);
|
||||
- int wdata = 0, inst_id = -1, ret = 0;
|
||||
+ int wdata = 0, inst_id = -1, ret = 0, i;
|
||||
+
|
||||
+ if (wparam == RIM_INPUT || wparam == RIM_INPUTSINK)
|
||||
+ {
|
||||
+ RAWINPUTHEADER raw_header;
|
||||
+ RAWINPUT raw_input;
|
||||
+ UINT size;
|
||||
+ POINT rel, pt;
|
||||
+
|
||||
+ static const USHORT mouse_button_flags[] =
|
||||
+ {
|
||||
+ RI_MOUSE_BUTTON_1_DOWN, RI_MOUSE_BUTTON_1_UP,
|
||||
+ RI_MOUSE_BUTTON_2_DOWN, RI_MOUSE_BUTTON_2_UP,
|
||||
+ RI_MOUSE_BUTTON_3_DOWN, RI_MOUSE_BUTTON_3_UP,
|
||||
+ RI_MOUSE_BUTTON_4_DOWN, RI_MOUSE_BUTTON_4_UP,
|
||||
+ RI_MOUSE_BUTTON_5_DOWN, RI_MOUSE_BUTTON_5_UP
|
||||
+ };
|
||||
+
|
||||
+ TRACE("(%p) wp %08lx, lp %08lx\n", iface, wparam, lparam);
|
||||
+
|
||||
+ size = sizeof(raw_header);
|
||||
+ if (GetRawInputData( (HRAWINPUT)lparam, RID_HEADER, &raw_header, &size, sizeof(RAWINPUTHEADER) ) != sizeof(raw_header))
|
||||
+ {
|
||||
+ WARN( "Unable to read raw input data header\n" );
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (raw_header.dwType != RIM_TYPEMOUSE)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (raw_header.dwSize > sizeof(raw_input))
|
||||
+ {
|
||||
+ WARN( "Unexpected size for mouse raw input data\n" );
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ size = raw_header.dwSize;
|
||||
+ if (GetRawInputData( (HRAWINPUT)lparam, RID_INPUT, &raw_input, &size, sizeof(RAWINPUTHEADER) ) != raw_header.dwSize )
|
||||
+ {
|
||||
+ WARN( "Unable to read raw input data\n" );
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (raw_input.data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP)
|
||||
+ FIXME( "Unimplemented MOUSE_VIRTUAL_DESKTOP flag\n" );
|
||||
+ if (raw_input.data.mouse.usFlags & MOUSE_ATTRIBUTES_CHANGED)
|
||||
+ FIXME( "Unimplemented MOUSE_ATTRIBUTES_CHANGED flag\n" );
|
||||
+
|
||||
+ EnterCriticalSection(&This->base.crit);
|
||||
+
|
||||
+ rel.x = raw_input.data.mouse.lLastX;
|
||||
+ rel.y = raw_input.data.mouse.lLastY;
|
||||
+ if (raw_input.data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE)
|
||||
+ {
|
||||
+ GetCursorPos(&pt);
|
||||
+ rel.x -= pt.x;
|
||||
+ rel.y -= pt.y;
|
||||
+ }
|
||||
+
|
||||
+ This->m_state.lX += rel.x;
|
||||
+ This->m_state.lY += rel.y;
|
||||
+
|
||||
+ if (This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS)
|
||||
+ {
|
||||
+ pt.x = This->m_state.lX;
|
||||
+ pt.y = This->m_state.lY;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ pt = rel;
|
||||
+ }
|
||||
+
|
||||
+ if (rel.x)
|
||||
+ queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS,
|
||||
+ pt.x, GetCurrentTime(), This->base.dinput->evsequence);
|
||||
+
|
||||
+ if (rel.y)
|
||||
+ queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS,
|
||||
+ pt.y, GetCurrentTime(), This->base.dinput->evsequence);
|
||||
+
|
||||
+ if (rel.x || rel.y)
|
||||
+ {
|
||||
+ if ((This->warp_override == WARP_FORCE_ON) ||
|
||||
+ (This->warp_override != WARP_DISABLE && (This->base.dwCoopLevel & DISCL_EXCLUSIVE)))
|
||||
+ This->need_warp = TRUE;
|
||||
+ }
|
||||
+
|
||||
+ if (raw_input.data.mouse.usButtonFlags & RI_MOUSE_WHEEL)
|
||||
+ {
|
||||
+ This->m_state.lZ += (wdata = (SHORT)raw_input.data.mouse.usButtonData);
|
||||
+ queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_Z_AXIS_INSTANCE) | DIDFT_RELAXIS,
|
||||
+ wdata, GetCurrentTime(), This->base.dinput->evsequence);
|
||||
+ ret = This->clipped;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(mouse_button_flags); ++i)
|
||||
+ {
|
||||
+ if (raw_input.data.mouse.usButtonFlags & mouse_button_flags[i])
|
||||
+ {
|
||||
+ This->m_state.rgbButtons[i / 2] = 0x80 - (i % 2) * 0x80;
|
||||
+ queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + (i / 2)) | DIDFT_PSHBUTTON,
|
||||
+ This->m_state.rgbButtons[i / 2], GetCurrentTime(), This->base.dinput->evsequence);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ LeaveCriticalSection(&This->base.crit);
|
||||
+
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
TRACE("msg %lx @ (%d %d)\n", wparam, hook->pt.x, hook->pt.y);
|
||||
|
||||
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c
|
||||
index 45fc2889066..42ba78707c6 100644
|
||||
--- a/dlls/dinput8/tests/device.c
|
||||
+++ b/dlls/dinput8/tests/device.c
|
||||
@@ -696,13 +696,9 @@ static void test_mouse_keyboard(void)
|
||||
raw_devices_count = ARRAY_SIZE(raw_devices);
|
||||
memset(raw_devices, 0, sizeof(raw_devices));
|
||||
hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
|
||||
- todo_wine
|
||||
ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].usUsage == 2, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
|
||||
todo_wine
|
||||
ok(raw_devices[0].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
|
||||
@@ -712,6 +708,9 @@ static void test_mouse_keyboard(void)
|
||||
GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE));
|
||||
ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count);
|
||||
|
||||
+ if (raw_devices[0].hwndTarget != NULL)
|
||||
+ di_hwnd = raw_devices[0].hwndTarget;
|
||||
+
|
||||
/* expect dinput8 to take over any activated raw input devices */
|
||||
raw_devices[0].usUsagePage = 0x01;
|
||||
raw_devices[0].usUsage = 0x05;
|
||||
@@ -739,9 +738,7 @@ static void test_mouse_keyboard(void)
|
||||
ok(hr == 3, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
|
||||
ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage);
|
||||
ok(raw_devices[0].usUsage == 2, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
|
||||
ok(raw_devices[1].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage);
|
||||
ok(raw_devices[1].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage);
|
||||
@@ -767,7 +764,6 @@ static void test_mouse_keyboard(void)
|
||||
todo_wine
|
||||
ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
|
||||
ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage);
|
||||
ok(raw_devices[0].dwFlags == 0, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
|
||||
ok(raw_devices[0].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
|
||||
--
|
||||
2.24.1
|
||||
|
2
patches/user32-rawinput-mouse/definition
Normal file
2
patches/user32-rawinput-mouse/definition
Normal file
@ -0,0 +1,2 @@
|
||||
Fixes: [42631] - user32: Add Raw Input support.
|
||||
Depends: winex11.drv-mouse-coorrds
|
@ -0,0 +1,44 @@
|
||||
From a4256a564e309ad44a8aa8e8571c69444de20bf9 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 19 Dec 2019 19:00:21 +0100
|
||||
Subject: [PATCH 1/4] dinput8/tests: Add test for DISCL_EXCLUSIVE flag
|
||||
interaction with rawinput.
|
||||
|
||||
---
|
||||
dlls/dinput8/tests/device.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c
|
||||
index 42ba78707c6..845146af023 100644
|
||||
--- a/dlls/dinput8/tests/device.c
|
||||
+++ b/dlls/dinput8/tests/device.c
|
||||
@@ -759,6 +759,26 @@ static void test_mouse_keyboard(void)
|
||||
todo_wine
|
||||
ok(raw_devices_count == 1, "Unexpected raw devices registered: %d\n", raw_devices_count);
|
||||
|
||||
+ IDirectInputDevice8_SetCooperativeLevel(di_mouse, hwnd, DISCL_FOREGROUND|DISCL_EXCLUSIVE);
|
||||
+ IDirectInputDevice8_SetCooperativeLevel(di_keyboard, hwnd, DISCL_FOREGROUND|DISCL_EXCLUSIVE);
|
||||
+
|
||||
+ hr = IDirectInputDevice8_Acquire(di_keyboard);
|
||||
+ ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
|
||||
+ hr = IDirectInputDevice8_Acquire(di_mouse);
|
||||
+ ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
|
||||
+ raw_devices_count = ARRAY_SIZE(raw_devices);
|
||||
+ memset(raw_devices, 0, sizeof(raw_devices));
|
||||
+ hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
|
||||
+ ok(hr == 3, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
|
||||
+ todo_wine
|
||||
+ ok(raw_devices[0].dwFlags == (RIDEV_CAPTUREMOUSE|RIDEV_NOLEGACY), "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
|
||||
+ todo_wine
|
||||
+ ok(raw_devices[2].dwFlags == (RIDEV_NOHOTKEYS|RIDEV_NOLEGACY), "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags);
|
||||
+ hr = IDirectInputDevice8_Unacquire(di_keyboard);
|
||||
+ ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
|
||||
+ hr = IDirectInputDevice8_Unacquire(di_mouse);
|
||||
+ ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
|
||||
+
|
||||
raw_devices_count = ARRAY_SIZE(raw_devices);
|
||||
hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
|
||||
todo_wine
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,75 @@
|
||||
From c39bb27347442d2d229d6e851c17094c086411d6 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dereklesho52@Gmail.com>
|
||||
Date: Tue, 25 Jun 2019 16:23:02 -0400
|
||||
Subject: [PATCH 2/4] user32: Add support for RIDEV_NOLEGACY flag in
|
||||
RegisterRawInputDevices.
|
||||
|
||||
---
|
||||
dlls/user32/rawinput.c | 2 +-
|
||||
server/queue.c | 9 +++++++++
|
||||
2 files changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
|
||||
index 3792360b057..8cf9f8ebf62 100644
|
||||
--- a/dlls/user32/rawinput.c
|
||||
+++ b/dlls/user32/rawinput.c
|
||||
@@ -283,7 +283,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)
|
||||
+ if (devices[i].dwFlags & ~(RIDEV_REMOVE|RIDEV_NOLEGACY))
|
||||
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 8a1bbfff5aa..f5dc06100d1 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -427,6 +427,9 @@ static void set_cursor_pos( struct desktop *desktop, int x, int y )
|
||||
static const struct hw_msg_source source = { IMDT_UNAVAILABLE, IMO_SYSTEM };
|
||||
struct message *msg;
|
||||
|
||||
+ if (current->process->rawinput_mouse &&
|
||||
+ current->process->rawinput_mouse->flags & RIDEV_NOLEGACY) return;
|
||||
+
|
||||
if (!(msg = alloc_hardware_message( 0, source, get_tick_count() ))) return;
|
||||
|
||||
msg->msg = WM_MOUSEMOVE;
|
||||
@@ -1793,6 +1796,7 @@ done:
|
||||
static int queue_mouse_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
|
||||
unsigned int origin, struct msg_queue *sender, unsigned int req_flags )
|
||||
{
|
||||
+ const struct rawinput_device *device;
|
||||
struct hardware_msg_data *msg_data;
|
||||
struct rawinput_message raw_msg;
|
||||
struct message *msg;
|
||||
@@ -1866,6 +1870,8 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
|
||||
if (!(req_flags & SEND_HWMSG_WINDOW))
|
||||
return 0;
|
||||
+ if ((device = current->process->rawinput_mouse) && (device->flags & RIDEV_NOLEGACY))
|
||||
+ return 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE( messages ); i++)
|
||||
{
|
||||
@@ -1901,6 +1907,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
unsigned int origin, struct msg_queue *sender, unsigned int req_flags )
|
||||
{
|
||||
struct hw_msg_source source = { IMDT_KEYBOARD, origin };
|
||||
+ const struct rawinput_device *device;
|
||||
struct hardware_msg_data *msg_data;
|
||||
struct rawinput_message raw_msg;
|
||||
struct message *msg;
|
||||
@@ -1996,6 +2003,8 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
|
||||
if (!(req_flags & SEND_HWMSG_WINDOW))
|
||||
return 0;
|
||||
+ if ((device = current->process->rawinput_kbd) && (device->flags & RIDEV_NOLEGACY))
|
||||
+ return 0;
|
||||
|
||||
if (!(msg = alloc_hardware_message( input->kbd.info, source, time ))) return 0;
|
||||
msg_data = msg->data;
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,28 @@
|
||||
From 1372e0e8582eeb423aa65deab17c52f4f5e153d0 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 19 Dec 2019 19:00:50 +0100
|
||||
Subject: [PATCH 3/4] dinput: Set RIDEV_INPUTSINK flag only when
|
||||
DISCL_BACKGROUND is requested.
|
||||
|
||||
---
|
||||
dlls/dinput/dinput_main.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
|
||||
index 9e3b9f48250..ef92a7d7c50 100644
|
||||
--- a/dlls/dinput/dinput_main.c
|
||||
+++ b/dlls/dinput/dinput_main.c
|
||||
@@ -1960,7 +1960,9 @@ void check_dinput_hooks(LPDIRECTINPUTDEVICE8W iface, BOOL acquired)
|
||||
{
|
||||
if (acquired)
|
||||
{
|
||||
- dev->raw_device.dwFlags = RIDEV_INPUTSINK;
|
||||
+ dev->raw_device.dwFlags = 0;
|
||||
+ if (dev->dwCoopLevel & DISCL_BACKGROUND)
|
||||
+ dev->raw_device.dwFlags |= RIDEV_INPUTSINK;
|
||||
dev->raw_device.hwndTarget = di_em_win;
|
||||
}
|
||||
else
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,40 @@
|
||||
From 68898282e49228e9a26328373b4cd661a86d7672 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 19 Dec 2019 19:30:49 +0100
|
||||
Subject: [PATCH 4/4] dinput: Set correct rawinput flags for DISCL_EXCLUSIVE.
|
||||
|
||||
---
|
||||
dlls/dinput/dinput_main.c | 4 ++++
|
||||
dlls/dinput8/tests/device.c | 1 -
|
||||
2 files changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
|
||||
index ef92a7d7c50..6a74b6da500 100644
|
||||
--- a/dlls/dinput/dinput_main.c
|
||||
+++ b/dlls/dinput/dinput_main.c
|
||||
@@ -1963,6 +1963,10 @@ void check_dinput_hooks(LPDIRECTINPUTDEVICE8W iface, BOOL acquired)
|
||||
dev->raw_device.dwFlags = 0;
|
||||
if (dev->dwCoopLevel & DISCL_BACKGROUND)
|
||||
dev->raw_device.dwFlags |= RIDEV_INPUTSINK;
|
||||
+ if ((dev->dwCoopLevel & DISCL_EXCLUSIVE) && dev->raw_device.usUsage == 2)
|
||||
+ dev->raw_device.dwFlags |= (RIDEV_CAPTUREMOUSE|RIDEV_NOLEGACY);
|
||||
+ if ((dev->dwCoopLevel & DISCL_EXCLUSIVE) && dev->raw_device.usUsage == 6)
|
||||
+ dev->raw_device.dwFlags |= (RIDEV_NOHOTKEYS|RIDEV_NOLEGACY);
|
||||
dev->raw_device.hwndTarget = di_em_win;
|
||||
}
|
||||
else
|
||||
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c
|
||||
index 845146af023..31220db220a 100644
|
||||
--- a/dlls/dinput8/tests/device.c
|
||||
+++ b/dlls/dinput8/tests/device.c
|
||||
@@ -770,7 +770,6 @@ static void test_mouse_keyboard(void)
|
||||
memset(raw_devices, 0, sizeof(raw_devices));
|
||||
hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
|
||||
ok(hr == 3, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
|
||||
- todo_wine
|
||||
ok(raw_devices[0].dwFlags == (RIDEV_CAPTUREMOUSE|RIDEV_NOLEGACY), "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
|
||||
todo_wine
|
||||
ok(raw_devices[2].dwFlags == (RIDEV_NOHOTKEYS|RIDEV_NOLEGACY), "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags);
|
||||
--
|
||||
2.24.1
|
||||
|
1
patches/user32-rawinput-nolegacy/definition
Normal file
1
patches/user32-rawinput-nolegacy/definition
Normal file
@ -0,0 +1 @@
|
||||
Depends: user32-rawinput-mouse
|
@ -1,61 +0,0 @@
|
||||
From c91add917b374a1dd98f07d4d3647295d4fd7f20 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dereklesho52@Gmail.com>
|
||||
Date: Tue, 25 Jun 2019 16:23:02 -0400
|
||||
Subject: [PATCH 01/11] user32: Add support for RIDEV_NOLEGACY flag.
|
||||
|
||||
Signed-off-by: Derek Lesho <dereklesho52@Gmail.com>
|
||||
---
|
||||
dlls/user32/rawinput.c | 2 +-
|
||||
server/queue.c | 9 +++++++++
|
||||
2 files changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
|
||||
index 94cf7a9a5d..661a0e3b25 100644
|
||||
--- a/dlls/user32/rawinput.c
|
||||
+++ b/dlls/user32/rawinput.c
|
||||
@@ -282,7 +282,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)
|
||||
+ if (devices[i].dwFlags & ~(RIDEV_REMOVE|RIDEV_NOLEGACY))
|
||||
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 b5e17be18f..7c3c7e5148 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -372,6 +372,9 @@ static void set_cursor_pos( struct desktop *desktop, int x, int y )
|
||||
static const struct hw_msg_source source = { IMDT_UNAVAILABLE, IMO_SYSTEM };
|
||||
struct message *msg;
|
||||
|
||||
+ if (current->process->rawinput_mouse &&
|
||||
+ current->process->rawinput_mouse->flags & RIDEV_NOLEGACY) return;
|
||||
+
|
||||
if (!(msg = alloc_hardware_message( 0, source, get_tick_count() ))) return;
|
||||
|
||||
msg->msg = WM_MOUSEMOVE;
|
||||
@@ -1670,6 +1673,9 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
queue_hardware_message( desktop, msg, 0 );
|
||||
}
|
||||
|
||||
+ if (device && device->flags & RIDEV_NOLEGACY)
|
||||
+ return FALSE;
|
||||
+
|
||||
for (i = 0; i < ARRAY_SIZE( messages ); i++)
|
||||
{
|
||||
if (!messages[i]) continue;
|
||||
@@ -1795,6 +1801,9 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
queue_hardware_message( desktop, msg, 0 );
|
||||
}
|
||||
|
||||
+ if (device && device->flags & RIDEV_NOLEGACY)
|
||||
+ return FALSE;
|
||||
+
|
||||
if (!(msg = alloc_hardware_message( input->kbd.info, source, time ))) return 0;
|
||||
msg_data = msg->data;
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
@ -1,165 +0,0 @@
|
||||
From 107e1c0afb7e4a6639726891df26a724ffda5f1e Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dereklesho52@Gmail.com>
|
||||
Date: Tue, 25 Jun 2019 20:47:20 -0400
|
||||
Subject: [PATCH 02/11] server: Move mouse raw-input message faking from user32
|
||||
to wineserver.
|
||||
|
||||
Signed-off-by: Derek Lesho <dereklesho52@Gmail.com>
|
||||
---
|
||||
dlls/user32/message.c | 46 +++----------------------------------------
|
||||
server/protocol.def | 9 +++++----
|
||||
server/queue.c | 46 +++++++++++++++++++++++++++++++++++++++++--
|
||||
3 files changed, 52 insertions(+), 49 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
|
||||
index 1336865112..cf0fbe2f0c 100644
|
||||
--- a/dlls/user32/message.c
|
||||
+++ b/dlls/user32/message.c
|
||||
@@ -2295,54 +2295,14 @@ static BOOL process_rawinput_message( MSG *msg, const struct hardware_msg_data *
|
||||
rawinput->header.dwType = msg_data->rawinput.type;
|
||||
if (msg_data->rawinput.type == RIM_TYPEMOUSE)
|
||||
{
|
||||
- static const unsigned int button_flags[] =
|
||||
- {
|
||||
- 0, /* MOUSEEVENTF_MOVE */
|
||||
- RI_MOUSE_LEFT_BUTTON_DOWN, /* MOUSEEVENTF_LEFTDOWN */
|
||||
- RI_MOUSE_LEFT_BUTTON_UP, /* MOUSEEVENTF_LEFTUP */
|
||||
- RI_MOUSE_RIGHT_BUTTON_DOWN, /* MOUSEEVENTF_RIGHTDOWN */
|
||||
- RI_MOUSE_RIGHT_BUTTON_UP, /* MOUSEEVENTF_RIGHTUP */
|
||||
- RI_MOUSE_MIDDLE_BUTTON_DOWN, /* MOUSEEVENTF_MIDDLEDOWN */
|
||||
- RI_MOUSE_MIDDLE_BUTTON_UP, /* MOUSEEVENTF_MIDDLEUP */
|
||||
- };
|
||||
- unsigned int i;
|
||||
-
|
||||
rawinput->header.dwSize = FIELD_OFFSET(RAWINPUT, data) + sizeof(RAWMOUSE);
|
||||
rawinput->header.hDevice = WINE_MOUSE_HANDLE;
|
||||
rawinput->header.wParam = 0;
|
||||
|
||||
rawinput->data.mouse.usFlags = MOUSE_MOVE_RELATIVE;
|
||||
- rawinput->data.mouse.u.s.usButtonFlags = 0;
|
||||
- rawinput->data.mouse.u.s.usButtonData = 0;
|
||||
- for (i = 1; i < ARRAY_SIZE(button_flags); ++i)
|
||||
- {
|
||||
- if (msg_data->flags & (1 << i))
|
||||
- rawinput->data.mouse.u.s.usButtonFlags |= button_flags[i];
|
||||
- }
|
||||
- if (msg_data->flags & MOUSEEVENTF_WHEEL)
|
||||
- {
|
||||
- rawinput->data.mouse.u.s.usButtonFlags |= RI_MOUSE_WHEEL;
|
||||
- rawinput->data.mouse.u.s.usButtonData = msg_data->rawinput.mouse.data;
|
||||
- }
|
||||
- if (msg_data->flags & MOUSEEVENTF_HWHEEL)
|
||||
- {
|
||||
- rawinput->data.mouse.u.s.usButtonFlags |= RI_MOUSE_HORIZONTAL_WHEEL;
|
||||
- rawinput->data.mouse.u.s.usButtonData = msg_data->rawinput.mouse.data;
|
||||
- }
|
||||
- if (msg_data->flags & MOUSEEVENTF_XDOWN)
|
||||
- {
|
||||
- if (msg_data->rawinput.mouse.data == XBUTTON1)
|
||||
- rawinput->data.mouse.u.s.usButtonFlags |= RI_MOUSE_BUTTON_4_DOWN;
|
||||
- else if (msg_data->rawinput.mouse.data == XBUTTON2)
|
||||
- rawinput->data.mouse.u.s.usButtonFlags |= RI_MOUSE_BUTTON_5_DOWN;
|
||||
- }
|
||||
- if (msg_data->flags & MOUSEEVENTF_XUP)
|
||||
- {
|
||||
- if (msg_data->rawinput.mouse.data == XBUTTON1)
|
||||
- rawinput->data.mouse.u.s.usButtonFlags |= RI_MOUSE_BUTTON_4_UP;
|
||||
- else if (msg_data->rawinput.mouse.data == XBUTTON2)
|
||||
- rawinput->data.mouse.u.s.usButtonFlags |= RI_MOUSE_BUTTON_5_UP;
|
||||
- }
|
||||
+
|
||||
+ rawinput->data.mouse.u.s.usButtonFlags = msg_data->rawinput.mouse.button_flags;
|
||||
+ rawinput->data.mouse.u.s.usButtonData = msg_data->rawinput.mouse.button_data;
|
||||
|
||||
rawinput->data.mouse.ulRawButtons = 0;
|
||||
rawinput->data.mouse.lLastX = msg_data->rawinput.mouse.x;
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index 6af0ae0cff..7346e6aa44 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -304,10 +304,11 @@ struct hardware_msg_data
|
||||
} kbd;
|
||||
struct
|
||||
{
|
||||
- int type; /* RIM_TYPEMOUSE */
|
||||
- int x; /* x coordinate */
|
||||
- int y; /* y coordinate */
|
||||
- unsigned int data; /* mouse data */
|
||||
+ int type; /* RIM_TYPEMOUSE */
|
||||
+ int x; /* x coordinate */
|
||||
+ int y; /* y coordinate */
|
||||
+ unsigned short button_flags; /* mouse button */
|
||||
+ unsigned short button_data; /* event details */
|
||||
} mouse;
|
||||
} rawinput;
|
||||
};
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index 7c3c7e5148..a85bb15227 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -1627,6 +1627,16 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
WM_MOUSEHWHEEL /* 0x1000 = MOUSEEVENTF_HWHEEL */
|
||||
};
|
||||
|
||||
+ static const unsigned int raw_button_flags[] = {
|
||||
+ 0, /* 0x0001 = MOUSEEVENTF_MOVE */
|
||||
+ RI_MOUSE_LEFT_BUTTON_DOWN, /* 0x0002 = MOUSEEVENTF_LEFTDOWN */
|
||||
+ RI_MOUSE_LEFT_BUTTON_UP, /* 0x0004 = MOUSEEVENTF_LEFTUP */
|
||||
+ RI_MOUSE_RIGHT_BUTTON_DOWN, /* 0x0008 = MOUSEEVENTF_RIGHTDOWN */
|
||||
+ RI_MOUSE_RIGHT_BUTTON_UP, /* 0x0010 = MOUSEEVENTF_RIGHTUP */
|
||||
+ RI_MOUSE_MIDDLE_BUTTON_DOWN, /* 0x0020 = MOUSEEVENTF_MIDDLEDOWN */
|
||||
+ RI_MOUSE_MIDDLE_BUTTON_UP, /* 0x0040 = MOUSEEVENTF_MIDDLEUP */
|
||||
+ };
|
||||
+
|
||||
desktop->cursor.last_change = get_tick_count();
|
||||
flags = input->mouse.flags;
|
||||
time = input->mouse.time;
|
||||
@@ -1664,11 +1674,43 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
msg->wparam = RIM_INPUT;
|
||||
msg->lparam = 0;
|
||||
|
||||
- msg_data->flags = flags;
|
||||
+ msg_data->flags = 0;
|
||||
msg_data->rawinput.type = RIM_TYPEMOUSE;
|
||||
msg_data->rawinput.mouse.x = x - desktop->cursor.x;
|
||||
msg_data->rawinput.mouse.y = y - desktop->cursor.y;
|
||||
- msg_data->rawinput.mouse.data = input->mouse.data;
|
||||
+ msg_data->rawinput.mouse.button_flags = 0;
|
||||
+ msg_data->rawinput.mouse.button_data = 0;
|
||||
+
|
||||
+ for (i = 1; i < ARRAY_SIZE(raw_button_flags); ++i)
|
||||
+ {
|
||||
+ if (flags & (1 << i))
|
||||
+ msg_data->rawinput.mouse.button_flags |= raw_button_flags[i];
|
||||
+ }
|
||||
+
|
||||
+ if (flags & MOUSEEVENTF_WHEEL)
|
||||
+ {
|
||||
+ msg_data->rawinput.mouse.button_flags |= RI_MOUSE_WHEEL;
|
||||
+ msg_data->rawinput.mouse.button_data = input->mouse.data;
|
||||
+ }
|
||||
+ if (flags & MOUSEEVENTF_HWHEEL)
|
||||
+ {
|
||||
+ msg_data->rawinput.mouse.button_flags |= RI_MOUSE_HORIZONTAL_WHEEL;
|
||||
+ msg_data->rawinput.mouse.button_data = input->mouse.data;
|
||||
+ }
|
||||
+ if (flags & MOUSEEVENTF_XDOWN)
|
||||
+ {
|
||||
+ if (input->mouse.data == XBUTTON1)
|
||||
+ msg_data->rawinput.mouse.button_flags |= RI_MOUSE_BUTTON_4_DOWN;
|
||||
+ else if (input->mouse.data == XBUTTON2)
|
||||
+ msg_data->rawinput.mouse.button_flags |= RI_MOUSE_BUTTON_5_DOWN;
|
||||
+ }
|
||||
+ if (flags & MOUSEEVENTF_XUP)
|
||||
+ {
|
||||
+ if (input->mouse.data == XBUTTON1)
|
||||
+ msg_data->rawinput.mouse.button_flags |= RI_MOUSE_BUTTON_4_UP;
|
||||
+ else if (input->mouse.data == XBUTTON2)
|
||||
+ msg_data->rawinput.mouse.button_flags |= RI_MOUSE_BUTTON_5_UP;
|
||||
+ }
|
||||
|
||||
queue_hardware_message( desktop, msg, 0 );
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
@ -1,210 +0,0 @@
|
||||
From 3757f19f58dcbf11648d602212f412d29dc37750 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dereklesho52@Gmail.com>
|
||||
Date: Tue, 25 Jun 2019 21:24:12 -0400
|
||||
Subject: [PATCH 03/11] server: Add request for sending native raw-input
|
||||
messages.
|
||||
|
||||
Signed-off-by: Derek Lesho <dereklesho52@Gmail.com>
|
||||
---
|
||||
dlls/user32/message.c | 2 +-
|
||||
server/protocol.def | 51 +++++++++++++++++++++++++++----------------
|
||||
server/queue.c | 49 +++++++++++++++++++++++++++++++++++++++++
|
||||
server/trace.c | 21 ++++++++++++++++++
|
||||
tools/make_requests | 1 +
|
||||
5 files changed, 104 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
|
||||
index cf0fbe2f0c..98d2c1d2c2 100644
|
||||
--- a/dlls/user32/message.c
|
||||
+++ b/dlls/user32/message.c
|
||||
@@ -2299,7 +2299,7 @@ static BOOL process_rawinput_message( MSG *msg, const struct hardware_msg_data *
|
||||
rawinput->header.hDevice = WINE_MOUSE_HANDLE;
|
||||
rawinput->header.wParam = 0;
|
||||
|
||||
- rawinput->data.mouse.usFlags = MOUSE_MOVE_RELATIVE;
|
||||
+ rawinput->data.mouse.usFlags = msg_data->rawinput.mouse.flags;
|
||||
|
||||
rawinput->data.mouse.u.s.usButtonFlags = msg_data->rawinput.mouse.button_flags;
|
||||
rawinput->data.mouse.u.s.usButtonData = msg_data->rawinput.mouse.button_data;
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index 7346e6aa44..451c9253ee 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -286,31 +286,39 @@ struct hw_msg_source
|
||||
unsigned int origin; /* source origin (IMO_* values) */
|
||||
};
|
||||
|
||||
+typedef 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 */
|
||||
+ unsigned short flags; /* event flags */
|
||||
+ int x; /* x coordinate */
|
||||
+ int y; /* y coordinate */
|
||||
+ unsigned short button_flags; /* mouse button */
|
||||
+ unsigned short button_data; /* event details */
|
||||
+ } mouse;
|
||||
+ struct
|
||||
+ {
|
||||
+ int type; /* RIM_TYPEHID */
|
||||
+ /* TODO: fill this in if/when necessary */
|
||||
+ } hid;
|
||||
+} hw_rawinput_t;
|
||||
+
|
||||
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 short button_flags; /* mouse button */
|
||||
- unsigned short button_data; /* event details */
|
||||
- } mouse;
|
||||
- } rawinput;
|
||||
+ hw_rawinput_t rawinput;
|
||||
};
|
||||
|
||||
struct callback_msg_data
|
||||
@@ -2318,6 +2326,11 @@ enum message_type
|
||||
#define SEND_HWMSG_INJECTED 0x01
|
||||
|
||||
|
||||
+@REQ(send_rawinput_message)
|
||||
+ hw_rawinput_t input;
|
||||
+@END
|
||||
+
|
||||
+
|
||||
/* Get a message from the current queue */
|
||||
@REQ(get_message)
|
||||
unsigned int flags; /* PM_* flags */
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index a85bb15227..f9787933f2 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -2421,6 +2421,55 @@ DECL_HANDLER(send_hardware_message)
|
||||
release_object( desktop );
|
||||
}
|
||||
|
||||
+/* send a hardware rawinput message to the queue thread */
|
||||
+DECL_HANDLER(send_rawinput_message)
|
||||
+{
|
||||
+ const struct rawinput_device *device;
|
||||
+ struct hardware_msg_data *msg_data;
|
||||
+ struct message *msg;
|
||||
+ struct desktop *desktop;
|
||||
+ struct hw_msg_source source = { IMDT_MOUSE, IMO_HARDWARE };
|
||||
+
|
||||
+ desktop = get_thread_desktop( current, 0 );
|
||||
+
|
||||
+ switch (req->input.type)
|
||||
+ {
|
||||
+ case RIM_TYPEMOUSE:
|
||||
+ if ((device = current->process->rawinput_mouse))
|
||||
+ {
|
||||
+ struct thread *thread = device->target ? get_window_thread( device->target ) : NULL;
|
||||
+ if ((current->queue->input != desktop->foreground_input) || (thread && thread != current))
|
||||
+ goto done;
|
||||
+
|
||||
+ if (!(msg = alloc_hardware_message( 0, source, 0 ))) goto done;
|
||||
+ msg_data = msg->data;
|
||||
+
|
||||
+ msg->win = device->target;
|
||||
+ msg->msg = WM_INPUT;
|
||||
+ msg->wparam = RIM_INPUT;
|
||||
+ msg->lparam = 0;
|
||||
+
|
||||
+ msg_data->flags = 0;
|
||||
+ msg_data->rawinput.type = RIM_TYPEMOUSE;
|
||||
+ msg_data->rawinput.mouse.x = req->input.mouse.x;
|
||||
+ msg_data->rawinput.mouse.y = req->input.mouse.y;
|
||||
+ msg_data->rawinput.mouse.button_flags = req->input.mouse.button_flags;
|
||||
+ msg_data->rawinput.mouse.button_data = req->input.mouse.button_data;
|
||||
+ msg_data->rawinput.mouse.flags = req->input.mouse.flags;
|
||||
+
|
||||
+ queue_hardware_message( desktop, msg, 0 );
|
||||
+
|
||||
+ done:
|
||||
+ if (thread) release_object( thread );
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ set_error( STATUS_INVALID_PARAMETER );
|
||||
+ }
|
||||
+
|
||||
+ release_object(desktop);
|
||||
+}
|
||||
+
|
||||
/* post a quit message to the current queue */
|
||||
DECL_HANDLER(post_quit_message)
|
||||
{
|
||||
diff --git a/server/trace.c b/server/trace.c
|
||||
index 615542cff5..c936c7e57a 100644
|
||||
--- a/server/trace.c
|
||||
+++ b/server/trace.c
|
||||
@@ -405,6 +405,27 @@ static void dump_hw_input( const char *prefix, const hw_input_t *input )
|
||||
}
|
||||
}
|
||||
|
||||
+static void dump_hw_rawinput( const char *prefix, const hw_rawinput_t *rawinput )
|
||||
+{
|
||||
+ switch (rawinput->type)
|
||||
+ {
|
||||
+ case RIM_TYPEMOUSE:
|
||||
+ fprintf( stderr, "%s{type=MOUSE,flags=%04hx,x=%d,y=%d,button_flags=%04hx,button_data=%04hx}",
|
||||
+ prefix, rawinput->mouse.flags, rawinput->mouse.x, rawinput->mouse.y,
|
||||
+ rawinput->mouse.button_flags, rawinput->mouse.button_data);
|
||||
+ break;
|
||||
+ case RIM_TYPEKEYBOARD:
|
||||
+ fprintf( stderr, "%s{type=KEYBOARD}\n", prefix);
|
||||
+ break;
|
||||
+ case RIM_TYPEHID:
|
||||
+ fprintf( stderr, "%s{type=HID}\n", prefix);
|
||||
+ break;
|
||||
+ default:
|
||||
+ fprintf( stderr, "%s{type=%04x}", prefix, rawinput->type);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void dump_luid( const char *prefix, const luid_t *luid )
|
||||
{
|
||||
fprintf( stderr, "%s%d.%u", prefix, luid->high_part, luid->low_part );
|
||||
diff --git a/tools/make_requests b/tools/make_requests
|
||||
index faeabe5852..a6f12af041 100755
|
||||
--- a/tools/make_requests
|
||||
+++ b/tools/make_requests
|
||||
@@ -53,6 +53,7 @@ my %formats =
|
||||
"ioctl_code_t" => [ 4, 4, "&dump_ioctl_code" ],
|
||||
"client_cpu_t" => [ 4, 4, "&dump_client_cpu" ],
|
||||
"hw_input_t" => [ 32, 8, "&dump_hw_input" ],
|
||||
+ "hw_rawinput_t" => [ 20, 4, "&dump_hw_rawinput" ]
|
||||
);
|
||||
|
||||
my @requests = ();
|
||||
--
|
||||
2.23.0
|
||||
|
@ -1,86 +0,0 @@
|
||||
From 8e384f61c8d864ee95892f250cd0f384ac98d587 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dereklesho52@Gmail.com>
|
||||
Date: Tue, 25 Jun 2019 21:28:54 -0400
|
||||
Subject: [PATCH 04/11] user32: Add helper for input drivers to submit native
|
||||
rawinput msgs.
|
||||
|
||||
Signed-off-by: Derek Lesho <dereklesho52@Gmail.com>
|
||||
---
|
||||
dlls/user32/input.c | 30 ++++++++++++++++++++++++++++++
|
||||
dlls/user32/user32.spec | 1 +
|
||||
include/winuser.h | 1 +
|
||||
3 files changed, 32 insertions(+)
|
||||
|
||||
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
|
||||
index 8b2ae805aa..9b9cc4f0d7 100644
|
||||
--- a/dlls/user32/input.c
|
||||
+++ b/dlls/user32/input.c
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
#define NONAMELESSUNION
|
||||
+#define NONAMELESSSTRUCT
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
@@ -129,6 +130,35 @@ BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input )
|
||||
return !status;
|
||||
}
|
||||
|
||||
+BOOL CDECL __wine_send_raw_input( const RAWINPUT *raw_input )
|
||||
+{
|
||||
+ NTSTATUS status;
|
||||
+
|
||||
+ SERVER_START_REQ( send_rawinput_message )
|
||||
+ {
|
||||
+ req->input.type = raw_input->header.dwType;
|
||||
+ switch (raw_input->header.dwType)
|
||||
+ {
|
||||
+ case RIM_TYPEMOUSE:
|
||||
+ if (raw_input->data.mouse.ulRawButtons ||
|
||||
+ raw_input->data.mouse.ulExtraInformation)
|
||||
+ FIXME("Unhandled parameters\n");
|
||||
+
|
||||
+ req->input.mouse.flags = raw_input->data.mouse.usFlags;
|
||||
+ req->input.mouse.x = raw_input->data.mouse.lLastX;
|
||||
+ req->input.mouse.y = raw_input->data.mouse.lLastY;
|
||||
+ req->input.mouse.button_flags = raw_input->data.mouse.u.s.usButtonFlags;
|
||||
+ req->input.mouse.button_data = raw_input->data.mouse.u.s.usButtonData;
|
||||
+ break;
|
||||
+ }
|
||||
+ status = wine_server_call( req );
|
||||
+ }
|
||||
+ SERVER_END_REQ;
|
||||
+
|
||||
+ if (status) SetLastError( RtlNtStatusToDosError(status) );
|
||||
+ return !status;
|
||||
+}
|
||||
+
|
||||
|
||||
/***********************************************************************
|
||||
* update_mouse_coords
|
||||
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec
|
||||
index f9a4ae26df..3311dcd685 100644
|
||||
--- a/dlls/user32/user32.spec
|
||||
+++ b/dlls/user32/user32.spec
|
||||
@@ -833,4 +833,5 @@
|
||||
# or 'wine_' (for user-visible functions) to avoid namespace conflicts.
|
||||
#
|
||||
@ cdecl __wine_send_input(long ptr)
|
||||
+@ cdecl __wine_send_raw_input(ptr)
|
||||
@ cdecl __wine_set_pixel_format(long long)
|
||||
diff --git a/include/winuser.h b/include/winuser.h
|
||||
index 51c73d25c2..259db275c4 100644
|
||||
--- a/include/winuser.h
|
||||
+++ b/include/winuser.h
|
||||
@@ -4390,6 +4390,7 @@ WORD WINAPI SYSTEM_KillSystemTimer( WORD );
|
||||
|
||||
#ifdef __WINESRC__
|
||||
WINUSERAPI BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input );
|
||||
+WINUSERAPI BOOL CDECL __wine_send_raw_input( const RAWINPUT *raw_input );
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
--
|
||||
2.23.0
|
||||
|
@ -1,45 +0,0 @@
|
||||
From 45b1aba399b89c20e93bc358dfba261e40fcf30b Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dereklesho52@Gmail.com>
|
||||
Date: Tue, 25 Jun 2019 21:58:34 -0400
|
||||
Subject: [PATCH 05/11] server: Don't emulate rawinput mouse events if native
|
||||
exist.
|
||||
|
||||
Signed-off-by: Derek Lesho <dereklesho52@Gmail.com>
|
||||
---
|
||||
server/queue.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index f9787933f2..060e73b819 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -1599,6 +1599,8 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static int emulate_raw_mouse = 1;
|
||||
+
|
||||
/* 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 )
|
||||
@@ -1664,7 +1666,8 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
y = desktop->cursor.y;
|
||||
}
|
||||
|
||||
- if ((device = current->process->rawinput_mouse))
|
||||
+ device = current->process->rawinput_mouse;
|
||||
+ if (device && emulate_raw_mouse)
|
||||
{
|
||||
if (!(msg = alloc_hardware_message( input->mouse.info, source, time ))) return 0;
|
||||
msg_data = msg->data;
|
||||
@@ -2435,6 +2438,7 @@ DECL_HANDLER(send_rawinput_message)
|
||||
switch (req->input.type)
|
||||
{
|
||||
case RIM_TYPEMOUSE:
|
||||
+ emulate_raw_mouse = 0;
|
||||
if ((device = current->process->rawinput_mouse))
|
||||
{
|
||||
struct thread *thread = device->target ? get_window_thread( device->target ) : NULL;
|
||||
--
|
||||
2.23.0
|
||||
|
@ -1,200 +0,0 @@
|
||||
From 73d2f9ea82a3897f7ba3f979b599ba0273d8f39d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Tue, 23 Jul 2019 14:10:44 +0200
|
||||
Subject: [PATCH 06/11] winex11.drv: Directly listen to master XInput2 devices
|
||||
if supported
|
||||
|
||||
Under XInput2 protocol version < 2.1, raw events should not be received
|
||||
if pointer grab is active. However slave device events are still
|
||||
received regardless of this specification and Wine implemented a
|
||||
workaround to get raw events during pointer grabs by listening to these
|
||||
slave device events.
|
||||
|
||||
By advertising to support XInput2 protocol version >= 2.1, where raw
|
||||
events are sent even during pointer grabs, it is possible to simplify
|
||||
the code by listening to master device events only.
|
||||
|
||||
Signed-off-by: Derek Lesho <dereklesho52@Gmail.com>
|
||||
---
|
||||
dlls/winex11.drv/event.c | 42 +-----------------------------
|
||||
dlls/winex11.drv/mouse.c | 56 +++++++++++++++++++++++++++++-----------
|
||||
2 files changed, 42 insertions(+), 56 deletions(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
|
||||
index 25730192d3..e31e2cc0c5 100644
|
||||
--- a/dlls/winex11.drv/event.c
|
||||
+++ b/dlls/winex11.drv/event.c
|
||||
@@ -274,46 +274,6 @@ enum event_merge_action
|
||||
MERGE_IGNORE /* ignore the new event, keep the old one */
|
||||
};
|
||||
|
||||
-/***********************************************************************
|
||||
- * merge_raw_motion_events
|
||||
- */
|
||||
-#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
-static enum event_merge_action merge_raw_motion_events( XIRawEvent *prev, XIRawEvent *next )
|
||||
-{
|
||||
- int i, j, k;
|
||||
- unsigned char mask;
|
||||
-
|
||||
- if (!prev->valuators.mask_len) return MERGE_HANDLE;
|
||||
- if (!next->valuators.mask_len) return MERGE_HANDLE;
|
||||
-
|
||||
- mask = prev->valuators.mask[0] | next->valuators.mask[0];
|
||||
- if (mask == next->valuators.mask[0]) /* keep next */
|
||||
- {
|
||||
- for (i = j = k = 0; i < 8; i++)
|
||||
- {
|
||||
- if (XIMaskIsSet( prev->valuators.mask, i ))
|
||||
- next->valuators.values[j] += prev->valuators.values[k++];
|
||||
- if (XIMaskIsSet( next->valuators.mask, i )) j++;
|
||||
- }
|
||||
- TRACE( "merging duplicate GenericEvent\n" );
|
||||
- return MERGE_DISCARD;
|
||||
- }
|
||||
- if (mask == prev->valuators.mask[0]) /* keep prev */
|
||||
- {
|
||||
- for (i = j = k = 0; i < 8; i++)
|
||||
- {
|
||||
- if (XIMaskIsSet( next->valuators.mask, i ))
|
||||
- prev->valuators.values[j] += next->valuators.values[k++];
|
||||
- if (XIMaskIsSet( prev->valuators.mask, i )) j++;
|
||||
- }
|
||||
- TRACE( "merging duplicate GenericEvent\n" );
|
||||
- return MERGE_IGNORE;
|
||||
- }
|
||||
- /* can't merge events with disjoint masks */
|
||||
- return MERGE_HANDLE;
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
/***********************************************************************
|
||||
* merge_events
|
||||
*
|
||||
@@ -365,7 +325,7 @@ static enum event_merge_action merge_events( XEvent *prev, XEvent *next )
|
||||
if (next->xcookie.extension != xinput2_opcode) break;
|
||||
if (next->xcookie.evtype != XI_RawMotion) break;
|
||||
if (x11drv_thread_data()->warp_serial) break;
|
||||
- return merge_raw_motion_events( prev->xcookie.data, next->xcookie.data );
|
||||
+ return MERGE_HANDLE;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index 15e5c04a41..23c7c6fb35 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -133,6 +133,8 @@ static Cursor create_cursor( HANDLE handle );
|
||||
|
||||
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
static BOOL xinput2_available;
|
||||
+static int xinput2_version_major = 2;
|
||||
+static int xinput2_version_minor = 1;
|
||||
static BOOL broken_rawevents;
|
||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
|
||||
MAKE_FUNCPTR(XIGetClientPointer);
|
||||
@@ -304,8 +306,11 @@ static void enable_xinput2(void)
|
||||
|
||||
if (data->xi2_state == xi_unknown)
|
||||
{
|
||||
- int major = 2, minor = 0;
|
||||
- if (!pXIQueryVersion( data->display, &major, &minor )) data->xi2_state = xi_disabled;
|
||||
+ if (!pXIQueryVersion( data->display, &xinput2_version_major, &xinput2_version_minor ))
|
||||
+ {
|
||||
+ TRACE( "XInput2 v%d.%d available\n", xinput2_version_major, xinput2_version_minor );
|
||||
+ data->xi2_state = xi_disabled;
|
||||
+ }
|
||||
else
|
||||
{
|
||||
data->xi2_state = xi_unavailable;
|
||||
@@ -317,11 +322,19 @@ static void enable_xinput2(void)
|
||||
|
||||
mask.mask = mask_bits;
|
||||
mask.mask_len = sizeof(mask_bits);
|
||||
- mask.deviceid = XIAllDevices;
|
||||
+ mask.deviceid = XIAllMasterDevices;
|
||||
memset( mask_bits, 0, sizeof(mask_bits) );
|
||||
- XISetMask( mask_bits, XI_DeviceChanged );
|
||||
XISetMask( mask_bits, XI_RawMotion );
|
||||
XISetMask( mask_bits, XI_ButtonPress );
|
||||
+ XISetMask( mask_bits, XI_DeviceChanged );
|
||||
+
|
||||
+ /* XInput 2.0 has a problematic behavior where master pointer will
|
||||
+ * not send raw events to the root window whenever a grab is active
|
||||
+ */
|
||||
+ if (xinput2_version_major == 2 && xinput2_version_minor == 0)
|
||||
+ {
|
||||
+ mask.deviceid = XIAllDevices;
|
||||
+ }
|
||||
|
||||
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
|
||||
|
||||
@@ -336,7 +349,7 @@ static void enable_xinput2(void)
|
||||
* safe to be obtained statically at enable_xinput2() time.
|
||||
*/
|
||||
if (data->xi2_devices) pXIFreeDeviceInfo( data->xi2_devices );
|
||||
- data->xi2_devices = pXIQueryDevice( data->display, XIAllDevices, &data->xi2_device_count );
|
||||
+ data->xi2_devices = pXIQueryDevice( data->display, mask.deviceid, &data->xi2_device_count );
|
||||
data->xi2_current_slave = 0;
|
||||
|
||||
data->xi2_state = xi_enabled;
|
||||
@@ -359,7 +372,13 @@ static void disable_xinput2(void)
|
||||
|
||||
mask.mask = NULL;
|
||||
mask.mask_len = 0;
|
||||
- mask.deviceid = XIAllDevices;
|
||||
+ mask.deviceid = XIAllMasterDevices;
|
||||
+
|
||||
+ /* XInput 2.0 has a problematic behavior where master pointer will
|
||||
+ * not send raw events to the root window whenever a grab is active
|
||||
+ */
|
||||
+ if (xinput2_version_major == 2 && xinput2_version_minor == 0)
|
||||
+ mask.deviceid = XIAllDevices;
|
||||
|
||||
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
|
||||
pXIFreeDeviceInfo( data->xi2_devices );
|
||||
@@ -1793,25 +1812,32 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
if (!event->valuators.mask_len) return FALSE;
|
||||
if (thread_data->xi2_state != xi_enabled) return FALSE;
|
||||
|
||||
- /* If there is no slave currently detected, no previous motion nor device
|
||||
- * change events were received. Look it up now on the device list in this
|
||||
- * case.
|
||||
- */
|
||||
- if (!thread_data->xi2_current_slave)
|
||||
+ if (xinput2_version_major == 2 && xinput2_version_minor == 0)
|
||||
{
|
||||
XIDeviceInfo *devices = thread_data->xi2_devices;
|
||||
|
||||
- for (i = 0; i < thread_data->xi2_device_count; i++)
|
||||
+ /* If there is no slave currently detected, no previous motion nor device
|
||||
+ * change events were received. Look it up now on the device list in this
|
||||
+ * case.
|
||||
+ */
|
||||
+ for (i = 0; !thread_data->xi2_current_slave && i < thread_data->xi2_device_count; i++)
|
||||
{
|
||||
if (devices[i].use != XISlavePointer) continue;
|
||||
if (devices[i].deviceid != event->deviceid) continue;
|
||||
if (devices[i].attachment != thread_data->xi2_core_pointer) continue;
|
||||
thread_data->xi2_current_slave = event->deviceid;
|
||||
- break;
|
||||
}
|
||||
- }
|
||||
|
||||
- if (event->deviceid != thread_data->xi2_current_slave) return FALSE;
|
||||
+ /* Only listen to slave device events on XInput == 2.0 */
|
||||
+ if (event->deviceid != thread_data->xi2_current_slave)
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* Only listen to master device events on XInput >= 2.1 */
|
||||
+ if (event->deviceid != thread_data->xi2_core_pointer)
|
||||
+ return FALSE;
|
||||
+ }
|
||||
|
||||
x_rel = &thread_data->x_rel_valuator;
|
||||
y_rel = &thread_data->y_rel_valuator;
|
||||
--
|
||||
2.23.0
|
||||
|
@ -1,316 +0,0 @@
|
||||
From c91c52063e8c06bc8e8788309ecb7dca70bc6b9a Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dereklesho52@Gmail.com>
|
||||
Date: Tue, 25 Jun 2019 22:37:34 -0400
|
||||
Subject: [PATCH 07/11] winex11.drv: Implement native mouse-movement raw-input
|
||||
using RawMotion.
|
||||
|
||||
Signed-off-by: Derek Lesho <dereklesho52@Gmail.com>
|
||||
---
|
||||
dlls/winex11.drv/mouse.c | 102 +++++++++++++++++++++++++++------
|
||||
dlls/winex11.drv/x11drv.h | 8 ++-
|
||||
dlls/winex11.drv/x11drv_main.c | 6 ++
|
||||
3 files changed, 97 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index 23c7c6fb35..212511fde8 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -262,6 +262,8 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
|
||||
|
||||
thread_data->x_rel_valuator.number = -1;
|
||||
thread_data->y_rel_valuator.number = -1;
|
||||
+ thread_data->x_abs_valuator.number = -1;
|
||||
+ thread_data->y_abs_valuator.number = -1;
|
||||
|
||||
for (i = 0; i < n_valuators; i++)
|
||||
{
|
||||
@@ -279,6 +281,16 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
|
||||
{
|
||||
valuator_data = &thread_data->y_rel_valuator;
|
||||
}
|
||||
+ else if (class->label == x11drv_atom( Abs_X ) ||
|
||||
+ (!class->label && class->number == 0 && class->mode == XIModeAbsolute))
|
||||
+ {
|
||||
+ valuator_data = &thread_data->x_abs_valuator;
|
||||
+ }
|
||||
+ else if (class->label == x11drv_atom( Abs_Y ) ||
|
||||
+ (!class->label && class->number == 1 && class->mode == XIModeAbsolute))
|
||||
+ {
|
||||
+ valuator_data = &thread_data->y_abs_valuator;
|
||||
+ }
|
||||
|
||||
if (valuator_data) {
|
||||
valuator_data->number = class->number;
|
||||
@@ -291,9 +303,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();
|
||||
@@ -324,8 +336,8 @@ 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 );
|
||||
XISetMask( mask_bits, XI_DeviceChanged );
|
||||
|
||||
/* XInput 2.0 has a problematic behavior where master pointer will
|
||||
@@ -357,15 +369,15 @@ 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();
|
||||
XIEventMask mask;
|
||||
|
||||
- if (data->xi2_state != xi_enabled) return;
|
||||
+ if (data->xi2_state < xi_enabled) return;
|
||||
|
||||
TRACE( "disabling\n" );
|
||||
data->xi2_state = xi_disabled;
|
||||
@@ -390,6 +402,21 @@ static void disable_xinput2(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
+static void use_xinput2_path(void)
|
||||
+{
|
||||
+ struct x11drv_thread_data *thread_data = x11drv_thread_data();
|
||||
+
|
||||
+ if (thread_data->xi2_state == xi_enabled)
|
||||
+ thread_data->xi2_state = xi_extra;
|
||||
+}
|
||||
+
|
||||
+static void disable_xinput2_path(void)
|
||||
+{
|
||||
+ struct x11drv_thread_data *thread_data = x11drv_thread_data();
|
||||
+
|
||||
+ if (thread_data->xi2_state == xi_extra)
|
||||
+ thread_data->xi2_state = xi_enabled;
|
||||
+}
|
||||
|
||||
/***********************************************************************
|
||||
* grab_clipping_window
|
||||
@@ -428,9 +455,9 @@ 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) use_xinput2_path();
|
||||
|
||||
- if (data->xi2_state != xi_enabled)
|
||||
+ if (data->xi2_state < xi_extra)
|
||||
{
|
||||
WARN( "XInput2 not supported, refusing to clip to %s\n", wine_dbgstr_rect(clip) );
|
||||
DestroyWindow( msg_hwnd );
|
||||
@@ -458,7 +485,7 @@ static BOOL grab_clipping_window( const RECT *clip )
|
||||
|
||||
if (!clipping_cursor)
|
||||
{
|
||||
- disable_xinput2();
|
||||
+ disable_xinput2_path();
|
||||
DestroyWindow( msg_hwnd );
|
||||
return FALSE;
|
||||
}
|
||||
@@ -539,7 +566,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();
|
||||
+ disable_xinput2_path();
|
||||
DestroyWindow( hwnd );
|
||||
}
|
||||
else if (hwnd == GetForegroundWindow()) /* request to clip */
|
||||
@@ -1801,16 +1828,20 @@ 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;
|
||||
INPUT input;
|
||||
+ RAWINPUT raw_input;
|
||||
int i;
|
||||
- double dx = 0, dy = 0, val;
|
||||
+ double dx = 0, dy = 0, raw_x = 0, raw_y = 0, val, raw_val;
|
||||
struct x11drv_thread_data *thread_data = x11drv_thread_data();
|
||||
- struct x11drv_valuator_data *x_rel, *y_rel;
|
||||
+ struct x11drv_valuator_data *x_rel, *y_rel, *x_abs, *y_abs;
|
||||
+
|
||||
+ if ((thread_data->x_rel_valuator.number < 0 || thread_data->y_rel_valuator.number < 0) &&
|
||||
+ (thread_data->x_abs_valuator.number < 0 || thread_data->y_abs_valuator.number < 0) return FALSE;
|
||||
|
||||
- if (thread_data->x_rel_valuator.number < 0 || thread_data->y_rel_valuator.number < 0) return FALSE;
|
||||
if (!event->valuators.mask_len) return FALSE;
|
||||
- if (thread_data->xi2_state != xi_enabled) return FALSE;
|
||||
+ if (thread_data->xi2_state < xi_enabled) return FALSE;
|
||||
|
||||
if (xinput2_version_major == 2 && xinput2_version_minor == 0)
|
||||
{
|
||||
@@ -1841,7 +1872,10 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
|
||||
x_rel = &thread_data->x_rel_valuator;
|
||||
y_rel = &thread_data->y_rel_valuator;
|
||||
+ x_abs = &thread_data->x_abs_valuator;
|
||||
+ y_abs = &thread_data->y_abs_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 );
|
||||
@@ -1849,18 +1883,31 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
input.u.mi.dx = 0;
|
||||
input.u.mi.dy = 0;
|
||||
|
||||
+ raw_input.header.dwType = RIM_TYPEMOUSE;
|
||||
+ raw_input.data.mouse.u.usButtonFlags = 0;
|
||||
+ raw_input.data.mouse.u.usButtonData = 0;
|
||||
+ raw_input.data.mouse.ulExtraInformation = 0;
|
||||
+ raw_input.data.mouse.ulRawButtons = 0;
|
||||
+ raw_input.data.mouse.usFlags = 0;
|
||||
+ raw_input.data.mouse.lLastX = 0;
|
||||
+ raw_input.data.mouse.lLastY = 0;
|
||||
+
|
||||
virtual_rect = get_virtual_screen_rect();
|
||||
|
||||
- for (i = 0; i <= max ( x_rel->number, y_rel->number ); i++)
|
||||
+ for (i = 0; i <= max(max(max( x_abs->number, y_abs->number), x_rel->number), y_rel->number); i++)
|
||||
{
|
||||
if (!XIMaskIsSet( event->valuators.mask, i )) continue;
|
||||
val = *values++;
|
||||
+ raw_val = *raw_values++;
|
||||
if (i == x_rel->number)
|
||||
{
|
||||
input.u.mi.dx = dx = val;
|
||||
if (x_rel->min < x_rel->max)
|
||||
input.u.mi.dx = val * (virtual_rect.right - virtual_rect.left)
|
||||
/ (x_rel->max - x_rel->min);
|
||||
+
|
||||
+ raw_input.data.mouse.usFlags = MOUSE_MOVE_RELATIVE;
|
||||
+ raw_input.data.mouse.lLastX = raw_x = raw_val;
|
||||
}
|
||||
if (i == y_rel->number)
|
||||
{
|
||||
@@ -1868,6 +1915,19 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
if (y_rel->min < y_rel->max)
|
||||
input.u.mi.dy = val * (virtual_rect.bottom - virtual_rect.top)
|
||||
/ (y_rel->max - y_rel->min);
|
||||
+
|
||||
+ raw_input.data.mouse.usFlags = MOUSE_MOVE_RELATIVE;
|
||||
+ raw_input.data.mouse.lLastY = raw_y = raw_val;
|
||||
+ }
|
||||
+ if (i == x_abs->number)
|
||||
+ {
|
||||
+ raw_input.data.mouse.usFlags = MOUSE_MOVE_ABSOLUTE | MOUSE_VIRTUAL_DESKTOP;
|
||||
+ raw_input.data.mouse.lLastX = raw_x = raw_val * (65536 / (x_abs->max - x_abs->min));
|
||||
+ }
|
||||
+ if (i == y_abs->number)
|
||||
+ {
|
||||
+ raw_input.data.mouse.usFlags = MOUSE_MOVE_ABSOLUTE | MOUSE_VIRTUAL_DESKTOP;
|
||||
+ raw_input.data.mouse.lLastY = raw_y = raw_val * (65536 / (y_abs->max - y_abs->min));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1877,10 +1937,16 @@ 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_state == xi_extra)
|
||||
+ {
|
||||
+ TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
|
||||
+ __wine_send_input( 0, &input );
|
||||
+ }
|
||||
+
|
||||
+ TRACE("raw %s event %f,%f\n",
|
||||
+ raw_input.data.mouse.usFlags ? "absolute" : "relative", raw_x, raw_y);
|
||||
+ __wine_send_raw_input( &raw_input );
|
||||
|
||||
- input.type = INPUT_MOUSE;
|
||||
- __wine_send_input( 0, &input );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
|
||||
index 135faa8989..e9d9514ee2 100644
|
||||
--- a/dlls/winex11.drv/x11drv.h
|
||||
+++ b/dlls/winex11.drv/x11drv.h
|
||||
@@ -194,6 +194,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,
|
||||
@@ -335,11 +337,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 */
|
||||
- enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled } xi2_state; /* XInput2 state */
|
||||
+ enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled, xi_extra } xi2_state; /* XInput2 state */
|
||||
void *xi2_devices; /* list of XInput2 devices (valid when state is enabled) */
|
||||
int xi2_device_count;
|
||||
struct x11drv_valuator_data x_rel_valuator;
|
||||
struct x11drv_valuator_data y_rel_valuator;
|
||||
+ struct x11drv_valuator_data x_abs_valuator;
|
||||
+ struct x11drv_valuator_data y_abs_valuator;
|
||||
int xi2_core_pointer; /* XInput2 core pointer id */
|
||||
int xi2_current_slave; /* Current slave driving the Core pointer */
|
||||
};
|
||||
@@ -426,6 +430,8 @@ enum x11drv_atoms
|
||||
XATOM_RAW_CAP_HEIGHT,
|
||||
XATOM_Rel_X,
|
||||
XATOM_Rel_Y,
|
||||
+ XATOM_Abs_X,
|
||||
+ XATOM_Abs_Y,
|
||||
XATOM_WM_PROTOCOLS,
|
||||
XATOM_WM_DELETE_WINDOW,
|
||||
XATOM_WM_STATE,
|
||||
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
|
||||
index 21807af3f1..fb25a45ae2 100644
|
||||
--- a/dlls/winex11.drv/x11drv_main.c
|
||||
+++ b/dlls/winex11.drv/x11drv_main.c
|
||||
@@ -120,6 +120,8 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
|
||||
"RAW_CAP_HEIGHT",
|
||||
"Rel X",
|
||||
"Rel Y",
|
||||
+ "Abs X",
|
||||
+ "Abs Y",
|
||||
"WM_PROTOCOLS",
|
||||
"WM_DELETE_WINDOW",
|
||||
"WM_STATE",
|
||||
@@ -611,6 +613,8 @@ void CDECL X11DRV_ThreadDetach(void)
|
||||
|
||||
if (data)
|
||||
{
|
||||
+ X11DRV_XInput2_Disable();
|
||||
+
|
||||
if (data->xim) XCloseIM( data->xim );
|
||||
if (data->font_set) XFreeFontSet( data->display, data->font_set );
|
||||
XCloseDisplay( data->display );
|
||||
@@ -681,6 +685,8 @@ struct x11drv_thread_data *x11drv_init_thread_data(void)
|
||||
|
||||
if (use_xim) X11DRV_SetupXIM();
|
||||
|
||||
+ X11DRV_XInput2_Enable();
|
||||
+
|
||||
return data;
|
||||
}
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
@ -1,234 +0,0 @@
|
||||
From f55c05132e87dd3e9436c68920ad512bdcfb8df8 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dereklesho52@Gmail.com>
|
||||
Date: Fri, 26 Jul 2019 17:37:19 -0400
|
||||
Subject: [PATCH 08/11] winex11.drv: Implement native mouse-button raw-input
|
||||
using RawButton*.
|
||||
|
||||
Signed-off-by: Derek Lesho <dereklesho52@Gmail.com>
|
||||
---
|
||||
dlls/winex11.drv/mouse.c | 97 +++++++++++++++++++++++++++++++---
|
||||
dlls/winex11.drv/x11drv.h | 3 ++
|
||||
dlls/winex11.drv/x11drv_main.c | 1 +
|
||||
3 files changed, 95 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index 212511fde8..1d9833b5c9 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -264,12 +264,21 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
|
||||
thread_data->y_rel_valuator.number = -1;
|
||||
thread_data->x_abs_valuator.number = -1;
|
||||
thread_data->y_abs_valuator.number = -1;
|
||||
+ thread_data->wheel_valuator.number = -1;
|
||||
+
|
||||
+ thread_data->xi2_wheel_multiplier = 0;
|
||||
|
||||
for (i = 0; i < n_valuators; i++)
|
||||
{
|
||||
XIValuatorClassInfo *class = (XIValuatorClassInfo *)valuators[i];
|
||||
+ XIScrollClassInfo *scroll_class = (XIScrollClassInfo *)valuators[i];
|
||||
struct x11drv_valuator_data *valuator_data = NULL;
|
||||
|
||||
+ if (valuators[i]->type == XIScrollClass)
|
||||
+ {
|
||||
+ if (scroll_class->scroll_type == XIScrollTypeVertical)
|
||||
+ thread_data->xi2_wheel_multiplier = -WHEEL_DELTA / scroll_class->increment;
|
||||
+ }
|
||||
if (valuators[i]->type != XIValuatorClass) continue;
|
||||
if (class->label == x11drv_atom( Rel_X ) ||
|
||||
(!class->label && class->number == 0 && class->mode == XIModeRelative))
|
||||
@@ -291,6 +300,11 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
|
||||
{
|
||||
valuator_data = &thread_data->y_abs_valuator;
|
||||
}
|
||||
+ else if (class->label == x11drv_atom( Rel_Vert_Scroll ) ||
|
||||
+ (!class->label && class->number == 3 && class->mode == XIModeRelative))
|
||||
+ {
|
||||
+ valuator_data = &thread_data->wheel_valuator;
|
||||
+ }
|
||||
|
||||
if (valuator_data) {
|
||||
valuator_data->number = class->number;
|
||||
@@ -339,6 +353,8 @@ void X11DRV_XInput2_Enable(void)
|
||||
XISetMask( mask_bits, XI_DeviceChanged );
|
||||
XISetMask( mask_bits, XI_RawMotion );
|
||||
XISetMask( mask_bits, XI_DeviceChanged );
|
||||
+ XISetMask( mask_bits, XI_RawButtonPress );
|
||||
+ XISetMask( mask_bits, XI_RawButtonRelease );
|
||||
|
||||
/* XInput 2.0 has a problematic behavior where master pointer will
|
||||
* not send raw events to the root window whenever a grab is active
|
||||
@@ -396,6 +412,7 @@ void X11DRV_XInput2_Disable(void)
|
||||
pXIFreeDeviceInfo( data->xi2_devices );
|
||||
data->x_rel_valuator.number = -1;
|
||||
data->y_rel_valuator.number = -1;
|
||||
+ data->wheel_valuator.number = -1;
|
||||
data->xi2_devices = NULL;
|
||||
data->xi2_core_pointer = 0;
|
||||
data->xi2_current_slave = 0;
|
||||
@@ -1833,12 +1850,13 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
INPUT input;
|
||||
RAWINPUT raw_input;
|
||||
int i;
|
||||
- double dx = 0, dy = 0, raw_x = 0, raw_y = 0, val, raw_val;
|
||||
+ double dx = 0, dy = 0, raw_x = 0, raw_y = 0, raw_dwheel = 0, val, raw_val;
|
||||
struct x11drv_thread_data *thread_data = x11drv_thread_data();
|
||||
- struct x11drv_valuator_data *x_rel, *y_rel, *x_abs, *y_abs;
|
||||
+ struct x11drv_valuator_data *x_rel, *y_rel, *x_abs, *y_abs, *wheel;
|
||||
|
||||
if ((thread_data->x_rel_valuator.number < 0 || thread_data->y_rel_valuator.number < 0) &&
|
||||
- (thread_data->x_abs_valuator.number < 0 || thread_data->y_abs_valuator.number < 0) return FALSE;
|
||||
+ (thread_data->x_abs_valuator.number < 0 || thread_data->y_abs_valuator.number < 0) &&
|
||||
+ thread_data->wheel_valuator.number < 0) return FALSE;
|
||||
|
||||
if (!event->valuators.mask_len) return FALSE;
|
||||
if (thread_data->xi2_state < xi_enabled) return FALSE;
|
||||
@@ -1874,6 +1892,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
y_rel = &thread_data->y_rel_valuator;
|
||||
x_abs = &thread_data->x_abs_valuator;
|
||||
y_abs = &thread_data->y_abs_valuator;
|
||||
+ wheel = &thread_data->wheel_valuator;
|
||||
|
||||
input.type = INPUT_MOUSE;
|
||||
input.u.mi.mouseData = 0;
|
||||
@@ -1894,7 +1913,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
|
||||
virtual_rect = get_virtual_screen_rect();
|
||||
|
||||
- for (i = 0; i <= max(max(max( x_abs->number, y_abs->number), x_rel->number), y_rel->number); i++)
|
||||
+ for (i = 0; i <= max(max(max(max(x_abs->number, y_abs->number), x_rel->number), y_rel->number), wheel->number); i++)
|
||||
{
|
||||
if (!XIMaskIsSet( event->valuators.mask, i )) continue;
|
||||
val = *values++;
|
||||
@@ -1929,6 +1948,10 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
raw_input.data.mouse.usFlags = MOUSE_MOVE_ABSOLUTE | MOUSE_VIRTUAL_DESKTOP;
|
||||
raw_input.data.mouse.lLastY = raw_y = raw_val * (65536 / (y_abs->max - y_abs->min));
|
||||
}
|
||||
+ if (i == wheel->number)
|
||||
+ {
|
||||
+ raw_dwheel = raw_val * thread_data->xi2_wheel_multiplier;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (broken_rawevents && is_old_motion_event( xev->serial ))
|
||||
@@ -1943,13 +1966,70 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
__wine_send_input( 0, &input );
|
||||
}
|
||||
|
||||
- TRACE("raw %s event %f,%f\n",
|
||||
- raw_input.data.mouse.usFlags ? "absolute" : "relative", raw_x, raw_y);
|
||||
+ if (raw_dwheel)
|
||||
+ {
|
||||
+ raw_input.data.mouse.u.usButtonFlags = RI_MOUSE_WHEEL;
|
||||
+ raw_input.data.mouse.u.usButtonData = raw_dwheel;
|
||||
+ }
|
||||
+
|
||||
+ TRACE("raw %s event %f,%f + %f\n",
|
||||
+ raw_input.data.mouse.usFlags ? "absolute" : "relative", raw_x, raw_y, raw_dwheel);
|
||||
__wine_send_raw_input( &raw_input );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+/***********************************************************************
|
||||
+ * X11DRV_RawButton
|
||||
+ */
|
||||
+static BOOL X11DRV_RawButton( XGenericEventCookie *xev )
|
||||
+{
|
||||
+ RAWINPUT ri;
|
||||
+
|
||||
+ static const unsigned short raw_button_press_flags[] = {
|
||||
+ 0, /* 0 = unused */
|
||||
+ RI_MOUSE_LEFT_BUTTON_DOWN, /* 1 */
|
||||
+ RI_MOUSE_MIDDLE_BUTTON_DOWN, /* 2 */
|
||||
+ RI_MOUSE_RIGHT_BUTTON_DOWN, /* 3 */
|
||||
+ 0, /* 4 = unknown */
|
||||
+ 0, /* 5 = unknown */
|
||||
+ 0, /* 6 = unknown */
|
||||
+ 0, /* 7 = unknown */
|
||||
+ RI_MOUSE_BUTTON_4_DOWN, /* 8 */
|
||||
+ RI_MOUSE_BUTTON_5_DOWN /* 9 */
|
||||
+ };
|
||||
+
|
||||
+ static const unsigned short raw_button_release_flags[] = {
|
||||
+ 0, /* 0 = unused */
|
||||
+ RI_MOUSE_LEFT_BUTTON_UP, /* 1 */
|
||||
+ RI_MOUSE_MIDDLE_BUTTON_UP, /* 2 */
|
||||
+ RI_MOUSE_RIGHT_BUTTON_UP, /* 3 */
|
||||
+ 0, /* 4 = unknown */
|
||||
+ 0, /* 5 = unknown */
|
||||
+ 0, /* 6 = unknown */
|
||||
+ 0, /* 7 = unknown */
|
||||
+ RI_MOUSE_BUTTON_4_UP, /* 8 */
|
||||
+ RI_MOUSE_BUTTON_5_UP /* 9 */
|
||||
+ };
|
||||
+
|
||||
+ int detail = ((XIRawEvent*)xev->data)->detail;
|
||||
+ if (detail > 9) return TRUE;
|
||||
+
|
||||
+ ri.header.dwType = RIM_TYPEMOUSE;
|
||||
+ ri.data.mouse.u.usButtonFlags = xev->evtype == XI_RawButtonPress ? raw_button_press_flags[detail] : raw_button_release_flags[detail] ;
|
||||
+ ri.data.mouse.u.usButtonData = 0;
|
||||
+ ri.data.mouse.lLastX = 0;
|
||||
+ ri.data.mouse.lLastY = 0;
|
||||
+ ri.data.mouse.usFlags = 0;
|
||||
+ ri.data.mouse.ulRawButtons = 0;
|
||||
+ ri.data.mouse.ulExtraInformation = 0;
|
||||
+
|
||||
+ if (ri.data.mouse.u.usButtonFlags)
|
||||
+ __wine_send_raw_input( &ri );
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
#endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */
|
||||
|
||||
|
||||
@@ -2014,6 +2094,11 @@ BOOL X11DRV_GenericEvent( HWND hwnd, XEvent *xev )
|
||||
case XI_RawMotion:
|
||||
ret = X11DRV_RawMotion( event );
|
||||
break;
|
||||
+ case XI_RawButtonPress:
|
||||
+ /* fall through */
|
||||
+ case XI_RawButtonRelease:
|
||||
+ ret = X11DRV_RawButton( 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 e9d9514ee2..599ed48154 100644
|
||||
--- a/dlls/winex11.drv/x11drv.h
|
||||
+++ b/dlls/winex11.drv/x11drv.h
|
||||
@@ -344,6 +344,8 @@ struct x11drv_thread_data
|
||||
struct x11drv_valuator_data y_rel_valuator;
|
||||
struct x11drv_valuator_data x_abs_valuator;
|
||||
struct x11drv_valuator_data y_abs_valuator;
|
||||
+ struct x11drv_valuator_data wheel_valuator;
|
||||
+ double xi2_wheel_multiplier;
|
||||
int xi2_core_pointer; /* XInput2 core pointer id */
|
||||
int xi2_current_slave; /* Current slave driving the Core pointer */
|
||||
};
|
||||
@@ -432,6 +434,7 @@ enum x11drv_atoms
|
||||
XATOM_Rel_Y,
|
||||
XATOM_Abs_X,
|
||||
XATOM_Abs_Y,
|
||||
+ XATOM_Rel_Vert_Scroll,
|
||||
XATOM_WM_PROTOCOLS,
|
||||
XATOM_WM_DELETE_WINDOW,
|
||||
XATOM_WM_STATE,
|
||||
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
|
||||
index fb25a45ae2..05a445a9c1 100644
|
||||
--- a/dlls/winex11.drv/x11drv_main.c
|
||||
+++ b/dlls/winex11.drv/x11drv_main.c
|
||||
@@ -122,6 +122,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
|
||||
"Rel Y",
|
||||
"Abs X",
|
||||
"Abs Y",
|
||||
+ "Rel Vert Scroll",
|
||||
"WM_PROTOCOLS",
|
||||
"WM_DELETE_WINDOW",
|
||||
"WM_STATE",
|
||||
--
|
||||
2.23.0
|
||||
|
@ -1,121 +0,0 @@
|
||||
From 5c4db171dc87400ecd3e57b7efff805032328b5f Mon Sep 17 00:00:00 2001
|
||||
From: Jordan Galby <gravemind2a+wine@gmail.com>
|
||||
Date: Tue, 16 Jul 2019 00:34:38 -0400
|
||||
Subject: [PATCH 09/11] winex11.drv: Don't react to small slow mouse movements.
|
||||
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=42631
|
||||
From: Jordan Galby <gravemind2a+wine@gmail.com>
|
||||
Signed-off-by: Derek Lesho <dereklesho52@Gmail.com>
|
||||
---
|
||||
dlls/winex11.drv/mouse.c | 51 +++++++++++++++++++++++++++++++--------
|
||||
dlls/winex11.drv/x11drv.h | 1 +
|
||||
2 files changed, 42 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index 1d9833b5c9..1b109c8d1a 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -266,6 +266,10 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
|
||||
thread_data->y_abs_valuator.number = -1;
|
||||
thread_data->wheel_valuator.number = -1;
|
||||
|
||||
+ thread_data->x_rel_valuator.accum = 0;
|
||||
+ thread_data->y_rel_valuator.accum = 0;
|
||||
+ thread_data->wheel_valuator.accum = 0;
|
||||
+
|
||||
thread_data->xi2_wheel_multiplier = 0;
|
||||
|
||||
for (i = 0; i < n_valuators; i++)
|
||||
@@ -1920,9 +1924,9 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
raw_val = *raw_values++;
|
||||
if (i == x_rel->number)
|
||||
{
|
||||
- input.u.mi.dx = dx = val;
|
||||
+ dx = val;
|
||||
if (x_rel->min < x_rel->max)
|
||||
- input.u.mi.dx = val * (virtual_rect.right - virtual_rect.left)
|
||||
+ dx = val * (virtual_rect.right - virtual_rect.left)
|
||||
/ (x_rel->max - x_rel->min);
|
||||
|
||||
raw_input.data.mouse.usFlags = MOUSE_MOVE_RELATIVE;
|
||||
@@ -1930,9 +1934,9 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
}
|
||||
if (i == y_rel->number)
|
||||
{
|
||||
- input.u.mi.dy = dy = val;
|
||||
+ dy = val;
|
||||
if (y_rel->min < y_rel->max)
|
||||
- input.u.mi.dy = val * (virtual_rect.bottom - virtual_rect.top)
|
||||
+ dy = val * (virtual_rect.bottom - virtual_rect.top)
|
||||
/ (y_rel->max - y_rel->min);
|
||||
|
||||
raw_input.data.mouse.usFlags = MOUSE_MOVE_RELATIVE;
|
||||
@@ -1956,20 +1960,47 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
|
||||
if (broken_rawevents && is_old_motion_event( xev->serial ))
|
||||
{
|
||||
- TRACE( "pos %d,%d old serial %lu, ignoring\n", input.u.mi.dx, input.u.mi.dy, xev->serial );
|
||||
+ TRACE( "pos %d,%d old serial %lu, ignoring\n", (LONG) dx, (LONG) dy, xev->serial );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- if (thread_data->xi2_state == xi_extra)
|
||||
+ /* Accumulate the fractional parts so they aren't lost after casting
|
||||
+ * successive motion values to integral fields.
|
||||
+ *
|
||||
+ * Note: It looks like raw_dx and raw_dy are already integral values
|
||||
+ * but that may be wrong.
|
||||
+ */
|
||||
+
|
||||
+ x_rel->accum += dx;
|
||||
+ y_rel->accum += dy;
|
||||
+ if ((dy || dy) && fabs(x_rel->accum) < 1.0 && fabs(y_rel->accum) < 1.0)
|
||||
+ {
|
||||
+ TRACE( "accumulating raw motion (event %f,%f, accum %f,%f)\n", dx, dy, x_rel->accum, y_rel->accum );
|
||||
+ }
|
||||
+ else
|
||||
{
|
||||
- TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
|
||||
- __wine_send_input( 0, &input );
|
||||
+ input.u.mi.dx = x_rel->accum;
|
||||
+ input.u.mi.dy = y_rel->accum;
|
||||
+ x_rel->accum -= input.u.mi.dx;
|
||||
+ y_rel->accum -= input.u.mi.dy;
|
||||
+
|
||||
+ if (thread_data->xi2_state == xi_extra)
|
||||
+ {
|
||||
+ TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
|
||||
+ __wine_send_input( 0, &input );
|
||||
+ }
|
||||
}
|
||||
|
||||
- if (raw_dwheel)
|
||||
+ wheel->accum += raw_dwheel;
|
||||
+ if (raw_dwheel && fabs(wheel->accum) < 1.0)
|
||||
+ {
|
||||
+ TRACE("accumulating wheel motion (event %f, accum %f)\n", raw_dwheel, wheel->accum);
|
||||
+ }
|
||||
+ else
|
||||
{
|
||||
raw_input.data.mouse.u.usButtonFlags = RI_MOUSE_WHEEL;
|
||||
- raw_input.data.mouse.u.usButtonData = raw_dwheel;
|
||||
+ raw_input.data.mouse.u.usButtonData = wheel->accum;
|
||||
+ wheel->accum -= raw_dwheel;
|
||||
}
|
||||
|
||||
TRACE("raw %s event %f,%f + %f\n",
|
||||
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
|
||||
index 599ed48154..005512fc4e 100644
|
||||
--- a/dlls/winex11.drv/x11drv.h
|
||||
+++ b/dlls/winex11.drv/x11drv.h
|
||||
@@ -320,6 +320,7 @@ struct x11drv_valuator_data
|
||||
double min;
|
||||
double max;
|
||||
int number;
|
||||
+ double accum;
|
||||
};
|
||||
|
||||
struct x11drv_thread_data
|
||||
--
|
||||
2.23.0
|
||||
|
@ -1,42 +0,0 @@
|
||||
From 97ab5ded8d021c911308f215bbfd27ebd0de4294 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dereklesho52@Gmail.com>
|
||||
Date: Sat, 10 Aug 2019 12:20:59 -0400
|
||||
Subject: [PATCH 10/11] server: Implement RIDEV_INPUTSINK flag
|
||||
|
||||
Signed-off-by: Derek Lesho <dereklesho52@Gmail.com>
|
||||
---
|
||||
dlls/user32/rawinput.c | 2 +-
|
||||
server/queue.c | 4 +++-
|
||||
2 files changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
|
||||
index 661a0e3b25..a93dc36500 100644
|
||||
--- a/dlls/user32/rawinput.c
|
||||
+++ b/dlls/user32/rawinput.c
|
||||
@@ -282,7 +282,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))
|
||||
+ if (devices[i].dwFlags & ~(RIDEV_REMOVE|RIDEV_NOLEGACY|RIDEV_INPUTSINK))
|
||||
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 060e73b819..0c3b5354bd 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -2442,7 +2442,9 @@ DECL_HANDLER(send_rawinput_message)
|
||||
if ((device = current->process->rawinput_mouse))
|
||||
{
|
||||
struct thread *thread = device->target ? get_window_thread( device->target ) : NULL;
|
||||
- if ((current->queue->input != desktop->foreground_input) || (thread && thread != current))
|
||||
+ if ((current->queue->input != desktop->foreground_input && !(device->flags & RIDEV_INPUTSINK))
|
||||
+ || (thread && thread != current)
|
||||
+ || (!thread && device->flags & RIDEV_INPUTSINK))
|
||||
goto done;
|
||||
|
||||
if (!(msg = alloc_hardware_message( 0, source, 0 ))) goto done;
|
||||
--
|
||||
2.23.0
|
||||
|
@ -1,76 +0,0 @@
|
||||
From 1a2b1df3e51425163af922ae5181d17a7f5ad380 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dereklesho52@Gmail.com>
|
||||
Date: Wed, 4 Sep 2019 10:07:39 -0500
|
||||
Subject: [PATCH 11/11] winex11.drv: [HACK] XWayland workaround.
|
||||
|
||||
---
|
||||
dlls/winex11.drv/mouse.c | 36 ++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 32 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index 1b109c8d1a..b06b7dc170 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/cursorfont.h>
|
||||
#include <stdarg.h>
|
||||
+#include <stdlib.h>
|
||||
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
@@ -1842,6 +1843,17 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev )
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+/* XWayland only reports normalized absolute values and raw relative values,
|
||||
+ * all under an absolute valuator.
|
||||
+ */
|
||||
+static inline int xwayland_workaround(void)
|
||||
+{
|
||||
+ static int workaround = -1;
|
||||
+ if (workaround != -1) return workaround;
|
||||
+ workaround = !!getenv("WAYLAND_DISPLAY");
|
||||
+ return workaround;
|
||||
+}
|
||||
+
|
||||
/***********************************************************************
|
||||
* X11DRV_RawMotion
|
||||
*/
|
||||
@@ -1944,13 +1956,29 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
}
|
||||
if (i == x_abs->number)
|
||||
{
|
||||
- raw_input.data.mouse.usFlags = MOUSE_MOVE_ABSOLUTE | MOUSE_VIRTUAL_DESKTOP;
|
||||
- raw_input.data.mouse.lLastX = raw_x = raw_val * (65536 / (x_abs->max - x_abs->min));
|
||||
+ if (xwayland_workaround())
|
||||
+ {
|
||||
+ raw_input.data.mouse.usFlags = MOUSE_MOVE_RELATIVE;
|
||||
+ raw_input.data.mouse.lLastX = raw_x = raw_val;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ raw_input.data.mouse.usFlags = MOUSE_MOVE_ABSOLUTE | MOUSE_VIRTUAL_DESKTOP;
|
||||
+ raw_input.data.mouse.lLastX = raw_x = raw_val * (65536 / (x_abs->max - x_abs->min));
|
||||
+ }
|
||||
}
|
||||
if (i == y_abs->number)
|
||||
{
|
||||
- raw_input.data.mouse.usFlags = MOUSE_MOVE_ABSOLUTE | MOUSE_VIRTUAL_DESKTOP;
|
||||
- raw_input.data.mouse.lLastY = raw_y = raw_val * (65536 / (y_abs->max - y_abs->min));
|
||||
+ if (xwayland_workaround())
|
||||
+ {
|
||||
+ raw_input.data.mouse.usFlags = MOUSE_MOVE_RELATIVE;
|
||||
+ raw_input.data.mouse.lLastY = raw_y = raw_val;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ raw_input.data.mouse.usFlags = MOUSE_MOVE_ABSOLUTE | MOUSE_VIRTUAL_DESKTOP;
|
||||
+ raw_input.data.mouse.lLastY = raw_y = raw_val * (65536 / (y_abs->max - y_abs->min));
|
||||
+ }
|
||||
}
|
||||
if (i == wheel->number)
|
||||
{
|
||||
--
|
||||
2.23.0
|
||||
|
@ -1,5 +0,0 @@
|
||||
Fixes: [42675] - Overwatch - Phantom mouse input / view pulled up to ceiling.
|
||||
Fixes: [45882] - Raw Input should use untransformed mouse values (affects Overwatch, several Source games).
|
||||
Fixes: [47457] - Mouse click-click-hold is treated as double click, causing gun jam in Overwatch.
|
||||
Fixes: [42631] - user32: Add Raw Input support.
|
||||
Disabled: True
|
@ -1,17 +1,17 @@
|
||||
From 335a6ec241f64bf4ceffc39170cfd3ab88001cb8 Mon Sep 17 00:00:00 2001
|
||||
From 614fe3af1cabb038c779700fa18dc4992747a164 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Thomases <ken@codeweavers.com>
|
||||
Date: Tue, 11 Dec 2018 08:30:41 +1100
|
||||
Subject: [PATCH 1/2] winex11: Match keyboard in Unicode
|
||||
Subject: [PATCH] winex11: Match keyboard in Unicode
|
||||
|
||||
---
|
||||
dlls/winex11.drv/keyboard.c | 163 ++++++++++++++++++++++--------------
|
||||
1 file changed, 98 insertions(+), 65 deletions(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
|
||||
index b9b8293e4d8..3f13a7331cc 100644
|
||||
index 4d113d8c184..b16d913a4a2 100644
|
||||
--- a/dlls/winex11.drv/keyboard.c
|
||||
+++ b/dlls/winex11.drv/keyboard.c
|
||||
@@ -37,6 +37,7 @@
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
@ -19,7 +19,7 @@ index b9b8293e4d8..3f13a7331cc 100644
|
||||
|
||||
#define NONAMELESSUNION
|
||||
|
||||
@@ -76,7 +77,7 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
|
||||
@@ -79,7 +80,7 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
|
||||
};
|
||||
static CRITICAL_SECTION kbd_section = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
@ -28,9 +28,9 @@ index b9b8293e4d8..3f13a7331cc 100644
|
||||
|
||||
/* Keyboard translation tables */
|
||||
#define MAIN_LEN 49
|
||||
@@ -1452,6 +1453,36 @@ BOOL X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
|
||||
return TRUE;
|
||||
@@ -1455,6 +1456,36 @@ BOOL X11DRV_RawKeyEvent( XGenericEventCookie *cookie )
|
||||
}
|
||||
#endif
|
||||
|
||||
+static WCHAR translate_keysym( Display *display, KeySym keysym )
|
||||
+{
|
||||
@ -65,7 +65,7 @@ index b9b8293e4d8..3f13a7331cc 100644
|
||||
/**********************************************************************
|
||||
* X11DRV_KEYBOARD_DetectLayout
|
||||
*
|
||||
@@ -1468,8 +1499,8 @@ X11DRV_KEYBOARD_DetectLayout( Display *display )
|
||||
@@ -1471,8 +1502,8 @@ X11DRV_KEYBOARD_DetectLayout( Display *display )
|
||||
KeySym keysym = 0;
|
||||
const char (*lkey)[MAIN_LEN][4];
|
||||
unsigned max_seq = 0;
|
||||
@ -76,7 +76,7 @@ index b9b8293e4d8..3f13a7331cc 100644
|
||||
|
||||
syms = keysyms_per_keycode;
|
||||
if (syms > 4) {
|
||||
@@ -1482,35 +1513,25 @@ X11DRV_KEYBOARD_DetectLayout( Display *display )
|
||||
@@ -1485,35 +1516,25 @@ X11DRV_KEYBOARD_DetectLayout( Display *display )
|
||||
/* get data for keycode from X server */
|
||||
for (i = 0; i < syms; i++) {
|
||||
if (!(keysym = keycode_to_keysym (display, keyc, i))) continue;
|
||||
@ -120,7 +120,7 @@ index b9b8293e4d8..3f13a7331cc 100644
|
||||
for (keyc = min_keycode; keyc <= max_keycode; keyc++) {
|
||||
if (ckey[keyc][0]) {
|
||||
/* search for a match in layout table */
|
||||
@@ -1519,10 +1540,13 @@ X11DRV_KEYBOARD_DetectLayout( Display *display )
|
||||
@@ -1522,10 +1543,13 @@ X11DRV_KEYBOARD_DetectLayout( Display *display )
|
||||
/* the table, it's okay that the X server has "3#£", for example) */
|
||||
/* however, the score will be higher for longer matches */
|
||||
for (key = 0; key < MAIN_LEN; key++) {
|
||||
@ -137,7 +137,7 @@ index b9b8293e4d8..3f13a7331cc 100644
|
||||
ok = -1;
|
||||
}
|
||||
if (ok > 0) {
|
||||
@@ -1537,11 +1561,7 @@ X11DRV_KEYBOARD_DetectLayout( Display *display )
|
||||
@@ -1540,11 +1564,7 @@ X11DRV_KEYBOARD_DetectLayout( Display *display )
|
||||
if (key > pkey) seq++;
|
||||
pkey = key;
|
||||
} else {
|
||||
@ -150,7 +150,7 @@ index b9b8293e4d8..3f13a7331cc 100644
|
||||
mismatch++;
|
||||
score -= syms;
|
||||
}
|
||||
@@ -1648,9 +1668,11 @@ void X11DRV_InitKeyboard( Display *display )
|
||||
@@ -1651,9 +1671,11 @@ void X11DRV_InitKeyboard( Display *display )
|
||||
XKeyEvent e2;
|
||||
WORD scan, vkey;
|
||||
int keyc, i, keyn, syms;
|
||||
@ -163,7 +163,7 @@ index b9b8293e4d8..3f13a7331cc 100644
|
||||
|
||||
/* Ranges of OEM, function key, and character virtual key codes.
|
||||
* Don't include those handled specially in X11DRV_ToUnicodeEx and
|
||||
@@ -1707,7 +1729,11 @@ void X11DRV_InitKeyboard( Display *display )
|
||||
@@ -1710,7 +1732,11 @@ void X11DRV_InitKeyboard( Display *display )
|
||||
/* Detect the keyboard layout */
|
||||
X11DRV_KEYBOARD_DetectLayout( display );
|
||||
lkey = main_key_tab[kbd_layout].key;
|
||||
@ -175,7 +175,7 @@ index b9b8293e4d8..3f13a7331cc 100644
|
||||
|
||||
/* Now build two conversion arrays :
|
||||
* keycode -> vkey + scancode + extended
|
||||
@@ -1748,26 +1774,14 @@ void X11DRV_InitKeyboard( Display *display )
|
||||
@@ -1751,26 +1777,14 @@ void X11DRV_InitKeyboard( Display *display )
|
||||
int maxlen=0,maxval=-1,ok;
|
||||
for (i=0; i<syms; i++) {
|
||||
keysym = keycode_to_keysym(display, keyc, i);
|
||||
@ -207,7 +207,7 @@ index b9b8293e4d8..3f13a7331cc 100644
|
||||
if (!ok) i--; /* we overshot */
|
||||
if (ok||(i>maxlen)) {
|
||||
maxlen=i; maxval=keyn;
|
||||
@@ -2369,7 +2383,7 @@ INT CDECL X11DRV_GetKeyNameText(LONG lParam, LPWSTR lpBuffer, INT nSize)
|
||||
@@ -2388,7 +2402,7 @@ INT CDECL X11DRV_GetKeyNameText(LONG lParam, LPWSTR lpBuffer, INT nSize)
|
||||
/***********************************************************************
|
||||
* X11DRV_KEYBOARD_MapDeadKeysym
|
||||
*/
|
||||
@ -216,7 +216,7 @@ index b9b8293e4d8..3f13a7331cc 100644
|
||||
{
|
||||
switch (keysym)
|
||||
{
|
||||
@@ -2379,65 +2393,84 @@ static char KEYBOARD_MapDeadKeysym(KeySym keysym)
|
||||
@@ -2398,65 +2412,84 @@ static char KEYBOARD_MapDeadKeysym(KeySym keysym)
|
||||
#endif
|
||||
case 0x1000FE7E : /* Xfree's XK_Dtilde */
|
||||
return '~'; /* '? */
|
||||
@ -316,7 +316,7 @@ index b9b8293e4d8..3f13a7331cc 100644
|
||||
*/
|
||||
}
|
||||
TRACE("no character for dead keysym 0x%08lx\n",keysym);
|
||||
@@ -2622,7 +2655,7 @@ INT CDECL X11DRV_ToUnicodeEx(UINT virtKey, UINT scanCode, const BYTE *lpKeyState
|
||||
@@ -2641,7 +2674,7 @@ INT CDECL X11DRV_ToUnicodeEx(UINT virtKey, UINT scanCode, const BYTE *lpKeyState
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
@ -325,7 +325,7 @@ index b9b8293e4d8..3f13a7331cc 100644
|
||||
|
||||
#ifdef XK_EuroSign
|
||||
/* An ugly hack for EuroSign: X can't translate it to a character
|
||||
@@ -2646,7 +2679,7 @@ INT CDECL X11DRV_ToUnicodeEx(UINT virtKey, UINT scanCode, const BYTE *lpKeyState
|
||||
@@ -2665,7 +2698,7 @@ INT CDECL X11DRV_ToUnicodeEx(UINT virtKey, UINT scanCode, const BYTE *lpKeyState
|
||||
dead_char = KEYBOARD_MapDeadKeysym(keysym);
|
||||
if (dead_char)
|
||||
{
|
||||
@ -335,5 +335,5 @@ index b9b8293e4d8..3f13a7331cc 100644
|
||||
goto found;
|
||||
}
|
||||
--
|
||||
2.19.2
|
||||
2.24.0
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user