Home | History | Annotate | Line # | Download | only in cw
      1 /*
      2  * Copyright  2004 Eric Anholt
      3  *
      4  * Permission to use, copy, modify, distribute, and sell this software and its
      5  * documentation for any purpose is hereby granted without fee, provided that
      6  * the above copyright notice appear in all copies and that both that
      7  * copyright notice and this permission notice appear in supporting
      8  * documentation, and that the name of Eric Anholt not be used in
      9  * advertising or publicity pertaining to distribution of the software without
     10  * specific, written prior permission.  Eric Anholt makes no
     11  * representations about the suitability of this software for any purpose.  It
     12  * is provided "as is" without express or implied warranty.
     13  *
     14  * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     16  * EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     20  * PERFORMANCE OF THIS SOFTWARE.
     21  */
     22 
     23 #ifdef HAVE_DIX_CONFIG_H
     24 #include <dix-config.h>
     25 #endif
     26 
     27 #include <stdlib.h>
     28 
     29 #include "gcstruct.h"
     30 #include "pixmapstr.h"
     31 #include "cw.h"
     32 #include "mi.h"
     33 
     34 #define SETUP_BACKING_DST(_pDst, _pGC) \
     35     cwGCPtr pGCPrivate = getCwGC (_pGC); \
     36     int dst_off_x, dst_off_y; \
     37     DrawablePtr pBackingDst = cwGetBackingDrawable(pDst, &dst_off_x, \
     38 	&dst_off_y); \
     39     GCPtr pBackingGC = pGCPrivate->pBackingGC ? pGCPrivate->pBackingGC : _pGC
     40 
     41 #define SETUP_BACKING_SRC(pSrc, pGC) \
     42     int src_off_x, src_off_y; \
     43     DrawablePtr pBackingSrc = cwGetBackingDrawable(pSrc, &src_off_x, \
     44 	&src_off_y)
     45 
     46 #define PROLOGUE(pGC) do { \
     47     if (pBackingGC->serialNumber != pBackingDst->serialNumber) { \
     48 	ValidateGC(pBackingDst, pBackingGC); \
     49     } \
     50     pGC->funcs = pGCPrivate->wrapFuncs;\
     51     pGC->ops = pGCPrivate->wrapOps;\
     52 } while (0)
     53 
     54 #define EPILOGUE(pGC) do { \
     55     pGCPrivate->wrapFuncs = (pGC)->funcs; \
     56     pGCPrivate->wrapOps = (pGC)->ops; \
     57     (pGC)->funcs = &cwGCFuncs; \
     58     (pGC)->ops = &cwGCOps; \
     59 } while (0)
     60 
     61 extern GCFuncs cwGCFuncs;
     62 
     63 /*
     64  * GC ops -- wrap each GC operation with our own function
     65  */
     66 
     67 static void cwFillSpans(DrawablePtr pDst, GCPtr pGC, int nInit,
     68 			DDXPointPtr pptInit, int *pwidthInit, int fSorted);
     69 static void cwSetSpans(DrawablePtr pDst, GCPtr pGC, char *psrc,
     70 		       DDXPointPtr ppt, int *pwidth, int nspans, int fSorted);
     71 static void cwPutImage(DrawablePtr pDst, GCPtr pGC, int depth,
     72 		       int x, int y, int w, int h, int leftPad, int format,
     73 		       char *pBits);
     74 static RegionPtr cwCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
     75 			    int srcx, int srcy, int w, int h,
     76 			    int dstx, int dsty);
     77 static RegionPtr cwCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
     78 			     int srcx, int srcy, int w, int h,
     79 			     int dstx, int dsty, unsigned long plane);
     80 static void cwPolyPoint(DrawablePtr pDst, GCPtr pGC, int mode, int npt,
     81 			xPoint *pptInit);
     82 static void cwPolylines(DrawablePtr pDst, GCPtr pGC, int mode, int npt,
     83 			DDXPointPtr pptInit);
     84 static void cwPolySegment(DrawablePtr pDst, GCPtr pGC, int nseg,
     85 			  xSegment *pSegs);
     86 static void cwPolyRectangle(DrawablePtr pDst, GCPtr pGC,
     87 			    int nrects, xRectangle *pRects);
     88 static void cwPolyArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *parcs);
     89 static void cwFillPolygon(DrawablePtr pDst, GCPtr pGC, int shape, int mode,
     90 			  int count, DDXPointPtr pPts);
     91 static void cwPolyFillRect(DrawablePtr pDst, GCPtr pGC,
     92 			   int nrectFill, xRectangle *prectInit);
     93 static void cwPolyFillArc(DrawablePtr pDst, GCPtr pGC,
     94 			  int narcs, xArc *parcs);
     95 static int cwPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
     96 		       int count, char *chars);
     97 static int cwPolyText16(DrawablePtr pDst, GCPtr pGC, int x, int y,
     98 			int count, unsigned short *chars);
     99 static void cwImageText8(DrawablePtr pDst, GCPtr pGC, int x, int y,
    100 			 int count, char *chars);
    101 static void cwImageText16(DrawablePtr pDst, GCPtr pGC, int x, int y,
    102 			  int count, unsigned short *chars);
    103 static void cwImageGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y,
    104 			    unsigned int nglyph, CharInfoPtr *ppci,
    105 			    pointer pglyphBase);
    106 static void cwPolyGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y,
    107 			   unsigned int nglyph, CharInfoPtr *ppci,
    108 			   pointer pglyphBase);
    109 static void cwPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
    110 			 int w, int h, int x, int y);
    111 
    112 GCOps cwGCOps = {
    113 	cwFillSpans,
    114 	cwSetSpans,
    115 	cwPutImage,
    116 	cwCopyArea,
    117 	cwCopyPlane,
    118 	cwPolyPoint,
    119 	cwPolylines,
    120 	cwPolySegment,
    121 	cwPolyRectangle,
    122 	cwPolyArc,
    123 	cwFillPolygon,
    124 	cwPolyFillRect,
    125 	cwPolyFillArc,
    126 	cwPolyText8,
    127 	cwPolyText16,
    128 	cwImageText8,
    129 	cwImageText16,
    130 	cwImageGlyphBlt,
    131 	cwPolyGlyphBlt,
    132 	cwPushPixels
    133 };
    134 
    135 static void
    136 cwFillSpans(DrawablePtr pDst, GCPtr pGC, int nspans, DDXPointPtr ppt,
    137 	    int *pwidth, int fSorted)
    138 {
    139     SETUP_BACKING_DST(pDst, pGC);
    140 
    141     PROLOGUE(pGC);
    142 
    143     CW_OFFSET_XYPOINTS(ppt, nspans);
    144 
    145     (*pBackingGC->ops->FillSpans)(pBackingDst, pBackingGC, nspans, ppt,
    146 				  pwidth, fSorted);
    147 
    148     EPILOGUE(pGC);
    149 }
    150 
    151 static void
    152 cwSetSpans(DrawablePtr pDst, GCPtr pGC, char *psrc, DDXPointPtr ppt,
    153 	   int *pwidth, int nspans, int fSorted)
    154 {
    155     SETUP_BACKING_DST(pDst, pGC);
    156 
    157     PROLOGUE(pGC);
    158 
    159     CW_OFFSET_XYPOINTS(ppt, nspans);
    160 
    161     (*pBackingGC->ops->SetSpans)(pBackingDst, pBackingGC, psrc, ppt, pwidth,
    162 				 nspans, fSorted);
    163 
    164     EPILOGUE(pGC);
    165 }
    166 
    167 static void
    168 cwPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y, int w, int h,
    169 	   int leftPad, int format, char *pBits)
    170 {
    171     SETUP_BACKING_DST(pDst, pGC);
    172 
    173     PROLOGUE(pGC);
    174 
    175     CW_OFFSET_XY_DST(x, y);
    176 
    177     (*pBackingGC->ops->PutImage)(pBackingDst, pBackingGC, depth, x, y, w, h,
    178 				 leftPad, format, pBits);
    179 
    180     EPILOGUE(pGC);
    181 }
    182 
    183 static RegionPtr
    184 cwCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy,
    185 	   int w, int h, int dstx, int dsty)
    186 {
    187     int		odstx, odsty;
    188     int		osrcx, osrcy;
    189     SETUP_BACKING_DST(pDst, pGC);
    190     SETUP_BACKING_SRC(pSrc, pGC);
    191 
    192     PROLOGUE(pGC);
    193 
    194     odstx = dstx;
    195     odsty = dsty;
    196     osrcx = srcx;
    197     osrcy = srcy;
    198     CW_OFFSET_XY_DST(dstx, dsty);
    199     CW_OFFSET_XY_SRC(srcx, srcy);
    200 
    201     (*pBackingGC->ops->CopyArea)(pBackingSrc, pBackingDst,
    202 				 pBackingGC, srcx, srcy, w, h,
    203 				 dstx, dsty);
    204 
    205     EPILOGUE(pGC);
    206 
    207     return miHandleExposures(pSrc, pDst, pGC,
    208 			     osrcx, osrcy, w, h,
    209 			     odstx, odsty, 0);
    210 }
    211 
    212 static RegionPtr
    213 cwCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy,
    214 	    int w, int h, int dstx, int dsty, unsigned long plane)
    215 {
    216     int		odstx, odsty;
    217     int		osrcx, osrcy;
    218     SETUP_BACKING_DST(pDst, pGC);
    219     SETUP_BACKING_SRC(pSrc, pGC);
    220 
    221     PROLOGUE(pGC);
    222 
    223     odstx = dstx;
    224     odsty = dsty;
    225     osrcx = srcx;
    226     osrcy = srcy;
    227     CW_OFFSET_XY_DST(dstx, dsty);
    228     CW_OFFSET_XY_SRC(srcx, srcy);
    229 
    230     (*pBackingGC->ops->CopyPlane)(pBackingSrc, pBackingDst,
    231 				  pBackingGC, srcx, srcy, w, h,
    232 				  dstx, dsty, plane);
    233 
    234     EPILOGUE(pGC);
    235 
    236     return miHandleExposures(pSrc, pDst, pGC,
    237 			     osrcx, osrcy, w, h,
    238 			     odstx, odsty, plane);
    239 }
    240 
    241 static void
    242 cwPolyPoint(DrawablePtr pDst, GCPtr pGC, int mode, int npt, xPoint *ppt)
    243 {
    244     SETUP_BACKING_DST(pDst, pGC);
    245 
    246     PROLOGUE(pGC);
    247 
    248     if (mode == CoordModeOrigin)
    249 	CW_OFFSET_XYPOINTS(ppt, npt);
    250     else
    251 	CW_OFFSET_XYPOINTS(ppt, 1);
    252 
    253     (*pBackingGC->ops->PolyPoint)(pBackingDst, pBackingGC, mode, npt, ppt);
    254 
    255     EPILOGUE(pGC);
    256 }
    257 
    258 static void
    259 cwPolylines(DrawablePtr pDst, GCPtr pGC, int mode, int npt, DDXPointPtr ppt)
    260 {
    261     SETUP_BACKING_DST(pDst, pGC);
    262 
    263     PROLOGUE(pGC);
    264 
    265     if (mode == CoordModeOrigin)
    266 	CW_OFFSET_XYPOINTS(ppt, npt);
    267     else
    268 	CW_OFFSET_XYPOINTS(ppt, 1);
    269 
    270     (*pBackingGC->ops->Polylines)(pBackingDst, pBackingGC, mode, npt, ppt);
    271 
    272     EPILOGUE(pGC);
    273 }
    274 
    275 static void
    276 cwPolySegment(DrawablePtr pDst, GCPtr pGC, int nseg, xSegment *pSegs)
    277 {
    278     SETUP_BACKING_DST(pDst, pGC);
    279 
    280     PROLOGUE(pGC);
    281 
    282     CW_OFFSET_XYPOINTS(pSegs, nseg * 2);
    283 
    284     (*pBackingGC->ops->PolySegment)(pBackingDst, pBackingGC, nseg, pSegs);
    285 
    286     EPILOGUE(pGC);
    287 }
    288 
    289 static void
    290 cwPolyRectangle(DrawablePtr pDst, GCPtr pGC, int nrects, xRectangle *pRects)
    291 {
    292     SETUP_BACKING_DST(pDst, pGC);
    293 
    294     PROLOGUE(pGC);
    295 
    296     CW_OFFSET_RECTS(pRects, nrects);
    297 
    298     (*pBackingGC->ops->PolyRectangle)(pBackingDst, pBackingGC, nrects, pRects);
    299 
    300     EPILOGUE(pGC);
    301 }
    302 
    303 static void
    304 cwPolyArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *pArcs)
    305 {
    306     SETUP_BACKING_DST(pDst, pGC);
    307 
    308     PROLOGUE(pGC);
    309 
    310     CW_OFFSET_RECTS(pArcs, narcs);
    311 
    312     (*pBackingGC->ops->PolyArc)(pBackingDst, pBackingGC, narcs, pArcs);
    313 
    314     EPILOGUE(pGC);
    315 }
    316 
    317 static void
    318 cwFillPolygon(DrawablePtr pDst, GCPtr pGC, int shape, int mode, int npt,
    319 	      DDXPointPtr ppt)
    320 {
    321     SETUP_BACKING_DST(pDst, pGC);
    322 
    323     PROLOGUE(pGC);
    324 
    325     if (mode == CoordModeOrigin)
    326 	CW_OFFSET_XYPOINTS(ppt, npt);
    327     else
    328 	CW_OFFSET_XYPOINTS(ppt, 1);
    329 
    330     (*pBackingGC->ops->FillPolygon)(pBackingDst, pBackingGC, shape, mode, npt,
    331 				    ppt);
    332 
    333     EPILOGUE(pGC);
    334 }
    335 
    336 static void
    337 cwPolyFillRect(DrawablePtr pDst, GCPtr pGC, int nrects, xRectangle *pRects)
    338 {
    339     SETUP_BACKING_DST(pDst, pGC);
    340 
    341     PROLOGUE(pGC);
    342 
    343     CW_OFFSET_RECTS(pRects, nrects);
    344 
    345     (*pBackingGC->ops->PolyFillRect)(pBackingDst, pBackingGC, nrects, pRects);
    346 
    347     EPILOGUE(pGC);
    348 }
    349 
    350 static void
    351 cwPolyFillArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *parcs)
    352 {
    353     SETUP_BACKING_DST(pDst, pGC);
    354 
    355     PROLOGUE(pGC);
    356 
    357     CW_OFFSET_RECTS(parcs, narcs);
    358 
    359     (*pBackingGC->ops->PolyFillArc)(pBackingDst, pBackingGC, narcs, parcs);
    360 
    361     EPILOGUE(pGC);
    362 }
    363 
    364 static int
    365 cwPolyText8(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, char *chars)
    366 {
    367     int result;
    368     SETUP_BACKING_DST(pDst, pGC);
    369 
    370     PROLOGUE(pGC);
    371 
    372     CW_OFFSET_XY_DST(x, y);
    373 
    374     result = (*pBackingGC->ops->PolyText8)(pBackingDst, pBackingGC, x, y,
    375 					   count, chars);
    376 
    377     EPILOGUE(pGC);
    378 
    379     return result;
    380 }
    381 
    382 static int
    383 cwPolyText16(DrawablePtr pDst, GCPtr pGC, int x, int y, int count,
    384 	     unsigned short *chars)
    385 {
    386     int result;
    387     SETUP_BACKING_DST(pDst, pGC);
    388 
    389     PROLOGUE(pGC);
    390 
    391     CW_OFFSET_XY_DST(x, y);
    392 
    393     result = (*pBackingGC->ops->PolyText16)(pBackingDst, pBackingGC, x, y,
    394 					    count, chars);
    395 
    396     EPILOGUE(pGC);
    397     return result;
    398 }
    399 
    400 static void
    401 cwImageText8(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, char *chars)
    402 {
    403     SETUP_BACKING_DST(pDst, pGC);
    404 
    405     PROLOGUE(pGC);
    406 
    407     CW_OFFSET_XY_DST(x, y);
    408 
    409     (*pBackingGC->ops->ImageText8)(pBackingDst, pBackingGC, x, y, count,
    410 				   chars);
    411 
    412     EPILOGUE(pGC);
    413 }
    414 
    415 static void
    416 cwImageText16(DrawablePtr pDst, GCPtr pGC, int x, int y, int count,
    417 	     unsigned short *chars)
    418 {
    419     SETUP_BACKING_DST(pDst, pGC);
    420 
    421     PROLOGUE(pGC);
    422 
    423     CW_OFFSET_XY_DST(x, y);
    424 
    425     (*pBackingGC->ops->ImageText16)(pBackingDst, pBackingGC, x, y, count,
    426 				    chars);
    427 
    428     EPILOGUE(pGC);
    429 }
    430 
    431 static void
    432 cwImageGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, unsigned int nglyph,
    433 		CharInfoPtr *ppci, pointer pglyphBase)
    434 {
    435     SETUP_BACKING_DST(pDst, pGC);
    436 
    437     PROLOGUE(pGC);
    438 
    439     CW_OFFSET_XY_DST(x, y);
    440 
    441     (*pBackingGC->ops->ImageGlyphBlt)(pBackingDst, pBackingGC, x, y, nglyph,
    442 				      ppci, pglyphBase);
    443 
    444     EPILOGUE(pGC);
    445 }
    446 
    447 static void
    448 cwPolyGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, unsigned int nglyph,
    449 	       CharInfoPtr *ppci, pointer pglyphBase)
    450 {
    451     SETUP_BACKING_DST(pDst, pGC);
    452 
    453     PROLOGUE(pGC);
    454 
    455     CW_OFFSET_XY_DST(x, y);
    456 
    457     (*pBackingGC->ops->PolyGlyphBlt)(pBackingDst, pBackingGC, x, y, nglyph,
    458 				      ppci, pglyphBase);
    459 
    460     EPILOGUE(pGC);
    461 }
    462 
    463 static void
    464 cwPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, int w, int h,
    465 	     int x, int y)
    466 {
    467     SETUP_BACKING_DST(pDst, pGC);
    468 
    469     PROLOGUE(pGC);
    470 
    471     CW_OFFSET_XY_DST(x, y);
    472 
    473     (*pBackingGC->ops->PushPixels)(pBackingGC, pBitMap, pBackingDst, w, h,
    474 				   x, y);
    475 
    476     EPILOGUE(pGC);
    477 }
    478 
    479