|
|
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: /* $Header: mfbbitblt.c,v 1.42 87/08/09 13:58:52 ham Exp $ */
25: #include "X.h"
26: #include "Xprotostr.h"
27:
28: #include "miscstruct.h"
29: #include "regionstr.h"
30: #include "gcstruct.h"
31: #include "windowstr.h"
32: #include "pixmapstr.h"
33: #include "scrnintstr.h"
34:
35: #include "mfb.h"
36: #include "maskbits.h"
37:
38:
39: /* CopyArea and CopyPlane for a monchrome frame buffer
40:
41:
42: clip the source rectangle to the source's available bits. (this
43: avoids copying unnecessary pieces that will just get exposed anyway.)
44: this becomes the new shape of the destination.
45: clip the destination region to the composite clip in the
46: GC. this requires translating the destination region to (dstx, dsty).
47: build a list of source points, one for each rectangle in the
48: destination. this is a simple translation.
49: go do the multiple rectangle copies
50: do graphics exposures
51: */
52:
53: void
54: mfbCopyArea(pSrcDrawable, pDstDrawable,
55: pGC, srcx, srcy, width, height, dstx, dsty)
56: register DrawablePtr pSrcDrawable;
57: register DrawablePtr pDstDrawable;
58: GC *pGC;
59: int srcx, srcy;
60: int width, height;
61: int dstx, dsty;
62: {
63: BoxRec srcBox;
64: RegionPtr prgnSrcClip; /* may be a new region, or just a copy */
65: int realSrcClip = 0; /* non-0 if we've created a src clip */
66:
67: RegionPtr prgnDst;
68: DDXPointPtr pptSrc;
69: register DDXPointPtr ppt;
70: register BoxPtr pbox;
71: int i;
72: register int dx;
73: register int dy;
74: xRectangle origSource;
75: DDXPointRec origDest;
76:
77: if (!(pGC->planemask & 1))
78: return;
79:
80: origSource.x = srcx;
81: origSource.y = srcy;
82: origSource.width = width;
83: origSource.height = height;
84: origDest.x = dstx;
85: origDest.y = dsty;
86:
87: /*
88: clip the left and top edges of the source
89: */
90: if (srcx < 0)
91: {
92: width += srcx;
93: srcx = 0;
94: }
95: if (srcy < 0)
96: {
97: height += srcy;
98: srcy = 0;
99: }
100:
101: /* clip the source */
102:
103: if (pSrcDrawable->type == DRAWABLE_PIXMAP)
104: {
105: BoxRec box;
106:
107: box.x1 = 0;
108: box.y1 = 0;
109: box.x2 = ((PixmapPtr)pSrcDrawable)->width;
110: box.y2 = ((PixmapPtr)pSrcDrawable)->height;
111:
112: prgnSrcClip = miRegionCreate(&box, 1);
113: realSrcClip = 1;
114: }
115: else
116: {
117: srcx += ((WindowPtr)pSrcDrawable)->absCorner.x;
118: srcy += ((WindowPtr)pSrcDrawable)->absCorner.y;
119: prgnSrcClip = ((WindowPtr)pSrcDrawable)->clipList;
120: }
121:
122: srcBox.x1 = srcx;
123: srcBox.y1 = srcy;
124: srcBox.x2 = srcx + width;
125: srcBox.y2 = srcy + height;
126:
127: prgnDst = miRegionCreate(&srcBox, 1);
128: miIntersect(prgnDst, prgnDst, prgnSrcClip);
129:
130: if (pDstDrawable->type == DRAWABLE_WINDOW)
131: {
132: if (!((WindowPtr)pDstDrawable)->realized)
133: {
134: miSendNoExpose(pGC);
135: miRegionDestroy(prgnDst);
136: if (realSrcClip)
137: miRegionDestroy(prgnSrcClip);
138: return;
139: }
140: dstx += ((WindowPtr)pDstDrawable)->absCorner.x;
141: dsty += ((WindowPtr)pDstDrawable)->absCorner.y;
142: }
143:
144: dx = srcx - dstx;
145: dy = srcy - dsty;
146:
147: /* clip the shape of the dst to the destination composite clip */
148: miTranslateRegion(prgnDst, -dx, -dy);
149: miIntersect(prgnDst,
150: prgnDst,
151: ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip);
152:
153: if (!prgnDst->numRects)
154: {
155: miSendNoExpose(pGC);
156: miRegionDestroy(prgnDst);
157: if (realSrcClip)
158: miRegionDestroy(prgnSrcClip);
159: return;
160: }
161: if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL( prgnDst->numRects *
162: sizeof(DDXPointRec))))
163: {
164: miRegionDestroy(prgnDst);
165: if (realSrcClip)
166: miRegionDestroy(prgnSrcClip);
167: return;
168: }
169: pbox = prgnDst->rects;
170: ppt = pptSrc;
171: for (i=0; i<prgnDst->numRects; i++, pbox++, ppt++)
172: {
173: ppt->x = pbox->x1 + dx;
174: ppt->y = pbox->y1 + dy;
175: }
176:
177: mfbDoBitblt(pSrcDrawable, pDstDrawable, pGC->alu, prgnDst, pptSrc);
178:
179: if (((mfbPrivGC *)(pGC->devPriv))->fExpose)
180: miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
181: origSource.x, origSource.y,
182: origSource.width, origSource.height,
183: origDest.x, origDest.y);
184:
185: DEALLOCATE_LOCAL(pptSrc);
186: miRegionDestroy(prgnDst);
187: if (realSrcClip)
188: miRegionDestroy(prgnSrcClip);
189: }
190:
191: /* DoBitblt() does multiple rectangle moves into the rectangles
192: DISCLAIMER:
193: this code can be made much faster; this implementation is
194: designed to be independent of byte/bit order, processor
195: instruction set, and the like. it could probably be done
196: in a similarly device independent way using mask tables instead
197: of the getbits/putbits macros. the narrow case (w<32) can be
198: subdivided into a case that crosses word boundaries and one that
199: doesn't.
200:
201: we have to cope with the dircetion on a per band basis,
202: rather than a per rectangle basis. moving bottom to top
203: means we have to invert the order of the bands; moving right
204: to left requires reversing the order of the rectangles in
205: each band.
206:
207: if src or dst is a window, the points have already been
208: translated.
209: */
210:
211: mfbDoBitblt(pSrcDrawable, pDstDrawable, alu, prgnDst, pptSrc)
212: DrawablePtr pSrcDrawable;
213: DrawablePtr pDstDrawable;
214: int alu;
215: RegionPtr prgnDst;
216: DDXPointPtr pptSrc;
217: {
218: unsigned int *psrcBase, *pdstBase;
219: /* start of src and dst bitmaps */
220: int widthSrc, widthDst; /* add to get to same position in next line */
221:
222: register BoxPtr pbox;
223: int nbox;
224:
225: BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
226: /* temporaries for shuffling rectangles */
227: DDXPointPtr pptTmp, pptNew1, pptNew2;
228: /* shuffling boxes entails shuffling the
229: source points too */
230: int w, h;
231: int xdir; /* 1 = left right, -1 = right left/ */
232: int ydir; /* 1 = top down, -1 = bottom up */
233:
234: unsigned int *psrcLine, *pdstLine;
235: /* pointers to line with current src and dst */
236: register unsigned int *psrc;/* pointer to current src longword */
237: register unsigned int *pdst;/* pointer to current dst longword */
238:
239: /* following used for looping through a line */
240: int startmask, endmask; /* masks for writing ends of dst */
241: int nlMiddle; /* whole longwords in dst */
242: register int nl; /* temp copy of nlMiddle */
243: register unsigned int tmpSrc;
244: /* place to store full source word */
245: register int xoffSrc; /* offset (>= 0, < 32) from which to
246: fetch whole longwords fetched
247: in src */
248: int nstart; /* number of ragged bits at start of dst */
249: int nend; /* number of ragged bits at end of dst */
250: int srcStartOver; /* pulling nstart bits from src
251: overflows into the next word? */
252:
253:
254: if (pSrcDrawable->type == DRAWABLE_WINDOW)
255: {
256: psrcBase = (unsigned int *)
257: (((PixmapPtr)(pSrcDrawable->pScreen->devPrivate))->devPrivate);
258: widthSrc = (int)
259: ((PixmapPtr)(pSrcDrawable->pScreen->devPrivate))->devKind
260: >> 2;
261: }
262: else
263: {
264: psrcBase = (unsigned int *)(((PixmapPtr)pSrcDrawable)->devPrivate);
265: widthSrc = (int)(((PixmapPtr)pSrcDrawable)->devKind) >> 2;
266: }
267:
268: if (pDstDrawable->type == DRAWABLE_WINDOW)
269: {
270: pdstBase = (unsigned int *)
271: (((PixmapPtr)(pDstDrawable->pScreen->devPrivate))->devPrivate);
272: widthDst = (int)
273: ((PixmapPtr)(pDstDrawable->pScreen->devPrivate))->devKind
274: >> 2;
275: }
276: else
277: {
278: pdstBase = (unsigned int *)(((PixmapPtr)pDstDrawable)->devPrivate);
279: widthDst = (int)(((PixmapPtr)pDstDrawable)->devKind) >> 2;
280: }
281:
282: pbox = prgnDst->rects;
283: nbox = prgnDst->numRects;
284:
285: pboxNew1 = 0;
286: pptNew1 = 0;
287: pboxNew2 = 0;
288: pptNew2 = 0;
289: if (pptSrc->y < pbox->y1)
290: {
291: /* walk source botttom to top */
292: ydir = -1;
293: widthSrc = -widthSrc;
294: widthDst = -widthDst;
295:
296: if (nbox > 1)
297: {
298: /* keep ordering in each band, reverse order of bands */
299: pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
300: pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
301: if(!pboxNew1 || !pptNew1)
302: {
303: DEALLOCATE_LOCAL(pptNew1);
304: DEALLOCATE_LOCAL(pboxNew1);
305: return;
306: }
307: pboxBase = pboxNext = pbox+nbox-1;
308: while (pboxBase >= pbox)
309: {
310: while ((pboxNext >= pbox) &&
311: (pboxBase->y1 == pboxNext->y1))
312: pboxNext--;
313: pboxTmp = pboxNext+1;
314: pptTmp = pptSrc + (pboxTmp - pbox);
315: while (pboxTmp <= pboxBase)
316: {
317: *pboxNew1++ = *pboxTmp++;
318: *pptNew1++ = *pptTmp++;
319: }
320: pboxBase = pboxNext;
321: }
322: pboxNew1 -= nbox;
323: pbox = pboxNew1;
324: pptNew1 -= nbox;
325: pptSrc = pptNew1;
326: }
327: }
328: else
329: {
330: /* walk source top to bottom */
331: ydir = 1;
332: }
333:
334: if (pptSrc->x < pbox->x1)
335: {
336: /* walk source right to left */
337: xdir = -1;
338:
339: if (nbox > 1)
340: {
341: /* reverse order of rects in each band */
342: pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
343: pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
344: pboxBase = pboxNext = pbox;
345: if(!pboxNew2 || !pptNew2)
346: {
347: DEALLOCATE_LOCAL(pptNew2);
348: DEALLOCATE_LOCAL(pboxNew2);
349: return;
350: }
351: while (pboxBase < pbox+nbox)
352: {
353: while ((pboxNext < pbox+nbox) &&
354: (pboxNext->y1 == pboxBase->y1))
355: pboxNext++;
356: pboxTmp = pboxNext;
357: pptTmp = pptSrc + (pboxTmp - pbox);
358: while (pboxTmp != pboxBase)
359: {
360: *pboxNew2++ = *--pboxTmp;
361: *pptNew2++ = *--pptTmp;
362: }
363: pboxBase = pboxNext;
364: }
365: pboxNew2 -= nbox;
366: pbox = pboxNew2;
367: pptNew2 -= nbox;
368: pptSrc = pptNew2;
369: }
370: }
371: else
372: {
373: /* walk source left to right */
374: xdir = 1;
375: }
376:
377:
378: /* special case copy */
379: if (alu == GXcopy)
380: {
381: while (nbox--)
382: {
383: w = pbox->x2 - pbox->x1;
384: h = pbox->y2 - pbox->y1;
385:
386: if (ydir == -1) /* start at last scanline of rectangle */
387: {
388: psrcLine = psrcBase + ((pptSrc->y+h-1) * -widthSrc);
389: pdstLine = pdstBase + ((pbox->y2-1) * -widthDst);
390: }
391: else /* start at first scanline */
392: {
393: psrcLine = psrcBase + (pptSrc->y * widthSrc);
394: pdstLine = pdstBase + (pbox->y1 * widthDst);
395: }
396:
397: /* x direction doesn't matter for < 1 longword */
398: if (w <= 32)
399: {
400: int srcBit, dstBit; /* bit offset of src and dst */
401:
402: pdstLine += (pbox->x1 >> 5);
403: psrcLine += (pptSrc->x >> 5);
404: psrc = psrcLine;
405: pdst = pdstLine;
406:
407: srcBit = pptSrc->x & 0x1f;
408: dstBit = pbox->x1 & 0x1f;
409:
410: while(h--)
411: {
412: getbits(psrc, srcBit, w, tmpSrc)
413: putbits(tmpSrc, dstBit, w, pdst)
414: pdst += widthDst;
415: psrc += widthSrc;
416: }
417: }
418: else
419: {
420: maskbits(pbox->x1, w, startmask, endmask, nlMiddle)
421: if (startmask)
422: nstart = 32 - (pbox->x1 & 0x1f);
423: else
424: nstart = 0;
425: if (endmask)
426: nend = pbox->x2 & 0x1f;
427: else
428: nend = 0;
429:
430: xoffSrc = ((pptSrc->x & 0x1f) + nstart) & 0x1f;
431: srcStartOver = ((pptSrc->x & 0x1f) + nstart) > 31;
432:
433: if (xdir == 1) /* move left to right */
434: {
435: pdstLine += (pbox->x1 >> 5);
436: psrcLine += (pptSrc->x >> 5);
437:
438: while (h--)
439: {
440: psrc = psrcLine;
441: pdst = pdstLine;
442:
443: if (startmask)
444: {
445: getbits(psrc, (pptSrc->x & 0x1f), nstart, tmpSrc)
446: putbits(tmpSrc, (pbox->x1 & 0x1f), nstart, pdst)
447: pdst++;
448: if (srcStartOver)
449: psrc++;
450: }
451:
452: nl = nlMiddle;
453: while (nl--)
454: {
455: getbits(psrc, xoffSrc, 32, tmpSrc)
456: *pdst++ = tmpSrc;
457: psrc++;
458: }
459:
460: if (endmask)
461: {
462: getbits(psrc, xoffSrc, nend, tmpSrc)
463: putbits(tmpSrc, 0, nend, pdst)
464: }
465:
466: pdstLine += widthDst;
467: psrcLine += widthSrc;
468: }
469: }
470: else /* move right to left */
471: {
472: pdstLine += (pbox->x2 >> 5);
473: psrcLine += (pptSrc->x+w >> 5);
474: /* if fetch of last partial bits from source crosses
475: a longword boundary, start at the previous longword
476: */
477: if (xoffSrc + nend >= 32)
478: --psrcLine;
479:
480: while (h--)
481: {
482: psrc = psrcLine;
483: pdst = pdstLine;
484:
485: if (endmask)
486: {
487: getbits(psrc, xoffSrc, nend, tmpSrc)
488: putbits(tmpSrc, 0, nend, pdst)
489: }
490:
491: nl = nlMiddle;
492: while (nl--)
493: {
494: --psrc;
495: getbits(psrc, xoffSrc, 32, tmpSrc)
496: *--pdst = tmpSrc;
497: }
498:
499: if (startmask)
500: {
501: if (srcStartOver)
502: --psrc;
503: --pdst;
504: getbits(psrc, (pptSrc->x & 0x1f), nstart, tmpSrc)
505: putbits(tmpSrc, (pbox->x1 & 0x1f), nstart, pdst)
506: }
507:
508: pdstLine += widthDst;
509: psrcLine += widthSrc;
510: }
511: } /* move right to left */
512: }
513: pbox++;
514: pptSrc++;
515: } /* while (nbox--) */
516: }
517: else /* do some rop */
518: {
519: while (nbox--)
520: {
521: w = pbox->x2 - pbox->x1;
522: h = pbox->y2 - pbox->y1;
523:
524: if (ydir == -1) /* start at last scanline of rectangle */
525: {
526: psrcLine = psrcBase + ((pptSrc->y+h-1) * -widthSrc);
527: pdstLine = pdstBase + ((pbox->y2-1) * -widthDst);
528: }
529: else /* start at first scanline */
530: {
531: psrcLine = psrcBase + (pptSrc->y * widthSrc);
532: pdstLine = pdstBase + (pbox->y1 * widthDst);
533: }
534:
535: /* x direction doesn't matter for < 1 longword */
536: if (w <= 32)
537: {
538: int srcBit, dstBit; /* bit offset of src and dst */
539:
540: pdstLine += (pbox->x1 >> 5);
541: psrcLine += (pptSrc->x >> 5);
542: psrc = psrcLine;
543: pdst = pdstLine;
544:
545: srcBit = pptSrc->x & 0x1f;
546: dstBit = pbox->x1 & 0x1f;
547:
548: while(h--)
549: {
550: getbits(psrc, srcBit, w, tmpSrc)
551: putbitsrop(tmpSrc, dstBit, w, pdst, alu)
552: pdst += widthDst;
553: psrc += widthSrc;
554: }
555: }
556: else
557: {
558: maskbits(pbox->x1, w, startmask, endmask, nlMiddle)
559: if (startmask)
560: nstart = 32 - (pbox->x1 & 0x1f);
561: else
562: nstart = 0;
563: if (endmask)
564: nend = pbox->x2 & 0x1f;
565: else
566: nend = 0;
567:
568: xoffSrc = ((pptSrc->x & 0x1f) + nstart) & 0x1f;
569: srcStartOver = ((pptSrc->x & 0x1f) + nstart) > 31;
570:
571: if (xdir == 1) /* move left to right */
572: {
573: pdstLine += (pbox->x1 >> 5);
574: psrcLine += (pptSrc->x >> 5);
575:
576: while (h--)
577: {
578: psrc = psrcLine;
579: pdst = pdstLine;
580:
581: if (startmask)
582: {
583: getbits(psrc, (pptSrc->x & 0x1f), nstart, tmpSrc)
584: putbitsrop(tmpSrc, (pbox->x1 & 0x1f), nstart, pdst,
585: alu)
586: pdst++;
587: if (srcStartOver)
588: psrc++;
589: }
590:
591: nl = nlMiddle;
592: while (nl--)
593: {
594: getbits(psrc, xoffSrc, 32, tmpSrc)
595: *pdst = DoRop(alu, tmpSrc, *pdst);
596: pdst++;
597: psrc++;
598: }
599:
600: if (endmask)
601: {
602: getbits(psrc, xoffSrc, nend, tmpSrc)
603: putbitsrop(tmpSrc, 0, nend, pdst, alu)
604: }
605:
606: pdstLine += widthDst;
607: psrcLine += widthSrc;
608: }
609: }
610: else /* move right to left */
611: {
612: pdstLine += (pbox->x2 >> 5);
613: psrcLine += (pptSrc->x+w >> 5);
614: /* if fetch of last partial bits from source crosses
615: a longword boundary, start at the previous longword
616: */
617: if (xoffSrc + nend >= 32)
618: --psrcLine;
619:
620: while (h--)
621: {
622: psrc = psrcLine;
623: pdst = pdstLine;
624:
625: if (endmask)
626: {
627: getbits(psrc, xoffSrc, nend, tmpSrc)
628: putbitsrop(tmpSrc, 0, nend, pdst, alu)
629: }
630:
631: nl = nlMiddle;
632: while (nl--)
633: {
634: --psrc;
635: --pdst;
636: getbits(psrc, xoffSrc, 32, tmpSrc)
637: *pdst = DoRop(alu, tmpSrc, *pdst);
638: }
639:
640: if (startmask)
641: {
642: if (srcStartOver)
643: --psrc;
644: --pdst;
645: getbits(psrc, (pptSrc->x & 0x1f), nstart, tmpSrc)
646: putbitsrop(tmpSrc, (pbox->x1 & 0x1f), nstart, pdst,
647: alu)
648: }
649:
650: pdstLine += widthDst;
651: psrcLine += widthSrc;
652: }
653: } /* move right to left */
654: }
655: pbox++;
656: pptSrc++;
657: } /* while (nbox--) */
658: }
659:
660: /* free up stuff */
661: if (pptNew1)
662: {
663: DEALLOCATE_LOCAL(pptNew1);
664: }
665: if (pboxNew1)
666: {
667: DEALLOCATE_LOCAL(pboxNew1);
668: }
669: if (pptNew2)
670: {
671: DEALLOCATE_LOCAL(pptNew2);
672: }
673: if (pboxNew2)
674: {
675: DEALLOCATE_LOCAL(pboxNew2);
676: }
677: }
678:
679:
680: /*
681: if fg == 1 and bg ==0, we can do an ordinary CopyArea.
682: if fg == bg, we can do a CopyArea with alu = ReduceRop(alu, fg)
683: if fg == 0 and bg == 1, we use the same rasterop, with
684: source operand inverted.
685:
686: CopyArea deals with all of the graphics exposure events.
687: This code depends on knowing that we can change the
688: alu in the GC without having to call ValidateGC() before calling
689: CopyArea().
690:
691: */
692:
693: void
694: mfbCopyPlane(pSrcDrawable, pDstDrawable,
695: pGC, srcx, srcy, width, height, dstx, dsty, plane)
696: DrawablePtr pSrcDrawable, pDstDrawable;
697: register GC *pGC;
698: int srcx, srcy;
699: int width, height;
700: int dstx, dsty;
701: unsigned int plane;
702: {
703: int alu;
704:
705: if (!(pGC->planemask & 1))
706: return;
707:
708: if (plane != 1)
709: return;
710:
711: if ((pGC->fgPixel == 1) && (pGC->bgPixel == 0))
712: {
713: (*pGC->CopyArea)(pSrcDrawable, pDstDrawable,
714: pGC, srcx, srcy, width, height, dstx, dsty);
715: }
716: else if (pGC->fgPixel == pGC->bgPixel)
717: {
718: alu = pGC->alu;
719: pGC->alu = ReduceRop(pGC->alu, pGC->fgPixel);
720: (*pGC->CopyArea)(pSrcDrawable, pDstDrawable,
721: pGC, srcx, srcy, width, height, dstx, dsty);
722: pGC->alu = alu;
723: }
724: else /* need to invert the src */
725: {
726: alu = pGC->alu;
727: pGC->alu = InverseAlu[alu];
728: (*pGC->CopyArea)(pSrcDrawable, pDstDrawable,
729: pGC, srcx, srcy, width, height, dstx, dsty);
730: pGC->alu = alu;
731: }
732: }
733:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.