~ubuntu-branches/ubuntu/lucid/xscreensaver/lucid

« back to all changes in this revision

Viewing changes to hacks/whirlygig.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2007-12-06 09:53:12 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20071206095312-fkzcwe4vqm50z208
Tags: 5.04-1ubuntu1
* Merge from debian unstable, remaining changes:
  - split xscreensaver into xscreensaver, xscreensaver-data (hacks we ship),
    xscreensaver-data-extra (hacks in universe). split out gl hacks for
    universe to xscreensaver-gl-extra
  - use fridge for rss screensavers
  - create and install .desktop files for gnome-screensaver

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
 *  by the beauty of the shapes one receives when playing with sine waves
13
13
 *  Here is a little experiment to show that beauty is simple
14
14
 */
 
15
 
15
16
#include <stdio.h>
16
17
#include <math.h>
17
18
#include "screenhack.h"
41
42
    double xoffset;
42
43
    double yoffset;
43
44
    double offset_period;
44
 
    int wrap;
 
45
    Bool wrap;
45
46
};
46
47
 
47
48
enum object_mode {
48
49
    spin_mode, funky_mode, circle_mode, linear_mode, test_mode, fun_mode, innie_mode, lissajous_mode
49
 
} mode;
50
 
 
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);
61
 
 
62
 
XColor colors[NCOLORS];
63
 
int ncolors = NCOLORS;
64
 
char *progclass = "Whirlygig";
65
 
 
66
 
char *defaults [] = {
67
 
  ".background: black",
68
 
  ".foreground: white",
69
 
  "*xspeed: 1.0",
70
 
  "*yspeed: 1.0",
71
 
  "*xamplitude: 1.0",
72
 
  "*yamplitude: 1.0",
73
 
  "*whirlies: -1",
74
 
  "*nlines: -1",
75
 
  "*xmode: change",
76
 
  "*ymode: change",
77
 
  "*speed: 1",
78
 
  "*trail: 0",
79
 
  "*color_modifier: -1",
80
 
  "*start_time: -1",
81
 
  "*explain: False",
82
 
  "*xoffset: 1.0",
83
 
  "*yoffset: 1.0",
84
 
  "*offset_period:    1",
85
 
  "*wrap:               0",
86
 
  "*doubleBuffer:       True",
 
50
};
 
51
 
 
52
struct state {
 
53
  Display *dpy;
 
54
  Window window;
 
55
 
 
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
88
 
  "*useDBE:             True",
89
 
  "*useDBEClear:        True",
 
60
    Bool dbeclear_p;
 
61
    XdbeBackBuffer backb;
90
62
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
91
 
  0
92
 
};
93
 
 
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" },
133
 
  { 0, 0, 0, 0 }
134
 
};
 
63
 
 
64
    GC fgc, bgc;
 
65
    int screen;
 
66
    Bool dbuf;
 
67
 
 
68
    unsigned long int current_time; /* The global int telling the current time */
 
69
    unsigned long int start_time;
 
70
    struct info  *info;
 
71
    char *xmode_str, *ymode_str; /* holds the current mode for x and y computation */
 
72
 
 
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 */
 
77
 
 
78
    int pos[2], last_x[100][100], last_y[100][100], last_size[100][100];
 
79
    int current_color;
 
80
    Bool wrap;
 
81
    int xmode, ymode;
 
82
    double modifier;    /* for innie */
 
83
 
 
84
   XColor colors[NCOLORS];
 
85
   int ncolors;
 
86
   int explaining;
 
87
};
 
88
 
 
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);
 
98
 
 
99
 
135
100
 
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";
159
124
 
160
125
static void
161
 
explain(int xmode, int ymode, struct info *info, Display *display, Window window, GC fgc)
162
 
{
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);
167
 
    sleep(3);
168
 
    XClearWindow(display, window);
169
 
}
170
 
 
171
 
static void
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) 
173
127
{
174
128
  switch(mode) {
175
129
  case spin_mode:
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));
178
132
    break;
