diff --git a/dix/getevents.c b/dix/getevents.c index bb1f5c96d..ade3ca132 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 4901d139b..55e4081f2 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 35428df32..45abb5b56 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);