Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winex11.drv/mouse.c | 125 ++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 61 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 42bac332664..2243261e0b8 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -634,6 +634,65 @@ static void map_event_coords( HWND hwnd, Window window, Window event_root, int x input->u.mi.dy = pt.y; }
+static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) +{ + struct x11drv_thread_data *thread_data = x11drv_thread_data(); + const double *values = event->valuators.values; + struct x11drv_valuator_data *x_rel, *y_rel; + double dx = 0, dy = 0, val; + RECT virtual_rect; + int i; + + if (thread_data->x_rel_valuator.number < 0 || thread_data->y_rel_valuator.number < 0) return FALSE; + if (!event->valuators.mask_len) return FALSE; + if (thread_data->xi2_state != xi_enabled) return FALSE; + + /* If there is no slave currently detected, no previous motion nor device + * change events were received. Look it up now on the device list in this + * case. + */ + if (!thread_data->xi2_current_slave) + { + XIDeviceInfo *devices = thread_data->xi2_devices; + + for (i = 0; i < thread_data->xi2_device_count; i++) + { + if (devices[i].use != XISlavePointer) continue; + if (devices[i].deviceid != event->deviceid) continue; + if (devices[i].attachment != thread_data->xi2_core_pointer) continue; + thread_data->xi2_current_slave = event->deviceid; + break; + } + } + if (event->deviceid != thread_data->xi2_current_slave) return FALSE; + + x_rel = &thread_data->x_rel_valuator; + y_rel = &thread_data->y_rel_valuator; + + 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++; + 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); + } + if (i == y_rel->number) + { + input->u.mi.dy = dy = val; + if (y_rel->min < y_rel->max) + input->u.mi.dy = val * (virtual_rect.bottom - virtual_rect.top) / (y_rel->max - y_rel->min); + } + } + + TRACE( "pos %d,%d (event %f,%f)\n", input->u.mi.dx, input->u.mi.dy, dx, dy ); + return TRUE; +} +
/*********************************************************************** * send_mouse_input @@ -1827,79 +1886,23 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev ) static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) { XIRawEvent *event = xev->data; - const double *values = event->valuators.values; - RECT virtual_rect; INPUT input; - int i; - double dx = 0, dy = 0, 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 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 (broken_rawevents && is_old_motion_event( xev->serial )) { - XIDeviceInfo *devices = thread_data->xi2_devices; - - for (i = 0; i < thread_data->xi2_device_count; i++) - { - if (devices[i].use != XISlavePointer) continue; - if (devices[i].deviceid != event->deviceid) continue; - if (devices[i].attachment != thread_data->xi2_core_pointer) continue; - thread_data->xi2_current_slave = event->deviceid; - break; - } + TRACE( "old serial %lu, ignoring\n", xev->serial ); + return FALSE; }
- if (event->deviceid != thread_data->xi2_current_slave) return FALSE; - - 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; + if (!map_raw_event_coords( event, &input )) return FALSE;
- 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++; - 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); - } - if (i == y_rel->number) - { - input.u.mi.dy = dy = val; - if (y_rel->min < y_rel->max) - input.u.mi.dy = val * (virtual_rect.bottom - virtual_rect.top) - / (y_rel->max - y_rel->min); - } - } - - 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 ); - - input.type = INPUT_MOUSE; __wine_send_input( 0, &input, NULL ); return TRUE; }
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winex11.drv/mouse.c | 18 +++--------------- dlls/winex11.drv/window.c | 3 +++ dlls/winex11.drv/x11drv.h | 16 +++++++--------- 3 files changed, 13 insertions(+), 24 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 2243261e0b8..c6daa30392c 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -262,25 +262,13 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator for (i = 0; i < n_valuators; i++) { XIValuatorClassInfo *class = (XIValuatorClassInfo *)valuators[i]; - struct x11drv_valuator_data *valuator_data = NULL; - if (valuators[i]->type != XIValuatorClass) continue; if (class->label == x11drv_atom( Rel_X ) || (!class->label && class->number == 0 && class->mode == XIModeRelative)) - { - valuator_data = &thread_data->x_rel_valuator; - } + thread_data->x_rel_valuator = *class; else if (class->label == x11drv_atom( Rel_Y ) || (!class->label && class->number == 1 && class->mode == XIModeRelative)) - { - valuator_data = &thread_data->y_rel_valuator; - } - - if (valuator_data) { - valuator_data->number = class->number; - valuator_data->min = class->min; - valuator_data->max = class->max; - } + thread_data->y_rel_valuator = *class; } } #endif @@ -638,7 +626,7 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) { struct x11drv_thread_data *thread_data = x11drv_thread_data(); const double *values = event->valuators.values; - struct x11drv_valuator_data *x_rel, *y_rel; + XIValuatorClassInfo *x_rel, *y_rel; double dx = 0, dy = 0, val; RECT virtual_rect; int i; diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 7ec2639e309..bcb0b8044bc 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -36,6 +36,9 @@ #ifdef HAVE_LIBXSHAPE #include <X11/extensions/shape.h> #endif /* HAVE_LIBXSHAPE */ +#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H +#include <X11/extensions/XInput2.h> +#endif
/* avoid conflict with field names in included win32 headers */ #undef Status diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index e82ee921830..962fe373833 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -32,6 +32,9 @@ #include <X11/Xresource.h> #include <X11/Xutil.h> #include <X11/Xatom.h> +#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H +#include <X11/extensions/XInput2.h> +#endif
#define BOOL X_BOOL #define BYTE X_BYTE @@ -314,13 +317,6 @@ struct x11drv_escape_flush_gl_drawable * X11 USER driver */
-struct x11drv_valuator_data -{ - double min; - double max; - int number; -}; - struct x11drv_thread_data { Display *display; @@ -335,13 +331,15 @@ struct x11drv_thread_data Window clip_window; /* window used for cursor clipping */ HWND clip_hwnd; /* message window stored in desktop while clipping is active */ DWORD clip_reset; /* time when clipping was last reset */ +#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled } xi2_state; /* XInput2 state */ void *xi2_devices; /* list of XInput2 devices (valid when state is enabled) */ int xi2_device_count; - struct x11drv_valuator_data x_rel_valuator; - struct x11drv_valuator_data y_rel_valuator; + XIValuatorClassInfo x_rel_valuator; + XIValuatorClassInfo y_rel_valuator; int xi2_core_pointer; /* XInput2 core pointer id */ int xi2_current_slave; /* Current slave driving the Core pointer */ +#endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */ };
extern struct x11drv_thread_data *x11drv_init_thread_data(void) DECLSPEC_HIDDEN;
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winex11.drv/mouse.c | 33 +++++++++++++++------------------ dlls/winex11.drv/x11drv.h | 4 ++-- 2 files changed, 17 insertions(+), 20 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index c6daa30392c..1ef7027e838 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -256,8 +256,8 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator struct x11drv_thread_data *thread_data = x11drv_thread_data(); int i;
- thread_data->x_rel_valuator.number = -1; - thread_data->y_rel_valuator.number = -1; + thread_data->x_valuator.number = -1; + thread_data->y_valuator.number = -1;
for (i = 0; i < n_valuators; i++) { @@ -265,10 +265,10 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator if (valuators[i]->type != XIValuatorClass) continue; if (class->label == x11drv_atom( Rel_X ) || (!class->label && class->number == 0 && class->mode == XIModeRelative)) - thread_data->x_rel_valuator = *class; + thread_data->x_valuator = *class; else if (class->label == x11drv_atom( Rel_Y ) || (!class->label && class->number == 1 && class->mode == XIModeRelative)) - thread_data->y_rel_valuator = *class; + thread_data->y_valuator = *class; } } #endif @@ -349,8 +349,8 @@ static void disable_xinput2(void)
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 ); pXIFreeDeviceInfo( data->xi2_devices ); - data->x_rel_valuator.number = -1; - data->y_rel_valuator.number = -1; + data->x_valuator.number = -1; + data->y_valuator.number = -1; data->xi2_devices = NULL; data->xi2_core_pointer = 0; data->xi2_current_slave = 0; @@ -625,13 +625,13 @@ static void map_event_coords( HWND hwnd, Window window, Window event_root, int x static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) { struct x11drv_thread_data *thread_data = x11drv_thread_data(); + XIValuatorClassInfo *x = &thread_data->x_valuator, *y = &thread_data->y_valuator; const double *values = event->valuators.values; - XIValuatorClassInfo *x_rel, *y_rel; double dx = 0, dy = 0, val; RECT virtual_rect; int i;
- if (thread_data->x_rel_valuator.number < 0 || thread_data->y_rel_valuator.number < 0) return FALSE; + if (x->number < 0 || y->number < 0) return FALSE; if (!event->valuators.mask_len) return FALSE; if (thread_data->xi2_state != xi_enabled) return FALSE;
@@ -654,26 +654,23 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) } if (event->deviceid != thread_data->xi2_current_slave) return FALSE;
- x_rel = &thread_data->x_rel_valuator; - y_rel = &thread_data->y_rel_valuator; - virtual_rect = get_virtual_screen_rect();
- for (i = 0; i <= max( x_rel->number, y_rel->number ); i++) + for (i = 0; i <= max( x->number, y->number ); i++) { if (!XIMaskIsSet( event->valuators.mask, i )) continue; val = *values++; - if (i == x_rel->number) + if (i == x->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); + if (x->min < x->max) + input->u.mi.dx = val * (virtual_rect.right - virtual_rect.left) / (x->max - x->min); } - if (i == y_rel->number) + if (i == y->number) { input->u.mi.dy = dy = val; - if (y_rel->min < y_rel->max) - input->u.mi.dy = val * (virtual_rect.bottom - virtual_rect.top) / (y_rel->max - y_rel->min); + if (y->min < y->max) + input->u.mi.dy = val * (virtual_rect.bottom - virtual_rect.top) / (y->max - y->min); } }
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 962fe373833..d384a8a68c0 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -335,8 +335,8 @@ struct x11drv_thread_data enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled } xi2_state; /* XInput2 state */ void *xi2_devices; /* list of XInput2 devices (valid when state is enabled) */ int xi2_device_count; - XIValuatorClassInfo x_rel_valuator; - XIValuatorClassInfo y_rel_valuator; + XIValuatorClassInfo x_valuator; + XIValuatorClassInfo y_valuator; int xi2_core_pointer; /* XInput2 core pointer id */ int xi2_current_slave; /* Current slave driving the Core pointer */ #endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=38420 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winex11.drv/mouse.c | 41 +++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 1ef7027e838..8cc30f0736d 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -22,6 +22,8 @@ #include "config.h" #include "wine/port.h"
+#include <math.h> + #include <X11/Xlib.h> #include <X11/cursorfont.h> #include <stdarg.h> @@ -270,6 +272,9 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator (!class->label && class->number == 1 && class->mode == XIModeRelative)) thread_data->y_valuator = *class; } + + thread_data->x_valuator.value = 0; + thread_data->y_valuator.value = 0; } #endif
@@ -351,6 +356,8 @@ static void disable_xinput2(void) pXIFreeDeviceInfo( data->xi2_devices ); data->x_valuator.number = -1; data->y_valuator.number = -1; + data->x_valuator.value = 0; + data->y_valuator.value = 0; data->xi2_devices = NULL; data->xi2_core_pointer = 0; data->xi2_current_slave = 0; @@ -626,8 +633,8 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) { struct x11drv_thread_data *thread_data = x11drv_thread_data(); XIValuatorClassInfo *x = &thread_data->x_valuator, *y = &thread_data->y_valuator; + double x_value = 0, y_value = 0, x_scale, y_scale; const double *values = event->valuators.values; - double dx = 0, dy = 0, val; RECT virtual_rect; int i;
@@ -656,25 +663,41 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input )
virtual_rect = get_virtual_screen_rect();
+ if (x->max <= x->min) x_scale = 1; + else x_scale = (virtual_rect.right - virtual_rect.left) / (x->max - x->min); + if (y->max <= y->min) y_scale = 1; + else y_scale = (virtual_rect.bottom - virtual_rect.top) / (y->max - y->min); + for (i = 0; i <= max( x->number, y->number ); i++) { if (!XIMaskIsSet( event->valuators.mask, i )) continue; - val = *values++; if (i == x->number) { - input->u.mi.dx = dx = val; - if (x->min < x->max) - input->u.mi.dx = val * (virtual_rect.right - virtual_rect.left) / (x->max - x->min); + x_value = *values; + x->value += x_value * x_scale; } if (i == y->number) { - input->u.mi.dy = dy = val; - if (y->min < y->max) - input->u.mi.dy = val * (virtual_rect.bottom - virtual_rect.top) / (y->max - y->min); + y_value = *values; + y->value += y_value * y_scale; } + values++; + } + + input->u.mi.dx = round( x->value ); + input->u.mi.dy = round( y->value ); + + TRACE( "event %f,%f value %f,%f input %d,%d\n", x_value, y_value, x->value, y->value, input->u.mi.dx, input->u.mi.dy ); + + x->value -= input->u.mi.dx; + y->value -= input->u.mi.dy; + + if (!input->u.mi.dx && !input->u.mi.dy) + { + TRACE( "accumulating motion\n" ); + return FALSE; }
- TRACE( "pos %d,%d (event %f,%f)\n", input->u.mi.dx, input->u.mi.dy, dx, dy ); return TRUE; }