On Sat, 2019-07-20 at 16:09 -0400, Derek Lesho wrote:
Signed-off-by: Derek Lesho
<dereklesho52(a)Gmail.com>
---
dlls/winex11.drv/mouse.c | 89 +++++++++++++++++++++++++++-------
dlls/winex11.drv/x11drv.h | 4 +-
dlls/winex11.drv/x11drv_main.c | 4 ++
3 files changed, 79 insertions(+), 18 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index f737a306a5..db71a33a41 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -284,11 +284,26 @@ static void update_relative_valuators(XIAnyClassInfo **valuators,
int n_valuator
}
#endif
+/***********************************************************************
+ * inform_wineserver
+ */
+static void inform_wineserver(void)
+{
+ static int once = 0;
+ if (!once)
+ {
+ RAWINPUT raw_input;
+ raw_input.header.dwType = RIM_ENABLE_NATIVE_MOUSE_MOVE;
+ __wine_send_raw_input(&raw_input);
+ once = 1;
+ }
+}
+
/***********************************************************************
- * 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();
@@ -318,7 +333,6 @@ static void enable_xinput2(void)
memset( mask_bits, 0, sizeof(mask_bits) );
XISetMask( mask_bits, XI_DeviceChanged );
XISetMask( mask_bits, XI_RawMotion );
- XISetMask( mask_bits, XI_ButtonPress );
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask,
1 );
@@ -337,19 +351,21 @@ static void enable_xinput2(void)
data->xi2_current_slave = 0;
data->xi2_state = xi_enabled;
+
+ inform_wineserver();
#endif
}
/***********************************************************************
- * 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;
@@ -368,6 +384,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
@@ -393,9 +424,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 );
@@ -423,7 +454,7 @@ static BOOL grab_clipping_window( const RECT *clip )
if (!clipping_cursor)
{
- disable_xinput2();
+ disable_xinput2_path();
DestroyWindow( msg_hwnd );
return FALSE;
}
@@ -489,7 +520,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 */
@@ -1724,16 +1755,19 @@ 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;
+ static unsigned long last_time = 0;
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 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
@@ -1758,12 +1792,20 @@ 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 );
input.u.mi.dwExtraInfo = 0;
- input.u.mi.dx = 0;
- input.u.mi.dy = 0;
+ 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.lLastX = 0;
+ raw_input.data.mouse.lLastY = 0;
virtual_rect = get_virtual_screen_rect();
@@ -1771,12 +1813,15 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
{
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)
{
@@ -1784,6 +1829,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;
}
}
@@ -1793,10 +1840,18 @@ 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 );
+ }
+
+ if (InterlockedExchange( (LONG volatile*)&last_time, (LONG)event->time ) !=
event->time)
+ {
+ 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;
}
I think it /should/ be safe to only call __wine_send_raw_input here,
although not 100% sure about it.
AFAICS MotionNotify events are sent as well - even with a 0x0 clip
rectangle - and they will get translated to the corresponding WM_MOUSE*
and WM_*BUTTON* events, and update the desktop cursor position if
necessary. I understand that the call was here only to trigger the raw
input emulation.
--
Rémi Bernon <rbernon(a)codeweavers.com>