mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-01-28 22:04:43 -08:00
Added user32-rawinput patchset
This include patch from winex11-mouse-movements.
This commit is contained in:
parent
618e349c72
commit
938dddf7df
@ -52,7 +52,7 @@ usage()
|
||||
# Get the upstream commit sha
|
||||
upstream_commit()
|
||||
{
|
||||
echo "a64b9c93b1eeef151221b5a100547fdae85435f4"
|
||||
echo "fb5b0c64639c056d55e14011a3b4e6f2d83e7cda"
|
||||
}
|
||||
|
||||
# Show version information
|
||||
@ -303,6 +303,7 @@ patch_enable_all ()
|
||||
enable_user32_ScrollWindowEx="$1"
|
||||
enable_user32_ShowWindow="$1"
|
||||
enable_user32_msgbox_Support_WM_COPY_mesg="$1"
|
||||
enable_user32_rawinput="$1"
|
||||
enable_user32_recursive_activation="$1"
|
||||
enable_uxtheme_CloseThemeClass="$1"
|
||||
enable_uxtheme_GTK_Theming="$1"
|
||||
@ -354,7 +355,6 @@ patch_enable_all ()
|
||||
enable_winex11__NET_ACTIVE_WINDOW="$1"
|
||||
enable_winex11_ime_check_thread_data="$1"
|
||||
enable_winex11_key_translation="$1"
|
||||
enable_winex11_mouse_movements="$1"
|
||||
enable_winex11_wglShareLists="$1"
|
||||
enable_winex11_drv_Query_server_position="$1"
|
||||
enable_winex11_drv_mouse_coorrds="$1"
|
||||
@ -1040,6 +1040,9 @@ patch_enable ()
|
||||
user32-msgbox-Support-WM_COPY-mesg)
|
||||
enable_user32_msgbox_Support_WM_COPY_mesg="$2"
|
||||
;;
|
||||
user32-rawinput)
|
||||
enable_user32_rawinput="$2"
|
||||
;;
|
||||
user32-recursive-activation)
|
||||
enable_user32_recursive_activation="$2"
|
||||
;;
|
||||
@ -1193,9 +1196,6 @@ patch_enable ()
|
||||
winex11-key_translation)
|
||||
enable_winex11_key_translation="$2"
|
||||
;;
|
||||
winex11-mouse-movements)
|
||||
enable_winex11_mouse_movements="$2"
|
||||
;;
|
||||
winex11-wglShareLists)
|
||||
enable_winex11_wglShareLists="$2"
|
||||
;;
|
||||
@ -6419,6 +6419,44 @@ if test "$enable_user32_msgbox_Support_WM_COPY_mesg" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset user32-rawinput
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#42675] - Overwatch - Phantom mouse input / view pulled up to ceiling.
|
||||
# | * [#45882] - Raw Input should use untransformed mouse values (affects Overwatch, several Source games).
|
||||
# | * [#47457] - Mouse click-click-hold is treated as double click, causing gun jam in Overwatch.
|
||||
# | * [#42631] - user32: Add Raw Input support.
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/user32/input.c, dlls/user32/message.c, dlls/user32/rawinput.c, dlls/user32/user32.spec, dlls/winex11.drv/event.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, server/trace.c, tools/make_requests
|
||||
# |
|
||||
if test "$enable_user32_rawinput" -eq 1; then
|
||||
patch_apply user32-rawinput/0001-user32-Add-support-for-RIDEV_NOLEGACY-flag.patch
|
||||
patch_apply user32-rawinput/0002-server-Move-mouse-raw-input-message-faking-from-user.patch
|
||||
patch_apply user32-rawinput/0003-server-Add-request-for-sending-native-raw-input-mess.patch
|
||||
patch_apply user32-rawinput/0004-user32-Add-helper-for-input-drivers-to-submit-native.patch
|
||||
patch_apply user32-rawinput/0005-server-Don-t-emulate-rawinput-mouse-events-if-native.patch
|
||||
patch_apply user32-rawinput/0006-winex11.drv-Directly-listen-to-master-XInput2-device.patch
|
||||
patch_apply user32-rawinput/0007-winex11.drv-Implement-native-mouse-movement-raw-inpu.patch
|
||||
patch_apply user32-rawinput/0008-winex11.drv-Implement-native-mouse-button-raw-input-.patch
|
||||
patch_apply user32-rawinput/0009-winex11.drv-Don-t-react-to-small-slow-mouse-movement.patch
|
||||
patch_apply user32-rawinput/0010-server-Implement-RIDEV_INPUTSINK-flag.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Derek Lesho", "user32: Add support for RIDEV_NOLEGACY flag.", 1 },';
|
||||
printf '%s\n' '+ { "Derek Lesho", "server: Move mouse raw-input message faking from user32 to wineserver.", 1 },';
|
||||
printf '%s\n' '+ { "Derek Lesho", "server: Add request for sending native raw-input messages.", 1 },';
|
||||
printf '%s\n' '+ { "Derek Lesho", "user32: Add helper for input drivers to submit native rawinput msgs.", 1 },';
|
||||
printf '%s\n' '+ { "Derek Lesho", "server: Don'\''t emulate rawinput mouse events if native exist.", 1 },';
|
||||
printf '%s\n' '+ { "Rémi Bernon", "winex11.drv: Directly listen to master XInput2 devices if supported.", 1 },';
|
||||
printf '%s\n' '+ { "Derek Lesho", "winex11.drv: Implement native mouse-movement raw-input using RawMotion.", 1 },';
|
||||
printf '%s\n' '+ { "Derek Lesho", "winex11.drv: Implement native mouse-button raw-input using RawButton*.", 1 },';
|
||||
printf '%s\n' '+ { "Jordan Galby", "winex11.drv: Don'\''t react to small slow mouse movements.", 1 },';
|
||||
printf '%s\n' '+ { "Derek Lesho", "server: Implement RIDEV_INPUTSINK flag.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset user32-recursive-activation
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
@ -7220,21 +7258,6 @@ if test "$enable_winex11_key_translation" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset winex11-mouse-movements
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#42631] Mouse drift, jump or don't react to small slow movements in Unity-engine games
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/winex11.drv/mouse.c, dlls/winex11.drv/x11drv.h
|
||||
# |
|
||||
if test "$enable_winex11_mouse_movements" -eq 1; then
|
||||
patch_apply winex11-mouse-movements/0001-winex11-Don-t-react-to-small-slow-mouse-movements.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Jordan Galby", "winex11: Don'\''t react to small slow mouse movements.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset winex11-wglShareLists
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
|
@ -0,0 +1,61 @@
|
||||
From 5b72eb081757521ee2f86aad97c36ed751733b1d 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/10] 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 49cf9f73a0..58480b8ae7 100644
|
||||
--- a/dlls/user32/rawinput.c
|
||||
+++ b/dlls/user32/rawinput.c
|
||||
@@ -271,7 +271,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 96587d11d1..40a566a2b7 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
|
||||
|
@ -0,0 +1,165 @@
|
||||
From 8cd2c66e39dee6edb4dda9faef5601785a8eb9eb 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/10] 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 43ce77c2dd..b6dd7d5932 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 8157199f2f..f7e0008b04 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 40a566a2b7..b58dfd5213 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
|
||||
|
@ -0,0 +1,194 @@
|
||||
From c086e4c12e621444c4f1922d4fd48b57423d430d 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/10] server: Add request for sending native raw-input
|
||||
messages.
|
||||
|
||||
Signed-off-by: Derek Lesho <dereklesho52@Gmail.com>
|
||||
---
|
||||
server/protocol.def | 50 ++++++++++++++++++++++++++++-----------------
|
||||
server/queue.c | 48 +++++++++++++++++++++++++++++++++++++++++++
|
||||
server/trace.c | 21 +++++++++++++++++++
|
||||
tools/make_requests | 1 +
|
||||
4 files changed, 101 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index f7e0008b04..15cd48bbb5 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -286,31 +286,38 @@ 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 */
|
||||
+ 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 +2325,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 b58dfd5213..c61fd28a24 100644
|
||||
--- a/server/queue.c
|
||||
+++ b/server/queue.c
|
||||
@@ -2421,6 +2421,54 @@ 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;
|
||||
+
|
||||
+ 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 0df649ea29..d849d89772 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,x=%d,y=%d,button_flags=%04hx,button_data=%04hx}",
|
||||
+ prefix, 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..8b1f1a263b 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" => [ 16, 8, "&dump_hw_rawinput" ]
|
||||
);
|
||||
|
||||
my @requests = ();
|
||||
--
|
||||
2.23.0
|
||||
|
@ -0,0 +1,86 @@
|
||||
From 4e45880cdd3493507dbc26f840dbe96dc089f032 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/10] 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..f3f5646a4c 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.usFlags ||
|
||||
+ raw_input->data.mouse.ulRawButtons ||
|
||||
+ raw_input->data.mouse.ulExtraInformation)
|
||||
+ FIXME("Unhandled parameters\n");
|
||||
+
|
||||
+ 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
|
||||
|
@ -0,0 +1,45 @@
|
||||
From ac1dd32eca67140548a27b40904cccd56c785d7d 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/10] 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 c61fd28a24..e540fd0a64 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
|
||||
|
@ -0,0 +1,201 @@
|
||||
From b33da9582fa3d8a6bd761abf72542d24a10fb948 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/10] 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 5c465aa033..1e64f0d2a3 100644
|
||||
--- a/dlls/winex11.drv/event.c
|
||||
+++ b/dlls/winex11.drv/event.c
|
||||
@@ -271,46 +271,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
|
||||
*
|
||||
@@ -362,7 +322,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 f737a306a5..578efa1931 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -130,6 +130,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);
|
||||
@@ -301,8 +303,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;
|
||||
@@ -314,12 +319,20 @@ 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 );
|
||||
|
||||
+ /* 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;
|
||||
+ XISetMask( mask_bits, XI_DeviceChanged );
|
||||
+ }
|
||||
+
|
||||
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
|
||||
|
||||
pointer_info = pXIQueryDevice( data->display, data->xi2_core_pointer, &count );
|
||||
@@ -333,7 +346,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;
|
||||
@@ -356,7 +369,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 );
|
||||
@@ -1735,25 +1754,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
|
||||
|
@ -0,0 +1,243 @@
|
||||
From 81a576cc51c02c93a20bf874052be30c8de2d950 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/10] winex11.drv: Implement native mouse-movement raw-input
|
||||
using RawMotion.
|
||||
|
||||
Signed-off-by: Derek Lesho <dereklesho52@Gmail.com>
|
||||
---
|
||||
dlls/winex11.drv/mouse.c | 66 ++++++++++++++++++++++++++--------
|
||||
dlls/winex11.drv/x11drv.h | 4 ++-
|
||||
dlls/winex11.drv/x11drv_main.c | 4 +++
|
||||
3 files changed, 58 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index 578efa1931..26d5e6a575 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -288,9 +288,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();
|
||||
@@ -322,7 +322,6 @@ static void enable_xinput2(void)
|
||||
mask.deviceid = XIAllMasterDevices;
|
||||
memset( mask_bits, 0, sizeof(mask_bits) );
|
||||
XISetMask( mask_bits, XI_RawMotion );
|
||||
- XISetMask( mask_bits, XI_ButtonPress );
|
||||
|
||||
/* XInput 2.0 has a problematic behavior where master pointer will
|
||||
* not send raw events to the root window whenever a grab is active
|
||||
@@ -354,15 +353,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;
|
||||
@@ -387,6 +386,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
|
||||
@@ -412,9 +426,9 @@ static BOOL grab_clipping_window( const RECT *clip )
|
||||
return TRUE;
|
||||
|
||||
/* 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 );
|
||||
@@ -442,7 +456,7 @@ static BOOL grab_clipping_window( const RECT *clip )
|
||||
|
||||
if (!clipping_cursor)
|
||||
{
|
||||
- disable_xinput2();
|
||||
+ disable_xinput2_path();
|
||||
DestroyWindow( msg_hwnd );
|
||||
return FALSE;
|
||||
}
|
||||
@@ -508,7 +522,7 @@ LRESULT clip_cursor_notify( HWND 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 */
|
||||
@@ -1743,16 +1757,18 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
{
|
||||
XIRawEvent *event = xev->data;
|
||||
const double *values = event->valuators.values;
|
||||
+ const double *raw_values = event->raw_values;
|
||||
RECT virtual_rect;
|
||||
INPUT input;
|
||||
+ RAWINPUT raw_input;
|
||||
int i;
|
||||
- double dx = 0, dy = 0, val;
|
||||
+ double dx = 0, dy = 0, raw_dx = 0, raw_dy = 0, val, raw_val;
|
||||
struct x11drv_thread_data *thread_data = x11drv_thread_data();
|
||||
struct x11drv_valuator_data *x_rel, *y_rel;
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -1784,6 +1800,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 );
|
||||
@@ -1791,18 +1808,30 @@ 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++)
|
||||
{
|
||||
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.lLastX = raw_dx = raw_val;
|
||||
}
|
||||
if (i == y_rel->number)
|
||||
{
|
||||
@@ -1810,6 +1839,8 @@ 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.lLastY = raw_dy = raw_val;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1819,10 +1850,15 @@ 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 event %f,%f\n", raw_dx, raw_dy);
|
||||
+ __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 0d3695bdcf..2223629c7b 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,7 +337,7 @@ struct x11drv_thread_data
|
||||
HWND clip_hwnd; /* message window stored in desktop while clipping is active */
|
||||
DWORD clip_reset; /* time when clipping was last reset */
|
||||
HKL kbd_layout; /* active keyboard layout */
|
||||
- enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled } xi2_state; /* XInput2 state */
|
||||
+ enum { 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;
|
||||
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
|
||||
index 21807af3f1..214c101b67 100644
|
||||
--- a/dlls/winex11.drv/x11drv_main.c
|
||||
+++ b/dlls/winex11.drv/x11drv_main.c
|
||||
@@ -611,6 +611,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 +683,8 @@ struct x11drv_thread_data *x11drv_init_thread_data(void)
|
||||
|
||||
if (use_xim) X11DRV_SetupXIM();
|
||||
|
||||
+ X11DRV_XInput2_Enable();
|
||||
+
|
||||
return data;
|
||||
}
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
@ -0,0 +1,218 @@
|
||||
From b187bccf25714eb5cde3e785e52aba2166f0bbec 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/10] winex11.drv: Implement native mouse-button raw-input
|
||||
using RawButton*.
|
||||
|
||||
Signed-off-by: Derek Lesho <dereklesho52@Gmail.com>
|
||||
---
|
||||
dlls/winex11.drv/mouse.c | 89 ++++++++++++++++++++++++++++++++--
|
||||
dlls/winex11.drv/x11drv.h | 2 +
|
||||
dlls/winex11.drv/x11drv_main.c | 1 +
|
||||
3 files changed, 87 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index 26d5e6a575..df60c41e61 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -259,6 +259,7 @@ 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->wheel_valuator.number = -1;
|
||||
|
||||
for (i = 0; i < n_valuators; i++)
|
||||
{
|
||||
@@ -276,6 +277,11 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
|
||||
{
|
||||
valuator_data = &thread_data->y_rel_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;
|
||||
@@ -322,6 +328,8 @@ void X11DRV_XInput2_Enable(void)
|
||||
mask.deviceid = XIAllMasterDevices;
|
||||
memset( mask_bits, 0, sizeof(mask_bits) );
|
||||
XISetMask( mask_bits, XI_RawMotion );
|
||||
+ 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
|
||||
@@ -380,6 +388,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;
|
||||
@@ -1762,11 +1771,11 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
INPUT input;
|
||||
RAWINPUT raw_input;
|
||||
int i;
|
||||
- double dx = 0, dy = 0, raw_dx = 0, raw_dy = 0, val, raw_val;
|
||||
+ double dx = 0, dy = 0, raw_dx = 0, raw_dy = 0, raw_dwheel = 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, *wheel;
|
||||
|
||||
- if (thread_data->x_rel_valuator.number < 0 || thread_data->y_rel_valuator.number < 0) return FALSE;
|
||||
+ if (thread_data->x_rel_valuator.number < 0 || thread_data->y_rel_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;
|
||||
|
||||
@@ -1799,6 +1808,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
|
||||
x_rel = &thread_data->x_rel_valuator;
|
||||
y_rel = &thread_data->y_rel_valuator;
|
||||
+ wheel = &thread_data->wheel_valuator;
|
||||
|
||||
input.type = INPUT_MOUSE;
|
||||
input.u.mi.mouseData = 0;
|
||||
@@ -1819,7 +1829,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
|
||||
virtual_rect = get_virtual_screen_rect();
|
||||
|
||||
- for (i = 0; i <= max ( x_rel->number, y_rel->number ); i++)
|
||||
+ for (i = 0; i <= max( wheel->number, max( x_rel->number, y_rel->number ) ); i++)
|
||||
{
|
||||
if (!XIMaskIsSet( event->valuators.mask, i )) continue;
|
||||
val = *values++;
|
||||
@@ -1842,6 +1852,13 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
|
||||
raw_input.data.mouse.lLastY = raw_dy = raw_val;
|
||||
}
|
||||
+ if (i == wheel->number)
|
||||
+ {
|
||||
+ /* NOTE: Testing showed a 8x factor between X11 and Windows
|
||||
+ * values, but that may be device specific
|
||||
+ */
|
||||
+ raw_dwheel = raw_val * -8;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (broken_rawevents && is_old_motion_event( xev->serial ))
|
||||
@@ -1856,12 +1873,69 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
__wine_send_input( 0, &input );
|
||||
}
|
||||
|
||||
- TRACE("raw event %f,%f\n", raw_dx, raw_dy);
|
||||
+ if (raw_dwheel)
|
||||
+ {
|
||||
+ raw_input.data.mouse.u.usButtonFlags = RI_MOUSE_WHEEL;
|
||||
+ raw_input.data.mouse.u.usButtonData = raw_dwheel;
|
||||
+ }
|
||||
+
|
||||
+ TRACE("raw event %f,%f + %f\n", raw_dx, raw_dy, 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 */
|
||||
|
||||
|
||||
@@ -1926,6 +2000,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 2223629c7b..c74f1493c0 100644
|
||||
--- a/dlls/winex11.drv/x11drv.h
|
||||
+++ b/dlls/winex11.drv/x11drv.h
|
||||
@@ -342,6 +342,7 @@ struct x11drv_thread_data
|
||||
int xi2_device_count;
|
||||
struct x11drv_valuator_data x_rel_valuator;
|
||||
struct x11drv_valuator_data y_rel_valuator;
|
||||
+ struct x11drv_valuator_data wheel_valuator;
|
||||
int xi2_core_pointer; /* XInput2 core pointer id */
|
||||
int xi2_current_slave; /* Current slave driving the Core pointer */
|
||||
};
|
||||
@@ -427,6 +428,7 @@ enum x11drv_atoms
|
||||
XATOM_RAW_CAP_HEIGHT,
|
||||
XATOM_Rel_X,
|
||||
XATOM_Rel_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 214c101b67..86b6efac08 100644
|
||||
--- a/dlls/winex11.drv/x11drv_main.c
|
||||
+++ b/dlls/winex11.drv/x11drv_main.c
|
||||
@@ -120,6 +120,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
|
||||
"RAW_CAP_HEIGHT",
|
||||
"Rel X",
|
||||
"Rel Y",
|
||||
+ "Rel Vert Scroll",
|
||||
"WM_PROTOCOLS",
|
||||
"WM_DELETE_WINDOW",
|
||||
"WM_STATE",
|
||||
--
|
||||
2.23.0
|
||||
|
@ -0,0 +1,120 @@
|
||||
From 4d2c65f23588f7953f93ab1426bc88e0bdc977a2 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/10] 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 df60c41e61..6df473e548 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -261,6 +261,10 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
|
||||
thread_data->y_rel_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;
|
||||
+
|
||||
for (i = 0; i < n_valuators; i++)
|
||||
{
|
||||
XIValuatorClassInfo *class = (XIValuatorClassInfo *)valuators[i];
|
||||
@@ -1836,18 +1840,18 @@ 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.lLastX = raw_dx = raw_val;
|
||||
}
|
||||
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.lLastY = raw_dy = raw_val;
|
||||
@@ -1863,20 +1867,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 (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 (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 event %f,%f + %f\n", raw_dx, raw_dy, raw_dwheel);
|
||||
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
|
||||
index c74f1493c0..8a59874251 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
|
||||
|
@ -0,0 +1,42 @@
|
||||
From 0f75495249bd3b4a78daab8efde1421602f8062d 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/10] 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 58480b8ae7..c231e2059c 100644
|
||||
--- a/dlls/user32/rawinput.c
|
||||
+++ b/dlls/user32/rawinput.c
|
||||
@@ -271,7 +271,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 e540fd0a64..c76b18afcd 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
|
||||
|
5
patches/user32-rawinput/definition
Normal file
5
patches/user32-rawinput/definition
Normal file
@ -0,0 +1,5 @@
|
||||
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.
|
||||
|
@ -1,104 +0,0 @@
|
||||
From 005267dd840714e4b47a608c0f196a45904d080a Mon Sep 17 00:00:00 2001
|
||||
From: Jordan Galby <gravemind2a+wine@gmail.com>
|
||||
Date: Thu, 30 Aug 2018 11:59:12 +1000
|
||||
Subject: [PATCH] winex11: Don't react to small slow mouse movements
|
||||
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=42631
|
||||
---
|
||||
dlls/winex11.drv/mouse.c | 36 ++++++++++++++++++++++++++++--------
|
||||
dlls/winex11.drv/x11drv.h | 1 +
|
||||
2 files changed, 29 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
||||
index 10985c1..27a0c35 100644
|
||||
--- a/dlls/winex11.drv/mouse.c
|
||||
+++ b/dlls/winex11.drv/mouse.c
|
||||
@@ -257,6 +257,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_rel_valuator.accum = 0;
|
||||
+ thread_data->y_rel_valuator.accum = 0;
|
||||
|
||||
for (i = 0; i < n_valuators; i++)
|
||||
{
|
||||
@@ -362,6 +364,8 @@ static void disable_xinput2(void)
|
||||
pXIFreeDeviceInfo( data->xi2_devices );
|
||||
data->x_rel_valuator.number = -1;
|
||||
data->y_rel_valuator.number = -1;
|
||||
+ data->x_rel_valuator.accum = 0;
|
||||
+ data->y_rel_valuator.accum = 0;
|
||||
data->xi2_devices = NULL;
|
||||
data->xi2_core_pointer = 0;
|
||||
data->xi2_current_slave = 0;
|
||||
@@ -1769,31 +1773,47 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
||||
|
||||
for (i = 0; i <= max ( x_rel->number, y_rel->number ); i++)
|
||||
{
|
||||
- if (!XIMaskIsSet( event->valuators.mask, i )) continue;
|
||||
+ if (!XIMaskIsSet( event->valuators.mask, i ))
|
||||
+ continue;
|
||||
val = *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)
|
||||
- / (x_rel->max - x_rel->min);
|
||||
+ dx = val * (virtual_rect.right - virtual_rect.left)
|
||||
+ / (x_rel->max - x_rel->min);
|
||||
}
|
||||
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)
|
||||
- / (y_rel->max - y_rel->min);
|
||||
+ dy = val * (virtual_rect.bottom - virtual_rect.top)
|
||||
+ / (y_rel->max - y_rel->min);
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Accumulate the *double* dx/dy motions so sub-pixel motions wont be lost
|
||||
+ * when sent/cast to *LONG* input.u.mi.dx/dy.
|
||||
+ */
|
||||
+ x_rel->accum += dx;
|
||||
+ y_rel->accum += dy;
|
||||
+ if (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 );
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+ 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 (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;
|
||||
}
|
||||
|
||||
- TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
|
||||
+ TRACE( "pos %d,%d (event %f,%f, accum %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy, x_rel->accum, y_rel->accum );
|
||||
|
||||
input.type = INPUT_MOUSE;
|
||||
__wine_send_input( 0, &input );
|
||||
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
|
||||
index a0308b0..3df6b7a 100644
|
||||
--- a/dlls/winex11.drv/x11drv.h
|
||||
+++ b/dlls/winex11.drv/x11drv.h
|
||||
@@ -318,6 +318,7 @@ struct x11drv_valuator_data
|
||||
double min;
|
||||
double max;
|
||||
int number;
|
||||
+ double accum;
|
||||
};
|
||||
|
||||
struct x11drv_thread_data
|
||||
--
|
||||
1.9.1
|
||||
|
@ -1 +0,0 @@
|
||||
Fixes: [42631] Mouse drift, jump or don't react to small slow movements in Unity-engine games
|
Loading…
x
Reference in New Issue
Block a user