mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
244 lines
8.8 KiB
Diff
244 lines
8.8 KiB
Diff
|
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
|
||
|
|