summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2004-08-14 19:53:36 +0000
committerKeith Packard <keithp@keithp.com>2004-08-14 19:53:36 +0000
commitcc3ad0ed4302f54318e190a2b10646337f242d40 (patch)
tree54b1414304c8a9759effd8841ad28a9c2026543f
parent183c6d06455114c61f6db57ec0a084caf11ece3a (diff)
Fix clip list computation and setting to ignore clip changes to "real"
GC/Picture and track serial numbers correctly when copying pCompositeClip down.
-rw-r--r--miext/cw/cw.c42
-rw-r--r--miext/cw/cw.h14
-rw-r--r--miext/cw/cw_render.c123
3 files changed, 109 insertions, 70 deletions
diff --git a/miext/cw/cw.c b/miext/cw/cw.c
index f3a9934ca..6e9ef6a07 100644
--- a/miext/cw/cw.c
+++ b/miext/cw/cw.c
@@ -218,23 +218,15 @@ cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
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)
+ /*
+ * Copy the composite clip into the backing GC if either
+ * the drawable clip list has changed or the client has changed
+ * the client clip data
+ */
+ if (pDrawable->serialNumber != pPriv->serialNumber ||
+ (pPriv->stateChanges & (GCClipXOrigin|GCClipYOrigin|GCClipMask)))
{
XID vals[2];
- vals[0] = pGC->patOrg.x + x_off;
- vals[1] = pGC->patOrg.y + y_off;
- dixChangeGC(NullClient, pBackingGC,
- (GCTileStipXOrigin | GCTileStipYOrigin), vals, NULL);
- }
-
- if (pDrawable->serialNumber != pPriv->serialNumber) {
- XID vals[2];
RegionPtr pCompositeClip;
pCompositeClip = REGION_CREATE (pScreen, NULL, 0);
@@ -254,6 +246,26 @@ cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
(GCClipXOrigin | GCClipYOrigin), vals, NULL);
pPriv->serialNumber = pDrawable->serialNumber;
+ /*
+ * Mask off any client clip changes to make sure
+ * the clip list set above remains in effect
+ */
+ pPriv->stateChanges &= ~(GCClipXOrigin|GCClipYOrigin|GCClipMask);
+ }
+
+ 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;
+ dixChangeGC(NullClient, pBackingGC,
+ (GCTileStipXOrigin | GCTileStipYOrigin), vals, NULL);
}
ValidateGC(pBackingDrawable, pBackingGC);
diff --git a/miext/cw/cw.h b/miext/cw/cw.h
index 2ff2e6576..8c3cca64c 100644
--- a/miext/cw/cw.h
+++ b/miext/cw/cw.h
@@ -44,6 +44,20 @@ extern int cwGCIndex;
#define getCwGC(pGC) ((cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr)
#define setCwGC(pGC,p) ((pGC)->devPrivates[cwGCIndex].ptr = (pointer) (p))
+/*
+ * One of these structures is allocated per Picture that gets used with a
+ * window with a backing pixmap
+ */
+
+typedef struct {
+ PicturePtr pBackingPicture;
+ unsigned long serialNumber;
+ unsigned long stateChanges;
+} cwPictureRec, *cwPicturePtr;
+
+#define getCwPicture(pPicture) ((cwPicturePtr)(pPicture)->devPrivates[cwPictureIndex].ptr)
+#define setCwPicture(pPicture,p) ((pPicture)->devPrivates[cwPictureIndex].ptr = (pointer) (p))
+
extern int cwPictureIndex;
#define cwDrawableIsRedirWindow(pDraw) \
diff --git a/miext/cw/cw_render.c b/miext/cw/cw_render.c
index 8e6d011b6..ab698dca6 100644
--- a/miext/cw/cw_render.c
+++ b/miext/cw/cw_render.c
@@ -31,9 +31,8 @@
PictureScreenPtr ps = GetPictureScreen (pScreen); \
cwScreenPtr pCwScreen = getCwScreen (pScreen)
-#define cwPictureDecl \
- PicturePtr pBackingPicture = \
- ((pPicture)->devPrivates[cwPictureIndex].ptr)
+#define cwPicturePrivate \
+ cwPicturePtr pPicturePrivate = getCwPicture(pPicture)
#define cwSrcPictureDecl \
int src_picture_x_off, src_picture_y_off; \
@@ -63,45 +62,60 @@
ps->elt = func; \
}
-static PicturePtr
-cwCreateBackingPicture (PicturePtr pPicture)
+static cwPicturePtr
+cwCreatePicturePrivate (PicturePtr pPicture)
{
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWindow);
int error;
- PicturePtr pBackingPicture;
+ cwPicturePtr pPicturePrivate;
- pBackingPicture = CreatePicture (0, &pPixmap->drawable, pPicture->pFormat,
- 0, 0, serverClient, &error);
- if (!pBackingPicture)
+ pPicturePrivate = xalloc (sizeof (cwPictureRec));
+ if (!pPicturePrivate)
return NULL;
+
+ pPicturePrivate->pBackingPicture = CreatePicture (0, &pPixmap->drawable,
+ pPicture->pFormat,
+ 0, 0, serverClient,
+ &error);
+ if (!pPicturePrivate->pBackingPicture)
+ {
+ xfree (pPicturePrivate);
+ return NULL;
+ }
- pPicture->devPrivates[cwPictureIndex].ptr = pBackingPicture;
-
- CopyPicture(pPicture, (1 << (CPLastBit + 1)) - 1, pBackingPicture);
+ /*
+ * Ensure that this serial number does not match the window's
+ */
+ pPicturePrivate->serialNumber = pPixmap->drawable.serialNumber;
+ pPicturePrivate->stateChanges = (1 << (CPLastBit + 1)) - 1;
+
+ setCwPicture(pPicture, pPicturePrivate);
- return pBackingPicture;
+ return pPicturePrivate;
}
static void
-cwDestroyBackingPicture (PicturePtr pPicture)
+cwDestroyPicturePrivate (PicturePtr pPicture)
{
- cwPictureDecl;
+ cwPicturePrivate;
- if (pBackingPicture)
+ if (pPicturePrivate)
{
- FreePicture (pBackingPicture, 0);
- pPicture->devPrivates[cwPictureIndex].ptr = NULL;
+ if (pPicturePrivate->pBackingPicture)
+ FreePicture (pPicturePrivate->pBackingPicture, 0);
+ xfree (pPicturePrivate);
+ setCwPicture(pPicture, NULL);
}
}
static PicturePtr
cwGetBackingPicture (PicturePtr pPicture, int *x_off, int *y_off)
{
- cwPictureDecl;
+ cwPicturePrivate;
- if (pBackingPicture)
+ if (pPicturePrivate)
{
DrawablePtr pDrawable = pPicture->pDrawable;
ScreenPtr pScreen = pDrawable->pScreen;
@@ -111,7 +125,7 @@ cwGetBackingPicture (PicturePtr pPicture, int *x_off, int *y_off)
*x_off = pWin->drawable.x - pPixmap->screen_x;
*y_off = pWin->drawable.y - pPixmap->screen_y;
- return pBackingPicture;
+ return pPicturePrivate->pBackingPicture;
}
else
{
@@ -127,33 +141,22 @@ cwDestroyPicture (PicturePtr pPicture)
cwPsDecl(pScreen);
cwPsUnwrap(DestroyPicture);
- cwDestroyBackingPicture (pPicture);
+ cwDestroyPicturePrivate (pPicture);
(*ps->DestroyPicture) (pPicture);
cwPsWrap(DestroyPicture, cwDestroyPicture);
- /* The ChangePicture and ValidatePictures on the window haven't been passed
- * down the stack, so report all state being changed.
- */
- pPicture->stateChanges |= (1 << (CPLastBit + 1)) - 1;
- (*ps->ChangePicture) (pPicture, (1 << (CPLastBit + 1)) - 1);
}
static void
-cwChangePicture (PicturePtr pPicture,
- Mask mask)
+cwChangePicture (PicturePtr pPicture, Mask mask)
{
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
cwPsDecl(pScreen);
- cwPictureDecl;
+ cwPicturePtr pPicturePrivate = getCwPicture(pPicture);
cwPsUnwrap(ChangePicture);
- if (pBackingPicture)
- {
- (*ps->ChangePicture) (pBackingPicture, mask);
- }
- else
- {
- (*ps->ChangePicture) (pPicture, mask);
- }
+ (*ps->ChangePicture) (pPicture, mask);
+ if (pPicturePrivate)
+ pPicturePrivate->stateChanges |= mask;
cwPsWrap(ChangePicture, cwChangePicture);
}
@@ -165,7 +168,7 @@ cwValidatePicture (PicturePtr pPicture,
DrawablePtr pDrawable = pPicture->pDrawable;
ScreenPtr pScreen = pDrawable->pScreen;
cwPsDecl(pScreen);
- cwPictureDecl;
+ cwPicturePrivate;
cwPsUnwrap(ValidatePicture);
@@ -176,44 +179,54 @@ cwValidatePicture (PicturePtr pPicture,
if (!cwDrawableIsRedirWindow (pDrawable))
{
- if (pBackingPicture)
- cwDestroyBackingPicture (pPicture);
+ if (pPicturePrivate)
+ cwDestroyPicturePrivate (pPicture);
}
else
{
+ PicturePtr pBackingPicture;
DrawablePtr pBackingDrawable;
int x_off, y_off;
- pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off,
- &y_off);
+ pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);
- if (pBackingPicture && pBackingPicture->pDrawable != pBackingDrawable)
+ if (pPicturePrivate &&
+ pPicturePrivate->pBackingPicture->pDrawable != pBackingDrawable)
{
- cwDestroyBackingPicture (pPicture);
- pBackingPicture = 0;
+ cwDestroyPicturePrivate (pPicture);
+ pPicturePrivate = 0;
}
- if (!pBackingPicture)
+ if (!pPicturePrivate)
{
- pBackingPicture = cwCreateBackingPicture (pPicture);
- if (!pBackingPicture)
+ pPicturePrivate = cwCreatePicturePrivate (pPicture);
+ if (!pPicturePrivate)
{
cwPsWrap(ValidatePicture, cwValidatePicture);
return;
}
}
+ pBackingPicture = pPicturePrivate->pBackingPicture;
+
SetPictureTransform(pBackingPicture, pPicture->transform);
/* XXX Set filters */
- mask &= ~(CPClipXOrigin | CPClipYOrigin);
+ pPicturePrivate->stateChanges |= mask;
- CopyPicture(pPicture, mask, pBackingPicture);
+ if (pPicturePrivate->serialNumber != pDrawable->serialNumber ||
+ (pPicturePrivate->stateChanges & (CPClipXOrigin|CPClipYOrigin|CPClipMask)))
+ {
+ SetPictureClipRegion (pBackingPicture,
+ x_off - pDrawable->x,
+ y_off - pDrawable->y,
+ pPicture->pCompositeClip);
+
+ pPicturePrivate->serialNumber = pDrawable->serialNumber;
+ pPicturePrivate->stateChanges &= ~(CPClipXOrigin | CPClipYOrigin | CPClipMask);
+ }
- SetPictureClipRegion (pBackingPicture,
- x_off - pDrawable->x,
- y_off - pDrawable->y,
- pPicture->pCompositeClip);
+ CopyPicture(pPicture, pPicturePrivate->stateChanges, pBackingPicture);
ValidatePicture (pBackingPicture);
}