diff options
author | Eric Anholt <anholt@freebsd.org> | 2004-07-31 08:24:14 +0000 |
---|---|---|
committer | Eric Anholt <anholt@freebsd.org> | 2004-07-31 08:24:14 +0000 |
commit | d690556d496c7331bd112903a0c9e6553c7d3342 (patch) | |
tree | 0e0016e04d05d6cbcdfb689ddb05d8f3a928dadf /miext | |
parent | 8763cca7f9927bd6c9caf804bf09dcfea929eed0 (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.c | 570 | ||||
-rw-r--r-- | miext/cw/cw.h | 164 | ||||
-rw-r--r-- | miext/cw/cw_ops.c | 537 | ||||
-rw-r--r-- | miext/cw/cw_render.c | 447 |
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 */ |