]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/xserver.git/blobdiff - mi/mipointer.c
Imported Debian patch 1.11.4-0ubuntu3
[glsdk/xserver.git] / mi / mipointer.c
index 7680ca19b12e3464e699d09d951499d66f4c3255..998c86c15f279a82fc5bac461f653030608b81b5 100644 (file)
@@ -569,64 +569,87 @@ miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen,
  *
  * @param pDev The device to move
  * @param mode Movement mode (Absolute or Relative)
- * @param[in,out] x The x coordiante in screen coordinates (in regards to total
- * desktop size)
- * @param[in,out] y The y coordiante in screen coordinates (in regards to total
- * desktop size)
+ * @param[in,out] screenx The x coordinate in desktop coordinates
+ * @param[in,out] screeny The y coordinate in desktop coordinates
  */
-void
-miPointerSetPosition(DeviceIntPtr pDev, int mode, int *x, int *y)
+ScreenPtr
+miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx, double *screeny)
 {
     miPointerScreenPtr pScreenPriv;
     ScreenPtr          pScreen;
     ScreenPtr          newScreen;
+    int                        x, y;
+    Bool               switch_screen = FALSE;
 
     miPointerPtr        pPointer; 
 
     if (!pDev || !pDev->coreEvents)
-        return;
+        return NULL;
 
     pPointer = MIPOINTER(pDev);
     pScreen = pPointer->pScreen;
     if (!pScreen)
-       return;     /* called before ready */
+       return NULL;    /* called before ready */
+
+    x = trunc(*screenx);
+    y = trunc(*screeny);
+
+    switch_screen = !point_on_screen(pScreen, x, y);
 
-    if (*x < 0 || *x >= pScreen->width || *y < 0 || *y >= pScreen->height)
+    /* Switch to per-screen coordinates for CursorOffScreen and
+     * Pointer->limits */
+    x -= pScreen->x;
+    y -= pScreen->y;
+
+    if (switch_screen)
     {
        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;
                (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen,
                                                             FALSE);
-               /* Smash the confine to the new screen */
+               /* Smash the confine to the new screen */
                 pPointer->limits.x2 = pScreen->width;
                 pPointer->limits.y2 = pScreen->height;
            }
        }
     }
     /* 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 && 
-            pPointer->pScreen == pScreen) 
-        return;
+    if (pPointer->x != x || pPointer->y != y ||
+            pPointer->pScreen != pScreen)
+        miPointerMoveNoEvent(pDev, pScreen, x, y);
+
+    /* Convert to desktop coordinates again */
+    x += pScreen->x;
+    y += pScreen->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;
 
-    miPointerMoveNoEvent(pDev, pScreen, *x, *y);
+    return pScreen;
 }
 
 /**