GC.c revision 706f2543
1706f2543Smrg/* 2706f2543Smrg 3706f2543SmrgCopyright 1993 by Davor Matic 4706f2543Smrg 5706f2543SmrgPermission to use, copy, modify, distribute, and sell this software 6706f2543Smrgand its documentation for any purpose is hereby granted without fee, 7706f2543Smrgprovided that the above copyright notice appear in all copies and that 8706f2543Smrgboth that copyright notice and this permission notice appear in 9706f2543Smrgsupporting documentation. Davor Matic makes no representations about 10706f2543Smrgthe suitability of this software for any purpose. It is provided "as 11706f2543Smrgis" without express or implied warranty. 12706f2543Smrg 13706f2543Smrg*/ 14706f2543Smrg 15706f2543Smrg#ifdef HAVE_XNEST_CONFIG_H 16706f2543Smrg#include <xnest-config.h> 17706f2543Smrg#endif 18706f2543Smrg 19706f2543Smrg#include <X11/X.h> 20706f2543Smrg#include <X11/Xproto.h> 21706f2543Smrg#include "gcstruct.h" 22706f2543Smrg#include "windowstr.h" 23706f2543Smrg#include "pixmapstr.h" 24706f2543Smrg#include "scrnintstr.h" 25706f2543Smrg#include <X11/fonts/fontstruct.h> 26706f2543Smrg#include "mistruct.h" 27706f2543Smrg#include "region.h" 28706f2543Smrg 29706f2543Smrg#include "Xnest.h" 30706f2543Smrg 31706f2543Smrg#include "Display.h" 32706f2543Smrg#include "XNGC.h" 33706f2543Smrg#include "GCOps.h" 34706f2543Smrg#include "Drawable.h" 35706f2543Smrg#include "XNFont.h" 36706f2543Smrg#include "Color.h" 37706f2543Smrg 38706f2543SmrgDevPrivateKeyRec xnestGCPrivateKeyRec; 39706f2543Smrg 40706f2543Smrgstatic GCFuncs xnestFuncs = { 41706f2543Smrg xnestValidateGC, 42706f2543Smrg xnestChangeGC, 43706f2543Smrg xnestCopyGC, 44706f2543Smrg xnestDestroyGC, 45706f2543Smrg xnestChangeClip, 46706f2543Smrg xnestDestroyClip, 47706f2543Smrg xnestCopyClip, 48706f2543Smrg}; 49706f2543Smrg 50706f2543Smrgstatic GCOps xnestOps = { 51706f2543Smrg xnestFillSpans, 52706f2543Smrg xnestSetSpans, 53706f2543Smrg xnestPutImage, 54706f2543Smrg xnestCopyArea, 55706f2543Smrg xnestCopyPlane, 56706f2543Smrg xnestPolyPoint, 57706f2543Smrg xnestPolylines, 58706f2543Smrg xnestPolySegment, 59706f2543Smrg xnestPolyRectangle, 60706f2543Smrg xnestPolyArc, 61706f2543Smrg xnestFillPolygon, 62706f2543Smrg xnestPolyFillRect, 63706f2543Smrg xnestPolyFillArc, 64706f2543Smrg xnestPolyText8, 65706f2543Smrg xnestPolyText16, 66706f2543Smrg xnestImageText8, 67706f2543Smrg xnestImageText16, 68706f2543Smrg xnestImageGlyphBlt, 69706f2543Smrg xnestPolyGlyphBlt, 70706f2543Smrg xnestPushPixels 71706f2543Smrg}; 72706f2543Smrg 73706f2543SmrgBool 74706f2543SmrgxnestCreateGC(GCPtr pGC) 75706f2543Smrg{ 76706f2543Smrg pGC->funcs = &xnestFuncs; 77706f2543Smrg pGC->ops = &xnestOps; 78706f2543Smrg 79706f2543Smrg pGC->miTranslate = 1; 80706f2543Smrg 81706f2543Smrg xnestGCPriv(pGC)->gc = XCreateGC(xnestDisplay, 82706f2543Smrg xnestDefaultDrawables[pGC->depth], 83706f2543Smrg 0L, NULL); 84706f2543Smrg xnestGCPriv(pGC)->nClipRects = 0; 85706f2543Smrg 86706f2543Smrg return True; 87706f2543Smrg} 88706f2543Smrg 89706f2543Smrgvoid 90706f2543SmrgxnestValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) 91706f2543Smrg{ 92706f2543Smrg} 93706f2543Smrg 94706f2543Smrgvoid 95706f2543SmrgxnestChangeGC(GCPtr pGC, unsigned long mask) 96706f2543Smrg{ 97706f2543Smrg XGCValues values; 98706f2543Smrg 99706f2543Smrg if (mask & GCFunction) 100706f2543Smrg values.function = pGC->alu; 101706f2543Smrg 102706f2543Smrg if (mask & GCPlaneMask) 103706f2543Smrg values.plane_mask = pGC->planemask; 104706f2543Smrg 105706f2543Smrg if (mask & GCForeground) 106706f2543Smrg values.foreground = xnestPixel(pGC->fgPixel); 107706f2543Smrg 108706f2543Smrg if (mask & GCBackground) 109706f2543Smrg values.background = xnestPixel(pGC->bgPixel); 110706f2543Smrg 111706f2543Smrg if (mask & GCLineWidth) 112706f2543Smrg values.line_width = pGC->lineWidth; 113706f2543Smrg 114706f2543Smrg if (mask & GCLineStyle) 115706f2543Smrg values.line_style = pGC->lineStyle; 116706f2543Smrg 117706f2543Smrg if (mask & GCCapStyle) 118706f2543Smrg values.cap_style = pGC->capStyle; 119706f2543Smrg 120706f2543Smrg if (mask & GCJoinStyle) 121706f2543Smrg values.join_style = pGC->joinStyle; 122706f2543Smrg 123706f2543Smrg if (mask & GCFillStyle) 124706f2543Smrg values.fill_style = pGC->fillStyle; 125706f2543Smrg 126706f2543Smrg if (mask & GCFillRule) 127706f2543Smrg values.fill_rule = pGC->fillRule; 128706f2543Smrg 129706f2543Smrg if (mask & GCTile) { 130706f2543Smrg if (pGC->tileIsPixel) 131706f2543Smrg mask &= ~GCTile; 132706f2543Smrg else 133706f2543Smrg values.tile = xnestPixmap(pGC->tile.pixmap); 134706f2543Smrg } 135706f2543Smrg 136706f2543Smrg if (mask & GCStipple) 137706f2543Smrg values.stipple = xnestPixmap(pGC->stipple); 138706f2543Smrg 139706f2543Smrg if (mask & GCTileStipXOrigin) 140706f2543Smrg values.ts_x_origin = pGC->patOrg.x; 141706f2543Smrg 142706f2543Smrg if (mask & GCTileStipYOrigin) 143706f2543Smrg values.ts_y_origin = pGC->patOrg.y; 144706f2543Smrg 145706f2543Smrg if (mask & GCFont) 146706f2543Smrg values.font = xnestFont(pGC->font); 147706f2543Smrg 148706f2543Smrg if (mask & GCSubwindowMode) 149706f2543Smrg values.subwindow_mode = pGC->subWindowMode; 150706f2543Smrg 151706f2543Smrg if (mask & GCGraphicsExposures) 152706f2543Smrg values.graphics_exposures = pGC->graphicsExposures; 153706f2543Smrg 154706f2543Smrg if (mask & GCClipXOrigin) 155706f2543Smrg values.clip_x_origin = pGC->clipOrg.x; 156706f2543Smrg 157706f2543Smrg if (mask & GCClipYOrigin) 158706f2543Smrg values.clip_y_origin = pGC->clipOrg.y; 159706f2543Smrg 160706f2543Smrg if (mask & GCClipMask) /* this is handled in change clip */ 161706f2543Smrg mask &= ~GCClipMask; 162706f2543Smrg 163706f2543Smrg if (mask & GCDashOffset) 164706f2543Smrg values.dash_offset = pGC->dashOffset; 165706f2543Smrg 166706f2543Smrg if (mask & GCDashList) { 167706f2543Smrg mask &= ~GCDashList; 168706f2543Smrg XSetDashes(xnestDisplay, xnestGC(pGC), 169706f2543Smrg pGC->dashOffset, (char *)pGC->dash, pGC->numInDashList); 170706f2543Smrg } 171706f2543Smrg 172706f2543Smrg if (mask & GCArcMode) 173706f2543Smrg values.arc_mode = pGC->arcMode; 174706f2543Smrg 175706f2543Smrg if (mask) 176706f2543Smrg XChangeGC(xnestDisplay, xnestGC(pGC), mask, &values); 177706f2543Smrg} 178706f2543Smrg 179706f2543Smrgvoid 180706f2543SmrgxnestCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst) 181706f2543Smrg{ 182706f2543Smrg XCopyGC(xnestDisplay, xnestGC(pGCSrc), mask, xnestGC(pGCDst)); 183706f2543Smrg} 184706f2543Smrg 185706f2543Smrgvoid 186706f2543SmrgxnestDestroyGC(GCPtr pGC) 187706f2543Smrg{ 188706f2543Smrg XFreeGC(xnestDisplay, xnestGC(pGC)); 189706f2543Smrg} 190706f2543Smrg 191706f2543Smrgvoid 192706f2543SmrgxnestChangeClip(GCPtr pGC, int type, pointer pValue, int nRects) 193706f2543Smrg{ 194706f2543Smrg int i, size; 195706f2543Smrg BoxPtr pBox; 196706f2543Smrg XRectangle *pRects; 197706f2543Smrg 198706f2543Smrg xnestDestroyClipHelper(pGC); 199706f2543Smrg 200706f2543Smrg switch(type) 201706f2543Smrg { 202706f2543Smrg case CT_NONE: 203706f2543Smrg XSetClipMask(xnestDisplay, xnestGC(pGC), None); 204706f2543Smrg break; 205706f2543Smrg 206706f2543Smrg case CT_REGION: 207706f2543Smrg nRects = RegionNumRects((RegionPtr)pValue); 208706f2543Smrg size = nRects * sizeof(*pRects); 209706f2543Smrg pRects = (XRectangle *) malloc(size); 210706f2543Smrg pBox = RegionRects((RegionPtr)pValue); 211706f2543Smrg for (i = nRects; i-- > 0; ) { 212706f2543Smrg pRects[i].x = pBox[i].x1; 213706f2543Smrg pRects[i].y = pBox[i].y1; 214706f2543Smrg pRects[i].width = pBox[i].x2 - pBox[i].x1; 215706f2543Smrg pRects[i].height = pBox[i].y2 - pBox[i].y1; 216706f2543Smrg } 217706f2543Smrg XSetClipRectangles(xnestDisplay, xnestGC(pGC), 0, 0, 218706f2543Smrg pRects, nRects, Unsorted); 219706f2543Smrg free((char *) pRects); 220706f2543Smrg break; 221706f2543Smrg 222706f2543Smrg case CT_PIXMAP: 223706f2543Smrg XSetClipMask(xnestDisplay, xnestGC(pGC), 224706f2543Smrg xnestPixmap((PixmapPtr)pValue)); 225706f2543Smrg /* 226706f2543Smrg * Need to change into region, so subsequent uses are with 227706f2543Smrg * current pixmap contents. 228706f2543Smrg */ 229706f2543Smrg pGC->clientClip = (pointer) (*pGC->pScreen->BitmapToRegion)((PixmapPtr)pValue); 230706f2543Smrg (*pGC->pScreen->DestroyPixmap)((PixmapPtr)pValue); 231706f2543Smrg pValue = pGC->clientClip; 232706f2543Smrg type = CT_REGION; 233706f2543Smrg break; 234706f2543Smrg 235706f2543Smrg case CT_UNSORTED: 236706f2543Smrg XSetClipRectangles(xnestDisplay, xnestGC(pGC), 237706f2543Smrg pGC->clipOrg.x, pGC->clipOrg.y, 238706f2543Smrg (XRectangle *)pValue, nRects, Unsorted); 239706f2543Smrg break; 240706f2543Smrg 241706f2543Smrg case CT_YSORTED: 242706f2543Smrg XSetClipRectangles(xnestDisplay, xnestGC(pGC), 243706f2543Smrg pGC->clipOrg.x, pGC->clipOrg.y, 244706f2543Smrg (XRectangle *)pValue, nRects, YSorted); 245706f2543Smrg break; 246706f2543Smrg 247706f2543Smrg case CT_YXSORTED: 248706f2543Smrg XSetClipRectangles(xnestDisplay, xnestGC(pGC), 249706f2543Smrg pGC->clipOrg.x, pGC->clipOrg.y, 250706f2543Smrg (XRectangle *)pValue, nRects, YXSorted); 251706f2543Smrg break; 252706f2543Smrg 253706f2543Smrg case CT_YXBANDED: 254706f2543Smrg XSetClipRectangles(xnestDisplay, xnestGC(pGC), 255706f2543Smrg pGC->clipOrg.x, pGC->clipOrg.y, 256706f2543Smrg (XRectangle *)pValue, nRects, YXBanded); 257706f2543Smrg break; 258706f2543Smrg } 259706f2543Smrg 260706f2543Smrg switch(type) 261706f2543Smrg { 262706f2543Smrg default: 263706f2543Smrg break; 264706f2543Smrg 265706f2543Smrg case CT_UNSORTED: 266706f2543Smrg case CT_YSORTED: 267706f2543Smrg case CT_YXSORTED: 268706f2543Smrg case CT_YXBANDED: 269706f2543Smrg 270706f2543Smrg /* 271706f2543Smrg * other parts of server can only deal with CT_NONE, 272706f2543Smrg * CT_PIXMAP and CT_REGION client clips. 273706f2543Smrg */ 274706f2543Smrg pGC->clientClip = (pointer) RegionFromRects(nRects, 275706f2543Smrg (xRectangle *)pValue, type); 276706f2543Smrg free(pValue); 277706f2543Smrg pValue = pGC->clientClip; 278706f2543Smrg type = CT_REGION; 279706f2543Smrg 280706f2543Smrg break; 281706f2543Smrg } 282706f2543Smrg 283706f2543Smrg pGC->clientClipType = type; 284706f2543Smrg pGC->clientClip = pValue; 285706f2543Smrg xnestGCPriv(pGC)->nClipRects = nRects; 286706f2543Smrg} 287706f2543Smrg 288706f2543Smrgvoid 289706f2543SmrgxnestDestroyClip(GCPtr pGC) 290706f2543Smrg{ 291706f2543Smrg xnestDestroyClipHelper(pGC); 292706f2543Smrg 293706f2543Smrg XSetClipMask(xnestDisplay, xnestGC(pGC), None); 294706f2543Smrg 295706f2543Smrg pGC->clientClipType = CT_NONE; 296706f2543Smrg pGC->clientClip = NULL; 297706f2543Smrg xnestGCPriv(pGC)->nClipRects = 0; 298706f2543Smrg} 299706f2543Smrg 300706f2543Smrgvoid 301706f2543SmrgxnestDestroyClipHelper(GCPtr pGC) 302706f2543Smrg{ 303706f2543Smrg switch (pGC->clientClipType) 304706f2543Smrg { 305706f2543Smrg default: 306706f2543Smrg case CT_NONE: 307706f2543Smrg break; 308706f2543Smrg 309706f2543Smrg case CT_REGION: 310706f2543Smrg RegionDestroy(pGC->clientClip); 311706f2543Smrg break; 312706f2543Smrg } 313706f2543Smrg} 314706f2543Smrg 315706f2543Smrgvoid 316706f2543SmrgxnestCopyClip(GCPtr pGCDst, GCPtr pGCSrc) 317706f2543Smrg{ 318706f2543Smrg RegionPtr pRgn; 319706f2543Smrg 320706f2543Smrg switch (pGCSrc->clientClipType) 321706f2543Smrg { 322706f2543Smrg default: 323706f2543Smrg case CT_NONE: 324706f2543Smrg xnestDestroyClip(pGCDst); 325706f2543Smrg break; 326706f2543Smrg 327706f2543Smrg case CT_REGION: 328706f2543Smrg pRgn = RegionCreate(NULL, 1); 329706f2543Smrg RegionCopy(pRgn, pGCSrc->clientClip); 330706f2543Smrg xnestChangeClip(pGCDst, CT_REGION, pRgn, 0); 331706f2543Smrg break; 332706f2543Smrg } 333706f2543Smrg} 334