/** * Set the devices' cursor position to the given x/y position. * * This function is called during the pointer update path in * GetPointerEvents and friends (and the same in the xwin DDX). * * The coordinates provided are always absolute. The parameter mode whether * it was relative or absolute movement that landed us at those coordinates. * * @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) */ void miPointerSetPosition(DeviceIntPtr pDev, int mode, int *x, int *y) { miPointerScreenPtr pScreenPriv; ScreenPtr pScreen; ScreenPtr newScreen; miPointerPtr pPointer; if (!pDev || !pDev->coreEvents) return; pPointer = MIPOINTER(pDev); pScreen = pPointer->pScreen; if (!pScreen) return; /* called before ready */ 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); if (newScreen != pScreen) { pScreen = newScreen; (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, FALSE); pScreenPriv = GetScreenPrivate (pScreen); /* 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 (pScreen->ConstrainCursorHarder) pScreen->ConstrainCursorHarder(pDev, pScreen, mode, x, y); if (pPointer->x == *x && pPointer->y == *y && pPointer->pScreen == pScreen) return; miPointerMoveNoEvent(pDev, pScreen, *x, *y); }
/** * Set the device's cursor position to the x/y position on the given screen. * Generates and event if required. * * This function is called from: * - sprite init code to place onto initial position * - the various WarpPointer implementations (core, XI, Xinerama, dmx,…) * - during the cursor update path in CheckMotion * - in the Xinerama part of NewCurrentScreen * - when a RandR/RandR1.2 mode was applied (it may have moved the pointer, so * it's set back to the original pos) * * @param pDev The device to move * @param pScreen The screen the device is on * @param x The x coordinate in per-screen coordinates * @param y The y coordinate in per-screen coordinates * @param generateEvent True if the pointer movement should generate an * event. * * @return TRUE in all cases */ static Bool miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y, Bool generateEvent) { SetupScreen(pScreen); miPointerPtr pPointer = MIPOINTER(pDev); pPointer->generateEvent = generateEvent; if (pScreen->ConstrainCursorHarder) pScreen->ConstrainCursorHarder(pDev, pScreen, Absolute, &x, &y); /* device dependent - must pend signal and call miPointerWarpCursor */ (*pScreenPriv->screenFuncs->WarpCursor) (pDev, pScreen, x, y); if (!generateEvent) miPointerUpdateSprite(pDev); return TRUE; }
/** * Set the devices' cursor position to the given x/y position. * * This function is called during the pointer update path in * GetPointerEvents and friends (and the same in the xwin DDX). * * The coordinates provided are always absolute. The parameter mode whether * it was relative or absolute movement that landed us at those coordinates. * * @param pDev The device to move * @param mode Movement mode (Absolute or Relative) * @param[in,out] screenx The x coordinate in desktop coordinates * @param[in,out] screeny The y coordinate in desktop coordinates */ ScreenPtr miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx, double *screeny, int *nevents, InternalEvent* events) { miPointerScreenPtr pScreenPriv; ScreenPtr pScreen; ScreenPtr newScreen; int x, y; Bool switch_screen = FALSE; Bool should_constrain_barriers = FALSE; int i; miPointerPtr pPointer; pPointer = MIPOINTER(pDev); pScreen = pPointer->pScreen; x = trunc(*screenx); y = trunc(*screeny); switch_screen = !point_on_screen(pScreen, x, y); /* Switch to per-screen coordinates for CursorOffScreen and * Pointer->limits */ x -= pScreen->x; y -= pScreen->y; should_constrain_barriers = (mode == Relative); if (should_constrain_barriers) { /* coordinates after clamped to a barrier */ int constrained_x, constrained_y; int current_x, current_y; /* current position in per-screen coord */ current_x = MIPOINTER(pDev)->x - pScreen->y; current_y = MIPOINTER(pDev)->y - pScreen->x; input_constrain_cursor(pDev, pScreen, current_x, current_y, x, y, &constrained_x, &constrained_y, nevents, events); x = constrained_x; y = constrained_y; } if (switch_screen) { pScreenPriv = GetScreenPrivate(pScreen); if (!pPointer->confined) { newScreen = pScreen; (*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, &x, &y); if (newScreen != pScreen) { pScreen = newScreen; (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, FALSE); /* 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 (pScreen->ConstrainCursorHarder) pScreen->ConstrainCursorHarder(pDev, pScreen, mode, &x, &y); if (pPointer->x != x || pPointer->y != y || pPointer->pScreen != pScreen) miPointerMoveNoEvent(pDev, pScreen, x, y); /* check if we generated any barrier events and if so, update root x/y * to the fully constrained coords */ if (should_constrain_barriers) { for (i = 0; i < *nevents; i++) { if (events[i].any.type == ET_BarrierHit || events[i].any.type == ET_BarrierLeave) { events[i].barrier_event.root_x = x; events[i].barrier_event.root_y = 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; return pScreen; }
/** * Set the devices' cursor position to the given x/y position. * * This function is called during the pointer update path in * GetPointerEvents and friends (and the same in the xwin DDX). * * The coordinates provided are always absolute. The parameter mode whether * it was relative or absolute movement that landed us at those coordinates. * * @param pDev The device to move * @param mode Movement mode (Absolute or Relative) * @param[in,out] screenx The x coordinate in desktop coordinates * @param[in,out] screeny The y coordinate in desktop coordinates */ 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 NULL; pPointer = MIPOINTER(pDev); pScreen = pPointer->pScreen; if (!pScreen) return NULL; /* called before ready */ x = trunc(*screenx); y = trunc(*screeny); switch_screen = !point_on_screen(pScreen, x, y); /* 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); if (newScreen != pScreen) { pScreen = newScreen; (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, FALSE); /* 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 (pScreen->ConstrainCursorHarder) pScreen->ConstrainCursorHarder(pDev, pScreen, mode, &x, &y); 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; return pScreen; }