179
133
  case funky_mode:
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));
182
136
    break;
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));
186
140
    break;
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));
190
144
    break;
191
145
  case test_mode:
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));
194
148
    break;
195
149
  case fun_mode:
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));
198
152
    break;
199
153
  case innie_mode:
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));
202
156
    break;
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));    
206
160
  }
207
161
}
208
162
 
209
163
static void
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)
211
165
{
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;
218
172
    }
219
173
    else {
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;
225
179
    }
226
180
}
227
181
 
228
182
static void
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)
230
184
{
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;
239
193
    }
240
194
    else {
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;
243
197
    }
244
198
}
245
199
 
246
200
static void
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)
248
202
{
249
203
      /*  This is a pretty standard lissajous curve
250
204
           x = a sin(nt + c) 
256
210
  double weird = cos((time / 1100000.0) / 1000.0);
257
211
 
258
212
  if (index == 0) {
259
 
      result = info->xamplitude * 200.0 * sin((weird * time) + fun) + info->half_width;
 
213
      result = st->info->xamplitude * 200.0 * sin((weird * time) + fun) + st->info->half_width;
260
214
  }
261
215
  else {
262
 
      result = info->yamplitude * 200.0 * sin(time) + info->half_height;
 
216
      result = st->info->yamplitude * 200.0 * sin(time) + st->info->half_height;
263
217
  }
264
 
  pos[index] = result;
 
218
  st->pos[index] = result;
265
219
266
220
 
267
221
static void
268
 
circle(unsigned long int the_time, struct info *info, int pos[], int index)
 
222
circle(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
269
223
{
270
224
    int result;
271
225
    if (index == 0) {
272
 
        result = info->xamplitude * (cos((double)the_time / 100.0 * info->xspeed) * (info->half_width / 2)) + info->half_width;
 
226
        result = st->info->xamplitude * (cos((double)the_time / 100.0 * st->info->xspeed) * (st->info->half_width / 2)) + st->info->half_width;
273
227
    }
274
228
    else {
275
 
        result = info->yamplitude * (sin((double)the_time / 100.0 * info->yspeed) * (info->half_height / 2)) + info->half_height;
 
229
        result = st->info->yamplitude * (sin((double)the_time / 100.0 * st->info->yspeed) * (st->info->half_height / 2)) + st->info->half_height;
276
230
    }
277
 
    pos[index] = result;
 
231
    st->pos[index] = result;
278
232
}
279
233
 
280
234
#if 0
282
236
mod(unsigned long int the_time, struct info *info, int pos[], int index)
283
237
{
284
238
    int amplitude;
285
 
    int max = info->half_width;
 
239
    int max = st->info->half_width;
286
240
    if ((the_time % (max * 2)) < max)
287
241
        amplitude = max - ((the_time % (max * 2)) - max);
288
242
    else
292
246
#endif
293
247
 
294
248
static void
295
 
spin(unsigned long int the_time, struct info *info, int pos[], int index)
 
249
spin(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
296
250
{
297
251
    double funky = (((the_time % 360) * 1.0) / 180.0) * M_PI;
298
252
    if (index ==0) {
299
 
    double the_cos = cos((double)the_time / (180.0 * info->xspeed));
300
 
    double dist_mod_x = cos((double)funky) * (info->half_width - 50);
301
 
    pos[index] = info->xamplitude * (the_cos * dist_mod_x) + info->half_width;
 
253
    double the_cos = cos((double)the_time / (180.0 * st->info->xspeed));
 
254
    double dist_mod_x = cos((double)funky) * (st->info->half_width - 50);
 
255
    st->pos[index] = st->info->xamplitude * (the_cos * dist_mod_x) + st->info->half_width;
302
256
    }
303
257
    else {
304
 
    double the_sin = sin((double)the_time / (180.0 * info->yspeed));
305
 
    double dist_mod_y = sin((double)funky) * (info->half_height - 50);
306
 
    pos[index] = info->yamplitude * (the_sin * dist_mod_y) + info->half_height;
 
258
    double the_sin = sin((double)the_time / (180.0 * st->info->yspeed));
 
259
    double dist_mod_y = sin((double)funky) * (st->info->half_height - 50);
 
260
    st->pos[index] = st->info->yamplitude * (the_sin * dist_mod_y) + st->info->half_height;
307
261
    }
308
262
}
309
263
 
310
264
static void
311
 
fun(unsigned long int the_time, struct info *info, int pos[], int index)
 
265
fun(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
312
266
{
313
267
    int amplitude;
314
 
    int max = info->half_width;
 
268
    int max = st->info->half_width;
315
269
    if ((the_time % (max * 2)) < max)
316
270
        amplitude = max - ((the_time % (max * 2)) - max);
317
271
    else
318
272
        amplitude = the_time % (max * 2);
319
273
    amplitude = amplitude - max;
320
274
    if (index ==0) {
321
 
        pos[index] = (amplitude * cos((double)the_time / 100.0 * info->xspeed)) + info->half_width;
 
275
        st->pos[index] = (amplitude * cos((double)the_time / 100.0 * st->info->xspeed)) + st->info->half_width;
322
276
    }
323
277
    else {
324
 
        pos[index] = (amplitude * sin((double)the_time / 100.0 * info->yspeed)) + info->half_height;
 
278
        st->pos[index] = (amplitude * sin((double)the_time / 100.0 * st->info->yspeed)) + st->info->half_height;
325
279
    }
326
280
}
327
281
 
328
282
static void
329
 
linear(unsigned long int the_time, struct info *info, int pos[], int index)
 
283
linear(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
330
284
{
331
285
    if (index == 0)   /* Calculate for the x axis */
332
 
        pos[index] = ((the_time / 2) % (info->half_width * 2));
 
286
        st->pos[index] = ((the_time / 2) % (st->info->half_width * 2));
333
287
    else
334
 
        pos[index] = ((the_time / 2) % (info->half_height * 2));
 
288
        st->pos[index] = ((the_time / 2) % (st->info->half_height * 2));
335
289
}
336
290
 
