Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xnest / GCOps.c
1 /*
2
3 Copyright 1993 by Davor Matic
4
5 Permission to use, copy, modify, distribute, and sell this software
6 and its documentation for any purpose is hereby granted without fee,
7 provided that the above copyright notice appear in all copies and that
8 both that copyright notice and this permission notice appear in
9 supporting documentation. Davor Matic makes no representations about
10 the suitability of this software for any purpose. It is provided "as
11 is" without express or implied warranty.
12
13 */
14
15 #ifdef HAVE_XNEST_CONFIG_H
16 #include <xnest-config.h>
17 #endif
18
19 #include <X11/X.h>
20 #include <X11/Xproto.h>
21 #include "regionstr.h"
22 #include <X11/fonts/fontstruct.h>
23 #include "gcstruct.h"
24 #include "scrnintstr.h"
25 #include "windowstr.h"
26 #include "pixmapstr.h"
27 #include "region.h"
28 #include "servermd.h"
29
30 #include "Xnest.h"
31
32 #include "Display.h"
33 #include "Screen.h"
34 #include "XNGC.h"
35 #include "XNFont.h"
36 #include "GCOps.h"
37 #include "Drawable.h"
38 #include "Visual.h"
39
40 void
41 xnestFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nSpans, xPoint * pPoints,
42 int *pWidths, int fSorted)
43 {
44 ErrorF("xnest warning: function xnestFillSpans not implemented\n");
45 }
46
47 void
48 xnestSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *pSrc,
49 xPoint * pPoints, int *pWidths, int nSpans, int fSorted)
50 {
51 ErrorF("xnest warning: function xnestSetSpans not implemented\n");
52 }
53
54 void
55 xnestGetSpans(DrawablePtr pDrawable, int maxWidth, DDXPointPtr pPoints,
56 int *pWidths, int nSpans, char *pBuffer)
57 {
58 ErrorF("xnest warning: function xnestGetSpans not implemented\n");
59 }
60
61 void
62 xnestQueryBestSize(int class, unsigned short *pWidth, unsigned short *pHeight,
63 ScreenPtr pScreen)
64 {
65 unsigned int width, height;
66
67 width = *pWidth;
68 height = *pHeight;
69
70 XQueryBestSize(xnestDisplay, class,
71 xnestDefaultWindows[pScreen->myNum],
72 width, height, &width, &height);
73
74 *pWidth = width;
75 *pHeight = height;
76 }
77
78 void
79 xnestPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
80 int w, int h, int leftPad, int format, char *pImage)
81 {
82 XImage *ximage;
83
84 ximage = XCreateImage(xnestDisplay, xnestDefaultVisual(pDrawable->pScreen),
85 depth, format, leftPad, (char *) pImage,
86 w, h, BitmapPad(xnestDisplay),
87 (format == ZPixmap) ?
88 PixmapBytePad(w, depth) : BitmapBytePad(w + leftPad));
89
90 if (ximage) {
91 XPutImage(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
92 ximage, 0, 0, x, y, w, h);
93 XFree(ximage);
94 }
95 }
96
97 static int
98 xnestIgnoreErrorHandler (Display *display,
99 XErrorEvent *event)
100 {
101 return False; /* return value is ignored */
102 }
103
104 void
105 xnestGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
106 unsigned int format, unsigned long planeMask, char *pImage)
107 {
108 XImage *ximage;
109 int length;
110 int (*old_handler)(Display*, XErrorEvent*);
111
112 /* we may get BadMatch error when xnest window is minimized */
113 XSync(xnestDisplay, False);
114 old_handler = XSetErrorHandler (xnestIgnoreErrorHandler);
115
116 ximage = XGetImage(xnestDisplay, xnestDrawable(pDrawable),
117 x, y, w, h, planeMask, format);
118 XSetErrorHandler(old_handler);
119
120 if (ximage) {
121 length = ximage->bytes_per_line * ximage->height;
122
123 memmove(pImage, ximage->data, length);
124
125 XDestroyImage(ximage);
126 }
127 }
128
129 static Bool
130 xnestBitBlitPredicate(Display * display, XEvent * event, char *args)
131 {
132 return event->type == GraphicsExpose || event->type == NoExpose;
133 }
134
135 static RegionPtr
136 xnestBitBlitHelper(GCPtr pGC)
137 {
138 if (!pGC->graphicsExposures)
139 return NullRegion;
140 else {
141 XEvent event;
142 RegionPtr pReg, pTmpReg;
143 BoxRec Box;
144 Bool pending, overlap;
145
146 pReg = RegionCreate(NULL, 1);
147 pTmpReg = RegionCreate(NULL, 1);
148 if (!pReg || !pTmpReg)
149 return NullRegion;
150
151 pending = True;
152 while (pending) {
153 XIfEvent(xnestDisplay, &event, xnestBitBlitPredicate, NULL);
154
155 switch (event.type) {
156 case NoExpose:
157 pending = False;
158 break;
159
160 case GraphicsExpose:
161 Box.x1 = event.xgraphicsexpose.x;
162 Box.y1 = event.xgraphicsexpose.y;
163 Box.x2 = event.xgraphicsexpose.x + event.xgraphicsexpose.width;
164 Box.y2 = event.xgraphicsexpose.y + event.xgraphicsexpose.height;
165 RegionReset(pTmpReg, &Box);
166 RegionAppend(pReg, pTmpReg);
167 pending = event.xgraphicsexpose.count;
168 break;
169 }
170 }
171
172 RegionDestroy(pTmpReg);
173 RegionValidate(pReg, &overlap);
174 return pReg;
175 }
176 }
177
178 RegionPtr
179 xnestCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
180 GCPtr pGC, int srcx, int srcy, int width, int height,
181 int dstx, int dsty)
182 {
183 XCopyArea(xnestDisplay,
184 xnestDrawable(pSrcDrawable), xnestDrawable(pDstDrawable),
185 xnestGC(pGC), srcx, srcy, width, height, dstx, dsty);
186
187 return xnestBitBlitHelper(pGC);
188 }
189
190 RegionPtr
191 xnestCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
192 GCPtr pGC, int srcx, int srcy, int width, int height,
193 int dstx, int dsty, unsigned long plane)
194 {
195 XCopyPlane(xnestDisplay,
196 xnestDrawable(pSrcDrawable), xnestDrawable(pDstDrawable),
197 xnestGC(pGC), srcx, srcy, width, height, dstx, dsty, plane);
198
199 return xnestBitBlitHelper(pGC);
200 }
201
202 void
203 xnestPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int nPoints,
204 DDXPointPtr pPoints)
205 {
206 XDrawPoints(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
207 (XPoint *) pPoints, nPoints, mode);
208 }
209
210 void
211 xnestPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int nPoints,
212 DDXPointPtr pPoints)
213 {
214 XDrawLines(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
215 (XPoint *) pPoints, nPoints, mode);
216 }
217
218 void
219 xnestPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nSegments,
220 xSegment * pSegments)
221 {
222 XDrawSegments(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
223 (XSegment *) pSegments, nSegments);
224 }
225
226 void
227 xnestPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nRectangles,
228 xRectangle *pRectangles)
229 {
230 XDrawRectangles(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
231 (XRectangle *) pRectangles, nRectangles);
232 }
233
234 void
235 xnestPolyArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc * pArcs)
236 {
237 XDrawArcs(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
238 (XArc *) pArcs, nArcs);
239 }
240
241 void
242 xnestFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape, int mode,
243 int nPoints, DDXPointPtr pPoints)
244 {
245 XFillPolygon(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
246 (XPoint *) pPoints, nPoints, shape, mode);
247 }
248
249 void
250 xnestPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nRectangles,
251 xRectangle *pRectangles)
252 {
253 XFillRectangles(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
254 (XRectangle *) pRectangles, nRectangles);
255 }
256
257 void
258 xnestPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc * pArcs)
259 {
260 XFillArcs(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
261 (XArc *) pArcs, nArcs);
262 }
263
264 int
265 xnestPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
266 char *string)
267 {
268 int width;
269
270 XDrawString(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
271 x, y, string, count);
272
273 width = XTextWidth(xnestFontStruct(pGC->font), string, count);
274
275 return width + x;
276 }
277
278 int
279 xnestPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
280 unsigned short *string)
281 {
282 int width;
283
284 XDrawString16(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
285 x, y, (XChar2b *) string, count);
286
287 width = XTextWidth16(xnestFontStruct(pGC->font), (XChar2b *) string, count);
288
289 return width + x;
290 }
291
292 void
293 xnestImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
294 char *string)
295 {
296 XDrawImageString(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
297 x, y, string, count);
298 }
299
300 void
301 xnestImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
302 unsigned short *string)
303 {
304 XDrawImageString16(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
305 x, y, (XChar2b *) string, count);
306 }
307
308 void
309 xnestImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
310 unsigned int nGlyphs, CharInfoPtr * pCharInfo,
311 pointer pGlyphBase)
312 {
313 ErrorF("xnest warning: function xnestImageGlyphBlt not implemented\n");
314 }
315
316 void
317 xnestPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
318 unsigned int nGlyphs, CharInfoPtr * pCharInfo,
319 pointer pGlyphBase)
320 {
321 ErrorF("xnest warning: function xnestPolyGlyphBlt not implemented\n");
322 }
323
324 void
325 xnestPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDst,
326 int width, int height, int x, int y)
327 {
328 /* only works for solid bitmaps */
329 if (pGC->fillStyle == FillSolid) {
330 XSetStipple(xnestDisplay, xnestGC(pGC), xnestPixmap(pBitmap));
331 XSetTSOrigin(xnestDisplay, xnestGC(pGC), x, y);
332 XSetFillStyle(xnestDisplay, xnestGC(pGC), FillStippled);
333 XFillRectangle(xnestDisplay, xnestDrawable(pDst),
334 xnestGC(pGC), x, y, width, height);
335 XSetFillStyle(xnestDisplay, xnestGC(pGC), FillSolid);
336 }
337 else
338 ErrorF("xnest warning: function xnestPushPixels not implemented\n");
339 }