|
|
1.1 ! root 1: /************************************************************ ! 2: Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA. ! 3: ! 4: All Rights Reserved ! 5: ! 6: Permission to use, copy, modify, and distribute this ! 7: software and its documentation for any purpose and without ! 8: fee is hereby granted, provided that the above copyright no- ! 9: tice appear in all copies and that both that copyright no- ! 10: tice and this permission notice appear in supporting docu- ! 11: mentation, and that the names of Sun or MIT not be used in ! 12: advertising or publicity pertaining to distribution of the ! 13: software without specific prior written permission. Sun and ! 14: M.I.T. make no representations about the suitability of this ! 15: software for any purpose. It is provided "as is" without any ! 16: express or implied warranty. ! 17: ! 18: SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, ! 19: INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- ! 20: NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI- ! 21: ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 22: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR ! 23: PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR ! 24: OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH ! 25: THE USE OR PERFORMANCE OF THIS SOFTWARE. ! 26: ! 27: ********************************************************/ ! 28: ! 29: ! 30: /*********************************************************** ! 31: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, ! 32: and the Massachusetts Institute of Technology, Cambridge, Massachusetts. ! 33: ! 34: All Rights Reserved ! 35: ! 36: Permission to use, copy, modify, and distribute this software and its ! 37: documentation for any purpose and without fee is hereby granted, ! 38: provided that the above copyright notice appear in all copies and that ! 39: both that copyright notice and this permission notice appear in ! 40: supporting documentation, and that the names of Digital or MIT not be ! 41: used in advertising or publicity pertaining to distribution of the ! 42: software without specific, written prior permission. ! 43: ! 44: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 45: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 46: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 47: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 48: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 49: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 50: SOFTWARE. ! 51: ! 52: ******************************************************************/ ! 53: ! 54: #include "X.h" ! 55: #include "Xprotostr.h" ! 56: ! 57: #include "miscstruct.h" ! 58: #include "regionstr.h" ! 59: #include "gcstruct.h" ! 60: #include "windowstr.h" ! 61: #include "pixmapstr.h" ! 62: #include "scrnintstr.h" ! 63: ! 64: #include "cfb.h" ! 65: #include "cfbmskbits.h" ! 66: ! 67: ! 68: /* CopyArea and CopyPlane for a monchrome frame buffer ! 69: ! 70: ! 71: clip the source rectangle to the source's available bits. (this ! 72: avoids copying unnecessary pieces that will just get exposed anyway.) ! 73: this becomes the new shape of the destination. ! 74: clip the destination region to the composite clip in the ! 75: GC. this requires translating the destination region to (dstx, dsty). ! 76: build a list of source points, one for each rectangle in the ! 77: destination. this is a simple translation. ! 78: go do the multiple rectangle copies ! 79: do graphics exposures ! 80: */ ! 81: ! 82: /* macro for bitblt to avoid a switch on the alu per scanline ! 83: comments are in the real code in cfbDoBitblt. ! 84: we need tmpDst for things less than 1 word wide becuase ! 85: the destination may cross a word boundary, and we need to read ! 86: it all at once to do the rasterop. (this perhaps argues for ! 87: sub-casing narrow things that don't cross a word boundary.) ! 88: */ ! 89: #define DOBITBLT(ALU) \ ! 90: while (nbox--) \ ! 91: { \ ! 92: w = pbox->x2 - pbox->x1; \ ! 93: h = pbox->y2 - pbox->y1; \ ! 94: if (ydir == -1) \ ! 95: { \ ! 96: psrcLine = psrcBase + ((pptSrc->y+h-1) * -widthSrc); \ ! 97: pdstLine = pdstBase + ((pbox->y2-1) * -widthDst); \ ! 98: } \ ! 99: else \ ! 100: { \ ! 101: psrcLine = psrcBase + (pptSrc->y * widthSrc); \ ! 102: pdstLine = pdstBase + (pbox->y1 * widthDst); \ ! 103: } \ ! 104: if (w <= PPW) \ ! 105: { \ ! 106: int tmpDst; \ ! 107: int srcBit, dstBit; \ ! 108: pdstLine += (pbox->x1 >> PWSH); \ ! 109: psrcLine += (pptSrc->x >> PWSH); \ ! 110: psrc = psrcLine; \ ! 111: pdst = pdstLine; \ ! 112: srcBit = pptSrc->x & PIM; \ ! 113: dstBit = pbox->x1 & PIM; \ ! 114: while(h--) \ ! 115: { \ ! 116: getbits(psrc, srcBit, w, tmpSrc) \ ! 117: getbits(pdst, dstBit, w, tmpDst) \ ! 118: tmpSrc = ALU(tmpSrc, tmpDst); \ ! 119: /*XXX*/ putbits(tmpSrc, dstBit, w, pdst, -1) \ ! 120: pdst += widthDst; \ ! 121: psrc += widthSrc; \ ! 122: } \ ! 123: } \ ! 124: else \ ! 125: { \ ! 126: register int xoffSrc; \ ! 127: int nstart; \ ! 128: int nend; \ ! 129: int srcStartOver; \ ! 130: maskbits(pbox->x1, w, startmask, endmask, nlMiddle) \ ! 131: if (startmask) \ ! 132: nstart = PPW - (pbox->x1 & PIM); \ ! 133: else \ ! 134: nstart = 0; \ ! 135: if (endmask) \ ! 136: nend = pbox->x2 & PIM; \ ! 137: else \ ! 138: nend = 0; \ ! 139: xoffSrc = ((pptSrc->x & PIM) + nstart) & PIM; \ ! 140: srcStartOver = ((pptSrc->x & PIM) + nstart) > PLST; \ ! 141: if (xdir == 1) \ ! 142: { \ ! 143: pdstLine += (pbox->x1 >> PWSH); \ ! 144: psrcLine += (pptSrc->x >> PWSH); \ ! 145: while (h--) \ ! 146: { \ ! 147: psrc = psrcLine; \ ! 148: pdst = pdstLine; \ ! 149: if (startmask) \ ! 150: { \ ! 151: getbits(psrc, (pptSrc->x & PIM), nstart, tmpSrc) \ ! 152: tmpSrc = ALU(tmpSrc, *pdst); \ ! 153: /*XXX*/ putbits(tmpSrc, (pbox->x1 & PIM), nstart, pdst, -1) \ ! 154: pdst++; \ ! 155: if (srcStartOver) \ ! 156: psrc++; \ ! 157: } \ ! 158: nl = nlMiddle; \ ! 159: while (nl--) \ ! 160: { \ ! 161: getbits(psrc, xoffSrc, PPW, tmpSrc) \ ! 162: *pdst = ALU(tmpSrc, *pdst); \ ! 163: pdst++; \ ! 164: psrc++; \ ! 165: } \ ! 166: if (endmask) \ ! 167: { \ ! 168: getbits(psrc, xoffSrc, nend, tmpSrc) \ ! 169: tmpSrc = ALU(tmpSrc, *pdst); \ ! 170: /*XXX*/ putbits(tmpSrc, 0, nend, pdst, -1) \ ! 171: } \ ! 172: pdstLine += widthDst; \ ! 173: psrcLine += widthSrc; \ ! 174: } \ ! 175: } \ ! 176: else \ ! 177: { \ ! 178: pdstLine += (pbox->x2 >> PWSH); \ ! 179: psrcLine += (pptSrc->x+w >> PWSH); \ ! 180: if (xoffSrc + nend >= PPW) \ ! 181: --psrcLine; \ ! 182: while (h--) \ ! 183: { \ ! 184: psrc = psrcLine; \ ! 185: pdst = pdstLine; \ ! 186: if (endmask) \ ! 187: { \ ! 188: getbits(psrc, xoffSrc, nend, tmpSrc) \ ! 189: tmpSrc = ALU(tmpSrc, *pdst); \ ! 190: /*XXX*/ putbits(tmpSrc, 0, nend, pdst, -1) \ ! 191: } \ ! 192: nl = nlMiddle; \ ! 193: while (nl--) \ ! 194: { \ ! 195: --psrc; \ ! 196: getbits(psrc, xoffSrc, PPW, tmpSrc) \ ! 197: --pdst; \ ! 198: *pdst = ALU(tmpSrc, *pdst); \ ! 199: } \ ! 200: if (startmask) \ ! 201: { \ ! 202: if (srcStartOver) \ ! 203: --psrc; \ ! 204: --pdst; \ ! 205: getbits(psrc, (pptSrc->x & PIM), nstart, tmpSrc) \ ! 206: tmpSrc = ALU(tmpSrc, *pdst); \ ! 207: /*XXX*/ putbits(tmpSrc, (pbox->x1 & PIM), nstart, pdst, -1) \ ! 208: } \ ! 209: pdstLine += widthDst; \ ! 210: psrcLine += widthSrc; \ ! 211: } \ ! 212: } \ ! 213: } \ ! 214: pbox++; \ ! 215: pptSrc++; \ ! 216: } ! 217: ! 218: ! 219: /* DoBitblt() does multiple rectangle moves into the rectangles ! 220: DISCLAIMER: ! 221: this code can be made much faster; this implementation is ! 222: designed to be independent of byte/bit order, processor ! 223: instruction set, and the like. it could probably be done ! 224: in a similarly device independent way using mask tables instead ! 225: of the getbits/putbits macros. the narrow case (w<32) can be ! 226: subdivided into a case that crosses word boundaries and one that ! 227: doesn't. ! 228: ! 229: we have to cope with the dircetion on a per band basis, ! 230: rather than a per rectangle basis. moving bottom to top ! 231: means we have to invert the order of the bands; moving right ! 232: to left requires reversing the order of the rectangles in ! 233: each band. ! 234: ! 235: if src or dst is a window, the points have already been ! 236: translated. ! 237: */ ! 238: ! 239: cfbDoBitblt(pSrcDrawable, pDstDrawable, alu, prgnDst, pptSrc) ! 240: DrawablePtr pSrcDrawable; ! 241: DrawablePtr pDstDrawable; ! 242: int alu; ! 243: RegionPtr prgnDst; ! 244: DDXPointPtr pptSrc; ! 245: { ! 246: int *psrcBase, *pdstBase; /* start of src and dst bitmaps */ ! 247: int widthSrc, widthDst; /* add to get to same position in next line */ ! 248: ! 249: register BoxPtr pbox; ! 250: int nbox; ! 251: ! 252: BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew; ! 253: /* temporaries for shuffling rectangles */ ! 254: DDXPointPtr pptTmp, pptNew; /* shuffling boxes entails shuffling the ! 255: source points too */ ! 256: int w, h; ! 257: int xdir; /* 1 = left right, -1 = right left/ */ ! 258: int ydir; /* 1 = top down, -1 = bottom up */ ! 259: ! 260: int *psrcLine, *pdstLine; /* pointers to line with current src and dst */ ! 261: register int *psrc; /* pointer to current src longword */ ! 262: register int *pdst; /* pointer to current dst longword */ ! 263: ! 264: /* following used for looping through a line */ ! 265: int startmask, endmask; /* masks for writing ends of dst */ ! 266: int nlMiddle; /* whole longwords in dst */ ! 267: register int nl; /* temp copy of nlMiddle */ ! 268: register int tmpSrc; /* place to store full source word */ ! 269: ! 270: if (pSrcDrawable->type == DRAWABLE_WINDOW) ! 271: { ! 272: psrcBase = (int *) ! 273: (((PixmapPtr)(pSrcDrawable->pScreen->devPrivate))->devPrivate); ! 274: widthSrc = (int) ! 275: ((PixmapPtr)(pSrcDrawable->pScreen->devPrivate))->devKind ! 276: >> 2; ! 277: } ! 278: else ! 279: { ! 280: psrcBase = (int *)(((PixmapPtr)pSrcDrawable)->devPrivate); ! 281: widthSrc = (int)(((PixmapPtr)pSrcDrawable)->devKind) >> 2; ! 282: } ! 283: ! 284: if (pDstDrawable->type == DRAWABLE_WINDOW) ! 285: { ! 286: pdstBase = (int *) ! 287: (((PixmapPtr)(pDstDrawable->pScreen->devPrivate))->devPrivate); ! 288: widthDst = (int) ! 289: ((PixmapPtr)(pDstDrawable->pScreen->devPrivate))->devKind ! 290: >> 2; ! 291: } ! 292: else ! 293: { ! 294: pdstBase = (int *)(((PixmapPtr)pDstDrawable)->devPrivate); ! 295: widthDst = (int)(((PixmapPtr)pDstDrawable)->devKind) >> 2; ! 296: } ! 297: ! 298: pbox = prgnDst->rects; ! 299: nbox = prgnDst->numRects; ! 300: ! 301: pboxNew = 0; ! 302: pptNew = 0; ! 303: if (pptSrc->y < pbox->y1) ! 304: { ! 305: /* walk source botttom to top */ ! 306: ydir = -1; ! 307: widthSrc = -widthSrc; ! 308: widthDst = -widthDst; ! 309: ! 310: if (nbox > 1) ! 311: { ! 312: /* keep ordering in each band, reverse order of bands */ ! 313: pboxNew = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox); ! 314: pptNew = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox); ! 315: if(!pboxNew || !pptNew) ! 316: { ! 317: DEALLOCATE_LOCAL(pptNew); ! 318: DEALLOCATE_LOCAL(pboxNew); ! 319: return; ! 320: } ! 321: pboxBase = pboxNext = pbox+nbox-1; ! 322: while (pboxBase >= pbox) ! 323: { ! 324: while ((pboxNext >= pbox) && ! 325: (pboxBase->y1 == pboxNext->y1)) ! 326: pboxNext--; ! 327: pboxTmp = pboxNext+1; ! 328: pptTmp = pptSrc + (pboxTmp - pbox); ! 329: while (pboxTmp <= pboxBase) ! 330: { ! 331: *pboxNew++ = *pboxTmp++; ! 332: *pptNew++ = *pptTmp++; ! 333: } ! 334: pboxBase = pboxNext; ! 335: } ! 336: pboxNew -= nbox; ! 337: pbox = pboxNew; ! 338: pptNew -= nbox; ! 339: pptSrc = pptNew; ! 340: } ! 341: } ! 342: else ! 343: { ! 344: /* walk source top to bottom */ ! 345: ydir = 1; ! 346: } ! 347: ! 348: if (pptSrc->x < pbox->x1) ! 349: { ! 350: /* walk source right to left */ ! 351: xdir = -1; ! 352: ! 353: if (nbox > 1) ! 354: { ! 355: /* reverse order of rects ineach band */ ! 356: pboxNew = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox); ! 357: pptNew = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox); ! 358: pboxBase = pboxNext = pbox; ! 359: if(!pboxNew || !pptNew) ! 360: { ! 361: DEALLOCATE_LOCAL(pptNew); ! 362: DEALLOCATE_LOCAL(pboxNew); ! 363: return; ! 364: } ! 365: while (pboxBase < pbox+nbox) ! 366: { ! 367: while ((pboxNext < pbox+nbox) && ! 368: (pboxNext->y1 == pboxBase->y1)) ! 369: pboxNext++; ! 370: pboxTmp = pboxNext; ! 371: pptTmp = pptSrc + (pboxTmp - pbox); ! 372: while (pboxTmp != pboxBase) ! 373: { ! 374: *pboxNew++ = *--pboxTmp; ! 375: *pptNew++ = *--pptTmp; ! 376: } ! 377: pboxBase = pboxNext; ! 378: } ! 379: pboxNew -= nbox; ! 380: pbox = pboxNew; ! 381: pptNew -= nbox; ! 382: pptSrc = pptNew; ! 383: } ! 384: } ! 385: else ! 386: { ! 387: /* walk source left to right */ ! 388: xdir = 1; ! 389: } ! 390: ! 391: ! 392: /* special case copy, to avoid some redundant moves into temporaries */ ! 393: if (alu == GXcopy) ! 394: { ! 395: while (nbox--) ! 396: { ! 397: w = pbox->x2 - pbox->x1; ! 398: h = pbox->y2 - pbox->y1; ! 399: ! 400: if (ydir == -1) /* start at last scanline of rectangle */ ! 401: { ! 402: psrcLine = psrcBase + ((pptSrc->y+h-1) * -widthSrc); ! 403: pdstLine = pdstBase + ((pbox->y2-1) * -widthDst); ! 404: } ! 405: else /* start at first scanline */ ! 406: { ! 407: psrcLine = psrcBase + (pptSrc->y * widthSrc); ! 408: pdstLine = pdstBase + (pbox->y1 * widthDst); ! 409: } ! 410: ! 411: /* x direction doesn't matter for < 1 longword */ ! 412: if (w <= PPW) ! 413: { ! 414: int srcBit, dstBit; /* bit offset of src and dst */ ! 415: ! 416: pdstLine += (pbox->x1 >> PWSH); ! 417: psrcLine += (pptSrc->x >> PWSH); ! 418: psrc = psrcLine; ! 419: pdst = pdstLine; ! 420: ! 421: srcBit = pptSrc->x & PIM; ! 422: dstBit = pbox->x1 & PIM; ! 423: ! 424: while(h--) ! 425: { ! 426: getbits(psrc, srcBit, w, tmpSrc) ! 427: /*XXX*/ putbits(tmpSrc, dstBit, w, pdst, -1) ! 428: pdst += widthDst; ! 429: psrc += widthSrc; ! 430: } ! 431: } ! 432: else ! 433: { ! 434: register int xoffSrc; /* offset (>= 0, < 32) from which to ! 435: fetch whole longwords fetched ! 436: in src */ ! 437: int nstart; /* number of ragged bits ! 438: at start of dst */ ! 439: int nend; /* number of ragged bits at end ! 440: of dst */ ! 441: int srcStartOver; /* pulling nstart bits from src ! 442: overflows into the next word? */ ! 443: ! 444: maskbits(pbox->x1, w, startmask, endmask, nlMiddle) ! 445: if (startmask) ! 446: nstart = PPW - (pbox->x1 & PIM); ! 447: else ! 448: nstart = 0; ! 449: if (endmask) ! 450: nend = pbox->x2 & PIM; ! 451: else ! 452: nend = 0; ! 453: ! 454: xoffSrc = ((pptSrc->x & PIM) + nstart) & PIM; ! 455: srcStartOver = ((pptSrc->x & PIM) + nstart) > PLST; ! 456: ! 457: if (xdir == 1) /* move left to right */ ! 458: { ! 459: pdstLine += (pbox->x1 >> PWSH); ! 460: psrcLine += (pptSrc->x >> PWSH); ! 461: ! 462: while (h--) ! 463: { ! 464: psrc = psrcLine; ! 465: pdst = pdstLine; ! 466: ! 467: if (startmask) ! 468: { ! 469: getbits(psrc, (pptSrc->x & PIM), nstart, tmpSrc) ! 470: /*XXX*/ putbits(tmpSrc, (pbox->x1 & PIM), nstart, pdst, ! 471: -1) ! 472: pdst++; ! 473: if (srcStartOver) ! 474: psrc++; ! 475: } ! 476: ! 477: nl = nlMiddle; ! 478: while (nl--) ! 479: { ! 480: getbits(psrc, xoffSrc, PPW, tmpSrc) ! 481: *pdst++ = tmpSrc; ! 482: psrc++; ! 483: } ! 484: ! 485: if (endmask) ! 486: { ! 487: getbits(psrc, xoffSrc, nend, tmpSrc) ! 488: /*XXX*/ putbits(tmpSrc, 0, nend, pdst, -1) ! 489: } ! 490: ! 491: pdstLine += widthDst; ! 492: psrcLine += widthSrc; ! 493: } ! 494: } ! 495: else /* move right to left */ ! 496: { ! 497: pdstLine += (pbox->x2 >> PWSH); ! 498: psrcLine += (pptSrc->x+w >> PWSH); ! 499: /* if fetch of last partial bits from source crosses ! 500: a longword boundary, start at the previous longword ! 501: */ ! 502: if (xoffSrc + nend >= PPW) ! 503: --psrcLine; ! 504: ! 505: while (h--) ! 506: { ! 507: psrc = psrcLine; ! 508: pdst = pdstLine; ! 509: ! 510: if (endmask) ! 511: { ! 512: getbits(psrc, xoffSrc, nend, tmpSrc) ! 513: /*XXX*/ putbits(tmpSrc, 0, nend, pdst, -1) ! 514: } ! 515: ! 516: nl = nlMiddle; ! 517: while (nl--) ! 518: { ! 519: --psrc; ! 520: getbits(psrc, xoffSrc, PPW, tmpSrc) ! 521: *--pdst = tmpSrc; ! 522: } ! 523: ! 524: if (startmask) ! 525: { ! 526: if (srcStartOver) ! 527: --psrc; ! 528: --pdst; ! 529: getbits(psrc, (pptSrc->x & PIM), nstart, tmpSrc) ! 530: /*XXX*/ putbits(tmpSrc, (pbox->x1 & PIM), nstart, pdst, ! 531: -1) ! 532: } ! 533: ! 534: pdstLine += widthDst; ! 535: psrcLine += widthSrc; ! 536: } ! 537: } /* move right to left */ ! 538: } ! 539: pbox++; ! 540: pptSrc++; ! 541: } /* while (nbox--) */ ! 542: } ! 543: else ! 544: { ! 545: if (alu == GXclear) ! 546: DOBITBLT(fnCLEAR) ! 547: else if (alu ==GXand) ! 548: DOBITBLT(fnAND) ! 549: else if (alu == GXandReverse) ! 550: DOBITBLT(fnANDREVERSE) ! 551: else if (alu == GXcopy) ! 552: DOBITBLT(fnCOPY) ! 553: else if (alu == GXandInverted) ! 554: DOBITBLT(fnANDINVERTED) ! 555: /* ! 556: else if (alu == GXnoop) ! 557: */ ! 558: else if (alu == GXxor) ! 559: DOBITBLT(fnXOR) ! 560: else if (alu == GXor) ! 561: DOBITBLT(fnOR) ! 562: else if (alu == GXnor) ! 563: DOBITBLT(fnNOR) ! 564: else if (alu == GXequiv) ! 565: DOBITBLT(fnEQUIV) ! 566: else if (alu == GXinvert) ! 567: DOBITBLT(fnINVERT) ! 568: else if (alu == GXorReverse) ! 569: DOBITBLT(fnORREVERSE) ! 570: else if (alu == GXcopyInverted) ! 571: DOBITBLT(fnCOPYINVERTED) ! 572: else if (alu == GXorInverted) ! 573: DOBITBLT(fnORINVERTED) ! 574: else if (alu == GXnand) ! 575: DOBITBLT(fnNAND) ! 576: else if (alu == GXset) ! 577: DOBITBLT(fnSET) ! 578: } ! 579: ! 580: if (pptNew) ! 581: { ! 582: DEALLOCATE_LOCAL(pptNew); ! 583: } ! 584: if (pboxNew) ! 585: { ! 586: DEALLOCATE_LOCAL(pboxNew); ! 587: } ! 588: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.