]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/cfb/cfbtileodd.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / programs / Xserver / cfb / cfbtileodd.c
1 /*
2  * Fill odd tiled rectangles and spans.
3  * no depth dependencies.
4  */
5
6 /*
7
8 Copyright (c) 1989  X Consortium
9
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
16
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
23 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
24 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27 Except as contained in this notice, the name of the X Consortium shall not be
28 used in advertising or otherwise to promote the sale, use or other dealings
29 in this Software without prior written authorization from the X Consortium.
30 */
31
32 /* $XConsortium: cfbtileodd.c,v 1.16 94/04/17 20:29:06 dpw Exp $ */
33 /* $XFree86: xc/programs/Xserver/cfb/cfbtileodd.c,v 3.0 1996/06/29 09:05:55 dawes Exp $ */
34
35 #include "X.h"
36 #include "Xmd.h"
37 #include "servermd.h"
38 #include "gcstruct.h"
39 #include "window.h"
40 #include "pixmapstr.h"
41 #include "scrnintstr.h"
42 #include "windowstr.h"
43
44 #include "cfb.h"
45 #include "cfbmskbits.h"
46 #include "cfb8bit.h"
47
48 #include "mergerop.h"
49
50 #if PSZ == 24
51 #if PGSZ == 32
52 #define LEFTSHIFT_AMT (3)
53 #else /* PGSZ == 64 */
54 #define LEFTSHIFT_AMT (4 - PWSH)
55 #endif /* PGSZ */
56 #else /* PSZ != 24 */
57 #if PGSZ == 32
58 #define LEFTSHIFT_AMT (5 - PWSH)
59 #else /* PGSZ == 64 */
60 #define LEFTSHIFT_AMT (6 - PWSH)
61 #endif /* PGSZ */
62 #endif /* PSZ == 24*/
63
64 #define LastTileBits {\
65     tmp = bits; \
66     if (tileEndPart) \
67         bits = (*pSrc & tileEndMask) | BitRight (*pSrcLine, tileEndLeftShift); \
68     else \
69         bits = *pSrc; \
70 }
71
72 #if PSZ == 24
73 #define ResetTileBits {\
74     pSrc = pSrcLine; \
75     nlwSrc = widthSrc;\
76     if (tileEndPart) { \
77         if (4 - xoff + tileEndPart <= 4) {\
78             bits = *pSrc++; \
79             nlwSrc--; \
80         } else \
81             bits = BitLeft(tmp, tileEndLeftShift) | \
82                    BitRight(bits, tileEndRightShift); \
83         xoff = (xoff + xoffStep) & 3; \
84         leftShift = xoff << LEFTSHIFT_AMT; \
85         rightShift = PGSZ - leftShift; \
86     }\
87 }
88 #else
89 #define ResetTileBits {\
90     pSrc = pSrcLine; \
91     nlwSrc = widthSrc;\
92     if (tileEndPart) { \
93         if (PPW - xoff + tileEndPart <= PPW) {\
94             bits = *pSrc++; \
95             nlwSrc--; \
96         } else \
97             bits = BitLeft(tmp, tileEndLeftShift) | \
98                    BitRight(bits, tileEndRightShift); \
99         xoff = (xoff + xoffStep) & PIM; \
100         leftShift = xoff << LEFTSHIFT_AMT; \
101         rightShift = PGSZ - leftShift; \
102     }\
103 }
104 #endif
105
106 #define NextTileBits {\
107     if (nlwSrc == 1) {\
108         LastTileBits\
109     } else { \
110         if (nlwSrc == 0) {\
111             ResetTileBits\
112         } \
113         if (nlwSrc == 1) {\
114             LastTileBits\
115         } else {\
116             tmp = bits; \
117             bits = *pSrc++; \
118         }\
119     }\
120     nlwSrc--; \
121 }
122
123 void
124 MROP_NAME(cfbFillBoxTileOdd) (pDrawable, nBox, pBox, tile, xrot, yrot, alu, planemask)
125     DrawablePtr     pDrawable;
126     int             nBox;       /* number of boxes to fill */
127     register BoxPtr pBox;       /* pointer to list of boxes to fill */
128     PixmapPtr       tile;       /* tile */
129     int             xrot, yrot;
130     int             alu;
131     unsigned long   planemask;
132 {
133     int tileWidth;      /* width of tile in pixels */
134     int tileHeight;     /* height of the tile */
135     int widthSrc;
136
137     int widthDst;       /* width in longwords of the dest pixmap */
138     int w;              /* width of current box */
139     int h;              /* height of current box */
140     unsigned long startmask;
141     unsigned long endmask;/* masks for reggedy bits at either end of line */
142     int nlwMiddle;      /* number of longwords between sides of boxes */
143     int nlwSrc;         /* number of whole longwords in source */
144     
145     register int nlw;   /* loop version of nlwMiddle */
146     int srcy;           /* current tile y position */
147     int srcx;           /* current tile x position */
148     int xoffDst, xoffSrc;
149     int leftShift, rightShift;
150
151     MROP_DECLARE_REG()
152
153     unsigned long *pDstBase;    /* pointer to start of dest */
154     unsigned long *pDstLine;    /* poitner to start of dest box */
155     unsigned long *pSrcBase;    /* pointer to start of source */
156     unsigned long *pSrcLine;    /* pointer to start of source line */
157     register unsigned long *pDst;
158     register unsigned long *pSrc;
159     register unsigned long bits, tmp;
160     register int           nlwPart;
161     int xoffStart, xoff;
162     int leftShiftStart, rightShiftStart, nlwSrcStart;
163     unsigned long tileEndMask;
164     int tileEndLeftShift, tileEndRightShift;
165     int xoffStep;
166     int tileEndPart;
167     int needFirst;
168     unsigned long   narrow[2];
169     unsigned long   narrowMask;
170     int     narrowShift;
171     Bool    narrowTile;
172
173     MROP_INITIALIZE (alu, planemask)
174
175     tileHeight = tile->drawable.height;
176     tileWidth = tile->drawable.width;
177     widthSrc = tile->devKind / PGSZB;
178     narrowTile = FALSE;
179     if (widthSrc == 1)
180     {
181         narrowShift = tileWidth;
182         narrowMask = cfbendpartial [tileWidth];
183         tileWidth *= 2;
184         widthSrc = 2;
185         narrowTile = TRUE;
186     }
187     pSrcBase = (unsigned long *)tile->devPrivate.ptr;
188
189     cfbGetLongWidthAndPointer (pDrawable, widthDst, pDstBase)
190
191 #if PSZ == 24
192     tileEndPart = (4 - tileWidth) & 3;
193     tileEndMask = cfbendpartial[tileWidth & 3];
194 #else
195     tileEndPart = tileWidth & PIM;
196     tileEndMask = cfbendpartial[tileEndPart];
197 #endif /* PSZ == 24 */
198     tileEndLeftShift = (tileEndPart) << LEFTSHIFT_AMT;
199     tileEndRightShift = PGSZ - tileEndLeftShift;
200 #if PSZ == 24
201     xoffStep = 4 - tileEndPart;
202 #else
203     xoffStep = PPW - tileEndPart;
204 #endif /* PSZ == 24 */
205     /*
206      * current assumptions: tile > 32 bits wide.
207      */
208     while (nBox--)
209     {
210         w = pBox->x2 - pBox->x1;
211         h = pBox->y2 - pBox->y1;
212         modulus (pBox->x1 - xrot, tileWidth, srcx);
213         modulus (pBox->y1 - yrot, tileHeight, srcy);
214 #if PSZ == 24
215         xoffDst = (4 - pBox->x1) & 3;
216         if (w == 1  &&  (xoffDst == 0  ||  xoffDst == 1))
217 #else
218         xoffDst = pBox->x1 & PIM;
219         if (xoffDst + w < PPW)
220 #endif
221         {
222             maskpartialbits(pBox->x1, w, startmask);
223             endmask = 0;
224             nlwMiddle = 0;
225         }
226         else
227         {
228             maskbits (pBox->x1, w, startmask, endmask, nlwMiddle)
229         }
230 #if PSZ == 24
231         pDstLine = pDstBase + (pBox->y1 * widthDst) + ((pBox->x1*3) >> 2);
232 #else
233         pDstLine = pDstBase + (pBox->y1 * widthDst) + (pBox->x1 >> PWSH);
234 #endif
235         pSrcLine = pSrcBase + (srcy * widthSrc);
236 #if PSZ == 24
237         xoffSrc = (4 - srcx) & 3;
238 #else
239         xoffSrc = srcx & PIM;
240 #endif
241         if (xoffSrc >= xoffDst)
242         {
243             xoffStart = xoffSrc - xoffDst;
244             needFirst = 1;
245         }
246         else
247         {
248 #if PSZ == 24
249             xoffStart = 4 - (xoffDst - xoffSrc);
250 #else
251             xoffStart = PPW - (xoffDst - xoffSrc);
252 #endif
253             needFirst = 0;
254         }
255         leftShiftStart = (xoffStart) << LEFTSHIFT_AMT;
256         rightShiftStart = PGSZ - leftShiftStart;
257 #if PSZ == 24
258         nlwSrcStart = widthSrc - ((srcx*3) >> 2);
259 #else
260         nlwSrcStart = widthSrc - (srcx >> PWSH);
261 #endif
262         while (h--)
263         {
264             /* XXX only works when narrowShift >= PPW/2 */
265             if (narrowTile)
266             {
267                 tmp = pSrcBase[srcy] & narrowMask; /* source width == 1 */
268                 narrow[0] = tmp | SCRRIGHT (tmp, narrowShift);
269 #if PSZ == 24
270                 narrow[1] = BitLeft (tmp, 8) |
271                             BitRight(tmp, 16);
272 #else
273                 narrow[1] = SCRLEFT (tmp, PPW - narrowShift) |
274                             SCRRIGHT(tmp, 2 * narrowShift - PPW);
275 #endif
276                 pSrcLine = narrow;
277             }
278             xoff = xoffStart;
279             leftShift = leftShiftStart;
280             rightShift = rightShiftStart;
281             nlwSrc = nlwSrcStart;
282 #if PSZ == 24
283             pSrc = pSrcLine + ((srcx * 3) >> 2);
284 #else
285             pSrc = pSrcLine + (srcx >> PWSH);
286 #endif
287             pDst = pDstLine;
288             bits = 0;
289             if (needFirst)
290             {
291                 NextTileBits
292             }
293             if (startmask)
294             {
295                 NextTileBits
296                 tmp = BitLeft(tmp, leftShift);
297                 if (rightShift != PGSZ)
298                     tmp |= BitRight(bits,rightShift);
299                 *pDst = MROP_MASK (tmp, *pDst, startmask);
300                 ++pDst;
301             }
302             nlw = nlwMiddle;
303             while (nlw)
304             {
305 #if MROP == Mcopy
306                 if (nlwSrc > 1)
307                 {
308                     nlwPart = nlw;
309                     if (nlwPart >= nlwSrc)
310                         nlwPart = nlwSrc - 1;
311                     nlw -= nlwPart;
312                     nlwSrc -= nlwPart;
313                     if (rightShift != PGSZ)
314                     {
315                         while (nlwPart--)
316                         {
317                             tmp = bits;
318                             bits = *pSrc++;
319                             *pDst = MROP_SOLID(BitLeft(tmp, leftShift) |
320                                               BitRight (bits, rightShift),
321                                               *pDst);
322                             ++pDst;
323                         }
324                     }
325                     else
326                     {
327                         if (nlwPart)
328                         {
329                             *pDst = MROP_SOLID (bits, *pDst);
330                             ++pDst;
331                             nlwPart--;
332                             while (nlwPart--)
333                             {
334                                 *pDst = MROP_SOLID(*pSrc, *pDst);
335                                 ++pDst; ++pSrc;
336                             }
337                             bits = *pSrc++;
338                         }
339                     }
340                 }
341                 else
342 #endif
343                 {
344                     NextTileBits
345                     if (rightShift != PGSZ)
346                     {
347                         *pDst = MROP_SOLID(BitLeft(tmp, leftShift) |
348                                            BitRight(bits, rightShift),
349                                            *pDst);
350                     }
351                     else
352                     {
353                         *pDst = MROP_SOLID (tmp, *pDst);
354                     }
355                     ++pDst;
356                     nlw--;
357                 }
358             }
359             if (endmask)
360             {
361                 NextTileBits
362                 if (rightShift == PGSZ)
363                     bits = 0;
364                 *pDst = MROP_MASK (BitLeft(tmp, leftShift) |
365                                    BitRight(bits,rightShift),
366                                    *pDst, endmask);
367             }
368             pDstLine += widthDst;
369             pSrcLine += widthSrc;
370             if (++srcy == tileHeight)
371             {
372                 srcy = 0;
373                 pSrcLine = pSrcBase;
374             }
375         }
376         pBox++;
377     }
378 }
379
380 void
381 MROP_NAME(cfbFillSpanTileOdd) (pDrawable, n, ppt, pwidth, tile, xrot, yrot, alu, planemask)
382     DrawablePtr pDrawable;
383     int         n;
384     DDXPointPtr ppt;
385     int         *pwidth;
386     PixmapPtr   tile;
387     int         xrot, yrot;
388     int         alu;
389     unsigned long   planemask;
390 {
391     int tileWidth;      /* width of tile in pixels */
392     int tileHeight;     /* height of the tile */
393     int widthSrc;
394
395     int widthDst;               /* width in longwords of the dest pixmap */
396     int w;              /* width of current span */
397     unsigned long startmask;
398     unsigned long endmask;      /* masks for reggedy bits at either end of line */
399     int nlwSrc;         /* number of whole longwords in source */
400     
401     register int nlw;   /* loop version of nlwMiddle */
402     int srcy;           /* current tile y position */
403     int srcx;           /* current tile x position */
404     int xoffDst, xoffSrc;
405     int leftShift, rightShift;
406
407     MROP_DECLARE_REG()
408
409     unsigned long *pDstBase;    /* pointer to start of dest */
410     unsigned long *pDstLine;    /* poitner to start of dest box */
411     unsigned long *pSrcBase;    /* pointer to start of source */
412     unsigned long *pSrcLine;    /* pointer to start of source line */
413     register unsigned long *pDst;
414     register unsigned long *pSrc;
415     register unsigned long bits, tmp;
416     register int           nlwPart;
417     int xoffStart, xoff;
418     int leftShiftStart, rightShiftStart, nlwSrcStart;
419     unsigned long tileEndMask;
420     int tileEndLeftShift, tileEndRightShift;
421     int xoffStep;
422     int tileEndPart;
423     int needFirst;
424     unsigned long   narrow[2];
425     unsigned long   narrowMask;
426     int     narrowShift;
427     Bool    narrowTile;
428
429     MROP_INITIALIZE (alu, planemask)
430
431     tileHeight = tile->drawable.height;
432     tileWidth = tile->drawable.width;
433     widthSrc = tile->devKind / PGSZB;
434     narrowTile = FALSE;
435     if (widthSrc == 1)
436     {
437         narrowShift = tileWidth;
438         narrowMask = cfbendpartial [tileWidth];
439         tileWidth *= 2;
440         widthSrc = 2;
441         narrowTile = TRUE;
442     }
443     pSrcBase = (unsigned long *)tile->devPrivate.ptr;
444
445     cfbGetLongWidthAndPointer (pDrawable, widthDst, pDstBase)
446
447 #if PSZ == 24
448     tileEndPart = (4 - tileWidth) & 3;
449     tileEndMask = cfbendpartial[tileWidth & 3];
450 #else
451     tileEndPart = tileWidth & PIM;
452     tileEndMask = cfbendpartial[tileEndPart];
453 #endif
454     tileEndLeftShift = (tileEndPart) << LEFTSHIFT_AMT;
455     tileEndRightShift = PGSZ - tileEndLeftShift;
456 #if PSZ == 24
457     xoffStep = 4 - tileEndPart;
458 #else
459     xoffStep = PPW - tileEndPart;
460 #endif
461     while (n--)
462     {
463         w = *pwidth++;
464         modulus (ppt->x - xrot, tileWidth, srcx);
465         modulus (ppt->y - yrot, tileHeight, srcy);
466 #if PSZ == 24
467         xoffDst = (4 - ppt->x) & 3;
468         if (w == 1  &&  (xoffDst == 0  ||  xoffDst == 1))
469 #else
470         xoffDst = ppt->x & PIM;
471         if (xoffDst + w < PPW)
472 #endif
473         {
474             maskpartialbits(ppt->x, w, startmask);
475             endmask = 0;
476             nlw = 0;
477         }
478         else
479         {
480             maskbits (ppt->x, w, startmask, endmask, nlw)
481         }
482 #if PSZ == 24
483         pDstLine = pDstBase + (ppt->y * widthDst)  + ((ppt->x *3)>> 2);
484 #else
485         pDstLine = pDstBase + (ppt->y * widthDst) + (ppt->x >> PWSH);
486 #endif
487         pSrcLine = pSrcBase + (srcy * widthSrc);
488 #if PSZ == 24
489         xoffSrc = (4 - srcx) & 3;
490 #else
491         xoffSrc = srcx & PIM;
492 #endif
493         if (xoffSrc >= xoffDst)
494         {
495             xoffStart = xoffSrc - xoffDst;
496             needFirst = 1;
497         }
498         else
499         {
500 #if PSZ == 24
501             xoffStart = 4 - (xoffDst - xoffSrc);
502 #else
503             xoffStart = PPW - (xoffDst - xoffSrc);
504 #endif
505             needFirst = 0;
506         }
507         leftShiftStart = (xoffStart) << LEFTSHIFT_AMT;
508         rightShiftStart = PGSZ - leftShiftStart;
509 #if PSZ == 24
510         nlwSrcStart = widthSrc - ((srcx*3) >> 2);
511 #else
512         nlwSrcStart = widthSrc - (srcx >> PWSH);
513 #endif
514         /* XXX only works when narrowShift >= PPW/2 */
515         if (narrowTile)
516         {
517             tmp = pSrcBase[srcy] & narrowMask;  /* source width == 1 */
518             narrow[0] = tmp | SCRRIGHT (tmp, narrowShift);
519 #if PSZ == 24
520             narrow[1] = BitLeft (tmp, 8) |
521                         BitRight(tmp, 16);
522 #else
523             narrow[1] = SCRLEFT (tmp, PPW - narrowShift) |
524                         SCRRIGHT(tmp, 2 * narrowShift - PPW);
525 #endif
526             pSrcLine = narrow;
527         }
528         xoff = xoffStart;
529         leftShift = leftShiftStart;
530         rightShift = rightShiftStart;
531         nlwSrc = nlwSrcStart;
532 #if PSZ == 24
533         pSrc = pSrcLine + ((srcx * 3) >> 2);
534 #else
535         pSrc = pSrcLine + (srcx >> PWSH);
536 #endif
537         pDst = pDstLine;
538         bits = 0;
539         if (needFirst)
540         {
541             NextTileBits
542         }
543         if (startmask)
544         {
545             NextTileBits
546             tmp = BitLeft(tmp, leftShift);
547             if (rightShift != PGSZ)
548                 tmp |= BitRight(bits,rightShift);
549             *pDst = MROP_MASK (tmp, *pDst, startmask);
550             ++pDst;
551         }
552         while (nlw)
553         {
554 #if MROP == Mcopy
555             if (nlwSrc > 1)
556             {
557                 nlwPart = nlw;
558                 if (nlwPart >= nlwSrc)
559                     nlwPart = nlwSrc - 1;
560                 nlw -= nlwPart;
561                 nlwSrc -= nlwPart;
562                 if (rightShift != PGSZ)
563                 {
564                     while (nlwPart--)
565                     {
566                         tmp = bits;
567                         bits = *pSrc++;
568                         *pDst = MROP_SOLID(BitLeft(tmp, leftShift) |
569                                           BitRight (bits, rightShift),
570                                           *pDst);
571                         ++pDst;
572                     }
573                 }
574                 else
575                 {
576                     if (nlwPart)
577                     {
578                         *pDst = MROP_SOLID (bits, *pDst);
579                         ++pDst;
580                         nlwPart--;
581                         while (nlwPart--)
582                         {
583                             *pDst = MROP_SOLID(*pSrc, *pDst);
584                             ++pDst; ++pSrc;
585                         }
586                         bits = *pSrc++;
587                     }
588                 }
589             }
590             else
591 #endif
592             {
593                 NextTileBits
594                 if (rightShift != PGSZ)
595                 {
596                     *pDst = MROP_SOLID(BitLeft(tmp, leftShift) |
597                                        BitRight(bits, rightShift),
598                                        *pDst);
599                     ++pDst;
600                 }
601                 else
602                 {
603                     *pDst = MROP_SOLID (tmp, *pDst);
604                     ++pDst;
605                 }
606                 nlw--;
607             }
608         }
609         if (endmask)
610         {
611             NextTileBits
612             if (rightShift == PGSZ)
613                 bits = 0;
614             *pDst = MROP_MASK (BitLeft(tmp, leftShift) |
615                                BitRight(bits,rightShift),
616                                *pDst, endmask);
617         }
618         ppt++;
619     }
620 }
621
622 # include "fastblt.h"
623
624 #define IncSrcPtr   psrc++; if (!--srcRemaining) { srcRemaining = widthSrc; psrc = psrcStart; }
625
626 void
627 MROP_NAME(cfbFillBoxTile32s) (pDrawable, nBox, pBox, tile, xrot, yrot, alu, planemask)
628     DrawablePtr     pDrawable;
629     int             nBox;       /* number of boxes to fill */
630     register BoxPtr pBox;       /* pointer to list of boxes to fill */
631     PixmapPtr       tile;       /* tile */
632     int             xrot, yrot;
633     int             alu;
634     unsigned long   planemask;
635 {
636     int tileWidth;      /* width of tile */
637     int tileHeight;     /* height of the tile */
638     int widthSrc;       /* width in longwords of the source tile */
639
640     int widthDst;       /* width in longwords of the dest pixmap */
641     int w;              /* width of current box */
642     int h;              /* height of current box */
643     unsigned long startmask;
644     unsigned long endmask;/* masks for reggedy bits at either end of line */
645     int nlMiddle;       /* number of longwords between sides of boxes */
646     
647     register int nl;    /* loop version of nlMiddle */
648     int srcy;           /* current tile y position */
649     int srcx;           /* current tile x position */
650     int srcRemaining;   /* number of longwords remaining in source */
651     int xoffDst, xoffSrc;
652     int srcStart;       /* number of longwords source offset at left of box */
653     int leftShift, rightShift;
654
655     MROP_DECLARE_REG()
656
657     unsigned long           *pdstBase;  /* pointer to start of dest */
658     unsigned long           *pdstLine;  /* poitner to start of dest box */
659     unsigned long           *psrcBase;  /* pointer to start of source */
660     unsigned long           *psrcLine;  /* pointer to fetch point of source */
661     unsigned long           *psrcStart; /* pointer to start of source line */
662     register unsigned long  *pdst;
663     register unsigned long  *psrc;
664     register unsigned long  bits, bits1;
665     register int            nlTemp;
666
667     MROP_INITIALIZE (alu, planemask)
668
669     psrcBase = (unsigned long *)tile->devPrivate.ptr;
670     tileHeight = tile->drawable.height;
671     tileWidth = tile->drawable.width;
672 #if PSZ == 24
673     widthSrc = tile->devKind / PGSZB;
674 #else
675     widthSrc = tileWidth >> PWSH;
676 #endif
677
678     cfbGetLongWidthAndPointer (pDrawable, widthDst, pdstBase)
679
680     while (nBox--)
681     {
682         w = pBox->x2 - pBox->x1;
683         h = pBox->y2 - pBox->y1;
684
685         /* set up source */
686         modulus (pBox->x1 - xrot, tileWidth, srcx);
687         modulus (pBox->y1 - yrot, tileHeight, srcy);
688 #if PSZ == 24
689         xoffSrc = (4 - srcx) & 3;
690         srcStart = (srcx * 3) >> 2;
691 #else
692         xoffSrc = srcx & PIM;
693         srcStart = (srcx >> PWSH);
694 #endif
695         psrcStart = psrcBase + (srcy * widthSrc);
696         psrcLine = psrcStart + srcStart;
697
698         /* set up dest */
699 #if PSZ == 24
700         xoffDst = (4 - pBox->x1) & 3;
701         pdstLine = pdstBase + (pBox->y1 * widthDst) + ((pBox->x1*3) >> 2);
702 #else
703         xoffDst = pBox->x1 & PIM;
704         pdstLine = pdstBase + (pBox->y1 * widthDst) + (pBox->x1 >> PWSH);
705 #endif
706         /* set up masks */
707 #if PSZ == 24
708         if (w == 1  &&  (xoffDst == 0  ||  xoffDst == 1))
709 #else
710         if (xoffDst + w < PPW)
711 #endif
712         {
713             maskpartialbits(pBox->x1, w, startmask);
714             endmask = 0;
715             nlMiddle = 0;
716         }
717         else
718         {
719             maskbits (pBox->x1, w, startmask, endmask, nlMiddle)
720         }
721         if (xoffSrc == xoffDst)
722         {
723             while (h--)
724             {
725                 psrc = psrcLine;
726                 pdst = pdstLine;
727                 srcRemaining = widthSrc - srcStart;
728                 if (startmask)
729                 {
730                     *pdst = MROP_MASK (*psrc, *pdst, startmask);
731                     pdst++;
732                     IncSrcPtr
733                 }
734                 nlTemp = nlMiddle;
735                 while (nlTemp)
736                 {
737                     nl = nlTemp;
738                     if (nl > srcRemaining)
739                         nl = srcRemaining;
740
741                     nlTemp -= nl;
742                     srcRemaining -= nl;
743
744 #if MROP == Mcopy
745 #ifdef LARGE_INSTRUCTION_CACHE
746 #ifdef FAST_CONSTANT_OFFSET_MODE
747
748                     psrc += nl & (UNROLL-1);
749                     pdst += nl & (UNROLL-1);
750
751 #define BodyOdd(n) pdst[-n] = MROP_SOLID (psrc[-n], pdst[-n]);
752 #define BodyEven(n) pdst[-n] = MROP_SOLID (psrc[-n], pdst[-n]);
753
754 #define LoopReset \
755 pdst += UNROLL; \
756 psrc += UNROLL;
757
758 #else
759
760 #define BodyOdd(n)  *pdst = MROP_SOLID (*psrc, *pdst); pdst++; psrc++;
761 #define BodyEven(n) BodyOdd(n)
762
763 #define LoopReset   ;
764
765 #endif
766                     PackedLoop
767
768 #undef BodyOdd
769 #undef BodyEven
770 #undef LoopReset
771
772 #else
773                     DuffL(nl, label1,
774                             *pdst = MROP_SOLID (*psrc, *pdst);
775                             pdst++; psrc++;)
776 #endif
777 #else
778                     while (nl--) {
779                             *pdst = MROP_SOLID (*psrc, *pdst);
780                             pdst++; psrc++;
781                     }
782 #endif
783                     if (!srcRemaining)
784                     {
785                         srcRemaining = widthSrc;
786                         psrc = psrcStart;
787                     }
788                 }
789                 if (endmask)
790                 {
791                     *pdst = MROP_MASK (*psrc, *pdst, endmask);
792                 }
793                 pdstLine += widthDst;
794                 psrcLine += widthSrc;
795                 psrcStart += widthSrc;
796                 if (++srcy == tileHeight)
797                 {
798                     psrcStart = psrcBase;
799                     psrcLine = psrcStart + srcStart;
800                     srcy = 0;
801                 }
802             }
803         }
804         else
805         {
806             if (xoffSrc > xoffDst)
807             {
808                 leftShift = (xoffSrc - xoffDst) << LEFTSHIFT_AMT;
809                 rightShift = PGSZ - leftShift;
810             }
811             else
812             {
813                 rightShift = (xoffDst - xoffSrc) << LEFTSHIFT_AMT;
814                 leftShift = PGSZ - rightShift;
815             }
816             while (h--)
817             {
818                 psrc = psrcLine;
819                 pdst = pdstLine;
820                 bits = 0;
821                 srcRemaining = widthSrc - srcStart;
822                 if (xoffSrc > xoffDst)
823                 {
824                     bits = *psrc;
825                     IncSrcPtr
826                 }
827                 if (startmask)
828                 {
829                     bits1 = BitLeft(bits,leftShift);
830                     bits = *psrc;
831                     IncSrcPtr
832                     bits1 |= BitRight(bits,rightShift);
833                     *pdst = MROP_MASK(bits1, *pdst, startmask);
834                     pdst++;
835                 }
836                 nlTemp = nlMiddle;
837                 while (nlTemp)
838                 {
839                     nl = nlTemp;
840                     if (nl > srcRemaining)
841                         nl = srcRemaining;
842
843                     nlTemp -= nl;
844                     srcRemaining -= nl;
845     
846 #if MROP == Mcopy
847 #ifdef LARGE_INSTRUCTION_CACHE
848                     bits1 = bits;
849     
850 #ifdef FAST_CONSTANT_OFFSET_MODE
851     
852                     psrc += nl & (UNROLL-1);
853                     pdst += nl & (UNROLL-1);
854     
855 #define BodyOdd(n) \
856     bits = psrc[-n]; \
857     pdst[-n] = MROP_SOLID(BitLeft(bits1, leftShift) | BitRight(bits, rightShift), pdst[-n]);
858     
859 #define BodyEven(n) \
860     bits1 = psrc[-n]; \
861     pdst[-n] = MROP_SOLID(BitLeft(bits, leftShift) | BitRight(bits1, rightShift), pdst[-n]);
862     
863 #define LoopReset \
864     pdst += UNROLL; \
865     psrc += UNROLL;
866     
867 #else
868     
869 #define BodyOdd(n) \
870     bits = *psrc++; \
871     *pdst = MROP_SOLID(BitLeft(bits1, leftShift) | BitRight(bits, rightShift), *pdst); \
872     pdst++;
873                    
874 #define BodyEven(n) \
875     bits1 = *psrc++; \
876     *pdst = MROP_SOLID(BitLeft(bits, leftShift) | BitRight(bits1, rightShift), *pdst); \
877     pdst++;
878     
879 #define LoopReset   ;
880     
881 #endif  /* !FAST_CONSTANT_OFFSET_MODE */
882     
883                     PackedLoop
884     
885 #undef BodyOdd
886 #undef BodyEven
887 #undef LoopReset
888     
889 #else
890                     DuffL (nl,label2,
891                         bits1 = BitLeft(bits, leftShift);
892                         bits = *psrc++;
893                         *pdst = MROP_SOLID (bits1 | BitRight(bits, rightShift), *pdst);
894                         pdst++;
895                     )
896 #endif
897 #else
898                     while (nl--) {
899                         bits1 = BitLeft(bits, leftShift);
900                         bits = *psrc++;
901                         *pdst = MROP_SOLID (bits1 | BitRight(bits, rightShift), *pdst);
902                         pdst++;
903                     }
904 #endif
905                     if (!srcRemaining)
906                     {
907                         srcRemaining = widthSrc;
908                         psrc = psrcStart;
909                     }
910                 }
911
912                 if (endmask)
913                 {
914                     bits1 = BitLeft(bits, leftShift);
915                     if (BitLeft(endmask, rightShift))
916                     {
917                         bits = *psrc;
918                         bits1 |= BitRight(bits, rightShift);
919                     }
920                     *pdst = MROP_MASK (bits1, *pdst, endmask);
921                 }
922                 pdstLine += widthDst;
923                 psrcLine += widthSrc;
924                 psrcStart += widthSrc;
925                 if (++srcy == tileHeight)
926                 {
927                     psrcStart = psrcBase;
928                     psrcLine = psrcStart + srcStart;
929                     srcy = 0;
930                 }
931             }
932         }
933         pBox++;
934     }
935 }
936
937 void
938 MROP_NAME(cfbFillSpanTile32s) (pDrawable, n, ppt, pwidth, tile, xrot, yrot, alu, planemask)
939     DrawablePtr pDrawable;
940     int         n;
941     DDXPointPtr ppt;
942     int         *pwidth;
943     PixmapPtr   tile;
944     int         xrot, yrot;
945     int         alu;
946     unsigned long   planemask;
947 {
948     int tileWidth;      /* width of tile */
949     int tileHeight;     /* height of the tile */
950     int widthSrc;       /* width in longwords of the source tile */
951
952     int widthDst;       /* width in longwords of the dest pixmap */
953     int w;              /* width of current box */
954     unsigned long startmask;
955     unsigned long endmask;/* masks for reggedy bits at either end of line */
956     int nlMiddle;       /* number of longwords between sides of boxes */
957     
958     register int nl;    /* loop version of nlMiddle */
959     int srcy;           /* current tile y position */
960     int srcx;           /* current tile x position */
961     int srcRemaining;   /* number of longwords remaining in source */
962     int xoffDst, xoffSrc;
963     int srcStart;       /* number of longwords source offset at left of box */
964     int leftShift, rightShift;
965
966     MROP_DECLARE_REG()
967
968     unsigned long           *pdstBase;  /* pointer to start of dest */
969     unsigned long           *pdstLine;  /* poitner to start of dest box */
970     unsigned long           *psrcBase;  /* pointer to start of source */
971     unsigned long           *psrcLine;  /* pointer to fetch point of source */
972     unsigned long           *psrcStart; /* pointer to start of source line */
973     register unsigned long  *pdst;
974     register unsigned long  *psrc;
975     register unsigned long  bits, bits1;
976     register int            nlTemp;
977
978     MROP_INITIALIZE (alu, planemask)
979
980     psrcBase = (unsigned long *)tile->devPrivate.ptr;
981     tileHeight = tile->drawable.height;
982     tileWidth = tile->drawable.width;
983 #if PSZ == 24
984     widthSrc = tile->devKind / PGSZB;
985 #else
986     widthSrc = tileWidth >> PWSH;
987 #endif
988
989     cfbGetLongWidthAndPointer (pDrawable, widthDst, pdstBase)
990
991     while (n--)
992     {
993         w = *pwidth++;
994
995         /* set up source */
996         modulus (ppt->x - xrot, tileWidth, srcx);
997         modulus (ppt->y - yrot, tileHeight, srcy);
998 #if PSZ == 24
999         xoffSrc = (4 - srcx) & 3;
1000         srcStart = (srcx * 3) >> 2;
1001 #else
1002         xoffSrc = srcx & PIM;
1003         srcStart = (srcx >> PWSH);
1004 #endif
1005         psrcStart = psrcBase + (srcy * widthSrc);
1006         psrcLine = psrcStart + srcStart;
1007
1008         /* set up dest */
1009 #if PSZ == 24
1010         xoffDst = (4 - ppt->x) & 3;
1011         pdstLine = pdstBase + (ppt->y * widthDst) + ((ppt->x *3) >> 2);
1012         /* set up masks */
1013         if (w == 1  &&  (xoffDst == 0  ||  xoffDst == 1))
1014 #else
1015         xoffDst = ppt->x & PIM;
1016         pdstLine = pdstBase + (ppt->y * widthDst) + (ppt->x >> PWSH);
1017         /* set up masks */
1018         if (xoffDst + w < PPW)
1019 #endif
1020         {
1021             maskpartialbits(ppt->x, w, startmask);
1022             endmask = 0;
1023             nlMiddle = 0;
1024         }
1025         else
1026         {
1027             maskbits (ppt->x, w, startmask, endmask, nlMiddle)
1028         }
1029
1030         if (xoffSrc == xoffDst)
1031         {
1032             psrc = psrcLine;
1033             pdst = pdstLine;
1034             srcRemaining = widthSrc - srcStart;
1035             if (startmask)
1036             {
1037                 *pdst = MROP_MASK (*psrc, *pdst, startmask);
1038                 pdst++;
1039                 IncSrcPtr
1040             }
1041             nlTemp = nlMiddle;
1042             while (nlTemp)
1043             {
1044                 nl = nlTemp;
1045                 if (nl > srcRemaining)
1046                     nl = srcRemaining;
1047
1048                 nlTemp -= nl;
1049                 srcRemaining -= nl;
1050
1051 #if MROP == Mcopy
1052 #ifdef LARGE_INSTRUCTION_CACHE
1053 #ifdef FAST_CONSTANT_OFFSET_MODE
1054
1055                 psrc += nl & (UNROLL-1);
1056                 pdst += nl & (UNROLL-1);
1057
1058 #define BodyOdd(n) pdst[-n] = MROP_SOLID (psrc[-n], pdst[-n]);
1059 #define BodyEven(n) pdst[-n] = MROP_SOLID (psrc[-n], pdst[-n]);
1060
1061 #define LoopReset \
1062 pdst += UNROLL; \
1063 psrc += UNROLL;
1064
1065 #else
1066
1067 #define BodyOdd(n)  *pdst = MROP_SOLID (*psrc, *pdst); pdst++; psrc++;
1068 #define BodyEven(n) BodyOdd(n)
1069
1070 #define LoopReset   ;
1071
1072 #endif
1073                 PackedLoop
1074
1075 #undef BodyOdd
1076 #undef BodyEven
1077 #undef LoopReset
1078
1079 #else
1080                 DuffL(nl, label1,
1081                         *pdst = MROP_SOLID (*psrc, *pdst);
1082                         pdst++; psrc++;)
1083 #endif
1084 #else
1085                 while (nl--) {
1086                         *pdst = MROP_SOLID (*psrc, *pdst);
1087                         pdst++; psrc++;
1088                 }
1089 #endif
1090                 if (!srcRemaining)
1091                 {
1092                     srcRemaining = widthSrc;
1093                     psrc = psrcStart;
1094                 }
1095             }
1096             if (endmask)
1097             {
1098                 *pdst = MROP_MASK (*psrc, *pdst, endmask);
1099             }
1100         }
1101         else
1102         {
1103             if (xoffSrc > xoffDst)
1104             {
1105                 leftShift = (xoffSrc - xoffDst) << LEFTSHIFT_AMT;
1106                 rightShift = PGSZ - leftShift;
1107             }
1108             else
1109             {
1110                 rightShift = (xoffDst - xoffSrc) << LEFTSHIFT_AMT;
1111                 leftShift = PGSZ - rightShift;
1112             }
1113             psrc = psrcLine;
1114             pdst = pdstLine;
1115             bits = 0;
1116             srcRemaining = widthSrc - srcStart;
1117             if (xoffSrc > xoffDst)
1118             {
1119                 bits = *psrc;
1120                 IncSrcPtr
1121             }
1122             if (startmask)
1123             {
1124                 bits1 = BitLeft(bits,leftShift);
1125                 bits = *psrc;
1126                 IncSrcPtr
1127                 bits1 |= BitRight(bits,rightShift);
1128                 *pdst = MROP_MASK(bits1, *pdst, startmask);
1129                 pdst++;
1130             }
1131             nlTemp = nlMiddle;
1132             while (nlTemp)
1133             {
1134                 nl = nlTemp;
1135                 if (nl > srcRemaining)
1136                     nl = srcRemaining;
1137
1138                 nlTemp -= nl;
1139                 srcRemaining -= nl;
1140
1141 #if MROP == Mcopy
1142 #ifdef LARGE_INSTRUCTION_CACHE
1143                 bits1 = bits;
1144
1145 #ifdef FAST_CONSTANT_OFFSET_MODE
1146
1147                 psrc += nl & (UNROLL-1);
1148                 pdst += nl & (UNROLL-1);
1149
1150 #define BodyOdd(n) \
1151 bits = psrc[-n]; \
1152 pdst[-n] = MROP_SOLID(BitLeft(bits1, leftShift) | BitRight(bits, rightShift), pdst[-n]);
1153
1154 #define BodyEven(n) \
1155 bits1 = psrc[-n]; \
1156 pdst[-n] = MROP_SOLID(BitLeft(bits, leftShift) | BitRight(bits1, rightShift), pdst[-n]);
1157
1158 #define LoopReset \
1159 pdst += UNROLL; \
1160 psrc += UNROLL;
1161
1162 #else
1163
1164 #define BodyOdd(n) \
1165 bits = *psrc++; \
1166 *pdst = MROP_SOLID(BitLeft(bits1, leftShift) | BitRight(bits, rightShift), *pdst); \
1167 pdst++;
1168                
1169 #define BodyEven(n) \
1170 bits1 = *psrc++; \
1171 *pdst = MROP_SOLID(BitLeft(bits, leftShift) | BitRight(bits1, rightShift), *pdst); \
1172 pdst++;
1173
1174 #define LoopReset   ;
1175
1176 #endif  /* !FAST_CONSTANT_OFFSET_MODE */
1177
1178                 PackedLoop
1179
1180 #undef BodyOdd
1181 #undef BodyEven
1182 #undef LoopReset
1183
1184 #else
1185                 DuffL (nl,label2,
1186                     bits1 = BitLeft(bits, leftShift);
1187                     bits = *psrc++;
1188                     *pdst = MROP_SOLID (bits1 | BitRight(bits, rightShift), *pdst);
1189                     pdst++;
1190                 )
1191 #endif
1192 #else
1193                 while (nl--) {
1194                     bits1 = BitLeft(bits,leftShift);
1195                     bits = *psrc++;
1196                     *pdst = MROP_SOLID(bits1|BitRight(bits,rightShift), *pdst);
1197                     pdst++;
1198                 }
1199 #endif
1200                 if (!srcRemaining)
1201                 {
1202                     srcRemaining = widthSrc;
1203                     psrc = psrcStart;
1204                 }
1205             }
1206
1207             if (endmask)
1208             {
1209                 bits1 = BitLeft(bits, leftShift);
1210                 if (BitLeft(endmask, rightShift))
1211                 {
1212                     bits = *psrc;
1213                     bits1 |= BitRight(bits, rightShift);
1214                 }
1215                 *pdst = MROP_MASK (bits1, *pdst, endmask);
1216             }
1217         }
1218         ppt++;
1219     }
1220 }