571 lines
14 KiB
C
571 lines
14 KiB
C
|
/*
|
|||
|
* Copyright <EFBFBD> 2004 Eric Anholt
|
|||
|
*
|
|||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
|||
|
* documentation for any purpose is hereby granted without fee, provided that
|
|||
|
* the above copyright notice appear in all copies and that both that
|
|||
|
* copyright notice and this permission notice appear in supporting
|
|||
|
* documentation, and that the name of Eric Anholt not be used in
|
|||
|
* advertising or publicity pertaining to distribution of the software without
|
|||
|
* specific, written prior permission. Eric Anholt makes no
|
|||
|
* representations about the suitability of this software for any purpose. It
|
|||
|
* is provided "as is" without express or implied warranty.
|
|||
|
*
|
|||
|
* ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|||
|
* EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|||
|
* PERFORMANCE OF THIS SOFTWARE.
|
|||
|
*/
|
|||
|
/* $Header$ */
|
|||
|
|
|||
|
#include "gcstruct.h"
|
|||
|
#include "windowstr.h"
|
|||
|
#include "cw.h"
|
|||
|
|
|||
|
#define CW_DEBUG 1
|
|||
|
|
|||
|
#if CW_DEBUG
|
|||
|
#define CW_ASSERT(x) do { \
|
|||
|
if (!(x)) { \
|
|||
|
ErrorF("composite wrapper: assertion failed at %s:%d\n", __FUNC__, \
|
|||
|
__LINE__); \
|
|||
|
} \
|
|||
|
} while (0)
|
|||
|
#else
|
|||
|
#define CW_ASSERT(x) do {} while (0)
|
|||
|
#endif
|
|||
|
|
|||
|
int cwGCIndex;
|
|||
|
int cwScreenIndex;
|
|||
|
#ifdef RENDER
|
|||
|
int cwPictureIndex;
|
|||
|
#endif
|
|||
|
static unsigned long cwGeneration = 0;
|
|||
|
extern GCOps cwGCOps;
|
|||
|
|
|||
|
static Bool
|
|||
|
cwCloseScreen (int i, ScreenPtr pScreen);
|
|||
|
|
|||
|
static void
|
|||
|
cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable);
|
|||
|
static void
|
|||
|
cwChangeGC(GCPtr pGC, unsigned long mask);
|
|||
|
static void
|
|||
|
cwCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
|
|||
|
static void
|
|||
|
cwDestroyGC(GCPtr pGC);
|
|||
|
static void
|
|||
|
cwChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
|
|||
|
static void
|
|||
|
cwCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
|
|||
|
static void
|
|||
|
cwDestroyClip(GCPtr pGC);
|
|||
|
|
|||
|
static void
|
|||
|
cwCheapValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable);
|
|||
|
static void
|
|||
|
cwCheapChangeGC(GCPtr pGC, unsigned long mask);
|
|||
|
static void
|
|||
|
cwCheapCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
|
|||
|
static void
|
|||
|
cwCheapDestroyGC(GCPtr pGC);
|
|||
|
static void
|
|||
|
cwCheapChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
|
|||
|
static void
|
|||
|
cwCheapCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
|
|||
|
static void
|
|||
|
cwCheapDestroyClip(GCPtr pGC);
|
|||
|
|
|||
|
static GCFuncs cwGCFuncs = {
|
|||
|
cwValidateGC,
|
|||
|
cwChangeGC,
|
|||
|
cwCopyGC,
|
|||
|
cwDestroyGC,
|
|||
|
cwChangeClip,
|
|||
|
cwDestroyClip,
|
|||
|
cwCopyClip,
|
|||
|
};
|
|||
|
|
|||
|
static GCFuncs cwCheapGCFuncs = {
|
|||
|
cwCheapValidateGC,
|
|||
|
cwCheapChangeGC,
|
|||
|
cwCheapCopyGC,
|
|||
|
cwCheapDestroyGC,
|
|||
|
cwCheapChangeClip,
|
|||
|
cwCheapDestroyClip,
|
|||
|
cwCheapCopyClip,
|
|||
|
};
|
|||
|
|
|||
|
DrawablePtr
|
|||
|
cwGetBackingDrawable(DrawablePtr pDrawable, int *x_off, int *y_off)
|
|||
|
{
|
|||
|
if (cwDrawableIsRedirWindow(pDrawable)) {
|
|||
|
WindowPtr pWin = (WindowPtr)pDrawable;
|
|||
|
PixmapPtr pPixmap = (*pDrawable->pScreen->GetWindowPixmap)(pWin);
|
|||
|
*x_off = -pPixmap->screen_x;
|
|||
|
*y_off = -pPixmap->screen_y;
|
|||
|
|
|||
|
return &pPixmap->drawable;
|
|||
|
} else {
|
|||
|
*x_off = *y_off = 0;
|
|||
|
|
|||
|
return pDrawable;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* create the full func/op wrappers for a GC
|
|||
|
*/
|
|||
|
|
|||
|
static Bool
|
|||
|
cwCreateGCPrivate(GCPtr pGC, DrawablePtr pDrawable)
|
|||
|
{
|
|||
|
cwGCRec *pPriv;
|
|||
|
int status, x_off, y_off;
|
|||
|
XID noexpose = xFalse;
|
|||
|
DrawablePtr pBackingDrawable;
|
|||
|
|
|||
|
pPriv = (cwGCRec *)xalloc(sizeof (cwGCRec));
|
|||
|
if (!pPriv)
|
|||
|
return FALSE;
|
|||
|
pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);
|
|||
|
pPriv->pBackingGC = CreateGC(pBackingDrawable, GCGraphicsExposures,
|
|||
|
&noexpose, &status);
|
|||
|
if (status != Success) {
|
|||
|
xfree(pPriv);
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
pPriv->guarantee = GuaranteeNothing;
|
|||
|
pPriv->serialNumber = 0;
|
|||
|
pPriv->stateChanges = (1 << (GCLastBit + 1)) - 1;
|
|||
|
pPriv->wrapOps = pGC->ops;
|
|||
|
pPriv->wrapFuncs = pGC->funcs;
|
|||
|
pGC->funcs = &cwGCFuncs;
|
|||
|
pGC->ops = &cwGCOps;
|
|||
|
setCwGC (pGC, pPriv);
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
cwDestroyGCPrivate(GCPtr pGC)
|
|||
|
{
|
|||
|
cwGCPtr pPriv;
|
|||
|
|
|||
|
pPriv = (cwGCPtr) getCwGC (pGC);
|
|||
|
pGC->funcs = &cwCheapGCFuncs;
|
|||
|
pGC->ops = pPriv->wrapOps;
|
|||
|
if (pPriv->pBackingGC)
|
|||
|
FreeGC(pPriv->pBackingGC, (XID)0);
|
|||
|
setCwGC (pGC, pPriv->wrapFuncs);
|
|||
|
xfree((pointer)pPriv);
|
|||
|
}
|
|||
|
|
|||
|
/* GCFuncs wrappers. These only get used when the drawable is a window with a
|
|||
|
* backing pixmap, to avoid the overhead in the non-window-backing-pixmap case.
|
|||
|
*/
|
|||
|
|
|||
|
#define FUNC_PROLOGUE(pGC, pPriv) \
|
|||
|
((pGC)->funcs = pPriv->wrapFuncs), \
|
|||
|
((pGC)->ops = pPriv->wrapOps)
|
|||
|
|
|||
|
#define FUNC_EPILOGUE(pGC, pPriv) \
|
|||
|
((pGC)->funcs = &cwGCFuncs), \
|
|||
|
((pGC)->ops = &cwGCOps)
|
|||
|
|
|||
|
static void
|
|||
|
cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
|
|||
|
{
|
|||
|
GCPtr pBackingGC;
|
|||
|
cwGCPtr pPriv;
|
|||
|
DrawablePtr pBackingDrawable;
|
|||
|
int x_off, y_off;
|
|||
|
|
|||
|
pPriv = (cwGCPtr) getCwGC (pGC);
|
|||
|
|
|||
|
FUNC_PROLOGUE(pGC, pPriv);
|
|||
|
|
|||
|
if (pDrawable->serialNumber != pPriv->serialNumber &&
|
|||
|
!cwDrawableIsRedirWindow(pDrawable))
|
|||
|
{
|
|||
|
/* The drawable is no longer a window with backing store, so kill the
|
|||
|
* private and go back to cheap functions.
|
|||
|
*/
|
|||
|
cwDestroyGCPrivate(pGC);
|
|||
|
(*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
|
|||
|
return;
|
|||
|
}
|
|||
|
(*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
|
|||
|
|
|||
|
/*
|
|||
|
* rewrap funcs and ops as Validate may have changed them
|
|||
|
*/
|
|||
|
pPriv->wrapFuncs = pGC->funcs;
|
|||
|
pPriv->wrapOps = pGC->ops;
|
|||
|
|
|||
|
pBackingGC = pPriv->pBackingGC;
|
|||
|
pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);
|
|||
|
|
|||
|
pPriv->stateChanges |= stateChanges;
|
|||
|
|
|||
|
if (pPriv->stateChanges) {
|
|||
|
CopyGC(pGC, pBackingGC, pPriv->stateChanges);
|
|||
|
pPriv->stateChanges = 0;
|
|||
|
}
|
|||
|
|
|||
|
if ((pGC->patOrg.x + x_off) != pBackingGC->patOrg.x ||
|
|||
|
(pGC->patOrg.y + y_off) != pBackingGC->patOrg.y)
|
|||
|
{
|
|||
|
XID vals[2];
|
|||
|
vals[0] = pGC->patOrg.x + x_off;
|
|||
|
vals[1] = pGC->patOrg.y + y_off;
|
|||
|
DoChangeGC(pBackingGC, GCTileStipXOrigin|GCTileStipYOrigin, vals, 0);
|
|||
|
}
|
|||
|
|
|||
|
if (pDrawable->serialNumber != pPriv->serialNumber) {
|
|||
|
XID vals[2];
|
|||
|
|
|||
|
/* Either the drawable has changed, or the clip list in the drawable has
|
|||
|
* changed. Copy the new clip list over and set the new translated
|
|||
|
* offset for it.
|
|||
|
*/
|
|||
|
|
|||
|
(*pBackingGC->funcs->DestroyClip)(pBackingGC);
|
|||
|
(*pBackingGC->funcs->CopyClip)(pBackingGC, pGC);
|
|||
|
vals[0] = pGC->clipOrg.x + x_off;
|
|||
|
vals[1] = pGC->clipOrg.y + y_off;
|
|||
|
DoChangeGC(pBackingGC, GCClipXOrigin|GCClipYOrigin, vals, 0);
|
|||
|
|
|||
|
ValidateGC(pBackingDrawable, pBackingGC);
|
|||
|
pPriv->serialNumber = pDrawable->serialNumber;
|
|||
|
}
|
|||
|
|
|||
|
FUNC_EPILOGUE(pGC, pPriv);
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
cwChangeGC(GCPtr pGC, unsigned long mask)
|
|||
|
{
|
|||
|
cwGCPtr pPriv = (cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr;
|
|||
|
|
|||
|
FUNC_PROLOGUE(pGC, pPriv);
|
|||
|
|
|||
|
(*pGC->funcs->ChangeGC) (pGC, mask);
|
|||
|
|
|||
|
FUNC_EPILOGUE(pGC, pPriv);
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
cwCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
|
|||
|
{
|
|||
|
cwGCPtr pPriv = (cwGCPtr)(pGCDst)->devPrivates[cwGCIndex].ptr;
|
|||
|
|
|||
|
FUNC_PROLOGUE(pGCDst, pPriv);
|
|||
|
|
|||
|
(*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
|
|||
|
|
|||
|
FUNC_EPILOGUE(pGCDst, pPriv);
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
cwDestroyGC(GCPtr pGC)
|
|||
|
{
|
|||
|
cwGCPtr pPriv = (cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr;
|
|||
|
|
|||
|
FUNC_PROLOGUE(pGC, pPriv);
|
|||
|
|
|||
|
cwDestroyGCPrivate(pGC);
|
|||
|
|
|||
|
(*pGC->funcs->DestroyGC) (pGC);
|
|||
|
|
|||
|
/* leave it unwrapped */
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
cwChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
|
|||
|
{
|
|||
|
cwGCPtr pPriv = (cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr;
|
|||
|
|
|||
|
FUNC_PROLOGUE(pGC, pPriv);
|
|||
|
|
|||
|
(*pGC->funcs->ChangeClip)(pGC, type, pvalue, nrects);
|
|||
|
|
|||
|
FUNC_EPILOGUE(pGC, pPriv);
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
cwCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
|
|||
|
{
|
|||
|
cwGCPtr pPriv = (cwGCPtr)(pgcDst)->devPrivates[cwGCIndex].ptr;
|
|||
|
|
|||
|
FUNC_PROLOGUE(pgcDst, pPriv);
|
|||
|
|
|||
|
(*pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
|
|||
|
|
|||
|
FUNC_EPILOGUE(pgcDst, pPriv);
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
cwDestroyClip(GCPtr pGC)
|
|||
|
{
|
|||
|
cwGCPtr pPriv = (cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr;
|
|||
|
|
|||
|
FUNC_PROLOGUE(pGC, pPriv);
|
|||
|
|
|||
|
(*pGC->funcs->DestroyClip)(pGC);
|
|||
|
|
|||
|
FUNC_EPILOGUE(pGC, pPriv);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* Cheap GC func wrappers. Pass everything through unless we find a window with
|
|||
|
* a backing pixmap, then turn on the real wrappers.
|
|||
|
*/
|
|||
|
|
|||
|
#define CHEAP_FUNC_PROLOGUE(pGC) \
|
|||
|
((pGC)->funcs = (GCFuncs *)(pGC)->devPrivates[cwGCIndex].ptr)
|
|||
|
|
|||
|
#define CHEAP_FUNC_EPILOGUE(pGC) \
|
|||
|
((pGC)->funcs = &cwCheapGCFuncs)
|
|||
|
|
|||
|
static void
|
|||
|
cwCheapValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
|
|||
|
{
|
|||
|
CHEAP_FUNC_PROLOGUE(pGC);
|
|||
|
|
|||
|
/* Check if the drawable is a window with backing pixmap. If so,
|
|||
|
* cwCreateGCPrivate will wrap with the backing-pixmap GC funcs and we won't
|
|||
|
* re-wrap on return.
|
|||
|
*/
|
|||
|
if (pDrawable->type == DRAWABLE_WINDOW &&
|
|||
|
cwDrawableIsRedirWindow(pDrawable) &&
|
|||
|
cwCreateGCPrivate(pGC, pDrawable))
|
|||
|
{
|
|||
|
(*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
(*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
|
|||
|
|
|||
|
/* rewrap funcs as Validate may have changed them */
|
|||
|
pGC->devPrivates[cwGCIndex].ptr = (pointer) pGC->funcs;
|
|||
|
|
|||
|
CHEAP_FUNC_EPILOGUE(pGC);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
cwCheapChangeGC(GCPtr pGC, unsigned long mask)
|
|||
|
{
|
|||
|
CHEAP_FUNC_PROLOGUE(pGC);
|
|||
|
|
|||
|
(*pGC->funcs->ChangeGC)(pGC, mask);
|
|||
|
|
|||
|
CHEAP_FUNC_EPILOGUE(pGC);
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
cwCheapCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
|
|||
|
{
|
|||
|
CHEAP_FUNC_PROLOGUE(pGCDst);
|
|||
|
|
|||
|
(*pGCDst->funcs->CopyGC)(pGCSrc, mask, pGCDst);
|
|||
|
|
|||
|
CHEAP_FUNC_EPILOGUE(pGCDst);
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
cwCheapDestroyGC(GCPtr pGC)
|
|||
|
{
|
|||
|
CHEAP_FUNC_PROLOGUE(pGC);
|
|||
|
|
|||
|
(*pGC->funcs->DestroyGC)(pGC);
|
|||
|
|
|||
|
/* leave it unwrapped */
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
cwCheapChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
|
|||
|
{
|
|||
|
CHEAP_FUNC_PROLOGUE(pGC);
|
|||
|
|
|||
|
(*pGC->funcs->ChangeClip)(pGC, type, pvalue, nrects);
|
|||
|
|
|||
|
CHEAP_FUNC_EPILOGUE(pGC);
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
cwCheapCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
|
|||
|
{
|
|||
|
CHEAP_FUNC_PROLOGUE(pgcDst);
|
|||
|
|
|||
|
(*pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
|
|||
|
|
|||
|
CHEAP_FUNC_EPILOGUE(pgcDst);
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
cwCheapDestroyClip(GCPtr pGC)
|
|||
|
{
|
|||
|
CHEAP_FUNC_PROLOGUE(pGC);
|
|||
|
|
|||
|
(*pGC->funcs->DestroyClip)(pGC);
|
|||
|
|
|||
|
CHEAP_FUNC_EPILOGUE(pGC);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* GC Create wrapper. Set up the cheap GC func wrappers to track
|
|||
|
* GC validation on BackingStore windows.
|
|||
|
*/
|
|||
|
|
|||
|
#define SCREEN_PROLOGUE(pScreen, field)\
|
|||
|
((pScreen)->field = ((cwScreenPtr) \
|
|||
|
(pScreen)->devPrivates[cwScreenIndex].ptr)->field)
|
|||
|
|
|||
|
#define SCREEN_EPILOGUE(pScreen, field, wrapper)\
|
|||
|
((pScreen)->field = wrapper)
|
|||
|
|
|||
|
static Bool
|
|||
|
cwCreateGC(GCPtr pGC)
|
|||
|
{
|
|||
|
ScreenPtr pScreen = pGC->pScreen;
|
|||
|
Bool ret;
|
|||
|
|
|||
|
SCREEN_PROLOGUE(pScreen, CreateGC);
|
|||
|
|
|||
|
if ( (ret = (*pScreen->CreateGC)(pGC)) )
|
|||
|
{
|
|||
|
pGC->devPrivates[cwGCIndex].ptr = (pointer)pGC->funcs;
|
|||
|
pGC->funcs = &cwCheapGCFuncs;
|
|||
|
}
|
|||
|
|
|||
|
SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC);
|
|||
|
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
cwGetImage(DrawablePtr pSrc, int sx, int sy, int w, int h, unsigned int format,
|
|||
|
unsigned long planemask, char *pdstLine)
|
|||
|
{
|
|||
|
ScreenPtr pScreen = pSrc->pScreen;
|
|||
|
DrawablePtr pBackingDrawable;
|
|||
|
int x_off, y_off;
|
|||
|
|
|||
|
SCREEN_PROLOGUE(pScreen, GetImage);
|
|||
|
|
|||
|
pBackingDrawable = cwGetBackingDrawable(pSrc, &x_off, &y_off);
|
|||
|
|
|||
|
sx += x_off;
|
|||
|
sy += y_off;
|
|||
|
|
|||
|
(*pScreen->GetImage)(pBackingDrawable, sx, sy, w, h, format, planemask, pdstLine);
|
|||
|
|
|||
|
SCREEN_EPILOGUE(pScreen, GetImage, cwGetImage);
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
cwGetSpans(DrawablePtr pSrc, int wMax, DDXPointPtr ppt, int *pwidth,
|
|||
|
int nspans, char *pdstStart)
|
|||
|
{
|
|||
|
ScreenPtr pScreen = pSrc->pScreen;
|
|||
|
DrawablePtr pBackingDrawable;
|
|||
|
int i;
|
|||
|
int x_off, y_off;
|
|||
|
DDXPointPtr ppt_trans;
|
|||
|
|
|||
|
SCREEN_PROLOGUE(pScreen, GetSpans);
|
|||
|
|
|||
|
pBackingDrawable = cwGetBackingDrawable(pSrc, &x_off, &y_off);
|
|||
|
|
|||
|
ppt_trans = (DDXPointPtr)ALLOCATE_LOCAL(nspans * sizeof(DDXPointRec));
|
|||
|
if (ppt_trans) {
|
|||
|
for (i = 0; i < nspans; i++) {
|
|||
|
ppt_trans[i].x = ppt[i].x + x_off;
|
|||
|
ppt_trans[i].y = ppt[i].y + y_off;
|
|||
|
}
|
|||
|
|
|||
|
(*pScreen->GetSpans)(pBackingDrawable, wMax, ppt, pwidth, nspans,
|
|||
|
pdstStart);
|
|||
|
DEALLOCATE_LOCAL(ppt_trans);
|
|||
|
}
|
|||
|
|
|||
|
SCREEN_EPILOGUE(pScreen, GetSpans, cwGetSpans);
|
|||
|
}
|
|||
|
|
|||
|
/* Screen initialization/teardown */
|
|||
|
void
|
|||
|
miInitializeCompositeWrapper(ScreenPtr pScreen)
|
|||
|
{
|
|||
|
cwScreenPtr pScreenPriv;
|
|||
|
|
|||
|
if (cwGeneration != serverGeneration)
|
|||
|
{
|
|||
|
cwScreenIndex = AllocateScreenPrivateIndex();
|
|||
|
if (cwScreenIndex < 0)
|
|||
|
return;
|
|||
|
cwGCIndex = AllocateGCPrivateIndex();
|
|||
|
#ifdef RENDER
|
|||
|
cwPictureIndex = AllocatePicturePrivateIndex();
|
|||
|
#endif
|
|||
|
cwGeneration = serverGeneration;
|
|||
|
}
|
|||
|
if (!AllocateGCPrivate(pScreen, cwGCIndex, 0))
|
|||
|
return;
|
|||
|
pScreenPriv = (cwScreenPtr)xalloc(sizeof(cwScreenRec));
|
|||
|
if (!pScreenPriv)
|
|||
|
return;
|
|||
|
|
|||
|
pScreenPriv->CloseScreen = pScreen->CloseScreen;
|
|||
|
pScreenPriv->GetImage = pScreen->GetImage;
|
|||
|
pScreenPriv->GetSpans = pScreen->GetSpans;
|
|||
|
pScreenPriv->CreateGC = pScreen->CreateGC;
|
|||
|
|
|||
|
pScreen->CloseScreen = cwCloseScreen;
|
|||
|
pScreen->GetImage = cwGetImage;
|
|||
|
pScreen->GetSpans = cwGetSpans;
|
|||
|
pScreen->CreateGC = cwCreateGC;
|
|||
|
|
|||
|
pScreen->devPrivates[cwScreenIndex].ptr = (pointer)pScreenPriv;
|
|||
|
|
|||
|
#ifdef RENDER
|
|||
|
if (GetPictureScreen (pScreen))
|
|||
|
{
|
|||
|
if (!cwInitializeRender (pScreen))
|
|||
|
/* FIXME */;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
ErrorF("Initialized composite wrapper\n");
|
|||
|
}
|
|||
|
|
|||
|
static Bool
|
|||
|
cwCloseScreen (int i, ScreenPtr pScreen)
|
|||
|
{
|
|||
|
cwScreenPtr pScreenPriv;
|
|||
|
#ifdef RENDER
|
|||
|
PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
|
|||
|
#endif
|
|||
|
|
|||
|
pScreenPriv = (cwScreenPtr)pScreen->devPrivates[cwScreenIndex].ptr;
|
|||
|
|
|||
|
pScreen->CloseScreen = pScreenPriv->CloseScreen;
|
|||
|
pScreen->GetImage = pScreenPriv->GetImage;
|
|||
|
pScreen->GetSpans = pScreenPriv->GetSpans;
|
|||
|
pScreen->CreateGC = pScreenPriv->CreateGC;
|
|||
|
|
|||
|
#ifdef RENDER
|
|||
|
if (ps) {
|
|||
|
ps->Composite = pScreenPriv->Composite;
|
|||
|
ps->Glyphs = pScreenPriv->Glyphs;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
xfree((pointer)pScreenPriv);
|
|||
|
|
|||
|
return (*pScreen->CloseScreen)(i, pScreen);
|
|||
|
}
|