mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-04-13 14:42:51 -07:00
user32-rawinput-*: Rebase and re-enable.
Thanks to Rémi Bernon for the rebased patch sets.
This commit is contained in:
parent
70f6f6d7e4
commit
f904ca32a3
@ -266,6 +266,9 @@ 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_mouse="$1"
|
||||
enable_user32_rawinput_mouse_experimental="$1"
|
||||
enable_user32_recursive_activation="$1"
|
||||
enable_user32_window_activation="$1"
|
||||
enable_uxtheme_CloseThemeClass="$1"
|
||||
@ -885,6 +888,15 @@ patch_enable ()
|
||||
user32-msgbox-Support-WM_COPY-mesg)
|
||||
enable_user32_msgbox_Support_WM_COPY_mesg="$2"
|
||||
;;
|
||||
user32-rawinput-hid)
|
||||
enable_user32_rawinput_hid="$2"
|
||||
;;
|
||||
user32-rawinput-mouse)
|
||||
enable_user32_rawinput_mouse="$2"
|
||||
;;
|
||||
user32-rawinput-mouse-experimental)
|
||||
enable_user32_rawinput_mouse_experimental="$2"
|
||||
;;
|
||||
user32-recursive-activation)
|
||||
enable_user32_recursive_activation="$2"
|
||||
;;
|
||||
@ -1492,6 +1504,27 @@ 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_mouse" -gt 1; then
|
||||
abort "Patchset user32-rawinput-mouse disabled, but user32-rawinput-mouse-experimental depends on that."
|
||||
fi
|
||||
enable_user32_rawinput_mouse=1
|
||||
fi
|
||||
|
||||
if test "$enable_user32_rawinput_hid" -eq 1; then
|
||||
if test "$enable_user32_rawinput_mouse" -gt 1; then
|
||||
abort "Patchset user32-rawinput-mouse disabled, but user32-rawinput-hid 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."
|
||||
@ -3592,7 +3625,7 @@ fi
|
||||
# | * [#43224] Improvement for heap allocation performance
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * configure.ac, dlls/ntdll/heap.c
|
||||
# | * dlls/ntdll/heap.c
|
||||
# |
|
||||
if test "$enable_ntdll_Heap_Improvements" -eq 1; then
|
||||
patch_apply ntdll-Heap_Improvements/0001-ntdll-Add-helper-function-to-delete-free-blocks.patch
|
||||
@ -3626,7 +3659,7 @@ fi
|
||||
# | * [#38656] Add support for hiding wine version information from applications
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/ntdll/loader.c
|
||||
# | * dlls/ntdll/loader.c, dlls/ntdll/ntdll_misc.h
|
||||
# |
|
||||
if test "$enable_ntdll_Hide_Wine_Exports" -eq 1; then
|
||||
patch_apply ntdll-Hide_Wine_Exports/0001-ntdll-Add-support-for-hiding-wine-version-informatio.patch
|
||||
@ -5169,6 +5202,110 @@ 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] Mouse drift, jump or don't react to small slow movements in Unity-engine games and Fallout 4 (partly fixed in
|
||||
# | Unity games, have walkaround in Fallout4 )
|
||||
# | * [#42675] Overwatch: Phantom mouse input / view pulled up to ceiling
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/dinput/device_private.h, dlls/dinput/dinput_main.c, dlls/dinput/dinput_private.h, dlls/dinput/mouse.c,
|
||||
# | dlls/dinput8/tests/device.c, dlls/user32/input.c, dlls/user32/rawinput.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-Implement-GetRegisteredRawInputDevices.patch
|
||||
patch_apply user32-rawinput-mouse/0002-dinput8-tests-Add-DISCL_EXCLUSIVE-rawinput-test.patch
|
||||
patch_apply user32-rawinput-mouse/0003-dinput8-Add-support-for-rawinput-based-devices.patch
|
||||
patch_apply user32-rawinput-mouse/0004-dinput8-Use-rawinput-interface-for-mouse-device.patch
|
||||
patch_apply user32-rawinput-mouse/0005-dinput8-Stop-using-LL-hooks-for-mouse-devices.patch
|
||||
patch_apply user32-rawinput-mouse/0006-server-Add-send_hardware_message-flags-for-rawinput-.patch
|
||||
patch_apply user32-rawinput-mouse/0007-user32-Add-__wine_send_input-flags-to-hint-raw-input.patch
|
||||
patch_apply user32-rawinput-mouse/0008-winex11.drv-Advertise-XInput2-version-2.1-support.patch
|
||||
patch_apply user32-rawinput-mouse/0009-winex11.drv-Keep-track-of-pointer-and-device-button-.patch
|
||||
patch_apply user32-rawinput-mouse/0010-winex11.drv-Listen-to-RawMotion-and-RawButton-events.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Rémi Bernon", "user32: Implement GetRegisteredRawInputDevices.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "dinput8/tests: Add DISCL_EXCLUSIVE / rawinput test.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "dinput8: Add support for rawinput based devices.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "dinput8: Use rawinput interface for mouse device.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "dinput8: Stop using LL hooks for mouse devices.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "server: Add send_hardware_message flags for rawinput translation.", 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 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset user32-rawinput-hid
|
||||
# |
|
||||
# | This patchset has the following (direct or indirect) dependencies:
|
||||
# | * winex11.drv-mouse-coorrds, user32-rawinput-mouse
|
||||
# |
|
||||
# | 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-Make-it-possible-to-queue-rawinput-message-on.patch
|
||||
patch_apply user32-rawinput-hid/0004-server-Add-HID-input-message-type-to-send_hardware_m.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: Make it possible to queue rawinput message on all desktops.", 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", "hidclass.sys: Send input message to server when HID report is received.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset user32-rawinput-mouse-experimental
|
||||
# |
|
||||
# | This patchset has the following (direct or indirect) dependencies:
|
||||
# | * winex11.drv-mouse-coorrds, user32-rawinput-mouse
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#45882] - Raw Input should use untransformed mouse values (affects Overwatch, several Source games).
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/user32/rawinput.c, dlls/winex11.drv/mouse.c, dlls/winex11.drv/x11drv.h, dlls/winex11.drv/x11drv_main.c,
|
||||
# | server/queue.c
|
||||
# |
|
||||
if test "$enable_user32_rawinput_mouse_experimental" -eq 1; then
|
||||
patch_apply user32-rawinput-mouse-experimental/0001-winex11.drv-Add-support-for-absolute-RawMotion-event.patch
|
||||
patch_apply user32-rawinput-mouse-experimental/0002-winex11.drv-Send-relative-RawMotion-events-unprocess.patch
|
||||
patch_apply user32-rawinput-mouse-experimental/0003-winex11.drv-Accumulate-mouse-movement-to-avoid-round.patch
|
||||
(
|
||||
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' '+ { "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:
|
||||
@ -5952,21 +6089,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:
|
||||
|
@ -4,7 +4,6 @@
|
||||
Depends: ntdll-Threading
|
||||
Depends: server-PeekMessage
|
||||
Depends: server-Signal_Thread
|
||||
Depends: user32-rawinput-nolegacy
|
||||
Depends: ntdll-ext4-case-folder
|
||||
# This is not worth rebasing right now.
|
||||
Disabled: true
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 694ff514bfce59c2590668e3e812d501b713acdb Mon Sep 17 00:00:00 2001
|
||||
From 1851c55f41d14e03c927b0e5220f9c00b1d05f6e 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.
|
||||
Subject: [PATCH] server: Add process argument to find_rawinput_device.
|
||||
|
||||
We need to be able to iterate all registered rawinput devices for
|
||||
foreign processes, not only the current one.
|
||||
@ -10,10 +10,10 @@ foreign processes, not only the current one.
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index f5dc06100d1..3ed7e82a906 100644
|
||||
index 46ace52f004..810612c5167 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
|
||||
@@ -1490,11 +1490,11 @@ static user_handle_t find_hardware_message_window( struct desktop *desktop, stru
|
||||
return win;
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ index f5dc06100d1..3ed7e82a906 100644
|
||||
{
|
||||
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)
|
||||
@@ -1507,7 +1507,7 @@ static void update_rawinput_device(const struct rawinput_device *device)
|
||||
{
|
||||
struct rawinput_device_entry *e;
|
||||
|
||||
@ -36,7 +36,7 @@ index f5dc06100d1..3ed7e82a906 100644
|
||||
{
|
||||
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)
|
||||
@@ -3286,9 +3286,9 @@ DECL_HANDLER(update_rawinput_devices)
|
||||
update_rawinput_device(&devices[i]);
|
||||
}
|
||||
|
||||
@ -49,5 +49,5 @@ index f5dc06100d1..3ed7e82a906 100644
|
||||
}
|
||||
|
||||
--
|
||||
2.24.1
|
||||
2.27.0
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 9aca9116db8ca84eea5be6a67b748ff6fdde9a31 Mon Sep 17 00:00:00 2001
|
||||
From ea854d200d2fb243dc898a1ef4e2a1a6f127a329 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 19 Sep 2019 09:20:44 +0200
|
||||
Subject: [PATCH] server: Allow extra data for hardware_msg_data message.
|
||||
@ -6,14 +6,14 @@ Subject: [PATCH] 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(-)
|
||||
server/queue.c | 31 +++++++++++++++++++++----------
|
||||
1 file changed, 21 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index 9dca519cad2..364c8e43485 100644
|
||||
index 810612c5167..f5d19031485 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_
|
||||
@@ -343,13 +343,13 @@ static int assign_thread_input( struct thread *thread, struct thread_input *new_
|
||||
|
||||
/* allocate a hardware message and its data */
|
||||
static struct message *alloc_hardware_message( lparam_t info, struct hw_msg_source source,
|
||||
@ -29,7 +29,7 @@ index 9dca519cad2..364c8e43485 100644
|
||||
{
|
||||
free( msg );
|
||||
return NULL;
|
||||
@@ -413,9 +413,9 @@ static struct message *alloc_hardware_message( lparam_t info, struct hw_msg_sour
|
||||
@@ -358,9 +358,9 @@ static struct message *alloc_hardware_message( lparam_t info, struct hw_msg_sour
|
||||
msg->type = MSG_HARDWARE;
|
||||
msg->time = time;
|
||||
msg->data = msg_data;
|
||||
@ -41,7 +41,7 @@ index 9dca519cad2..364c8e43485 100644
|
||||
msg_data->info = info;
|
||||
msg_data->source = source;
|
||||
return msg;
|
||||
@@ -448,7 +448,7 @@ static void set_cursor_pos( struct desktop *desktop, int x, int y )
|
||||
@@ -393,7 +393,7 @@ static void set_cursor_pos( struct desktop *desktop, int x, int y )
|
||||
return;
|
||||
}
|
||||
|
||||
@ -50,26 +50,26 @@ index 9dca519cad2..364c8e43485 100644
|
||||
|
||||
msg->msg = WM_MOUSEMOVE;
|
||||
msg->x = x;
|
||||
@@ -1756,6 +1756,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;
|
||||
@@ -1649,6 +1649,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 )
|
||||
@@ -1765,6 +1767,7 @@ static int queue_rawinput_message( struct process* process, void* user )
|
||||
struct desktop *desktop = NULL;
|
||||
struct thread *thread = NULL, *foreground = NULL;
|
||||
/* check if process is supposed to receive a WM_INPUT message and eventually queue it */
|
||||
@@ -1659,6 +1661,7 @@ static int queue_rawinput_message( struct process* process, void *arg )
|
||||
struct desktop *target_desktop = NULL;
|
||||
struct thread *target_thread = NULL;
|
||||
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;
|
||||
@@ -1787,14 +1790,18 @@ static int queue_rawinput_message( struct process* process, void* user )
|
||||
thread->process != foreground->process)
|
||||
goto done;
|
||||
@@ -1676,14 +1679,18 @@ static int queue_rawinput_message( struct process* process, void *arg )
|
||||
wparam = RIM_INPUTSINK;
|
||||
}
|
||||
|
||||
- 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 )))
|
||||
@ -78,7 +78,7 @@ index 9dca519cad2..364c8e43485 100644
|
||||
|
||||
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(raw_msg->data) );
|
||||
+
|
||||
@ -86,24 +86,18 @@ index 9dca519cad2..364c8e43485 100644
|
||||
+ 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 );
|
||||
queue_hardware_message( raw_msg->desktop, msg, 1 );
|
||||
|
||||
@@ -1863,9 +1870,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;
|
||||
@@ -1756,6 +1763,8 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
raw_msg.desktop = desktop;
|
||||
raw_msg.source = source;
|
||||
raw_msg.time = time;
|
||||
+ raw_msg.extra = NULL;
|
||||
+ raw_msg.extra_len = 0;
|
||||
|
||||
msg_data = &raw_msg.data;
|
||||
msg_data->info = input->mouse.info;
|
||||
@@ -1895,7 +1904,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
@@ -1785,7 +1794,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
if (!(flags & (1 << i))) continue;
|
||||
flags &= ~(1 << i);
|
||||
|
||||
@ -112,23 +106,17 @@ index 9dca519cad2..364c8e43485 100644
|
||||
msg_data = msg->data;
|
||||
|
||||
msg->win = get_user_full_handle( win );
|
||||
@@ -1999,9 +2008,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;
|
||||
@@ -1894,6 +1903,8 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
raw_msg.desktop = desktop;
|
||||
raw_msg.source = source;
|
||||
raw_msg.time = time;
|
||||
+ raw_msg.extra = NULL;
|
||||
+ raw_msg.extra_len = 0;
|
||||
|
||||
msg_data = &raw_msg.data;
|
||||
msg_data->info = input->kbd.info;
|
||||
@@ -2022,7 +2033,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
if ((device = current->process->rawinput_kbd) && (device->flags & RIDEV_NOLEGACY))
|
||||
@@ -1917,7 +1928,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
||||
if (!(req_flags & SEND_HWMSG_WINDOW))
|
||||
return 0;
|
||||
|
||||
- if (!(msg = alloc_hardware_message( input->kbd.info, source, time ))) return 0;
|
||||
@ -136,7 +124,7 @@ index 9dca519cad2..364c8e43485 100644
|
||||
msg_data = msg->data;
|
||||
|
||||
msg->win = get_user_full_handle( win );
|
||||
@@ -2060,7 +2071,7 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_
|
||||
@@ -1955,7 +1966,7 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_
|
||||
struct hw_msg_source source = { IMDT_UNAVAILABLE, origin };
|
||||
struct message *msg;
|
||||
|
||||
@ -146,5 +134,5 @@ index 9dca519cad2..364c8e43485 100644
|
||||
msg->win = get_user_full_handle( win );
|
||||
msg->msg = input->hw.msg;
|
||||
--
|
||||
2.17.1
|
||||
2.27.0
|
||||
|
||||
|
@ -0,0 +1,64 @@
|
||||
From eee5ecbed5c813be03d4b540675f1c4792101567 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Mon, 11 Nov 2019 18:35:18 +0100
|
||||
Subject: [PATCH] server: Make it possible to queue rawinput message on all
|
||||
desktops.
|
||||
|
||||
---
|
||||
server/queue.c | 18 +++++++++++++-----
|
||||
1 file changed, 13 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index f5d19031485..59c6cbb6921 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -1658,8 +1658,8 @@ static int queue_rawinput_message( struct process* process, void *arg )
|
||||
{
|
||||
const struct rawinput_message* raw_msg = arg;
|
||||
const struct rawinput_device *device = NULL;
|
||||
- struct desktop *target_desktop = NULL;
|
||||
- struct thread *target_thread = NULL;
|
||||
+ struct desktop *target_desktop = NULL, *desktop = NULL;
|
||||
+ struct thread *target_thread = NULL, *foreground = NULL;
|
||||
struct message *msg;
|
||||
struct hardware_msg_data *msg_data;
|
||||
int wparam = RIM_INPUT;
|
||||
@@ -1670,12 +1670,18 @@ static int queue_rawinput_message( struct process* process, void *arg )
|
||||
device = process->rawinput_kbd;
|
||||
if (!device) return 0;
|
||||
|
||||
- if (process != raw_msg->foreground->process)
|
||||
+ if (raw_msg->desktop) desktop = (struct desktop *)grab_object( raw_msg->desktop );
|
||||
+ else if (!(desktop = get_desktop_obj( process, process->desktop, 0 ))) goto done;
|
||||
+
|
||||
+ if (raw_msg->foreground) foreground = (struct thread *)grab_object( raw_msg->foreground );
|
||||
+ else if (!(foreground = get_foreground_thread( desktop, 0 ))) goto done;
|
||||
+
|
||||
+ if (process != foreground->process)
|
||||
{
|
||||
if (!(device->flags & RIDEV_INPUTSINK)) goto done;
|
||||
if (!(target_thread = get_window_thread( device->target ))) goto done;
|
||||
if (!(target_desktop = get_thread_desktop( target_thread, 0 ))) goto done;
|
||||
- if (target_desktop != raw_msg->desktop) goto done;
|
||||
+ if (target_desktop != desktop) goto done;
|
||||
wparam = RIM_INPUTSINK;
|
||||
}
|
||||
|
||||
@@ -1692,11 +1698,13 @@ static int queue_rawinput_message( struct process* process, void *arg )
|
||||
if (raw_msg->extra_len && raw_msg->extra)
|
||||
memcpy( msg_data + 1, raw_msg->extra, raw_msg->extra_len );
|
||||
|
||||
- queue_hardware_message( raw_msg->desktop, msg, 1 );
|
||||
+ queue_hardware_message( desktop, msg, 1 );
|
||||
|
||||
done:
|
||||
if (target_thread) release_object( target_thread );
|
||||
if (target_desktop) release_object( target_desktop );
|
||||
+ if (foreground) release_object( foreground );
|
||||
+ if (desktop) release_object( desktop );
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
@ -1,21 +1,23 @@
|
||||
From d0347613c7149144d4339109b641901537c4c326 Mon Sep 17 00:00:00 2001
|
||||
From 2c92d595325accce44db85552efda8070f526569 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.
|
||||
Subject: [PATCH] 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(-)
|
||||
dlls/user32/message.c | 4 ++-
|
||||
dlls/user32/rawinput.c | 60 ++++++++++++++++++++++++++++++++++++--
|
||||
dlls/user32/user_private.h | 2 ++
|
||||
server/protocol.def | 26 +++++++++++++++--
|
||||
server/queue.c | 58 +++++++++++++++++++++++++++++++-----
|
||||
server/trace.c | 10 +++++--
|
||||
6 files changed, 143 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/message.c b/dlls/user32/message.c
|
||||
index cc25d2f6c2f..55bbe409c9e 100644
|
||||
index c5c7db667cf..bb7c79b9b2c 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 )
|
||||
@@ -3244,10 +3244,10 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
|
||||
{
|
||||
req->win = wine_server_user_handle( hwnd );
|
||||
req->flags = flags;
|
||||
@ -27,7 +29,7 @@ index cc25d2f6c2f..55bbe409c9e 100644
|
||||
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 )
|
||||
@@ -3256,6 +3256,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
|
||||
req->input.mouse.info = input->u.mi.dwExtraInfo;
|
||||
break;
|
||||
case INPUT_KEYBOARD:
|
||||
@ -35,7 +37,7 @@ index cc25d2f6c2f..55bbe409c9e 100644
|
||||
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 )
|
||||
@@ -3263,6 +3264,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
|
||||
req->input.kbd.info = input->u.ki.dwExtraInfo;
|
||||
break;
|
||||
case INPUT_HARDWARE:
|
||||
@ -43,11 +45,139 @@ index cc25d2f6c2f..55bbe409c9e 100644
|
||||
req->input.hw.msg = input->u.hi.uMsg;
|
||||
req->input.hw.lparam = MAKELONG( input->u.hi.wParamL, input->u.hi.wParamH );
|
||||
break;
|
||||
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
|
||||
index 43da5248faf..90dc911397d 100644
|
||||
--- a/dlls/user32/rawinput.c
|
||||
+++ b/dlls/user32/rawinput.c
|
||||
@@ -47,6 +47,7 @@ struct device
|
||||
{
|
||||
WCHAR *path;
|
||||
HANDLE file;
|
||||
+ HANDLE handle;
|
||||
RID_DEVICE_INFO info;
|
||||
PHIDP_PREPARSED_DATA data;
|
||||
};
|
||||
@@ -63,6 +64,8 @@ static CRITICAL_SECTION_DEBUG rawinput_devices_cs_debug =
|
||||
};
|
||||
static CRITICAL_SECTION rawinput_devices_cs = { &rawinput_devices_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
+extern DWORD WINAPI GetFinalPathNameByHandleW(HANDLE file, LPWSTR path, DWORD charcount, DWORD flags);
|
||||
+
|
||||
static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size)
|
||||
{
|
||||
unsigned int new_capacity, max_capacity;
|
||||
@@ -144,10 +147,43 @@ static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
|
||||
device->path = path;
|
||||
device->file = file;
|
||||
device->info.cbSize = sizeof(RID_DEVICE_INFO);
|
||||
+ device->handle = INVALID_HANDLE_VALUE;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
+HANDLE rawinput_handle_from_device_handle(HANDLE device)
|
||||
+{
|
||||
+ WCHAR buffer[sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH + 1];
|
||||
+ OBJECT_NAME_INFORMATION *info = (OBJECT_NAME_INFORMATION*)&buffer;
|
||||
+ ULONG dummy;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ for (i = 0; i < rawinput_devices_count; ++i)
|
||||
+ {
|
||||
+ if (rawinput_devices[i].handle == device)
|
||||
+ return &rawinput_devices[i];
|
||||
+ }
|
||||
+
|
||||
+ if (NtQueryObject( device, ObjectNameInformation, &buffer, sizeof(buffer) - sizeof(WCHAR), &dummy ) || !info->Name.Buffer)
|
||||
+ return NULL;
|
||||
+
|
||||
+ /* replace \??\ with \\?\ to match rawinput_devices paths */
|
||||
+ if (info->Name.Length > 1 && info->Name.Buffer[0] == '\\' && info->Name.Buffer[1] == '?')
|
||||
+ info->Name.Buffer[1] = '\\';
|
||||
+
|
||||
+ for (i = 0; i < rawinput_devices_count; ++i)
|
||||
+ {
|
||||
+ if (strcmpW(rawinput_devices[i].path, info->Name.Buffer) == 0)
|
||||
+ {
|
||||
+ rawinput_devices[i].handle = device;
|
||||
+ return &rawinput_devices[i];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static void find_devices(void)
|
||||
{
|
||||
static ULONGLONG last_check;
|
||||
@@ -325,6 +361,22 @@ BOOL rawinput_from_hardware_message(RAWINPUT *rawinput, const struct hardware_ms
|
||||
rawinput->data.keyboard.Message = msg_data->rawinput.kbd.message;
|
||||
rawinput->data.keyboard.ExtraInformation = msg_data->info;
|
||||
}
|
||||
+ else if (msg_data->rawinput.type == RIM_TYPEHID)
|
||||
+ {
|
||||
+ if (sizeof(*rawinput) + msg_data->rawinput.hid.length > RAWINPUT_BUFFER_SIZE)
|
||||
+ {
|
||||
+ ERR("unexpectedly large hardware message dropped\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ rawinput->header.dwSize = FIELD_OFFSET(RAWINPUT, data.hid.bRawData) + msg_data->rawinput.hid.length;
|
||||
+ rawinput->header.hDevice = rawinput_handle_from_device_handle(wine_server_ptr_handle(msg_data->rawinput.hid.device));
|
||||
+ rawinput->header.wParam = 0;
|
||||
+
|
||||
+ rawinput->data.hid.dwSizeHid = msg_data->rawinput.hid.length;
|
||||
+ rawinput->data.hid.dwCount = 1;
|
||||
+ memcpy(rawinput->data.hid.bRawData, msg_data + 1, msg_data->rawinput.hid.length);
|
||||
+ }
|
||||
else
|
||||
{
|
||||
FIXME("Unhandled rawinput type %#x.\n", msg_data->rawinput.type);
|
||||
@@ -514,7 +566,7 @@ UINT WINAPI DECLSPEC_HOTPATCH GetRawInputBuffer(RAWINPUT *data, UINT *data_size,
|
||||
{
|
||||
struct hardware_msg_data *msg_data;
|
||||
RAWINPUT *rawinput;
|
||||
- UINT count = 0, rawinput_size, next_size, overhead;
|
||||
+ UINT count = 0, rawinput_size, msg_size, next_size, overhead;
|
||||
BOOL is_wow64;
|
||||
int i;
|
||||
|
||||
@@ -572,7 +624,10 @@ UINT WINAPI DECLSPEC_HOTPATCH GetRawInputBuffer(RAWINPUT *data, UINT *data_size,
|
||||
data->header.dwSize - sizeof(RAWINPUTHEADER));
|
||||
data->header.dwSize += overhead;
|
||||
data = NEXTRAWINPUTBLOCK(data);
|
||||
- msg_data++;
|
||||
+ msg_size = sizeof(*msg_data);
|
||||
+ if (msg_data->rawinput.type == RIM_TYPEHID)
|
||||
+ msg_size += msg_data->rawinput.hid.length;
|
||||
+ msg_data = (struct hardware_msg_data *)((char *)msg_data + msg_size);
|
||||
}
|
||||
|
||||
if (count == 0 && next_size == 0) *data_size = 0;
|
||||
@@ -647,6 +702,7 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT
|
||||
handle, command, data, data_size);
|
||||
|
||||
if (!data_size) return ~0U;
|
||||
+ if (!device) return ~0U;
|
||||
|
||||
/* each case below must set:
|
||||
* *data_size: length (meaning defined by command) of data we want to copy
|
||||
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
|
||||
index eb828203597..6592927cfae 100644
|
||||
--- a/dlls/user32/user_private.h
|
||||
+++ b/dlls/user32/user_private.h
|
||||
@@ -380,4 +380,6 @@ static inline WCHAR *heap_strdupW(const WCHAR *src)
|
||||
return dst;
|
||||
}
|
||||
|
||||
+extern HANDLE rawinput_handle_from_device_handle(HANDLE device);
|
||||
+
|
||||
#endif /* __WINE_USER_PRIVATE_H */
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index d37dceba40c..85cc2ac6937 100644
|
||||
index 21de849e5d8..d49c33f63f9 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -321,6 +321,13 @@ struct hardware_msg_data
|
||||
@@ -312,6 +312,13 @@ struct hardware_msg_data
|
||||
int y; /* y coordinate */
|
||||
unsigned int data; /* mouse data */
|
||||
} mouse;
|
||||
@ -61,7 +191,7 @@ index d37dceba40c..85cc2ac6937 100644
|
||||
} rawinput;
|
||||
};
|
||||
|
||||
@@ -344,7 +351,7 @@ typedef union
|
||||
@@ -335,7 +342,7 @@ typedef union
|
||||
int type;
|
||||
struct
|
||||
{
|
||||
@ -70,7 +200,7 @@ index d37dceba40c..85cc2ac6937 100644
|
||||
unsigned short vkey; /* virtual key code */
|
||||
unsigned short scan; /* scan code */
|
||||
unsigned int flags; /* event flags */
|
||||
@@ -353,7 +360,7 @@ typedef union
|
||||
@@ -344,7 +351,7 @@ typedef union
|
||||
} kbd;
|
||||
struct
|
||||
{
|
||||
@ -79,7 +209,7 @@ index d37dceba40c..85cc2ac6937 100644
|
||||
int x; /* coordinates */
|
||||
int y;
|
||||
unsigned int data; /* mouse data */
|
||||
@@ -363,11 +370,23 @@ typedef union
|
||||
@@ -354,11 +361,23 @@ typedef union
|
||||
} mouse;
|
||||
struct
|
||||
{
|
||||
@ -104,7 +234,7 @@ index d37dceba40c..85cc2ac6937 100644
|
||||
|
||||
typedef union
|
||||
{
|
||||
@@ -2361,6 +2380,7 @@ enum message_type
|
||||
@@ -2330,6 +2349,7 @@ enum message_type
|
||||
user_handle_t win; /* window handle */
|
||||
hw_input_t input; /* input data */
|
||||
unsigned int flags; /* flags (see below) */
|
||||
@ -113,10 +243,10 @@ index d37dceba40c..85cc2ac6937 100644
|
||||
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
|
||||
index 59c6cbb6921..fbed47d6951 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
|
||||
@@ -1594,7 +1594,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 */
|
||||
@ -125,7 +255,7 @@ index feff00e2b9f..85aa896c7bd 100644
|
||||
|
||||
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
|
||||
@@ -1612,7 +1612,7 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa
|
||||
msg->data_size = hardware_msg->data_size;
|
||||
msg->result = NULL;
|
||||
|
||||
@ -134,33 +264,33 @@ index feff00e2b9f..85aa896c7bd 100644
|
||||
{
|
||||
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 )
|
||||
@@ -1648,6 +1648,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;
|
||||
@@ -1657,6 +1659,7 @@ struct rawinput_message
|
||||
static int queue_rawinput_message( struct process* process, void *arg )
|
||||
{
|
||||
const struct rawinput_message* raw_msg = user;
|
||||
const struct rawinput_message* raw_msg = arg;
|
||||
+ 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 )
|
||||
struct desktop *target_desktop = NULL, *desktop = NULL;
|
||||
struct thread *target_thread = NULL, *foreground = NULL;
|
||||
@@ -1668,6 +1671,8 @@ static int queue_rawinput_message( struct process* process, void *arg )
|
||||
device = process->rawinput_mouse;
|
||||
else if (raw_msg->data.rawinput.type == RIM_TYPEKEYBOARD)
|
||||
device = process->rawinput_kbd;
|
||||
+ else if ((entry = find_rawinput_device( process, raw_msg->usage_page, raw_msg->usage )))
|
||||
+ device = &entry->device;
|
||||
if (!device) return 0;
|
||||
|
||||
if (!device)
|
||||
goto done;
|
||||
@@ -2067,6 +2072,38 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_
|
||||
if (raw_msg->desktop) desktop = (struct desktop *)grab_object( raw_msg->desktop );
|
||||
@@ -1986,6 +1991,37 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_
|
||||
queue_hardware_message( desktop, msg, 1 );
|
||||
}
|
||||
|
||||
@ -176,7 +306,9 @@ index feff00e2b9f..85aa896c7bd 100644
|
||||
+ if (!(req_flags & SEND_HWMSG_RAWINPUT))
|
||||
+ return;
|
||||
+
|
||||
+ raw_msg.desktop = NULL; /* send to all desktops */
|
||||
+ /* send to all desktops */
|
||||
+ raw_msg.foreground = NULL;
|
||||
+ raw_msg.desktop = NULL;
|
||||
+ raw_msg.source = source;
|
||||
+ raw_msg.time = get_tick_count();
|
||||
+ raw_msg.usage_page = input->hid.usage_page;
|
||||
@ -190,16 +322,13 @@ index feff00e2b9f..85aa896c7bd 100644
|
||||
+ 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 );
|
||||
+ enum_processes( queue_rawinput_message, &raw_msg );
|
||||
+}
|
||||
+
|
||||
/* check message filter for a hardware message */
|
||||
static int check_hw_message_filter( user_handle_t win, unsigned int msg_code,
|
||||
user_handle_t filter_win, unsigned int first, unsigned int last )
|
||||
@@ -2577,15 +2614,18 @@ DECL_HANDLER(send_hardware_message)
|
||||
@@ -2491,15 +2527,18 @@ DECL_HANDLER(send_hardware_message)
|
||||
|
||||
switch (req->input.type)
|
||||
{
|
||||
@ -221,11 +350,38 @@ index feff00e2b9f..85aa896c7bd 100644
|
||||
default:
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
}
|
||||
@@ -3271,20 +3310,23 @@ DECL_HANDLER(get_rawinput_buffer)
|
||||
{
|
||||
struct message *msg = LIST_ENTRY( ptr, struct message, entry );
|
||||
struct hardware_msg_data *data = msg->data;
|
||||
+ data_size_t msg_size = sizeof(*data);
|
||||
+ if (data->rawinput.type == RIM_TYPEHID)
|
||||
+ msg_size += data->rawinput.hid.length;
|
||||
|
||||
ptr = list_next( &input->msg_list, ptr );
|
||||
if (msg->msg != WM_INPUT) continue;
|
||||
|
||||
next_size = req->rawinput_size;
|
||||
if (size + next_size > req->buffer_size) break;
|
||||
- if (cur + sizeof(*data) > buf + get_reply_max_size()) break;
|
||||
+ if (cur + msg_size > buf + get_reply_max_size()) break;
|
||||
|
||||
- memcpy(cur, data, sizeof(*data));
|
||||
+ memcpy(cur, data, msg_size);
|
||||
list_remove( &msg->entry );
|
||||
free_message( msg );
|
||||
|
||||
size += next_size;
|
||||
- cur += sizeof(*data);
|
||||
+ cur += msg_size;
|
||||
count++;
|
||||
}
|
||||
|
||||
diff --git a/server/trace.c b/server/trace.c
|
||||
index 18b56c729e4..c39c56087c1 100644
|
||||
index 2fb5afd5ef1..bbf129ca4f1 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 )
|
||||
@@ -386,24 +386,28 @@ static void dump_hw_input( const char *prefix, const hw_input_t *input )
|
||||
{
|
||||
switch (input->type)
|
||||
{
|
||||
@ -258,5 +414,5 @@ index 18b56c729e4..c39c56087c1 100644
|
||||
fprintf( stderr, "%s{type=%04x}", prefix, input->type );
|
||||
break;
|
||||
--
|
||||
2.24.1
|
||||
2.27.0
|
||||
|
@ -1,138 +0,0 @@
|
||||
From a6c66494095012c8a867bf4ee6f44fbebf7bd69a 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] 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 8c915629613..5e8ae1e5fb5 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 0c72b3343ae..5211999e836 100644
|
||||
--- a/dlls/user32/rawinput.c
|
||||
+++ b/dlls/user32/rawinput.c
|
||||
@@ -46,6 +46,7 @@ struct device
|
||||
{
|
||||
WCHAR *path;
|
||||
HANDLE file;
|
||||
+ HANDLE handle;
|
||||
RID_DEVICE_INFO info;
|
||||
PHIDP_PREPARSED_DATA data;
|
||||
};
|
||||
@@ -62,6 +63,8 @@ static CRITICAL_SECTION_DEBUG rawinput_devices_cs_debug =
|
||||
};
|
||||
static CRITICAL_SECTION rawinput_devices_cs = { &rawinput_devices_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
+extern DWORD WINAPI GetFinalPathNameByHandleW(HANDLE file, LPWSTR path, DWORD charcount, DWORD flags);
|
||||
+
|
||||
static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size)
|
||||
{
|
||||
unsigned int new_capacity, max_capacity;
|
||||
@@ -143,10 +146,43 @@ static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
|
||||
device->path = path;
|
||||
device->file = file;
|
||||
device->info.cbSize = sizeof(RID_DEVICE_INFO);
|
||||
+ device->handle = INVALID_HANDLE_VALUE;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
+HANDLE rawinput_handle_from_device_handle(HANDLE device)
|
||||
+{
|
||||
+ WCHAR buffer[sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH + 1];
|
||||
+ OBJECT_NAME_INFORMATION *info = (OBJECT_NAME_INFORMATION*)&buffer;
|
||||
+ ULONG dummy;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ for (i = 0; i < rawinput_devices_count; ++i)
|
||||
+ {
|
||||
+ if (rawinput_devices[i].handle == device)
|
||||
+ return &rawinput_devices[i];
|
||||
+ }
|
||||
+
|
||||
+ if (NtQueryObject( device, ObjectNameInformation, &buffer, sizeof(buffer) - sizeof(WCHAR), &dummy ) || !info->Name.Buffer)
|
||||
+ return NULL;
|
||||
+
|
||||
+ /* replace \??\ with \\?\ to match hid_devices paths */
|
||||
+ if (info->Name.Length > 1 && info->Name.Buffer[0] == '\\' && info->Name.Buffer[1] == '?')
|
||||
+ info->Name.Buffer[1] = '\\';
|
||||
+
|
||||
+ for (i = 0; i < rawinput_devices_count; ++i)
|
||||
+ {
|
||||
+ if (strcmpW(rawinput_devices[i].path, info->Name.Buffer) == 0)
|
||||
+ {
|
||||
+ rawinput_devices[i].handle = device;
|
||||
+ return &rawinput_devices[i];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static void find_devices(void)
|
||||
{
|
||||
static ULONGLONG last_check;
|
||||
@@ -438,6 +474,7 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT
|
||||
handle, command, data, data_size);
|
||||
|
||||
if (!data_size) return ~0U;
|
||||
+ if (!device) return ~0U;
|
||||
|
||||
/* each case below must set:
|
||||
* *data_size: length (meaning defined by command) of data we want to copy
|
||||
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
|
||||
index 5172423280b..4c478db5449 100644
|
||||
--- a/dlls/user32/user_private.h
|
||||
+++ b/dlls/user32/user_private.h
|
||||
@@ -375,4 +375,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.25.1
|
||||
|
@ -1,8 +1,8 @@
|
||||
From 249548cff4ae17da6731e28a5fafe277a7b3d6ea Mon Sep 17 00:00:00 2001
|
||||
From 8f7a0c92c370cb4bf1ee6e6d7c51a3d90fe4cd48 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Wed, 18 Sep 2019 21:04:25 +0200
|
||||
Subject: [PATCH 5/5] hidclass.sys: Send input message to server when HID
|
||||
report is received.
|
||||
Subject: [PATCH] hidclass.sys: Send input message to server when HID report is
|
||||
received.
|
||||
|
||||
---
|
||||
dlls/hidclass.sys/device.c | 30 ++++++++++++++++++++++++++++++
|
||||
@ -135,5 +135,5 @@ index 1c130e8dd80..b84a358dba4 100644
|
||||
}
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
--
|
||||
2.24.1
|
||||
2.27.0
|
||||
|
||||
|
@ -1,2 +1 @@
|
||||
Depends: user32-rawinput-nolegacy
|
||||
Disabled: true
|
||||
Depends: user32-rawinput-mouse
|
||||
|
@ -1,82 +0,0 @@
|
||||
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,98 @@
|
||||
From f59841a0e07a536adda717cbe0bcd2686ab11507 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Sat, 6 Jun 2020 17:51:05 +0200
|
||||
Subject: [PATCH] dinput: Introduce dinput_keyboard_handle_key_event helper.
|
||||
|
||||
This factor the key event logic, so we can then use it in rawinput
|
||||
message handler as well.
|
||||
---
|
||||
dlls/dinput/keyboard.c | 52 +++++++++++++++++++++++++++---------------
|
||||
1 file changed, 33 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
|
||||
index 9981372d957..aa5bf30a378 100644
|
||||
--- a/dlls/dinput/keyboard.c
|
||||
+++ b/dlls/dinput/keyboard.c
|
||||
@@ -103,21 +103,16 @@ static BYTE map_dik_code(DWORD scanCode, DWORD vkCode, DWORD subType, DWORD vers
|
||||
return scanCode;
|
||||
}
|
||||
|
||||
-int dinput_keyboard_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam )
|
||||
+static void dinput_keyboard_handle_key_event( LPDIRECTINPUTDEVICE8A iface, DWORD vkey_code,
|
||||
+ DWORD scan_code, BOOL is_key_ext, BOOL is_key_up )
|
||||
{
|
||||
SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface);
|
||||
- int dik_code, ret = This->base.dwCoopLevel & DISCL_EXCLUSIVE;
|
||||
- KBDLLHOOKSTRUCT *hook = (KBDLLHOOKSTRUCT *)lparam;
|
||||
- BYTE new_diks;
|
||||
+ int dik_code;
|
||||
+ BYTE dik_state;
|
||||
|
||||
- if (wparam != WM_KEYDOWN && wparam != WM_KEYUP &&
|
||||
- wparam != WM_SYSKEYDOWN && wparam != WM_SYSKEYUP)
|
||||
- return 0;
|
||||
+ TRACE("(%p) vk %02x, scan %02x\n", iface, vkey_code, scan_code);
|
||||
|
||||
- TRACE("(%p) wp %08lx, lp %08lx, vk %02x, scan %02x\n",
|
||||
- iface, wparam, lparam, hook->vkCode, hook->scanCode);
|
||||
-
|
||||
- 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,24 +120,43 @@ int dinput_keyboard_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lpa
|
||||
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, This->base.dinput->dwVersion);
|
||||
- if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80;
|
||||
+ dik_code = map_dik_code(scan_code & 0xff, vkey_code, This->subtype, This->base.dinput->dwVersion);
|
||||
+ if (is_key_ext) dik_code |= 0x80;
|
||||
}
|
||||
- new_diks = hook->flags & LLKHF_UP ? 0 : 0x80;
|
||||
+ dik_state = (is_key_up ? 0 : 0x80);
|
||||
|
||||
/* returns now if key event already known */
|
||||
- if (new_diks == This->DInputKeyState[dik_code])
|
||||
- return ret;
|
||||
+ if (dik_state == This->DInputKeyState[dik_code])
|
||||
+ return;
|
||||
|
||||
- This->DInputKeyState[dik_code] = new_diks;
|
||||
+ This->DInputKeyState[dik_code] = dik_state;
|
||||
TRACE(" setting %02X to %02X\n", dik_code, This->DInputKeyState[dik_code]);
|
||||
|
||||
EnterCriticalSection(&This->base.crit);
|
||||
queue_event(iface, DIDFT_MAKEINSTANCE(dik_code) | DIDFT_PSHBUTTON,
|
||||
- new_diks, GetCurrentTime(), This->base.dinput->evsequence++);
|
||||
+ dik_state, GetCurrentTime(), This->base.dinput->evsequence++);
|
||||
LeaveCriticalSection(&This->base.crit);
|
||||
+}
|
||||
+
|
||||
+int dinput_keyboard_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam )
|
||||
+{
|
||||
+ SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface);
|
||||
+ KBDLLHOOKSTRUCT *hook = (KBDLLHOOKSTRUCT *)lparam;
|
||||
+ 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)
|
||||
+ return 0;
|
||||
+
|
||||
+ vkey_code = hook->vkCode;
|
||||
+ scan_code = hook->scanCode;
|
||||
+ is_key_ext = (hook->flags & LLKHF_EXTENDED);
|
||||
+ is_key_up = (hook->flags & LLKHF_UP);
|
||||
+
|
||||
+ dinput_keyboard_handle_key_event(iface, vkey_code, scan_code, is_key_ext, is_key_up);
|
||||
|
||||
- return ret;
|
||||
+ return (This->base.dwCoopLevel & DISCL_EXCLUSIVE);
|
||||
}
|
||||
|
||||
static DWORD get_keyboard_subtype(void)
|
||||
--
|
||||
2.27.0
|
||||
|
@ -1,146 +0,0 @@
|
||||
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,87 @@
|
||||
From 5449030617b7c85792128554b99b971ce2579e4d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Sat, 6 Jun 2020 17:52:26 +0200
|
||||
Subject: [PATCH] dinput8: Use rawinput interface for keyboard device.
|
||||
|
||||
---
|
||||
dlls/dinput/dinput_main.c | 10 ++++++++++
|
||||
dlls/dinput/dinput_private.h | 1 +
|
||||
dlls/dinput/keyboard.c | 22 ++++++++++++++++++++++
|
||||
3 files changed, 33 insertions(+)
|
||||
|
||||
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
|
||||
index 5e03964f901..0e45d821897 100644
|
||||
--- a/dlls/dinput/dinput_main.c
|
||||
+++ b/dlls/dinput/dinput_main.c
|
||||
@@ -662,6 +662,16 @@ static LRESULT WINAPI di_em_win_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPAR
|
||||
dinput_mouse_rawinput_hook( &dev->IDirectInputDevice8A_iface, wparam, lparam, &ri );
|
||||
LeaveCriticalSection( &dinput_hook_crit );
|
||||
}
|
||||
+ else if (ri.header.dwType == RIM_TYPEKEYBOARD)
|
||||
+ {
|
||||
+ EnterCriticalSection( &dinput_hook_crit );
|
||||
+ LIST_FOR_EACH_ENTRY( dev, &acquired_keyboard_list, IDirectInputDeviceImpl, entry )
|
||||
+ {
|
||||
+ if (!dev->use_raw_input) continue;
|
||||
+ dinput_keyboard_rawinput_hook( &dev->IDirectInputDevice8A_iface, wparam, lparam, &ri );
|
||||
+ }
|
||||
+ LeaveCriticalSection( &dinput_hook_crit );
|
||||
+ }
|
||||
}
|
||||
|
||||
return DefWindowProcW(hwnd, msg, wparam, lparam);
|
||||
diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h
|
||||
index c0c88da9674..690e4947f0b 100644
|
||||
--- a/dlls/dinput/dinput_private.h
|
||||
+++ b/dlls/dinput/dinput_private.h
|
||||
@@ -74,6 +74,7 @@ extern void dinput_hooks_unacquire_device(LPDIRECTINPUTDEVICE8W iface);
|
||||
extern int dinput_mouse_hook(LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam);
|
||||
extern int dinput_keyboard_hook(LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam);
|
||||
extern void dinput_mouse_rawinput_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam, RAWINPUT *raw );
|
||||
+extern void dinput_keyboard_rawinput_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam, RAWINPUT *raw );
|
||||
|
||||
extern void check_dinput_hooks(LPDIRECTINPUTDEVICE8W, BOOL) DECLSPEC_HIDDEN;
|
||||
extern void check_dinput_events(void) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
|
||||
index aa5bf30a378..fc59006018c 100644
|
||||
--- a/dlls/dinput/keyboard.c
|
||||
+++ b/dlls/dinput/keyboard.c
|
||||
@@ -138,6 +138,21 @@ static void dinput_keyboard_handle_key_event( LPDIRECTINPUTDEVICE8A iface, DWORD
|
||||
LeaveCriticalSection(&This->base.crit);
|
||||
}
|
||||
|
||||
+void dinput_keyboard_rawinput_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam, RAWINPUT *ri )
|
||||
+{
|
||||
+ DWORD vkey_code, scan_code;
|
||||
+ BOOL is_key_ext, is_key_up;
|
||||
+
|
||||
+ TRACE("(%p) wp %08lx, lp %08lx\n", iface, wparam, lparam);
|
||||
+
|
||||
+ vkey_code = ri->data.keyboard.VKey;
|
||||
+ scan_code = ri->data.keyboard.MakeCode;
|
||||
+ is_key_ext = (ri->data.keyboard.Flags & RI_KEY_E0);
|
||||
+ is_key_up = (ri->data.keyboard.Flags & RI_KEY_BREAK);
|
||||
+
|
||||
+ dinput_keyboard_handle_key_event(iface, vkey_code, scan_code, is_key_ext, is_key_up);
|
||||
+}
|
||||
+
|
||||
int dinput_keyboard_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam )
|
||||
{
|
||||
SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface);
|
||||
@@ -304,6 +319,13 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
|
||||
newDevice->base.data_format.wine_df = df;
|
||||
IDirectInput_AddRef(&newDevice->base.dinput->IDirectInput7A_iface);
|
||||
|
||||
+ 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:
|
||||
--
|
||||
2.27.0
|
||||
|
@ -0,0 +1,69 @@
|
||||
From fcf11610ea23ecb5a4b86e67c7c838457e2d8dcf Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Wed, 24 Jun 2020 12:13:02 +0200
|
||||
Subject: [PATCH] dinput8: Stop using LL hooks for keyboard devices.
|
||||
|
||||
---
|
||||
dlls/dinput/dinput_main.c | 17 +++++++++++------
|
||||
1 file changed, 11 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
|
||||
index 0e45d821897..9b6c4d4c434 100644
|
||||
--- a/dlls/dinput/dinput_main.c
|
||||
+++ b/dlls/dinput/dinput_main.c
|
||||
@@ -107,6 +107,7 @@ static struct list direct_input_list = LIST_INIT( direct_input_list );
|
||||
static struct list acquired_mouse_list = LIST_INIT( acquired_mouse_list );
|
||||
static struct list acquired_rawmouse_list = LIST_INIT( acquired_rawmouse_list );
|
||||
static struct list acquired_keyboard_list = LIST_INIT( acquired_keyboard_list );
|
||||
+static struct list acquired_rawkeyboard_list = LIST_INIT( acquired_rawkeyboard_list );
|
||||
static struct list acquired_device_list = LIST_INIT( acquired_device_list );
|
||||
|
||||
static HRESULT initialize_directinput_instance(IDirectInputImpl *This, DWORD dwVersion);
|
||||
@@ -120,7 +121,7 @@ void dinput_hooks_acquire_device(LPDIRECTINPUTDEVICE8W iface)
|
||||
if (IsEqualGUID( &dev->guid, &GUID_SysMouse ))
|
||||
list_add_tail( dev->use_raw_input ? &acquired_rawmouse_list : &acquired_mouse_list, &dev->entry );
|
||||
else if (IsEqualGUID( &dev->guid, &GUID_SysKeyboard ))
|
||||
- list_add_tail( &acquired_keyboard_list, &dev->entry );
|
||||
+ list_add_tail( dev->use_raw_input ? &acquired_rawkeyboard_list : &acquired_keyboard_list, &dev->entry );
|
||||
else
|
||||
list_add_tail( &acquired_device_list, &dev->entry );
|
||||
LeaveCriticalSection( &dinput_hook_crit );
|
||||
@@ -665,11 +666,8 @@ static LRESULT WINAPI di_em_win_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPAR
|
||||
else if (ri.header.dwType == RIM_TYPEKEYBOARD)
|
||||
{
|
||||
EnterCriticalSection( &dinput_hook_crit );
|
||||
- LIST_FOR_EACH_ENTRY( dev, &acquired_keyboard_list, IDirectInputDeviceImpl, entry )
|
||||
- {
|
||||
- if (!dev->use_raw_input) continue;
|
||||
+ LIST_FOR_EACH_ENTRY( dev, &acquired_rawkeyboard_list, IDirectInputDeviceImpl, entry )
|
||||
dinput_keyboard_rawinput_hook( &dev->IDirectInputDevice8A_iface, wparam, lparam, &ri );
|
||||
- }
|
||||
LeaveCriticalSection( &dinput_hook_crit );
|
||||
}
|
||||
}
|
||||
@@ -1736,7 +1734,6 @@ static LRESULT CALLBACK LL_hook_proc( int code, WPARAM wparam, LPARAM lparam )
|
||||
}
|
||||
LIST_FOR_EACH_ENTRY( dev, &acquired_keyboard_list, IDirectInputDeviceImpl, entry )
|
||||
{
|
||||
- if (dev->use_raw_input) continue;
|
||||
TRACE("calling dinput_keyboard_hook (%p %lx %lx)\n", dev, wparam, lparam);
|
||||
skip |= dinput_keyboard_hook( &dev->IDirectInputDevice8A_iface, wparam, lparam );
|
||||
}
|
||||
@@ -1790,6 +1787,14 @@ static LRESULT CALLBACK callwndproc_proc( int code, WPARAM wparam, LPARAM lparam
|
||||
IDirectInputDevice_Unacquire( &dev->IDirectInputDevice8A_iface );
|
||||
}
|
||||
}
|
||||
+ LIST_FOR_EACH_ENTRY_SAFE( dev, next, &acquired_rawkeyboard_list, IDirectInputDeviceImpl, entry )
|
||||
+ {
|
||||
+ if (msg->hwnd == dev->win && msg->hwnd != foreground)
|
||||
+ {
|
||||
+ TRACE( "%p window is not foreground - unacquiring %p\n", dev->win, dev );
|
||||
+ IDirectInputDevice_Unacquire( &dev->IDirectInputDevice8A_iface );
|
||||
+ }
|
||||
+ }
|
||||
LeaveCriticalSection( &dinput_hook_crit );
|
||||
|
||||
return CallNextHookEx( 0, code, wparam, lparam );
|
||||
--
|
||||
2.27.0
|
||||
|
@ -1,95 +0,0 @@
|
||||
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
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 18e2112beb69c8499cdd90b133348ec52502dc6d Mon Sep 17 00:00:00 2001
|
||||
From 58b859f29d69de9f86990170d637fb3a89c548bb 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.
|
||||
@ -79,10 +79,10 @@ index 37c96c926f4..4d113d8c184 100644
|
||||
* X11DRV_KEYBOARD_DetectLayout
|
||||
*
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index bc23b9cbba1..2e9b39fcff7 100644
|
||||
index e3c5f8d122e..95ece0710e5 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -406,6 +406,8 @@ void X11DRV_XInput2_Enable(void)
|
||||
@@ -415,6 +415,8 @@ void X11DRV_XInput2_Enable(void)
|
||||
{
|
||||
XISetMask( mask_bits, XI_RawButtonPress );
|
||||
XISetMask( mask_bits, XI_RawButtonRelease );
|
||||
@ -91,7 +91,7 @@ index bc23b9cbba1..2e9b39fcff7 100644
|
||||
data->xi2_rawinput_only = TRUE;
|
||||
}
|
||||
else
|
||||
@@ -2038,6 +2040,10 @@ BOOL X11DRV_GenericEvent( HWND hwnd, XEvent *xev )
|
||||
@@ -2123,6 +2125,10 @@ BOOL X11DRV_GenericEvent( HWND hwnd, XEvent *xev )
|
||||
case XI_RawButtonRelease:
|
||||
ret = X11DRV_RawButtonEvent( event );
|
||||
break;
|
||||
@ -103,10 +103,10 @@ index bc23b9cbba1..2e9b39fcff7 100644
|
||||
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
|
||||
index 396056464a7..eb6d6530c1e 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;
|
||||
@@ -517,6 +517,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;
|
||||
@ -115,5 +115,5 @@ index c843cd74ace..f89538a1755 100644
|
||||
extern BOOL X11DRV_DestroyNotify( HWND hwnd, XEvent *event ) DECLSPEC_HIDDEN;
|
||||
extern BOOL X11DRV_SelectionRequest( HWND hWnd, XEvent *event ) DECLSPEC_HIDDEN;
|
||||
--
|
||||
2.24.0
|
||||
2.27.0
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
Fixes: [35128] Air Conflicts (Pacific Carriers/Secret Wars) hangs at the loading screen (needs support for raw input in DInput8 keyboard)
|
||||
Depends: user32-rawinput-hid
|
||||
Disabled: True
|
||||
Disabled: true
|
||||
|
@ -1,7 +1,7 @@
|
||||
From c227552d313a51f625b741c330ce4509dff99cb5 Mon Sep 17 00:00:00 2001
|
||||
From 45bb2783e35fd9d20acc88bac151af3a57662edf 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.
|
||||
Subject: [PATCH] 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
|
||||
@ -18,18 +18,18 @@ 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/user32/rawinput.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 *
|
||||
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
|
||||
index 90dc911397d..d6dc377ddc3 100644
|
||||
--- a/dlls/user32/rawinput.c
|
||||
+++ b/dlls/user32/rawinput.c
|
||||
@@ -289,7 +289,12 @@ BOOL rawinput_from_hardware_message(RAWINPUT *rawinput, const struct hardware_ms
|
||||
rawinput->header.hDevice = WINE_MOUSE_HANDLE;
|
||||
rawinput->header.wParam = 0;
|
||||
|
||||
@ -44,10 +44,10 @@ index cc25d2f6c2f..26c3aa91421 100644
|
||||
rawinput->data.mouse.u.s.usButtonData = 0;
|
||||
for (i = 1; i < ARRAY_SIZE(button_flags); ++i)
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index d331ed5aef8..3474a176003 100644
|
||||
index ded877a140f..84a47f1e522 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
|
||||
@@ -331,32 +331,40 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
|
||||
struct x11drv_thread_data *thread_data = x11drv_thread_data();
|
||||
int i;
|
||||
|
||||
@ -106,7 +106,7 @@ index d331ed5aef8..3474a176003 100644
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -443,8 +451,8 @@ void X11DRV_XInput2_Disable(void)
|
||||
@@ -441,8 +449,8 @@ void X11DRV_XInput2_Disable(void)
|
||||
mask.deviceid = XIAllMasterDevices;
|
||||
|
||||
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
|
||||
@ -117,7 +117,7 @@ index d331ed5aef8..3474a176003 100644
|
||||
data->xi2_core_pointer = 0;
|
||||
#endif
|
||||
}
|
||||
@@ -1895,16 +1903,22 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
@@ -1893,16 +1901,22 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
INPUT input;
|
||||
int i;
|
||||
double dx = 0, dy = 0, val;
|
||||
@ -144,7 +144,7 @@ index d331ed5aef8..3474a176003 100644
|
||||
|
||||
input.type = INPUT_MOUSE;
|
||||
input.u.mi.mouseData = 0;
|
||||
@@ -1915,24 +1929,34 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
@@ -1913,24 +1927,34 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
input.u.mi.dy = 0;
|
||||
|
||||
virtual_rect = get_virtual_screen_rect();
|
||||
@ -192,7 +192,7 @@ index d331ed5aef8..3474a176003 100644
|
||||
}
|
||||
|
||||
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
|
||||
index 4a7cab67ada..c4218699034 100644
|
||||
index 6febdc18b0a..396056464a7 100644
|
||||
--- a/dlls/winex11.drv/x11drv.h
|
||||
+++ b/dlls/winex11.drv/x11drv.h
|
||||
@@ -32,6 +32,9 @@
|
||||
@ -219,7 +219,7 @@ index 4a7cab67ada..c4218699034 100644
|
||||
struct x11drv_thread_data
|
||||
{
|
||||
Display *display;
|
||||
@@ -341,11 +337,13 @@ struct x11drv_thread_data
|
||||
@@ -340,11 +336,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 */
|
||||
@ -235,7 +235,7 @@ index 4a7cab67ada..c4218699034 100644
|
||||
};
|
||||
|
||||
extern struct x11drv_thread_data *x11drv_init_thread_data(void) DECLSPEC_HIDDEN;
|
||||
@@ -431,6 +429,8 @@ enum x11drv_atoms
|
||||
@@ -429,6 +427,8 @@ enum x11drv_atoms
|
||||
XATOM_RAW_CAP_HEIGHT,
|
||||
XATOM_Rel_X,
|
||||
XATOM_Rel_Y,
|
||||
@ -245,10 +245,10 @@ index 4a7cab67ada..c4218699034 100644
|
||||
XATOM_WM_DELETE_WINDOW,
|
||||
XATOM_WM_STATE,
|
||||
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
|
||||
index f33a79d98bf..3e8dd82654a 100644
|
||||
index 4eaedd1c556..f08ac92e36f 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] =
|
||||
@@ -142,6 +142,8 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
|
||||
"RAW_CAP_HEIGHT",
|
||||
"Rel X",
|
||||
"Rel Y",
|
||||
@ -258,10 +258,10 @@ index f33a79d98bf..3e8dd82654a 100644
|
||||
"WM_DELETE_WINDOW",
|
||||
"WM_STATE",
|
||||
diff --git a/server/queue.c b/server/queue.c
|
||||
index f5dc06100d1..b369f0cdb78 100644
|
||||
index fbed47d6951..161b48e888f 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
|
||||
@@ -1783,8 +1783,8 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
|
||||
msg_data->info = input->mouse.info;
|
||||
msg_data->flags = flags;
|
||||
msg_data->rawinput.type = RIM_TYPEMOUSE;
|
||||
@ -271,7 +271,7 @@ index f5dc06100d1..b369f0cdb78 100644
|
||||
+ msg_data->rawinput.mouse.y = input->mouse.y;
|
||||
msg_data->rawinput.mouse.data = input->mouse.data;
|
||||
|
||||
if (req_flags == SEND_HWMSG_RAWINPUT)
|
||||
if ((req_flags & SEND_HWMSG_RAWINPUT))
|
||||
--
|
||||
2.24.1
|
||||
2.27.0
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 108f1467e2d2712b5fb8956e69d481a033cbcbfe Mon Sep 17 00:00:00 2001
|
||||
From ddb1995ab864885e9ab683a16f3594e712efa669 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.
|
||||
Subject: [PATCH] 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
|
||||
@ -13,10 +13,10 @@ This does not support mixed relative/absolute X/Y axis.
|
||||
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
|
||||
index 84a47f1e522..2fcacaee95c 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -1899,20 +1899,17 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
@@ -1897,20 +1897,17 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
{
|
||||
XIRawEvent *event = xev->data;
|
||||
const double *values = event->valuators.values;
|
||||
@ -39,7 +39,7 @@ index 3474a176003..a2310297ff9 100644
|
||||
if (!event->valuators.mask_len) return FALSE;
|
||||
if (thread_data->xi2_state != xi_enabled) return FALSE;
|
||||
if (event->deviceid != thread_data->xi2_core_pointer) return FALSE;
|
||||
@@ -1940,9 +1937,11 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
@@ -1938,9 +1935,11 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
{
|
||||
if (!XIMaskIsSet( event->valuators.mask, i )) continue;
|
||||
val = *values++;
|
||||
@ -51,7 +51,7 @@ index 3474a176003..a2310297ff9 100644
|
||||
input.u.mi.dwFlags |= (x_pos->mode == XIModeAbsolute ? MOUSEEVENTF_ABSOLUTE : 0);
|
||||
if (x_pos->mode == XIModeAbsolute)
|
||||
input.u.mi.dx = (dx - x_pos->min) * x_scale;
|
||||
@@ -1952,6 +1951,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
@@ -1950,6 +1949,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
if (i == y_pos->number)
|
||||
{
|
||||
dy = val;
|
||||
@ -59,7 +59,7 @@ index 3474a176003..a2310297ff9 100644
|
||||
input.u.mi.dwFlags |= (y_pos->mode == XIModeAbsolute ? MOUSEEVENTF_ABSOLUTE : 0);
|
||||
if (y_pos->mode == XIModeAbsolute)
|
||||
input.u.mi.dy = (dy - y_pos->min) * y_scale;
|
||||
@@ -1966,13 +1966,20 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
@@ -1964,13 +1964,20 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -82,5 +82,5 @@ index 3474a176003..a2310297ff9 100644
|
||||
__wine_send_input( 0, &input, SEND_HWMSG_RAWINPUT );
|
||||
}
|
||||
--
|
||||
2.24.1
|
||||
2.27.0
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From e53124abe8f6eaeebdb8ccb75cd884543f63a996 Mon Sep 17 00:00:00 2001
|
||||
From fd61f237db287d30a26fc6724103c871cff57bd2 Mon Sep 17 00:00:00 2001
|
||||
From: Jordan Galby <gravemind2a+wine@gmail.com>
|
||||
Date: Tue, 16 Jul 2019 00:34:38 -0400
|
||||
Subject: [PATCH 3/3] winex11.drv: Accumulate mouse movement to avoid rounding
|
||||
Subject: [PATCH] winex11.drv: Accumulate mouse movement to avoid rounding
|
||||
losses.
|
||||
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=42631
|
||||
@ -11,10 +11,10 @@ From: Jordan Galby <gravemind2a+wine@gmail.com>
|
||||
1 file changed, 33 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index a2310297ff9..e1273571fe2 100644
|
||||
index 2fcacaee95c..e3c5f8d122e 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -367,6 +367,9 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
|
||||
@@ -365,6 +365,9 @@ 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;
|
||||
@ -24,7 +24,7 @@ index a2310297ff9..e1273571fe2 100644
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1906,6 +1909,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
@@ -1904,6 +1907,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
double dx = 0, dy = 0, val;
|
||||
double raw_dx = 0, raw_dy = 0, raw_val;
|
||||
double x_scale = 1, y_scale = 1;
|
||||
@ -32,7 +32,7 @@ index a2310297ff9..e1273571fe2 100644
|
||||
struct x11drv_thread_data *thread_data = x11drv_thread_data();
|
||||
XIValuatorClassInfo *x_pos, *y_pos;
|
||||
|
||||
@@ -1917,6 +1921,9 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
@@ -1915,6 +1919,9 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
x_pos = &thread_data->x_pos_valuator;
|
||||
y_pos = &thread_data->y_pos_valuator;
|
||||
|
||||
@ -42,7 +42,7 @@ index a2310297ff9..e1273571fe2 100644
|
||||
input.type = INPUT_MOUSE;
|
||||
input.u.mi.mouseData = 0;
|
||||
input.u.mi.dwFlags = MOUSEEVENTF_MOVE;
|
||||
@@ -1944,9 +1951,9 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
@@ -1942,9 +1949,9 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
raw_dx = raw_val;
|
||||
input.u.mi.dwFlags |= (x_pos->mode == XIModeAbsolute ? MOUSEEVENTF_ABSOLUTE : 0);
|
||||
if (x_pos->mode == XIModeAbsolute)
|
||||
@ -54,7 +54,7 @@ index a2310297ff9..e1273571fe2 100644
|
||||
}
|
||||
if (i == y_pos->number)
|
||||
{
|
||||
@@ -1954,18 +1961,30 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
@@ -1952,18 +1959,30 @@ 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)
|
||||
@ -87,7 +87,7 @@ index a2310297ff9..e1273571fe2 100644
|
||||
if (x_pos->mode == XIModeAbsolute)
|
||||
{
|
||||
TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
|
||||
@@ -1973,14 +1992,21 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
@@ -1971,14 +1990,21 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
}
|
||||
else if (!thread_data->xi2_rawinput_only)
|
||||
{
|
||||
@ -113,5 +113,5 @@ index a2310297ff9..e1273571fe2 100644
|
||||
}
|
||||
return TRUE;
|
||||
--
|
||||
2.24.1
|
||||
2.27.0
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user