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