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 97static int 98xnestIgnoreErrorHandler (Display *dpy, 99 XErrorEvent *event) 100{ 101 return False; /* return value is ignored */ 102} 103 104void 105xnestGetImage(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 129static Bool 130xnestBitBlitPredicate(Display * dpy, XEvent * event, char *args) 131{ 132 return event->type == GraphicsExpose || event->type == NoExpose; 133} 134 135static RegionPtr 136xnestBitBlitHelper(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 178RegionPtr 179xnestCopyArea(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 190RegionPtr 191xnestCopyPlane(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 202void 203xnestPolyPoint(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 210void 211xnestPolylines(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 218void 219xnestPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nSegments, 220 xSegment * pSegments) 221{ 222 XDrawSegments(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC), 223 (XSegment *) pSegments, nSegments); 224} 225 226void 227xnestPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nRectangles, 228 xRectangle *pRectangles) 229{ 230 XDrawRectangles(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC), 231 (XRectangle *) pRectangles, nRectangles); 232} 233 234void 235xnestPolyArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc * pArcs) 236{ 237 XDrawArcs(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC), 238 (XArc *) pArcs, nArcs); 239} 240 241void 242xnestFillPolygon(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 249void 250xnestPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nRectangles, 251 xRectangle *pRectangles) 252{ 253 XFillRectangles(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC), 254 (XRectangle *) pRectangles, nRectangles); 255} 256 257void 258xnestPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc * pArcs) 259{ 260 XFillArcs(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC), 261 (XArc *) pArcs, nArcs); 262} 263 264int 265xnestPolyText8(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 278int 279xnestPolyText16(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 292void 293xnestImageText8(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 300void 301xnestImageText16(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 308void 309xnestImageGlyphBlt(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 316void 317xnestPolyGlyphBlt(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 324void 325xnestPushPixels(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