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