GC.c (7344B)
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 "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 38 DevPrivateKeyRec xnestGCPrivateKeyRec; 39 40 static GCFuncs xnestFuncs = { 41 xnestValidateGC, 42 xnestChangeGC, 43 xnestCopyGC, 44 xnestDestroyGC, 45 xnestChangeClip, 46 xnestDestroyClip, 47 xnestCopyClip, 48 }; 49 50 static 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 73 Bool 74 xnestCreateGC(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 88 void 89 xnestValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) 90 { 91 } 92 93 void 94 xnestChangeGC(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 178 void 179 xnestCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst) 180 { 181 XCopyGC(xnestDisplay, xnestGC(pGCSrc), mask, xnestGC(pGCDst)); 182 } 183 184 void 185 xnestDestroyGC(GCPtr pGC) 186 { 187 XFreeGC(xnestDisplay, xnestGC(pGC)); 188 } 189 190 void 191 xnestChangeClip(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 275 void 276 xnestDestroyClip(GCPtr pGC) 277 { 278 if (pGC->clientClip) { 279 RegionDestroy(pGC->clientClip); 280 XSetClipMask(xnestDisplay, xnestGC(pGC), None); 281 pGC->clientClip = NULL; 282 } 283 } 284 285 void 286 xnestCopyClip(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 }