Beispiel #1
0
/* Return NULL if an error occurs. */
static DRIDrawablePrivPtr
CreateSurfaceForWindow(ScreenPtr pScreen, WindowPtr pWin, xp_window_id *widPtr) {
    DRIDrawablePrivPtr pDRIDrawablePriv;
    xp_window_id wid = 0;

    *widPtr = 0;

    pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);

    if (pDRIDrawablePriv == NULL) {
	xp_error err;
	xp_window_changes wc;
	
	/* allocate a DRI Window Private record */
	if (!(pDRIDrawablePriv = xalloc(sizeof(*pDRIDrawablePriv)))) {
	    return NULL;
	}
	
	pDRIDrawablePriv->pDraw = (DrawablePtr)pWin;
	pDRIDrawablePriv->pScreen = pScreen;
	pDRIDrawablePriv->refCount = 0;
	pDRIDrawablePriv->drawableIndex = -1;
	pDRIDrawablePriv->notifiers = NULL;
	
	/* find the physical window */
	wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWin, TRUE));

	if (wid == 0) {
	    xfree(pDRIDrawablePriv);
	    return NULL;
	}
	
	/* allocate the physical surface */
	err = xp_create_surface(wid, &pDRIDrawablePriv->sid);

	if (err != Success) {
	    xfree(pDRIDrawablePriv);
	    return NULL;
	}

	/* Make it visible */
	wc.stack_mode = XP_MAPPED_ABOVE;
	wc.sibling = 0;
	err = xp_configure_surface(pDRIDrawablePriv->sid, XP_STACKING, &wc);

	if (err != Success) {
	    xp_destroy_surface(pDRIDrawablePriv->sid);
	    xfree(pDRIDrawablePriv);
	    return NULL;
	}

	/* save private off of preallocated index */
	dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey,
		      pDRIDrawablePriv);
    }

    *widPtr = wid;

    return pDRIDrawablePriv;
}
Beispiel #2
0
static void
DRIUpdateSurface(DRIDrawablePrivPtr pDRIDrawablePriv, DrawablePtr pDraw)
{
    xp_window_changes wc;
    unsigned int flags = 0;

    if (pDRIDrawablePriv->sid == 0)
        return;

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
    wc.depth = (pDraw->bitsPerPixel == 32 ? XP_DEPTH_ARGB8888
                : pDraw->bitsPerPixel == 16 ? XP_DEPTH_RGB555 : XP_DEPTH_NIL);
    if (wc.depth != XP_DEPTH_NIL)
        flags |= XP_DEPTH;
#endif

    if (pDraw->type == DRAWABLE_WINDOW) {
        WindowPtr pWin = (WindowPtr)pDraw;
        WindowPtr pTopWin = TopLevelParent(pWin);

        wc.x = pWin->drawable.x - (pTopWin->drawable.x - pTopWin->borderWidth);
        wc.y = pWin->drawable.y - (pTopWin->drawable.y - pTopWin->borderWidth);
        wc.width = pWin->drawable.width + 2 * pWin->borderWidth;
        wc.height = pWin->drawable.height + 2 * pWin->borderWidth;
        wc.bit_gravity = XP_GRAVITY_NONE;

        wc.shape_nrects = RegionNumRects(&pWin->clipList);
        wc.shape_rects = RegionRects(&pWin->clipList);
        wc.shape_tx = -(pTopWin->drawable.x - pTopWin->borderWidth);
        wc.shape_ty = -(pTopWin->drawable.y - pTopWin->borderWidth);

        flags |= XP_BOUNDS | XP_SHAPE;

    }
    else if (pDraw->type == DRAWABLE_PIXMAP) {
        wc.x = 0;
        wc.y = 0;
        wc.width = pDraw->width;
        wc.height = pDraw->height;
        wc.bit_gravity = XP_GRAVITY_NONE;
        flags |= XP_BOUNDS;
    }

    xp_configure_surface(pDRIDrawablePriv->sid, flags, &wc);
}
Beispiel #3
0
Bool
DRICreateSurface(ScreenPtr pScreen, Drawable id,
                 DrawablePtr pDrawable, xp_client_id client_id,
                 xp_surface_id *surface_id, unsigned int ret_key[2],
                 void (*notify) (void *arg, void *data), void *notify_data)
{
    DRIScreenPrivPtr    pDRIPriv = DRI_SCREEN_PRIV(pScreen);
    DRIDrawablePrivPtr  pDRIDrawablePriv;
    xp_window_id        wid = 0;

    if (pDrawable->type == DRAWABLE_WINDOW) {
        WindowPtr pWin = (WindowPtr)pDrawable;

        pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
        if (pDRIDrawablePriv == NULL) {
            xp_error err;
            xp_window_changes wc;

            /* allocate a DRI Window Private record */
            if (!(pDRIDrawablePriv = xalloc(sizeof(DRIDrawablePrivRec)))) {
                return FALSE;
            }

            pDRIDrawablePriv->pDraw = pDrawable;
            pDRIDrawablePriv->pScreen = pScreen;
            pDRIDrawablePriv->refCount = 0;
            pDRIDrawablePriv->drawableIndex = -1;
            pDRIDrawablePriv->notifiers = NULL;

            /* find the physical window */
            wid = (xp_window_id) RootlessFrameForWindow(pWin, TRUE);
            if (wid == 0) {
                xfree(pDRIDrawablePriv);
                return FALSE;
            }

            /* allocate the physical surface */
            err = xp_create_surface(wid, &pDRIDrawablePriv->sid);
            if (err != Success) {
                xfree(pDRIDrawablePriv);
                return FALSE;
            }

            /* Make it visible */
            wc.stack_mode = XP_MAPPED_ABOVE;
            wc.sibling = 0;
            err = xp_configure_surface(pDRIDrawablePriv->sid, XP_STACKING, &wc);
            if (err != Success)
            {
                xp_destroy_surface(pDRIDrawablePriv->sid);
                xfree(pDRIDrawablePriv);
                return FALSE;
            }

            /* save private off of preallocated index */
            pWin->devPrivates[DRIWindowPrivIndex].ptr = (pointer)pDRIDrawablePriv;
        }
    }

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
    else if (pDrawable->type == DRAWABLE_PIXMAP) {
        PixmapPtr pPix = (PixmapPtr)pDrawable;

        pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix);
        if (pDRIDrawablePriv == NULL) {
            xp_error err;

            /* allocate a DRI Window Private record */
            if (!(pDRIDrawablePriv = xcalloc(1, sizeof(DRIDrawablePrivRec)))) {
                return FALSE;
            }

            pDRIDrawablePriv->pDraw = pDrawable;
            pDRIDrawablePriv->pScreen = pScreen;
            pDRIDrawablePriv->refCount = 0;
            pDRIDrawablePriv->drawableIndex = -1;
            pDRIDrawablePriv->notifiers = NULL;

            /* Passing a null window id to Xplugin in 10.3+ asks for
               an accelerated offscreen surface. */

            err = xp_create_surface(0, &pDRIDrawablePriv->sid);
            if (err != Success) {
                xfree(pDRIDrawablePriv);
                return FALSE;
            }

            /* save private off of preallocated index */
            pPix->devPrivates[DRIPixmapPrivIndex].ptr = (pointer)pDRIDrawablePriv;
        }
    }
