From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/mouse.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index f6386918c09..d504a68e6ba 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -240,12 +240,18 @@ static void update_relative_valuators( XIAnyClassInfo **classes, int num_classes { valuator = (XIValuatorClassInfo *)classes[num_classes]; if (classes[num_classes]->type != XIValuatorClass) continue; - if (valuator->number == 0 && valuator->mode == XIModeRelative) thread_data->x_valuator = *valuator; - if (valuator->number == 1 && valuator->mode == XIModeRelative) thread_data->y_valuator = *valuator; + if (valuator->number == 0) thread_data->x_valuator = *valuator; + if (valuator->number == 1) thread_data->y_valuator = *valuator; }
if (thread_data->x_valuator.number < 0 || thread_data->y_valuator.number < 0) WARN( "X/Y axis valuators not found, ignoring RawMotion events\n" ); + else if (thread_data->x_valuator.mode != thread_data->y_valuator.mode) + { + WARN( "Relative/Absolute mismatch between X/Y axis, ignoring RawMotion events\n" ); + thread_data->x_valuator.number = -1; + thread_data->y_valuator.number = -1; + }
thread_data->x_valuator.value = 0; thread_data->y_valuator.value = 0; @@ -1660,6 +1666,7 @@ 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 UINT absolute_flags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK; double x_value = 0, y_value = 0, x_scale, y_scale; const double *values = event->valuators.values; RECT virtual_rect; @@ -1670,7 +1677,15 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) if (!xinput2_available) return FALSE; if (event->deviceid != thread_data->xinput2_pointer) return FALSE;
- virtual_rect = NtUserGetVirtualScreenRect( MDT_RAW_DPI ); + if (x->mode == XIModeRelative && y->mode == XIModeRelative) + input->mi.dwFlags &= ~absolute_flags; + else if (x->mode == XIModeAbsolute && y->mode == XIModeAbsolute) + input->mi.dwFlags |= absolute_flags; + else + FIXME( "Unsupported relative/absolute X/Y axis mismatch\n." ); + + if (input->mi.dwFlags & MOUSEEVENTF_VIRTUALDESK) SetRect( &virtual_rect, 0, 0, 65535, 65535 ); + else virtual_rect = NtUserGetVirtualScreenRect( MDT_RAW_DPI );
if (x->max <= x->min) x_scale = 1; else x_scale = (virtual_rect.right - virtual_rect.left) / (x->max - x->min); @@ -1683,17 +1698,26 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) if (i == x->number) { x_value = *values; - x->value += x_value * x_scale; + if (x->mode == XIModeRelative) x->value += x_value * x_scale; + else x->value = (x_value - x->min) * x_scale; } if (i == y->number) { y_value = *values; - y->value += y_value * y_scale; + if (y->mode == XIModeRelative) y->value += y_value * y_scale; + else y->value = (y_value - y->min) * y_scale; } values++; }
- if (!(input->mi.dx = round( x->value )) && !(input->mi.dy = round( y->value ))) + if (input->mi.dwFlags & MOUSEEVENTF_ABSOLUTE) + { + input->mi.dx = round( x->value ); + input->mi.dy = round( y->value ); + TRACE( "event %f,%f value %f,%f absolute input %d,%d\n", x_value, y_value, x->value, y->value, + (int)input->mi.dx, (int)input->mi.dy ); + } + else if (!(input->mi.dx = round( x->value )) && !(input->mi.dy = round( y->value ))) { TRACE( "event %f,%f value %f,%f, accumulating motion\n", x_value, y_value, x->value, y->value ); input->mi.dwFlags &= ~MOUSEEVENTF_MOVE;