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
xnestFillSpans(DrawablePtr pDrawable,GCPtr pGC,int nSpans,xPoint * pPoints,int * pWidths,int fSorted)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
xnestSetSpans(DrawablePtr pDrawable,GCPtr pGC,char * pSrc,xPoint * pPoints,int * pWidths,int nSpans,int fSorted)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
xnestGetSpans(DrawablePtr pDrawable,int maxWidth,DDXPointPtr pPoints,int * pWidths,int nSpans,char * pBuffer)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
xnestQueryBestSize(int class,unsigned short * pWidth,unsigned short * pHeight,ScreenPtr pScreen)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
xnestPutImage(DrawablePtr pDrawable,GCPtr pGC,int depth,int x,int y,int w,int h,int leftPad,int format,char * pImage)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
xnestIgnoreErrorHandler(Display * dpy,XErrorEvent * event)98 xnestIgnoreErrorHandler (Display *dpy,
99 XErrorEvent *event)
100 {
101 return False; /* return value is ignored */
102 }
103
104 void
xnestGetImage(DrawablePtr pDrawable,int x,int y,int w,int h,unsigned int format,unsigned long planeMask,char * pImage)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
xnestBitBlitPredicate(Display * dpy,XEvent * event,char * args)130 xnestBitBlitPredicate(Display * dpy, XEvent * event, char *args)
131 {
132 return event->type == GraphicsExpose || event->type == NoExpose;
133 }
134
135 static RegionPtr
xnestBitBlitHelper(GCPtr pGC)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
xnestCopyArea(DrawablePtr pSrcDrawable,DrawablePtr pDstDrawable,GCPtr pGC,int srcx,int srcy,int width,int height,int dstx,int dsty)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
xnestCopyPlane(DrawablePtr pSrcDrawable,DrawablePtr pDstDrawable,GCPtr pGC,int srcx,int srcy,int width,int height,int dstx,int dsty,unsigned long plane)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
xnestPolyPoint(DrawablePtr pDrawable,GCPtr pGC,int mode,int nPoints,DDXPointPtr pPoints)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
xnestPolylines(DrawablePtr pDrawable,GCPtr pGC,int mode,int nPoints,DDXPointPtr pPoints)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
xnestPolySegment(DrawablePtr pDrawable,GCPtr pGC,int nSegments,xSegment * pSegments)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
xnestPolyRectangle(DrawablePtr pDrawable,GCPtr pGC,int nRectangles,xRectangle * pRectangles)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
xnestPolyArc(DrawablePtr pDrawable,GCPtr pGC,int nArcs,xArc * pArcs)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
xnestFillPolygon(DrawablePtr pDrawable,GCPtr pGC,int shape,int mode,int nPoints,DDXPointPtr pPoints)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
xnestPolyFillRect(DrawablePtr pDrawable,GCPtr pGC,int nRectangles,xRectangle * pRectangles)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
xnestPolyFillArc(DrawablePtr pDrawable,GCPtr pGC,int nArcs,xArc * pArcs)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
xnestPolyText8(DrawablePtr pDrawable,GCPtr pGC,int x,int y,int count,char * string)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
xnestPolyText16(DrawablePtr pDrawable,GCPtr pGC,int x,int y,int count,unsigned short * string)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
xnestImageText8(DrawablePtr pDrawable,GCPtr pGC,int x,int y,int count,char * string)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
xnestImageText16(DrawablePtr pDrawable,GCPtr pGC,int x,int y,int count,unsigned short * string)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
xnestImageGlyphBlt(DrawablePtr pDrawable,GCPtr pGC,int x,int y,unsigned int nGlyphs,CharInfoPtr * pCharInfo,void * pGlyphBase)309 xnestImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
310 unsigned int nGlyphs, CharInfoPtr * pCharInfo,
311 void *pGlyphBase)
312 {
313 ErrorF("xnest warning: function xnestImageGlyphBlt not implemented\n");
314 }
315
316 void
xnestPolyGlyphBlt(DrawablePtr pDrawable,GCPtr pGC,int x,int y,unsigned int nGlyphs,CharInfoPtr * pCharInfo,void * pGlyphBase)317 xnestPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
318 unsigned int nGlyphs, CharInfoPtr * pCharInfo,
319 void *pGlyphBase)
320 {
321 ErrorF("xnest warning: function xnestPolyGlyphBlt not implemented\n");
322 }
323
324 void
xnestPushPixels(GCPtr pGC,PixmapPtr pBitmap,DrawablePtr pDst,int width,int height,int x,int y)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 }
340