]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/mfb/mfbzerarc.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / programs / Xserver / mfb / mfbzerarc.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: mfbzerarc.c /main/21 1995/12/06 16:55:48 dpw $ */
29 /* $XFree86: xc/programs/Xserver/mfb/mfbzerarc.c,v 3.1 1996/01/05 13:19:46 dawes Exp $ */
30
31 /* Derived from:
32  * "Algorithm for drawing ellipses or hyperbolae with a digital plotter"
33  * by M. L. V. Pitteway
34  * The Computer Journal, November 1967, Volume 10, Number 3, pp. 282-289
35  */
36
37 #include "X.h"
38 #include "Xprotostr.h"
39 #include "miscstruct.h"
40 #include "gcstruct.h"
41 #include "pixmapstr.h"
42 #include "scrnintstr.h"
43 #include "mfb.h"
44 #include "maskbits.h"
45 #include "mizerarc.h"
46 #include "mi.h"
47
48 /*
49  * Note: LEFTMOST must be the bit leftmost in the actual screen
50  * representation.  This depends also on the IMAGE_BYTE_ORDER.
51  * LONG2CHARS() takes care of the re-ordering as required. (DHD)
52  */
53 #if (BITMAP_BIT_ORDER == MSBFirst)
54 #define LEFTMOST        ((PixelType) LONG2CHARS(((unsigned long)1 << PLST)))
55 #else
56 #define LEFTMOST        ((PixelType) LONG2CHARS(1))
57 #endif
58
59 #define PixelateWhite(addr,yoff,xoff) \
60     *mfbScanlineOffset(addr, (yoff)+((xoff)>>PWSH)) |= \
61         SCRRIGHT (LEFTMOST, ((xoff) & PIM))
62 #define PixelateBlack(addr,yoff,xoff) \
63     *mfbScanlineOffset(addr, (yoff)+((xoff)>>PWSH)) &= \
64         ~(SCRRIGHT (LEFTMOST, ((xoff) & PIM)))
65
66 #define Pixelate(base,yoff,xoff) \
67 { \
68     paddr = mfbScanlineOffset(base, (yoff) + ((xoff)>>PWSH)); \
69     pmask = SCRRIGHT(LEFTMOST, (xoff) & PIM); \
70     *paddr = (*paddr & ~pmask) | (pixel & pmask); \
71 }
72
73 #define DoPix(bit,base,yoff,xoff) if (mask & bit) Pixelate(base,yoff,xoff);
74
75 static void
76 mfbZeroArcSS(pDraw, pGC, arc)
77     DrawablePtr pDraw;
78     GCPtr pGC;
79     xArc *arc;
80 {
81     miZeroArcRec info;
82     Bool do360;
83     register int x, y, a, b, d, mask;
84     register int k1, k3, dx, dy;
85     PixelType *addrl;
86     PixelType *yorgl, *yorgol;
87     PixelType pixel;
88     int nlwidth, yoffset, dyoffset;
89     PixelType pmask;
90     register PixelType *paddr;
91
92     if (((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->rop ==
93         RROP_BLACK)
94         pixel = 0;
95     else
96         pixel = ~0;
97
98     mfbGetPixelWidthAndPointer(pDraw, nlwidth, addrl);
99     do360 = miZeroArcSetup(arc, &info, TRUE);
100     yorgl = addrl + ((info.yorg + pDraw->y) * nlwidth);
101     yorgol = addrl + ((info.yorgo + pDraw->y) * nlwidth);
102     info.xorg += pDraw->x;
103     info.xorgo += pDraw->x;
104     MIARCSETUP();
105     yoffset = y ? nlwidth : 0;
106     dyoffset = 0;
107     mask = info.initialMask;
108     if (!(arc->width & 1))
109     {
110         DoPix(2, yorgl, 0, info.xorgo);
111         DoPix(8, yorgol, 0, info.xorgo);
112     }
113     if (!info.end.x || !info.end.y)
114     {
115         mask = info.end.mask;
116         info.end = info.altend;
117     }
118     if (do360 && (arc->width == arc->height) && !(arc->width & 1))
119     {
120         int xoffset = nlwidth;
121         PixelType *yorghl = mfbScanlineDeltaNoBankSwitch(yorgl, info.h, nlwidth);
122         int xorghp = info.xorg + info.h;
123         int xorghn = info.xorg - info.h;
124
125         if (pixel)
126         {
127             while (1)
128             {
129                 PixelateWhite(yorgl, yoffset, info.xorg + x);
130                 PixelateWhite(yorgl, yoffset, info.xorg - x);
131                 PixelateWhite(yorgol, -yoffset, info.xorg - x);
132                 PixelateWhite(yorgol, -yoffset, info.xorg + x);
133                 if (a < 0)
134                     break;
135                 PixelateWhite(yorghl, -xoffset, xorghp - y);
136                 PixelateWhite(yorghl, -xoffset, xorghn + y);
137                 PixelateWhite(yorghl, xoffset, xorghn + y);
138                 PixelateWhite(yorghl, xoffset, xorghp - y);
139                 xoffset += nlwidth;
140                 MIARCCIRCLESTEP(yoffset += nlwidth;);
141             }
142         }
143         else
144         {
145             while (1)
146             {
147                 PixelateBlack(yorgl, yoffset, info.xorg + x);
148                 PixelateBlack(yorgl, yoffset, info.xorg - x);
149                 PixelateBlack(yorgol, -yoffset, info.xorg - x);
150                 PixelateBlack(yorgol, -yoffset, info.xorg + x);
151                 if (a < 0)
152                     break;
153                 PixelateBlack(yorghl, -xoffset, xorghp - y);
154                 PixelateBlack(yorghl, -xoffset, xorghn + y);
155                 PixelateBlack(yorghl, xoffset, xorghn + y);
156                 PixelateBlack(yorghl, xoffset, xorghp - y);
157                 xoffset += nlwidth;
158                 MIARCCIRCLESTEP(yoffset += nlwidth;);
159             }
160         }
161         x = info.w;
162         yoffset = info.h * nlwidth;
163     }
164     else if (do360)
165     {
166         while (y < info.h || x < info.w)
167         {
168             MIARCOCTANTSHIFT(dyoffset = nlwidth;);
169             Pixelate(yorgl, yoffset, info.xorg + x);
170             Pixelate(yorgl, yoffset, info.xorgo - x);
171             Pixelate(yorgol, -yoffset, info.xorgo - x);
172             Pixelate(yorgol, -yoffset, info.xorg + x);
173             MIARCSTEP(yoffset += dyoffset;, yoffset += nlwidth;);
174         }
175     }
176     else
177     {
178         while (y < info.h || x < info.w)
179         {
180             MIARCOCTANTSHIFT(dyoffset = nlwidth;);
181             if ((x == info.start.x) || (y == info.start.y))
182             {
183                 mask = info.start.mask;
184                 info.start = info.altstart;
185             }
186             DoPix(1, yorgl, yoffset, info.xorg + x);
187             DoPix(2, yorgl, yoffset, info.xorgo - x);
188             DoPix(4, yorgol, -yoffset, info.xorgo - x);
189             DoPix(8, yorgol, -yoffset, info.xorg + x);
190             if ((x == info.end.x) || (y == info.end.y))
191             {
192                 mask = info.end.mask;
193                 info.end = info.altend;
194             }
195             MIARCSTEP(yoffset += dyoffset;, yoffset += nlwidth;);
196         }
197     }
198     if ((x == info.start.x) || (y == info.start.y))
199         mask = info.start.mask;
200     DoPix(1, yorgl, yoffset, info.xorg + x);
201     DoPix(4, yorgol, -yoffset, info.xorgo - x);
202     if (arc->height & 1)
203     {
204         DoPix(2, yorgl, yoffset, info.xorgo - x);
205         DoPix(8, yorgol, -yoffset, info.xorg + x);
206     }
207 }
208
209 void
210 mfbZeroPolyArcSS(pDraw, pGC, narcs, parcs)
211     DrawablePtr pDraw;
212     GCPtr       pGC;
213     int         narcs;
214     xArc        *parcs;
215 {
216     register xArc *arc;
217     register int i;
218     BoxRec box;
219     int x2, y2;
220     RegionPtr cclip;
221
222     if (!pGC->planemask & 1)
223         return;
224     cclip = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip;
225     for (arc = parcs, i = narcs; --i >= 0; arc++)
226     {
227         if (miCanZeroArc(arc))
228         {
229             box.x1 = arc->x + pDraw->x;
230             box.y1 = arc->y + pDraw->y;
231             /*
232              * Because box.x2 and box.y2 get truncated to 16 bits, and the
233              * RECT_IN_REGION test treats the resulting number as a signed
234              * integer, the RECT_IN_REGION test alone can go the wrong way.
235              * This can result in a server crash because the rendering
236              * routines in this file deal directly with cpu addresses
237              * of pixels to be stored, and do not clip or otherwise check
238              * that all such addresses are within their respective pixmaps.
239              * So we only allow the RECT_IN_REGION test to be used for
240              * values that can be expressed correctly in a signed short.
241              */
242             x2 = box.x1 + (int)arc->width + 1;
243             box.x2 = x2;
244             y2 = box.y1 + (int)arc->height + 1;
245             box.y2 = y2;
246             if ( (x2 <= MAXSHORT) && (y2 <= MAXSHORT) &&
247                     (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
248                 mfbZeroArcSS(pDraw, pGC, arc);
249             else
250                 miZeroPolyArc(pDraw, pGC, 1, arc);
251         }
252         else
253             miPolyArc(pDraw, pGC, 1, arc);
254     }
255 }