1/*
2
3Copyright 1993 by Davor Matic
4
5Permission to use, copy, modify, distribute, and sell this software
6and its documentation for any purpose is hereby granted without fee,
7provided that the above copyright notice appear in all copies and that
8both that copyright notice and this permission notice appear in
9supporting documentation.  Davor Matic makes no representations about
10the suitability of this software for any purpose.  It is provided "as
11is" 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
40void
41xnestFillSpans(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
47void
48xnestSetSpans(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
54void
55xnestGetSpans(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
61void
62xnestQueryBestSize(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
78void
79xnestPutImage(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
97void
98xnestGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
99	      unsigned int format, unsigned long planeMask,
100	      char *pImage)
101{
102  XImage *ximage;
103  int length;
104
105  ximage = XGetImage(xnestDisplay, xnestDrawable(pDrawable),
106                     x, y, w, h, planeMask, format);
107
108  if (ximage) {
109      length = ximage->bytes_per_line * ximage->height;
110
111      memmove(pImage, ximage->data, length);
112
113      XDestroyImage(ximage);
114  }
115}
116
117static Bool
118xnestBitBlitPredicate(Display *display, XEvent *event, char *args)
119{
120  return event->type == GraphicsExpose || event->type == NoExpose;
121}
122
123static RegionPtr
124xnestBitBlitHelper(GCPtr pGC)
125{
126  if (!pGC->graphicsExposures)
127    return NullRegion;
128  else {
129    XEvent event;
130    RegionPtr pReg, pTmpReg;
131    BoxRec Box;
132    Bool pending, overlap;
133
134    pReg = RegionCreate(NULL, 1);
135    pTmpReg = RegionCreate(NULL, 1);
136    if(!pReg || !pTmpReg) return NullRegion;
137
138    pending = True;
139    while (pending) {
140      XIfEvent(xnestDisplay, &event, xnestBitBlitPredicate, NULL);
141
142      switch (event.type) {
143      case NoExpose:
144	pending = False;
145	break;
146
147      case GraphicsExpose:
148	Box.x1 = event.xgraphicsexpose.x;
149	Box.y1 = event.xgraphicsexpose.y;
150	Box.x2 = event.xgraphicsexpose.x + event.xgraphicsexpose.width;
151	Box.y2 = event.xgraphicsexpose.y + event.xgraphicsexpose.height;
152	RegionReset(pTmpReg, &Box);
153	RegionAppend(pReg, pTmpReg);
154	pending = event.xgraphicsexpose.count;
155	break;
156      }
157    }
158
159    RegionDestroy(pTmpReg);
160    RegionValidate(pReg, &overlap);
161    return pReg;
162  }
163}
164
165RegionPtr
166xnestCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
167	      GCPtr pGC, int srcx, int srcy, int width, int height,
168	      int dstx, int dsty)
169{
170  XCopyArea(xnestDisplay,
171	    xnestDrawable(pSrcDrawable), xnestDrawable(pDstDrawable),
172	    xnestGC(pGC), srcx, srcy, width, height, dstx, dsty);
173
174  return xnestBitBlitHelper(pGC);
175}
176
177RegionPtr
178xnestCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
179	       GCPtr pGC, int srcx, int srcy, int width, int height,
180	       int dstx, int dsty, unsigned long plane)
181{
182  XCopyPlane(xnestDisplay,
183	     xnestDrawable(pSrcDrawable), xnestDrawable(pDstDrawable),
184	     xnestGC(pGC), srcx, srcy, width, height, dstx, dsty, plane);
185
186  return xnestBitBlitHelper(pGC);
187}
188
189void
190xnestPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int nPoints,
191	       DDXPointPtr pPoints)
192{
193  XDrawPoints(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
194              (XPoint *)pPoints, nPoints, mode);
195}
196
197void
198xnestPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int nPoints,
199	       DDXPointPtr pPoints)
200{
201  XDrawLines(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
202              (XPoint *)pPoints, nPoints, mode);
203}
204
205void
206xnestPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nSegments,
207		 xSegment *pSegments)
208{
209  XDrawSegments(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
210                (XSegment *)pSegments, nSegments);
211}
212
213void
214xnestPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nRectangles,
215		   xRectangle *pRectangles)
216{
217  XDrawRectangles(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
218                  (XRectangle *)pRectangles, nRectangles);
219}
220
221void
222xnestPolyArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc *pArcs)
223{
224  XDrawArcs(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
225            (XArc *)pArcs, nArcs);
226}
227
228void
229xnestFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape, int mode,
230		 int nPoints, DDXPointPtr pPoints)
231{
232  XFillPolygon(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
233               (XPoint *)pPoints, nPoints, shape, mode);
234}
235
236void
237xnestPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nRectangles,
238		  xRectangle *pRectangles)
239{
240  XFillRectangles(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
241                  (XRectangle *)pRectangles, nRectangles);
242}
243
244void
245xnestPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc *pArcs)
246{
247  XFillArcs(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
248            (XArc *)pArcs, nArcs);
249}
250
251int
252xnestPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
253	       char *string)
254{
255  int width;
256
257  XDrawString(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
258              x, y, string, count);
259
260  width = XTextWidth(xnestFontStruct(pGC->font), string, count);
261
262  return width + x;
263}
264
265int
266xnestPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
267		unsigned short *string)
268{
269  int width;
270
271  XDrawString16(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
272                x, y, (XChar2b *)string, count);
273
274  width = XTextWidth16(xnestFontStruct(pGC->font), (XChar2b *)string, count);
275
276  return width + x;
277}
278
279void
280xnestImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
281		char *string)
282{
283  XDrawImageString(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
284                   x, y, string, count);
285}
286
287void
288xnestImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
289		 unsigned short *string)
290{
291  XDrawImageString16(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
292                     x, y, (XChar2b *)string, count);
293}
294
295void
296xnestImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
297		   unsigned int nGlyphs, CharInfoPtr *pCharInfo,
298		   pointer pGlyphBase)
299{
300  ErrorF("xnest warning: function xnestImageGlyphBlt not implemented\n");
301}
302
303void
304xnestPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
305		  unsigned int nGlyphs, CharInfoPtr *pCharInfo,
306		  pointer pGlyphBase)
307{
308  ErrorF("xnest warning: function xnestPolyGlyphBlt not implemented\n");
309}
310
311void
312xnestPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDst,
313		int width, int height, int x, int y)
314{
315  /* only works for solid bitmaps */
316  if (pGC->fillStyle == FillSolid)
317  {
318    XSetStipple (xnestDisplay, xnestGC(pGC), xnestPixmap(pBitmap));
319    XSetTSOrigin (xnestDisplay, xnestGC(pGC), x, y);
320    XSetFillStyle (xnestDisplay, xnestGC(pGC), FillStippled);
321    XFillRectangle (xnestDisplay, xnestDrawable(pDst),
322		    xnestGC(pGC), x, y, width, height);
323    XSetFillStyle (xnestDisplay, xnestGC(pGC), FillSolid);
324  }
325  else
326    ErrorF("xnest warning: function xnestPushPixels not implemented\n");
327}
328