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
Bool
DRIDestroySurface(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable,
                  void (*notify) (void *, void *), void *notify_data)
{
    DRIDrawablePrivPtr  pDRIDrawablePriv;

    if (pDrawable->type == DRAWABLE_WINDOW) {
        pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW((WindowPtr)pDrawable);
    } else if (pDrawable->type == DRAWABLE_PIXMAP) {
        pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP((PixmapPtr)pDrawable);
    } else {
        return FALSE;
    }

    if (pDRIDrawablePriv != NULL) {
        if (notify != NULL) {
            pDRIDrawablePriv->notifiers = x_hook_remove(pDRIDrawablePriv->notifiers,
                                                        notify, notify_data);
        }
        if (--pDRIDrawablePriv->refCount <= 0) {
            /* This calls back to DRIDrawablePrivDelete
               which frees the private area */
            FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
        }
    }

    return TRUE;
}
Beispiel #3
0
/*
 * The assumption is that this is called when the refCount of a surface
 * drops to <= 0, or the window/pixmap is destroyed.
 */
Bool
DRIDrawablePrivDelete(pointer pResource, XID id)
{
    DrawablePtr pDrawable = (DrawablePtr)pResource;
    DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pDrawable->pScreen);
    DRIDrawablePrivPtr pDRIDrawablePriv = NULL;
    WindowPtr pWin = NULL;
    PixmapPtr pPix = NULL;

    if (pDrawable->type == DRAWABLE_WINDOW) {
        pWin = (WindowPtr)pDrawable;
        pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
    }
    else if (pDrawable->type == DRAWABLE_PIXMAP) {
        pPix = (PixmapPtr)pDrawable;
        pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix);
    }

    if (pDRIDrawablePriv == NULL) {
        /*
         * We reuse __func__ and the resource type for the GLXPixmap code.
         * Attempt to free a pixmap buffer associated with the resource
         * if possible.
         */
        return DRIFreePixmapImp(pDrawable);
    }

    if (pDRIDrawablePriv->drawableIndex != -1) {
        /* release drawable table entry */
        pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL;
    }

    if (pDRIDrawablePriv->sid != 0) {
        DRISurfaceNotify(pDRIDrawablePriv->sid,
                         AppleDRISurfaceNotifyDestroyed);
    }

    if (pDRIDrawablePriv->notifiers != NULL)
        x_hook_free(pDRIDrawablePriv->notifiers);

    free(pDRIDrawablePriv);

    if (pDrawable->type == DRAWABLE_WINDOW) {
        dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL);
    }
    else if (pDrawable->type == DRAWABLE_PIXMAP) {
        dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, NULL);
    }

    --pDRIPriv->nrWindows;

    return TRUE;
}
Beispiel #4
0
Bool
DRIDrawablePrivDelete(pointer pResource, XID id)
{
    DrawablePtr         pDrawable = (DrawablePtr)pResource;
    DRIScreenPrivPtr    pDRIPriv = DRI_SCREEN_PRIV(pDrawable->pScreen);
    DRIDrawablePrivPtr  pDRIDrawablePriv = NULL;
    WindowPtr           pWin = NULL;
    PixmapPtr           pPix = NULL;

    if (pDrawable->type == DRAWABLE_WINDOW) {
        pWin = (WindowPtr)pDrawable;
        pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
    } else if (pDrawable->type == DRAWABLE_PIXMAP) {
        pPix = (PixmapPtr)pDrawable;
        pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix);
    }

    if (pDRIDrawablePriv == NULL) {
	return DRIFreePixmapImp(pDrawable);
    }

    if (pDRIDrawablePriv->drawableIndex != -1) {
        /* release drawable table entry */
        pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL;
    }

    if (pDRIDrawablePriv->sid != 0) {
        xp_destroy_surface(pDRIDrawablePriv->sid);
        x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(pDRIDrawablePriv->sid));
    }

    if (pDRIDrawablePriv->notifiers != NULL)
        x_hook_free(pDRIDrawablePriv->notifiers);

    xfree(pDRIDrawablePriv);

    if (pDrawable->type == DRAWABLE_WINDOW) {
	dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL);
    } else if (pDrawable->type == DRAWABLE_PIXMAP) {
	dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, NULL);
    }

    --pDRIPriv->nrWindows;

    return TRUE;
}
Beispiel #5
0
void
DRIWindowExposures(WindowPtr pWin, RegionPtr prgn, RegionPtr bsreg)
{
    ScreenPtr pScreen = pWin->drawable.pScreen;
    DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
    DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);

    if (pDRIDrawablePriv) {
        /* FIXME: something? */
    }

    pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures;

    (*pScreen->WindowExposures)(pWin, prgn, bsreg);

    pScreen->WindowExposures = DRIWindowExposures;
}
Beispiel #6
0
Bool
DRIDestroySurface(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable,
                  void (*notify)(void *, void *), void *notify_data)
{
    DRIDrawablePrivPtr pDRIDrawablePriv;

    if (pDrawable->type == DRAWABLE_WINDOW) {
        pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW((WindowPtr)pDrawable);
    }
    else if (pDrawable->type == DRAWABLE_PIXMAP) {
        pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP((PixmapPtr)pDrawable);
    }
    else {
        return FALSE;
    }

    if (pDRIDrawablePriv != NULL) {
        /*
         * This doesn't seem to be used, because notify is NULL in all callers.
         */

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

        --pDRIDrawablePriv->refCount;

        /*
         * Check if the drawable privates still have a reference to the
         * surface.
         */

        if (pDRIDrawablePriv->refCount <= 0) {
            /*
             * This calls back to DRIDrawablePrivDelete which
             * frees the private area and dispatches events, if needed.
             */
            FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
        }
    }

    return TRUE;
}
Beispiel #7
0
void
DRIClipNotify(WindowPtr pWin, int dx, int dy)
{
    ScreenPtr pScreen = pWin->drawable.pScreen;
    DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
    DRIDrawablePrivPtr  pDRIDrawablePriv;

    if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
        DRIUpdateSurface(pDRIDrawablePriv, &pWin->drawable);
    }

    if (pDRIPriv->wrap.ClipNotify) {
        pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify;

        (*pScreen->ClipNotify)(pWin, dx, dy);

        pScreen->ClipNotify = DRIClipNotify;
    }
}
Beispiel #8
0
void
DRICopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
    ScreenPtr pScreen = pWin->drawable.pScreen;
    DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
    DRIDrawablePrivPtr pDRIDrawablePriv;

    if (pDRIPriv->nrWindows > 0) {
       pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
       if (pDRIDrawablePriv != NULL) {
            DRIUpdateSurface(pDRIDrawablePriv, &pWin->drawable);
       }
    }

    /* unwrap */
    pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow;

    /* call lower layers */
    (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);

    /* rewrap */
    pScreen->CopyWindow = DRICopyWindow;
}
Beispiel #9
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;
}