cw_ops.c revision 706f2543
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 61extern GCFuncs cwGCFuncs; 62 63/* 64 * GC ops -- wrap each GC operation with our own function 65 */ 66 67static void cwFillSpans(DrawablePtr pDst, GCPtr pGC, int nInit, 68 DDXPointPtr pptInit, int *pwidthInit, int fSorted); 69static void cwSetSpans(DrawablePtr pDst, GCPtr pGC, char *psrc, 70 DDXPointPtr ppt, int *pwidth, int nspans, int fSorted); 71static void cwPutImage(DrawablePtr pDst, GCPtr pGC, int depth, 72 int x, int y, int w, int h, int leftPad, int format, 73 char *pBits); 74static RegionPtr cwCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, 75 int srcx, int srcy, int w, int h, 76 int dstx, int dsty); 77static 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); 80static void cwPolyPoint(DrawablePtr pDst, GCPtr pGC, int mode, int npt, 81 xPoint *pptInit); 82static void cwPolylines(DrawablePtr pDst, GCPtr pGC, int mode, int npt, 83 DDXPointPtr pptInit); 84static void cwPolySegment(DrawablePtr pDst, GCPtr pGC, int nseg, 85 xSegment *pSegs); 86static void cwPolyRectangle(DrawablePtr pDst, GCPtr pGC, 87 int nrects, xRectangle *pRects); 88static void cwPolyArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *parcs); 89static void cwFillPolygon(DrawablePtr pDst, GCPtr pGC, int shape, int mode, 90 int count, DDXPointPtr pPts); 91static void cwPolyFillRect(DrawablePtr pDst, GCPtr pGC, 92 int nrectFill, xRectangle *prectInit); 93static void cwPolyFillArc(DrawablePtr pDst, GCPtr pGC, 94 int narcs, xArc *parcs); 95static int cwPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, 96 int count, char *chars); 97static int cwPolyText16(DrawablePtr pDst, GCPtr pGC, int x, int y, 98 int count, unsigned short *chars); 99static void cwImageText8(DrawablePtr pDst, GCPtr pGC, int x, int y, 100 int count, char *chars); 101static void cwImageText16(DrawablePtr pDst, GCPtr pGC, int x, int y, 102 int count, unsigned short *chars); 103static void cwImageGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, 104 unsigned int nglyph, CharInfoPtr *ppci, 105 pointer pglyphBase); 106static void cwPolyGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, 107 unsigned int nglyph, CharInfoPtr *ppci, 108 pointer pglyphBase); 109static void cwPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, 110 int w, int h, int x, int y); 111 112GCOps 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 135static void 136cwFillSpans(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 151static void 152cwSetSpans(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 167static void 168cwPutImage(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 183static RegionPtr 184cwCopyArea(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 212static RegionPtr 213cwCopyPlane(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 241static void 242cwPolyPoint(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 258static void 259cwPolylines(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 275static void 276cwPolySegment(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 289static void 290cwPolyRectangle(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 303static void 304cwPolyArc(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 317static void 318cwFillPolygon(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 336static void 337cwPolyFillRect(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 350static void 351cwPolyFillArc(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 364static int 365cwPolyText8(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 382static int 383cwPolyText16(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 400static void 401cwImageText8(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 415static void 416cwImageText16(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 431static void 432cwImageGlyphBlt(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 447static void 448cwPolyGlyphBlt(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 463static void 464cwPushPixels(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