Don't switch between doubles and ints in the caller, instead take doubles in miPointerSetPosition and do the conversion there. For full feature we should change everything down from here for doubles too.
Functional change: previously we'd restore the remainder regardless of screen switching/confinement (despite what the comment said). Now, screen changing or cursor constraints will cause the remainder be clipped off. This should happen for cursor constraints but arguably not for screen crossing. This also corrects a currently wrong comment about miPointerSetPosition's input coordinates. Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> --- dix/getevents.c | 27 ++++++++++++--------------- mi/mipointer.c | 47 +++++++++++++++++++++++++++++------------------ mi/mipointer.h | 4 ++-- 3 files changed, 43 insertions(+), 35 deletions(-) diff --git a/dix/getevents.c b/dix/getevents.c index 8b7ffeb..945e275 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -805,8 +805,8 @@ static ScreenPtr positionSprite(DeviceIntPtr dev, int mode, ValuatorMask *mask, double *screenx, double *screeny) { - int isx, isy; /* screen {x, y}, in int */ double x, y; + double tmpx, tmpy; ScreenPtr scr = miPointerGetScreen(dev); if (!dev->valuator || dev->valuator->numAxes < 2) @@ -827,25 +827,22 @@ positionSprite(DeviceIntPtr dev, int mode, ValuatorMask *mask, *screeny = rescaleValuatorAxis(y, dev->valuator->axes + 1, NULL, scr->height); + tmpx = *screenx; + tmpy = *screeny; /* miPointerSetPosition takes care of crossing screens for us, as well as - * clipping to the current screen. In the event we actually change screen, - * we just drop the float component on the floor, then convert from - * screenx back into device co-ordinates. */ - isx = trunc(*screenx); - isy = trunc(*screeny); - scr = miPointerSetPosition(dev, mode, &isx, &isy); - if (isx != trunc(*screenx)) - { - *screenx -= trunc(*screenx) - isx; + * clipping to the current screen. */ + scr = miPointerSetPosition(dev, mode, screenx, screeny); + + /* If we were constrained, rescale x/y from the screen coordinates so + * the device valuators reflect the correct position. For screen + * crossing this doesn't matter much, the coords would be 0 or max. + */ + if (tmpx != *screenx) x = rescaleValuatorAxis(*screenx, NULL, dev->valuator->axes + 0, scr->width); - } - if (isy != trunc(*screeny)) - { - *screeny -= trunc(*screeny) - isy; + if (tmpy != *screeny) y = rescaleValuatorAxis(*screeny, NULL, dev->valuator->axes + 1, scr->height); - } /* Update the MD's co-ordinates, which are always in screen space. */ if (!IsMaster(dev) || !IsFloating(dev)) { diff --git a/mi/mipointer.c b/mi/mipointer.c index 4901d13..55e4081 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -569,17 +569,16 @@ miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen, * * @param pDev The device to move * @param mode Movement mode (Absolute or Relative) - * @param[in,out] x The x coordinate in screen coordinates (in regards to total - * desktop size) - * @param[in,out] y The y coordinate in screen coordinates (in regards to total - * desktop size) + * @param[in,out] screenx The x coordinate in screen coordinates + * @param[in,out] screeny The y coordinate in screen coordinates */ ScreenPtr -miPointerSetPosition(DeviceIntPtr pDev, int mode, int *x, int *y) +miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx, double *screeny) { miPointerScreenPtr pScreenPriv; ScreenPtr pScreen; ScreenPtr newScreen; + int x, y; miPointerPtr pPointer; @@ -591,13 +590,16 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, int *x, int *y) if (!pScreen) return NULL; /* called before ready */ - if (*x < 0 || *x >= pScreen->width || *y < 0 || *y >= pScreen->height) + x = trunc(*screenx); + y = trunc(*screeny); + + if (x < 0 || x >= pScreen->width || y < 0 || y >= pScreen->height) { pScreenPriv = GetScreenPrivate (pScreen); if (!pPointer->confined) { newScreen = pScreen; - (*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, x, y); + (*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, &x, &y); if (newScreen != pScreen) { pScreen = newScreen; @@ -610,21 +612,30 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, int *x, int *y) } } /* Constrain the sprite to the current limits. */ - if (*x < pPointer->limits.x1) - *x = pPointer->limits.x1; - if (*x >= pPointer->limits.x2) - *x = pPointer->limits.x2 - 1; - if (*y < pPointer->limits.y1) - *y = pPointer->limits.y1; - if (*y >= pPointer->limits.y2) - *y = pPointer->limits.y2 - 1; + if (x < pPointer->limits.x1) + x = pPointer->limits.x1; + if (x >= pPointer->limits.x2) + x = pPointer->limits.x2 - 1; + if (y < pPointer->limits.y1) + y = pPointer->limits.y1; + if (y >= pPointer->limits.y2) + y = pPointer->limits.y2 - 1; if (pScreen->ConstrainCursorHarder) - pScreen->ConstrainCursorHarder(pDev, pScreen, mode, x, y); + pScreen->ConstrainCursorHarder(pDev, pScreen, mode, &x, &y); - if (pPointer->x != *x || pPointer->y != *y || + if (pPointer->x != x || pPointer->y != y || pPointer->pScreen != pScreen) - miPointerMoveNoEvent(pDev, pScreen, *x, *y); + miPointerMoveNoEvent(pDev, pScreen, x, y); + + /* In the event we actually change screen or we get confined, we just + * drop the float component on the floor + * FIXME: only drop remainder for ConstrainCursorHarder, not for screen + * crossings */ + if (x != trunc(*screenx)) + *screenx = x; + if (y != trunc(*screeny)) + *screeny = y; return pScreen; } diff --git a/mi/mipointer.h b/mi/mipointer.h index 35428df..45abb5b 100644 --- a/mi/mipointer.h +++ b/mi/mipointer.h @@ -134,8 +134,8 @@ extern _X_EXPORT void miPointerGetPosition( extern _X_EXPORT ScreenPtr miPointerSetPosition( DeviceIntPtr pDev, int mode, - int *x, - int *y); + double *x, + double *y); extern _X_EXPORT void miPointerUpdateSprite( DeviceIntPtr pDev); -- 1.7.6.4 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel