43
44
double offset_period;
48
49
spin_mode, funky_mode, circle_mode, linear_mode, test_mode, fun_mode, innie_mode, lissajous_mode
51
static void explain(int, int, struct info *, Display *, Window, GC);
52
static void draw_explain_string(int, int, Display *, Window, GC);
53
static void spin(unsigned long int, struct info *, int *, int);
54
static void funky(unsigned long int, struct info *, int *, int);
55
static void circle(unsigned long int, struct info *, int *, int);
56
static void fun(unsigned long int, struct info *, int *, int);
57
static void linear(unsigned long int, struct info *, int *, int);
58
static void lissajous(unsigned long int, struct info *, int *, int);
59
static void test(unsigned long int, struct info *, int *, int);
60
static void innie(unsigned long int, struct info *, int *, int, double);
62
XColor colors[NCOLORS];
63
int ncolors = NCOLORS;
64
char *progclass = "Whirlygig";
79
"*color_modifier: -1",
86
"*doubleBuffer: True",
56
XGCValues gcv; /* The structure to hold the GC data */
57
XWindowAttributes xgwa; /* A structure to hold window data */
58
Pixmap b, ba; /* double-buffer to reduce flicker */
87
59
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
90
62
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
94
XrmOptionDescRec options [] = {
95
{ "-xspeed", ".xspeed", XrmoptionSepArg, 0 },
96
/* xspeed is a modifier of the argument to cos -- changing it thus
97
changes the frequency of cos */
98
{ "-yspeed", ".yspeed", XrmoptionSepArg, 0 },
99
/* Similiarly, yspeed changes the frequency of sin */
100
{ "-xamplitude", ".xamplitude", XrmoptionSepArg, 0 },
101
/* A factor by which to increase/decrease the amplitude of the sin */
102
{ "-yamplitude", ".yamplitude", XrmoptionSepArg, 0 },
103
/* A factor by which to increase/decrease the amplitude of the cos */
104
{ "-whirlies", ".whirlies",XrmoptionSepArg, 0 },
105
/* whirlies defines the number of circles to draw per line */
106
{ "-nlines", ".nlines",XrmoptionSepArg, 0 },
107
/* nlines is the number of lines of whirlies to draw */
108
{ "-xmode", ".xmode", XrmoptionSepArg, 0 },
109
/* There are a few different modes that I have written -- each mode
110
is in theory a different experiment with the possible modifiers to sin/cos */
111
{ "-ymode", ".ymode", XrmoptionSepArg, 0 },
112
{ "-speed", ".speed", XrmoptionSepArg, 0 },
113
/* This will modify how often it should draw, changing it will probably suck */
114
{ "-trail", ".trail", XrmoptionSepArg, 0 },
115
/* Control whether or not you want the old circles to be erased */
116
{ "-color_modifier", ".color_modifier", XrmoptionSepArg, 0 },
117
/* How many colors away from the current should the next whirly be? */
118
{ "-start_time", ".start_time", XrmoptionSepArg, 0 },
119
/* Specify exactly at what time to start graphing... */
120
{ "-xoffset", ".xoffset", XrmoptionSepArg, 0 },
121
/* Tell the whirlies to be offset by this factor of a sin */
122
{ "-yoffset", ".yoffset", XrmoptionSepArg, 0 },
123
/* Tell the whirlies to be offset by this factor of a cos */
124
{ "-offset_period", ".offset_period", XrmoptionSepArg, 0 },
125
/* Change the period of an offset cycle */
126
{ "-explain", ".explain", XrmoptionNoArg, "True" },
127
/* Specify whether or not to print an explanation of the function used. */
128
{ "-wrap", ".wrap", XrmoptionSepArg, 0 },
129
/* Specify if you want whirlies which are out of the boundary of the screen to be
130
wrapped around to the other side */
131
{ "-db", ".doubleBuffer", XrmoptionNoArg, "True" },
132
{ "-no-db", ".doubleBuffer", XrmoptionNoArg, "False" },
68
unsigned long int current_time; /* The global int telling the current time */
69
unsigned long int start_time;
71
char *xmode_str, *ymode_str; /* holds the current mode for x and y computation */
73
/* pos is the current position x,y -- last_x contains one cell of
74
every x coordinate for every position of every whirly in every
75
line up to 100 whirlies in 100 lines -- lasy_y and last_size hold
76
the same information for y and size respectively */
78
int pos[2], last_x[100][100], last_y[100][100], last_size[100][100];
82
double modifier; /* for innie */
84
XColor colors[NCOLORS];
89
static void draw_explain_string(struct state *, int, int, Display *, Window, GC);
90
static void spin(struct state *, unsigned long int, struct info *, int *, int);
91
static void funky(struct state *, unsigned long int, struct info *, int *, int);
92
static void circle(struct state *, unsigned long int, struct info *, int *, int);
93
static void fun(struct state *, unsigned long int, struct info *, int *, int);
94
static void linear(struct state *, unsigned long int, struct info *, int *, int);
95
static void lissajous(struct state *, unsigned long int, struct info *, int *, int);
96
static void test(struct state *, unsigned long int, struct info *, int *, int);
97
static void innie(struct state *, unsigned long int, struct info *, int *, int, double);
136
101
static const char spin_explanation[] =
137
102
"Spin mode is a simple sin/cos with every argument modified";
158
123
"Lissajous mode draws a slightly modified lissajous curve";
161
explain(int xmode, int ymode, struct info *info, Display *display, Window window, GC fgc)
163
XClearWindow(display, window);
164
draw_explain_string(xmode, info->half_height-100, display, window, fgc);
165
/* draw_explain_string(ymode, info->half_height-50, display, window, fgc);*/
166
XSync(display, False);
168
XClearWindow(display, window);
172
draw_explain_string(int mode, int offset, Display *display, Window window, GC fgc)
126
draw_explain_string(struct state *st, int mode, int offset, Display *dpy, Window window, GC fgc)
176
XDrawString(display, window, fgc, 50, offset, spin_explanation,
177
strlen(spin_explanation));
130
XDrawString(st->dpy, st->window, st->fgc, 50, offset,
131
(char*) spin_explanation, strlen(spin_explanation));
180
XDrawString(display, window, fgc, 50, offset, funky_explanation,
181
strlen(funky_explanation));
134
XDrawString(st->dpy, st->window, st->fgc, 50, offset,
135
(char*) funky_explanation, strlen(funky_explanation));
183
137
case circle_mode:
184
XDrawString(display, window, fgc, 50, offset, circle_explanation,
185
strlen(circle_explanation));
138
XDrawString(st->dpy, st->window, st->fgc, 50, offset,
139
(char*) circle_explanation, strlen(circle_explanation));
187
141
case linear_mode:
188
XDrawString(display, window, fgc, 50, offset, linear_explanation,
189
strlen(linear_explanation));
142
XDrawString(st->dpy, st->window, st->fgc, 50, offset,
143
(char*) linear_explanation, strlen(linear_explanation));
192
XDrawString(display, window, fgc, 50, offset, test_explanation,
193
strlen(test_explanation));
146
XDrawString(st->dpy, st->window, st->fgc, 50, offset,
147
(char*) test_explanation, strlen(test_explanation));
196
XDrawString(display, window, fgc, 50, offset, fun_explanation,
197
strlen(fun_explanation));
150
XDrawString(st->dpy, st->window, st->fgc, 50, offset,
151
(char*) fun_explanation, strlen(fun_explanation));
200
XDrawString(display, window, fgc, 50, offset, innie_explanation,
201
strlen(innie_explanation));
154
XDrawString(st->dpy, st->window, st->fgc, 50, offset,
155
(char*) innie_explanation, strlen(innie_explanation));
203
157
case lissajous_mode:
204
XDrawString(display, window, fgc, 50, offset, lissajous_explanation,
205
strlen(linear_explanation));
158
XDrawString(st->dpy, st->window, st->fgc, 50, offset,
159
(char*) lissajous_explanation, strlen(linear_explanation));
210
funky(unsigned long int the_time, struct info *info, int pos[], int index)
164
funky(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
212
166
double new_time = ((the_time % 360 ) / 180.0) * M_PI;
213
167
if (index == 0) {
214
168
double time_modifier = cos(new_time / 180.0);
215
double the_cos = cos((new_time * (double)info->xspeed) + (time_modifier * 80.0));
216
double dist_mod_x = cos(new_time) * (info->half_width - 50);
217
pos[index]= info->xamplitude * (the_cos * dist_mod_x) + info->half_width;
169
double the_cos = cos((new_time * (double)st->info->xspeed) + (time_modifier * 80.0));
170
double dist_mod_x = cos(new_time) * (st->info->half_width - 50);
171
st->pos[index]= st->info->xamplitude * (the_cos * dist_mod_x) + st->info->half_width;
220
174
double new_time = ((the_time % 360 ) / 180.0) * M_PI;
221
175
double time_modifier = sin(new_time / 180.0);
222
double the_sin = sin((new_time * (double)info->yspeed) + (time_modifier * 80.0));
223
double dist_mod_y = sin(new_time) * (info->half_height - 50);
224
pos[index] = info->yamplitude * (the_sin * dist_mod_y) + info->half_height;
176
double the_sin = sin((new_time * (double)st->info->yspeed) + (time_modifier * 80.0));
177
double dist_mod_y = sin(new_time) * (st->info->half_height - 50);
178
st->pos[index] = st->info->yamplitude * (the_sin * dist_mod_y) + st->info->half_height;
229
innie(unsigned long int the_time, struct info *info, int pos[], int index, double modifier)
183
innie(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index, double modifier)
231
double frequency = 2000000.0 + (modifier * cos(((double)the_time / 100.0)));
185
double frequency = 2000000.0 + (st->modifier * cos(((double)the_time / 100.0)));
232
186
double arg = (double)the_time / frequency;
233
187
double amplitude = 200.0 * cos(arg);
234
188
double fun = 150.0 * cos((double)the_time / 2000.0);
235
189
int vert_mod, horiz_mod;
236
190
if (index == 0) {
237
horiz_mod = (int)(fun * cos((double)the_time / 100.0)) + info->half_width;
238
pos[index] = (amplitude * cos((double)the_time / 100.0 * info->xspeed)) + horiz_mod;
191
horiz_mod = (int)(fun * cos((double)the_time / 100.0)) + st->info->half_width;
192
st->pos[index] = (amplitude * cos((double)the_time / 100.0 * st->info->xspeed)) + horiz_mod;
241
vert_mod = (int)(fun * sin((double)the_time / 100.0)) + info->half_height;
242
pos[index] = (amplitude * sin((double)the_time / 100.0 * info->yspeed)) + vert_mod;
195
vert_mod = (int)(fun * sin((double)the_time / 100.0)) + st->info->half_height;
196
st->pos[index] = (amplitude * sin((double)the_time / 100.0 * st->info->yspeed)) + vert_mod;
247
lissajous(unsigned long int the_time, struct info *info, int pos[], int index)
201
lissajous(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
249
203
/* This is a pretty standard lissajous curve
250
204
x = a sin(nt + c)
364
318
if (distance > 2.0) {
365
319
int newx = (int)((xdistance / distance) * slope);
366
320
int newy = (int)((ydistance / distance) * slope);
368
XSetForeground(display, bgc, BlackPixel(display, screen));
369
XFillArc(display, window, bgc, lastx, lasty, size, size, START_ARC, END_ARC);
321
if (! st->info->trail) {
322
XSetForeground(st->dpy, st->bgc, BlackPixel(st->dpy, st->screen));
323
XFillArc(st->dpy, st->window, st->bgc, lastx, lasty, size, size, START_ARC, END_ARC);
371
XSetForeground(display, bgc, colors[last_color].pixel);
372
XFillArc(display, window, bgc, newx, newy, size, size, START_ARC, END_ARC);
373
XSync(display, False);
374
smoothen(newx, x, newy, y, size, last_color, colors, display, window, bgc, screen, info);
325
XSetForeground(st->dpy, st->bgc, st->colors[last_color].pixel);
326
XFillArc(st->dpy, st->window, st->bgc, newx, newy, size, size, START_ARC, END_ARC);
327
smoothen(st, newx, x, newy, y, size, last_color, st->colors, st->dpy, st->window, st->bgc, st->screen, st->info);
380
screenhack (Display *display, Window window)
333
whirlygig_init (Display *dpy, Window window)
382
/* The following are all X related toys */
383
XGCValues gcv; /* The structure to hold the GC data */
384
XWindowAttributes xgwa; /* A structure to hold window data */
385
Pixmap b=0, ba=0; /* double-buffer to reduce flicker */
386
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
387
XdbeBackBuffer backb = 0;
388
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
392
Bool dbuf = get_boolean_resource ("doubleBuffer", "Boolean");
393
Bool dbeclear_p = get_boolean_resource ("useDBEClear", "Boolean");
395
unsigned long int current_time = 0; /* The global int telling the current time */
396
unsigned long int start_time = current_time;
397
struct info *info = (struct info *)malloc(sizeof(struct info)); /* Dont forget to call free() later */
398
char *xmode_str, *ymode_str; /* holds the current mode for x and y computation */
399
/* pos is the current position x,y -- last_x contains one cell of every x coordinate
400
for every position of every whirly in every line up to 100 whirlies in 100 lines
401
-- lasy_y and last_size hold the same information for y and size respectively */
402
int pos[2], last_x[100][100], last_y[100][100], last_size[100][100];
406
double modifier; /* for innie */
407
/* Set up the X toys that I will be using later */
408
screen = DefaultScreen(display);
409
XGetWindowAttributes (display, window, &xgwa);
335
struct state *st = (struct state *) calloc (1, sizeof(*st));
339
st->ncolors = NCOLORS;
341
st->dbuf = get_boolean_resource (st->dpy, "doubleBuffer", "Boolean");
343
# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */
347
st->start_time = st->current_time;
348
st->info = (struct info *)malloc(sizeof(struct info));
350
st->screen = DefaultScreen(st->dpy);
351
XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
412
354
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
414
b = xdbe_get_backbuffer (display, window, XdbeBackground);
416
b = xdbe_get_backbuffer (display, window, XdbeUndefined);
355
if (get_boolean_resource(st->dpy,"useDBE","Boolean"))
357
st->dbeclear_p = get_boolean_resource (st->dpy, "useDBEClear",
360
st->b = xdbe_get_backbuffer (st->dpy, st->window, XdbeBackground);
362
st->b = xdbe_get_backbuffer (st->dpy, st->window, XdbeUndefined);
418
365
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
422
ba = XCreatePixmap (display, window, xgwa.width, xgwa.height,xgwa.depth);
369
st->ba = XCreatePixmap (st->dpy, st->window, st->xgwa.width, st->xgwa.height,st->xgwa.depth);
431
gcv.foreground = get_pixel_resource("foreground", "Foreground", display, xgwa.colormap);
432
fgc = XCreateGC (display, b, GCForeground, &gcv);
433
gcv.foreground = get_pixel_resource("background", "Background", display, xgwa.colormap);
434
bgc = XCreateGC (display, b, GCForeground, &gcv);
378
st->gcv.foreground = get_pixel_resource(st->dpy, st->xgwa.colormap, "foreground", "Foreground");
379
st->fgc = XCreateGC (st->dpy, st->b, GCForeground, &st->gcv);
380
st->gcv.foreground = get_pixel_resource(st->dpy, st->xgwa.colormap, "background", "Background");
381
st->bgc = XCreateGC (st->dpy, st->b, GCForeground, &st->gcv);
383
#ifdef HAVE_COCOA /* #### should turn off double-buffering instead */
384
jwxyz_XSetAntiAliasing (dpy, st->fgc, False);
385
jwxyz_XSetAntiAliasing (dpy, st->bgc, False);
436
389
Bool writable_p = False;
437
make_uniform_colormap (display, xgwa.visual, xgwa.colormap, colors, &ncolors, True, &writable_p, True);
390
make_uniform_colormap (st->dpy, st->xgwa.visual, st->xgwa.colormap, st->colors, &st->ncolors, True, &writable_p, True);
440
if (ba) XFillRectangle (display, ba, bgc, 0, 0, xgwa.width, xgwa.height);
393
if (st->ba) XFillRectangle (st->dpy, st->ba, st->bgc, 0, 0, st->xgwa.width, st->xgwa.height);
442
395
/* info is a structure holding all the random pieces of information I may want to
443
396
pass to my baby functions -- much of it I may never use, but it is nice to
444
397
have around just in case I want it to make a funky function funkier */
445
/* info->writable = get_boolean_resource ("cycle", "Boolean"); */
446
info->xspeed = get_float_resource("xspeed" , "Float");
447
info->yspeed = get_float_resource("yspeed" , "Float");
448
info->xamplitude = get_float_resource("xamplitude", "Float");
449
info->yamplitude = get_float_resource("yamplitude", "Float");
450
info->offset_period = get_float_resource("offset_period", "Float");
451
info->whirlies = get_integer_resource("whirlies", "Integer");
452
info->nlines = get_integer_resource("nlines", "Integer");
453
info->half_width = xgwa.width / 2;
454
info->half_height = xgwa.height / 2;
455
info->speed = get_integer_resource("speed" , "Integer");
456
info->trail = get_integer_resource("trail", "Integer");
457
info->color_modifier = get_integer_resource("color_modifier", "Integer");
458
info->xoffset = get_float_resource("xoffset", "Float");
459
info->yoffset = get_float_resource("yoffset", "Float");
460
xmode_str = get_string_resource("xmode", "Mode");
461
ymode_str = get_string_resource("ymode", "Mode");
462
wrap = get_integer_resource("wrap", "Integer");
463
modifier = 3000.0 + frand(1500.0);
464
if (! xmode_str) xmode = spin_mode;
465
else if (! strcmp (xmode_str, "spin")) xmode = spin_mode;
466
else if (! strcmp (xmode_str, "funky")) xmode = funky_mode;
467
else if (! strcmp (xmode_str, "circle")) xmode = circle_mode;
468
else if (! strcmp (xmode_str, "linear")) xmode = linear_mode;
469
else if (! strcmp (xmode_str, "test")) xmode = test_mode;
470
else if (! strcmp (xmode_str, "fun")) xmode = fun_mode;
471
else if (! strcmp (xmode_str, "innie")) xmode = innie_mode;
472
else if (! strcmp (xmode_str, "lissajous")) xmode = lissajous_mode;
476
if (! ymode_str) ymode = spin_mode;
477
else if (! strcmp (ymode_str, "spin")) ymode = spin_mode;
478
else if (! strcmp (ymode_str, "funky")) ymode = funky_mode;
479
else if (! strcmp (ymode_str, "circle")) ymode = circle_mode;
480
else if (! strcmp (ymode_str, "linear")) ymode = linear_mode;
481
else if (! strcmp (ymode_str, "test")) ymode = test_mode;
482
else if (! strcmp (ymode_str, "fun")) ymode = fun_mode;
483
else if (! strcmp (ymode_str, "innie")) ymode = innie_mode;
484
else if (! strcmp (ymode_str, "lissajous")) ymode = lissajous_mode;
489
if (get_integer_resource("start_time", "Integer") == -1)
490
current_time = (unsigned long int)(random());
492
current_time = get_integer_resource("start_time", "Integer");
493
if (info->whirlies == -1)
494
info->whirlies = 1 + (random() % 15);
495
if (info->nlines == -1)
496
info->nlines = 1 + (random() % 5);
497
if (info->color_modifier == -1)
498
info->color_modifier = 1 + (random() % 25);
499
if (get_boolean_resource("explain", "Integer"))
500
explain(xmode, ymode, info, display, window, fgc);
501
current_color = 1 + (random() % NCOLORS);
502
/* Now that info is full, lets play! */
505
int wcount; /* wcount is a counter incremented for every whirly take note of
506
internal_time before you mess with it */
507
int change_time = 4000;
508
if (! strcmp (xmode_str, "change") && ! strcmp (ymode_str, "change")) {
509
if ((current_time - start_time) > change_time) {
510
start_time = current_time;
511
xmode = 1 + (random() % 4);
512
ymode = 1 + (random() % 4);
515
else if (! strcmp (xmode_str, "change")) {
516
if ((current_time - start_time) > change_time) {
517
start_time = current_time;
518
xmode = 1 + (random() % 4);
521
else if (! strcmp (ymode_str, "change")) {
522
if ((current_time - start_time) > change_time) {
523
start_time = current_time;
524
ymode = 1 + (random() % 3);
525
printf("Changing ymode to %d\n", ymode);
528
if (++current_color >= NCOLORS)
530
for (wcount = 0; wcount < info->whirlies; wcount++) {
531
int lcount; /* lcount is a counter for every line -- take note of the offsets changing */
532
int internal_time = current_time;
533
int color_offset = (current_color + (info->color_modifier * wcount)) % NCOLORS;
534
if (current_time == 0)
537
/* I want the distance between whirlies to increase more each whirly */
538
internal_time = current_time + (10 * wcount) + (wcount * wcount);
540
/* All these functions expect an int time, the struct info,
541
a pointer to an array of positions, and the index that the
542
the function will fill of the array */
544
spin(internal_time, info, pos, 0);
547
funky(internal_time, info, pos, 0);
550
circle(internal_time, info, pos, 0);
553
linear(internal_time, info, pos, 0);
556
fun(internal_time, info, pos, 0);
559
test(internal_time, info, pos, 0);
562
innie(internal_time, info, pos, 0, modifier);
565
lissajous(internal_time, info, pos, 0);
568
spin(internal_time, info, pos, 0);
570
} /* End of the switch for the x position*/
573
spin(internal_time, info, pos, 1);
576
funky(internal_time, info, pos, 1);
579
circle(internal_time, info, pos, 1);
582
linear(internal_time, info, pos, 1);
585
fun(internal_time, info, pos, 1);
588
test(internal_time, info, pos, 1);
591
innie(internal_time, info, pos, 1, modifier);
594
lissajous(internal_time, info, pos, 1);
597
spin(internal_time, info, pos, 1);
599
} /* End of the switch for the y position*/
600
for (lcount = 0; lcount < info->nlines; lcount++) {
601
double arg = (double)((internal_time * info->offset_period) / 90.0);
602
double line_offset = 20.0 * (double)lcount * sin(arg);
604
size = (int)(15.0 + 5.0 * sin((double)internal_time / 180.0));
605
/* First delete the old circle... */
606
if (!info->trail && ( !dbeclear_p
607
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
609
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
611
XSetForeground(display, bgc, BlackPixel(display, screen));
612
XFillArc(display, b, bgc, last_x[wcount][lcount], last_y[wcount][lcount], last_size[wcount][lcount], last_size[wcount][lcount], START_ARC, END_ARC);
614
/* Now, lets draw in the new circle */
615
{ /* Starting new scope for local x_pos and y_pos */
618
xpos = preen((int)(info->xoffset*line_offset)+pos[0], info->half_width * 2);
619
ypos = preen((int)(info->yoffset*line_offset)+pos[1], info->half_height * 2);
622
xpos = (int)(info->xoffset*line_offset)+pos[0];
623
ypos = (int)(info->yoffset*line_offset)+pos[1];
625
if (start_time == current_time) {
626
/* smoothen should move from one mode to another prettily... */
628
/* Note: smoothen has not been modified to take the double
629
buffering code into account, and needs to be hacked on
633
smoothen(xpos, last_x[wcount][lcount], ypos, last_y[wcount][lcount], size, color_offset, colors, display, window, bgc, screen, info);
636
last_x[wcount][lcount] = xpos;
637
last_y[wcount][lcount] = ypos;
638
last_size[wcount][lcount] = size;
639
XSetForeground(display, bgc, colors[color_offset].pixel);
640
XFillArc(display, b, bgc, xpos, ypos, size, size, START_ARC, END_ARC);
641
} /* End of my temporary scope for xpos and ypos */
642
} /* End of the for each line in nlines */
643
} /* End of the for each whirly in whirlies */
647
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
650
XdbeSwapInfo info[1];
651
info[0].swap_window = window;
652
info[0].swap_action = (dbeclear_p ? XdbeBackground : XdbeUndefined);
653
XdbeSwapBuffers (display, info, 1);
656
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
659
XCopyArea (display, b, window, bgc, 0, 0,
660
xgwa.width, xgwa.height, 0, 0);
663
XSync(display, False);
664
if (current_time == FULL_CYCLE)
667
current_time = current_time + info->speed;
668
screenhack_handle_events(display);
669
/* if (!info->writable) */
671
} /* End the while loop! */
398
/* info->writable = get_boolean_resource (dpy, "cycle", "Boolean"); */
399
st->info->xspeed = get_float_resource(st->dpy, "xspeed" , "Float");
400
st->info->yspeed = get_float_resource(st->dpy, "yspeed" , "Float");
401
st->info->xamplitude = get_float_resource(st->dpy, "xamplitude", "Float");
402
st->info->yamplitude = get_float_resource(st->dpy, "yamplitude", "Float");
403
st->info->offset_period = get_float_resource(st->dpy, "offset_period", "Float");
404
st->info->whirlies = get_integer_resource(st->dpy, "whirlies", "Integer");
405
st->info->nlines = get_integer_resource(st->dpy, "nlines", "Integer");
406
st->info->half_width = st->xgwa.width / 2;
407
st->info->half_height = st->xgwa.height / 2;
408
st->info->speed = get_integer_resource(st->dpy, "speed" , "Integer");
409
st->info->trail = get_integer_resource(st->dpy, "trail", "Integer");
410
st->info->color_modifier = get_integer_resource(st->dpy, "color_modifier", "Integer");
411
st->info->xoffset = get_float_resource(st->dpy, "xoffset", "Float");
412
st->info->yoffset = get_float_resource(st->dpy, "yoffset", "Float");
413
st->xmode_str = get_string_resource(st->dpy, "xmode", "Mode");
414
st->ymode_str = get_string_resource(st->dpy, "ymode", "Mode");
415
st->wrap = get_boolean_resource(st->dpy, "wrap", "Boolean");
416
st->modifier = 3000.0 + frand(1500.0);
417
if (! st->xmode_str) st->xmode = spin_mode;
418
else if (! strcmp (st->xmode_str, "spin")) st->xmode = spin_mode;
419
else if (! strcmp (st->xmode_str, "funky")) st->xmode = funky_mode;
420
else if (! strcmp (st->xmode_str, "circle")) st->xmode = circle_mode;
421
else if (! strcmp (st->xmode_str, "linear")) st->xmode = linear_mode;
422
else if (! strcmp (st->xmode_str, "test")) st->xmode = test_mode;
423
else if (! strcmp (st->xmode_str, "fun")) st->xmode = fun_mode;
424
else if (! strcmp (st->xmode_str, "innie")) st->xmode = innie_mode;
425
else if (! strcmp (st->xmode_str, "lissajous")) st->xmode = lissajous_mode;
427
st->xmode = random() % (int) lissajous_mode;
429
if (! st->ymode_str) st->ymode = spin_mode;
430
else if (! strcmp (st->ymode_str, "spin")) st->ymode = spin_mode;
431
else if (! strcmp (st->ymode_str, "funky")) st->ymode = funky_mode;
432
else if (! strcmp (st->ymode_str, "circle")) st->ymode = circle_mode;
433
else if (! strcmp (st->ymode_str, "linear")) st->ymode = linear_mode;
434
else if (! strcmp (st->ymode_str, "test")) st->ymode = test_mode;
435
else if (! strcmp (st->ymode_str, "fun")) st->ymode = fun_mode;
436
else if (! strcmp (st->ymode_str, "innie")) st->ymode = innie_mode;
437
else if (! strcmp (st->ymode_str, "lissajous")) st->ymode = lissajous_mode;
439
st->ymode = random() % (int) lissajous_mode;
442
if (get_integer_resource(st->dpy, "start_time", "Integer") == -1)
443
st->current_time = (unsigned long int)(random());
445
st->current_time = get_integer_resource(st->dpy, "start_time", "Integer");
446
if (st->info->whirlies == -1)
447
st->info->whirlies = 1 + (random() % 15);
448
if (st->info->nlines == -1)
449
st->info->nlines = 1 + (random() % 5);
450
if (st->info->color_modifier == -1)
451
st->info->color_modifier = 1 + (random() % 25);
452
if (get_boolean_resource(st->dpy, "explain", "Integer"))
454
st->current_color = 1 + (random() % NCOLORS);
460
whirlygig_draw (Display *dpy, Window window, void *closure)
462
struct state *st = (struct state *) closure;
463
int wcount; /* wcount is a counter incremented for every whirly take note of
464
internal_time before you mess with it */
465
int change_time = 4000;
467
if (st->explaining == 1) {
468
XClearWindow (st->dpy, st->window);
469
draw_explain_string(st, st->xmode, st->info->half_height-100,
470
st->dpy, st->window, st->fgc);
473
} else if (st->explaining == 2) {
474
XClearWindow (st->dpy, st->window);
478
if (! strcmp (st->xmode_str, "change") && ! strcmp (st->ymode_str, "change")) {
479
if ((st->current_time - st->start_time) > change_time) {
480
st->start_time = st->current_time;
481
st->xmode = 1 + (random() % 4);
482
st->ymode = 1 + (random() % 4);
485
else if (! strcmp (st->xmode_str, "change")) {
486
if ((st->current_time - st->start_time) > change_time) {
487
st->start_time = st->current_time;
488
st->xmode = 1 + (random() % 4);
491
else if (! strcmp (st->ymode_str, "change")) {
492
if ((st->current_time - st->start_time) > change_time) {
493
st->start_time = st->current_time;
494
st->ymode = 1 + (random() % 3);
495
printf("Changing ymode to %d\n", st->ymode);
498
if (++st->current_color >= NCOLORS)
499
st->current_color = 0;
500
for (wcount = 0; wcount < st->info->whirlies; wcount++) {
501
int lcount; /* lcount is a counter for every line -- take note of the offsets changing */
502
int internal_time = st->current_time;
503
int color_offset = (st->current_color + (st->info->color_modifier * wcount)) % NCOLORS;
504
if (st->current_time == 0)
507
/* I want the distance between whirlies to increase more each whirly */
508
internal_time = st->current_time + (10 * wcount) + (wcount * wcount);
510
/* All these functions expect an int time, the struct info,
511
a pointer to an array of positions, and the index that the
512
the function will fill of the array */
514
spin(st, internal_time, st->info, st->pos, 0);
517
funky(st, internal_time, st->info, st->pos, 0);
520
circle(st, internal_time, st->info, st->pos, 0);
523
linear(st, internal_time, st->info, st->pos, 0);
526
fun(st, internal_time, st->info, st->pos, 0);
529
test(st, internal_time, st->info, st->pos, 0);
532
innie(st, internal_time, st->info, st->pos, 0, st->modifier);
535
lissajous(st, internal_time, st->info, st->pos, 0);
538
spin(st, internal_time, st->info, st->pos, 0);
540
} /* End of the switch for the x position*/
543
spin(st, internal_time, st->info, st->pos, 1);
546
funky(st, internal_time, st->info, st->pos, 1);
549
circle(st, internal_time, st->info, st->pos, 1);
552
linear(st, internal_time, st->info, st->pos, 1);
555
fun(st, internal_time, st->info, st->pos, 1);
558
test(st, internal_time, st->info, st->pos, 1);
561
innie(st, internal_time, st->info, st->pos, 1, st->modifier);
564
lissajous(st, internal_time, st->info, st->pos, 1);
567
spin(st, internal_time, st->info, st->pos, 1);
569
} /* End of the switch for the y position*/
570
for (lcount = 0; lcount < st->info->nlines; lcount++) {
571
double arg = (double)((internal_time * st->info->offset_period) / 90.0);
572
double line_offset = 20.0 * (double)lcount * sin(arg);
574
size = (int)(15.0 + 5.0 * sin((double)internal_time / 180.0));
575
/* First delete the old circle... */
577
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
578
&& ( !st->dbeclear_p || !st->backb)
579
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
581
XSetForeground(st->dpy, st->bgc, BlackPixel(st->dpy, st->screen));
582
XFillArc(st->dpy, st->b, st->bgc, st->last_x[wcount][lcount], st->last_y[wcount][lcount], st->last_size[wcount][lcount], st->last_size[wcount][lcount], START_ARC, END_ARC);
584
/* Now, lets draw in the new circle */
585
{ /* Starting new scope for local x_pos and y_pos */
588
xpos = preen((int)(st->info->xoffset*line_offset)+st->pos[0], st->info->half_width * 2);
589
ypos = preen((int)(st->info->yoffset*line_offset)+st->pos[1], st->info->half_height * 2);
592
xpos = (int)(st->info->xoffset*line_offset)+st->pos[0];
593
ypos = (int)(st->info->yoffset*line_offset)+st->pos[1];
595
if (st->start_time == st->current_time) {
596
/* smoothen should move from one mode to another prettily... */
598
/* Note: smoothen has not been modified to take the double
599
buffering code into account, and needs to be hacked on
603
smoothen(xpos, last_x[wcount][lcount], ypos, last_y[wcount][lcount], size, color_offset, colors, dpy, window, bgc, screen, info);
606
st->last_x[wcount][lcount] = xpos;
607
st->last_y[wcount][lcount] = ypos;
608
st->last_size[wcount][lcount] = size;
609
XSetForeground(st->dpy, st->bgc, st->colors[color_offset].pixel);
610
XFillArc(st->dpy, st->b, st->bgc, xpos, ypos, size, size, START_ARC, END_ARC);
611
} /* End of my temporary scope for xpos and ypos */
612
} /* End of the for each line in nlines */
613
} /* End of the for each whirly in whirlies */
616
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
619
XdbeSwapInfo info[1];
620
info[0].swap_window = st->window;
621
info[0].swap_action = (st->dbeclear_p ? XdbeBackground : XdbeUndefined);
622
XdbeSwapBuffers (st->dpy, info, 1);
625
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
628
XCopyArea (st->dpy, st->b, st->window, st->bgc, 0, 0,
629
st->xgwa.width, st->xgwa.height, 0, 0);
632
if (st->current_time == FULL_CYCLE)
633
st->current_time = 1;
635
st->current_time = st->current_time + st->info->speed;
642
whirlygig_reshape (Display *dpy, Window window, void *closure,
643
unsigned int w, unsigned int h)
648
whirlygig_event (Display *dpy, Window window, void *closure, XEvent *event)
654
whirlygig_free (Display *dpy, Window window, void *closure)
659
static const char *whirlygig_defaults [] = {
660
".background: black",
661
".foreground: white",
672
"*color_modifier: -1",
679
"*doubleBuffer: True",
680
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
681
"*useDBEClear: True",
683
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
687
static XrmOptionDescRec whirlygig_options [] = {
688
{ "-xspeed", ".xspeed", XrmoptionSepArg, 0 },
689
/* xspeed is a modifier of the argument to cos -- changing it thus
690
changes the frequency of cos */
691
{ "-yspeed", ".yspeed", XrmoptionSepArg, 0 },
692
/* Similiarly, yspeed changes the frequency of sin */
693
{ "-xamplitude", ".xamplitude", XrmoptionSepArg, 0 },
694
/* A factor by which to increase/decrease the amplitude of the sin */
695
{ "-yamplitude", ".yamplitude", XrmoptionSepArg, 0 },
696
/* A factor by which to increase/decrease the amplitude of the cos */
697
{ "-whirlies", ".whirlies",XrmoptionSepArg, 0 },
698
/* whirlies defines the number of circles to draw per line */
699
{ "-nlines", ".nlines",XrmoptionSepArg, 0 },
700
/* nlines is the number of lines of whirlies to draw */
701
{ "-xmode", ".xmode", XrmoptionSepArg, 0 },
702
/* There are a few different modes that I have written -- each mode
703
is in theory a different experiment with the possible modifiers to sin/cos */
704
{ "-ymode", ".ymode", XrmoptionSepArg, 0 },
705
{ "-speed", ".speed", XrmoptionSepArg, 0 },
706
/* This will modify how often it should draw, changing it will probably suck */
707
{ "-trail", ".trail", XrmoptionSepArg, 0 },
708
/* Control whether or not you want the old circles to be erased */
709
{ "-color_modifier", ".color_modifier", XrmoptionSepArg, 0 },
710
/* How many colors away from the current should the next whirly be? */
711
{ "-start_time", ".start_time", XrmoptionSepArg, 0 },
712
/* Specify exactly at what time to start graphing... */
713
{ "-xoffset", ".xoffset", XrmoptionSepArg, 0 },
714
/* Tell the whirlies to be offset by this factor of a sin */
715
{ "-yoffset", ".yoffset", XrmoptionSepArg, 0 },
716
/* Tell the whirlies to be offset by this factor of a cos */
717
{ "-offset_period", ".offset_period", XrmoptionSepArg, 0 },
718
/* Change the period of an offset cycle */
719
{ "-explain", ".explain", XrmoptionNoArg, "True" },
720
/* Specify whether or not to print an explanation of the function used. */
721
{ "-wrap", ".wrap", XrmoptionNoArg, "True" },
722
{ "-no-wrap", ".wrap", XrmoptionNoArg, "False" },
723
/* Specify if you want whirlies which are out of the boundary of the screen to be
724
wrapped around to the other side */
725
{ "-db", ".doubleBuffer", XrmoptionNoArg, "True" },
726
{ "-no-db", ".doubleBuffer", XrmoptionNoArg, "False" },
730
XSCREENSAVER_MODULE ("Whirlygig", whirlygig)