/**
 * 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);
}
Example #2
0
/**
 * 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;
}
Example #3
0
/**
 * 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;
}
Example #4
0
/**
 * 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;
}