|
|
1.1 ! root 1: /*********************************************************** ! 2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, ! 3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts. ! 4: ! 5: All Rights Reserved ! 6: ! 7: Permission to use, copy, modify, and distribute this software and its ! 8: documentation for any purpose and without fee is hereby granted, ! 9: provided that the above copyright notice appear in all copies and that ! 10: both that copyright notice and this permission notice appear in ! 11: supporting documentation, and that the names of Digital or MIT not be ! 12: used in advertising or publicity pertaining to distribution of the ! 13: software without specific, written prior permission. ! 14: ! 15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 21: SOFTWARE. ! 22: ! 23: ******************************************************************/ ! 24: ! 25: /* $Header: gc.c,v 1.95 87/09/03 15:52:13 toddb Exp $ */ ! 26: ! 27: #include "X.h" ! 28: #include "Xmd.h" ! 29: #include "Xproto.h" ! 30: #include "misc.h" ! 31: #include "resource.h" ! 32: #include "gcstruct.h" ! 33: #include "pixmapstr.h" ! 34: #include "dixfontstr.h" ! 35: #include "scrnintstr.h" ! 36: #include "region.h" ! 37: ! 38: #include "dix.h" ! 39: ! 40: extern int NotImplemented(); ! 41: ! 42: /* written by drewry august 1986 */ ! 43: ! 44: void ! 45: ValidateGC(pDraw, pGC) ! 46: DrawablePtr pDraw; ! 47: GC *pGC; ! 48: { ! 49: GCInterestPtr pQ, pQInit; ! 50: ! 51: pQ = pGC->pNextGCInterest; ! 52: pQInit = (GCInterestPtr) &pGC->pNextGCInterest; ! 53: if (pGC->serialNumber != pDraw->serialNumber) ! 54: pGC->stateChanges |= GC_CALL_VALIDATE_BIT; ! 55: do ! 56: { ! 57: if (pQ->ValInterestMask & pGC->stateChanges) ! 58: (* pQ->ValidateGC) (pGC, pQ, pGC->stateChanges, pDraw); ! 59: pQ = pQ->pNextGCInterest; ! 60: } ! 61: while(pQ != pQInit); ! 62: pGC->stateChanges = 0; ! 63: pGC->serialNumber = pDraw->serialNumber; ! 64: } ! 65: ! 66: ! 67: ! 68: /* Publically defined entry to ChangeGC. Just calls DoChangeGC and tells ! 69: * it that all of the entries are constants or IDs */ ! 70: ChangeGC(pGC, mask, pval) ! 71: register GC *pGC; ! 72: register BITS32 mask; ! 73: CARD32 *pval; ! 74: { ! 75: return (DoChangeGC(pGC, mask, pval, 0)); ! 76: } ! 77: /* DoChangeGC(pGC, mask, pval, fPointer) ! 78: mask is a set of bits indicating which values to change. ! 79: pval contains an appropriate value for each mask. ! 80: fPointer is true if the values for tiles, stipples, fonts or clipmasks ! 81: are pointers instead of IDs. ! 82: if there is an error, the value is marked as changed ! 83: anyway, which is probably wrong, but infrequent. ! 84: ! 85: NOTE: ! 86: all values sent over the protocol for ChangeGC requests are ! 87: 32 bits long ! 88: */ ! 89: ! 90: int ! 91: DoChangeGC(pGC, mask, pval, fPointer) ! 92: register GC *pGC; ! 93: register BITS32 mask; ! 94: CARD32 *pval; ! 95: int fPointer; ! 96: { ! 97: register int index; ! 98: register int error = 0; ! 99: PixmapPtr pPixmap; ! 100: BITS32 maskQ; ! 101: GCInterestPtr pQ, pQInit; ! 102: ! 103: pGC->serialNumber |= GC_CHANGE_SERIAL_BIT; ! 104: ! 105: maskQ = mask; /* save these for when we walk the GCque */ ! 106: while (mask && !error) ! 107: { ! 108: index = ffs(mask) - 1; ! 109: mask &= ~(index = (1 << index)); ! 110: pGC->stateChanges |= index; ! 111: switch (index) ! 112: { ! 113: case GCFunction: ! 114: if (((CARD8)*pval >= GXclear) && ((CARD8)*pval <= GXset)) ! 115: pGC->alu = (CARD8)*pval; ! 116: else ! 117: error = BadValue; ! 118: pval++; ! 119: break; ! 120: case GCPlaneMask: ! 121: pGC->planemask = *pval++; ! 122: break; ! 123: case GCForeground: ! 124: pGC->fgPixel = *pval++; ! 125: break; ! 126: case GCBackground: ! 127: pGC->bgPixel = *pval++; ! 128: break; ! 129: case GCLineWidth: /* ??? line width is a CARD16 */ ! 130: pGC->lineWidth = (CARD16)*pval; ! 131: pval++; ! 132: break; ! 133: case GCLineStyle: ! 134: if (((CARD8)*pval >= LineSolid) ! 135: && ((CARD8)*pval <= LineDoubleDash)) ! 136: pGC->lineStyle = (CARD8)*pval; ! 137: else ! 138: error = BadValue; ! 139: pval++; ! 140: break; ! 141: case GCCapStyle: ! 142: if (((CARD8)*pval >= CapNotLast) ! 143: && ((CARD8)*pval <= CapProjecting)) ! 144: pGC->capStyle = (CARD8)*pval; ! 145: else ! 146: error = BadValue; ! 147: pval++; ! 148: break; ! 149: case GCJoinStyle: ! 150: if (((CARD8)*pval >= JoinMiter) && ((CARD8)*pval <= JoinBevel)) ! 151: pGC->joinStyle = (CARD8)*pval; ! 152: else ! 153: error = BadValue; ! 154: pval++; ! 155: break; ! 156: case GCFillStyle: ! 157: if (((CARD8)*pval >= FillSolid) ! 158: && ((CARD8)*pval <= FillOpaqueStippled)) ! 159: pGC->fillStyle = (CARD8)*pval; ! 160: else ! 161: error = BadValue; ! 162: pval++; ! 163: break; ! 164: case GCFillRule: ! 165: if (((CARD8)*pval >= EvenOddRule) && ! 166: ((CARD8)*pval <= WindingRule)) ! 167: pGC->fillRule = (CARD8)*pval; ! 168: else ! 169: error = BadValue; ! 170: pval++; ! 171: break; ! 172: case GCTile: ! 173: if(fPointer) ! 174: pPixmap = (PixmapPtr) *pval; ! 175: else ! 176: pPixmap = (PixmapPtr)LookupID((CARD32)*pval, ! 177: RT_PIXMAP, RC_CORE); ! 178: pval++; ! 179: if (pPixmap) ! 180: { ! 181: if ((pPixmap->drawable.depth != pGC->depth) || ! 182: (pPixmap->drawable.pScreen != pGC->pScreen)) ! 183: { ! 184: error = BadMatch; ! 185: } ! 186: else ! 187: { ! 188: (* pGC->pScreen->DestroyPixmap)(pGC->tile); ! 189: pGC->tile = pPixmap; ! 190: pPixmap->refcnt++; ! 191: } ! 192: } ! 193: else ! 194: error = BadPixmap; ! 195: break; ! 196: case GCStipple: ! 197: if(fPointer) ! 198: pPixmap = (PixmapPtr) *pval; ! 199: else ! 200: pPixmap = (PixmapPtr)LookupID((CARD32)*pval, ! 201: RT_PIXMAP, RC_CORE); ! 202: pval++; ! 203: if (pPixmap) ! 204: { ! 205: if ((pPixmap->drawable.depth != 1) || ! 206: (pPixmap->drawable.pScreen != pGC->pScreen)) ! 207: { ! 208: error = BadMatch; ! 209: } ! 210: else ! 211: { ! 212: (* pGC->pScreen->DestroyPixmap)(pGC->stipple); ! 213: pGC->stipple = pPixmap; ! 214: pPixmap->refcnt++; ! 215: } ! 216: } ! 217: else ! 218: error = BadPixmap; ! 219: break; ! 220: case GCTileStipXOrigin: ! 221: pGC->patOrg.x = (INT16)*pval; ! 222: pval++; ! 223: break; ! 224: case GCTileStipYOrigin: ! 225: pGC->patOrg.y = (INT16)*pval; ! 226: pval++; ! 227: break; ! 228: case GCFont: ! 229: { ! 230: CARD32 fid; ! 231: FontPtr pFont; ! 232: ! 233: ! 234: if(fPointer) ! 235: pFont = (FontPtr) *pval++; ! 236: else ! 237: { ! 238: fid = * pval++; ! 239: pFont = (FontPtr)LookupID(fid, RT_FONT, RC_CORE); ! 240: } ! 241: ! 242: if (pFont) ! 243: { ! 244: if (pGC->font) ! 245: CloseFont( pGC->font); ! 246: pGC->font = pFont; ! 247: pGC->font->refcnt++; ! 248: } ! 249: else ! 250: error = BadFont; ! 251: break; ! 252: } ! 253: case GCSubwindowMode: ! 254: if ((*pval == ClipByChildren) || ! 255: (*pval == IncludeInferiors)) ! 256: pGC->subWindowMode = (CARD8)(*pval); ! 257: else ! 258: error = BadValue; ! 259: pval++; ! 260: break; ! 261: case GCGraphicsExposures: ! 262: if ((Bool)*pval == xFalse) ! 263: pGC->graphicsExposures = FALSE; ! 264: else if ((Bool)*pval == xTrue) ! 265: pGC->graphicsExposures = TRUE; ! 266: else ! 267: error = BadValue; ! 268: pval++; ! 269: break; ! 270: case GCClipXOrigin: ! 271: pGC->clipOrg.x = (INT16)(*pval); ! 272: pval++; ! 273: break; ! 274: case GCClipYOrigin: ! 275: pGC->clipOrg.y = (INT16)(*pval); ! 276: pval++; ! 277: break; ! 278: case GCClipMask: ! 279: { ! 280: Pixmap pid; ! 281: int clipType; ! 282: ! 283: pid = (Pixmap) *pval; ! 284: if (pid == None) ! 285: { ! 286: clipType = CT_NONE; ! 287: } ! 288: else ! 289: { ! 290: if(fPointer) ! 291: pPixmap = (PixmapPtr) pval; ! 292: else ! 293: pPixmap = (PixmapPtr)LookupID(pid, RT_PIXMAP, RC_CORE); ! 294: if (pPixmap) ! 295: { ! 296: clipType = CT_PIXMAP; ! 297: pPixmap->refcnt++; ! 298: } ! 299: else ! 300: error = BadPixmap; ! 301: } ! 302: pval++; ! 303: if(error == Success) ! 304: { ! 305: (*pGC->ChangeClip)(pGC, clipType, pPixmap, 0); ! 306: } ! 307: break; ! 308: } ! 309: case GCDashOffset: ! 310: pGC->dashOffset = (CARD16)*pval; ! 311: pval++; ! 312: break; ! 313: case GCDashList: ! 314: Xfree(pGC->dash); ! 315: pGC->numInDashList = 2; ! 316: pGC->dash = (unsigned char *)Xalloc(2 * sizeof(unsigned char)); ! 317: pGC->dash[0] = (CARD8)(*pval); ! 318: pGC->dash[1] = (CARD8)(*pval++); ! 319: break; ! 320: case GCArcMode: ! 321: if (((CARD8)*pval >= ArcChord) ! 322: && ((CARD8)*pval <= ArcPieSlice)) ! 323: pGC->arcMode = (CARD8)*pval; ! 324: else ! 325: error = BadValue; ! 326: pval++; ! 327: break; ! 328: default: ! 329: break; ! 330: } ! 331: } ! 332: pQ = pGC->pNextGCInterest; ! 333: pQInit = (GCInterestPtr) &pGC->pNextGCInterest; ! 334: do ! 335: { ! 336: /* I assume that if you've set a change interest mask, you've set a ! 337: * changeGC function */ ! 338: if(pQ->ChangeInterestMask & maskQ) ! 339: (*pQ->ChangeGC)(pGC, pQ, maskQ); ! 340: pQ = pQ->pNextGCInterest; ! 341: } ! 342: while(pQ != pQInit); ! 343: return error; ! 344: } ! 345: ! 346: /* CreateGC(pDrawable, mask, pval, pStatus) ! 347: creates a default GC for the given drawable, using mask to fill ! 348: in any non-default values. ! 349: Returns a pointer to the new GC on success, NULL otherwise. ! 350: returns status of non-default fields in pStatus ! 351: BUG: ! 352: should check for failure to create default tile and stipple ! 353: should be able to set the tile before the call the (pScreen->ChangeGC) ! 354: as it is, we must call ChangeGC twice. ! 355: ! 356: */ ! 357: ! 358: GC * ! 359: CreateGC(pDrawable, mask, pval, pStatus) ! 360: DrawablePtr pDrawable; ! 361: BITS32 mask; ! 362: long *pval; ! 363: BITS32 *pStatus; ! 364: { ! 365: register GC *pGC; ! 366: extern FontPtr defaultFont; ! 367: CARD32 tmpval[3]; ! 368: PixmapPtr pTile; ! 369: GCPtr pgcScratch; /* for drawing into default tile and stipple */ ! 370: xRectangle rect; ! 371: #ifdef DEBUG ! 372: void (**j)(); ! 373: #endif /* DEBUG */ ! 374: ! 375: pGC = (GC *)Xalloc(sizeof(GC)); ! 376: if (!pGC) ! 377: return (GC *)NULL; ! 378: ! 379: #ifdef DEBUG ! 380: for(j = &pGC->FillSpans; ! 381: j < &pGC->PushPixels; ! 382: j++ ) ! 383: *j = (void (*) ())NotImplemented; ! 384: #endif /* DEBUG */ ! 385: ! 386: pGC->pScreen = pDrawable->pScreen; ! 387: pGC->depth = pDrawable->depth; ! 388: pGC->alu = GXcopy; /* dst <- src */ ! 389: pGC->planemask = ~0; ! 390: pGC->serialNumber = GC_CHANGE_SERIAL_BIT; ! 391: ! 392: pGC->fgPixel = 0; ! 393: pGC->bgPixel = 1; ! 394: pGC->lineWidth = 0; ! 395: pGC->lineStyle = LineSolid; ! 396: pGC->capStyle = CapButt; ! 397: pGC->joinStyle = JoinMiter; ! 398: pGC->fillStyle = FillSolid; ! 399: pGC->fillRule = EvenOddRule; ! 400: pGC->arcMode = ArcPieSlice; ! 401: pGC->font = defaultFont; ! 402: if ( pGC->font) /* necessary, because open of default font could fail */ ! 403: pGC->font->refcnt++; ! 404: pGC->tile = NullPixmap; ! 405: ! 406: /* use the default stipple */ ! 407: pGC->stipple = pGC->pScreen->PixmapPerDepth[0]; ! 408: pGC->stipple->refcnt++; ! 409: pGC->patOrg.x = 0; ! 410: pGC->patOrg.y = 0; ! 411: pGC->subWindowMode = ClipByChildren; ! 412: pGC->graphicsExposures = TRUE; ! 413: pGC->clipOrg.x = 0; ! 414: pGC->clipOrg.y = 0; ! 415: pGC->clientClipType = CT_NONE; ! 416: pGC->clientClip = (pointer)NULL; ! 417: pGC->numInDashList = 2; ! 418: pGC->dash = (unsigned char *)Xalloc(2 * sizeof(unsigned char)); ! 419: pGC->dash[0] = 4; ! 420: pGC->dash[1] = 4; ! 421: pGC->dashOffset = 0; ! 422: ! 423: pGC->stateChanges = (1 << GCLastBit+1) - 1; ! 424: (*pGC->pScreen->CreateGC)(pGC); ! 425: if(mask) ! 426: *pStatus = ChangeGC(pGC, mask, pval); ! 427: else ! 428: *pStatus = Success; ! 429: ! 430: /* if the client hasn't provided a tile, build one and fill it with ! 431: the foreground pixel ! 432: */ ! 433: if (!pGC->tile) ! 434: { ! 435: int w, h; ! 436: ! 437: w = 16; ! 438: h = 16; ! 439: (*pGC->pScreen->QueryBestSize)(TileShape, &w, &h); ! 440: pTile = (PixmapPtr) ! 441: (*pGC->pScreen->CreatePixmap)(pDrawable->pScreen, ! 442: w, h, pGC->depth); ! 443: tmpval[0] = GXcopy; ! 444: tmpval[1] = pGC->fgPixel; ! 445: tmpval[2] = FillSolid; ! 446: pgcScratch = GetScratchGC(pGC->depth, pGC->pScreen); ! 447: ChangeGC(pgcScratch, GCFunction | GCForeground | GCFillStyle, ! 448: tmpval); ! 449: ValidateGC(pTile, pgcScratch); ! 450: rect.x = 0; ! 451: rect.y = 0; ! 452: rect.width = w; ! 453: rect.height = h; ! 454: (*pgcScratch->PolyFillRect)(pTile, pgcScratch, ! 455: 1, &rect); ! 456: /* Always remember to free the scratch graphics context after use. */ ! 457: FreeScratchGC(pgcScratch); ! 458: ! 459: /* ! 460: * Unfortunately, we must call ChangeGC a second time to get ! 461: * the tile installed. This would be nice to do before the first ! 462: * call to ChangeGC, but we don't know the value of the ! 463: * foreground pixel until afterwards. ! 464: */ ! 465: DoChangeGC(pGC, GCTile, (CARD32 *)&pTile, TRUE); ! 466: } ! 467: return (pGC); ! 468: } ! 469: ! 470: ! 471: void ! 472: CopyGC(pgcSrc, pgcDst, mask) ! 473: register GC *pgcSrc; ! 474: register GC *pgcDst; ! 475: register int mask; ! 476: { ! 477: register int index; ! 478: int maskQ; ! 479: GCInterestPtr pQ, pQInit; ! 480: int i; ! 481: ! 482: pgcDst->serialNumber |= GC_CHANGE_SERIAL_BIT; ! 483: pgcDst->stateChanges |= mask; ! 484: maskQ = mask; ! 485: while (mask) ! 486: { ! 487: index = ffs(mask) - 1; ! 488: mask &= ~(index = (1 << index)); ! 489: switch (index) ! 490: { ! 491: case GCFunction: ! 492: pgcDst->alu = pgcSrc->alu; ! 493: break; ! 494: case GCPlaneMask: ! 495: pgcDst->planemask = pgcSrc->planemask; ! 496: break; ! 497: case GCForeground: ! 498: pgcDst->fgPixel = pgcSrc->fgPixel; ! 499: break; ! 500: case GCBackground: ! 501: pgcDst->bgPixel = pgcSrc->bgPixel; ! 502: break; ! 503: case GCLineWidth: ! 504: pgcDst->lineWidth = pgcSrc->lineWidth; ! 505: break; ! 506: case GCLineStyle: ! 507: pgcDst->lineStyle = pgcSrc->lineStyle; ! 508: break; ! 509: case GCCapStyle: ! 510: pgcDst->capStyle = pgcSrc->capStyle; ! 511: break; ! 512: case GCJoinStyle: ! 513: pgcDst->joinStyle = pgcSrc->joinStyle; ! 514: break; ! 515: case GCFillStyle: ! 516: pgcDst->fillStyle = pgcSrc->fillStyle; ! 517: break; ! 518: case GCFillRule: ! 519: pgcDst->fillRule = pgcSrc->fillRule; ! 520: break; ! 521: case GCTile: ! 522: { ! 523: if (pgcDst->tile == pgcSrc->tile) ! 524: break; ! 525: (* pgcDst->pScreen->DestroyPixmap)(pgcDst->tile); ! 526: pgcDst->tile = pgcSrc->tile; ! 527: if (IS_VALID_PIXMAP(pgcDst->tile)) ! 528: pgcDst->tile->refcnt ++; ! 529: break; ! 530: } ! 531: case GCStipple: ! 532: { ! 533: if (pgcDst->stipple = pgcSrc->stipple) ! 534: break; ! 535: (* pgcDst->pScreen->DestroyPixmap)(pgcDst->stipple); ! 536: pgcDst->stipple = pgcSrc->stipple; ! 537: if (IS_VALID_PIXMAP(pgcDst->stipple)) ! 538: pgcDst->stipple->refcnt ++; ! 539: break; ! 540: } ! 541: case GCTileStipXOrigin: ! 542: pgcDst->patOrg.x = pgcSrc->patOrg.x; ! 543: break; ! 544: case GCTileStipYOrigin: ! 545: pgcDst->patOrg.y = pgcSrc->patOrg.y; ! 546: break; ! 547: case GCFont: ! 548: if (pgcDst->font == pgcSrc->font) ! 549: break; ! 550: if (pgcDst->font) ! 551: CloseFont(pgcDst->font); ! 552: if ((pgcDst->font = pgcSrc->font) != NullFont) ! 553: (pgcDst->font)->refcnt++; ! 554: break; ! 555: case GCSubwindowMode: ! 556: pgcDst->subWindowMode = pgcSrc->subWindowMode; ! 557: break; ! 558: case GCGraphicsExposures: ! 559: pgcDst->graphicsExposures = pgcSrc->graphicsExposures; ! 560: break; ! 561: case GCClipXOrigin: ! 562: pgcDst->clipOrg.x = pgcSrc->clipOrg.x; ! 563: break; ! 564: case GCClipYOrigin: ! 565: pgcDst->clipOrg.y = pgcSrc->clipOrg.y; ! 566: break; ! 567: case GCClipMask: ! 568: (* pgcDst->CopyClip)(pgcDst, pgcSrc); ! 569: break; ! 570: case GCDashOffset: ! 571: pgcDst->dashOffset = pgcSrc->dashOffset; ! 572: break; ! 573: case GCDashList: ! 574: Xfree(pgcDst->dash); ! 575: pgcDst->dash = (unsigned char *) ! 576: Xalloc(2 * sizeof(unsigned char)); ! 577: pgcDst->numInDashList = pgcSrc->numInDashList; ! 578: for (i=0; i<pgcSrc->numInDashList; i++) ! 579: pgcDst->dash[i] = pgcSrc->dash[i]; ! 580: break; ! 581: case GCArcMode: ! 582: pgcDst->arcMode = pgcSrc->arcMode; ! 583: break; ! 584: default: ! 585: break; ! 586: } ! 587: } ! 588: pQ = pgcSrc->pNextGCInterest; ! 589: pQInit = (GCInterestPtr) &pgcSrc->pNextGCInterest; ! 590: do ! 591: { ! 592: if(pQ->CopyGCSource) ! 593: (*pQ->CopyGCSource)(pgcSrc, pQ, maskQ, pgcDst); ! 594: pQ = pQ->pNextGCInterest; ! 595: } ! 596: while(pQ != pQInit); ! 597: pQ = pgcDst->pNextGCInterest; ! 598: pQInit = (GCInterestPtr) &pgcDst->pNextGCInterest; ! 599: do ! 600: { ! 601: if(pQ->CopyGCDest) ! 602: (*pQ->CopyGCDest)(pgcDst, pQ, maskQ, pgcSrc); ! 603: pQ = pQ->pNextGCInterest; ! 604: } ! 605: while(pQ != pQInit); ! 606: } ! 607: ! 608: /***************** ! 609: * FreeGC ! 610: * does the diX part of freeing the characteristics in the GC ! 611: ***************/ ! 612: ! 613: void ! 614: FreeGC(pGC, gid) ! 615: GC *pGC; ! 616: int gid; ! 617: { ! 618: GCInterestPtr pQ, pQInit, pQnext; ! 619: ! 620: CloseFont(pGC->font); ! 621: (* pGC->DestroyClip)(pGC); ! 622: ! 623: (* pGC->pScreen->DestroyPixmap)(pGC->tile); ! 624: (* pGC->pScreen->DestroyPixmap)(pGC->stipple); ! 625: ! 626: pQ = pGC->pNextGCInterest; ! 627: pQInit = (GCInterestPtr) &pGC->pNextGCInterest; ! 628: do ! 629: { ! 630: pQnext = pQ->pNextGCInterest; ! 631: if(pQ->DestroyGC) ! 632: (*pQ->DestroyGC) (pGC, pQ); ! 633: pQ = pQnext; ! 634: } ! 635: while(pQ != pQInit); ! 636: Xfree(pGC->dash); ! 637: Xfree(pGC); ! 638: } ! 639: ! 640: void ! 641: SetGCMask(pGC, selectMask, newDataMask) ! 642: GCPtr pGC; ! 643: Mask selectMask; ! 644: Mask newDataMask; ! 645: { ! 646: pGC->stateChanges = (~selectMask & pGC->stateChanges) | ! 647: (selectMask & newDataMask); ! 648: if (selectMask & newDataMask) ! 649: pGC->serialNumber |= GC_CHANGE_SERIAL_BIT; ! 650: } ! 651: ! 652: ! 653: ! 654: /* CreateScratchGC(pScreen, depth) ! 655: like CreateGC, but doesn't do the default tile or stipple, ! 656: since we can't create them without already having a GC. any code ! 657: using the tile or stipple has to set them explicitly anyway, ! 658: since the state of the scratch gc is unknown. This is OK ! 659: because ChangeGC() has to be able to deal with NULL tiles and ! 660: stipples anyway (in case the CreateGC() call has provided a ! 661: value for them -- we can't set the default tile until the ! 662: client-supplied attributes are installed, since the fgPixel ! 663: is what fills the default tile. (maybe this comment should ! 664: go with CreateGC() or ChangeGC().) ! 665: */ ! 666: ! 667: GC * ! 668: CreateScratchGC(pScreen, depth) ! 669: ScreenPtr pScreen; ! 670: int depth; ! 671: { ! 672: register GC *pGC; ! 673: extern FontPtr defaultFont; ! 674: #ifdef DEBUG ! 675: void (**j)(); ! 676: #endif /* DEBUG */ ! 677: ! 678: pGC = (GC *)Xalloc(sizeof(GC)); ! 679: if (!pGC) ! 680: return (GC *)NULL; ! 681: ! 682: #ifdef DEBUG ! 683: for(j = &pGC->FillSpans; ! 684: j < &pGC->PushPixels; ! 685: j++ ) ! 686: *j = (void (*) ())NotImplemented; ! 687: #endif /* DEBUG */ ! 688: ! 689: pGC->pScreen = pScreen; ! 690: pGC->depth = depth; ! 691: pGC->alu = GXcopy; /* dst <- src */ ! 692: pGC->planemask = ~0; ! 693: pGC->serialNumber = 0; ! 694: ! 695: pGC->fgPixel = 0; ! 696: pGC->bgPixel = 1; ! 697: pGC->lineWidth = 0; ! 698: pGC->lineStyle = LineSolid; ! 699: pGC->capStyle = CapButt; ! 700: pGC->joinStyle = JoinMiter; ! 701: pGC->fillStyle = FillSolid; ! 702: pGC->fillRule = EvenOddRule; ! 703: pGC->arcMode = ArcPieSlice; ! 704: pGC->font = defaultFont; ! 705: if ( pGC->font) /* necessary, because open of default font could fail */ ! 706: pGC->font->refcnt++; ! 707: pGC->tile = NullPixmap; ! 708: pGC->stipple = NullPixmap; ! 709: pGC->patOrg.x = 0; ! 710: pGC->patOrg.y = 0; ! 711: pGC->subWindowMode = ClipByChildren; ! 712: pGC->graphicsExposures = TRUE; ! 713: pGC->clipOrg.x = 0; ! 714: pGC->clipOrg.y = 0; ! 715: pGC->clientClipType = CT_NONE; ! 716: pGC->numInDashList = 2; ! 717: pGC->dash = (unsigned char *)Xalloc(2 * sizeof(unsigned char)); ! 718: pGC->dash[0] = 4; ! 719: pGC->dash[1] = 4; ! 720: pGC->dashOffset = 0; ! 721: ! 722: pGC->stateChanges = (1 << GCLastBit+1) - 1; ! 723: (*pScreen->CreateGC)(pGC); ! 724: return pGC; ! 725: } ! 726: ! 727: ! 728: FreeGCperDepth(screenNum) ! 729: int screenNum; ! 730: { ! 731: register int i; ! 732: register ScreenPtr pScreen; ! 733: GCPtr *ppGC; ! 734: ! 735: pScreen = &screenInfo.screen[screenNum]; ! 736: ppGC = (GCPtr *) pScreen->GCperDepth; ! 737: ! 738: /* do depth 1 seperately because it's not included in list */ ! 739: FreeGC(ppGC[0], 0); ! 740: ! 741: for (i = 0; i < pScreen-> numDepths; i++) ! 742: { ! 743: FreeGC(ppGC[i+1], 0); ! 744: } ! 745: } ! 746: ! 747: ! 748: CreateGCperDepthArray(screenNum) ! 749: int screenNum; ! 750: { ! 751: register int i; ! 752: register ScreenPtr pScreen; ! 753: DepthPtr pDepth; ! 754: ! 755: pScreen = &screenInfo.screen[screenNum]; ! 756: pScreen->rgf = 0; ! 757: /* do depth 1 seperately because it's not included in list */ ! 758: pScreen->GCperDepth[0] = CreateScratchGC(pScreen, 1); ! 759: (pScreen->GCperDepth[0])->graphicsExposures = FALSE; ! 760: ! 761: pDepth = pScreen->allowedDepths; ! 762: for (i=0; i<pScreen->numDepths; i++, pDepth++) ! 763: { ! 764: pScreen->GCperDepth[i+1] = CreateScratchGC(pScreen, ! 765: pDepth->depth); ! 766: (pScreen->GCperDepth[i+1])->graphicsExposures = FALSE; ! 767: } ! 768: } ! 769: ! 770: CreateDefaultStipple(screenNum) ! 771: int screenNum; ! 772: { ! 773: register ScreenPtr pScreen; ! 774: int tmpval[3]; ! 775: xRectangle rect; ! 776: int w, h; ! 777: GCPtr pgcScratch; ! 778: ! 779: pScreen = &screenInfo.screen[screenNum]; ! 780: ! 781: w = 16; ! 782: h = 16; ! 783: (* pScreen->QueryBestSize)(StippleShape, &w, &h); ! 784: pScreen->PixmapPerDepth[0] = ! 785: (*pScreen->CreatePixmap)(pScreen, w, h, 1); ! 786: ! 787: /* fill stipple with 1 */ ! 788: tmpval[0] = GXcopy; tmpval[1] = 1; tmpval[2] = FillSolid; ! 789: pgcScratch = GetScratchGC(1, pScreen); ! 790: ChangeGC(pgcScratch, GCFunction | GCForeground | GCFillStyle, tmpval); ! 791: ValidateGC(pScreen->PixmapPerDepth[0], pgcScratch); ! 792: rect.x = 0; ! 793: rect.y = 0; ! 794: rect.width = w; ! 795: rect.height = h; ! 796: (*pgcScratch->PolyFillRect)(pScreen->PixmapPerDepth[0], ! 797: pgcScratch, 1, &rect); ! 798: FreeScratchGC(pgcScratch); ! 799: } ! 800: ! 801: FreeDefaultStipple(screenNum) ! 802: int screenNum; ! 803: { ! 804: ScreenPtr pScreen = &screenInfo.screen[screenNum]; ! 805: (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]); ! 806: } ! 807: ! 808: ! 809: SetDashes(pGC, offset, ndash, pdash) ! 810: register GCPtr pGC; ! 811: int offset; ! 812: register int ndash; ! 813: register unsigned char *pdash; ! 814: { ! 815: register int i; ! 816: register unsigned char *p; ! 817: GCInterestPtr pQ, pQInit; ! 818: int maskQ = 0; ! 819: ! 820: i = ndash; ! 821: p = pdash; ! 822: while (i--) ! 823: { ! 824: if (!*p++) ! 825: { ! 826: /* dash segment must be > 0 */ ! 827: return BadValue; ! 828: } ! 829: } ! 830: ! 831: if (offset != pGC->dashOffset) ! 832: { ! 833: pGC->dashOffset = offset; ! 834: pGC->stateChanges |= GCDashOffset; ! 835: maskQ |= GCDashOffset; ! 836: } ! 837: ! 838: p = (unsigned char *)Xalloc(ndash * sizeof(unsigned char)); ! 839: if (!p) ! 840: { ! 841: return BadAlloc; ! 842: } ! 843: Xfree(pGC->dash); ! 844: pGC->dash = p; ! 845: pGC->numInDashList = ndash; ! 846: while(ndash--) ! 847: *p++ = *pdash++; ! 848: pGC->stateChanges |= GCDashList; ! 849: maskQ |= GCDashList; ! 850: ! 851: pQ = pGC->pNextGCInterest; ! 852: pQInit = (GCInterestPtr) &pGC->pNextGCInterest; ! 853: do ! 854: { ! 855: if(pQ->ChangeInterestMask & maskQ) ! 856: (*pQ->ChangeGC)(pGC, pQ, maskQ); ! 857: pQ = pQ->pNextGCInterest; ! 858: } ! 859: while(pQ != pQInit); ! 860: return Success; ! 861: } ! 862: ! 863: ! 864: int ! 865: SetClipRects(pGC, nrects, prects, ordering) ! 866: GCPtr pGC; ! 867: int nrects; ! 868: xRectangle *prects; ! 869: int ordering; ! 870: { ! 871: register xRectangle *prectP, *prectN; ! 872: register int i; ! 873: int newct, size; ! 874: xRectangle *prectsNew; ! 875: GCInterestPtr pQ, pQInit; ! 876: ! 877: switch(ordering) ! 878: { ! 879: case Unsorted: ! 880: newct = CT_UNSORTED; ! 881: break; ! 882: case YSorted: ! 883: if(i > 0) ! 884: { ! 885: prectP = prects; ! 886: prectN = prects + 1; ! 887: for(i = 1; i < nrects; i++, prectN++, prectP++) ! 888: if(prectN->y < prectP->y) ! 889: return(BadMatch); ! 890: } ! 891: newct = CT_YSORTED; ! 892: break; ! 893: case YXSorted: ! 894: if(i > 0) ! 895: { ! 896: for(i = 1; i < nrects; i++, prectN++, prectP++) ! 897: if((prectN->y < prectP->y) || ! 898: ( (prectN->y == prectP->y) && ! 899: (prectN->x < prectP->x) ) ) ! 900: return(BadMatch); ! 901: } ! 902: newct = CT_YXSORTED; ! 903: break; ! 904: case YXBanded: ! 905: if(i > 0) ! 906: { ! 907: for(i = 1; i < nrects; i++, prectN++, prectP++) ! 908: if((prectN->y < prectP->y) || ! 909: ( (prectN->y == prectP->y) && ! 910: ( (prectN->x < prectP->x) || ! 911: (prectN->height != prectP->height) ) ) ) ! 912: return(BadMatch); ! 913: } ! 914: newct = CT_YXBANDED; ! 915: break; ! 916: } ! 917: ! 918: size = nrects * sizeof(xRectangle); ! 919: prectsNew = (xRectangle *) Xalloc(size); ! 920: bcopy(prects, prectsNew, size); ! 921: (*pGC->ChangeClip)(pGC, newct, prectsNew, nrects); ! 922: pQ = pGC->pNextGCInterest; ! 923: pQInit = (GCInterestPtr) &pGC->pNextGCInterest; ! 924: do ! 925: { ! 926: if(pQ->ChangeInterestMask & GCClipMask) ! 927: (*pQ->ChangeGC)(pGC, pQ, GCClipMask); ! 928: pQ = pQ->pNextGCInterest; ! 929: } ! 930: while(pQ != pQInit); ! 931: return Success; ! 932: ! 933: } ! 934: ! 935: ! 936: /* ! 937: sets reasonable defaults ! 938: if we can get a pre-allocated one, use it and mark it as used. ! 939: if we can't, create one out of whole cloth (The Velveteen GC -- if ! 940: you use it often enough it will become real.) ! 941: */ ! 942: GCPtr ! 943: GetScratchGC(depth, pScreen) ! 944: register int depth; ! 945: register ScreenPtr pScreen; ! 946: { ! 947: register int i; ! 948: register GCPtr pGC = (GCPtr)NULL;; ! 949: ! 950: for (i=0; i<=pScreen->numDepths; i++) ! 951: if ( pScreen->GCperDepth[i]->depth == depth && ! 952: !(pScreen->rgf & 1 << (i+1)) ! 953: ) ! 954: { ! 955: pScreen->rgf |= 1 << (i+1); ! 956: pGC = (pScreen->GCperDepth[i]); ! 957: ! 958: pGC->alu = GXcopy; ! 959: pGC->planemask = ~0; ! 960: pGC->serialNumber = 0; ! 961: pGC->fgPixel = 0; ! 962: pGC->bgPixel = 1; ! 963: pGC->lineWidth = 0; ! 964: pGC->lineStyle = LineSolid; ! 965: pGC->capStyle = CapButt; ! 966: pGC->joinStyle = JoinMiter; ! 967: pGC->fillStyle = FillSolid; ! 968: pGC->fillRule = EvenOddRule; ! 969: pGC->arcMode = ArcChord; ! 970: pGC->patOrg.x = 0; ! 971: pGC->patOrg.y = 0; ! 972: pGC->subWindowMode = ClipByChildren; ! 973: pGC->graphicsExposures = FALSE; ! 974: pGC->clipOrg.x = 0; ! 975: pGC->clipOrg.y = 0; ! 976: /* can't change clip type, because we might drop storage */ ! 977: pGC->stateChanges = (1 << GCLastBit+1) - 1; ! 978: return pGC; ! 979: } ! 980: /* if we make it this far, need to roll our own */ ! 981: pGC = CreateScratchGC(pScreen, depth); ! 982: pGC->graphicsExposures = FALSE; ! 983: return pGC; ! 984: } ! 985: ! 986: /* ! 987: if the gc to free is in the table of pre-existing ones, ! 988: mark it as available. ! 989: if not, free it for real ! 990: */ ! 991: void ! 992: FreeScratchGC(pGC) ! 993: register GCPtr pGC; ! 994: { ! 995: register ScreenPtr pScreen = pGC->pScreen; ! 996: register int i; ! 997: ! 998: for (i=0; i<=pScreen->numDepths; i++) ! 999: { ! 1000: if ( pScreen->GCperDepth[i] == pGC) ! 1001: { ! 1002: pScreen->rgf &= ~(1<<i+1); ! 1003: return; ! 1004: } ! 1005: } ! 1006: FreeGC(pGC, 0); ! 1007: } ! 1008: ! 1009:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.