GC.c revision 35c4bbdf
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 "gcstruct.h" 22#include "windowstr.h" 23#include "pixmapstr.h" 24#include "scrnintstr.h" 25#include <X11/fonts/fontstruct.h> 26#include "mistruct.h" 27#include "region.h" 28 29#include "Xnest.h" 30 31#include "Display.h" 32#include "XNGC.h" 33#include "GCOps.h" 34#include "Drawable.h" 35#include "XNFont.h" 36#include "Color.h" 37 38DevPrivateKeyRec xnestGCPrivateKeyRec; 39 40static GCFuncs xnestFuncs = { 41 xnestValidateGC, 42 xnestChangeGC, 43 xnestCopyGC, 44 xnestDestroyGC, 45 xnestChangeClip, 46 xnestDestroyClip, 47 xnestCopyClip, 48}; 49 50static GCOps xnestOps = { 51 xnestFillSpans, 52 xnestSetSpans, 53 xnestPutImage, 54 xnestCopyArea, 55 xnestCopyPlane, 56 xnestPolyPoint, 57 xnestPolylines, 58 xnestPolySegment, 59 xnestPolyRectangle, 60 xnestPolyArc, 61 xnestFillPolygon, 62 xnestPolyFillRect, 63 xnestPolyFillArc, 64 xnestPolyText8, 65 xnestPolyText16, 66 xnestImageText8, 67 xnestImageText16, 68 xnestImageGlyphBlt, 69 xnestPolyGlyphBlt, 70 xnestPushPixels 71}; 72 73Bool 74xnestCreateGC(GCPtr pGC) 75{ 76 pGC->funcs = &xnestFuncs; 77 pGC->ops = &xnestOps; 78 79 pGC->miTranslate = 1; 80 81 xnestGCPriv(pGC)->gc = XCreateGC(xnestDisplay, 82 xnestDefaultDrawables[pGC->depth], 83 0L, NULL); 84 85 return True; 86} 87 88void 89xnestValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) 90{ 91} 92 93void 94xnestChangeGC(GCPtr pGC, unsigned long mask) 95{ 96 XGCValues values; 97 98 if (mask & GCFunction) 99 values.function = pGC->alu; 100 101 if (mask & GCPlaneMask) 102 values.plane_mask = pGC->planemask; 103 104 if (mask & GCForeground) 105 values.foreground = xnestPixel(pGC->fgPixel); 106 107 if (mask & GCBackground) 108 values.background = xnestPixel(pGC->bgPixel); 109 110 if (mask & GCLineWidth) 111 values.line_width = pGC->lineWidth; 112 113 if (mask & GCLineStyle) 114 values.line_style = pGC->lineStyle; 115 116 if (mask & GCCapStyle) 117 values.cap_style = pGC->capStyle; 118 119 if (mask & GCJoinStyle) 120 values.join_style = pGC->joinStyle; 121 122 if (mask & GCFillStyle) 123 values.fill_style = pGC->fillStyle; 124 125 if (mask & GCFillRule) 126 values.fill_rule = pGC->fillRule; 127 128 if (mask & GCTile) { 129 if (pGC->tileIsPixel) 130 mask &= ~GCTile; 131 else 132 values.tile = xnestPixmap(pGC->tile.pixmap); 133 } 134 135 if (mask & GCStipple) 136 values.stipple = xnestPixmap(pGC->stipple); 137 138 if (mask & GCTileStipXOrigin) 139 values.ts_x_origin = pGC->patOrg.x; 140 141 if (mask & GCTileStipYOrigin) 142 values.ts_y_origin = pGC->patOrg.y; 143 144 if (mask & GCFont) 145 values.font = xnestFont(pGC->font); 146 147 if (mask & GCSubwindowMode) 148 values.subwindow_mode = pGC->subWindowMode; 149 150 if (mask & GCGraphicsExposures) 151 values.graphics_exposures = pGC->graphicsExposures; 152 153 if (mask & GCClipXOrigin) 154 values.clip_x_origin = pGC->clipOrg.x; 155 156 if (mask & GCClipYOrigin) 157 values.clip_y_origin = pGC->clipOrg.y; 158 159 if (mask & GCClipMask) /* this is handled in change clip */ 160 mask &= ~GCClipMask; 161 162 if (mask & GCDashOffset) 163 values.dash_offset = pGC->dashOffset; 164 165 if (mask & GCDashList) { 166 mask &= ~GCDashList; 167 XSetDashes(xnestDisplay, xnestGC(pGC), 168 pGC->dashOffset, (char *) pGC->dash, pGC->numInDashList); 169 } 170 171 if (mask & GCArcMode) 172 values.arc_mode = pGC->arcMode; 173 174 if (mask) 175 XChangeGC(xnestDisplay, xnestGC(pGC), mask, &values); 176} 177 178void 179xnestCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst) 180{ 181 XCopyGC(xnestDisplay, xnestGC(pGCSrc), mask, xnestGC(pGCDst)); 182} 183 184void 185xnestDestroyGC(GCPtr pGC) 186{ 187 XFreeGC(xnestDisplay, xnestGC(pGC)); 188} 189 190void 191xnestChangeClip(GCPtr pGC, int type, void *pValue, int nRects) 192{ 193 int i; 194 BoxPtr pBox; 195 XRectangle *pRects; 196 197 xnestDestroyClip(pGC); 198 199 switch (type) { 200 case CT_NONE: 201 XSetClipMask(xnestDisplay, xnestGC(pGC), None); 202 pValue = NULL; 203 break; 204 205 case CT_REGION: 206 nRects = RegionNumRects((RegionPtr) pValue); 207 pRects = xallocarray(nRects, sizeof(*pRects)); 208 pBox = RegionRects((RegionPtr) pValue); 209 for (i = nRects; i-- > 0;) { 210 pRects[i].x = pBox[i].x1; 211 pRects[i].y = pBox[i].y1; 212 pRects[i].width = pBox[i].x2 - pBox[i].x1; 213 pRects[i].height = pBox[i].y2 - pBox[i].y1; 214 } 215 XSetClipRectangles(xnestDisplay, xnestGC(pGC), 0, 0, 216 pRects, nRects, Unsorted); 217 free((char *) pRects); 218 break; 219 220 case CT_PIXMAP: 221 XSetClipMask(xnestDisplay, xnestGC(pGC), 222 xnestPixmap((PixmapPtr) pValue)); 223 /* 224 * Need to change into region, so subsequent uses are with 225 * current pixmap contents. 226 */ 227 pGC->clientClip = (*pGC->pScreen->BitmapToRegion) ((PixmapPtr) pValue); 228 (*pGC->pScreen->DestroyPixmap) ((PixmapPtr) pValue); 229 pValue = pGC->clientClip; 230 break; 231 232 case CT_UNSORTED: 233 XSetClipRectangles(xnestDisplay, xnestGC(pGC), 234 pGC->clipOrg.x, pGC->clipOrg.y, 235 (XRectangle *) pValue, nRects, Unsorted); 236 break; 237 238 case CT_YSORTED: 239 XSetClipRectangles(xnestDisplay, xnestGC(pGC), 240 pGC->clipOrg.x, pGC->clipOrg.y, 241 (XRectangle *) pValue, nRects, YSorted); 242 break; 243 244 case CT_YXSORTED: 245 XSetClipRectangles(xnestDisplay, xnestGC(pGC), 246 pGC->clipOrg.x, pGC->clipOrg.y, 247 (XRectangle *) pValue, nRects, YXSorted); 248 break; 249 250 case CT_YXBANDED: 251 XSetClipRectangles(xnestDisplay, xnestGC(pGC), 252 pGC->clipOrg.x, pGC->clipOrg.y, 253 (XRectangle *) pValue, nRects, YXBanded); 254 break; 255 } 256 257 switch (type) { 258 default: 259 break; 260 261 case CT_UNSORTED: 262 case CT_YSORTED: 263 case CT_YXSORTED: 264 case CT_YXBANDED: 265 /* server clip representation is a region */ 266 pGC->clientClip = RegionFromRects(nRects, (xRectangle *) pValue, type); 267 free(pValue); 268 pValue = pGC->clientClip; 269 break; 270 } 271 272 pGC->clientClip = pValue; 273} 274 275void 276xnestDestroyClip(GCPtr pGC) 277{ 278 if (pGC->clientClip) { 279 RegionDestroy(pGC->clientClip); 280 XSetClipMask(xnestDisplay, xnestGC(pGC), None); 281 pGC->clientClip = NULL; 282 } 283} 284 285void 286xnestCopyClip(GCPtr pGCDst, GCPtr pGCSrc) 287{ 288 if (pGCSrc->clientClip) { 289 RegionPtr pRgn = RegionCreate(NULL, 1); 290 RegionCopy(pRgn, pGCSrc->clientClip); 291 xnestChangeClip(pGCDst, CT_REGION, pRgn, 0); 292 } else { 293 xnestDestroyClip(pGCDst); 294 } 295} 296