337
291
static void
338
 
test(unsigned long int the_time, struct info *info, int pos[], int index)
 
292
test(struct state *st, unsigned long int the_time, struct info *info, int pos[], int index)
339
293
{
340
294
    if (index == 0) {
341
 
        pos[index] = info->xamplitude * (cos((double)the_time / 100.0 * info->xspeed) * (info->half_width / 2)) + info->half_width;
 
295
        st->pos[index] = st->info->xamplitude * (cos((double)the_time / 100.0 * st->info->xspeed) * (st->info->half_width / 2)) + st->info->half_width;
342
296
    }
343
297
    else {
344
 
        pos[index] = info->yamplitude * (sin((double)the_time / 100.0 * info->yspeed) * (info->half_height / 2)) + info->half_height;
 
298
        st->pos[index] = st->info->yamplitude * (sin((double)the_time / 100.0 * st->info->yspeed) * (st->info->half_height / 2)) + st->info->half_height;
345
299
    }   
346
300
}
347
301
 
354
308
}
355
309
 
356
310
static void
357
 
smoothen(int x, int lastx, int y, int lasty, int size, int last_color, XColor *colors, Display *display, Window window, GC bgc, int screen, struct info *info)
 
311
smoothen(struct state *st, int x, int lastx, int y, int lasty, int size, int last_color, XColor *colors, Display *dpy, Window window, GC bgc, int screen, struct info *info)
358
312
{
359
313
    double xdistance = abs((double)x-(double)lastx);
360
314
    double ydistance = abs((double)y-(double)lasty);
364
318
    if (distance > 2.0) {
365
319
        int newx = (int)((xdistance / distance) * slope);
366
320
        int newy = (int)((ydistance / distance) * slope);
367
 
        if (! info->trail) {
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);
370
324
        }
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);
375
328
    }
376
329
}
377
330
 
378
331
 
379
 
void
380
 
