]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/mfb/mfbclip.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / programs / Xserver / mfb / mfbclip.c
1 /***********************************************************
2
3 Copyright (c) 1987  X Consortium
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 Except as contained in this notice, the name of the X Consortium shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from the X Consortium.
25
26
27 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
28
29                         All Rights Reserved
30
31 Permission to use, copy, modify, and distribute this software and its 
32 documentation for any purpose and without fee is hereby granted, 
33 provided that the above copyright notice appear in all copies and that
34 both that copyright notice and this permission notice appear in 
35 supporting documentation, and that the name of Digital not be
36 used in advertising or publicity pertaining to distribution of the
37 software without specific, written prior permission.  
38
39 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
40 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
41 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
42 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
43 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
44 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
45 SOFTWARE.
46
47 ******************************************************************/
48 /* $XConsortium: mfbclip.c,v 5.6 94/04/17 20:28:19 dpw Exp $ */
49 #include "X.h"
50 #include "miscstruct.h"
51 #include "pixmapstr.h"
52 #include "scrnintstr.h"
53 #include "regionstr.h"
54 #include "gc.h"
55 #include "maskbits.h"
56 #include "mi.h"
57
58 #define ADDRECT(reg,r,fr,rx1,ry1,rx2,ry2)                       \
59 if (((rx1) < (rx2)) && ((ry1) < (ry2)) &&                       \
60     (!((reg)->data->numRects &&                                 \
61        ((r-1)->y1 == (ry1)) &&                                  \
62        ((r-1)->y2 == (ry2)) &&                                  \
63        ((r-1)->x1 <= (rx1)) &&                                  \
64        ((r-1)->x2 >= (rx2)))))                                  \
65 {                                                               \
66     if ((reg)->data->numRects == (reg)->data->size)             \
67     {                                                           \
68         miRectAlloc(reg, 1);                                    \
69         fr = REGION_BOXPTR(reg);                                \
70         r = fr + (reg)->data->numRects;                         \
71     }                                                           \
72     r->x1 = (rx1);                                              \
73     r->y1 = (ry1);                                              \
74     r->x2 = (rx2);                                              \
75     r->y2 = (ry2);                                              \
76     (reg)->data->numRects++;                                    \
77     if(r->x1 < (reg)->extents.x1)                               \
78         (reg)->extents.x1 = r->x1;                              \
79     if(r->x2 > (reg)->extents.x2)                               \
80         (reg)->extents.x2 = r->x2;                              \
81     r++;                                                        \
82 }
83
84 /* Convert bitmap clip mask into clipping region. 
85  * First, goes through each line and makes boxes by noting the transitions
86  * from 0 to 1 and 1 to 0.
87  * Then it coalesces the current line with the previous if they have boxes
88  * at the same X coordinates.
89  */
90 RegionPtr
91 mfbPixmapToRegion(pPix)
92     PixmapPtr   pPix;
93 {
94     register RegionPtr  pReg;
95     register PixelType  *pw, w;
96     register int        ib;
97     int                 width, h, base, rx1, crects;
98     PixelType           *pwLineEnd;
99     int                 irectPrevStart, irectLineStart;
100     register BoxPtr     prectO, prectN;
101     BoxPtr              FirstRect, rects, prectLineStart;
102     Bool                fInBox, fSame;
103     register PixelType  mask0 = mask[0];
104     PixelType           *pwLine;
105     int                 nWidth;
106
107     pReg = REGION_CREATE(pPix->drawable.pScreen, NULL, 1);
108     if(!pReg)
109         return NullRegion;
110     FirstRect = REGION_BOXPTR(pReg);
111     rects = FirstRect;
112
113     pwLine = (PixelType *) pPix->devPrivate.ptr;
114     nWidth = pPix->devKind / PGSZB;
115
116     width = pPix->drawable.width;
117     pReg->extents.x1 = width - 1;
118     pReg->extents.x2 = 0;
119     irectPrevStart = -1;
120     for(h = 0; h < pPix->drawable.height; h++)
121     {
122         pw = pwLine;
123         pwLine += nWidth;
124         irectLineStart = rects - FirstRect;
125         /* If the Screen left most bit of the word is set, we're starting in
126          * a box */
127         if(*pw & mask0)
128         {
129             fInBox = TRUE;
130             rx1 = 0;
131         }
132         else
133             fInBox = FALSE;
134         /* Process all words which are fully in the pixmap */
135         pwLineEnd = pw + (width >> PWSH);
136         for (base = 0; pw < pwLineEnd; base += PPW)
137         {
138             w = *pw++;
139             if (fInBox)
140             {
141                 if (!~w)
142                     continue;
143             }
144             else
145             {
146                 if (!w)
147                     continue;
148             }
149             for(ib = 0; ib < PPW; ib++)
150             {
151                 /* If the Screen left most bit of the word is set, we're
152                  * starting a box */
153                 if(w & mask0)
154                 {
155                     if(!fInBox)
156                     {
157                         rx1 = base + ib;
158                         /* start new box */
159                         fInBox = TRUE;
160                     }
161                 }
162                 else
163                 {
164                     if(fInBox)
165                     {
166                         /* end box */
167                         ADDRECT(pReg, rects, FirstRect,
168                                 rx1, h, base + ib, h + 1);
169                         fInBox = FALSE;
170                     }
171                 }
172                 /* Shift the word VISUALLY left one. */
173                 w = SCRLEFT(w, 1);
174             }
175         }
176         if(width & PIM)
177         {
178             /* Process final partial word on line */
179             w = *pw++;
180             for(ib = 0; ib < (width & PIM); ib++)
181             {
182                 /* If the Screen left most bit of the word is set, we're
183                  * starting a box */
184                 if(w & mask0)
185                 {
186                     if(!fInBox)
187                     {
188                         rx1 = base + ib;
189                         /* start new box */
190                         fInBox = TRUE;
191                     }
192                 }
193                 else
194                 {
195                     if(fInBox)
196                     {
197                         /* end box */
198                         ADDRECT(pReg, rects, FirstRect,
199                                 rx1, h, base + ib, h + 1);
200                         fInBox = FALSE;
201                     }
202                 }
203                 /* Shift the word VISUALLY left one. */
204                 w = SCRLEFT(w, 1);
205             }
206         }
207         /* If scanline ended with last bit set, end the box */
208         if(fInBox)
209         {
210             ADDRECT(pReg, rects, FirstRect,
211                     rx1, h, base + (width & PIM), h + 1);
212         }
213         /* if all rectangles on this line have the same x-coords as
214          * those on the previous line, then add 1 to all the previous  y2s and 
215          * throw away all the rectangles from this line 
216          */
217         fSame = FALSE;
218         if(irectPrevStart != -1)
219         {
220             crects = irectLineStart - irectPrevStart;
221             if(crects == ((rects - FirstRect) - irectLineStart))
222             {
223                 prectO = FirstRect + irectPrevStart;
224                 prectN = prectLineStart = FirstRect + irectLineStart;
225                 fSame = TRUE;
226                 while(prectO < prectLineStart)
227                 {
228                     if((prectO->x1 != prectN->x1) || (prectO->x2 != prectN->x2))
229                     {
230                           fSame = FALSE;
231                           break;
232                     }
233                     prectO++;
234                     prectN++;
235                 }
236                 if (fSame)
237                 {
238                     prectO = FirstRect + irectPrevStart;
239                     while(prectO < prectLineStart)
240                     {
241                         prectO->y2 += 1;
242                         prectO++;
243                     }
244                     rects -= crects;
245                     pReg->data->numRects -= crects;
246                 }
247             }
248         }
249         if(!fSame)
250             irectPrevStart = irectLineStart;
251     }
252     if (!pReg->data->numRects)
253         pReg->extents.x1 = pReg->extents.x2 = 0;
254     else
255     {
256         pReg->extents.y1 = REGION_BOXPTR(pReg)->y1;
257         pReg->extents.y2 = REGION_END(pReg)->y2;
258         if (pReg->data->numRects == 1)
259         {
260             xfree(pReg->data);
261             pReg->data = (RegDataPtr)NULL;
262         }
263     }
264 #ifdef DEBUG
265     if (!miValidRegion(pReg))
266         FatalError("Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__);
267 #endif
268     return(pReg);
269 }