1 #if 0
2 static const char sccsid[] = "@(#)mode.c 5.12 04/03/09 xlockmore";
3
4 #endif
5 /*-
6 * mode.c - Modes for xlock.
7 *
8 * See xlock.c for copying information.
9 *
10 * Revision History:
11 * 01-Apr-97: Fixed memory leak in XStringListToTextProperty.
12 * 23-Feb-96: Extensive revision to implement new mode hooks and stuff
13 * Ron Hitchens <ron AT idiom.com>
14 * 04-Sep-95: Moved over from mode.h (previously resource.h) with new
15 * "&*_opts" by Heath A. Kehoe <hakehoe AT icaen.uiowa.edu>.
16 *
17 */
18
19 #include "xlock.h"
20 #ifdef USE_GL
21 # include "visgl.h"
22 #endif
23
24
25 /* -------------------------------------------------------------------- */
26
27 /*-
28 * Mode options: If count, cycles, or size options are set to 1 ...
29 * they are probably not used by the mode.
30 * To remove unwanted modes see mode.h.
31 * When adding new modes, keep them in
32 * alphabetical order for -sequential to work properly.
33 */
34
35 #ifndef USE_MODULES
36
37 LockStruct LockProcs[] =
38 {
39 #ifdef MODE_anemone
40 {(char *) "anemone", init_anemone, draw_anemone, release_anemone,
41 (ModeHook *) NULL, init_anemone, free_anemone, &anemone_opts,
42 50000, 1, 1, 1, 64, 1.0, (char *) "",
43 (char *) "Shows wiggling tentacles", 0, NULL},
44 #endif
45 #ifdef MODE_ant
46 {(char *) "ant", init_ant, draw_ant, release_ant,
47 refresh_ant, init_ant, free_ant, &ant_opts,
48 1000, -3, 40000, -12, 64, 1.0, (char *) "",
49 (char *) "Shows Langton's and Turk's generalized ants", 0, NULL},
50 #endif
51 #ifdef MODE_ant3d
52 {(char *) "ant3d", init_ant3d, draw_ant3d, release_ant3d,
53 refresh_ant3d, init_ant3d, free_ant3d, &ant3d_opts,
54 5000, -3, 10000, 1, 64, 1.0, (char *) "",
55 (char *) "Shows 3D ants", 0, NULL},
56 #endif
57 #ifdef MODE_apollonian
58 {(char *) "apollonian", init_apollonian, draw_apollonian, release_apollonian,
59 init_apollonian, init_apollonian, free_apollonian, &apollonian_opts,
60 1000000, 64, 20, 1, 64, 1.0, (char *) "",
61 (char *) "Shows Apollonian circles", 0, NULL},
62 #endif
63 #ifdef MODE_atlantis
64 {(char *) "atlantis", init_atlantis, draw_atlantis, release_atlantis,
65 (ModeHook *) NULL, change_atlantis, (ModeHook *) NULL, &atlantis_opts,
66 25000, 4, 100, 6000, 64, 1.0, (char *) "",
67 (char *) "Shows moving sharks/whales/dolphin", 0, NULL},
68 #endif
69 #ifdef MODE_atunnels
70 {(char *) "atunnels", init_atunnels, draw_atunnels, release_atunnels,
71 draw_atunnels, change_atunnels, (ModeHook *) NULL, &atunnels_opts,
72 25000, 1, 1, 0, 64, 1.0, (char *) "",
73 (char *) "Shows an OpenGL advanced tunnel screensaver", 0, NULL},
74 #endif
75 #ifdef MODE_ball
76 {(char *) "ball", init_ball, draw_ball, release_ball,
77 refresh_ball, init_ball, free_ball, &ball_opts,
78 10000, 10, 20, -100, 64, 1.0, (char *) "",
79 (char *) "Shows bouncing balls", 0, NULL},
80 #endif
81 #ifdef MODE_bat
82 {(char *) "bat", init_bat, draw_bat, release_bat,
83 refresh_bat, init_bat, free_bat, &bat_opts,
84 100000, -8, 1, 0, 64, 1.0, (char *) "",
85 (char *) "Shows bouncing flying bats", 0, NULL},
86 #endif
87 #ifdef MODE_billiards
88 {(char *) "billiards", init_billiards, draw_billiards, release_billiards,
89 refresh_billiards, init_billiards, (ModeHook *) NULL, &billiards_opts,
90 200000, 6, 30, 1, 64, 0.3, (char *) "",
91 (char *) "Shows billiards", 0, NULL},
92 #endif
93 #ifdef MODE_blot
94 {(char *) "blot", init_blot, draw_blot, release_blot,
95 refresh_blot, init_blot, free_blot, &blot_opts,
96 200000, 6, 30, 1, 64, 0.3, (char *) "",
97 (char *) "Shows Rorschach's ink blot test", 0, NULL},
98 #endif
99 #ifdef MODE_bouboule
100 {(char *) "bouboule", init_bouboule, draw_bouboule, release_bouboule,
101 refresh_bouboule, init_bouboule, (ModeHook *) NULL, &bouboule_opts,
102 10000, 100, 1, 15, 64, 1.0, (char *) "",
103 (char *) "Shows Mimi's bouboule of moving stars", 0, NULL},
104 #endif
105 #ifdef MODE_bounce
106 {(char *) "bounce", init_bounce, draw_bounce, release_bounce,
107 refresh_bounce, init_bounce, (ModeHook *) NULL, &bounce_opts,
108 5000, -10, 1, 0, 64, 1.0, (char *) "",
109 (char *) "Shows bouncing footballs", 0, NULL},
110 #endif
111 #ifdef MODE_boxed
112 {(char *) "boxed", init_boxed, draw_boxed, release_boxed,
113 draw_boxed, init_boxed, (ModeHook *) NULL, &boxed_opts,
114 1000, 1, 2, 1, 64, 1.0, (char *) "",
115 (char *) "Shows GL's boxed balls", 0, NULL},
116 #endif
117 #ifdef MODE_braid
118 {(char *) "braid", init_braid, draw_braid, release_braid,
119 refresh_braid, init_braid, (ModeHook *) NULL, &braid_opts,
120 1000, 15, 100, -7, 64, 1.0, (char *) "",
121 (char *) "Shows random braids and knots", 0, NULL},
122 #endif
123 #ifdef MODE_bubble
124 {(char *) "bubble", init_bubble, draw_bubble, release_bubble,
125 (ModeHook *) NULL, init_bubble, free_bubble, &bubble_opts,
126 100000, 25, 1, 100, 64, 0.3, (char *) "",
127 (char *) "Shows popping bubbles", 0, NULL},
128 #endif
129 #ifdef MODE_bubble3d
130 {(char *) "bubble3d", init_bubble3d, draw_bubble3d, release_bubble3d,
131 draw_bubble3d, (ModeHook *) NULL, (ModeHook *) NULL, &bubble3d_opts,
132 20000, 1, 2, 1, 64, 1.0, (char *) "",
133 (char *) "Richard Jones's GL bubbles", 0, NULL},
134 #endif
135 #ifdef MODE_bug
136 {(char *) "bug", init_bug, draw_bug, release_bug,
137 refresh_bug, init_bug, (ModeHook *) NULL, &bug_opts,
138 75000, 10, 32767, -4, 64, 1.0, (char *) "",
139 (char *) "Shows Palmiter's bug evolution and garden of Eden", 0, NULL},
140 #endif
141 #ifdef MODE_cage
142 {(char *) "cage", init_cage, draw_cage, release_cage,
143 draw_cage, change_cage, (ModeHook *) NULL, &cage_opts,
144 80000, 1, 1, 1, 64, 1.0, (char *) "",
145 (char *) "Shows the Impossible Cage, an Escher-like GL scene", 0, NULL},
146 #endif
147 #ifdef MODE_cartoon
148 {"cartoon", init_cartoon, draw_cartoon, release_cartoon,
149 NULL, init_cartoon, NULL, &cartoon_opts,
150 10000, 1, 1, 1, 64, 1.0, "",
151 "Shows bouncing cartoons", 0, NULL},
152 #endif
153 #ifdef MODE_clock
154 {(char *) "clock", init_clock, draw_clock, release_clock,
155 refresh_clock, init_clock, (ModeHook *) NULL, &clock_opts,
156 100000, -16, 200, -200, 64, 1.0, (char *) "",
157 (char *) "Shows Packard's clock", 0, NULL},
158 #endif
159 #ifdef MODE_coral
160 {(char *) "coral", init_coral, draw_coral, release_coral,
161 init_coral, init_coral, (ModeHook *) NULL, &coral_opts,
162 60000, -3, 1, 35, 64, 0.6, (char *) "",
163 (char *) "Shows a coral reef", 0, NULL},
164 #endif
165 #ifdef MODE_crystal
166 {(char *) "crystal", init_crystal, draw_crystal, release_crystal,
167 refresh_crystal, init_crystal, (ModeHook *) NULL, &crystal_opts,
168 60000, -500, 200, -15, 64, 1.0, (char *) "",
169 (char *) "Shows polygons in 2D plane groups", 0, NULL},
170 #endif
171 #ifdef MODE_daisy
172 {(char *) "daisy", init_daisy, draw_daisy, release_daisy,
173 refresh_daisy, init_daisy, (ModeHook *) NULL, &daisy_opts,
174 100000, 300, 350, 1, 64, 1.0, (char *) "",
175 (char *) "Shows a meadow of daisies", 0, NULL},
176 #endif
177 #ifdef MODE_dclock
178 {(char *) "dclock", init_dclock, draw_dclock, release_dclock,
179 refresh_dclock, init_dclock, (ModeHook *) NULL, &dclock_opts,
180 10000, 1, 10000, 1, 64, 0.3, (char *) "",
181 (char *) "Shows a floating digital clock or message", 0, NULL},
182 #endif
183 #ifdef MODE_decay
184 {(char *) "decay", init_decay, draw_decay, release_decay,
185 refresh_decay, init_decay, (ModeHook *) NULL, &decay_opts,
186 200000, 6, 30, 1, 64, 0.3, (char *) "",
187 (char *) "Shows a decaying screen", 0, NULL},
188 #endif
189 #ifdef MODE_deco
190 {(char *) "deco", init_deco, draw_deco, release_deco,
191 init_deco, init_deco, (ModeHook *) NULL, &deco_opts,
192 1000000, -30, 2, -10, 64, 0.6, (char *) "",
193 (char *) "Shows art as ugly as sin", 0, NULL},
194 #endif
195 #ifdef MODE_deluxe
196 {(char *) "deluxe", init_deluxe, draw_deluxe, release_deluxe,
197 (ModeHook *) NULL, init_deluxe, (ModeHook *) NULL, &deluxe_opts,
198 5000, 5, 1, 1, 64, 1.0, (char *) "",
199 (char *) "Shows pulsing sequence of stars, circles, and lines", 0, NULL},
200 #endif
201 #ifdef MODE_demon
202 {(char *) "demon", init_demon, draw_demon, release_demon,
203 refresh_demon, init_demon, (ModeHook *) NULL, &demon_opts,
204 50000, 0, 1000, -7, 64, 1.0, (char *) "",
205 (char *) "Shows Griffeath's cellular automata", 0, NULL},
206 #endif
207 #ifdef MODE_dilemma
208 {(char *) "dilemma", init_dilemma, draw_dilemma, release_dilemma,
209 refresh_dilemma, init_dilemma, (ModeHook *) NULL, &dilemma_opts,
210 200000, -2, 1000, 0, 64, 1.0, (char *) "",
211 (char *) "Shows Lloyd's Prisoner's Dilemma simulation", 0, NULL},
212 #endif
213 #ifdef MODE_discrete
214 {(char *) "discrete", init_discrete, draw_discrete, release_discrete,
215 refresh_discrete, init_discrete, (ModeHook *) NULL, &discrete_opts,
216 1000, 4096, 2500, 1, 64, 1.0, (char *) "",
217 (char *) "Shows various discrete maps", 0, NULL},
218 #endif
219 #ifdef MODE_dragon
220 {(char *) "dragon", init_dragon, draw_dragon, release_dragon,
221 refresh_dragon, init_dragon, (ModeHook *) NULL, &dragon_opts,
222 2000000, 1, 16, -24, 64, 1.0, (char *) "",
223 (char *) "Shows Deventer's Hexagonal Dragons Maze", 0, NULL},
224 #endif
225 #ifdef MODE_drift
226 {(char *) "drift", init_drift, draw_drift, release_drift,
227 refresh_drift, init_drift, (ModeHook *) NULL, &drift_opts,
228 10000, 30, 1, 1, 64, 1.0, (char *) "",
229 (char *) "Shows cosmic drifting flame fractals", 0, NULL},
230 #endif
231 #ifdef MODE_euler2d
232 {(char *) "euler2d", init_euler2d, draw_euler2d, release_euler2d,
233 refresh_euler2d, init_euler2d, (ModeHook *) NULL, &euler2d_opts,
234 1000, 1024, 3000, 1, 64, 1.0, (char *) "",
235 (char *) "Shows a simulation of 2D incompressible inviscid fluid", 0, NULL},
236 #endif
237 #ifdef MODE_eyes
238 {(char *) "eyes", init_eyes, draw_eyes, release_eyes,
239 refresh_eyes, init_eyes, (ModeHook *) NULL, &eyes_opts,
240 20000, -8, 5, 1, 64, 1.0, (char *) "",
241 (char *) "Shows eyes following a bouncing grelb", 0, NULL},
242 #endif
243 #ifdef MODE_fadeplot
244 {(char *) "fadeplot", init_fadeplot, draw_fadeplot, release_fadeplot,
245 refresh_fadeplot, init_fadeplot, (ModeHook *) NULL, &fadeplot_opts,
246 30000, 10, 1500, 1, 64, 0.6, (char *) "",
247 (char *) "Shows a fading plot of sine squared", 0, NULL},
248 #endif
249 #ifdef MODE_fiberlamp
250 {(char *) "fiberlamp", init_fiberlamp, draw_fiberlamp, release_fiberlamp,
251 draw_fiberlamp, change_fiberlamp, (ModeHook *) NULL, &fiberlamp_opts,
252 10000, 500, 10000, 0, 64, 1.0, (char *) "",
253 (char *) "Shows a Fiber Optic Lamp", 0, NULL},
254 #endif
255 #ifdef MODE_fire
256 {(char *) "fire", init_fire, draw_fire, release_fire,
257 draw_fire, change_fire, (ModeHook *) NULL, &fire_opts,
258 10000, 800, 1, 0, 64, 1.0, (char *) "",
259 (char *) "Shows a 3D fire-like image", 0, NULL},
260 #endif
261 #ifdef MODE_flag
262 {(char *) "flag", init_flag, draw_flag, release_flag,
263 refresh_flag, init_flag, (ModeHook *) NULL, &flag_opts,
264 50000, 1, 1000, -7, 64, 1.0, (char *) "",
265 (char *) "Shows a waving flag image", 0, NULL},
266 #endif
267 #ifdef MODE_flame
268 {(char *) "flame", init_flame, draw_flame, release_flame,
269 refresh_flame, init_flame, (ModeHook *) NULL, &flame_opts,
270 750000, 20, 10000, 1, 64, 1.0, (char *) "",
271 (char *) "Shows cosmic flame fractals", 0, NULL},
272 #endif
273 #ifdef MODE_flow
274 {(char *) "flow", init_flow, draw_flow, release_flow,
275 refresh_flow, init_flow, (ModeHook *) NULL, &flow_opts,
276 1000, 1024, 10000, -10, 64, 1.0, (char *) "",
277 (char *) "Shows dynamic strange attractors", 0, NULL},
278 #endif
279 #ifdef MODE_forest
280 {(char *) "forest", init_forest, draw_forest, release_forest,
281 refresh_forest, init_forest, (ModeHook *) NULL, &forest_opts,
282 400000, 100, 200, 1, 64, 1.0, (char *) "",
283 (char *) "Shows binary trees of a fractal forest", 0, NULL},
284 #endif
285 #ifdef MODE_fzort
286 {(char *) "fzort", init_fzort, draw_fzort, release_fzort,
287 refresh_fzort, init_fzort, (ModeHook *) NULL, &fzort_opts,
288 10000, 1, 1000, 1, 64, 1.0, (char *) "",
289 (char *) "Draws a metallic-looking fzort.", 0, NULL},
290 #endif
291 #ifdef MODE_galaxy
292 {(char *) "galaxy", init_galaxy, draw_galaxy, release_galaxy,
293 refresh_galaxy, init_galaxy, (ModeHook *) NULL, &galaxy_opts,
294 100, -5, 250, -3, 64, 1.0, (char *) "",
295 (char *) "Shows crashing spiral galaxies", 0, NULL},
296 #endif
297 #ifdef MODE_gears
298 {(char *) "gears", init_gears, draw_gears, release_gears,
299 draw_gears, init_gears, (ModeHook *) NULL, &gears_opts,
300 50000, 1, 2, 1, 64, 1.0, (char *) "",
301 (char *) "Shows GL's gears", 0, NULL},
302 #endif
303 #ifdef MODE_glplanet
304 {(char *) "glplanet", init_glplanet, draw_glplanet, release_glplanet,
305 draw_glplanet, init_glplanet, (ModeHook *) NULL, &glplanet_opts,
306 15000, 1, 2, 1, 64, 1.0, (char *) "",
307 (char *) "Animates texture mapped sphere (planet)", 0, NULL},
308 #endif
309 #ifdef MODE_goop
310 {(char *) "goop", init_goop, draw_goop, release_goop,
311 init_goop, init_goop, (ModeHook *) NULL, &goop_opts,
312 10000, -12, 1, 1, 64, 1.0, (char *) "",
313 (char *) "Shows goop from a lava lamp", 0, NULL},
314 #endif
315 #ifdef MODE_grav
316 {(char *) "grav", init_grav, draw_grav, release_grav,
317 refresh_grav, init_grav, (ModeHook *) NULL, &grav_opts,
318 10000, -12, 1, 1, 64, 1.0, (char *) "",
319 (char *) "Shows orbiting planets", 0, NULL},
320 #endif
321 #ifdef MODE_helix
322 {(char *) "helix", init_helix, draw_helix, release_helix,
323 refresh_helix, init_helix, (ModeHook *) NULL, &helix_opts,
324 25000, 1, 100, 1, 64, 1.0, (char *) "",
325 (char *) "Shows string art", 0, NULL},
326 #endif
327 #ifdef MODE_hop
328 {(char *) "hop", init_hop, draw_hop, release_hop,
329 refresh_hop, init_hop, (ModeHook *) NULL, &hop_opts,
330 10000, 1000, 2500, 1, 64, 1.0, (char *) "",
331 (char *) "Shows real plane iterated fractals", 0, NULL},
332 #endif
333 #ifdef MODE_hyper
334 {(char *) "hyper", init_hyper, draw_hyper, release_hyper,
335 refresh_hyper, change_hyper, (ModeHook *) NULL, &hyper_opts,
336 100000, -6, 300, 1, 64, 1.0, (char *) "",
337 (char *) "Shows spinning n-dimensional hypercubes", 0, NULL},
338 #endif
339 #ifdef MODE_ico
340 {(char *) "ico", init_ico, draw_ico, release_ico,
341 refresh_ico, change_ico, (ModeHook *) NULL, &ico_opts,
342 200000, 0, 400, 0, 64, 1.0, (char *) "",
343 (char *) "Shows a bouncing polyhedron", 0, NULL},
344 #endif
345 #ifdef MODE_ifs
346 {(char *) "ifs", init_ifs, draw_ifs, release_ifs,
347 init_ifs, init_ifs, (ModeHook *) NULL, &ifs_opts,
348 1000, 1, 1, 1, 64, 1.0, (char *) "",
349 (char *) "Shows a modified iterated function system", 0, NULL},
350 #endif
351 #ifdef MODE_image
352 {(char *) "image", init_image, draw_image, release_image,
353 refresh_image, init_image, (ModeHook *) NULL, &image_opts,
354 3000000, -20, 1, 1, 64, 1.0, (char *) "",
355 (char *) "Shows randomly appearing logos", 0, NULL},
356 #endif
357 #ifdef MODE_invert
358 {(char *) "invert", init_invert, draw_invert, release_invert,
359 draw_invert, init_invert, (ModeHook *) NULL, &invert_opts,
360 80000, 1, 1, 1, 64, 1.0, (char *) "",
361 (char *) "Shows a sphere inverted without wrinkles", 0, NULL},
362 #endif
363 #ifdef MODE_juggle
364 {(char *) "juggle", init_juggle, draw_juggle, release_juggle,
365 draw_juggle, change_juggle, (ModeHook *) NULL, &juggle_opts,
366 10000, 200, 1000, 1, 64, 1.0, (char *) "",
367 (char *) "Shows a Juggler, juggling", 0, NULL},
368 #endif
369 #ifdef MODE_juggler3d
370 {(char *) "juggler3d", init_juggler3d, draw_juggler3d, release_juggler3d,
371 draw_juggler3d, change_juggler3d, (ModeHook *) NULL, &juggler3d_opts,
372 10000, 200, 1000, 1, 64, 1.0, (char *) "",
373 (char *) "Shows a 3D Juggler, juggling", 0, NULL},
374 #endif
375 #ifdef MODE_julia
376 {(char *) "julia", init_julia, draw_julia, release_julia,
377 refresh_julia, init_julia, (ModeHook *) NULL, &julia_opts,
378 10000, 1000, 20, 1, 64, 1.0, (char *) "",
379 (char *) "Shows the Julia set", 0, NULL},
380 #endif
381 #ifdef MODE_kaleid
382 {(char *) "kaleid", init_kaleid, draw_kaleid, release_kaleid,
383 refresh_kaleid, init_kaleid, (ModeHook *) NULL, &kaleid_opts,
384 80000, 4, 40, -9, 64, 0.6, (char *) "",
385 (char *) "Shows a kaleidoscope", 0, NULL},
386 #endif
387 #ifdef MODE_kaleid2
388 {"kaleid2", init_kaleid2, draw_kaleid2, release_kaleid2,
389 refresh_kaleid2, init_kaleid2, NULL, &kaleid2_opts,
390 20000, 1, 700, 1, 64, 1.0, "",
391 (char *) "Shows a kaleidoscope", 0, NULL},
392 #endif
393 #ifdef MODE_kumppa
394 {(char *) "kumppa", init_kumppa, draw_kumppa, release_kumppa,
395 init_kumppa, init_kumppa, (ModeHook *) NULL, &kumppa_opts,
396 10000, 1, 1000, 1, 64, 1.0, (char *) "",
397 (char *) "Shows kumppa", 0, NULL},
398 #endif
399 #ifdef MODE_lament
400 {(char *) "lament", init_lament, draw_lament, release_lament,
401 draw_lament, change_lament, (ModeHook *) NULL, &lament_opts,
402 10000, 1, 1, 1, 64, 1.0, (char *) "",
403 (char *) "Shows Lemarchand's Box", 0, NULL},
404 #endif
405 #ifdef MODE_laser
406 {(char *) "laser", init_laser, draw_laser, release_laser,
407 refresh_laser, init_laser, free_laser, &laser_opts,
408 20000, -10, 200, 1, 64, 1.0, (char *) "",
409 (char *) "Shows spinning lasers", 0, NULL},
410 #endif
411 #ifdef MODE_life
412 {(char *) "life", init_life, draw_life, release_life,
413 refresh_life, change_life, free_life, &life_opts,
414 750000, 40, 140, 0, 64, 1.0, (char *) "",
415 (char *) "Shows Conway's game of Life", 0, NULL},
416 #endif
417 #ifdef MODE_life1d
418 {(char *) "life1d", init_life1d, draw_life1d, release_life1d,
419 refresh_life1d, init_life1d, free_life1d, &life1d_opts,
420 100000, -5, 1200, -15, 64, 1.0, (char *) "",
421 (char *) "Shows Wolfram's game of 1D Life", 0, NULL},
422 #endif
423 #ifdef MODE_life3d
424 {(char *) "life3d", init_life3d, draw_life3d, release_life3d,
425 refresh_life3d, change_life3d, free_life3d, &life3d_opts,
426 1000000, 35, 85, 1, 64, 1.0, (char *) "",
427 (char *) "Shows Bays' game of 3D Life", 0, NULL},
428 #endif
429 #ifdef MODE_lightning
430 {(char *) "lightning", init_lightning, draw_lightning, release_lightning,
431 (ModeHook *) NULL, init_lightning, (ModeHook *) NULL, &lightning_opts,
432 10000, 1, 1, 1, 64, 0.6, (char *) "",
433 (char *) "Shows Keith's fractal lightning bolts", 0, NULL},
434 #endif
435 #ifdef MODE_lisa
436 {(char *) "lisa", init_lisa, draw_lisa, release_lisa,
437 refresh_lisa, change_lisa, (ModeHook *) NULL, &lisa_opts,
438 25000, 1, 256, -1, 64, 1.0, (char *) "",
439 (char *) "Shows animated lisajous loops", 0, NULL},
440 #endif
441 #ifdef MODE_lissie
442 {(char *) "lissie", init_lissie, draw_lissie, release_lissie,
443 refresh_lissie, init_lissie, (ModeHook *) NULL, &lissie_opts,
444 10000, 1, 2000, -200, 64, 0.6, (char *) "",
445 (char *) "Shows lissajous worms", 0, NULL},
446 #endif
447 #ifdef MODE_loop
448 {(char *) "loop", init_loop, draw_loop, release_loop,
449 refresh_loop, init_loop, (ModeHook *) NULL, &loop_opts,
450 100000, -5, 1600, -12, 64, 1.0, (char *) "",
451 (char *) "Shows Langton's self-producing loops", 0, NULL},
452 #endif
453 #ifdef MODE_lyapunov
454 {(char *) "lyapunov", init_lyapunov, draw_lyapunov, release_lyapunov,
455 (ModeHook *) NULL, init_lyapunov, (ModeHook *) NULL, &lyapunov_opts,
456 25000, 600, 1, 1, 64, 1.0, (char *) "",
457 (char *) "Shows lyapunov space", 0, NULL},
458 #endif
459 #ifdef MODE_mandelbrot
460 {(char *) "mandelbrot", init_mandelbrot, draw_mandelbrot, release_mandelbrot,
461 (ModeHook *) NULL, init_mandelbrot, (ModeHook *) NULL, &mandelbrot_opts,
462 25000, -8, 20000, 1, 64, 1.0, (char *) "",
463 (char *) "Shows mandelbrot sets", 0, NULL},
464 #endif
465 #ifdef MODE_marquee
466 {(char *) "marquee", init_marquee, draw_marquee, release_marquee,
467 init_marquee, init_marquee, (ModeHook *) NULL, &marquee_opts,
468 100000, 1, 1, 1, 64, 1.0, (char *) "",
469 (char *) "Shows messages", 0, NULL},
470 #endif
471 #ifdef MODE_matrix
472 {(char *) "matrix", init_matrix, draw_matrix, release_matrix,
473 refresh_matrix, change_matrix, (ModeHook *) NULL, &matrix_opts,
474 1000, 1, 1, 1, 64, 1.0, (char *) "",
475 (char *) "Shows the Matrix", 0, NULL},
476 #endif
477 #ifdef MODE_maze
478 {(char *) "maze", init_maze, draw_maze, release_maze,
479 refresh_maze, init_maze, (ModeHook *) NULL, &maze_opts,
480 1000, 1, 3000, -40, 64, 1.0, (char *) "",
481 (char *) "Shows a random maze and a depth first search solution", 0, NULL},
482 #endif
483 #ifdef MODE_maze3d
484 {(char *) "maze3d", init_maze3d, draw_maze3d, release_maze3d,
485 draw_maze3d, init_maze3d, (ModeHook *) NULL, &maze3d_opts,
486 20000, 1, 2, 1, 64, 1.0, (char *) "",
487 (char *) "Shows a 3D maze", 0, NULL},
488 #endif
489 #ifdef MODE_moebius
490 {(char *) "moebius", init_moebius, draw_moebius, release_moebius,
491 draw_moebius, change_moebius, (ModeHook *) NULL, &moebius_opts,
492 30000, 1, 1, 1, 64, 1.0, (char *) "",
493 (char *) "Shows Moebius Strip II, an Escher-like GL scene with ants", 0, NULL},
494 #endif
495 #ifdef MODE_molecule
496 {(char *) "molecule", init_molecule, draw_molecule, release_molecule,
497 draw_molecule, init_molecule, (ModeHook *) NULL, &molecule_opts,
498 50000, 1, 20, 1, 64, 1.0, (char *) "",
499 (char *) "Draws molecules", 0, NULL},
500 #endif
501 #ifdef MODE_morph3d
502 {(char *) "morph3d", init_morph3d, draw_morph3d, release_morph3d,
503 draw_morph3d, change_morph3d, (ModeHook *) NULL, &morph3d_opts,
504 40000, 0, 1, 1, 64, 1.0, (char *) "",
505 (char *) "Shows GL morphing polyhedra", 0, NULL},
506 #endif
507 #ifdef MODE_mountain
508 {(char *) "mountain", init_mountain, draw_mountain, release_mountain,
509 refresh_mountain, init_mountain, (ModeHook *) NULL, &mountain_opts,
510 1000, 30, 4000, 1, 64, 1.0, (char *) "",
511 (char *) "Shows Papo's mountain range", 0, NULL},
512 #endif
513 #ifdef MODE_munch
514 {(char *) "munch", init_munch, draw_munch, release_munch,
515 init_munch, init_munch, (ModeHook *) NULL, &munch_opts,
516 5000, 1, 7, 1, 64, 1.0, (char *) "",
517 (char *) "Shows munching squares", 0, NULL},
518 #endif
519 #ifdef MODE_noof
520 {(char *) "noof", init_noof, draw_noof, release_noof,
521 draw_noof, init_noof, (ModeHook *) NULL, &noof_opts,
522 1000, 1, 1, 1, 64, 1.0, (char *) "",
523 (char *) "Shows SGI Diatoms", 0, NULL},
524 #endif
525 #ifdef MODE_nose
526 {(char *) "nose", init_nose, draw_nose, release_nose,
527 refresh_nose, init_nose, (ModeHook *) NULL, &nose_opts,
528 100000, 1, 1, 1, 64, 1.0, (char *) "",
529 (char *) "Shows a man with a big nose runs around spewing out messages", 0, NULL},
530 #endif
531 #ifdef MODE_pacman
532 {(char *) "pacman", init_pacman, draw_pacman, release_pacman,
533 refresh_pacman, change_pacman, (ModeHook *) NULL, &pacman_opts,
534 20000, 10, 1, 0, 64, 1.0, (char *) "",
535 (char *) "Shows Pacman(tm)", 0, NULL},
536 #endif
537 #ifdef MODE_penrose
538 {(char *) "penrose", init_penrose, draw_penrose, release_penrose,
539 init_penrose, init_penrose, (ModeHook *) NULL, &penrose_opts,
540 10000, 1, 1, -40, 64, 1.0, (char *) "",
541 (char *) "Shows Penrose's quasiperiodic tilings", 0, NULL},
542 #endif
543 #ifdef MODE_petal
544 {(char *) "petal", init_petal, draw_petal, release_petal,
545 refresh_petal, init_petal, (ModeHook *) NULL, &petal_opts,
546 10000, -500, 400, 1, 64, 1.0, (char *) "",
547 (char *) "Shows various GCD Flowers", 0, NULL},
548 #endif
549 #ifdef MODE_petri
550 {(char *) "petri", init_petri, draw_petri, release_petri,
551 refresh_petri, init_petri, (ModeHook *) NULL, &petri_opts,
552 10000, 1, 1, 4, 8, 1.0, (char *) "",
553 (char *) "Shows a mold simulation in a petri dish", 0, NULL},
554 #endif
555 #ifdef MODE_pipes
556 {(char *) "pipes", init_pipes, draw_pipes, release_pipes,
557 #if defined( MESA ) && defined( SLOW )
558 draw_pipes,
559 #else
560 change_pipes,
561 #endif
562 change_pipes, (ModeHook *) NULL, &pipes_opts,
563 1000, 2, 5, 500, 64, 1.0, (char *) "",
564 (char *) "Shows a selfbuilding pipe system", 0, NULL},
565 #endif
566 #ifdef MODE_polyominoes
567 {(char *) "polyominoes", init_polyominoes, draw_polyominoes, release_polyominoes,
568 refresh_polyominoes, init_polyominoes, (ModeHook *) NULL, &polyominoes_opts,
569 6000, 1, 8192, 1, 64, 1.0, (char *) "",
570 (char *) "Shows attempts to place polyominoes into a rectangle", 0, NULL},
571 #endif
572 #ifdef MODE_puzzle
573 {(char *) "puzzle", init_puzzle, draw_puzzle, release_puzzle,
574 init_puzzle, init_puzzle, (ModeHook *) NULL, &puzzle_opts,
575 10000, 250, 1, 1, 64, 1.0, (char *) "",
576 (char *) "Shows a puzzle being scrambled and then solved", 0, NULL},
577 #endif
578 #ifdef MODE_pyro
579 {(char *) "pyro", init_pyro, draw_pyro, release_pyro,
580 refresh_pyro, init_pyro, (ModeHook *) NULL, &pyro_opts,
581 15000, 100, 1, -3, 64, 1.0, (char *) "",
582 (char *) "Shows fireworks", 0, NULL},
583 #endif
584 #ifdef MODE_pyro2
585 {(char *) "pyro2", init_pyro2, draw_pyro2, release_pyro2,
586 refresh_pyro2, init_pyro2, (ModeHook *) NULL, &pyro2_opts,
587 15000, 100, 1, -3, 64, 1.0, (char *) "",
588 (char *) "Shows other fireworks", 0, NULL},
589 #endif
590 #ifdef MODE_qix
591 {(char *) "qix", init_qix, draw_qix, release_qix,
592 refresh_qix, init_qix, free_qix, &qix_opts,
593 30000, -5, 32, 1, 64, 1.0, (char *) "",
594 (char *) "Shows spinning lines a la Qix(tm)", 0, NULL},
595 #endif
596 #ifdef MODE_rain
597 {(char *) "rain", init_rain, draw_rain, release_rain,
598 refresh_rain, init_rain, (ModeHook *) NULL, &rain_opts,
599 35000, 1, 1, 1, 64, 0.3, (char *) "",
600 (char *) "It's raining", 0, NULL},
601 #endif
602 #ifdef MODE_roll
603 {(char *) "roll", init_roll, draw_roll, release_roll,
604 refresh_roll, init_roll, (ModeHook *) NULL, &roll_opts,
605 100000, 25, 1, -64, 64, 0.6, (char *) "",
606 (char *) "Shows a rolling ball", 0, NULL},
607 #endif
608 #ifdef MODE_rotor
609 {(char *) "rotor", init_rotor, draw_rotor, release_rotor,
610 refresh_rotor, init_rotor, (ModeHook *) NULL, &rotor_opts,
611 100, 4, 100, -6, 64, 0.3, (char *) "",
612 (char *) "Shows Tom's Roto-Rooter", 0, NULL},
613 #endif
614 #ifdef MODE_rubik
615 {(char *) "rubik", init_rubik, draw_rubik, release_rubik,
616 draw_rubik, change_rubik, (ModeHook *) NULL, &rubik_opts,
617 100000, -30, 5, -6, 64, 1.0, (char *) "",
618 (char *) "Shows an auto-solving Rubik's Cube", 0, NULL},
619 #endif
620 #ifdef MODE_sballs
621 {(char *) "sballs", init_sballs, draw_sballs, release_sballs,
622 draw_sballs, change_sballs, (ModeHook *) NULL, &sballs_opts,
623 40000, 0, 10, 0, 64, 1.0, (char *) "",
624 (char *) "Shows balls spinning like crazy in GL", 0, NULL},
625 #endif
626 #ifdef MODE_scooter
627 {(char *) "scooter", init_scooter, draw_scooter, release_scooter,
628 refresh_scooter, change_scooter, (ModeHook *) NULL, &scooter_opts,
629 20000, 24, 3, 100, 64, 1.0, (char *) "",
630 (char *) "Shows a journey through space tunnel and stars", 0, NULL},
631 #endif
632 #ifdef MODE_shape
633 {(char *) "shape", init_shape, draw_shape, release_shape,
634 refresh_shape, init_shape, (ModeHook *) NULL, &shape_opts,
635 10000, 100, 256, 1, 64, 1.0, (char *) "",
636 (char *) "Shows stippled rectangles, ellipses, and triangles", 0, NULL},
637 #endif
638 #ifdef MODE_sierpinski
639 {(char *) "sierpinski", init_sierpinski, draw_sierpinski, release_sierpinski,
640 refresh_sierpinski, init_sierpinski, (ModeHook *) NULL, &sierpinski_opts,
641 400000, 2000, 100, 1, 64, 1.0, (char *) "",
642 (char *) "Shows Sierpinski's triangle", 0, NULL},
643 #endif
644 #ifdef MODE_sierpinski3d
645 {(char *) "sierpinski3d", init_gasket, draw_gasket, release_gasket,
646 draw_gasket, init_gasket, (ModeHook *) NULL, &gasket_opts,
647 1000, 1, 2, 1, 64, 1.0, (char *) "",
648 (char *) "Shows GL's Sierpinski gasket", 0, NULL},
649 #endif
650 #ifdef MODE_skewb
651 {(char *) "skewb", init_skewb, draw_skewb, release_skewb,
652 draw_skewb, change_skewb, (ModeHook *) NULL, &skewb_opts,
653 100000, -30, 5, 1, 64, 1.0, (char *) "",
654 (char *) "Shows an auto-solving Skewb", 0, NULL},
655 #endif
656 #ifdef MODE_slip
657 {(char *) "slip", init_slip, draw_slip, release_slip,
658 init_slip, init_slip, (ModeHook *) NULL, &slip_opts,
659 50000, 35, 50, 1, 64, 1.0, (char *) "",
660 (char *) "Shows slipping blits", 0, NULL},
661 #endif
662 #ifdef MODE_solitaire
663 {(char *) "solitaire", init_solitaire, draw_solitaire, release_solitaire,
664 refresh_solitaire, init_solitaire, (ModeHook *) NULL, &solitaire_opts,
665 2000000, 1, 1, 1, 64, 1.0, (char *) "",
666 (char *) "Shows Klondike's game of solitaire", 0, NULL},
667 #endif
668 #ifdef MODE_space
669 {(char *) "space", init_space, draw_space, release_space,
670 (ModeHook *) NULL, init_space, (ModeHook *) NULL, &space_opts,
671 10000, 100, 1, 1, 64, 1.0, (char *) "",
672 (char *) "Shows a journey into deep space", 0, NULL},
673 #endif
674 #ifdef MODE_sphere
675 {(char *) "sphere", init_sphere, draw_sphere, release_sphere,
676 refresh_sphere, init_sphere, (ModeHook *) NULL, &sphere_opts,
677 5000, 1, 20, 0, 64, 1.0, (char *) "",
678 (char *) "Shows a bunch of shaded spheres", 0, NULL},
679 #endif
680 #ifdef MODE_spiral
681 {(char *) "spiral", init_spiral, draw_spiral, release_spiral,
682 refresh_spiral, init_spiral, (ModeHook *) NULL, &spiral_opts,
683 5000, -40, 350, 1, 64, 1.0, (char *) "",
684 (char *) "Shows a helical locus of points", 0, NULL},
685 #endif
686 #ifdef MODE_spline
687 {(char *) "spline", init_spline, draw_spline, release_spline,
688 refresh_spline, init_spline, (ModeHook *) NULL, &spline_opts,
689 30000, -6, 2048, 1, 64, 0.3, (char *) "",
690 (char *) "Shows colorful moving splines", 0, NULL},
691 #endif
692 #ifdef MODE_sproingies
693 {(char *) "sproingies", init_sproingies, draw_sproingies, release_sproingies,
694 (ModeHook *) NULL, init_sproingies, (ModeHook *) NULL, &sproingies_opts,
695 80000, 5, 0, 0, 64, 1.0, (char *) "",
696 (char *) "Shows Sproingies! Nontoxic. Safe for pets and small children", 0, NULL},
697 #endif
698 #ifdef MODE_stairs
699 {(char *) "stairs", init_stairs, draw_stairs, release_stairs,
700 draw_stairs, change_stairs, (ModeHook *) NULL, &stairs_opts,
701 200000, 0, 1, 1, 64, 1.0, (char *) "",
702 (char *) "Shows some Infinite Stairs, an Escher-like scene", 0, NULL},
703 #endif
704 #ifdef MODE_star
705 {(char *) "star", init_star, draw_star, release_star,
706 refresh_star, init_star, (ModeHook *) NULL, &star_opts,
707 75000, 100, 1, 100, 64, 0.3, (char *) "",
708 (char *) "Shows a star field with a twist", 0, NULL},
709 #endif
710 #ifdef MODE_starfish
711 {(char *) "starfish", init_starfish, draw_starfish, release_starfish,
712 init_starfish, init_starfish, (ModeHook *) NULL, &starfish_opts,
713 2000, 1, 1000, 1, 64, 1.0, (char *) "",
714 (char *) "Shows starfish", 0, NULL},
715 #endif
716 #ifdef MODE_strange
717 {(char *) "strange", init_strange, draw_strange, release_strange,
718 init_strange, init_strange, (ModeHook *) NULL, &strange_opts,
719 10000, 1, 1, 1, 64, 1.0, (char *) "",
720 (char *) "Shows strange attractors", 0, NULL},
721 #endif
722 #ifdef MODE_superquadrics
723 {(char *) "superquadrics", init_superquadrics, draw_superquadrics, release_superquadrics,
724 (ModeHook *) NULL, init_superquadrics, (ModeHook *) NULL, &superquadrics_opts,
725 40000, 25, 40, 1, 64, 1.0, (char *) "",
726 (char *) "Shows 3D mathematical shapes", 0, NULL},
727 #endif
728 #ifdef MODE_swarm
729 {(char *) "swarm", init_swarm, draw_swarm, release_swarm,
730 refresh_swarm, init_swarm, (ModeHook *) NULL, &swarm_opts,
731 15000, -100, 1, -10, 64, 1.0, (char *) "",
732 (char *) "Shows a swarm of bees following a wasp", 0, NULL},
733 #endif
734 #ifdef MODE_swirl
735 {(char *) "swirl", init_swirl, draw_swirl, release_swirl,
736 refresh_swirl, init_swirl, (ModeHook *) NULL, &swirl_opts,
737 5000, 5, 1, 1, 64, 1.0, (char *) "",
738 (char *) "Shows animated swirling patterns", 0, NULL},
739 #endif
740 #ifdef MODE_t3d
741 {(char *) "t3d", init_t3d, draw_t3d, release_t3d,
742 refresh_t3d, init_t3d, (ModeHook *) NULL, &t3d_opts,
743 250000, 1, 60000, 1, 64, 1.0, (char *) "",
744 (char *) "Shows a Flying Balls Clock Demo", 0, NULL},
745 #endif
746 #ifdef MODE_tetris
747 {(char *) "tetris", init_tetris, draw_tetris, release_tetris,
748 refresh_tetris, change_tetris, (ModeHook *) NULL, &tetris_opts,
749 50000, 1, 1, -100, 64, 1.0, (char *) "",
750 (char *) "Shows an autoplaying tetris game", 0, NULL},
751 #endif
752 #ifdef MODE_text3d
753 {(char *) "text3d", init_text3d, draw_text3d, release_text3d,
754 refresh_text3d, change_text3d, (ModeHook *) NULL, &text3d_opts,
755 100000, 10, 1, 1, 64, 1.0, (char *) "",
756 (char *) "Shows 3D text", 0, NULL},
757 #endif
758 #ifdef MODE_text3d2
759 {(char *) "text3d2", init_text3d2, draw_text3d2, release_text3d2,
760 refresh_text3d2, change_text3d2, (ModeHook *) NULL, &text3d2_opts,
761 100000, 10, 1, 1, 64, 1.0, (char *) "",
762 (char *) "Shows 3D text", 0, NULL},
763 #endif
764 #ifdef MODE_thornbird
765 {(char *) "thornbird", init_thornbird, draw_thornbird, release_thornbird,
766 refresh_thornbird, init_thornbird, (ModeHook *) NULL, þbird_opts,
767 1000, 800, 16, 1, 64, 1.0, (char *) "",
768 (char *) "Shows an animated bird in a thorn bush fractal map", 0, NULL},
769 #endif
770 #ifdef MODE_tik_tak
771 {(char *) "tik_tak", init_tik_tak, draw_tik_tak, release_tik_tak,
772 refresh_tik_tak, init_tik_tak, (ModeHook *) NULL, &tik_tak_opts,
773 60000, -20, 200, -1000, 64, 1.0, (char *) "",
774 (char *) "Shows rotating polygons", 0, NULL},
775 #endif
776 #ifdef MODE_toneclock
777 {(char *) "toneclock", init_toneclock, draw_toneclock, release_toneclock,
778 refresh_toneclock, init_toneclock, (ModeHook *) NULL, &toneclock_opts,
779 60000, -20, 200, -1000, 64, 1.0, (char *) "",
780 (char *) "Shows Peter Schat's toneclock", 0, NULL},
781 #endif
782 #ifdef MODE_triangle
783 {(char *) "triangle", init_triangle, draw_triangle, release_triangle,
784 refresh_triangle, init_triangle, (ModeHook *) NULL, &triangle_opts,
785 10000, 1, 1, 1, 64, 1.0, (char *) "",
786 (char *) "Shows a triangle mountain range", 0, NULL},
787 #endif
788 #ifdef MODE_tube
789 {(char *) "tube", init_tube, draw_tube, release_tube,
790 (ModeHook *) NULL, init_tube, (ModeHook *) NULL, &tube_opts,
791 25000, -9, 20000, -200, 64, 1.0, (char *) "",
792 (char *) "Shows an animated tube", 0, NULL},
793 #endif
794 #ifdef MODE_turtle
795 {(char *) "turtle", init_turtle, draw_turtle, release_turtle,
796 init_turtle, init_turtle, (ModeHook *) NULL, &turtle_opts,
797 1000000, 1, 20, 1, 64, 1.0, (char *) "",
798 (char *) "Shows turtle fractals", 0, NULL},
799 #endif
800 #ifdef MODE_vines
801 {(char *) "vines", init_vines, draw_vines, release_vines,
802 refresh_vines, init_vines, (ModeHook *) NULL, &vines_opts,
803 200000, 0, 1, 1, 64, 1.0, (char *) "",
804 (char *) "Shows fractals", 0, NULL},
805 #endif
806 #ifdef MODE_voters
807 {(char *) "voters", init_voters, draw_voters, release_voters,
808 refresh_voters, init_voters, (ModeHook *) NULL, &voters_opts,
809 1000, 0, 327670, 0, 64, 1.0, (char *) "",
810 (char *) "Shows Dewdney's Voters", 0, NULL},
811 #endif
812 #ifdef MODE_wator
813 {(char *) "wator", init_wator, draw_wator, release_wator,
814 refresh_wator, init_wator, (ModeHook *) NULL, &wator_opts,
815 750000, 1, 32767, 0, 64, 1.0, (char *) "",
816 (char *) "Shows Dewdney's Water-Torus planet of fish and sharks", 0, NULL},
817 #endif
818 #ifdef MODE_wire
819 {(char *) "wire", init_wire, draw_wire, release_wire,
820 refresh_wire, init_wire, (ModeHook *) NULL, &wire_opts,
821 500000, 1000, 150, -8, 64, 1.0, (char *) "",
822 (char *) "Shows a random circuit with 2 electrons", 0, NULL},
823 #endif
824 #ifdef MODE_world
825 {(char *) "world", init_world, draw_world, release_world,
826 refresh_world, init_world, (ModeHook *) NULL, &world_opts,
827 100000, -16, 1, 1, 64, 0.3, (char *) "",
828 (char *) "Shows spinning Earths", 0, NULL},
829 #endif
830 #ifdef MODE_worm
831 {(char *) "worm", init_worm, draw_worm, release_worm,
832 refresh_worm, init_worm, (ModeHook *) NULL, &worm_opts,
833 17000, -20, 10, -3, 64, 1.0, (char *) "",
834 (char *) "Shows wiggly worms", 0, NULL},
835 #endif
836 #ifdef MODE_xcl
837 {(char *) "xcl", init_xcl, draw_xcl, release_xcl,
838 draw_xcl, init_xcl, (ModeHook *) NULL, &xcl_opts,
839 20000, -3, 1, 1, 64, 1.0, (char *) "",
840 (char *) "Shows a control line combat model race", 0, NULL},
841 #endif
842 #ifdef MODE_xjack
843 {(char *) "xjack", init_xjack, draw_xjack, release_xjack,
844 init_xjack, init_xjack, (ModeHook *) NULL, &xjack_opts,
845 50000, 1, 1, 1, 64, 1.0, (char *) "",
846 (char *) "Shows Jack having one of those days", 0, NULL},
847 #endif
848
849 /* SPECIAL MODES */
850 #ifndef WIN32
851 {(char *) "blank", init_blank, (ModeHook *) NULL, (ModeHook *) NULL,
852 (ModeHook *) NULL, init_blank, (ModeHook *) NULL, &blank_opts,
853 3000000, 1, 1, 1, 64, 1.0, (char *) "",
854 (char *) "Shows nothing but a black screen", 0, NULL},
855 #endif /* !WIN32 */
856 #ifdef MODE_run
857 {(char *) "run", init_run, (ModeHook *) NULL, release_run,
858 (ModeHook *) NULL, init_run, free_run, &run_opts,
859 3000000, 1, 1, 1, 64, 1.0, (char *) "",
860 (char *) "Shows another xprogram", 0, NULL},
861 #endif
862 #ifdef MODE_bomb
863 {(char *) "bomb", init_bomb, draw_bomb, release_bomb,
864 refresh_bomb, change_bomb, (ModeHook *) NULL, &bomb_opts,
865 100000, 10, 20, 1, 64, 1.0, (char *) "",
866 (char *) "Shows a bomb and will autologout after a time", 0, NULL},
867 #endif
868 {(char *) "random", init_random, draw_random, release_random,
869 refresh_random, change_random, (ModeHook *) NULL, &random_opts,
870 1, 1, 1, 1, 64, 1.0, (char *) "",
871 #ifdef MODE_bomb
872 (char *) "Shows a random mode (except blank and bomb)",
873 #else
874 (char *) "Shows a random mode (except blank)",
875 #endif
876 0, NULL},
877 };
878
879 int numprocs = sizeof (LockProcs) / sizeof (LockProcs[0]);
880
881 #else /* #ifndef USE_MODULES */
882
883 #include <sys/stat.h>
884 #include <pwd.h>
885 #include <dlfcn.h>
886 #include <errno.h>
887
888 LockStruct *LockProcs = NULL;
889 void **LoadedModules = NULL; /* save module handles to unload them later */
890 int numprocs = 0;
891
892 /*-
893 * I use a stack to save information about each module until they are
894 * all loaded because I can not allocate LockProcs until I know how many
895 * modules there are.
896 */
897 typedef struct stack {
898 struct stack *next;
899 LockStruct *lock;
900 void *mod; /* pointer to module */
901 } stack;
902
903 /*-
904 * compare function to use with qsort, to sort the list of modules
905 * after loading them.
906 */
907 static int
lock_compare(const void * a,const void * b)908 lock_compare(const void *a, const void *b)
909 {
910 const LockStruct *A = *((LockStruct **) a), *B = *((LockStruct **) b);
911
912 return strcmp(A->cmdline_arg, B->cmdline_arg);
913 }
914
915 /*-
916 * Does tilde expansion on path, and expands any occurrence of %S to
917 * the default modulepath. Returns a pointer to a static string
918 * containing the expanded path. This will be overwritten by
919 * subsequent calls to ExpandPath.
920 */
921 static char *
ExpandPath(char * path)922 ExpandPath(char *path)
923 {
924 static char expandedpath[1024];
925 char *ep = expandedpath;
926
927 if (path[0] == '~') { /* find homedir */
928 int i = 0;
929 char user[128], *homedir;
930 struct passwd *pw = NULL;
931
932 path++;
933 while (*path && *path != '/')
934 user[i++] = *path++;
935 user[i] = '\0';
936
937 if (user[0] == '\0') { /* get this user's homedir */
938 homedir = getenv("HOME");
939 if (!homedir) { /* try password entry */
940 pw = getpwuid(getuid());
941 if (!pw) {
942 char *login = getlogin();
943
944 if (login)
945 pw = getpwnam(login);
946 }
947 if (pw)
948 homedir = pw->pw_dir;
949 else
950 return NULL; /* can't expand name */
951 }
952 } else { /* refers to another user's home dir */
953 pw = getpwnam(user);
954 if (pw)
955 homedir = pw->pw_dir;
956 else
957 return NULL;
958 }
959 (void) strcpy(ep, homedir);
960 ep += strlen(homedir);
961 } /* if (path[0] .. */
962 while (*path) {
963 switch (*path) {
964 case '%':
965 path++;
966 switch (*path) {
967 case 'S':
968 *ep = '\0';
969 (void) strcat(ep, DEF_MODULEPATH);
970 ep += strlen(DEF_MODULEPATH);
971 break;
972 case '%':
973 *ep++ = *path++;
974 break;
975 default:
976 path++;
977 break;
978 }
979 break;
980 default:
981 *ep++ = *path++;
982 break;
983 }
984 }
985
986 *ep = '\0';
987 return expandedpath;
988 }
989
990 /*-
991 * Loads screensaver modules in the directories in path. path is a
992 * colon separated list of directories to search in. LoadModules
993 * searches for files ending in .xlk to load as modules.
994 */
995
996 #define nextone (void) fprintf(stderr, "LoadModule: %s: %s\n", cpath, dlerror()); \
997 (void) dlclose(mp); \
998 free(newstack->lock); \
999 free(newstack); \
1000 continue
1001
1002 void
LoadModules(char * path)1003 LoadModules(char *path)
1004 {
1005 DIR *dp;
1006 struct stat st;
1007 struct dirent *ent;
1008 char cpath[128], *p, *thisp;
1009 stack *newstack, *head = NULL;
1010 int count = 0;
1011
1012 if (path) {
1013 p = (char *) malloc(strlen(path) + 1);
1014 (void) strcpy(p, path);
1015 } else {
1016 p = (char *) malloc(1);
1017 p[0] = '\0';
1018 (void) fprintf(stderr, "%s: LoadModules: modulepath is null\n",
1019 ProgramName);
1020 }
1021 for (thisp = strtok(p, ": \t"); thisp != NULL; thisp = strtok(NULL, ": \t")) {
1022 char *ep;
1023
1024 ep = ExpandPath(thisp);
1025 if (ep == NULL) {
1026 (void) fprintf(stderr, "%s: LoadModules: Can not expand path - '%s'\n",
1027 ProgramName, thisp);
1028 continue;
1029 } else
1030 thisp = ep;
1031
1032 dp = opendir(thisp);
1033 if (dp == NULL) {
1034 (void) fprintf(stderr, "%s: LoadModules: %s: %s\n", ProgramName,
1035 thisp, strerror(errno));
1036 continue;
1037 }
1038 while ((ent = readdir(dp)) != NULL) {
1039 int len;
1040 void *mp;
1041
1042 if ((len = strlen(ent->d_name)) > 4) {
1043 char *suf = &ent->d_name[len - 4]; /* check suffix */
1044
1045 if (strcmp(suf, ".xlk") != 0)
1046 continue;
1047 } else
1048 continue;
1049
1050 (void) sprintf(cpath, "%s%s%s", thisp,
1051 (thisp[strlen(thisp) - 1] == '/') ? "" : "/",
1052 ent->d_name);
1053 if (stat(cpath, &st) != 0) {
1054 (void) fprintf(stderr, "%s: LoadModules: %s: %s\n", ProgramName,
1055 cpath, strerror(errno));
1056 continue;
1057 }
1058 if (!S_ISREG(st.st_mode)) /* make sure it's not a directory */
1059 continue;
1060
1061 mp = dlopen(cpath, RTLD_NOW); /* load module */
1062 if (mp == NULL) {
1063 (void) fprintf(stderr, "%s: LoadModule: %s: %s\n", ProgramName,
1064 cpath, dlerror());
1065 continue;
1066 } else {
1067 char descsym[32];
1068 ModStruct *desc;
1069
1070 /*
1071 * The name of the description structure is formed by concatenating
1072 * the name of the module minus the .xlk suffix, and the string
1073 * "_description".
1074 */
1075 (void) sprintf(descsym, "%.*s_description", len - 4, ent->d_name);
1076 desc = (ModStruct *) dlsym(mp, descsym);
1077 if (desc == NULL) {
1078 (void) fprintf(stderr, "LoadModule: %s: %s\n", descsym, dlerror());
1079 (void) dlclose(mp);
1080 continue;
1081 }
1082 /* save information about module on stack. */
1083 newstack = (stack *) malloc(sizeof (stack));
1084 newstack->mod = mp;
1085 newstack->lock = (LockStruct *) malloc(sizeof (LockStruct));
1086 newstack->lock->cmdline_arg = (char *) desc->cmdline_arg;
1087
1088 if (desc->init_name != NULL) {
1089 newstack->lock->init_hook = (ModeHook *) dlsym(mp, (char *) desc->init_name);
1090 if (newstack->lock->init_hook == NULL) {
1091 nextone;
1092 }
1093 } else
1094 newstack->lock->init_hook = NULL;
1095 if (desc->callback_name != NULL) {
1096 newstack->lock->callback_hook = (ModeHook *) dlsym(mp, desc->callback_name);
1097 if (newstack->lock->callback_hook == NULL) {
1098 nextone;
1099 }
1100 } else
1101 newstack->lock->callback_hook = NULL;
1102 if (desc->release_name != NULL) {
1103 newstack->lock->release_hook = (ModeHook *) dlsym(mp, desc->release_name);
1104 if (newstack->lock->release_hook == NULL) {
1105 nextone;
1106 }
1107 } else
1108 newstack->lock->refresh_hook = NULL;
1109 if (desc->refresh_name != NULL) {
1110 newstack->lock->refresh_hook = (ModeHook *) dlsym(mp, desc->refresh_name);
1111 if (newstack->lock->refresh_hook == NULL) {
1112 nextone;
1113 }
1114 } else
1115 newstack->lock->refresh_hook = NULL;
1116 if (desc->change_name != NULL) {
1117 newstack->lock->change_hook = (ModeHook *) dlsym(mp, desc->change_name);
1118 if (newstack->lock->change_hook == NULL) {
1119 nextone;
1120 }
1121 } else
1122 newstack->lock->change_hook = NULL;
1123 /*if (desc->unused_name != NULL) {
1124 newstack->lock->unused_hook = (ModeHook *) dlsym(mp, desc->unused_name);
1125 if (newstack->lock->unused_hook == NULL) {
1126 nextone;
1127 }
1128 } else
1129 newstack->lock->unused_hook = NULL;*/
1130 newstack->lock->msopt = desc->msopt;
1131 newstack->lock->def_delay = desc->def_delay;
1132 newstack->lock->def_count = desc->def_count;
1133 newstack->lock->def_cycles = desc->def_cycles;
1134 newstack->lock->def_size = desc->def_size;
1135 newstack->lock->def_ncolors = desc->def_ncolors;
1136 newstack->lock->def_saturation = desc->def_saturation;
1137 newstack->lock->def_bitmap = (char *) desc->def_bitmap;
1138 newstack->lock->desc = (char *) desc->desc;
1139 newstack->lock->flags = desc->flags;
1140 newstack->lock->userdata = desc->userdata;
1141
1142 newstack->next = head;
1143 head = newstack;
1144 count++;
1145 } /* if (mp == NULL) .. else */
1146 } /* while ((ent = ...) */
1147
1148 (void) closedir(dp);
1149 } /* for (thisp = ... */
1150 free(p);
1151
1152 if (count > 0) {
1153 int i;
1154 stack *discard;
1155 LockStruct **locks;
1156
1157 LoadedModules = (void **) malloc(count * sizeof (void *));
1158
1159 LockProcs = (LockStruct *) malloc(count * sizeof (LockStruct));
1160 locks = (LockStruct **) malloc(count * sizeof (LockStruct *));
1161
1162 /* Copy module info from stack to locks array temporarily to
1163 * sort them. Then copy them to LockProcs. Also save module
1164 * handles in LoadedModules, to be used by UnloadModules()
1165 * later.
1166 */
1167 for (i = 0; i < count; i++) {
1168 LoadedModules[i] = head->mod;
1169 locks[i] = head->lock;
1170 discard = head;
1171 head = head->next;
1172 free(discard);
1173 }
1174 (void) qsort((void *) locks, count, sizeof (LockStruct *), lock_compare);
1175 for (i = 0; i < count; i++) {
1176 (void) memcpy(&LockProcs[i], locks[i], sizeof (LockStruct));
1177 free(locks[i]);
1178 }
1179 free(locks);
1180 }
1181 numprocs = count;
1182 }
1183
1184 void
UnloadModules()1185 UnloadModules()
1186 {
1187 int i;
1188
1189 if (LoadedModules != NULL) {
1190 for (i = 0; i < numprocs; i++)
1191 (void) dlclose(LoadedModules[i]);
1192
1193 free(LoadedModules);
1194 }
1195 if (LockProcs != NULL)
1196 free(LockProcs);
1197 }
1198
1199 #endif /* #ifndef USE_MODULES ... #else */
1200
1201 /* -------------------------------------------------------------------- */
1202
1203 static LockStruct *last_initted_mode = (LockStruct *) NULL;
1204 static LockStruct *default_mode = (LockStruct *) NULL;
1205
1206 /* -------------------------------------------------------------------- */
1207
1208 void
set_default_mode(LockStruct * ls)1209 set_default_mode(LockStruct * ls)
1210 {
1211 default_mode = ls;
1212 }
1213
1214 /* -------------------------------------------------------------------- */
1215
1216 extern Bool description;
1217
1218 static void
set_window_title(ModeInfo * mi)1219 set_window_title(ModeInfo * mi)
1220 {
1221 XTextProperty prop;
1222 char *buf;
1223 unsigned int status;
1224
1225 buf = (char *) malloc(strlen(MI_NAME(mi)) + strlen(MI_DESC(mi)) + 3);
1226 (void) sprintf(buf, "%s: %s", MI_NAME(mi), MI_DESC(mi));
1227 status = XStringListToTextProperty(&buf, 1, &prop);
1228 if (status != 0) {
1229 XSetWMName(MI_DISPLAY(mi), MI_WINDOW(mi), &prop);
1230 XFree((caddr_t) prop.value);
1231 }
1232 free(buf);
1233 if (MI_IS_ICONIC(mi) && description) {
1234 modeDescription(mi);
1235 }
1236 }
1237
1238 /* -------------------------------------------------------------------- */
1239
1240 /*-
1241 * This hook is called prior to calling the init hook of a
1242 * different mode. It is to inform the mode that it is losing
1243 * control, and should therefore release any dynamically created
1244 * resources.
1245 */
1246
1247 void
call_release_hook(LockStruct * ls,ModeInfo * mi)1248 call_release_hook(LockStruct * ls, ModeInfo * mi)
1249 {
1250 if (ls == NULL) {
1251 return;
1252 }
1253 MI_LOCKSTRUCT(mi) = ls;
1254
1255 if (ls->free_hook != NULL) {
1256 int old_screen = MI_SCREEN(mi);
1257 for (MI_SCREEN(mi) = 0; MI_SCREEN(mi) != MI_NUM_SCREENS(mi); ++MI_SCREEN(mi))
1258 ls->free_hook (mi);
1259 MI_SCREEN(mi) = old_screen;
1260 }
1261
1262 if (ls->release_hook != NULL) {
1263 ls->release_hook(mi);
1264 }
1265
1266 if (ls->state_array) { /* MI_INIT modes only. */
1267 free(*ls->state_array);
1268 *ls->state_array = NULL;
1269 ls->state_array = NULL;
1270
1271 #ifdef USE_GL
1272 FreeAllGL(mi); /* Should be a safe no-op for Xlib modes. */
1273 #endif
1274 }
1275
1276 ls->flags &= ~(LS_FLAG_INITED);
1277
1278 last_initted_mode = (LockStruct *) NULL;
1279 }
1280
1281 void
release_last_mode(ModeInfo * mi)1282 release_last_mode(ModeInfo * mi)
1283 {
1284 if (last_initted_mode == NULL) {
1285 return;
1286 }
1287 call_release_hook(last_initted_mode, mi);
1288
1289 last_initted_mode = (LockStruct *) NULL;
1290 }
1291
1292 void
mi_init(ModeInfo * mi,size_t state_size,void ** state_array)1293 mi_init(ModeInfo *mi, size_t state_size, void **state_array)
1294 {
1295 LockStruct *ls = MI_LOCKSTRUCT(mi);
1296 ls->state_array = state_array;
1297
1298 if (!*state_array) {
1299 *state_array = calloc (MI_NUM_SCREENS(mi), state_size);
1300
1301 if (!*state_array) {
1302 return;
1303 }
1304 }
1305
1306 if (ls->free_hook)
1307 ls->free_hook (mi);
1308 memset ((char *)(*ls->state_array) + MI_SCREEN(mi) * state_size, 0, state_size);
1309 }
1310
1311 /* -------------------------------------------------------------------- */
1312
1313 /*-
1314 * Call the init hook for a mode. If this mode is not the same
1315 * as the last one, call the release proc for the previous mode
1316 * so that it will surrender its dynamic resources.
1317 * A mode's init hook may be called multiple times, without
1318 * intervening release calls.
1319 */
1320
1321 void
call_init_hook(LockStruct * ls,ModeInfo * mi)1322 call_init_hook(LockStruct * ls, ModeInfo * mi)
1323 {
1324 if (ls == NULL) {
1325 if (default_mode == NULL) {
1326 return;
1327 } else {
1328 ls = default_mode;
1329 }
1330 }
1331 if (ls != last_initted_mode) {
1332 call_release_hook(last_initted_mode, mi);
1333 }
1334 MI_LOCKSTRUCT(mi) = ls;
1335 set_window_title(mi);
1336
1337 ls->init_hook(mi);
1338
1339 ls->flags |= LS_FLAG_INITED;
1340 MI_SET_FLAG_STATE(mi, WI_FLAG_JUST_INITTED, True);
1341
1342 last_initted_mode = ls;
1343 }
1344
1345 /* -------------------------------------------------------------------- */
1346
1347 /*-
1348 * Call the callback hook for a mode. This hook is called repeatedly,
1349 * at (approximately) constant time intervals. The time between calls
1350 * is controlled by the -delay command line option, which is mapped
1351 * to the variable named delay.
1352 */
1353
1354 void
call_callback_hook(LockStruct * ls,ModeInfo * mi)1355 call_callback_hook(LockStruct * ls, ModeInfo * mi)
1356 {
1357 if (ls == NULL) {
1358 if (default_mode == NULL) {
1359 return;
1360 } else {
1361 ls = default_mode;
1362 }
1363 }
1364 MI_LOCKSTRUCT(mi) = ls;
1365
1366 if (ls->callback_hook != NULL)
1367 ls->callback_hook(mi);
1368
1369 MI_SET_FLAG_STATE(mi, WI_FLAG_JUST_INITTED, False);
1370 }
1371
1372 /* -------------------------------------------------------------------- */
1373
1374 /*-
1375 * Window damage has occurred. If the mode has been initted and
1376 * supplied a refresh proc, call that. Otherwise call its init
1377 * hook again.
1378 */
1379
1380 #define JUST_INITTED(mi) (MI_FLAG_IS_SET(mi, WI_FLAG_JUST_INITTED))
1381
1382 void
call_refresh_hook(LockStruct * ls,ModeInfo * mi)1383 call_refresh_hook(LockStruct * ls, ModeInfo * mi)
1384 {
1385 if (ls == NULL) {
1386 if (default_mode == NULL) {
1387 return;
1388 } else {
1389 ls = default_mode;
1390 }
1391 }
1392 MI_LOCKSTRUCT(mi) = ls;
1393
1394 if (ls->refresh_hook == NULL) {
1395 /*
1396 * No refresh hook supplied. If the mode has been
1397 * initialized, and the callback has been called at least
1398 * once, then call the init hook to do the refresh.
1399 * Note that two flags are examined here. The first
1400 * indicates if the mode has ever had its init hook called,
1401 * the second is a per-screen flag which indicates
1402 * if the draw (callback) hook has been called since the
1403 * init hook was called for that screen.
1404 * This second test is a hack. A mode should gracefully
1405 * deal with its init hook being called twice in a row.
1406 * Once all the modes have been updated, this hack should
1407 * be removed.
1408 */
1409 if (MODE_NOT_INITED(ls) || JUST_INITTED(mi)) {
1410 return;
1411 }
1412 call_init_hook(ls, mi);
1413 } else {
1414 ls->refresh_hook(mi);
1415 }
1416 }
1417
1418 /* -------------------------------------------------------------------- */
1419
1420 /*-
1421 * The user has requested a change, by pressing the middle mouse
1422 * button. Let the mode know about it.
1423 */
1424
1425 void
call_change_hook(LockStruct * ls,ModeInfo * mi)1426 call_change_hook(LockStruct * ls, ModeInfo * mi)
1427 {
1428 if (ls == NULL) {
1429 if (default_mode == NULL) {
1430 return;
1431 } else {
1432 ls = default_mode;
1433 }
1434 }
1435 MI_LOCKSTRUCT(mi) = ls;
1436
1437 if (ls->change_hook != NULL) {
1438 ls->change_hook(mi);
1439 }
1440 }
1441
1442 /*-
1443 * Future?
1444 */
1445
1446 /*void
1447 call_unused_hook(LockStruct * ls, ModeInfo * mi)
1448 {
1449 if (ls == NULL) {
1450 if (default_mode == NULL) {
1451 return;
1452 } else {
1453 ls = default_mode;
1454 }
1455 }
1456 MI_LOCKSTRUCT(mi) = ls;
1457
1458 if (ls->unused_hook != NULL) {
1459 ls->unused_hook(mi);
1460 }
1461 }*/
1462