screenhack (Display *display, Window window)
 
332
static void *
 
333
whirlygig_init (Display *dpy, Window window)
381
334
{
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 */
389
 
 
390
 
    GC fgc, bgc;
391
 
    int screen;
392
 
    Bool dbuf = get_boolean_resource ("doubleBuffer", "Boolean");
393
 
    Bool dbeclear_p = get_boolean_resource ("useDBEClear", "Boolean");
394
 
 
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];
403
 
    int current_color;
404
 
    int wrap;
405
 
    int xmode, ymode;
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);
410
 
    if (dbuf)
 
335
  struct state *st = (struct state *) calloc (1, sizeof(*st));
 
336
  st->dpy = dpy;
 
337
  st->window = window;
 
338
 
 
339
  st->ncolors = NCOLORS;
 
340
 
 
341
    st->dbuf = get_boolean_resource (st->dpy, "doubleBuffer", "Boolean");
 
342
 
 
343
# ifdef HAVE_COCOA      /* Don't second-guess Quartz's double-buffering */
 
344
    st->dbuf = False;
 
345
# endif
 
346
 
 
347
    st->start_time = st->current_time;
 
348
    st->info = (struct info *)malloc(sizeof(struct info));
 
349
 
 
350
    st->screen = DefaultScreen(st->dpy);
 
351
    XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
 
352
    if (st->dbuf)
411
353
      {
412
354
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
413
 
        if (dbeclear_p)
414
 
          b = xdbe_get_backbuffer (display, window, XdbeBackground);
415
 
        else
416
 
          b = xdbe_get_backbuffer (display, window, XdbeUndefined);
417
 
        backb = b;
 
355
        if (get_boolean_resource(st->dpy,"useDBE","Boolean"))
 
356
          {
 
357
            st->dbeclear_p = get_boolean_resource (st->dpy, "useDBEClear",
 
358
                                                   "Boolean");
 
359
            if (st->dbeclear_p)
 
360
              st->b = xdbe_get_backbuffer (st->dpy, st->window, XdbeBackground);
 
361
            else
 
362
              st->b = xdbe_get_backbuffer (st->dpy, st->window, XdbeUndefined);
 
363
            st->backb = st->b;
 
364
          }
418
365
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
419
366
 
420
 
        if (!b)
 
367
        if (!st->b)
421
368
          {
422
 
            ba = XCreatePixmap (display, window, xgwa.width, xgwa.height,xgwa.depth);
423
 
            b = ba;
 
369
            st->ba = XCreatePixmap (st->dpy, st->window, st->xgwa.width, st->xgwa.height,st->xgwa.depth);
 
370
            st->b = st->ba;
424
371
          }
425
372
      }
426
373
    else
427
374
      {
428
 
        b = window;
 
375
        st->b = st->window;
429
376
      }
430
377
 
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);
 
382
 
 
383
#ifdef HAVE_COCOA  /* #### should turn off double-buffering instead */
 
384
    jwxyz_XSetAntiAliasing (dpy, st->fgc, False);
 
385
    jwxyz_XSetAntiAliasing (dpy, st->bgc, False);
 
386
#endif
 
387
 
435
388
    {
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);
438
391
    }
439
392
 
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);
441
394
 
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;
473
 
    else {
474
 
        xmode = spin_mode;
475
 
    }
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;
485
 
    else {
486
 
        ymode = spin_mode;
487
 
    }
488
 
 
489
 
    if (get_integer_resource("start_time", "Integer") == -1)
490
 
        current_time = (unsigned long int)(random());
491
 
    else
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! */
503
 
    
504
 
    while (1) {
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);
513
 
            }
514
 
        }
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);
519
 
            }
520
 
        }
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);
526
 
            }
527
 
        }
528
 
        if (++current_color >= NCOLORS)
529
 
            current_color = 0;
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)
535
 
                internal_time = 0;
536
 
            else
537
 
                    /* I want the distance between whirlies to increase more each whirly */
