1 /* -*- Mode: C; tab-width: 4 -*- */
2 /* random --- run random modes for a certain duration */
3
4 #if 0
5 static const char sccsid[] = "@(#)random.c 5.00 2000/11/01 xlockmore";
6
7 #endif
8
9 /*-
10 * Permission to use, copy, modify, and distribute this software and its
11 * documentation for any purpose and without fee is hereby granted,
12 * provided that the above copyright notice appear in all copies and that
13 * both that copyright notice and this permission notice appear in
14 * supporting documentation.
15 *
16 * This file is provided AS IS with no warranties of any kind. The author
17 * shall have no liability with respect to the infringement of copyrights,
18 * trade secrets or any patents by this file or any part thereof. In no
19 * event will the author be liable for any lost revenue or profits or
20 * other special, indirect and consequential damages.
21 *
22 * Revision History:
23 * 01-Nov-2000: Allocation checks
24 * 10-May-1997: Made more compatible with xscreensaver :)
25 * 18-Mar-1996: Ron Hitchens <ron AT idiom.com>
26 * Re-coded for the ModeInfo calling scheme. Added the
27 * change hook. Get ready for 3.8 release.
28 * 23-Dec-1995: Ron Hitchens <ron AT idiom.com>
29 * Re-coded pickMode() to keep track of the modes, so
30 * that all modes are tried before there are any repeats.
31 * Also prevent a mode from being picked twice in a row
32 * (could happen as first pick after refreshing the list).
33 * 04-Sep-1995: Written by Heath A. Kehoe <hakehoe AT icaen.uiowa.edu>.
34 *
35 */
36
37 #ifdef STANDALONE
38 #define MODE_random
39 #define DEFAULTS "*verbose: False \n" \
40
41 # define free_random 0
42 # define reshape_random 0
43 # define random_handle_event 0
44 #include "xlockmore.h" /* in xscreensaver distribution */
45 #else /* STANDALONE */
46 #include "xlock.h" /* in xlockmore distribution */
47 #include "color.h"
48 #include "util.h"
49 #endif /* STANDALONE */
50
51 #define DEF_DURATION "60" /* 0 == infinite duration */
52 #define DEF_MODELIST ""
53 #define DEF_SEQUENTIAL "False"
54 #define DEF_FULLRANDOM "True"
55
56 static int duration;
57 static char *modelist;
58 static Bool sequential;
59 extern Bool fullrandom;
60
61 static XrmOptionDescRec opts[] =
62 {
63 {(char *) "-duration", (char *) ".random.duration", XrmoptionSepArg, (caddr_t) NULL},
64 {(char *) "-modelist", (char *) ".random.modelist", XrmoptionSepArg, (caddr_t) NULL},
65 {(char *) "-sequential", (char *) ".random.sequential", XrmoptionNoArg, (caddr_t) "on"},
66 {(char *) "+sequential", (char *) ".random.sequential", XrmoptionNoArg, (caddr_t) "off"},
67 {(char *) "-fullrandom", (char *) ".random.fullrandom", XrmoptionNoArg, (caddr_t) "on"},
68 {(char *) "+fullrandom", (char *) ".random.fullrandom", XrmoptionNoArg, (caddr_t) "off"}
69 };
70
71 static argtype vars[] =
72 {
73 {(void *) & duration, (char *) "duration", (char *) "Duration", (char *) DEF_DURATION, t_Int},
74 {(void *) & modelist, (char *) "modelist", (char *) "Modelist", (char *) DEF_MODELIST, t_String},
75 {(void *) & sequential, (char *) "sequential", (char *) "Sequential", (char *) DEF_SEQUENTIAL, t_Bool},
76 {(void *) & fullrandom, (char *) "fullrandom", (char *) "FullRandom", (char *) DEF_FULLRANDOM, t_Bool}
77 };
78
79 static OptionStruct desc[] =
80 {
81 {(char *) "-duration num", (char *) "how long a mode runs before changing to another"},
82 {(char *) "-modelist string", (char *) "list of modes to randomly choose from"},
83 {(char *) "-/+sequential", (char *) "turn on/off picking of modes sequentially"},
84 {(char *) "-/+fullrandom", (char *) "turn on/off full random choice of mode-options"}
85 };
86
87 ENTRYPOINT ModeSpecOpt random_opts =
88 {sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc};
89
90 #ifdef USE_MODULES
91 ModStruct random_description =
92 {"random", "init_random", "draw_random", "release_random",
93 "refresh_random", "change_random", (char *) NULL, &random_opts,
94 1, 1, 1, 1, 64, 1.0, "",
95 #ifdef MODE_run
96 #ifdef MODE_bomb
97 "Shows a random mode from above except blank, run, and bomb", 0, NULL};
98 #else
99 "Shows a random mode from above except blank and run", 0, NULL};
100 #endif
101 #else
102 #ifdef MODE_bomb
103 "Shows a random mode from above except blank and bomb", 0, NULL};
104 #else
105 "Shows a random mode from above except blank", 0, NULL};
106 #endif
107 #endif
108
109 #endif
110
111 #define GC_SAVE_VALUES (GCFunction|GCLineWidth|GCLineStyle|GCCapStyle|GCJoinStyle|GCGraphicsExposures|GCFont|GCSubwindowMode)
112
113 extern int startscreen;
114 extern int delay;
115 extern int count;
116 extern int cycles;
117 extern int size;
118 extern int ncolors;
119 extern float saturation;
120 extern char *bitmap;
121
122 #define MAXMODECHARS 14
123
124 static char special_modes[][MAXMODECHARS] =
125 {
126 #ifdef MODE_bomb
127 "bomb",
128 #endif
129 #ifdef MODE_run
130 "run",
131 #endif
132 "blank", "random"
133 };
134
135 #define NUMSPECIAL (int) (sizeof (special_modes) / sizeof (special_modes[0]))
136
137 #ifdef USE_GL
138 static char gl_modes[][MAXMODECHARS] =
139 {
140 #ifdef MODE_atlantis
141 "atlantis",
142 #endif
143 #ifdef MODE_atunnels
144 "atunnels",
145 #endif
146 #ifdef MODE_boxed
147 "boxed",
148 #endif
149 #ifdef MODE_bubble3d
150 "bubble3d",
151 #endif
152 #ifdef MODE_cage
153 "cage",
154 #endif
155 #ifdef MODE_fire
156 "fire",
157 #endif
158 #ifdef MODE_gears
159 "gears",
160 #endif
161 #ifdef MODE_glplanet
162 "glplanet",
163 #endif
164 #ifdef MODE_invert
165 "invert",
166 #endif
167 #ifdef MODE_juggler3d
168 "juggler3d",
169 #endif
170 #ifdef MODE_lament
171 "lament",
172 #endif
173 #ifdef MODE_maze3d
174 "maze3d",
175 #endif
176 #ifdef MODE_moebius
177 "moebius",
178 #endif
179 #ifdef MODE_molecule
180 "molecule",
181 #endif
182 #ifdef MODE_morph3d
183 "morph3d",
184 #endif
185 #ifdef MODE_noof
186 "noof",
187 #endif
188 #ifdef MODE_pipes
189 "pipes",
190 #endif
191 #ifdef MODE_rubik
192 "rubik",
193 #endif
194 #ifdef MODE_sballs
195 "sballs",
196 #endif
197 #ifdef MODE_sierpinski3d
198 "sierpinski3d",
199 #endif
200 #ifdef MODE_skewb
201 "skewb",
202 #endif
203 #ifdef MODE_sproingies
204 "sproingies",
205 #endif
206 #ifdef MODE_stairs
207 "stairs",
208 #endif
209 #ifdef MODE_superquadrics
210 "superquadrics",
211 #endif
212 #ifdef MODE_text3d
213 "text3d",
214 #endif
215 #ifdef MODE_text3d2
216 "text3d2",
217 #endif
218 };
219
220 #define NUMGL (int) (sizeof (gl_modes) / sizeof (gl_modes[0]))
221 #else
222 static char gl_modes[][MAXMODECHARS] =
223 {""};
224
225 #define NUMGL 0
226 #endif
227
228 static char xpm_modes[][MAXMODECHARS] =
229 {
230 #ifdef MODE_bat
231 "bat",
232 #endif
233 #ifdef MODE_image
234 "image",
235 #endif
236 #ifdef MODE_flag
237 "flag",
238 #endif
239 #ifdef MODE_life
240 "life",
241 #endif
242 #ifdef MODE_life1d
243 "life1d",
244 #endif
245 #ifdef MODE_maze
246 "maze",
247 #endif
248 #ifdef MODE_puzzle
249 "puzzle"
250 #endif
251 };
252
253 #define NUMXPM (int) (sizeof (xpm_modes) / sizeof (xpm_modes[0]))
254
255 static char write_modes[][MAXMODECHARS] =
256 {
257 #ifdef MODE_crystal
258 "crystal",
259 #endif
260 #ifdef MODE_lyapunov
261 "lyapunov",
262 #endif
263 #ifdef MODE_mandelbrot
264 "mandelbrot",
265 #endif
266 #ifdef MODE_starfish
267 "starfish",
268 #endif
269 #ifdef MODE_swirl
270 "swirl",
271 #endif
272 #ifdef MODE_tetris
273 "tetris",
274 #endif
275 #ifdef MODE_tik_tak
276 "tik_tak",
277 #endif
278 #ifdef MODE_toneclock
279 "toneclock",
280 #endif
281 #ifdef MODE_tube
282 "tube"
283 #endif
284 /* XPM modes are usually writable too ... */
285 };
286
287 #define NUMWRITE (int) (sizeof (write_modes) / sizeof (write_modes[0]))
288
289 static char nice_modes[][MAXMODECHARS] =
290 {
291 #ifdef MODE_apollonian
292 "apollonian",
293 #endif
294 #ifdef MODE_blot
295 "blot",
296 #endif
297 #ifdef MODE_bouboule
298 "bouboule",
299 #endif
300 #ifdef MODE_bug
301 "bug",
302 #endif
303 #ifdef MODE_clock
304 "clock",
305 #endif
306 #ifdef MODE_daisy
307 "daisy",
308 #endif
309 #ifdef MODE_dclock
310 "dclock",
311 #endif
312 #ifdef MODE_decay
313 "decay",
314 #endif
315 #ifdef MODE_deco
316 "deco",
317 #endif
318 #ifdef MODE_demon
319 "demon",
320 #endif
321 #ifdef MODE_dilemma
322 "dilemma",
323 #endif
324 #ifdef MODE_dragon
325 "dragon",
326 #endif
327 #ifdef MODE_eyes
328 "eyes",
329 #endif
330 #ifdef MODE_fadeplot
331 "fadeplot",
332 #endif
333 #ifdef MODE_flame
334 "flame",
335 #endif
336 #ifdef MODE_forest
337 "forest",
338 #endif
339 #ifdef MODE_grav
340 "grav",
341 #endif
342 #ifdef MODE_hop
343 "hop",
344 #endif
345 #ifdef MODE_hyper
346 "hyper",
347 #endif
348 #ifdef MODE_ico
349 "ico",
350 #endif
351 #ifdef MODE_image
352 "image",
353 #endif
354 #ifdef MODE_kaleid
355 "kaleid",
356 #endif
357 #ifdef MODE_life
358 "life",
359 #endif
360 #ifdef MODE_life1d
361 "life1d",
362 #endif
363 #ifdef MODE_life3d
364 "life3d",
365 #endif
366 #ifdef MODE_lightning
367 "lightning",
368 #endif
369 #ifdef MODE_lisa
370 "lisa",
371 #endif
372 #ifdef MODE_lissie
373 "lissie",
374 #endif
375 #ifdef MODE_loop
376 "loop",
377 #endif
378 #ifdef MODE_marquee
379 "marquee",
380 #endif
381 #ifdef MODE_munch
382 "munch",
383 #endif
384 #ifdef MODE_nose
385 "nose",
386 #endif
387 #ifdef MODE_pacman
388 "pacman",
389 #endif
390 #ifdef MODE_penrose
391 "penrose",
392 #endif
393 #ifdef MODE_petal
394 "petal",
395 #endif
396 #ifdef MODE_puzzle
397 "puzzle",
398 #endif
399 #ifdef MODE_pyro
400 "pyro",
401 #endif
402 #ifdef MODE_qix
403 "qix",
404 #endif
405 #ifdef MODE_roll
406 "roll",
407 #endif
408 #ifdef MODE_solitaire
409 "solitaire",
410 #endif
411 #ifdef MODE_space
412 "space",
413 #endif
414 #ifdef MODE_sphere
415 "sphere",
416 #endif
417 #ifdef MODE_spiral
418 "spiral",
419 #endif
420 #ifdef MODE_spline
421 "spline",
422 #endif
423 #ifdef MODE_star
424 "star",
425 #endif
426 #ifdef MODE_swarm
427 "swarm",
428 #endif
429 #ifdef MODE_tetris
430 "tetris",
431 #endif
432 #ifdef MODE_triangle
433 "triangle",
434 #endif
435 #ifdef MODE_tube
436 "tube",
437 #endif
438 #ifdef MODE_turtle
439 "turtle",
440 #endif
441 #ifdef MODE_vines
442 "vines",
443 #endif
444 #ifdef MODE_wator
445 "wator",
446 #endif
447 #ifdef MODE_wire
448 "wire",
449 #endif
450 #ifdef MODE_world
451 "world",
452 #endif
453 #ifdef MODE_worm
454 "worm",
455 #endif
456 #ifdef MODE_xcl
457 "xcl",
458 #endif
459 #ifdef MODE_xjack
460 "xjack"
461 #endif
462 };
463
464 #define NUMNICE (int) (sizeof (nice_modes) / sizeof (nice_modes[0]))
465
466 static char use3d_modes[][MAXMODECHARS] =
467 {
468 #ifdef MODE_bouboule
469 "bouboule",
470 #endif
471 #ifdef MODE_hyper
472 "hyper",
473 #endif
474 #ifdef MODE_pyro
475 "pyro",
476 #endif
477 #ifdef MODE_star
478 "star",
479 #endif
480 #ifdef MODE_worm
481 "worm"
482 #endif
483 };
484
485 #define NUMUSE3D (int) (sizeof (use3d_modes) / sizeof (use3d_modes[0]))
486
487 static char mouse_modes[][MAXMODECHARS] =
488 {
489 #ifndef DISABLE_INTERACTIVE
490 #ifdef MODE_maze
491 "maze",
492 #endif
493 #ifdef MODE_pacman
494 "pacman",
495 #endif
496 #ifdef MODE_solitaire
497 "solitaire",
498 #endif
499 #ifdef MODE_tetris
500 "tetris",
501 #endif
502 #endif
503 /* Mostly harmless interaction */
504 #ifdef MODE_eyes
505 "eyes",
506 #endif
507 #ifdef MODE_fire
508 "fire",
509 #endif
510 #ifdef MODE_julia
511 "julia",
512 #endif
513 #ifdef MODE_swarm
514 "swarm",
515 #endif
516 #ifdef MODE_t3d
517 "t3d"
518 #endif
519 };
520
521 #define NUMMOUSE (int) (sizeof (mouse_modes) / sizeof (mouse_modes[0]))
522
523 static char automata_modes[][MAXMODECHARS] =
524 {
525 #ifdef MODE_ant
526 "ant",
527 #endif
528 #ifdef MODE_ant3d
529 "ant3d",
530 #endif
531 #ifdef MODE_bug
532 "bug",
533 #endif
534 #ifdef MODE_demon
535 "demon",
536 #endif
537 #ifdef MODE_dilemma
538 "dilemma",
539 #endif
540 #ifdef MODE_life
541 "life",
542 #endif
543 #ifdef MODE_life1d
544 "life1d",
545 #endif
546 #ifdef MODE_life3d
547 "life3d",
548 #endif
549 #ifdef MODE_loop
550 "loop",
551 #endif
552 #ifdef MODE_petri
553 "petri",
554 #endif
555 #ifdef MODE_voters
556 "voters",
557 #endif
558 #ifdef MODE_wator
559 "wator",
560 #endif
561 #ifdef MODE_wire
562 "wire"
563 #endif
564 };
565
566 #define NUMAUTOMATA (int) (sizeof (automata_modes) / sizeof (automata_modes[0]))
567
568 static char fractal_modes[][MAXMODECHARS] =
569 {
570 #ifdef MODE_coral
571 "coral",
572 #endif
573 #ifdef MODE_discrete
574 "discrete",
575 #endif
576 #ifdef MODE_dragon
577 "dragon",
578 #endif
579 #ifdef MODE_drift
580 "drift",
581 #endif
582 #ifdef MODE_euler2d
583 "euler2d",
584 #endif
585 #ifdef MODE_flame
586 "flame",
587 #endif
588 #ifdef MODE_flow
589 "flow",
590 #endif
591 #ifdef MODE_forest
592 "forest",
593 #endif
594 #ifdef MODE_julia
595 "julia",
596 #endif
597 #ifdef MODE_hop
598 "hop",
599 #endif
600 #ifdef MODE_ifs
601 "ifs",
602 #endif
603 #ifdef MODE_lightning
604 "lightning",
605 #endif
606 #ifdef MODE_mandelbrot
607 "mandelbrot",
608 #endif
609 #ifdef MODE_mountain
610 "mountain",
611 #endif
612 #ifdef MODE_sierpinski
613 "sierpinski",
614 #endif
615 #ifdef MODE_strange
616 "strange",
617 #endif
618 #ifdef MODE_thornbird
619 "thornbird",
620 #endif
621 #ifdef MODE_triangle
622 "triangle",
623 #endif
624 #ifdef MODE_turtle
625 "turtle",
626 #endif
627 #ifdef MODE_vines
628 "vines"
629 #endif
630 };
631
632 #define NUMFRACTAL (int) (sizeof (fractal_modes) / sizeof (fractal_modes[0]))
633
634
635 static char geometry_modes[][MAXMODECHARS] =
636 {
637 #ifdef MODE_apollonian
638 "apollonian",
639 #endif
640 #ifdef MODE_braid
641 "braid",
642 #endif
643 #ifdef MODE_fadeplot
644 "fadeplot",
645 #endif
646 #ifdef MODE_helix
647 "helix",
648 #endif
649 #ifdef MODE_hyper
650 "hyper",
651 #endif
652 #ifdef MODE_ico
653 "ico",
654 #endif
655 #ifdef MODE_kaleid
656 "kaleid",
657 #endif
658 #ifdef MODE_laser
659 "laser",
660 #endif
661 #ifdef MODE_lisa
662 "lisa",
663 #endif
664 #ifdef MODE_lissie
665 "lissie",
666 #endif
667 #ifdef MODE_penrose
668 "penrose",
669 #endif
670 #ifdef MODE_petal
671 "petal",
672 #endif
673 #ifdef MODE_polyominoes
674 "polyominoes",
675 #endif
676 #ifdef MODE_qix
677 "qix",
678 #endif
679 #ifdef MODE_shape
680 "shape",
681 #endif
682 #ifdef MODE_sphere
683 "sphere",
684 #endif
685 #ifdef MODE_spiral
686 "spiral",
687 #endif
688 #ifdef MODE_spline
689 "spline",
690 #endif
691 #ifdef MODE_tik_tak
692 "tik_tak",
693 #endif
694 #ifdef MODE_toneclock
695 "toneclock"
696 #endif
697 };
698
699 #define NUMGEOMETRY (int) (sizeof (geometry_modes) / sizeof (geometry_modes[0]))
700
701 static char space_modes[][MAXMODECHARS] =
702 {
703 #ifdef MODE_bouboule
704 "bouboule",
705 #endif
706 #ifdef MODE_galaxy
707 "galaxy",
708 #endif
709 #ifdef MODE_grav
710 "grav",
711 #endif
712 #ifdef MODE_star
713 "star",
714 #endif
715 #ifdef MODE_world
716 "world"
717 #endif
718 };
719
720 #define NUMSPACE (int) (sizeof (space_modes) / sizeof (space_modes[0]))
721
722 typedef struct {
723 XGCValues gcvs;
724 int fix;
725 } randomstruct;
726
727 static int currentmode = -1;
728 static int previousmode = -1;
729 static unsigned long starttime;
730 static int *modes;
731 static int nmodes;
732 static Bool change_now = False;
733
734 static randomstruct *randoms;
735
736 static int
pickMode(void)737 pickMode(void)
738 {
739 static int *mode_indexes = (int *) NULL;
740 static int mode_count = 0;
741 static int last_mode = -1, last_index = -1;
742 int mode, i;
743
744 if (mode_indexes == NULL) {
745 if (!nmodes)
746 return 0;
747 if ((mode_indexes = (int *) calloc(nmodes,
748 sizeof (int))) == NULL) {
749 if (sequential)
750 return modes[0];
751 else
752 return modes[NRAND(nmodes)];
753 }
754 }
755 if (mode_count == 0) {
756 for (i = 0; i < nmodes; i++) {
757 mode_indexes[i] = modes[i];
758 }
759 mode_count = nmodes;
760 }
761 if (mode_count == 1) {
762 /* only one left, let's use that one */
763 last_index = -1;
764 return (last_mode = mode_indexes[--mode_count]);
765 } else {
766 /* pick a random slot in the list, check for last */
767 if (sequential) {
768 last_index = i = (last_index + 1) % nmodes;
769 } else
770 while (mode_indexes[i = NRAND(mode_count)] == last_mode);
771 }
772
773 mode = mode_indexes[i]; /* copy out chosen mode */
774 /* move mode at end of list to slot vacated by chosen mode, dec count */
775 mode_indexes[i] = mode_indexes[--mode_count];
776 return (last_mode = mode); /* remember last mode picked */
777 }
778
779 static char *
strpmtok(int * sign,char * str)780 strpmtok(int *sign, char *str)
781 {
782 static int nextsign = 0;
783 static char *loc;
784 char *p, *r;
785
786 if (str)
787 loc = str;
788 if (nextsign) {
789 *sign = nextsign;
790 nextsign = 0;
791 }
792 p = loc - 1;
793 for (;;) {
794 switch (*++p) {
795 case '+':
796 *sign = 1;
797 continue;
798 case '-':
799 *sign = -1;
800 continue;
801 case ' ':
802 case ',':
803 case '\t':
804 case '\n':
805 continue;
806 case 0:
807 loc = p;
808 return (char *) NULL;
809 }
810 break;
811 }
812 r = p;
813
814 for (;;) {
815 switch (*++p) {
816 case '+':
817 nextsign = 1;
818 break;
819 case '-':
820 nextsign = -1;
821 break;
822 case ' ':
823 case ',':
824 case '\t':
825 case '\n':
826 case 0:
827 break;
828 default:
829 continue;
830 }
831 break;
832 }
833 if (*p) {
834 *p = 0;
835 loc = p + 1;
836 } else
837 loc = p;
838
839 return r;
840 }
841
842 static Bool
parsemodelist(ModeInfo * mi)843 parsemodelist(ModeInfo * mi)
844 {
845 int i, sign = 1, j, found;
846 char *p;
847
848 if ((modes = (int *) calloc(numprocs - 1, sizeof (int))) == NULL) {
849 return False;
850 }
851 p = strpmtok(&sign, (modelist) ? modelist : (char *) "");
852
853 while (p) {
854 if (!strcmp(p, "all")) {
855 for (i = 0; i < numprocs; i++) {
856 found = 0;
857 for (j = 0; j < NUMSPECIAL; j++)
858 if (!strcmp(special_modes[j], LockProcs[i].cmdline_arg)) {
859 found = 1; /* if found do not want on list nomatter sign */
860 break;
861 }
862 if (!found)
863 modes[i] = (sign > 0);
864 }
865 } else if (!strcmp(p, "allgl")) {
866 for (i = 0; i < numprocs; i++)
867 for (j = 0; j < NUMGL; j++)
868 if (!strcmp(gl_modes[j], LockProcs[i].cmdline_arg))
869 modes[i] = (sign > 0);
870 } else if (!strcmp(p, "allxpm")) {
871 for (i = 0; i < numprocs; i++)
872 for (j = 0; j < NUMXPM; j++)
873 if (!strcmp(xpm_modes[j], LockProcs[i].cmdline_arg))
874 modes[i] = (sign > 0);
875 } else if (!strcmp(p, "allwrite")) {
876 for (i = 0; i < numprocs; i++)
877 for (j = 0; j < NUMWRITE; j++)
878 if (!strcmp(write_modes[j], LockProcs[i].cmdline_arg))
879 modes[i] = (sign > 0);
880 } else if (!strcmp(p, "allnice")) {
881 for (i = 0; i < numprocs; i++)
882 for (j = 0; j < NUMNICE; j++)
883 if (!strcmp(nice_modes[j], LockProcs[i].cmdline_arg))
884 modes[i] = (sign > 0);
885 } else if (!strcmp(p, "all3d")) {
886 for (i = 0; i < numprocs; i++)
887 for (j = 0; j < NUMUSE3D; j++)
888 if (!strcmp(use3d_modes[j], LockProcs[i].cmdline_arg))
889 modes[i] = (sign > 0);
890 } else if (!strcmp(p, "allmouse")) {
891 for (i = 0; i < numprocs; i++)
892 for (j = 0; j < NUMMOUSE; j++)
893 if (!strcmp(mouse_modes[j], LockProcs[i].cmdline_arg))
894 modes[i] = (sign > 0);
895 } else if (!strcmp(p, "allautomata")) {
896 for (i = 0; i < numprocs; i++)
897 for (j = 0; j < NUMAUTOMATA; j++)
898 if (!strcmp(automata_modes[j], LockProcs[i].cmdline_arg))
899 modes[i] = (sign > 0);
900 } else if (!strcmp(p, "allfractal")) {
901 for (i = 0; i < numprocs; i++)
902 for (j = 0; j < NUMFRACTAL; j++)
903 if (!strcmp(fractal_modes[j], LockProcs[i].cmdline_arg))
904 modes[i] = (sign > 0);
905 } else if (!strcmp(p, "allgeometry")) {
906 for (i = 0; i < numprocs; i++)
907 for (j = 0; j < NUMGEOMETRY; j++)
908 if (!strcmp(geometry_modes[j], LockProcs[i].cmdline_arg))
909 modes[i] = (sign > 0);
910 } else if (!strcmp(p, "allspace")) {
911 for (i = 0; i < numprocs; i++)
912 for (j = 0; j < NUMSPACE; j++)
913 if (!strcmp(space_modes[j], LockProcs[i].cmdline_arg))
914 modes[i] = (sign > 0);
915 } else {
916 for (i = 0; i < numprocs - 1; i++)
917 if (!strcmp(p, LockProcs[i].cmdline_arg))
918 break;
919 if (i < numprocs - 1)
920 modes[i] = (sign > 0);
921 else
922 (void) fprintf(stderr, "unrecognized mode \"%s\"\n", p);
923 }
924 p = strpmtok(&sign, (char *) NULL);
925 }
926
927 nmodes = 0;
928 for (i = 0; i < numprocs - 1; i++)
929 if (modes[i])
930 modes[nmodes++] = i;
931 if (!nmodes) { /* empty list */
932 for (i = 0; i < numprocs; i++) {
933 found = 0;
934 for (j = 0; j < NUMSPECIAL; j++)
935 if (!strcmp(special_modes[j], LockProcs[i].cmdline_arg)) {
936 found = 1;
937 break;
938 }
939 if (!found)
940 modes[i] = i;
941 }
942 nmodes = numprocs - NUMSPECIAL;
943 }
944 if (MI_IS_DEBUG(mi)) {
945 (void) fprintf(stderr, "%d mode%s: ", nmodes, ((nmodes == 1) ? "" : "s"));
946 for (i = 0; i < nmodes; i++)
947 (void) fprintf(stderr, "%d ", modes[i]);
948 (void) fprintf(stderr, "\n");
949 }
950 return True;
951 }
952 #ifdef WIN32
953 extern int showtext;/* from xlock.c */
954 extern char* xlock95_get_modelist(void);/* from xlock95.c */
955 extern GC GCCreate();
956 extern void xlockmore_set_mode_options(ModeSpecOpt *ms);
957 extern void XGetGCValues(Display *display, GC gc, unsigned long valuemask,
958 XGCValues* values_return);
959 #endif
960
961 static void
setMode(ModeInfo * mi,int newmode)962 setMode(ModeInfo * mi, int newmode)
963 {
964 #ifndef WIN32
965 randomstruct *rp = &randoms[MI_SCREEN(mi)];
966 int i;
967 #endif
968
969 previousmode = currentmode;
970 currentmode = newmode;
971
972 /* FIX THIS GLOBAL ACCESS */
973 delay = MI_DELAY(mi) = LockProcs[currentmode].def_delay;
974 count = MI_COUNT(mi) = LockProcs[currentmode].def_count;
975 cycles = MI_CYCLES(mi) = LockProcs[currentmode].def_cycles;
976 size = MI_SIZE(mi) = LockProcs[currentmode].def_size;
977 ncolors = MI_NCOLORS(mi) = LockProcs[currentmode].def_ncolors;
978 saturation = MI_SATURATION(mi) = LockProcs[currentmode].def_saturation;
979 bitmap = MI_BITMAP(mi) = LockProcs[currentmode].def_bitmap;
980
981 #ifndef WIN32
982 for (i = startscreen; i < MI_NUM_SCREENS(mi); i++) {
983
984 XChangeGC(MI_DISPLAY(mi), MI_GC(mi), GC_SAVE_VALUES,
985 &(rp->gcvs)); /* Not sure if this is right for multiscreens */
986 randoms[i].fix = True;
987 }
988 #endif
989 if (MI_IS_VERBOSE(mi))
990 (void) fprintf(stderr, "mode %d: %s\n", currentmode, LockProcs[currentmode].cmdline_arg);
991 #ifdef WIN32
992 {
993 ModeSpecOpt *ms = LockProcs[currentmode].msopt;
994 /*MI_COLORMAP_SIZE(mi) = ncolors = mi->screeninfo->npixels = colorcount;*/
995 XFreeGC(MI_DISPLAY(mi), MI_GC(mi));
996 MI_GC(mi) = GCCreate();
997 xlockmore_set_mode_options(ms);
998
999 /* Needed because WIN32 sections of xlock.c use these as
1000 globals */
1001 /*randommode = currentmode;
1002 showtext=0;*/
1003 }
1004 #endif
1005 }
1006
1007 ENTRYPOINT void
init_random(ModeInfo * mi)1008 init_random(ModeInfo * mi)
1009 {
1010 randomstruct *rp;
1011 int i;
1012
1013 /* NO MI_INIT here*/
1014 if (randoms == NULL) {
1015 if ((randoms = (randomstruct *) calloc(MI_NUM_SCREENS(mi),
1016 sizeof (randomstruct))) == NULL)
1017 return;
1018 }
1019 rp = &randoms[MI_SCREEN(mi)];
1020 #ifdef WIN32
1021 /* Fetch current modelist from registry */
1022 modelist = xlock95_get_modelist();
1023 #endif
1024 MI_SET_FLAG_STATE(mi, WI_FLAG_FULLRANDOM, fullrandom);
1025 if (currentmode < 0) {
1026 if (!parsemodelist(mi))
1027 return;
1028 for (i = startscreen; i < MI_NUM_SCREENS(mi); i++) {
1029 (void) XGetGCValues(MI_DISPLAY(mi), MI_GC(mi),
1030 GC_SAVE_VALUES, &(rp->gcvs));
1031 }
1032 setMode(mi, pickMode());
1033 starttime = seconds();
1034 if (duration < 0)
1035 duration = 0;
1036 }
1037 if (rp->fix) {
1038 fixColormap(mi, MI_NCOLORS(mi),
1039 MI_SATURATION(mi), MI_IS_MONO(mi), MI_IS_INSTALL(mi),
1040 MI_IS_INROOT(mi), MI_IS_INWINDOW(mi), MI_IS_VERBOSE(mi));
1041 rp->fix = False;
1042 }
1043 call_init_hook(&LockProcs[currentmode], mi);
1044 }
1045
1046 ENTRYPOINT void
draw_random(ModeInfo * mi)1047 draw_random(ModeInfo * mi)
1048 {
1049 int scrn = MI_SCREEN(mi);
1050 int newmode;
1051 unsigned long now = seconds();
1052 int has_run = (duration == 0) ? 0 : (int) (now - starttime);
1053 static int do_init = 0;
1054 randomstruct *rp;
1055
1056 if (randoms == NULL)
1057 return;
1058 rp = &randoms[scrn];
1059 if (currentmode < 0)
1060 return;
1061
1062 if ((scrn == startscreen) && do_init) {
1063 do_init = 0;
1064 }
1065 if ((scrn == startscreen) && (change_now || (has_run > duration))) {
1066 newmode = pickMode();
1067
1068 MI_CLEARWINDOW(mi);
1069
1070 setMode(mi, newmode);
1071 starttime = now;
1072 do_init = 1;
1073 change_now = False;
1074 }
1075 if (rp->fix) {
1076 fixColormap(mi, MI_NCOLORS(mi),
1077 MI_SATURATION(mi), MI_IS_MONO(mi), MI_IS_INSTALL(mi),
1078 MI_IS_INROOT(mi), MI_IS_INWINDOW(mi), MI_IS_VERBOSE(mi));
1079 rp->fix = False;
1080 }
1081 if (do_init) {
1082 call_init_hook(&LockProcs[currentmode], mi);
1083 }
1084 call_callback_hook(&LockProcs[currentmode], mi);
1085 }
1086
1087 ENTRYPOINT void
release_random(ModeInfo * mi)1088 release_random(ModeInfo * mi)
1089 {
1090 if (previousmode >= 0 && previousmode != currentmode)
1091 call_release_hook(&LockProcs[previousmode], mi);
1092 previousmode = currentmode;
1093 }
1094
1095 #ifndef STANDALONE
1096 ENTRYPOINT void
refresh_random(ModeInfo * mi)1097 refresh_random(ModeInfo * mi)
1098 {
1099 if (currentmode < 0)
1100 return;
1101 call_refresh_hook(&LockProcs[currentmode], mi);
1102 }
1103
1104 ENTRYPOINT void
change_random(ModeInfo * mi)1105 change_random(ModeInfo * mi)
1106 {
1107 if (currentmode < 0)
1108 return;
1109 if (MI_SCREEN(mi) == startscreen)
1110 change_now = True; /* force a change on next draw callback */
1111 draw_random(mi);
1112 }
1113 #endif
1114
1115 XSCREENSAVER_MODULE ("Random", random)
1116