summaryrefslogtreecommitdiff
path: root/miext
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2004-07-31 08:24:14 +0000
committerEric Anholt <anholt@freebsd.org>2004-07-31 08:24:14 +0000
commitd690556d496c7331bd112903a0c9e6553c7d3342 (patch)
tree0e0016e04d05d6cbcdfb689ddb05d8f3a928dadf /miext
parent8763cca7f9927bd6c9caf804bf09dcfea929eed0 (diff)
Integrate COMPOSITEWRAP branch including composite wrapper. This code still
has several issues, including: - CopyWindow and PaintWindow wrappers missing (will be done soon) - Some segfaults seen in the Render wrappers. - Xprt server build breaks with Composite. - DDXs must be recompiled for Composite due to VisualRec size change. - Composite bugs pointed out by Deron Johnson in email. Also, reorder XFixes initialization according to comments by Keith which are also in xserver CVS.
Diffstat (limited to 'miext')
-rw-r--r--miext/cw/cw.c570
-rw-r--r--miext/cw/cw.h164
-rw-r--r--miext/cw/cw_ops.c537
-rw-r--r--miext/cw/cw_render.c447
4 files changed, 1718 insertions, 0 deletions
diff --git a/miext/cw/cw.c b/miext/cw/cw.c
new file mode 100644
index 000000000..8394ca8a3
--- /dev/null
+++ b/miext/cw/cw.c
@@ -0,0 +1,570 @@
+/*
+ * Copyright © 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);
+}
diff --git a/miext/cw/cw.h b/miext/cw/cw.h
new file mode 100644
index 000000000..33e62f039
--- /dev/null
+++ b/miext/cw/cw.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright © 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 "picturestr.h"
+
+/*
+ * One of these structures is allocated per GC that gets used with a window with
+ * backing pixmap.
+ */
+
+typedef struct {
+ GCPtr pBackingGC; /* Copy of the GC but with graphicsExposures
+ * set FALSE and the clientClip set to
+ * clip output to the valid regions of the
+ * backing pixmap. */
+ int guarantee; /* GuaranteeNothing, etc. */
+ unsigned long serialNumber; /* clientClip computed time */
+ unsigned long stateChanges; /* changes in parent gc since last copy */
+ GCOps *wrapOps; /* wrapped ops */
+ GCFuncs *wrapFuncs; /* wrapped funcs */
+} cwGCRec, *cwGCPtr;
+
+extern int cwGCIndex;
+
+#define getCwGC(pGC) ((cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr)
+#define setCwGC(pGC,p) ((pGC)->devPrivates[cwGCIndex].ptr = (pointer) (p))
+
+typedef struct {
+ PicturePtr pBackingPicture;
+ unsigned long serialNumber; /* clientClip computed time */
+ unsigned long stateChanges; /* changes in parent gc since last copy */
+} cwPictureRec, *cwPicturePtr;
+
+extern int cwPictureIndex;
+
+#define getCwPicture(pPicture) ((cwPicturePtr)(pPicture)->devPrivates[cwPictureIndex].ptr)
+#define setCwPicture(pPicture,p) ((pPicture)->devPrivates[cwPictureIndex].ptr = (pointer) (p))
+
+#define cwDrawableIsRedirWindow(pDraw) ((pDraw)->type == DRAWABLE_WINDOW && \
+ ((WindowPtr)(pDraw))->redirectDraw)
+
+typedef struct {
+ /*
+ * screen func wrappers
+ */
+ CloseScreenProcPtr CloseScreen;
+ GetImageProcPtr GetImage;
+ GetSpansProcPtr GetSpans;
+ CreateGCProcPtr CreateGC;
+
+ DestroyWindowProcPtr DestroyWindow;
+
+ StoreColorsProcPtr StoreColors;
+
+ InitIndexedProcPtr InitIndexed;
+ CloseIndexedProcPtr CloseIndexed;
+ UpdateIndexedProcPtr UpdateIndexed;
+
+#ifdef RENDER
+ CreatePictureProcPtr CreatePicture;
+ DestroyPictureProcPtr DestroyPicture;
+ ChangePictureClipProcPtr ChangePictureClip;
+ DestroyPictureClipProcPtr DestroyPictureClip;
+
+ ChangePictureProcPtr ChangePicture;
+ ValidatePictureProcPtr ValidatePicture;
+
+ CompositeProcPtr Composite;
+ GlyphsProcPtr Glyphs;
+ CompositeRectsProcPtr CompositeRects;
+
+ TrapezoidsProcPtr Trapezoids;
+ TrianglesProcPtr Triangles;
+ TriStripProcPtr TriStrip;
+ TriFanProcPtr TriFan;
+
+ RasterizeTrapezoidProcPtr RasterizeTrapezoid;
+#if 0
+ AddTrapsProcPtr AddTraps;
+#endif
+#endif
+} cwScreenRec, *cwScreenPtr;
+
+extern int cwScreenIndex;
+
+#define getCwScreen(pScreen) ((cwScreenPtr)(pScreen)->devPrivates[cwScreenIndex].ptr)
+#define setCwScreen(pScreen,p) ((cwScreenPtr)(pScreen)->devPrivates[cwScreenIndex].ptr = (p))
+
+#define CW_COPY_OFFSET_XYPOINTS(ppt_trans, ppt, npt) do { \
+ short *_origpt = (short *)(ppt); \
+ short *_transpt = (short *)(ppt_trans); \
+ int _i; \
+ for (_i = 0; _i < npt; _i++) { \
+ *_transpt++ = *_origpt++ + dst_off_x; \
+ *_transpt++ = *_origpt++ + dst_off_y; \
+ } \
+} while (0)
+
+#define CW_COPY_OFFSET_RECTS(prect_trans, prect, nrect) do { \
+ short *_origpt = (short *)(prect); \
+ short *_transpt = (short *)(prect_trans); \
+ int _i; \
+ for (_i = 0; _i < nrect; _i++) { \
+ *_transpt++ = *_origpt++ + dst_off_x; \
+ *_transpt++ = *_origpt++ + dst_off_y; \
+ _transpt += 2; \
+ _origpt += 2; \
+ } \
+} while (0)
+
+#define CW_COPY_OFFSET_ARCS(parc_trans, parc, narc) do { \
+ short *_origpt = (short *)(parc); \
+ short *_transpt = (short *)(parc_trans); \
+ int _i; \
+ for (_i = 0; _i < narc; _i++) { \
+ *_transpt++ = *_origpt++ + dst_off_x; \
+ *_transpt++ = *_origpt++ + dst_off_y; \
+ _transpt += 4; \
+ _origpt += 4; \
+ } \
+} while (0)
+
+#define CW_COPY_OFFSET_XY_DST(bx, by, x, y) do { \
+ bx = x + dst_off_x; \
+ by = y + dst_off_y; \
+} while (0)
+
+#define CW_COPY_OFFSET_XY_SRC(bx, by, x, y) do { \
+ bx = x + src_off_x; \
+ by = y + src_off_y; \
+} while (0)
+
+/* cw.c */
+DrawablePtr
+cwGetBackingDrawable(DrawablePtr pDrawable, int *x_off, int *y_off);
+
+/* cw_render.c */
+
+Bool
+cwInitializeRender (ScreenPtr pScreen);
+
+/* cw.c */
+void
+miInitializeCompositeWrapper(ScreenPtr pScreen);
diff --git a/miext/cw/cw_ops.c b/miext/cw/cw_ops.c
new file mode 100644
index 000000000..879bfb04d
--- /dev/null
+++ b/miext/cw/cw_ops.c
@@ -0,0 +1,537 @@
+/*
+ * Copyright © 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 "cw.h"
+
+#define SETUP_BACKING_DST(_pDst, _pGC) \
+ cwGCPtr pGCPrivate = getCwGC (_pGC); \
+ GCFuncs *oldFuncs = (_pGC)->funcs; \
+ GCPtr pBackingGC = pGCPrivate->pBackingGC; \
+ int dst_off_x, dst_off_y; \
+ DrawablePtr pBackingDst = cwGetBackingDrawable(pDst, &dst_off_x, \
+ &dst_off_y)
+
+#define SETUP_BACKING_SRC(pSrc, pGC) \
+ int src_off_x, src_off_y; \
+ DrawablePtr pBackingSrc = cwGetBackingDrawable(pSrc, &src_off_x, \
+ &src_off_y)
+
+#define PROLOGUE(pGC) do { \
+ pGC->ops = pGCPrivate->wrapOps;\
+ pGC->funcs = pGCPrivate->wrapFuncs; \
+} while (0)
+
+#define EPILOGUE(pGC) do { \
+ pGCPrivate->wrapOps = (pGC)->ops; \
+ (pGC)->ops = &cwGCOps; \
+ (pGC)->funcs = oldFuncs; \
+} while (0)
+
+/*
+ * GC ops -- wrap each GC operation with our own function
+ */
+
+static void cwFillSpans(DrawablePtr pDst, GCPtr pGC, int nInit,
+ DDXPointPtr pptInit, int *pwidthInit, int fSorted);
+static void cwSetSpans(DrawablePtr pDst, GCPtr pGC, char *psrc,
+ DDXPointPtr ppt, int *pwidth, int nspans, int fSorted);
+static void cwPutImage(DrawablePtr pDst, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ char *pBits);
+static RegionPtr cwCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h,
+ int dstx, int dsty);
+static RegionPtr cwCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h,
+ int dstx, int dsty, unsigned long plane);
+static void cwPolyPoint(DrawablePtr pDst, GCPtr pGC, int mode, int npt,
+ xPoint *pptInit);
+static void cwPolylines(DrawablePtr pDst, GCPtr pGC, int mode, int npt,
+ DDXPointPtr pptInit);
+static void cwPolySegment(DrawablePtr pDst, GCPtr pGC, int nseg,
+ xSegment *pSegs);
+static void cwPolyRectangle(DrawablePtr pDst, GCPtr pGC,
+ int nrects, xRectangle *pRects);
+static void cwPolyArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *parcs);
+static void cwFillPolygon(DrawablePtr pDst, GCPtr pGC, int shape, int mode,
+ int count, DDXPointPtr pPts);
+static void cwPolyFillRect(DrawablePtr pDst, GCPtr pGC,
+ int nrectFill, xRectangle *prectInit);
+static void cwPolyFillArc(DrawablePtr pDst, GCPtr pGC,
+ int narcs, xArc *parcs);
+static int cwPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ int count, char *chars);
+static int cwPolyText16(DrawablePtr pDst, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars);
+static void cwImageText8(DrawablePtr pDst, GCPtr pGC, int x, int y,
+ int count, char *chars);
+static void cwImageText16(DrawablePtr pDst, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars);
+static void cwImageGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y,
+ unsigned int nglyph, CharInfoPtr *ppci,
+ pointer pglyphBase);
+static void cwPolyGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y,
+ unsigned int nglyph, CharInfoPtr *ppci,
+ pointer pglyphBase);
+static void cwPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
+ int w, int h, int x, int y);
+
+GCOps cwGCOps = {
+ cwFillSpans,
+ cwSetSpans,
+ cwPutImage,
+ cwCopyArea,
+ cwCopyPlane,
+ cwPolyPoint,
+ cwPolylines,
+ cwPolySegment,
+ cwPolyRectangle,
+ cwPolyArc,
+ cwFillPolygon,
+ cwPolyFillRect,
+ cwPolyFillArc,
+ cwPolyText8,
+ cwPolyText16,
+ cwImageText8,
+ cwImageText16,
+ cwImageGlyphBlt,
+ cwPolyGlyphBlt,
+ cwPushPixels
+};
+
+static void
+cwFillSpans(DrawablePtr pDst, GCPtr pGC, int nspans, DDXPointPtr ppt,
+ int *pwidth, int fSorted)
+{
+ DDXPointPtr ppt_trans;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ ppt_trans = (DDXPointPtr)ALLOCATE_LOCAL(nspans * sizeof(DDXPointRec));
+ if (ppt_trans)
+ {
+ CW_COPY_OFFSET_XYPOINTS(ppt_trans, ppt, nspans);
+
+ (*pBackingGC->ops->FillSpans)(pBackingDst, pBackingGC,
+ nspans, ppt_trans, pwidth, fSorted);
+
+ DEALLOCATE_LOCAL(ppt_trans);
+ }
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwSetSpans(DrawablePtr pDst, GCPtr pGC, char *psrc, DDXPointPtr ppt,
+ int *pwidth, int nspans, int fSorted)
+{
+ DDXPointPtr ppt_trans;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ ppt_trans = (DDXPointPtr)ALLOCATE_LOCAL(nspans*sizeof(DDXPointRec));
+ if (ppt_trans)
+ {
+ CW_COPY_OFFSET_XYPOINTS(ppt_trans, ppt, nspans);
+
+ (*pBackingGC->ops->SetSpans)(pBackingDst, pBackingGC, psrc,
+ ppt_trans, pwidth, nspans, fSorted);
+
+ DEALLOCATE_LOCAL(ppt_trans);
+ }
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y, int w, int h,
+ int leftPad, int format, char *pBits)
+{
+ int bx, by;
+
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_COPY_OFFSET_XY_DST(bx, by, x, y);
+
+ (*pBackingGC->ops->PutImage)(pBackingDst, pBackingGC, depth, bx, by,
+ w, h, leftPad, format, pBits);
+
+ EPILOGUE(pGC);
+}
+
+static RegionPtr
+cwCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy,
+ int w, int h, int dstx, int dsty)
+{
+ int bsrcx, bsrcy, bdstx, bdsty;
+ RegionPtr exposed = NULL;
+ SETUP_BACKING_DST(pDst, pGC);
+ SETUP_BACKING_SRC(pSrc, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_COPY_OFFSET_XY_DST(bdstx, bdsty, dstx, dsty);
+ CW_COPY_OFFSET_XY_SRC(bsrcx, bsrcy, srcx, srcy);
+
+ exposed = (*pBackingGC->ops->CopyArea)(pBackingSrc, pBackingDst,
+ pBackingGC, bsrcx, bsrcy, w, h,
+ bdstx, bdsty);
+
+ /* XXX: Simplify? */
+ if (exposed != NULL)
+ REGION_TRANSLATE(pDst->pScreen, exposed, dstx - bdstx, dsty - bdsty);
+
+ EPILOGUE(pGC);
+
+ return exposed;
+}
+
+static RegionPtr
+cwCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy,
+ int w, int h, int dstx, int dsty, unsigned long plane)
+{
+ int bsrcx, bsrcy, bdstx, bdsty;
+ RegionPtr exposed = NULL;
+ SETUP_BACKING_DST(pDst, pGC);
+ SETUP_BACKING_SRC(pSrc, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_COPY_OFFSET_XY_DST(bdstx, bdsty, dstx, dsty);
+ CW_COPY_OFFSET_XY_SRC(bsrcx, bsrcy, srcx, srcy);
+
+ exposed = (*pBackingGC->ops->CopyPlane)(pBackingSrc, pBackingDst,
+ pBackingGC, bsrcx, bsrcy, w, h,
+ bdstx, bdsty, plane);
+
+ /* XXX: Simplify? */
+ REGION_TRANSLATE(pDst->pScreen, exposed, dstx - bdstx, dsty - bdsty);
+
+ EPILOGUE(pGC);
+
+ return exposed;
+}
+
+static void
+cwPolyPoint(DrawablePtr pDst, GCPtr pGC, int mode, int npt, xPoint *ppt)
+{
+ xPoint *ppt_trans;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ ppt_trans = (xPoint *)ALLOCATE_LOCAL(npt * sizeof(xPoint));
+ if (ppt_trans)
+ {
+ CW_COPY_OFFSET_XYPOINTS(ppt_trans, ppt, npt);
+
+ (*pBackingGC->ops->PolyPoint)(pBackingDst, pBackingGC, mode, npt,
+ ppt_trans);
+
+ DEALLOCATE_LOCAL(ppt_trans);
+ }
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwPolylines(DrawablePtr pDst, GCPtr pGC, int mode, int npt, DDXPointPtr ppt)
+{
+ DDXPointPtr ppt_trans;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ ppt_trans = (DDXPointPtr)ALLOCATE_LOCAL(npt * sizeof(DDXPointRec));
+ if (ppt_trans)
+ {
+ CW_COPY_OFFSET_XYPOINTS(ppt_trans, ppt, npt);
+
+ (*pBackingGC->ops->Polylines)(pBackingDst, pBackingGC, mode, npt,
+ ppt_trans);
+
+ DEALLOCATE_LOCAL(ppt_trans);
+ }
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwPolySegment(DrawablePtr pDst, GCPtr pGC, int nseg, xSegment *pSegs)
+{
+ xSegment *psegs_trans;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ psegs_trans = (xSegment *)ALLOCATE_LOCAL(nseg * sizeof(xSegment));
+ if (psegs_trans)
+ {
+ CW_COPY_OFFSET_XYPOINTS(psegs_trans, pSegs, nseg * 2);
+
+ (*pBackingGC->ops->PolySegment)(pBackingDst, pBackingGC, nseg,
+ psegs_trans);
+
+ DEALLOCATE_LOCAL(psegs_trans);
+ }
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwPolyRectangle(DrawablePtr pDst, GCPtr pGC, int nrects, xRectangle *pRects)
+{
+ xRectangle *prects_trans;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ prects_trans = (xRectangle *)ALLOCATE_LOCAL(nrects * sizeof(xRectangle));
+ if (prects_trans)
+ {
+ CW_COPY_OFFSET_RECTS(prects_trans, pRects, nrects);
+
+ (*pBackingGC->ops->PolyRectangle)(pBackingDst, pBackingGC, nrects,
+ prects_trans);
+
+ DEALLOCATE_LOCAL(pRectsCopy);
+ }
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwPolyArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *pArcs)
+{
+ xArc *parcs_trans;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ parcs_trans = (xArc *)ALLOCATE_LOCAL(narcs * sizeof(xArc));
+ if (parcs_trans)
+ {
+ CW_COPY_OFFSET_RECTS(parcs_trans, pArcs, narcs);
+
+ (*pBackingGC->ops->PolyArc)(pBackingDst, pBackingGC, narcs,
+ parcs_trans);
+
+ DEALLOCATE_LOCAL(parcs_trans);
+ }
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwFillPolygon(DrawablePtr pDst, GCPtr pGC, int shape, int mode, int npt,
+ DDXPointPtr ppt)
+{
+ DDXPointPtr ppt_trans;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ ppt_trans = (DDXPointPtr)ALLOCATE_LOCAL(npt * sizeof(DDXPointRec));
+ if (ppt_trans)
+ {
+ CW_COPY_OFFSET_XYPOINTS(ppt_trans, ppt, npt);
+
+ (*pBackingGC->ops->FillPolygon)(pBackingDst, pBackingGC, shape, mode,
+ npt, ppt_trans);
+
+ DEALLOCATE_LOCAL(ppt_trans);
+ }
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwPolyFillRect(DrawablePtr pDst, GCPtr pGC, int nrects, xRectangle *pRects)
+{
+ xRectangle *prects_trans;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ prects_trans = (xRectangle *)ALLOCATE_LOCAL(nrects * sizeof(xRectangle));
+ if (prects_trans)
+ {
+ CW_COPY_OFFSET_RECTS(prects_trans, pRects, nrects);
+
+ (*pBackingGC->ops->PolyFillRect)(pBackingDst, pBackingGC, nrects,
+ prects_trans);
+
+ DEALLOCATE_LOCAL(pRectsCopy);
+ }
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwPolyFillArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *parcs)
+{
+ xArc *parcs_trans;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ parcs_trans = (xArc *)ALLOCATE_LOCAL(narcs * sizeof(xArc));
+ if (parcs_trans)
+ {
+ CW_COPY_OFFSET_RECTS(parcs_trans, parcs, narcs);
+
+ (*pBackingGC->ops->PolyFillArc)(pBackingDst, pBackingGC, narcs,
+ parcs_trans);
+
+ DEALLOCATE_LOCAL(parcs_trans);
+ }
+
+ EPILOGUE(pGC);
+}
+
+static int
+cwPolyText8(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, char *chars)
+{
+ int result;
+ int bx, by;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_COPY_OFFSET_XY_DST(bx, by, x, y);
+
+ result = (*pBackingGC->ops->PolyText8)(pBackingDst, pBackingGC, bx, by,
+ count, chars);
+
+ EPILOGUE(pGC);
+ return result;
+}
+
+static int
+cwPolyText16(DrawablePtr pDst, GCPtr pGC, int x, int y, int count,
+ unsigned short *chars)
+{
+ int result;
+ int bx, by;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_COPY_OFFSET_XY_DST(bx, by, x, y);
+
+ result = (*pBackingGC->ops->PolyText16)(pBackingDst, pBackingGC, bx, by,
+ count, chars);
+
+ EPILOGUE(pGC);
+ return result;
+}
+
+static void
+cwImageText8(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, char *chars)
+{
+ int bx, by;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_COPY_OFFSET_XY_DST(bx, by, x, y);
+
+ (*pBackingGC->ops->ImageText8)(pBackingDst, pBackingGC, bx, by, count,
+ chars);
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwImageText16(DrawablePtr pDst, GCPtr pGC, int x, int y, int count,
+ unsigned short *chars)
+{
+ int bx, by;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_COPY_OFFSET_XY_DST(bx, by, x, y);
+
+ (*pBackingGC->ops->ImageText16)(pBackingDst, pBackingGC, bx, by, count,
+ chars);
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwImageGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ int bx, by;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_COPY_OFFSET_XY_DST(bx, by, x, y);
+
+ (*pBackingGC->ops->ImageGlyphBlt)(pBackingDst, pBackingGC, bx, by, nglyph,
+ ppci, pglyphBase);
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwPolyGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ int bx, by;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_COPY_OFFSET_XY_DST(bx, by, x, y);
+
+ (*pBackingGC->ops->PolyGlyphBlt)(pBackingDst, pBackingGC, bx, by, nglyph,
+ ppci, pglyphBase);
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, int w, int h,
+ int x, int y)
+{
+ int bx, by;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_COPY_OFFSET_XY_DST(bx, by, x, y);
+
+ (*pBackingGC->ops->PushPixels)(pBackingGC, pBitMap, pBackingDst, w, h,
+ bx, by);
+
+ EPILOGUE(pGC);
+}
+
diff --git a/miext/cw/cw_render.c b/miext/cw/cw_render.c
new file mode 100644
index 000000000..4f8bed8e4
--- /dev/null
+++ b/miext/cw/cw_render.c
@@ -0,0 +1,447 @@
+/*
+ * Copyright © 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"
+
+#ifdef RENDER
+
+#define cwPsDecl(pScreen) \
+ PictureScreenPtr ps = GetPictureScreen (pScreen); \
+ cwScreenPtr pCwScreen = getCwScreen (pScreen)
+
+#define cwBackingPicture(pCwPicture, pPicture) \
+ ((pCwPicture && pCwPicture->pBackingPicture) ? \
+ pCwPicture->pBackingPicture : pPicture)
+
+#define cwPictureDecl \
+ cwPicturePtr pCwPicture = getCwPicture(pPicture); \
+ PicturePtr pBackingPicture = pCwPicture ? pCwPicture->pBackingPicture : 0
+
+#define cwSrcPictureDecl \
+ int src_picture_x_off, src_picture_y_off; \
+ PicturePtr pBackingSrcPicture = cwGetBackingPicture(pSrcPicture, \
+ &src_picture_x_off,\
+ &src_picture_y_off)
+
+#define cwDstPictureDecl \
+ int dst_picture_x_off, dst_picture_y_off; \
+ PicturePtr pBackingDstPicture = cwGetBackingPicture(pDstPicture, \
+ &dst_picture_x_off,\
+ &dst_picture_y_off)
+
+#define cwMskPictureDecl \
+ int msk_picture_x_off = 0, msk_picture_y_off = 0; \
+ PicturePtr pBackingMskPicture = (!pMskPicture ? 0 : \
+ cwGetBackingPicture(pMskPicture, \
+ &msk_picture_x_off,\
+ &msk_picture_y_off))
+
+#define cwPsUnwrap(elt) { \
+ ps->elt = pCwScreen->elt; \
+}
+
+#define cwPsWrap(elt,func) { \
+ pCwScreen->elt = ps->elt; \
+ ps->elt = func; \
+}
+
+static VisualPtr
+cwFindVisualById (ScreenPtr pScreen, VisualID visual)
+{
+ int i;
+ VisualPtr pVisual;
+ for (i = 0, pVisual = pScreen->visuals;
+ i < pScreen->numVisuals;
+ i++, pVisual++)
+ {
+ if (pVisual->vid == visual)
+ return pVisual;
+ }
+ return 0;
+}
+
+static PicturePtr
+cwCreateBackingPicture (PicturePtr pPicture)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
+ PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWindow);
+ VisualPtr pVisual = cwFindVisualById (pScreen, wVisual (pWindow));
+ PictFormatPtr pFormat = PictureMatchVisual (pScreen, pWindow->drawable.depth,
+ pVisual);
+ int error;
+ PicturePtr pBackingPicture = CreatePicture (0, &pPixmap->drawable, pFormat,
+ 0, 0, serverClient, &error);
+ cwPicturePtr pCwPicture = getCwPicture (pPicture);
+
+ return pCwPicture->pBackingPicture = pBackingPicture;
+}
+
+static void
+cwDestroyBackingPicture (PicturePtr pPicture)
+{
+ cwPictureDecl;
+
+ if (pBackingPicture)
+ {
+ FreePicture (pBackingPicture, 0);
+ pCwPicture->pBackingPicture = 0;
+ }
+}
+
+static PicturePtr
+cwGetBackingPicture (PicturePtr pPicture, int *x_off, int *y_off)
+{
+ cwPictureDecl;
+
+ if (pBackingPicture)
+ {
+ DrawablePtr pDrawable = pPicture->pDrawable;
+ ScreenPtr pScreen = pDrawable->pScreen;
+ WindowPtr pWin = (WindowPtr) pDrawable;
+ PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
+
+ *x_off = -pPixmap->screen_x;
+ *y_off = -pPixmap->screen_y;
+
+ return pBackingPicture;
+ }
+ else
+ {
+ *x_off = *y_off = 0;
+ return pPicture;
+ }
+}
+
+static int
+cwCreatePicture (PicturePtr pPicture)
+{
+ int ret;
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+
+ cwPsUnwrap (CreatePicture);
+ setCwPicture(pPicture, 0);
+ ret = (*ps->CreatePicture) (pPicture);
+ cwPsWrap (CreatePicture, cwCreatePicture);
+ return ret;
+}
+
+static void
+cwDestroyPicture (PicturePtr pPicture)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+
+ cwPsUnwrap(DestroyPicture);
+ cwDestroyBackingPicture (pPicture);
+ (*ps->DestroyPicture) (pPicture);
+ cwPsWrap(DestroyPicture, cwDestroyPicture);
+}
+
+static void
+cwChangePicture (PicturePtr pPicture,
+ Mask mask)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwPictureDecl;
+
+ cwPsUnwrap(ChangePicture);
+ if (pBackingPicture)
+ {
+ (*ps->ChangePicture) (pBackingPicture, mask);
+ }
+ else
+ {
+ (*ps->ChangePicture) (pPicture, mask);
+ }
+ cwPsWrap(ChangePicture, cwChangePicture);
+}
+
+static void
+cwValidatePicture (PicturePtr pPicture,
+ Mask mask)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwPictureDecl;
+
+ cwPsUnwrap(ValidatePicture);
+ (*ps->ValidatePicture) (pPicture, mask);
+ if (!cwDrawableIsRedirWindow (pPicture->pDrawable))
+ {
+ if (pBackingPicture)
+ cwDestroyBackingPicture (pPicture);
+ }
+ else
+ {
+ DrawablePtr pDrawable = pPicture->pDrawable;
+ WindowPtr pWin = (WindowPtr) (pDrawable);
+ DrawablePtr pBackingDrawable;
+ int x_off, y_off;
+
+ if (pBackingPicture && pBackingPicture->pDrawable !=
+ &(*pScreen->GetWindowPixmap) ((WindowPtr) pPicture->pDrawable)->drawable)
+ {
+ cwDestroyBackingPicture (pPicture);
+ pBackingPicture = 0;
+ }
+
+ if (!pBackingPicture)
+ {
+ pBackingPicture = cwCreateBackingPicture (pPicture);
+ if (!pBackingPicture)
+ {
+ cwPsWrap(ValidatePicture, cwValidatePicture);
+ return;
+ }
+ }
+
+ pBackingDrawable = cwGetBackingDrawable (&pWin->drawable, &x_off, &y_off);
+
+ /* Check to see if a new composite clip must be generated */
+
+ if (pDrawable->serialNumber != pCwPicture->serialNumber ||
+ (mask & (CPClipXOrigin|CPClipYOrigin|CPClipMask|CPSubwindowMode)))
+ {
+ RegionPtr pCompositeClip;
+
+ pCompositeClip = REGION_CREATE(pScreen, NULL, 1);
+ /* note - CT_PIXMAP "cannot" happen because no DDX supports it*/
+ REGION_COPY (pScreen, pCompositeClip, pPicture->pCompositeClip);
+ SetPictureClipRegion (pBackingPicture, -x_off, -y_off,
+ pCompositeClip);
+ pCwPicture->serialNumber = pDrawable->serialNumber;
+ }
+ mask |= pCwPicture->stateChanges;
+ (*ps->ValidatePicture) (pBackingPicture, mask);
+ pCwPicture->stateChanges = 0;
+ pBackingPicture->serialNumber = pBackingDrawable->serialNumber;
+ }
+ cwPsWrap(ValidatePicture, cwValidatePicture);
+}
+
+static void
+cwComposite (CARD8 op,
+ PicturePtr pSrcPicture,
+ PicturePtr pMskPicture,
+ PicturePtr pDstPicture,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMsk,
+ INT16 yMsk,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwSrcPictureDecl;
+ cwMskPictureDecl;
+ cwDstPictureDecl;
+
+ cwPsUnwrap(Composite);
+ (*ps->Composite) (op, pBackingSrcPicture, pBackingMskPicture, pBackingDstPicture,
+ xSrc + src_picture_x_off, ySrc + src_picture_y_off,
+ xMsk + msk_picture_x_off, yMsk + msk_picture_y_off,
+ xDst + dst_picture_x_off, yDst + dst_picture_y_off,
+ width, height);
+ cwPsWrap(Composite, cwComposite);
+}
+
+static void
+cwGlyphs (CARD8 op,
+ PicturePtr pSrcPicture,
+ PicturePtr pDstPicture,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlists,
+ GlyphListPtr lists,
+ GlyphPtr *glyphs)
+{
+ ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwSrcPictureDecl;
+ cwDstPictureDecl;
+
+ cwPsUnwrap(Glyphs);
+ if (nlists)
+ {
+ lists->xOff += dst_picture_x_off;
+ lists->yOff += dst_picture_y_off;
+ }
+ (*ps->Glyphs) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
+ xSrc + src_picture_x_off, ySrc + src_picture_y_off,
+ nlists, lists, glyphs);
+ if (nlists)
+ {
+ lists->xOff -= dst_picture_x_off;
+ lists->yOff -= dst_picture_y_off;
+ }
+ cwPsWrap(Glyphs, cwGlyphs);
+}
+
+static void
+cwCompositeRects (CARD8 op,
+ PicturePtr pDstPicture,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects)
+{
+ ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwDstPictureDecl;
+ int i;
+
+ cwPsUnwrap(CompositeRects);
+ for (i = 0; i < nRect; i++)
+ {
+ rects[i].x += dst_picture_x_off;
+ rects[i].y += dst_picture_y_off;
+ }
+ (*ps->CompositeRects) (op, pBackingDstPicture, color, nRect, rects);
+ for (i = 0; i < nRect; i++)
+ {
+ rects[i].x -= dst_picture_x_off;
+ rects[i].y -= dst_picture_y_off;
+ }
+ cwPsWrap(CompositeRects, cwCompositeRects);
+}
+
+static void
+cwTrapezoids (CARD8 op,
+ PicturePtr pSrcPicture,
+ PicturePtr pDstPicture,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps)
+{
+ ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwSrcPictureDecl;
+ cwDstPictureDecl;
+ int i;
+
+ cwPsUnwrap(Trapezoids);
+ if (dst_picture_x_off | dst_picture_y_off)
+ for (i = 0; i < ntrap; i++)
+ {
+ traps[i].top += dst_picture_y_off << 16;
+ traps[i].bottom += dst_picture_y_off << 16;
+ traps[i].left.p1.x += dst_picture_x_off << 16;
+ traps[i].left.p1.y += dst_picture_y_off << 16;
+ traps[i].left.p2.x += dst_picture_x_off << 16;
+ traps[i].left.p2.y += dst_picture_y_off << 16;
+ traps[i].right.p1.x += dst_picture_x_off << 16;
+ traps[i].right.p1.y += dst_picture_y_off << 16;
+ traps[i].right.p2.x += dst_picture_x_off << 16;
+ traps[i].right.p2.y += dst_picture_y_off << 16;
+ }
+ (*ps->Trapezoids) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
+ xSrc + src_picture_x_off, ySrc + src_picture_y_off,
+ ntrap, traps);
+ if (dst_picture_x_off | dst_picture_y_off)
+ for (i = 0; i < ntrap; i++)
+ {
+ traps[i].top -= dst_picture_y_off << 16;
+ traps[i].bottom -= dst_picture_y_off << 16;
+ traps[i].left.p1.x -= dst_picture_x_off << 16;
+ traps[i].left.p1.y -= dst_picture_y_off << 16;
+ traps[i].left.p2.x -= dst_picture_x_off << 16;
+ traps[i].left.p2.y -= dst_picture_y_off << 16;
+ traps[i].right.p1.x -= dst_picture_x_off << 16;
+ traps[i].right.p1.y -= dst_picture_y_off << 16;
+ traps[i].right.p2.x -= dst_picture_x_off << 16;
+ traps[i].right.p2.y -= dst_picture_y_off << 16;
+ }
+ cwPsWrap(Trapezoids, cwTrapezoids);
+}
+
+static void
+cwTriangles (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntri,
+ xTriangle *tris)
+{
+ /* FIXME */
+}
+
+static void
+cwTriStrip (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points)
+{
+ /* FIXME */
+}
+
+static void
+cwTriFan (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points)
+{
+ /* FIXME */
+}
+
+Bool
+cwInitializeRender (ScreenPtr pScreen)
+{
+ cwPsDecl (pScreen);
+
+ if (!AllocatePicturePrivate (pScreen, cwPictureIndex, 0))
+ return FALSE;
+ cwPsWrap(CreatePicture, cwCreatePicture);
+ cwPsWrap(DestroyPicture, cwDestroyPicture);
+ cwPsWrap(ChangePicture, cwChangePicture);
+ cwPsWrap(ValidatePicture, cwValidatePicture);
+ cwPsWrap(Composite, cwComposite);
+ cwPsWrap(Glyphs, cwGlyphs);
+ cwPsWrap(CompositeRects, cwCompositeRects);
+ cwPsWrap(Trapezoids, cwTrapezoids);
+ cwPsWrap(Triangles, cwTriangles);
+ cwPsWrap(TriStrip, cwTriStrip);
+ cwPsWrap(TriFan, cwTriFan);
+ return TRUE;
+}
+
+#endif /* RENDER */