|
|
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.