Beispiel #1
0
bool cursor_on_shape(Matrix4 const& model_view_projection, std::vector<Vector3> const& vertices, Vector2 const& cursor) {
    for (int i = 0; i < vertices.size(); i+=3) {
        Vector2 p0 = point_on_screen(model_view_projection, vertices[i+0]);
        Vector2 p1 = point_on_screen(model_view_projection, vertices[i+1]);
        Vector2 p2 = point_on_screen(model_view_projection, vertices[i+2]);
        if (area(p0, p1, cursor) <= 0.0f && area(p1, p2, cursor) <= 0.0f && area(p2, p0, cursor) <= 0.0f) {
            return true;
        }
    }
    return false;
}
Beispiel #2
0
Rect2 rect_on_screen(Matrix4 const& view_projection, std::vector<Vector3> const& vertices) {
    Vector2 p = point_on_screen(view_projection, vertices[0]);
    Vector2 min = p;
    Vector2 max = p;
    for (Vector3 const& v : vertices) {
        p = point_on_screen(view_projection, v);
        min = minimum(min, p);
        max = maximum(max, p);
    }
    return Rect2{min, max - min};
}
Beispiel #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;
}
Beispiel #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;
}