diff options
Diffstat (limited to 'xserver/dix/getevents.c')
-rw-r--r-- | xserver/dix/getevents.c | 61 |
1 files changed, 39 insertions, 22 deletions
diff --git a/xserver/dix/getevents.c b/xserver/dix/getevents.c index 8b4379d1c..707678352 100644 --- a/xserver/dix/getevents.c +++ b/xserver/dix/getevents.c @@ -787,11 +787,33 @@ add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, doubl * @param[in,out] mask Valuator data for this event, modified in-place. */ static void -moveRelative(DeviceIntPtr dev, ValuatorMask *mask) +moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask) { int i; Bool clip_xy = IsMaster(dev) || !IsFloating(dev); + /* for abs devices in relative mode, we've just scaled wrong, since we + mapped the device's shape into the screen shape. Undo this. */ + if ((flags & POINTER_ABSOLUTE) == 0 && dev->valuator && + dev->valuator->axes[0].min_value < dev->valuator->axes[0].max_value) { + + double ratio = 1.0 * screenInfo.width/screenInfo.height; + + if (ratio > 1.0) { + double y; + if (valuator_mask_fetch_double(mask, 1, &y)) { + y *= ratio; + valuator_mask_set_double(mask, 1, y); + } + } else { + double x; + if (valuator_mask_fetch_double(mask, 0, &x)) { + x *= ratio; + valuator_mask_set_double(mask, 0, x); + } + } + } + /* calc other axes, clip, drop back into valuators */ for (i = 0; i < valuator_mask_size(mask); i++) { double val = dev->last.valuators[i]; @@ -844,14 +866,14 @@ scale_from_screen(DeviceIntPtr dev, ValuatorMask *mask) scaled = valuator_mask_get_double(mask, 0) + scr->x; scaled = rescaleValuatorAxis(scaled, NULL, dev->valuator->axes + 0, - 0, scr->width); + screenInfo.x, screenInfo.width); valuator_mask_set_double(mask, 0, scaled); } if (valuator_mask_isset(mask, 1)) { scaled = valuator_mask_get_double(mask, 1) + scr->y; scaled = rescaleValuatorAxis(scaled, NULL, dev->valuator->axes + 1, - 0, scr->height); + screenInfo.y, screenInfo.height); valuator_mask_set_double(mask, 1, scaled); } } @@ -1387,7 +1409,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type, if ((flags & POINTER_NORAW) == 0) set_raw_valuators(raw, &mask, raw->valuators.data); - moveRelative(pDev, &mask); + moveRelative(pDev, flags, &mask); } /* valuators are in device coordinate system in absolute coordinates */ @@ -1951,32 +1973,27 @@ GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid, default: return 0; } - if (t->mode == XIDirectTouch && !(flags & TOUCH_CLIENT_ID)) { - if (!valuator_mask_isset(&mask, 0)) - valuator_mask_set_double(&mask, 0, - valuator_mask_get_double(touchpoint.ti-> - valuators, 0)); - if (!valuator_mask_isset(&mask, 1)) - valuator_mask_set_double(&mask, 1, - valuator_mask_get_double(touchpoint.ti-> - valuators, 1)); - } /* Get our screen event co-ordinates (root_x/root_y/event_x/event_y): * these come from the touchpoint in Absolute mode, or the sprite in * Relative. */ if (t->mode == XIDirectTouch) { - transformAbsolute(dev, &mask); - if (!(flags & TOUCH_CLIENT_ID)) { - for (i = 0; i < valuator_mask_size(&mask); i++) { - double val; - - if (valuator_mask_fetch_double(&mask, i, &val)) - valuator_mask_set_double(touchpoint.ti->valuators, i, val); - } + for (i = 0; i < max(valuator_mask_size(&mask), 2); i++) { + double val; + + if (valuator_mask_fetch_double(&mask, i, &val)) + valuator_mask_set_double(touchpoint.ti->valuators, i, val); + /* If the device doesn't post new X and Y axis values, + * use the last values posted. + */ + else if (i < 2 && + valuator_mask_fetch_double(touchpoint.ti->valuators, i, &val)) + valuator_mask_set_double(&mask, i, val); + } } + transformAbsolute(dev, &mask); clipAbsolute(dev, &mask); } else { |