|
|
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: #include "X.h" ! 25: #include "Xmd.h" ! 26: #include "Xproto.h" ! 27: #include "dixfontstr.h" ! 28: #include "fontstruct.h" ! 29: #include "gcstruct.h" ! 30: #include "windowstr.h" ! 31: #include "pixmapstr.h" ! 32: #include "scrnintstr.h" ! 33: #include "region.h" ! 34: ! 35: #include "cfb.h" ! 36: #include "mistruct.h" ! 37: ! 38: #include "cfbmskbits.h" ! 39: extern cfbXRotatePixmap(); ! 40: extern cfbYRotatePixmap(); ! 41: extern void mfbPushPixels(); ! 42: ! 43: Bool ! 44: cfbCreateGC(pGC) ! 45: register GCPtr pGC; ! 46: { ! 47: GCInterestPtr pQ; ! 48: ! 49: switch (pGC->depth) { ! 50: case 1: ! 51: return (mfbCreateGC(pGC)); ! 52: case PSZ: ! 53: break; ! 54: default: ! 55: ErrorF("cfbCreateGC: unsupported depth: %d\n", pGC->depth); ! 56: return FALSE; ! 57: } ! 58: pGC->clientClip = NULL; ! 59: pGC->clientClipType = CT_NONE; ! 60: ! 61: /* ! 62: * some of the output primitives aren't really necessary, since they ! 63: * will be filled in ValidateGC because of dix/CreateGC() setting all ! 64: * the change bits. Others are necessary because although they depend ! 65: * on being a color frame buffer, they don't change ! 66: */ ! 67: ! 68: pGC->FillSpans = cfbSolidFS; ! 69: pGC->SetSpans = cfbSetSpans; ! 70: pGC->PutImage = miPutImage; ! 71: pGC->CopyArea = miCopyArea; ! 72: pGC->CopyPlane = miCopyPlane; ! 73: pGC->PolyPoint = miPolyPoint; ! 74: ! 75: #ifdef notdef ! 76: pGC->Polylines = miNotMiter; /* Doesn't work for 0-width lines */ ! 77: #else ! 78: pGC->Polylines = miZeroLine; ! 79: #endif notdef ! 80: pGC->PolySegment = miPolySegment; ! 81: pGC->PolyRectangle = miPolyRectangle; ! 82: pGC->PolyArc = miPolyArc; ! 83: pGC->FillPolygon = miFillPolygon; ! 84: pGC->PolyFillRect = miPolyFillRect; ! 85: pGC->PolyFillArc = miPolyFillArc; ! 86: pGC->PolyText8 = miPolyText8; ! 87: pGC->ImageText8 = miImageText8; ! 88: pGC->PolyText16 = miPolyText16; ! 89: pGC->ImageText16 = miImageText16; ! 90: pGC->ImageGlyphBlt = miImageGlyphBlt; ! 91: pGC->PolyGlyphBlt = miPolyGlyphBlt; ! 92: #ifdef notdef ! 93: pGC->PushPixels = miPushPixels; /* miPushPixels is garbage */ ! 94: #else ! 95: pGC->PushPixels = mfbPushPixels; /* but mfbPushPixels isn't depth ! 96: * dependent */ ! 97: #endif ! 98: pGC->LineHelper = miMiter; ! 99: pGC->ChangeClip = cfbChangeClip; ! 100: pGC->DestroyClip = cfbDestroyClip; ! 101: pGC->CopyClip = cfbCopyClip; ! 102: ! 103: /* cfb wants to translate before scan convesion */ ! 104: pGC->miTranslate = 1; ! 105: ! 106: { ! 107: cfbPrivGC *pPriv; ! 108: ! 109: pPriv = (cfbPrivGC *) Xalloc(sizeof(cfbPrivGC)); ! 110: if (!pPriv) ! 111: return FALSE; ! 112: else { ! 113: pPriv->rop = pGC->alu; ! 114: pPriv->fExpose = TRUE; ! 115: pGC->devPriv = (pointer) pPriv; ! 116: pPriv->pRotatedTile = NullPixmap; ! 117: pPriv->pRotatedStipple = NullPixmap; ! 118: pPriv->pAbsClientRegion = (*pGC->pScreen->RegionCreate) (NULL, 1); ! 119: pPriv->pCompositeClip = (*pGC->pScreen->RegionCreate) (NULL, 1); ! 120: pPriv->freeCompClip = REPLACE_CC; ! 121: } ! 122: } ! 123: pQ = (GCInterestPtr) Xalloc(sizeof(GCInterestRec)); ! 124: if (!pQ) { ! 125: Xfree(pGC->devPriv); ! 126: return FALSE; ! 127: } ! 128: ! 129: /* Now link this device into the GCque */ ! 130: pGC->pNextGCInterest = pQ; ! 131: pGC->pLastGCInterest = pQ; ! 132: pQ->pNextGCInterest = (GCInterestPtr) & pGC->pNextGCInterest; ! 133: pQ->pLastGCInterest = (GCInterestPtr) & pGC->pNextGCInterest; ! 134: pQ->length = sizeof(GCInterestRec); ! 135: pQ->owner = 0; /* server owns this */ ! 136: pQ->ValInterestMask = ~0; /* interested in everything at validate ! 137: * time */ ! 138: pQ->ValidateGC = cfbValidateGC; ! 139: pQ->ChangeInterestMask = 0; /* interested in nothing at change time */ ! 140: pQ->ChangeGC = (int (*) ()) NULL; ! 141: pQ->CopyGCSource = (void (*) ()) NULL; ! 142: pQ->CopyGCDest = cfbCopyGCDest; ! 143: pQ->DestroyGC = cfbDestroyGC; ! 144: return TRUE; ! 145: } ! 146: ! 147: void ! 148: cfbDestroyGC(pGC, pQ) ! 149: GC *pGC; ! 150: GCInterestPtr pQ; ! 151: ! 152: { ! 153: cfbPrivGC *pPriv; ! 154: ! 155: switch (pGC->depth) { ! 156: case 1: ! 157: mfbDestroyGC(pGC, pQ); ! 158: return; ! 159: case PSZ: ! 160: break; ! 161: default: ! 162: ErrorF("cfbCreateGC: unsupported depth: %d\n", pGC->depth); ! 163: return; ! 164: } ! 165: /* Most GCInterest pointers would free pQ->devPriv. This one is privileged ! 166: * and allowed to allocate its private data directly in the GC (this ! 167: * saves an indirection). We must also unlink and free the pQ. ! 168: */ ! 169: pQ->pLastGCInterest->pNextGCInterest = pGC->pNextGCInterest; ! 170: pQ->pNextGCInterest->pLastGCInterest = pGC->pLastGCInterest; ! 171: ! 172: pPriv = (cfbPrivGC *)(pGC->devPriv); ! 173: if (pPriv->pRotatedTile) ! 174: cfbDestroyPixmap(pPriv->pRotatedTile); ! 175: if (pPriv->pRotatedStipple) ! 176: cfbDestroyPixmap(pPriv->pRotatedStipple); ! 177: if (pPriv->freeCompClip == FREE_CC && pPriv->pCompositeClip) ! 178: (*pGC->pScreen->RegionDestroy)(pPriv->pCompositeClip); ! 179: if(pPriv->pAbsClientRegion) ! 180: (*pGC->pScreen->RegionDestroy)(pPriv->pAbsClientRegion); ! 181: Xfree(pGC->devPriv); ! 182: Xfree(pQ); ! 183: } ! 184: ! 185: #define WINMOVED(pWin, pGC) \ ! 186: ((pWin->absCorner.x != pGC->lastWinOrg.x) || \ ! 187: (pWin->absCorner.y != pGC->lastWinOrg.y)) ! 188: ! 189: /* Clipping conventions ! 190: if the drawable is a window ! 191: CT_REGION ==> pCompositeClip really is the composite ! 192: CT_other ==> pCompositeClip is the window clip region ! 193: if the drawable is a pixmap ! 194: CT_REGION ==> pCompositeClip is the translated client region ! 195: clipped to the pixmap boundary ! 196: CT_other ==> pCompositeClip is the pixmap bounding box ! 197: */ ! 198: ! 199: void ! 200: cfbValidateGC(pGC, pQ, changes, pDrawable) ! 201: register GC *pGC; ! 202: GCInterestPtr *pQ; ! 203: Mask changes; ! 204: DrawablePtr pDrawable; ! 205: { ! 206: WindowPtr pWin; ! 207: int mask; /* stateChanges */ ! 208: int index; /* used for stepping through bitfields */ ! 209: int xrot, yrot; /* rotations for tile and stipple pattern */ ! 210: Bool fRotate = FALSE;/* True if rotated pixmaps are needed */ ! 211: int new_line, new_text, new_fillspans; ! 212: /* flags for changing the proc vector */ ! 213: cfbPrivGCPtr devPriv; ! 214: ! 215: switch (pGC->depth) { ! 216: case PSZ: ! 217: break; ! 218: case 1: ! 219: if (pDrawable->type == DRAWABLE_PIXMAP) { ! 220: mfbValidateGC(pGC, pQ, changes, pDrawable); ! 221: return; ! 222: } ! 223: /* WARNING - FALL THROUGH */ ! 224: default: ! 225: ErrorF("cfbCreateGC: unsupported depth: %d\n", pGC->depth); ! 226: return; ! 227: } ! 228: if (pDrawable->type == DRAWABLE_WINDOW) ! 229: pWin = (WindowPtr) pDrawable; ! 230: else ! 231: pWin = (WindowPtr) NULL; ! 232: ! 233: devPriv = ((cfbPrivGCPtr) (pGC->devPriv)); ! 234: ! 235: /* ! 236: * if the client clip is different or moved OR the subwindowMode has ! 237: * changed OR the window's clip has changed since the last validation ! 238: * we need to recompute the composite clip ! 239: */ ! 240: ! 241: if ((changes & (GCClipXOrigin | GCClipYOrigin | GCClipMask)) || ! 242: (changes & GCSubwindowMode) || ! 243: (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS)) ! 244: ) { ! 245: ! 246: /* ! 247: * if there is a client clip (always a region, for us) AND it has ! 248: * moved or is different OR the window has moved we need to ! 249: * (re)translate it. ! 250: */ ! 251: if ((pGC->clientClipType == CT_REGION) && ! 252: ((changes & (GCClipXOrigin | GCClipYOrigin | GCClipMask)) || ! 253: (pWin && WINMOVED(pWin, pGC)) ! 254: ) ! 255: ) { ! 256: /* retranslate client clip */ ! 257: (*pGC->pScreen->RegionCopy) (devPriv->pAbsClientRegion, ! 258: pGC->clientClip); ! 259: ! 260: if (pWin) { ! 261: pGC->lastWinOrg.x = pWin->absCorner.x; ! 262: pGC->lastWinOrg.y = pWin->absCorner.y; ! 263: (*pGC->pScreen->TranslateRegion) ( ! 264: devPriv->pAbsClientRegion, ! 265: pGC->lastWinOrg.x + pGC->clipOrg.x, ! 266: pGC->lastWinOrg.y + pGC->clipOrg.y); ! 267: } ! 268: else { ! 269: pGC->lastWinOrg.x = 0; ! 270: pGC->lastWinOrg.y = 0; ! 271: (*pGC->pScreen->TranslateRegion) ( ! 272: devPriv->pAbsClientRegion, pGC->clipOrg.x, pGC->clipOrg.y); ! 273: } ! 274: } ! 275: ! 276: if (pWin) { ! 277: RegionPtr pregWin; ! 278: int freeTmpClip, freeCompClip; ! 279: ! 280: if (pGC->subWindowMode == IncludeInferiors) { ! 281: pregWin = NotClippedByChildren(pWin); ! 282: freeTmpClip = FREE_CC; ! 283: } ! 284: else { ! 285: pregWin = pWin->clipList; ! 286: freeTmpClip = REPLACE_CC; ! 287: } ! 288: freeCompClip = devPriv->freeCompClip; ! 289: ! 290: /* ! 291: * if there is no client clip, we can get by with just keeping ! 292: * the pointer we got, and remembering whether or not should ! 293: * destroy (or maybe re-use) it later. this way, we avoid ! 294: * unnecessary copying of regions. (this wins especially if ! 295: * many clients clip by children and have no client clip.) ! 296: */ ! 297: if (pGC->clientClipType == CT_NONE) { ! 298: if (freeCompClip == FREE_CC) { ! 299: (*pGC->pScreen->RegionDestroy) (devPriv->pCompositeClip); ! 300: } ! 301: devPriv->pCompositeClip = pregWin; ! 302: devPriv->freeCompClip = freeTmpClip; ! 303: } ! 304: else { ! 305: /* ! 306: * we need one 'real' region to put into the composite ! 307: * clip. if pregWin the current composite clip are real, ! 308: * we can get rid of one. if pregWin is real and the ! 309: * current composite clip isn't, use pregWin for the ! 310: * composite clip. if the current composite clip is real ! 311: * and pregWin isn't, use the current composite clip. if ! 312: * neither is real, create a new region. ! 313: */ ! 314: ! 315: if ((freeTmpClip == FREE_CC) && (freeCompClip == FREE_CC)) { ! 316: (*pGC->pScreen->Intersect) ( ! 317: devPriv->pCompositeClip, ! 318: pregWin, ! 319: devPriv->pAbsClientRegion); ! 320: (*pGC->pScreen->RegionDestroy) (pregWin); ! 321: } ! 322: else if ((freeTmpClip == REPLACE_CC) && ! 323: (freeCompClip == FREE_CC)) { ! 324: devPriv->pCompositeClip = pregWin; ! 325: (*pGC->pScreen->Intersect) ( ! 326: devPriv->pCompositeClip, ! 327: devPriv->pCompositeClip, ! 328: devPriv->pAbsClientRegion); ! 329: } ! 330: else if ((freeTmpClip == FREE_CC) && ! 331: (freeCompClip == REPLACE_CC)) { ! 332: (*pGC->pScreen->Intersect) ( ! 333: devPriv->pCompositeClip, ! 334: pregWin, ! 335: devPriv->pAbsClientRegion); ! 336: } ! 337: else if ((freeTmpClip == REPLACE_CC) && ! 338: (freeCompClip == REPLACE_CC)) { ! 339: devPriv->pCompositeClip = ! 340: (*pGC->pScreen->RegionCreate) (NULL, 1); ! 341: (*pGC->pScreen->Intersect) ( ! 342: devPriv->pCompositeClip, ! 343: pregWin, ! 344: devPriv->pAbsClientRegion); ! 345: } ! 346: } ! 347: } /* end of composite clip for a window */ ! 348: else { ! 349: BoxRec pixbounds; ! 350: ! 351: pixbounds.x1 = 0; ! 352: pixbounds.y1 = 0; ! 353: pixbounds.x2 = ((PixmapPtr) pDrawable)->width; ! 354: pixbounds.y2 = ((PixmapPtr) pDrawable)->height; ! 355: ! 356: if (devPriv->freeCompClip == FREE_CC) ! 357: (*pGC->pScreen->RegionReset) ( ! 358: devPriv->pCompositeClip, &pixbounds); ! 359: else { ! 360: devPriv->freeCompClip = FREE_CC; ! 361: devPriv->pCompositeClip = ! 362: (*pGC->pScreen->RegionCreate) (&pixbounds, 1); ! 363: } ! 364: ! 365: if (pGC->clientClipType == CT_REGION) ! 366: (*pGC->pScreen->Intersect) ( ! 367: devPriv->pCompositeClip, ! 368: devPriv->pCompositeClip, ! 369: devPriv->pAbsClientRegion); ! 370: } /* end of composute clip for pixmap */ ! 371: } ! 372: ! 373: if (pWin) { ! 374: ! 375: /* ! 376: * rotate tile patterns so that pattern can be combined in word by ! 377: * word, but the pattern seems to begin aligned with the window ! 378: */ ! 379: xrot = pWin->absCorner.x; ! 380: yrot = pWin->absCorner.y; ! 381: } ! 382: else { ! 383: yrot = 0; ! 384: xrot = 0; ! 385: } ! 386: ! 387: ! 388: new_line = FALSE; ! 389: new_text = FALSE; ! 390: new_fillspans = FALSE; ! 391: ! 392: mask = changes; ! 393: while (mask) { ! 394: index = ffs(mask) - 1; ! 395: mask &= ~(index = (1 << index)); ! 396: ! 397: /* ! 398: * this switch acculmulates a list of which procedures might have ! 399: * to change due to changes in the GC. in some cases (e.g. ! 400: * changing one 16 bit tile for another) we might not really need ! 401: * a change, but the code is being paranoid. this sort of batching ! 402: * wins if, for example, the alu and the font have been changed, ! 403: * or any other pair of items that both change the same thing. ! 404: */ ! 405: switch (index) { ! 406: case GCFunction: ! 407: case GCForeground: ! 408: new_text = TRUE; ! 409: break; ! 410: case GCPlaneMask: ! 411: break; ! 412: case GCBackground: ! 413: new_fillspans = TRUE; ! 414: break; ! 415: case GCLineStyle: ! 416: break; ! 417: case GCLineWidth: ! 418: case GCCapStyle: ! 419: case GCJoinStyle: ! 420: new_line = TRUE; ! 421: break; ! 422: case GCFillStyle: ! 423: new_text = TRUE; ! 424: new_fillspans = TRUE; ! 425: new_line = TRUE; ! 426: break; ! 427: case GCFillRule: ! 428: break; ! 429: case GCTile: ! 430: if (pGC->tile == (PixmapPtr) NULL) ! 431: break; ! 432: cfbPadPixmap(pGC->tile); ! 433: fRotate = TRUE; ! 434: new_fillspans = TRUE; ! 435: break; ! 436: ! 437: case GCStipple: ! 438: if (pGC->stipple == (PixmapPtr) NULL) ! 439: break; ! 440: cfbPadPixmap(pGC->stipple); ! 441: fRotate = TRUE; ! 442: new_fillspans = TRUE; ! 443: break; ! 444: ! 445: case GCTileStipXOrigin: ! 446: fRotate = TRUE; ! 447: break; ! 448: ! 449: case GCTileStipYOrigin: ! 450: fRotate = TRUE; ! 451: break; ! 452: ! 453: case GCFont: ! 454: new_text = TRUE; ! 455: break; ! 456: case GCSubwindowMode: ! 457: break; ! 458: case GCGraphicsExposures: ! 459: break; ! 460: case GCClipXOrigin: ! 461: break; ! 462: case GCClipYOrigin: ! 463: break; ! 464: case GCClipMask: ! 465: break; ! 466: case GCDashOffset: ! 467: break; ! 468: case GCDashList: ! 469: break; ! 470: case GCArcMode: ! 471: break; ! 472: default: ! 473: break; ! 474: } ! 475: } ! 476: ! 477: /* ! 478: * If the drawable has changed, check its depth & ensure suitable ! 479: * entries are in the proc vector. ! 480: */ ! 481: if (pDrawable->serialNumber != (pGC->serialNumber & (DRAWABLE_SERIAL_BITS))) { ! 482: new_fillspans = TRUE; /* deal with FillSpans later */ ! 483: pGC->SetSpans = cfbSetSpans; ! 484: } ! 485: ! 486: /* deal with the changes we've collected */ ! 487: ! 488: if (new_line) { ! 489: if (pGC->lineWidth == 0) { ! 490: #ifdef notdef ! 491: if (pGC->fillStyle == FillSolid) ! 492: pGC->Polylines = miNotMiter; /* XXX - doesn't work for ! 493: * zero. ???miNotMiter??? */ ! 494: else ! 495: #endif ! 496: pGC->Polylines = miZeroLine; ! 497: } ! 498: else { ! 499: switch (pGC->joinStyle) { ! 500: case JoinMiter: ! 501: pGC->LineHelper = miMiter; ! 502: break; ! 503: case JoinRound: ! 504: case JoinBevel: ! 505: pGC->LineHelper = miNotMiter; ! 506: break; ! 507: } ! 508: } ! 509: } ! 510: ! 511: if (new_text && pGC->font) { ! 512: pGC->PolyGlyphBlt = miPolyGlyphBlt; ! 513: pGC->ImageGlyphBlt = miImageGlyphBlt; ! 514: pGC->PolyGlyphBlt = miPolyGlyphBlt; ! 515: pGC->ImageGlyphBlt = miImageGlyphBlt; ! 516: } ! 517: ! 518: if (new_fillspans) { ! 519: switch (pGC->fillStyle) { ! 520: case FillSolid: ! 521: pGC->FillSpans = cfbSolidFS; ! 522: break; ! 523: case FillTiled: ! 524: pGC->FillSpans = cfbUnnaturalTileFS; ! 525: if (!pGC->tile) ! 526: FatalError("cfbValidateGC: tile mode & no tile\n"); ! 527: if (((DrawablePtr)pGC->tile)->depth != pGC->depth) ! 528: FatalError("cfbValidateGC: tile wrong depth\n"); ! 529: break; ! 530: case FillStippled: ! 531: pGC->FillSpans = cfbUnnaturalStippleFS; ! 532: if (!pGC->stipple) ! 533: FatalError("cfbValidateGC: stipple mode & no stipple\n"); ! 534: if (((DrawablePtr)pGC->stipple)->depth != 1) ! 535: FatalError("cfbValidateGC: stipple wrong depth\n"); ! 536: break; ! 537: case FillOpaqueStippled: ! 538: if (pGC->fgPixel == pGC->bgPixel) ! 539: pGC->FillSpans = cfbSolidFS; ! 540: else { ! 541: pGC->FillSpans = cfbUnnaturalStippleFS; ! 542: if (!pGC->stipple) ! 543: FatalError("cfbValidateGC: stipple mode & no stipple\n"); ! 544: if (((DrawablePtr)pGC->stipple)->depth != 1) ! 545: FatalError("cfbValidateGC: stipple wrong depth\n"); ! 546: } ! 547: break; ! 548: default: ! 549: FatalError("cfbValidateGC: illegal fillStyle\n"); ! 550: } ! 551: } /* end of new_fillspans */ ! 552: ! 553: if (xrot || yrot || fRotate) { ! 554: /* ! 555: * First destroy any previously-rotated tile/stipple ! 556: */ ! 557: if (devPriv->pRotatedTile) { ! 558: cfbDestroyPixmap(devPriv->pRotatedTile); ! 559: devPriv->pRotatedTile = (PixmapPtr)NULL; ! 560: } ! 561: if (devPriv->pRotatedStipple) { ! 562: cfbDestroyPixmap(devPriv->pRotatedStipple); ! 563: devPriv->pRotatedStipple = (PixmapPtr)NULL; ! 564: } ! 565: if (pGC->tile && ! 566: (devPriv->pRotatedTile = cfbCopyPixmap(pGC->tile)) ! 567: == (PixmapPtr) NULL) ! 568: FatalError("cfbValidateGC: cannot rotate tile\n"); ! 569: if (pGC->stipple && ! 570: (devPriv->pRotatedStipple = cfbCopyPixmap(pGC->stipple)) ! 571: == (PixmapPtr) NULL) ! 572: FatalError("cfbValidateGC: cannot rotate stipple\n"); ! 573: /* ! 574: * If we've gotten here, we're probably going to rotate the tile ! 575: * and/or stipple, so we have to add the pattern origin into ! 576: * the rotation factor, even if it hasn't changed. ! 577: */ ! 578: xrot += pGC->patOrg.x; ! 579: yrot += pGC->patOrg.y; ! 580: if (xrot) { ! 581: if (pGC->tile && devPriv->pRotatedTile) ! 582: cfbXRotatePixmap(devPriv->pRotatedTile, xrot); ! 583: if (pGC->stipple && devPriv->pRotatedStipple) ! 584: cfbXRotatePixmap(devPriv->pRotatedStipple, xrot); ! 585: } ! 586: if (yrot) { ! 587: if (pGC->tile && devPriv->pRotatedTile) ! 588: cfbYRotatePixmap(devPriv->pRotatedTile, yrot); ! 589: if (pGC->stipple && devPriv->pRotatedStipple) ! 590: cfbYRotatePixmap(devPriv->pRotatedStipple, yrot); ! 591: } ! 592: } ! 593: } ! 594: ! 595: ! 596: void ! 597: cfbDestroyClip(pGC) ! 598: GCPtr pGC; ! 599: { ! 600: switch (pGC->depth) { ! 601: case 1: ! 602: mfbDestroyClip(pGC); ! 603: return; ! 604: case PSZ: ! 605: break; ! 606: default: ! 607: ErrorF("cfbCreateGC: unsupported depth: %d\n", pGC->depth); ! 608: return; ! 609: } ! 610: if(pGC->clientClipType == CT_NONE) ! 611: return; ! 612: (*pGC->pScreen->RegionDestroy)(pGC->clientClip); ! 613: pGC->clientClip = NULL; ! 614: pGC->clientClipType = CT_NONE; ! 615: pGC->stateChanges |= (GCClipXOrigin | GCClipYOrigin | GCClipMask); ! 616: } ! 617: ! 618: void ! 619: cfbChangeClip(pGC, type, pvalue, nrects) ! 620: GCPtr pGC; ! 621: int type; ! 622: pointer pvalue; ! 623: int nrects; ! 624: { ! 625: switch (pGC->depth) { ! 626: case 1: ! 627: mfbChangeClip(pGC, type, pvalue, nrects); ! 628: return; ! 629: case PSZ: ! 630: break; ! 631: default: ! 632: ErrorF("cfbChangeClip: unsupported depth: %d\n", pGC->depth); ! 633: return; ! 634: } ! 635: cfbDestroyClip(pGC); ! 636: if(type == CT_PIXMAP) ! 637: { ! 638: pGC->clientClip = (pointer) mfbPixmapToRegion(pvalue); ! 639: (*pGC->pScreen->DestroyPixmap)(pvalue); ! 640: } ! 641: else if (type == CT_REGION) { ! 642: pGC->clientClip = (pointer) (*pGC->pScreen->RegionCreate)( NULL, 0 ); ! 643: (*pGC->pScreen->RegionCopy)( pGC->clientClip, pvalue ); ! 644: } ! 645: else if (type != CT_NONE) ! 646: { ! 647: pGC->clientClip = (pointer) miRectsToRegion(pGC, nrects, pvalue, type); ! 648: Xfree(pvalue); ! 649: } ! 650: pGC->clientClipType = (pGC->clientClip) ? CT_REGION : CT_NONE; ! 651: pGC->stateChanges |= (GCClipXOrigin | GCClipYOrigin | GCClipMask); ! 652: } ! 653: ! 654: void ! 655: cfbCopyClip (pgcDst, pgcSrc) ! 656: GCPtr pgcDst, pgcSrc; ! 657: { ! 658: RegionPtr prgnNew; ! 659: ! 660: switch (pgcSrc->depth) { ! 661: case 1: ! 662: mfbCopyClip(pgcDst, pgcSrc); ! 663: return; ! 664: case PSZ: ! 665: break; ! 666: default: ! 667: ErrorF("cfbCopyClip: unsupported depth: %d\n", pgcSrc->depth); ! 668: return; ! 669: } ! 670: switch(pgcSrc->clientClipType) ! 671: { ! 672: case CT_NONE: ! 673: case CT_PIXMAP: ! 674: cfbChangeClip(pgcDst, pgcSrc->clientClipType, pgcSrc->clientClip, 0); ! 675: break; ! 676: case CT_REGION: ! 677: prgnNew = (*pgcSrc->pScreen->RegionCreate)(NULL, 1); ! 678: (*pgcSrc->pScreen->RegionCopy)(prgnNew, ! 679: (RegionPtr)(pgcSrc->clientClip)); ! 680: cfbChangeClip(pgcDst, CT_REGION, prgnNew, 0); ! 681: break; ! 682: } ! 683: } ! 684: ! 685: void ! 686: cfbCopyGCDest (pGC, pQ, changes, pGCSrc) ! 687: GCPtr pGC; ! 688: GCInterestPtr pQ; ! 689: Mask changes; ! 690: GCPtr pGCSrc; ! 691: { ! 692: RegionPtr pClip; ! 693: ! 694: switch (pGC->depth) { ! 695: case 1: ! 696: mfbCopyGCDest(pGC); ! 697: return; ! 698: case PSZ: ! 699: break; ! 700: default: ! 701: ErrorF("cfbCreateGC: unsupported depth: %d\n", pGC->depth); ! 702: return; ! 703: } ! 704: if(changes & GCClipMask) ! 705: { ! 706: if(pGC->clientClipType == CT_PIXMAP) ! 707: { ! 708: ((PixmapPtr)pGC->clientClip)->refcnt++; ! 709: } ! 710: else if(pGC->clientClipType == CT_REGION) ! 711: { ! 712: BoxRec pixbounds; ! 713: ! 714: pixbounds.x1 = 0; ! 715: pixbounds.y1 = 0; ! 716: pixbounds.x2 = 0; ! 717: pixbounds.y2 = 0; ! 718: ! 719: pClip = (RegionPtr) pGC->clientClip; ! 720: pGC->clientClip = ! 721: (pointer)(* pGC->pScreen->RegionCreate)(&pixbounds, 1); ! 722: (* pGC->pScreen->RegionCopy)(pGC->clientClip, pClip); ! 723: } ! 724: } ! 725: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.