538
 
                internal_time = current_time + (10 * wcount) + (wcount * wcount); 
539
 
            switch (xmode) {
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 */
543
 
                case spin_mode:
544
 
                    spin(internal_time, info, pos, 0);
545
 
                    break;
546
 
                case funky_mode:
547
 
                    funky(internal_time, info, pos, 0);
548
 
                    break;
549
 
                case circle_mode:
550
 
                    circle(internal_time, info, pos, 0);
551
 
                    break;
552
 
                case linear_mode:
553
 
                    linear(internal_time, info, pos, 0);
554
 
                    break;
555
 
                case fun_mode:
556
 
                    fun(internal_time, info, pos, 0);
557
 
                    break;
558
 
                case test_mode:
559
 
                    test(internal_time, info, pos, 0);
560
 
                    break;
561
 
                case innie_mode:
562
 
                    innie(internal_time, info, pos, 0, modifier);
563
 
                    break;
564
 
                case lissajous_mode:
565
 
                    lissajous(internal_time, info, pos, 0);
566
 
                    break;
567
 
                default:
568
 
                    spin(internal_time, info, pos, 0);
569
 
                    break;
570
 
            }   /* End of the switch for the x position*/
571
 
            switch (ymode) {
572
 
                case spin_mode:
573
 
                    spin(internal_time, info, pos, 1);
574
 
                    break;
575
 
                case funky_mode:
576
 
                    funky(internal_time, info, pos, 1);
577
 
                    break;
578
 
                case circle_mode:
579
 
                    circle(internal_time, info, pos, 1);
580
 
                    break;
581
 
                case linear_mode:
582
 
                    linear(internal_time, info, pos, 1);
583
 
                    break;
584
 
                case fun_mode:
585
 
                    fun(internal_time, info, pos, 1);
586
 
                    break;
587
 
                case test_mode:
588
 
                    test(internal_time, info, pos, 1);
589
 
                    break;
590
 
                case innie_mode:
591
 
                    innie(internal_time, info, pos, 1, modifier);
592
 
                    break;
593
 
                case lissajous_mode:
594
 
                    lissajous(internal_time, info, pos, 1);
595
 
                    break;
596
 
                default:
597
 
                    spin(internal_time, info, pos, 1);
598
 
                    break;
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); 
603
 
                int size;
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
608
 
                    || !backb
609
 
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
610
 
                    )) {
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);
613
 
                }
614
 
                    /* Now, lets draw in the new circle */
615
 
                {  /* Starting new scope for local x_pos and y_pos */
616
 
                    int xpos, ypos;
617
 
                    if (wrap) {
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);
620
 
                    }
621
 
                    else {
622
 
                        xpos = (int)(info->xoffset*line_offset)+pos[0];
623
 
                        ypos = (int)(info->yoffset*line_offset)+pos[1]; 
624
 
                    }
625
 
                    if (start_time == current_time) {
626
 
                      /* smoothen should move from one mode to another prettily... */
627
 
 
628
 
                      /* Note: smoothen has not been modified to take the double
629
 
                         buffering code into account, and needs to be hacked on
630
 
                         before uncommenting.
631
 
                      */
632
 
/* 
633
 
   smoothen(xpos, last_x[wcount][lcount], ypos, last_y[wcount][lcount], size, color_offset, colors, display, window, bgc, screen, info);
634
 
 */
635
 
                    }
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 */
644
 
 
645
 
 
646
 
 
647
 
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
648
 
        if (backb)
649
 
          {
650
 
            XdbeSwapInfo info[1];
651
 
            info[0].swap_window = window;
652
 
            info[0].swap_action = (dbeclear_p ? XdbeBackground : XdbeUndefined);
653
 
            XdbeSwapBuffers (display, info, 1);
654
 
          }
655
 
        else
656
 
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
657
 
          if (dbuf)
658
 
            {
659
 
              XCopyArea (display, b, window, bgc, 0, 0,
660
 
                         xgwa.width, xgwa.height, 0, 0);
661
 
            }
