]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/mfb/mfbsetsp.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / programs / Xserver / mfb / mfbsetsp.c
1 /* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
2 /***********************************************************
3
4 Copyright (c) 1987  X Consortium
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23 Except as contained in this notice, the name of the X Consortium shall not be
24 used in advertising or otherwise to promote the sale, use or other dealings
25 in this Software without prior written authorization from the X Consortium.
26
27
28 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
29
30                         All Rights Reserved
31
32 Permission to use, copy, modify, and distribute this software and its 
33 documentation for any purpose and without fee is hereby granted, 
34 provided that the above copyright notice appear in all copies and that
35 both that copyright notice and this permission notice appear in 
36 supporting documentation, and that the name of Digital not be
37 used in advertising or publicity pertaining to distribution of the
38 software without specific, written prior permission.  
39
40 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
41 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
42 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
43 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
44 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
45 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
46 SOFTWARE.
47
48 ******************************************************************/
49 /* $XConsortium: mfbsetsp.c,v 5.8 94/04/17 20:28:34 dpw Exp $ */
50
51 #include "X.h"
52 #include "Xmd.h"
53
54 #include "misc.h"
55 #include "regionstr.h"
56 #include "gcstruct.h"
57 #include "windowstr.h"
58 #include "pixmapstr.h"
59 #include "scrnintstr.h"
60
61 #include "mfb.h"
62 #include "maskbits.h"
63
64 #include "servermd.h"
65
66
67 /* mfbSetScanline -- copies the bits from psrc to the drawable starting at
68  * (xStart, y) and continuing to (xEnd, y).  xOrigin tells us where psrc 
69  * starts on the scanline. (I.e., if this scanline passes through multiple
70  * boxes, we may not want to start grabbing bits at psrc but at some offset
71  * further on.) 
72  */
73 mfbSetScanline(y, xOrigin, xStart, xEnd, psrc, alu, pdstBase, widthDst)
74     int                 y;
75     int                 xOrigin;        /* where this scanline starts */
76     int                 xStart;         /* first bit to use from scanline */
77     int                 xEnd;           /* last bit to use from scanline + 1 */
78     register PixelType  *psrc;
79     register int        alu;            /* raster op */
80     PixelType           *pdstBase;      /* start of the drawable */
81     int                 widthDst;       /* width of drawable in words */
82 {
83     int                 w;              /* width of scanline in bits */
84     register PixelType  *pdst;          /* where to put the bits */
85     register PixelType  tmpSrc;         /* scratch buffer to collect bits in */
86     int                 dstBit;         /* offset in bits from beginning of 
87                                          * word */
88     register int        nstart;         /* number of bits from first partial */
89     register int        nend;           /* " " last partial word */
90     int         offSrc;
91     PixelType   startmask, endmask;
92     int         nlMiddle, nl;
93
94     pdst = mfbScanline(pdstBase, xStart, y, widthDst);
95     psrc += (xStart - xOrigin) >> PWSH;
96     offSrc = (xStart - xOrigin) & PIM;
97     w = xEnd - xStart;
98     dstBit = xStart & PIM;
99
100     if (dstBit + w <= PPW) 
101     { 
102         getandputrop(psrc, offSrc, dstBit, w, pdst, alu)
103     } 
104     else 
105     { 
106
107         maskbits(xStart, w, startmask, endmask, nlMiddle);
108         if (startmask) 
109             nstart = PPW - dstBit; 
110         else 
111             nstart = 0; 
112         if (endmask) 
113             nend = xEnd & PIM; 
114         else 
115             nend = 0; 
116         if (startmask) 
117         { 
118             getandputrop(psrc, offSrc, dstBit, nstart, pdst, alu)
119             pdst++; 
120             offSrc += nstart;
121             if (offSrc > PLST)
122             {
123                 psrc++;
124                 offSrc -= PPW;
125             }
126         } 
127         nl = nlMiddle; 
128         while (nl--) 
129         { 
130             getbits(psrc, offSrc, PPW, tmpSrc);
131             DoRop(*pdst, alu, tmpSrc, *pdst); 
132             pdst++; 
133             psrc++; 
134         } 
135         if (endmask) 
136         { 
137             getandputrop0(psrc, offSrc, nend, pdst, alu);
138         } 
139          
140     } 
141 }
142
143 \f
144
145 /* SetSpans -- for each span copy pwidth[i] bits from psrc to pDrawable at
146  * ppt[i] using the raster op from the GC.  If fSorted is TRUE, the scanlines
147  * are in increasing Y order.
148  * Source bit lines are server scanline padded so that they always begin
149  * on a word boundary.
150  */ 
151 void
152 mfbSetSpans(pDrawable, pGC, pcharsrc, ppt, pwidth, nspans, fSorted)
153     DrawablePtr         pDrawable;
154     GCPtr               pGC;
155     char                *pcharsrc;
156     register DDXPointPtr ppt;
157     int                 *pwidth;
158     int                 nspans;
159     int                 fSorted;
160 {
161     PixelType           *psrc = (PixelType *)pcharsrc;
162     PixelType           *pdstBase;      /* start of dst bitmap */
163     int                 widthDst;       /* width of bitmap in words */
164     register BoxPtr     pbox, pboxLast, pboxTest;
165     register DDXPointPtr pptLast;
166     int                 alu;
167     RegionPtr           prgnDst;
168     int                 xStart, xEnd;
169     int                 yMax;
170
171     alu = pGC->alu;
172     prgnDst = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip;
173
174     pptLast = ppt + nspans;
175
176     yMax = pDrawable->y + (int) pDrawable->height;
177     mfbGetPixelWidthAndPointer(pDrawable, widthDst, pdstBase);
178
179     pbox =  REGION_RECTS(prgnDst);
180     pboxLast = pbox + REGION_NUM_RECTS(prgnDst);
181
182     if(fSorted)
183     {
184     /* scan lines sorted in ascending order. Because they are sorted, we
185      * don't have to check each scanline against each clip box.  We can be
186      * sure that this scanline only has to be clipped to boxes at or after the
187      * beginning of this y-band 
188      */
189         pboxTest = pbox;
190         while(ppt < pptLast)
191         {
192             pbox = pboxTest;
193             if(ppt->y >= yMax)
194                 break;
195             while(pbox < pboxLast)
196             {
197                 if(pbox->y1 > ppt->y)
198                 {
199                     /* scanline is before clip box */
200                     break;
201                 }
202                 else if(pbox->y2 <= ppt->y)
203                 {
204                     /* clip box is before scanline */
205                     pboxTest = ++pbox;
206                     continue;
207                 }
208                 else if(pbox->x1 > ppt->x + *pwidth) 
209                 {
210                     /* clip box is to right of scanline */
211                     break;
212                 }
213                 else if(pbox->x2 <= ppt->x)
214                 {
215                     /* scanline is to right of clip box */
216                     pbox++;
217                     continue;
218                 }
219
220                 /* at least some of the scanline is in the current clip box */
221                 xStart = max(pbox->x1, ppt->x);
222                 xEnd = min(ppt->x + *pwidth, pbox->x2);
223                 mfbSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu,
224                                pdstBase, widthDst);
225                 if(ppt->x + *pwidth <= pbox->x2)
226                 {
227                     /* End of the line, as it were */
228                     break;
229                 }
230                 else
231                     pbox++;
232             }
233             /* We've tried this line against every box; it must be outside them
234              * all.  move on to the next point */
235             ppt++;
236             psrc += PixmapWidthInPadUnits(*pwidth, 1);
237             pwidth++;
238         }
239     }
240     else
241     {
242     /* scan lines not sorted. We must clip each line against all the boxes */
243         while(ppt < pptLast)
244         {
245             if(ppt->y >= 0 && ppt->y < yMax)
246             {
247                 
248                 for(pbox = REGION_RECTS(prgnDst); pbox< pboxLast; pbox++)
249                 {
250                     if(pbox->y1 > ppt->y)
251                     {
252                         /* rest of clip region is above this scanline,
253                          * skip it */
254                         break;
255                     }
256                     if(pbox->y2 <= ppt->y)
257                     {
258                         /* clip box is below scanline */
259                         pbox++;
260                         break;
261                     }
262                     if(pbox->x1 <= ppt->x + *pwidth &&
263                        pbox->x2 > ppt->x)
264                     {
265                         xStart = max(pbox->x1, ppt->x);
266                         xEnd = min(pbox->x2, ppt->x + *pwidth);
267                         mfbSetScanline(ppt->y, ppt->x, xStart, xEnd, 
268                                        psrc, alu, pdstBase, widthDst);
269                     }
270
271                 }
272             }
273         psrc += PixmapWidthInPadUnits(*pwidth, 1);
274         ppt++;
275         pwidth++;
276         }
277     }
278 }