1264fa531Smrg/*****************************************************************************
2264fa531SmrgCopyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
3264fa531Smrg
4264fa531Smrg                        All Rights Reserved
5264fa531Smrg
6dfac8f13SmrgPermission to use, copy, modify, and distribute this software and its
7dfac8f13Smrgdocumentation for any purpose and without fee is hereby granted,
8264fa531Smrgprovided that the above copyright notice appear in all copies and that
9dfac8f13Smrgboth that copyright notice and this permission notice appear in
10264fa531Smrgsupporting documentation, and that the name of Digital not be
11264fa531Smrgused in advertising or publicity pertaining to distribution of the
12dfac8f13Smrgsoftware without specific, written prior permission.
13264fa531Smrg
14264fa531SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15264fa531SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16264fa531SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17264fa531SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18264fa531SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19264fa531SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20264fa531SmrgSOFTWARE.
21264fa531Smrg
22264fa531Smrg******************************************************************************/
23264fa531Smrg
24264fa531Smrg#include "x11perf.h"
25264fa531Smrg
26264fa531Smrgstatic XSegment *segments;
27264fa531Smrgstatic GC       pgc;
28264fa531Smrg
29dfac8f13Smrgstatic void
30264fa531SmrgGenerateSegments(XParms xp, Parms p, Bool ddashed)
31264fa531Smrg{
32264fa531Smrg    int     size;
33264fa531Smrg    int     half;
34264fa531Smrg    int     i;
35264fa531Smrg    int     rows;	    /* Number of rows filled in current column      */
36264fa531Smrg    int     x, y;	    /* base of square to draw in		    */
37264fa531Smrg    int     x1=0, y1=0, x2=0, y2=0; /* offsets into square		    */
38264fa531Smrg    int     phase;	    /* how far into 0..8*size we are		    */
39264fa531Smrg    int     phaseinc;       /* how much to increment phase at each segment  */
40264fa531Smrg    int     size8;	    /* 8 * size					    */
41264fa531Smrg    XGCValues   gcv;
42264fa531Smrg
43264fa531Smrg    if(ddashed)
44264fa531Smrg	pgc = xp->ddfggc;
45264fa531Smrg    else
46264fa531Smrg	pgc = xp->fggc;
47264fa531Smrg
48264fa531Smrg
49264fa531Smrg    size = p->special;
50264fa531Smrg    size8 = 8 * size;
51264fa531Smrg    half = (size + 19) / 20;
52264fa531Smrg
53c9e4df9bSmrg    segments = malloc((p->objects) * sizeof(XSegment));
54264fa531Smrg
55264fa531Smrg    /* All this x, x1, etc. stuff is to create a pattern that
56264fa531Smrg	(1) scans down the screen vertically, with each new segment going
57264fa531Smrg	    into a square of size^2.
58264fa531Smrg
59264fa531Smrg	(2) rotates the endpoints clockwise around the square
60264fa531Smrg
61264fa531Smrg	(3) rotates by ``large'' steps if we aren't going to paint enough
62264fa531Smrg	    segments to get full coverage
63264fa531Smrg
64264fa531Smrg	(4) uses CapNotLast so we can create segments of length 1 that
65264fa531Smrg	    nonetheless have a distinct direction
66264fa531Smrg    */
67264fa531Smrg
68264fa531Smrg    x     = half;  y     = half;
69264fa531Smrg    phase = 0;
70264fa531Smrg    phaseinc = size8 / p->objects;
71264fa531Smrg    if (phaseinc == 0) phaseinc = 1;
72264fa531Smrg    rows = 0;
73264fa531Smrg
74dfac8f13Smrg    for (i = 0; i != p->objects; i++) {
75264fa531Smrg	switch (phase / size) {
76264fa531Smrg	case 0:
77264fa531Smrg	    x1 = 0;
78264fa531Smrg	    y1 = 0;
79264fa531Smrg	    x2 = size;
80264fa531Smrg	    y2 = phase;
81264fa531Smrg	    break;
82264fa531Smrg
83264fa531Smrg	case 1:
84dfac8f13Smrg	    x1 = phase % size;
85264fa531Smrg	    y1 = 0;
86264fa531Smrg	    x2 = size;
87264fa531Smrg	    y2 = size;
88264fa531Smrg	    break;
89264fa531Smrg
90264fa531Smrg	case 2:
91264fa531Smrg	    x1 = size;
92264fa531Smrg	    y1 = 0;
93264fa531Smrg	    x2 = size - phase % size;
94264fa531Smrg	    y2 = size;
95264fa531Smrg	    break;
96264fa531Smrg
97264fa531Smrg	case 3:
98264fa531Smrg	    x1 = size;
99264fa531Smrg	    y1 = phase % size;
100264fa531Smrg	    x2 = 0;
101264fa531Smrg	    y2 = size;
102264fa531Smrg	    break;
103264fa531Smrg
104264fa531Smrg	case 4:
105264fa531Smrg	    x1 = size;
106264fa531Smrg	    y1 = size;
107264fa531Smrg	    x2 = 0;
108264fa531Smrg	    y2 = size - phase % size;
109264fa531Smrg	    break;
110264fa531Smrg
111264fa531Smrg	case 5:
112264fa531Smrg	    x1 = size - phase % size;
113264fa531Smrg	    y1 = size;
114264fa531Smrg	    x2 = 0;
115264fa531Smrg	    y2 = 0;
116264fa531Smrg	    break;
117264fa531Smrg
118264fa531Smrg	case 6:
119264fa531Smrg	    x1 = 0;
120264fa531Smrg	    y1 = size;
121264fa531Smrg	    x2 = phase % size;
122264fa531Smrg	    y2 = 0;
123264fa531Smrg	    break;
124264fa531Smrg
125264fa531Smrg	case 7:
126264fa531Smrg	    x1 = 0;
127264fa531Smrg	    y1 = size - phase % size;
128264fa531Smrg	    x2 = size;
129264fa531Smrg	    y2 = 0;
130264fa531Smrg	    break;
131264fa531Smrg	} /* end switch */
132264fa531Smrg
133264fa531Smrg	segments[i].x1 = x + x1;
134264fa531Smrg	segments[i].y1 = y + y1;
135264fa531Smrg	segments[i].x2 = x + x2;
136264fa531Smrg	segments[i].y2 = y + y2;
137264fa531Smrg
138264fa531Smrg	/* Change square to draw segment in */
139264fa531Smrg	rows++;
140264fa531Smrg	y += size;
141264fa531Smrg	if (y >= HEIGHT - size - half || rows == MAXROWS) {
142264fa531Smrg	    /* Go to next column */
143264fa531Smrg	    rows = 0;
144264fa531Smrg	    y = half;
145264fa531Smrg	    x += size;
146264fa531Smrg	    if (x >= WIDTH - size - half) {
147264fa531Smrg		x = half;
148264fa531Smrg	    }
149264fa531Smrg	}
150264fa531Smrg
151264fa531Smrg	/* Increment phase */
152264fa531Smrg	phase += phaseinc;
153264fa531Smrg	if (phase >= size8) phase -= size8;
154264fa531Smrg
155264fa531Smrg    }
156264fa531Smrg
157264fa531Smrg    gcv.cap_style = CapNotLast;
158264fa531Smrg
159264fa531Smrg    if(ddashed) {
160264fa531Smrg	XChangeGC(xp->d, xp->ddfggc, GCCapStyle, &gcv);
161264fa531Smrg	XChangeGC(xp->d, xp->ddbggc, GCCapStyle, &gcv);
162264fa531Smrg    } else {
163264fa531Smrg	XChangeGC(xp->d, xp->fggc, GCCapStyle, &gcv);
164264fa531Smrg	XChangeGC(xp->d, xp->bggc, GCCapStyle, &gcv);
165264fa531Smrg    }
166264fa531Smrg}
167dfac8f13Smrg
168dfac8f13Smrgint
169533545b5SmrgInitSegments(XParms xp, Parms p, int64_t reps)
170264fa531Smrg{
171264fa531Smrg    GenerateSegments(xp, p, False);
172264fa531Smrg    return reps;
173264fa531Smrg}
174264fa531Smrg
175dfac8f13Smrgint
176533545b5SmrgInitDashedSegments(XParms xp, Parms p, int64_t reps)
177264fa531Smrg{
178264fa531Smrg    char dashes[2];
179264fa531Smrg
180264fa531Smrg    GenerateSegments(xp, p, False);
181264fa531Smrg
182264fa531Smrg    /* Modify GCs to draw dashed */
183264fa531Smrg    XSetLineAttributes
184264fa531Smrg	(xp->d, xp->bggc, 0, LineOnOffDash, CapNotLast, JoinMiter);
185264fa531Smrg    XSetLineAttributes
186264fa531Smrg	(xp->d, xp->fggc, 0, LineOnOffDash, CapNotLast, JoinMiter);
187264fa531Smrg    dashes[0] = 3;   dashes[1] = 2;
188264fa531Smrg    XSetDashes(xp->d, xp->fggc, 0, dashes, 2);
189264fa531Smrg    XSetDashes(xp->d, xp->bggc, 0, dashes, 2);
190264fa531Smrg    return reps;
191264fa531Smrg}
192264fa531Smrg
193dfac8f13Smrgint
194533545b5SmrgInitDoubleDashedSegments(XParms xp, Parms p, int64_t reps)
195264fa531Smrg{
196264fa531Smrg    char dashes[2];
197264fa531Smrg
198264fa531Smrg    GenerateSegments(xp, p, True);
199264fa531Smrg
200264fa531Smrg    /* Modify GCs to draw dashed */
201264fa531Smrg    XSetLineAttributes
202264fa531Smrg	(xp->d, xp->ddbggc, 0, LineDoubleDash, CapNotLast, JoinMiter);
203264fa531Smrg    XSetLineAttributes
204264fa531Smrg	(xp->d, xp->ddfggc, 0, LineDoubleDash, CapNotLast, JoinMiter);
205264fa531Smrg    dashes[0] = 3;   dashes[1] = 2;
206264fa531Smrg    XSetDashes(xp->d, xp->ddfggc, 0, dashes, 2);
207264fa531Smrg    XSetDashes(xp->d, xp->ddbggc, 0, dashes, 2);
208264fa531Smrg    return reps;
209264fa531Smrg}
210264fa531Smrg
211dfac8f13Smrgstatic int
212dfac8f13SmrgInitHorizSegmentsWidth(XParms xp, Parms p, int64_t reps, int width)
213264fa531Smrg{
214264fa531Smrg    int     size;
215264fa531Smrg    int     i;
216264fa531Smrg    int     x, y;	/* base of square to draw in			*/
217264fa531Smrg    int     y1;		/* y position inside square			*/
218264fa531Smrg    int     inc;
219264fa531Smrg    XGCValues   gcv;
220264fa531Smrg
221264fa531Smrg    pgc = xp->fggc;
222264fa531Smrg
223264fa531Smrg    size = p->special;
224264fa531Smrg
225c9e4df9bSmrg    segments = malloc((p->objects) * sizeof(XSegment));
226264fa531Smrg
227dfac8f13Smrg    x = width / 2 + 1;
228dfac8f13Smrg    y = width / 2 + 1;
229264fa531Smrg    y1 = 0;
230dfac8f13Smrg    inc = width + 1;
231264fa531Smrg
232264fa531Smrg    for (i = 0; i != p->objects; i++) {
233264fa531Smrg	if (i % 2) {
234264fa531Smrg	    segments[i].x1 = x + size;
235264fa531Smrg	    segments[i].x2 = x;
236dfac8f13Smrg	    segments[i].y1 = y + (HEIGHT - width - 2) - y1;
237dfac8f13Smrg	    segments[i].y2 = y + (HEIGHT - width - 2) - y1;
238dfac8f13Smrg            y1 += inc;
239264fa531Smrg	} else {
240264fa531Smrg	    segments[i].x1 = x;
241264fa531Smrg	    segments[i].x2 = x + size;
242264fa531Smrg	    segments[i].y1 = y + y1;
243264fa531Smrg	    segments[i].y2 = y + y1;
244264fa531Smrg	}
245dfac8f13Smrg        /* Go to next row */
246dfac8f13Smrg	if (y1 >= HEIGHT / 2 - (width + 2)) {
247dfac8f13Smrg	    y1 =0;
248dfac8f13Smrg	    x += size + inc;
249dfac8f13Smrg	    if (x >= WIDTH - size - width)
250dfac8f13Smrg		x = width/2 + 1;
251264fa531Smrg	}
252264fa531Smrg    }
253264fa531Smrg    gcv.cap_style = CapNotLast;
254264fa531Smrg    XChangeGC(xp->d, xp->fggc, GCCapStyle, &gcv);
255264fa531Smrg    XChangeGC(xp->d, xp->bggc, GCCapStyle, &gcv);
256264fa531Smrg    return reps;
257264fa531Smrg}
258264fa531Smrg
259dfac8f13Smrgint
260dfac8f13SmrgInitHorizSegments(XParms xp, Parms p, int64_t reps)
261dfac8f13Smrg{
262dfac8f13Smrg    return InitHorizSegmentsWidth(xp, p, reps, 1);
263dfac8f13Smrg}
264dfac8f13Smrg
265dfac8f13Smrgint
266533545b5SmrgInitWideHorizSegments(XParms xp, Parms p, int64_t reps)
267264fa531Smrg{
268dfac8f13Smrg    int size = p->special;
269264fa531Smrg
270dfac8f13Smrg    (void)InitHorizSegmentsWidth(xp, p, reps, (int) ((size + 9) / 10));
271264fa531Smrg
272264fa531Smrg    XSetLineAttributes(xp->d, xp->bggc, (int) ((size + 9) / 10),
273264fa531Smrg	LineSolid, CapRound, JoinRound);
274264fa531Smrg    XSetLineAttributes(xp->d, xp->fggc, (int) ((size + 9) / 10),
275264fa531Smrg	LineSolid, CapRound, JoinRound);
276264fa531Smrg
277264fa531Smrg    return reps;
278264fa531Smrg}
279264fa531Smrg
280dfac8f13Smrgstatic int
281dfac8f13SmrgInitVertSegmentsWidth(XParms xp, Parms p, int64_t reps, int width)
282264fa531Smrg{
283264fa531Smrg    int     size;
284264fa531Smrg    int     i;
285264fa531Smrg    int     x, y;	/* base of square to draw in			*/
286264fa531Smrg    int     x1;		/* x position inside square			*/
287264fa531Smrg    int     inc;
288264fa531Smrg    XGCValues   gcv;
289264fa531Smrg
290264fa531Smrg    pgc = xp->fggc;
291264fa531Smrg
292264fa531Smrg    size = p->special;
293264fa531Smrg
294c9e4df9bSmrg    segments = malloc((p->objects) * sizeof(XSegment));
295264fa531Smrg
296dfac8f13Smrg    x = width / 2 + 1;
297dfac8f13Smrg    y = width / 2 + 1;
298264fa531Smrg    x1 = 0;
299dfac8f13Smrg    inc = width + 1;
300264fa531Smrg
301264fa531Smrg    for (i = 0; i != p->objects; i++) {
302264fa531Smrg	if (i % 2) {
303dfac8f13Smrg	    segments[i].x1 = x + (WIDTH - width - 2) - x1;
304dfac8f13Smrg	    segments[i].x2 = x + (WIDTH - width - 2) - x1;
305264fa531Smrg	    segments[i].y1 = y + size;
306264fa531Smrg	    segments[i].y2 = y;
307dfac8f13Smrg            x1 += inc;
308264fa531Smrg	} else {
309264fa531Smrg	    segments[i].x1 = x + x1;
310264fa531Smrg	    segments[i].x2 = x + x1;
311264fa531Smrg	    segments[i].y1 = y;
312264fa531Smrg	    segments[i].y2 = y + size;
313264fa531Smrg	}
314dfac8f13Smrg        /* Go to next column */
315dfac8f13Smrg	if (x1 >= WIDTH / 2 - (width + 2)) {
316dfac8f13Smrg	    x1 = 0;
317dfac8f13Smrg            y += size + inc;
318dfac8f13Smrg            if (y >= HEIGHT - size - width)
319dfac8f13Smrg                y = width/2 + 1;
320264fa531Smrg	}
321264fa531Smrg    }
322264fa531Smrg    gcv.cap_style = CapNotLast;
323264fa531Smrg    XChangeGC(xp->d, xp->fggc, GCCapStyle, &gcv);
324264fa531Smrg    XChangeGC(xp->d, xp->bggc, GCCapStyle, &gcv);
325264fa531Smrg    return reps;
326264fa531Smrg}
327264fa531Smrg
328dfac8f13Smrgint
329dfac8f13SmrgInitVertSegments(XParms xp, Parms p, int64_t reps)
330dfac8f13Smrg{
331dfac8f13Smrg    return InitVertSegmentsWidth(xp, p, reps, 1);
332dfac8f13Smrg}
333dfac8f13Smrg
334dfac8f13Smrgint
335533545b5SmrgInitWideVertSegments(XParms xp, Parms p, int64_t reps)
336264fa531Smrg{
337dfac8f13Smrg    int    size = p->special;
338264fa531Smrg
339dfac8f13Smrg    (void)InitVertSegmentsWidth(xp, p, reps, (size + 9) / 10);
340264fa531Smrg
341264fa531Smrg    XSetLineAttributes(xp->d, xp->bggc, (int) ((size + 9) / 10),
342264fa531Smrg	LineSolid, CapRound, JoinRound);
343264fa531Smrg    XSetLineAttributes(xp->d, xp->fggc, (int) ((size + 9) / 10),
344264fa531Smrg	LineSolid, CapRound, JoinRound);
345264fa531Smrg
346264fa531Smrg    return reps;
347264fa531Smrg}
348264fa531Smrg
349dfac8f13Smrgvoid
350533545b5SmrgDoSegments(XParms xp, Parms p, int64_t reps)
351264fa531Smrg{
352264fa531Smrg    int i;
353264fa531Smrg
354264fa531Smrg    for (i = 0; i != reps; i++) {
355264fa531Smrg        XDrawSegments(xp->d, xp->w, pgc, segments, p->objects);
356264fa531Smrg        if (pgc == xp->ddbggc)
357264fa531Smrg            pgc = xp->ddfggc;
358264fa531Smrg        else if(pgc == xp->ddfggc)
359264fa531Smrg            pgc = xp->ddbggc;
360264fa531Smrg        else if (pgc == xp->bggc)
361264fa531Smrg            pgc = xp->fggc;
362264fa531Smrg        else
363264fa531Smrg            pgc = xp->bggc;
364264fa531Smrg	CheckAbort ();
365264fa531Smrg    }
366264fa531Smrg}
367264fa531Smrg
368dfac8f13Smrgvoid
369264fa531SmrgEndSegments(XParms xp, Parms p)
370264fa531Smrg{
371264fa531Smrg    free(segments);
372264fa531Smrg}
373