662
 
 
663
 
        XSync(display, False);
664
 
        if (current_time == FULL_CYCLE)
665
 
            current_time = 1;
666
 
        else
667
 
            current_time = current_time + info->speed;
668
 
        screenhack_handle_events(display);
669
 
/*        if (!info->writable) */
670
 
            usleep(10000);
671
 
    }   /*  End the while loop! */
672
 
    free(info);
673
 
}
 
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;
 
426
    else {
 
427
        st->xmode = random() % (int) lissajous_mode;
 
428
    }
 
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;
 
438
    else {
 
439
        st->ymode = random() % (int) lissajous_mode;
 
440
    }
 
441
 
 
442
    if (get_integer_resource(st->dpy, "start_time", "Integer") == -1)
 
443
        st->current_time = (unsigned long int)(random());
 
444
    else
 
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"))
 
453
      st->explaining = 1;
 
454
    st->current_color = 1 + (random() % NCOLORS);
 
455
 
 
456
  return st;
 
457
}
 
458
 
 
459
static unsigned long
 
460
whirlygig_draw (Display *dpy, Window window, void *closure)
 
461
{
 
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;
 
466
 
 
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);
 
471
    st->explaining++;
 
472
    return 3000000;
 
473
  } else if (st->explaining == 2) {
 
474
    XClearWindow (st->dpy, st->window);
 
475
    st->explaining = 0;
 
476
  }
 
477
 
 
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);
 
483
    }
 
484
  }
 
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);
 
489
    }
 
490
  }
 
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);
 
496
    }
 
497
  }
 
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)
 
505
      internal_time = 0;
 
506
    else
 
507
      /* I want the distance between whirlies to increase more each whirly */
 
508
      internal_time = st->current_time + (10 * wcount) + (wcount * wcount); 
 
509
    switch (st->xmode) {
 
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 */
 
513
    case spin_mode:
 
514
      spin(st, internal_time, st->info, st->pos, 0);
 
515
      break;
 
516
    case funky_mode:
 
517
      funky(st, internal_time, st->info, st->pos, 0);
 
518
      break;
 
519
    case circle_mode:
 
520
      circle(st, internal_time, st->info, st->pos, 0);
 
521
      break;
 
522
    case linear_mode:
 
523
      linear(st, internal_time, st->info, st->pos, 0);
 
524
      break;
 
525
    case fun_mode:
 
526
      fun(st, internal_time, st->info, st->pos, 0);
 
527
      break;
 
528
    case test_mode:
 
529
      test(st, internal_time, st->info, st->pos, 0);
 
530
      break;
 
531
    case innie_mode:
 
532
      innie(st, internal_time, st->info, st->pos, 0, st->modifier);
 
533
      break;
 
534
    case lissajous_mode:
 
535
      lissajous(st, internal_time, st->info, st->pos, 0);
 
536
      break;
 
537
    default:
 
538
      spin(st, internal_time, st->info, st->pos, 0);
 
539
      break;
 
540
    }   /* End of the switch for the x position*/
 
541
    switch (st->ymode) {
 
542
    case spin_mode:
 
543
      spin(st, internal_time, st->info, st->pos, 1);
 
544
      break;
 
545
    case funky_mode:
 
546
      funky(st, internal_time, st->info, st->pos, 1);
 
547
      break;
 
548
    case circle_mode:
 
549
      circle(st, internal_time, st->info, st->pos, 1);
 
550
      break;
 
551
    case linear_mode:
 
552
      linear(st, internal_time, st->info, st->pos, 1);
 
553
      break;
 
554
    case fun_mode:
 
555
      fun(st, internal_time, st->info, st->pos, 1);
 
556
      break;
 
557
    case test_mode:
 
558
      test(st, internal_time, st->info, st->pos, 1);
 
559
      break;
 
560
    case innie_mode:
 
561
      innie(st, internal_time, st->info, st->pos, 1, st->modifier);
 
562
      break;
 
563
    case lissajous_mode:
 
564
      lissajous(st, internal_time, st->info, st->pos, 1);
 
565
      break;
 
566
    default:
 
567
      spin(st, internal_time, st->info, st->pos, 1);
 
568
      break;
 
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); 
 
