Fix CopyArea for non-redir dst, redir src (Bug #1105, Eric Anholt).
This commit is contained in:
parent
9223baf985
commit
8784228500
195
miext/cw/cw.c
195
miext/cw/cw.c
|
@ -65,21 +65,6 @@ 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,
|
||||
|
@ -90,16 +75,6 @@ static GCFuncs cwGCFuncs = {
|
|||
cwCopyClip,
|
||||
};
|
||||
|
||||
static GCFuncs cwCheapGCFuncs = {
|
||||
cwCheapValidateGC,
|
||||
cwCheapChangeGC,
|
||||
cwCheapCopyGC,
|
||||
cwCheapDestroyGC,
|
||||
cwCheapChangeClip,
|
||||
cwCheapDestroyClip,
|
||||
cwCheapCopyClip,
|
||||
};
|
||||
|
||||
/* Find the real drawable to draw to, and provide offsets that will translate
|
||||
* window coordinates to backing pixmap coordinates.
|
||||
*/
|
||||
|
@ -120,10 +95,6 @@ cwGetBackingDrawable(DrawablePtr pDrawable, int *x_off, int *y_off)
|
|||
}
|
||||
}
|
||||
|
||||
/* 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) do { \
|
||||
(pGC)->funcs = (pPriv)->wrapFuncs; \
|
||||
(pGC)->ops = (pPriv)->wrapOps; \
|
||||
|
@ -136,73 +107,38 @@ cwGetBackingDrawable(DrawablePtr pDrawable, int *x_off, int *y_off)
|
|||
(pGC)->ops = &cwGCOps; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* 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 *)getCwGC(pGC))
|
||||
|
||||
#define CHEAP_FUNC_EPILOGUE(pGC) do { \
|
||||
setCwGC(pGC,(pGC)->funcs); \
|
||||
(pGC)->funcs = &cwCheapGCFuncs; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* create the full func/op wrappers for a GC.
|
||||
* This enters with the GC unwrapped. If successful, it must leave
|
||||
* with the GC wrapped. If unsuccessful, it leaves the GC alone
|
||||
*/
|
||||
|
||||
static Bool
|
||||
cwCreateGCPrivate(GCPtr pGC, DrawablePtr pDrawable)
|
||||
cwCreateBackingGC(GCPtr pGC, DrawablePtr pDrawable)
|
||||
{
|
||||
cwGCRec *pPriv;
|
||||
cwGCRec *pPriv = getCwGC(pGC);
|
||||
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);
|
||||
if (status != Success)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pPriv->serialNumber = 0;
|
||||
pPriv->stateChanges = (1 << (GCLastBit + 1)) - 1;
|
||||
|
||||
setCwGC(pGC,pPriv);
|
||||
|
||||
FUNC_EPILOGUE(pGC,pPriv);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy the full func/op wrappers for a GC and
|
||||
* switch backto the cheap ones
|
||||
* This enters with the GC unwrapped and must leave
|
||||
* with the GC cheap wrapped
|
||||
*/
|
||||
|
||||
static void
|
||||
cwDestroyGCPrivate(GCPtr pGC)
|
||||
cwDestroyBackingGC(GCPtr pGC)
|
||||
{
|
||||
cwGCPtr pPriv;
|
||||
|
||||
pPriv = (cwGCPtr) getCwGC (pGC);
|
||||
|
||||
if (pPriv->pBackingGC)
|
||||
if (pPriv->pBackingGC) {
|
||||
FreeGC(pPriv->pBackingGC, (XID)0);
|
||||
|
||||
xfree((pointer)pPriv);
|
||||
|
||||
CHEAP_FUNC_EPILOGUE (pGC);
|
||||
pPriv->pBackingGC = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -221,15 +157,16 @@ cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
|
|||
* Must call ValidateGC to ensure pGC->pCompositeClip is valid
|
||||
*/
|
||||
(*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
|
||||
|
||||
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);
|
||||
|
||||
if (!cwDrawableIsRedirWindow(pDrawable)) {
|
||||
cwDestroyBackingGC(pGC);
|
||||
FUNC_EPILOGUE(pGC, pPriv);
|
||||
return;
|
||||
} else {
|
||||
if (!pPriv->pBackingGC && !cwCreateBackingGC(pGC, pDrawable)) {
|
||||
FUNC_EPILOGUE(pGC, pPriv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pBackingGC = pPriv->pBackingGC;
|
||||
|
@ -323,7 +260,7 @@ cwDestroyGC(GCPtr pGC)
|
|||
|
||||
FUNC_PROLOGUE(pGC, pPriv);
|
||||
|
||||
cwDestroyGCPrivate(pGC);
|
||||
cwDestroyBackingGC(pGC);
|
||||
|
||||
(*pGC->funcs->DestroyGC) (pGC);
|
||||
|
||||
|
@ -366,91 +303,8 @@ cwDestroyClip(GCPtr pGC)
|
|||
FUNC_EPILOGUE(pGC, pPriv);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cwCheapValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
|
||||
{
|
||||
CHEAP_FUNC_PROLOGUE(pGC);
|
||||
|
||||
/*
|
||||
* If the drawable is a redirected window, switch the GC
|
||||
* around and revalidate with cwValidateGC.
|
||||
*/
|
||||
if (cwDrawableIsRedirWindow(pDrawable) &&
|
||||
cwCreateGCPrivate (pGC, pDrawable))
|
||||
{
|
||||
cwValidateGC (pGC, stateChanges, pDrawable);
|
||||
return;
|
||||
}
|
||||
|
||||
(*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
|
||||
|
||||
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.
|
||||
* Screen wrappers.
|
||||
*/
|
||||
|
||||
#define SCREEN_PROLOGUE(pScreen, field) \
|
||||
|
@ -464,16 +318,15 @@ cwCheapDestroyClip(GCPtr pGC)
|
|||
static Bool
|
||||
cwCreateGC(GCPtr pGC)
|
||||
{
|
||||
cwGCPtr pPriv = getCwGC(pGC);
|
||||
ScreenPtr pScreen = pGC->pScreen;
|
||||
Bool ret;
|
||||
|
||||
bzero(pPriv, sizeof(cwGCRec));
|
||||
SCREEN_PROLOGUE(pScreen, CreateGC);
|
||||
|
||||
|
||||
if ( (ret = (*pScreen->CreateGC)(pGC)) )
|
||||
{
|
||||
pGC->devPrivates[cwGCIndex].ptr = (pointer)pGC->funcs;
|
||||
pGC->funcs = &cwCheapGCFuncs;
|
||||
}
|
||||
FUNC_EPILOGUE(pGC, pPriv);
|
||||
|
||||
SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC);
|
||||
|
||||
|
@ -774,7 +627,7 @@ miInitializeCompositeWrapper(ScreenPtr pScreen)
|
|||
#endif
|
||||
cwGeneration = serverGeneration;
|
||||
}
|
||||
if (!AllocateGCPrivate(pScreen, cwGCIndex, 0))
|
||||
if (!AllocateGCPrivate(pScreen, cwGCIndex, sizeof(cwGCRec)))
|
||||
return;
|
||||
if (!AllocateWindowPrivate(pScreen, cwWindowIndex, 0))
|
||||
return;
|
||||
|
|
|
@ -26,10 +26,10 @@
|
|||
|
||||
#define SETUP_BACKING_DST(_pDst, _pGC) \
|
||||
cwGCPtr pGCPrivate = getCwGC (_pGC); \
|
||||
GCPtr pBackingGC = pGCPrivate->pBackingGC; \
|
||||
int dst_off_x, dst_off_y; \
|
||||
DrawablePtr pBackingDst = cwGetBackingDrawable(pDst, &dst_off_x, \
|
||||
&dst_off_y)
|
||||
&dst_off_y); \
|
||||
GCPtr pBackingGC = pGCPrivate->pBackingGC ? pGCPrivate->pBackingGC : _pGC
|
||||
|
||||
#define SETUP_BACKING_SRC(pSrc, pGC) \
|
||||
int src_off_x, src_off_y; \
|
||||
|
|
Loading…
Reference in New Issue