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