summaryrefslogtreecommitdiff
path: root/miext/cw/cw_ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'miext/cw/cw_ops.c')
-rw-r--r--miext/cw/cw_ops.c537
1 files changed, 537 insertions, 0 deletions
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);
+}
+