#endif

    else { /* for GLX 1.3, a PBuffer */
        /* NOT_DONE */
        return FALSE;
    }

    /* Finish initialization of new surfaces */
    if (pDRIDrawablePriv->refCount == 0) {
        unsigned int key[2] = {0};
        xp_error err;

        /* try to give the client access to the surface */
        if (client_id != 0 && wid != 0)
        {
            err = xp_export_surface(wid, pDRIDrawablePriv->sid,
                                    client_id, key);
            if (err != Success) {
                xp_destroy_surface(pDRIDrawablePriv->sid);
                xfree(pDRIDrawablePriv);
                return FALSE;
            }
        }

        pDRIDrawablePriv->key[0] = key[0];
        pDRIDrawablePriv->key[1] = key[1];

        ++pDRIPriv->nrWindows;

        /* and stash it by surface id */
        if (surface_hash == NULL)
            surface_hash = x_hash_table_new(NULL, NULL, NULL, NULL);
        x_hash_table_insert(surface_hash,
                            (void *) pDRIDrawablePriv->sid, pDRIDrawablePriv);

        /* track this in case this window is destroyed */
        AddResource(id, DRIDrawablePrivResType, (pointer)pDrawable);

        /* Initialize shape */
        DRIUpdateSurface(pDRIDrawablePriv, pDrawable);
    }

    pDRIDrawablePriv->refCount++;

    *surface_id = pDRIDrawablePriv->sid;

    if (ret_key != NULL) {
        ret_key[0] = pDRIDrawablePriv->key[0];
        ret_key[1] = pDRIDrawablePriv->key[1];
    }

    if (notify != NULL) {
        pDRIDrawablePriv->notifiers = x_hook_add(pDRIDrawablePriv->notifiers,
                                                 notify, notify_data);
    }

    return TRUE;
}