/**
 * 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);
}
예제 #2
0
void
miPointerSetScreen(DeviceIntPtr pDev, int screen_no, int x, int y)
{
	miPointerScreenPtr pScreenPriv;
	ScreenPtr pScreen;
        miPointerPtr pPointer;

        pPointer = MIPOINTER(pDev);

	pScreen = screenInfo.screens[screen_no];
	pScreenPriv = GetScreenPrivate (pScreen);
	(*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, FALSE);
	NewCurrentScreen (pDev, pScreen, x, y);

        pPointer->limits.x2 = pScreen->width;
        pPointer->limits.y2 = pScreen->height;
}
예제 #3
0
void
miPointerUpdateSprite (DeviceIntPtr pDev)
{
    ScreenPtr		pScreen;
    miPointerScreenPtr	pScreenPriv;
    CursorPtr		pCursor;
    int			x, y, devx, devy;
    miPointerPtr        pPointer;

    if (!pDev || !pDev->coreEvents)
        return;

    pPointer = MIPOINTER(pDev);

    if (!pPointer)
        return;

    pScreen = pPointer->pScreen;
    if (!pScreen)
	return;

    x = pPointer->x;
    y = pPointer->y;
    devx = pPointer->devx;
    devy = pPointer->devy;

    pScreenPriv = GetScreenPrivate (pScreen);
    /*
     * if the cursor has switched screens, disable the sprite
     * on the old screen
     */
    if (pScreen != pPointer->pSpriteScreen)
    {
	if (pPointer->pSpriteScreen)
	{
	    miPointerScreenPtr  pOldPriv;
    	
	    pOldPriv = GetScreenPrivate (pPointer->pSpriteScreen);
	    if (pPointer->pCursor)
	    {
	    	(*pOldPriv->spriteFuncs->SetCursor)
			    	(pDev, pPointer->pSpriteScreen, NullCursor, 0, 0);
	    }
	    (*pOldPriv->screenFuncs->CrossScreen) (pPointer->pSpriteScreen, FALSE);
	}
	(*pScreenPriv->screenFuncs->CrossScreen) (pScreen, TRUE);
	(*pScreenPriv->spriteFuncs->SetCursor)
				(pDev, pScreen, pPointer->pCursor, x, y);
	pPointer->devx = x;
	pPointer->devy = y;
	pPointer->pSpriteCursor = pPointer->pCursor;
	pPointer->pSpriteScreen = pScreen;
    }
    /*
     * if the cursor has changed, display the new one
     */
    else if (pPointer->pCursor != pPointer->pSpriteCursor)
    {
	pCursor = pPointer->pCursor;
	if (!pCursor || (pCursor->bits->emptyMask && !pScreenPriv->showTransparent))
	    pCursor = NullCursor;
	(*pScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen, pCursor, x, y);

	pPointer->devx = x;
	pPointer->devy = y;
	pPointer->pSpriteCursor = pPointer->pCursor;
    }
    else if (x != devx || y != devy)
    {
	pPointer->devx = x;
	pPointer->devy = y;
	if(pPointer->pCursor && !pPointer->pCursor->bits->emptyMask)
	    (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y);
    }
}
예제 #4
0
파일: mipointer.c 프로젝트: Agnesa/xserver
/**
 * 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;
}
예제 #5
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;
}