"Fossies" - the Fresh Open Source Software Archive

Member "xlockmore-5.59/modes/random.c" (21 Sep 2019, 22093 Bytes) of package /linux/misc/xlockmore-5.59.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "random.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 5.58_vs_5.59.

    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
  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 *
  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
  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
  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
 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
 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
 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
 1097 refresh_random(ModeInfo * mi)
 1098 {
 1099     if (currentmode < 0)
 1100         return;
 1101     call_refresh_hook(&LockProcs[currentmode], mi);
 1102 }
 1103 
 1104 ENTRYPOINT void
 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)