]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/mfb/mfbfillarc.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / programs / Xserver / mfb / mfbfillarc.c
1 /************************************************************
2
3 Copyright (c) 1989  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
28 /* $XConsortium: mfbfillarc.c /main/16 1995/12/06 16:54:28 dpw $ */
29
30 #include "X.h"
31 #include "Xprotostr.h"
32 #include "miscstruct.h"
33 #include "gcstruct.h"
34 #include "pixmapstr.h"
35 #include "scrnintstr.h"
36 #include "mfb.h"
37 #include "maskbits.h"
38 #include "mifillarc.h"
39 #include "mi.h"
40
41 static void
42 mfbFillEllipseSolid(pDraw, arc, rop)
43     DrawablePtr pDraw;
44     xArc *arc;
45     register int rop;
46 {
47     int x, y, e;
48     int yk, xk, ym, xm, dx, dy, xorg, yorg;
49     register int slw;
50     miFillArcRec info;
51     PixelType *addrlt, *addrlb;
52     register PixelType *addrl;
53     register int n;
54     int nlwidth;
55     register int xpos;
56     PixelType startmask, endmask;
57     int nlmiddle;
58
59     mfbGetPixelWidthAndPointer(pDraw, nlwidth, addrlt);
60     miFillArcSetup(arc, &info);
61     MIFILLARCSETUP();
62     xorg += pDraw->x;
63     yorg += pDraw->y;
64     addrlb = addrlt;
65     addrlt += nlwidth * (yorg - y);
66     addrlb += nlwidth * (yorg + y + dy);
67     while (y)
68     {
69         addrlt += nlwidth;
70         addrlb -= nlwidth;
71         MIFILLARCSTEP(slw);
72         if (!slw)
73             continue;
74         xpos = xorg - x;
75         addrl = mfbScanlineOffset(addrlt, (xpos >> PWSH));
76         if (((xpos & PIM) + slw) < PPW)
77         {
78             maskpartialbits(xpos, slw, startmask);
79             if (rop == RROP_BLACK)
80                 *addrl &= ~startmask;
81             else if (rop == RROP_WHITE)
82                 *addrl |= startmask;
83             else
84                 *addrl ^= startmask;
85             if (miFillArcLower(slw))
86             {
87                 addrl = mfbScanlineOffset(addrlb, (xpos >> PWSH));
88                 if (rop == RROP_BLACK)
89                     *addrl &= ~startmask;
90                 else if (rop == RROP_WHITE)
91                     *addrl |= startmask;
92                 else
93                     *addrl ^= startmask;
94             }
95             continue;
96         }
97         maskbits(xpos, slw, startmask, endmask, nlmiddle);
98         if (startmask)
99         {
100             if (rop == RROP_BLACK)
101                 *addrl++ &= ~startmask;
102             else if (rop == RROP_WHITE)
103                 *addrl++ |= startmask;
104             else
105                 *addrl++ ^= startmask;
106         }
107         n = nlmiddle;
108         if (rop == RROP_BLACK)
109             while (n--)
110                 *addrl++ = 0;
111         else if (rop == RROP_WHITE)
112             while (n--)
113                 *addrl++ = ~0;
114         else
115             while (n--)
116                 *addrl++ ^= ~0;
117         if (endmask)
118         {
119             if (rop == RROP_BLACK)
120                 *addrl &= ~endmask;
121             else if (rop == RROP_WHITE)
122                 *addrl |= endmask;
123             else
124                 *addrl ^= endmask;
125         }
126         if (!miFillArcLower(slw))
127             continue;
128         addrl = mfbScanlineOffset(addrlb, (xpos >> PWSH));
129         if (startmask)
130         {
131             if (rop == RROP_BLACK)
132                 *addrl++ &= ~startmask;
133             else if (rop == RROP_WHITE)
134                 *addrl++ |= startmask;
135             else
136                 *addrl++ ^= startmask;
137         }
138         n = nlmiddle;
139         if (rop == RROP_BLACK)
140             while (n--)
141                 *addrl++ = 0;
142         else if (rop == RROP_WHITE)
143             while (n--)
144                 *addrl++ = ~0;
145         else
146             while (n--)
147                 *addrl++ ^= ~0;
148         if (endmask)
149         {
150             if (rop == RROP_BLACK)
151                 *addrl &= ~endmask;
152             else if (rop == RROP_WHITE)
153                 *addrl |= endmask;
154             else
155                 *addrl ^= endmask;
156         }
157     }
158 }
159
160 #define FILLSPAN(xl,xr,addr) \
161     if (xr >= xl) \
162     { \
163         width = xr - xl + 1; \
164         addrl = mfbScanlineOffset(addr, (xl >> PWSH)); \
165         if (((xl & PIM) + width) < PPW) \
166         { \
167             maskpartialbits(xl, width, startmask); \
168             if (rop == RROP_BLACK) \
169                 *addrl &= ~startmask; \
170             else if (rop == RROP_WHITE) \
171                 *addrl |= startmask; \
172             else \
173                 *addrl ^= startmask; \
174         } \
175         else \
176         { \
177             maskbits(xl, width, startmask, endmask, nlmiddle); \
178             if (startmask) \
179             { \
180                 if (rop == RROP_BLACK) \
181                     *addrl++ &= ~startmask; \
182                 else if (rop == RROP_WHITE) \
183                     *addrl++ |= startmask; \
184                 else \
185                     *addrl++ ^= startmask; \
186             } \
187             n = nlmiddle; \
188             if (rop == RROP_BLACK) \
189                 while (n--) \
190                     *addrl++ = 0; \
191             else if (rop == RROP_WHITE) \
192                 while (n--) \
193                     *addrl++ = ~0; \
194             else \
195                 while (n--) \
196                     *addrl++ ^= ~0; \
197             if (endmask) \
198             { \
199                 if (rop == RROP_BLACK) \
200                     *addrl &= ~endmask; \
201                 else if (rop == RROP_WHITE) \
202                     *addrl |= endmask; \
203                 else \
204                     *addrl ^= endmask; \
205             } \
206         } \
207     }
208
209 #define FILLSLICESPANS(flip,addr) \
210     if (!flip) \
211     { \
212         FILLSPAN(xl, xr, addr); \
213     } \
214     else \
215     { \
216         xc = xorg - x; \
217         FILLSPAN(xc, xr, addr); \
218         xc += slw - 1; \
219         FILLSPAN(xl, xc, addr); \
220     }
221
222 static void
223 mfbFillArcSliceSolidCopy(pDraw, pGC, arc, rop)
224     DrawablePtr pDraw;
225     GCPtr pGC;
226     xArc *arc;
227     register int rop;
228 {
229     register PixelType *addrl;
230     register int n;
231     int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
232     register int x, y, e;
233     miFillArcRec info;
234     miArcSliceRec slice;
235     int xl, xr, xc;
236     PixelType *addrlt, *addrlb;
237     int nlwidth;
238     int width;
239     PixelType startmask, endmask;
240     int nlmiddle;
241
242     mfbGetPixelWidthAndPointer(pDraw, nlwidth, addrlt);
243     miFillArcSetup(arc, &info);
244     miFillArcSliceSetup(arc, &slice, pGC);
245     MIFILLARCSETUP();
246     xorg += pDraw->x;
247     yorg += pDraw->y;
248     addrlb = addrlt;
249     addrlt = mfbScanlineDeltaNoBankSwitch(addrlt, yorg - y, nlwidth);
250     addrlb = mfbScanlineDeltaNoBankSwitch(addrlb, yorg + y + dy, nlwidth);
251     slice.edge1.x += pDraw->x;
252     slice.edge2.x += pDraw->x;
253     while (y > 0)
254     {
255         mfbScanlineIncNoBankSwitch(addrlt, nlwidth);
256         mfbScanlineIncNoBankSwitch(addrlb, -nlwidth);
257         MIFILLARCSTEP(slw);
258         MIARCSLICESTEP(slice.edge1);
259         MIARCSLICESTEP(slice.edge2);
260         if (miFillSliceUpper(slice))
261         {
262             MIARCSLICEUPPER(xl, xr, slice, slw);
263             FILLSLICESPANS(slice.flip_top, addrlt);
264         }
265         if (miFillSliceLower(slice))
266         {
267             MIARCSLICELOWER(xl, xr, slice, slw);
268             FILLSLICESPANS(slice.flip_bot, addrlb);
269         }
270     }
271 }
272
273 void
274 mfbPolyFillArcSolid(pDraw, pGC, narcs, parcs)
275     register DrawablePtr pDraw;
276     GCPtr       pGC;
277     int         narcs;
278     xArc        *parcs;
279 {
280     mfbPrivGC *priv;
281     register xArc *arc;
282     register int i;
283     BoxRec box;
284     int x2, y2;
285     RegionPtr cclip;
286     int rop;
287
288     priv = (mfbPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr;
289     rop = priv->rop;
290     if ((rop == RROP_NOP) || !(pGC->planemask & 1))
291         return;
292     cclip = priv->pCompositeClip;
293     for (arc = parcs, i = narcs; --i >= 0; arc++)
294     {
295         if (miFillArcEmpty(arc))
296             continue;
297         if (miCanFillArc(arc))
298         {
299             box.x1 = arc->x + pDraw->x;
300             box.y1 = arc->y + pDraw->y;
301             /*
302              * Because box.x2 and box.y2 get truncated to 16 bits, and the
303              * RECT_IN_REGION test treats the resulting number as a signed
304              * integer, the RECT_IN_REGION test alone can go the wrong way.
305              * This can result in a server crash because the rendering
306              * routines in this file deal directly with cpu addresses
307              * of pixels to be stored, and do not clip or otherwise check
308              * that all such addresses are within their respective pixmaps.
309              * So we only allow the RECT_IN_REGION test to be used for
310              * values that can be expressed correctly in a signed short.
311              */
312             x2 = box.x1 + (int)arc->width + 1;
313             box.x2 = x2;
314             y2 = box.y1 + (int)arc->height + 1;
315             box.y2 = y2;
316             if ( (x2 <= MAXSHORT) && (y2 <= MAXSHORT) &&
317                     (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
318             {
319                 if ((arc->angle2 >= FULLCIRCLE) ||
320                     (arc->angle2 <= -FULLCIRCLE))
321                     mfbFillEllipseSolid(pDraw, arc, rop);
322                 else
323                     mfbFillArcSliceSolidCopy(pDraw, pGC, arc, rop);
324                 continue;
325             }
326         }
327         miPolyFillArc(pDraw, pGC, 1, arc);
328     }
329 }