573
      int size;
 
574
      size = (int)(15.0 + 5.0 * sin((double)internal_time / 180.0));
 
575
      /* First delete the old circle... */
 
576
      if (!st->info->trail
 
577
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
 
578
          && ( !st->dbeclear_p || !st->backb)
 
579
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
 
580
          ) {
 
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);
 
583
      }
 
584
      /* Now, lets draw in the new circle */
 
585
      {  /* Starting new scope for local x_pos and y_pos */
 
586
        int xpos, ypos;
 
587
        if (st->wrap) {
 
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);
 
590
        }
 
591
        else {
 
592
          xpos = (int)(st->info->xoffset*line_offset)+st->pos[0];
 
593
          ypos = (int)(st->info->yoffset*line_offset)+st->pos[1]; 
 
594
        }
 
595
        if (st->start_time == st->current_time) {
 
596
          /* smoothen should move from one mode to another prettily... */
 
597
 
 
598
          /* Note: smoothen has not been modified to take the double
 
599
             buffering code into account, and needs to be hacked on
 
600
             before uncommenting.
 
601
          */
 
602
          /* 
 
603
             smoothen(xpos, last_x[wcount][lcount], ypos, last_y[wcount][lcount], size, color_offset, colors, dpy, window, bgc, screen, info);
 
604
          */
 
605
        }
 
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 */
 
614
 
 
615
 
 
616
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
 
617
  if (st->backb)
 
618
    {
 
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);
 
623
    }
 
624
  else
 
625
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
 
626
    if (st->dbuf)
 
627
      {
 
628
        XCopyArea (st->dpy, st->b, st->window, st->bgc, 0, 0,
 
629
                   st->xgwa.width, st->xgwa.height, 0, 0);
 
630
      }
 
631
 
 
632
  if (st->current_time == FULL_CYCLE)
 
633
    st->current_time = 1;
 
634
  else
 
635
    st->current_time = st->current_time + st->info->speed;
 
636
 
 
637
  return 10000;
 
638
}
 
639
 
 
640
 
 
641
static void
 
642
whirlygig_reshape (Display *dpy, Window window, void *closure, 
 
643
                 unsigned int w, unsigned int h)
 
644
{
 
645
}
 
646
 
 
647
static Bool
 
648
whirlygig_event (Display *dpy, Window window, void *closure, XEvent *event)
 
649
{
 
650
  return False;
 
651
}
 
652
 
 
653
static void
 
654
whirlygig_free (Display *dpy, Window window, void *closure)
 
655
{
 
656
}
 
657
 
 
658
 
 
659
static const char *whirlygig_defaults [] = {
 
660
  ".background: black",
 
661
  ".foreground: white",
 
662
  "*xspeed: 1.0",
 
663
  "*yspeed: 1.0",
 
664
  "*xamplitude: 1.0",
 
665
  "*yamplitude: 1.0",
 
666
  "*whirlies: -1",
 
667
  "*nlines: -1",
 
668
  "*xmode: change",
 
669
  "*ymode: change",
 
670
  "*speed: 1",
 
671
  "*trail: 0",
 
672
  "*color_modifier: -1",
 
673
  "*start_time: -1",
 
674
  "*explain: False",
 
675
  "*xoffset: 1.0",
 
676
  "*yoffset: 1.0",
 
677
  "*offset_period:    1",
 
678
  "*wrap:               False",
 
679
  "*doubleBuffer:       True",
 
680
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
 
681
  "*useDBEClear:        True",
 
682
  "*useDBE:             True",
 
683
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
 
684
  0
 
685
};
 
686
 
 
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" },
 
727
  { 0, 0, 0, 0 }
 
728
};
 
729
 
 
730
XSCREENSAVER_MODULE ("Whirlygig", whirlygig)