1/************************************************************
2
3Copyright 1989, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25********************************************************/
26
27#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#include <limits.h>
32#include <X11/X.h>
33#include "gcstruct.h"
34#include "windowstr.h"
35#include "pixmapstr.h"
36#include "regionstr.h"
37#include <X11/Xprotostr.h>
38#include "regionstr.h"
39#include "mizerarc.h"
40#include "mi.h"
41#include "scrnintstr.h"
42#ifdef HAVE_XAA_H
43#include "xaa.h"
44#include "xaalocal.h"
45#endif
46#include "xf86.h"
47#include "xf86_OSproc.h"
48
49#include "xf86Pci.h"
50
51#include "mga.h"
52#include "mga_reg.h"
53#include "mga_macros.h"
54
55
56#define DRAW_POINT(x, y) { \
57	tmp = x; \
58	OUTREG(MGAREG_FXBNDRY, (tmp) | (((tmp) + 1) << 16)); \
59	OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, ((y) << 16) | 1); \
60}
61
62#ifdef USE_XAA
63static void
64MGAZeroArc(
65    DrawablePtr pDraw,
66    GCPtr pGC,
67    xArc *arc
68){
69    int yoffset, dyoffset, x, y, a, b, d, mask, k1, k3, dx, dy, tmp;
70    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
71    ScrnInfoPtr pScrn = infoRec->pScrn;
72    MGAPtr pMga = MGAPTR(pScrn);
73    miZeroArcRec info;
74    Bool do360;
75    DDXPointRec org, orgo;
76
77    CHECK_DMA_QUIESCENT( pMga, infoRec->pScrn );
78
79    (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel,
80		pGC->alu, pGC->planemask);
81
82    do360 = miZeroArcSetup(arc, &info, TRUE);
83    org.y = info.yorg + pDraw->y;
84    org.x = 0;
85    orgo.y = info.yorgo + pDraw->y;
86    orgo.x = 0;
87    info.xorg += pDraw->x;
88    info.xorgo += pDraw->x;
89
90    MIARCSETUP();
91    yoffset = y ? 1 : 0;
92    dyoffset = 0;
93    mask = info.initialMask;
94    if (!(arc->width & 1)) {
95	WAITFIFO(4);
96	if (mask & 2)
97	    DRAW_POINT(info.xorgo, org.y);
98	if (mask & 8)
99	    DRAW_POINT(info.xorgo, orgo.y);
100    }
101    if (!info.end.x || !info.end.y) {
102	mask = info.end.mask;
103	info.end = info.altend;
104    }
105    if (do360 && (arc->width == arc->height) && !(arc->width & 1)) {
106        int xoffset = 1;
107	DDXPointRec orghb, orgohb;
108
109	orghb.y = org.y + info.h;
110	orghb.x = org.x + info.xorg;
111	orgohb.y = orghb.y;
112	orgohb.x = orghb.x - info.h;
113
114	org.x += info.xorg;
115	orgo.x += info.xorg;
116	orghb.x += info.h;
117	while (1) {
118	    WAITFIFO(16);
119	    DRAW_POINT(org.x + x, org.y + yoffset);
120	    DRAW_POINT(org.x - x, org.y + yoffset);
121	    DRAW_POINT(orgo.x - x, orgo.y - yoffset);
122	    DRAW_POINT(orgo.x + x, orgo.y - yoffset);
123	    if (a < 0) break;
124	    DRAW_POINT(orghb.x - y, orghb.y - xoffset);
125	    DRAW_POINT(orgohb.x + y, orgohb.y - xoffset);
126	    DRAW_POINT(orgohb.x + y, orgohb.y + xoffset);
127	    DRAW_POINT(orghb.x - y, orghb.y + xoffset);
128	    xoffset ++;
129	    MIARCCIRCLESTEP(yoffset ++;);
130	}
131	org.x -= info.xorg;
132	orgo.x -= info.xorg;
133	x = info.w;
134	yoffset = info.h;
135    }
136    else if (do360) {
137	while (y < info.h || x < info.w) {
138	    MIARCOCTANTSHIFT(dyoffset = 1;);
139	    WAITFIFO(8);
140	    DRAW_POINT(org.x + info.xorg + x, org.y + yoffset);
141	    DRAW_POINT(org.x + info.xorgo - x, org.y + yoffset);
142	    DRAW_POINT(orgo.x + info.xorgo - x, orgo.y - yoffset);
143	    DRAW_POINT(orgo.x + info.xorg + x, orgo.y - yoffset);
144	    MIARCSTEP(yoffset += dyoffset;, yoffset++;);
145	}
146    }
147    else {
148	while (y < info.h || x < info.w) {
149	    MIARCOCTANTSHIFT(dyoffset = 1;);
150	    if ((x == info.start.x) || (y == info.start.y)) {
151		mask = info.start.mask;
152		info.start = info.altstart;
153	    }
154	    WAITFIFO(8);
155	    if (mask & 1)
156		DRAW_POINT(org.x + info.xorg + x, org.y + yoffset);
157	    if (mask & 2)
158		DRAW_POINT(org.x + info.xorgo - x, org.y + yoffset);
159	    if (mask & 4)
160		DRAW_POINT(orgo.x + info.xorgo - x, orgo.y - yoffset);
161	    if (mask & 8)
162		DRAW_POINT(orgo.x + info.xorg + x, orgo.y - yoffset);
163	    if ((x == info.end.x) || (y == info.end.y)) {
164		mask = info.end.mask;
165		info.end = info.altend;
166	    }
167	    MIARCSTEP(yoffset += dyoffset;, yoffset++;);
168	}
169    }
170    if ((x == info.start.x) || (y == info.start.y))
171	mask = info.start.mask;
172
173    WAITFIFO(4);
174    if (mask & 1)
175	DRAW_POINT(org.x + info.xorg + x, org.y + yoffset);
176    if (mask & 4)
177	DRAW_POINT(orgo.x + info.xorgo - x, orgo.y - yoffset);
178    if (arc->height & 1) {
179	WAITFIFO(4);
180	if (mask & 2)
181	    DRAW_POINT(org.x + info.xorgo - x, org.y + yoffset);
182	if (mask & 8)
183	    DRAW_POINT(orgo.x + info.xorg + x, orgo.y - yoffset);
184    }
185
186    SET_SYNC_FLAG(infoRec);
187}
188
189void
190MGAPolyArcThinSolid (
191    DrawablePtr	pDraw,
192    GCPtr	pGC,
193    int		narcs,
194    xArc	*parcs
195){
196    xArc *arc;
197    BoxRec box;
198    int i, x2, y2;
199    RegionPtr cclip;
200
201    cclip = pGC->pCompositeClip;
202
203    if(!REGION_NUM_RECTS(cclip))
204	return;
205
206    for (arc = parcs, i = narcs; --i >= 0; arc++) {
207	if (miCanZeroArc(arc)) {
208	    box.x1 = arc->x + pDraw->x;
209	    box.y1 = arc->y + pDraw->y;
210 	    x2 = box.x1 + (int)arc->width + 1;
211 	    box.x2 = x2;
212 	    y2 = box.y1 + (int)arc->height + 1;
213 	    box.y2 = y2;
214 	    if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) &&
215 		    (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
216		MGAZeroArc (pDraw, pGC, arc);
217	    else
218		miZeroPolyArc(pDraw, pGC, 1, arc);
219	}
220	else
221	    miPolyArc(pDraw, pGC, 1, arc);
222    }
223}
224#endif /* USE_XAA */
225
226