1098 lines
21 KiB
C
1098 lines
21 KiB
C
/* -*- Mode: C; tab-width: 4 -*- */
|
|
/* random --- run random modes for a certain duration */
|
|
|
|
#if !defined( lint ) && !defined( SABER )
|
|
static const char sccsid[] = "@(#)random.c 5.00 2000/11/01 xlockmore";
|
|
|
|
#endif
|
|
|
|
/*-
|
|
* Permission to use, copy, modify, and distribute this software and its
|
|
* documentation for any purpose and without fee is hereby granted,
|
|
* provided that the above copyright notice appear in all copies and that
|
|
* both that copyright notice and this permission notice appear in
|
|
* supporting documentation.
|
|
*
|
|
* This file is provided AS IS with no warranties of any kind. The author
|
|
* shall have no liability with respect to the infringement of copyrights,
|
|
* trade secrets or any patents by this file or any part thereof. In no
|
|
* event will the author be liable for any lost revenue or profits or
|
|
* other special, indirect and consequential damages.
|
|
*
|
|
* Revision History:
|
|
* 01-Nov-2000: Allocation checks
|
|
* 10-May-1997: Made more compatible with xscreensaver :)
|
|
* 18-Mar-1996: Ron Hitchens <ron@idiom.com>
|
|
* Re-coded for the ModeInfo calling scheme. Added the
|
|
* change hook. Get ready for 3.8 release.
|
|
* 23-Dec-1995: Ron Hitchens <ron@idiom.com>
|
|
* Re-coded pickMode() to keep track of the modes, so
|
|
* that all modes are tried before there are any repeats.
|
|
* Also prevent a mode from being picked twice in a row
|
|
* (could happen as first pick after refreshing the list).
|
|
* 04-Sep-1995: Written by Heath A. Kehoe <hakehoe@icaen.uiowa.edu>.
|
|
*
|
|
*/
|
|
|
|
#ifdef STANDALONE
|
|
#define PROGCLASS "Random"
|
|
#define HACK_INIT init_random
|
|
#define HACK_DRAW draw_random
|
|
#define random_opts xlockmore_opts
|
|
#define DEFAULTS "*verbose: False \n"
|
|
#include "xlockmore.h" /* in xscreensaver distribution */
|
|
#else /* STANDALONE */
|
|
#include "xlock.h" /* in xlockmore distribution */
|
|
#include "color.h"
|
|
#include "util.h"
|
|
#endif /* STANDALONE */
|
|
|
|
#define DEF_DURATION "60" /* 0 == infinite duration */
|
|
#define DEF_MODELIST ""
|
|
#define DEF_SEQUENTIAL "False"
|
|
#define DEF_FULLRANDOM "True"
|
|
|
|
static int duration;
|
|
static char *modelist;
|
|
static Bool sequential;
|
|
extern Bool fullrandom;
|
|
|
|
static XrmOptionDescRec opts[] =
|
|
{
|
|
{(char *) "-duration", (char *) ".random.duration", XrmoptionSepArg, (caddr_t) NULL},
|
|
{(char *) "-modelist", (char *) ".random.modelist", XrmoptionSepArg, (caddr_t) NULL},
|
|
{(char *) "-sequential", (char *) ".random.sequential", XrmoptionNoArg, (caddr_t) "on"},
|
|
{(char *) "+sequential", (char *) ".random.sequential", XrmoptionNoArg, (caddr_t) "off"},
|
|
{(char *) "-fullrandom", (char *) ".random.fullrandom", XrmoptionNoArg, (caddr_t) "on"},
|
|
{(char *) "+fullrandom", (char *) ".random.fullrandom", XrmoptionNoArg, (caddr_t) "off"}
|
|
};
|
|
|
|
static argtype vars[] =
|
|
{
|
|
{(void *) & duration, (char *) "duration", (char *) "Duration", (char *) DEF_DURATION, t_Int},
|
|
{(void *) & modelist, (char *) "modelist", (char *) "Modelist", (char *) DEF_MODELIST, t_String},
|
|
{(void *) & sequential, (char *) "sequential", (char *) "Sequential", (char *) DEF_SEQUENTIAL, t_Bool},
|
|
{(void *) & fullrandom, (char *) "fullrandom", (char *) "FullRandom", (char *) DEF_FULLRANDOM, t_Bool}
|
|
};
|
|
|
|
static OptionStruct desc[] =
|
|
{
|
|
{(char *) "-duration num", (char *) "how long a mode runs before changing to another"},
|
|
{(char *) "-modelist string", (char *) "list of modes to randomly choose from"},
|
|
{(char *) "-/+sequential", (char *) "turn on/off picking of modes sequentially"},
|
|
{(char *) "-/+fullrandom", (char *) "turn on/off full random choice of mode-options"}
|
|
};
|
|
|
|
ModeSpecOpt random_opts =
|
|
{sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc};
|
|
|
|
#ifdef USE_MODULES
|
|
ModStruct random_description =
|
|
{"random", "init_random", "draw_random", "release_random",
|
|
"refresh_random", "change_random", (char *) NULL, &random_opts,
|
|
1, 1, 1, 1, 64, 1.0, "",
|
|
#ifdef MODE_run
|
|
#ifdef MODE_bomb
|
|
"Shows a random mode from above except blank, run, and bomb", 0, NULL};
|
|
#else
|
|
"Shows a random mode from above except blank and run", 0, NULL};
|
|
#endif
|
|
#else
|
|
#ifdef MODE_bomb
|
|
"Shows a random mode from above except blank and bomb", 0, NULL};
|
|
#else
|
|
"Shows a random mode from above except blank", 0, NULL};
|
|
#endif
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#define GC_SAVE_VALUES (GCFunction|GCLineWidth|GCLineStyle|GCCapStyle|GCJoinStyle|GCGraphicsExposures|GCFont|GCSubwindowMode)
|
|
|
|
extern int startscreen;
|
|
extern int delay;
|
|
extern int count;
|
|
extern int cycles;
|
|
extern int size;
|
|
extern int ncolors;
|
|
extern float saturation;
|
|
extern char *bitmap;
|
|
|
|
#define MAXMODECHARS 14
|
|
|
|
static char special_modes[][MAXMODECHARS] =
|
|
{
|
|
#ifdef MODE_bomb
|
|
"bomb",
|
|
#endif
|
|
#ifdef MODE_run
|
|
"run",
|
|
#endif
|
|
"blank", "random"
|
|
};
|
|
|
|
#define NUMSPECIAL (int) (sizeof (special_modes) / sizeof (special_modes[0]))
|
|
|
|
#ifdef USE_GL
|
|
static char gl_modes[][MAXMODECHARS] =
|
|
{
|
|
#ifdef MODE_atlantis
|
|
"atlantis",
|
|
#endif
|
|
#ifdef MODE_atunnels
|
|
"atunnels",
|
|
#endif
|
|
#ifdef MODE_biof
|
|
"biof",
|
|
#endif
|
|
#ifdef MODE_bubble3d
|
|
"bubble3d",
|
|
#endif
|
|
#ifdef MODE_cage
|
|
"cage",
|
|
#endif
|
|
#ifdef MODE_fire
|
|
"fire",
|
|
#endif
|
|
#ifdef MODE_gears
|
|
"gears",
|
|
#endif
|
|
#ifdef MODE_glplanet
|
|
"glplanet",
|
|
#endif
|
|
#ifdef MODE_invert
|
|
"invert",
|
|
#endif
|
|
#ifdef MODE_lament
|
|
"lament",
|
|
#endif
|
|
#ifdef MODE_moebius
|
|
"moebius",
|
|
#endif
|
|
#ifdef MODE_molecule
|
|
"molecule",
|
|
#endif
|
|
#ifdef MODE_morph3d
|
|
"morph3d",
|
|
#endif
|
|
#ifdef MODE_noof
|
|
"noof",
|
|
#endif
|
|
#ifdef MODE_pipes
|
|
"pipes",
|
|
#endif
|
|
#ifdef MODE_rubik
|
|
"rubik",
|
|
#endif
|
|
#ifdef MODE_sballs
|
|
"sballs",
|
|
#endif
|
|
#ifdef MODE_sierpinski3d
|
|
"sierpinski3d",
|
|
#endif
|
|
#ifdef MODE_skewb
|
|
"skewb",
|
|
#endif
|
|
#ifdef MODE_sproingies
|
|
"sproingies",
|
|
#endif
|
|
#ifdef MODE_stairs
|
|
"stairs",
|
|
#endif
|
|
#ifdef MODE_superquadrics
|
|
"superquadrics",
|
|
#endif
|
|
#ifdef MODE_text3d
|
|
"text3d",
|
|
#endif
|
|
#ifdef MODE_text3d2
|
|
"text3d2",
|
|
#endif
|
|
};
|
|
|
|
#define NUMGL (int) (sizeof (gl_modes) / sizeof (gl_modes[0]))
|
|
#else
|
|
static char gl_modes[][MAXMODECHARS] =
|
|
{""};
|
|
|
|
#define NUMGL 0
|
|
#endif
|
|
|
|
static char xpm_modes[][MAXMODECHARS] =
|
|
{
|
|
#ifdef MODE_bat
|
|
"bat",
|
|
#endif
|
|
#ifdef MODE_image
|
|
"image",
|
|
#endif
|
|
#ifdef MODE_flag
|
|
"flag",
|
|
#endif
|
|
#ifdef MODE_life
|
|
"life",
|
|
#endif
|
|
#ifdef MODE_life1d
|
|
"life1d",
|
|
#endif
|
|
#ifdef MODE_maze
|
|
"maze",
|
|
#endif
|
|
#ifdef MODE_puzzle
|
|
"puzzle"
|
|
#endif
|
|
};
|
|
|
|
#define NUMXPM (int) (sizeof (xpm_modes) / sizeof (xpm_modes[0]))
|
|
|
|
static char write_modes[][MAXMODECHARS] =
|
|
{
|
|
#ifdef MODE_crystal
|
|
"crystal",
|
|
#endif
|
|
#ifdef MODE_lyapunov
|
|
"lyapunov",
|
|
#endif
|
|
#ifdef MODE_mandelbrot
|
|
"mandelbrot",
|
|
#endif
|
|
#ifdef MODE_starfish
|
|
"starfish",
|
|
#endif
|
|
#ifdef MODE_swirl
|
|
"swirl",
|
|
#endif
|
|
#ifdef MODE_tetris
|
|
"tetris",
|
|
#endif
|
|
#ifdef MODE_tik_tak
|
|
"tik_tak",
|
|
#endif
|
|
#ifdef MODE_toneclock
|
|
"toneclock",
|
|
#endif
|
|
#ifdef MODE_tube
|
|
"tube"
|
|
#endif
|
|
/* XPM modes are usually writable too ... */
|
|
};
|
|
|
|
#define NUMWRITE (int) (sizeof (write_modes) / sizeof (write_modes[0]))
|
|
|
|
static char nice_modes[][MAXMODECHARS] =
|
|
{
|
|
#ifdef MODE_apollonian
|
|
"apollonian",
|
|
#endif
|
|
#ifdef MODE_blot
|
|
"blot",
|
|
#endif
|
|
#ifdef MODE_bouboule
|
|
"bouboule",
|
|
#endif
|
|
#ifdef MODE_bug
|
|
"bug",
|
|
#endif
|
|
#ifdef MODE_clock
|
|
"clock",
|
|
#endif
|
|
#ifdef MODE_daisy
|
|
"daisy",
|
|
#endif
|
|
#ifdef MODE_dclock
|
|
"dclock",
|
|
#endif
|
|
#ifdef MODE_decay
|
|
"decay",
|
|
#endif
|
|
#ifdef MODE_deco
|
|
"deco",
|
|
#endif
|
|
#ifdef MODE_demon
|
|
"demon",
|
|
#endif
|
|
#ifdef MODE_dilemma
|
|
"dilemma",
|
|
#endif
|
|
#ifdef MODE_dragon
|
|
"dragon",
|
|
#endif
|
|
#ifdef MODE_eyes
|
|
"eyes",
|
|
#endif
|
|
#ifdef MODE_fadeplot
|
|
"fadeplot",
|
|
#endif
|
|
#ifdef MODE_flame
|
|
"flame",
|
|
#endif
|
|
#ifdef MODE_forest
|
|
"forest",
|
|
#endif
|
|
#ifdef MODE_grav
|
|
"grav",
|
|
#endif
|
|
#ifdef MODE_hop
|
|
"hop",
|
|
#endif
|
|
#ifdef MODE_hyper
|
|
"hyper",
|
|
#endif
|
|
#ifdef MODE_ico
|
|
"ico",
|
|
#endif
|
|
#ifdef MODE_image
|
|
"image",
|
|
#endif
|
|
#ifdef MODE_kaleid
|
|
"kaleid",
|
|
#endif
|
|
#ifdef MODE_life
|
|
"life",
|
|
#endif
|
|
#ifdef MODE_life1d
|
|
"life1d",
|
|
#endif
|
|
#ifdef MODE_life3d
|
|
"life3d",
|
|
#endif
|
|
#ifdef MODE_lightning
|
|
"lightning",
|
|
#endif
|
|
#ifdef MODE_lisa
|
|
"lisa",
|
|
#endif
|
|
#ifdef MODE_lissie
|
|
"lissie",
|
|
#endif
|
|
#ifdef MODE_loop
|
|
"loop",
|
|
#endif
|
|
#ifdef MODE_marquee
|
|
"marquee",
|
|
#endif
|
|
#ifdef MODE_munch
|
|
"munch",
|
|
#endif
|
|
#ifdef MODE_nose
|
|
"nose",
|
|
#endif
|
|
#ifdef MODE_pacman
|
|
"pacman",
|
|
#endif
|
|
#ifdef MODE_penrose
|
|
"penrose",
|
|
#endif
|
|
#ifdef MODE_petal
|
|
"petal",
|
|
#endif
|
|
#ifdef MODE_puzzle
|
|
"puzzle",
|
|
#endif
|
|
#ifdef MODE_pyro
|
|
"pyro",
|
|
#endif
|
|
#ifdef MODE_qix
|
|
"qix",
|
|
#endif
|
|
#ifdef MODE_roll
|
|
"roll",
|
|
#endif
|
|
#ifdef MODE_solitare
|
|
"solitare",
|
|
#endif
|
|
#ifdef MODE_space
|
|
"space",
|
|
#endif
|
|
#ifdef MODE_sphere
|
|
"sphere",
|
|
#endif
|
|
#ifdef MODE_spiral
|
|
"spiral",
|
|
#endif
|
|
#ifdef MODE_spline
|
|
"spline",
|
|
#endif
|
|
#ifdef MODE_star
|
|
"star",
|
|
#endif
|
|
#ifdef MODE_swarm
|
|
"swarm",
|
|
#endif
|
|
#ifdef MODE_tetris
|
|
"tetris",
|
|
#endif
|
|
#ifdef MODE_triangle
|
|
"triangle",
|
|
#endif
|
|
#ifdef MODE_tube
|
|
"tube",
|
|
#endif
|
|
#ifdef MODE_turtle
|
|
"turtle",
|
|
#endif
|
|
#ifdef MODE_vines
|
|
"vines",
|
|
#endif
|
|
#ifdef MODE_wator
|
|
"wator",
|
|
#endif
|
|
#ifdef MODE_wire
|
|
"wire",
|
|
#endif
|
|
#ifdef MODE_world
|
|
"world",
|
|
#endif
|
|
#ifdef MODE_worm
|
|
"worm",
|
|
#endif
|
|
#ifdef MODE_xcl
|
|
"xcl",
|
|
#endif
|
|
#ifdef MODE_xjack
|
|
"xjack"
|
|
#endif
|
|
};
|
|
|
|
#define NUMNICE (int) (sizeof (nice_modes) / sizeof (nice_modes[0]))
|
|
|
|
static char use3d_modes[][MAXMODECHARS] =
|
|
{
|
|
#ifdef MODE_bouboule
|
|
"bouboule",
|
|
#endif
|
|
#ifdef MODE_hyper
|
|
"hyper",
|
|
#endif
|
|
#ifdef MODE_pyro
|
|
"pyro",
|
|
#endif
|
|
#ifdef MODE_star
|
|
"star",
|
|
#endif
|
|
#ifdef MODE_worm
|
|
"worm"
|
|
#endif
|
|
};
|
|
|
|
#define NUMUSE3D (int) (sizeof (use3d_modes) / sizeof (use3d_modes[0]))
|
|
|
|
static char mouse_modes[][MAXMODECHARS] =
|
|
{
|
|
#ifndef DISABLE_INTERACTIVE
|
|
#ifdef MODE_maze
|
|
"maze",
|
|
#endif
|
|
#ifdef MODE_pacman
|
|
"pacman",
|
|
#endif
|
|
#ifdef MODE_solitare
|
|
"solitare",
|
|
#endif
|
|
#ifdef MODE_tetris
|
|
"tetris",
|
|
#endif
|
|
#endif
|
|
/* Mostly harmless interaction */
|
|
#ifdef MODE_eyes
|
|
"eyes",
|
|
#endif
|
|
#ifdef MODE_fire
|
|
"fire",
|
|
#endif
|
|
#ifdef MODE_julia
|
|
"julia",
|
|
#endif
|
|
#ifdef MODE_swarm
|
|
"swarm",
|
|
#endif
|
|
#ifdef MODE_t3d
|
|
"t3d"
|
|
#endif
|
|
};
|
|
|
|
#define NUMMOUSE (int) (sizeof (mouse_modes) / sizeof (mouse_modes[0]))
|
|
|
|
static char automata_modes[][MAXMODECHARS] =
|
|
{
|
|
#ifdef MODE_ant
|
|
"ant",
|
|
#endif
|
|
#ifdef MODE_ant3d
|
|
"ant3d",
|
|
#endif
|
|
#ifdef MODE_bug
|
|
"bug",
|
|
#endif
|
|
#ifdef MODE_demon
|
|
"demon",
|
|
#endif
|
|
#ifdef MODE_dilemma
|
|
"dilemma",
|
|
#endif
|
|
#ifdef MODE_life
|
|
"life",
|
|
#endif
|
|
#ifdef MODE_life1d
|
|
"life1d",
|
|
#endif
|
|
#ifdef MODE_life3d
|
|
"life3d",
|
|
#endif
|
|
#ifdef MODE_loop
|
|
"loop",
|
|
#endif
|
|
#ifdef MODE_petri
|
|
"petri",
|
|
#endif
|
|
#ifdef MODE_voters
|
|
"voters",
|
|
#endif
|
|
#ifdef MODE_wator
|
|
"wator",
|
|
#endif
|
|
#ifdef MODE_wire
|
|
"wire"
|
|
#endif
|
|
};
|
|
|
|
#define NUMAUTOMATA (int) (sizeof (automata_modes) / sizeof (automata_modes[0]))
|
|
|
|
static char fractal_modes[][MAXMODECHARS] =
|
|
{
|
|
#ifdef MODE_coral
|
|
"coral",
|
|
#endif
|
|
#ifdef MODE_discrete
|
|
"discrete",
|
|
#endif
|
|
#ifdef MODE_dragon
|
|
"dragon",
|
|
#endif
|
|
#ifdef MODE_drift
|
|
"drift",
|
|
#endif
|
|
#ifdef MODE_euler2d
|
|
"euler2d",
|
|
#endif
|
|
#ifdef MODE_flame
|
|
"flame",
|
|
#endif
|
|
#ifdef MODE_flow
|
|
"flow",
|
|
#endif
|
|
#ifdef MODE_forest
|
|
"forest",
|
|
#endif
|
|
#ifdef MODE_julia
|
|
"julia",
|
|
#endif
|
|
#ifdef MODE_hop
|
|
"hop",
|
|
#endif
|
|
#ifdef MODE_ifs
|
|
"ifs",
|
|
#endif
|
|
#ifdef MODE_lightning
|
|
"lightning",
|
|
#endif
|
|
#ifdef MODE_mandelbrot
|
|
"mandelbrot",
|
|
#endif
|
|
#ifdef MODE_mountain
|
|
"mountain",
|
|
#endif
|
|
#ifdef MODE_sierpinski
|
|
"sierpinski",
|
|
#endif
|
|
#ifdef MODE_strange
|
|
"strange",
|
|
#endif
|
|
#ifdef MODE_thornbird
|
|
"thornbird",
|
|
#endif
|
|
#ifdef MODE_triangle
|
|
"triangle",
|
|
#endif
|
|
#ifdef MODE_turtle
|
|
"turtle",
|
|
#endif
|
|
#ifdef MODE_vines
|
|
"vines"
|
|
#endif
|
|
};
|
|
|
|
#define NUMFRACTAL (int) (sizeof (fractal_modes) / sizeof (fractal_modes[0]))
|
|
|
|
|
|
static char geometry_modes[][MAXMODECHARS] =
|
|
{
|
|
#ifdef MODE_apollonian
|
|
"apollonian",
|
|
#endif
|
|
#ifdef MODE_braid
|
|
"braid",
|
|
#endif
|
|
#ifdef MODE_fadeplot
|
|
"fadeplot",
|
|
#endif
|
|
#ifdef MODE_helix
|
|
"helix",
|
|
#endif
|
|
#ifdef MODE_hyper
|
|
"hyper",
|
|
#endif
|
|
#ifdef MODE_ico
|
|
"ico",
|
|
#endif
|
|
#ifdef MODE_kaleid
|
|
"kaleid",
|
|
#endif
|
|
#ifdef MODE_laser
|
|
"laser",
|
|
#endif
|
|
#ifdef MODE_lisa
|
|
"lisa",
|
|
#endif
|
|
#ifdef MODE_lissie
|
|
"lissie",
|
|
#endif
|
|
#ifdef MODE_penrose
|
|
"penrose",
|
|
#endif
|
|
#ifdef MODE_petal
|
|
"petal",
|
|
#endif
|
|
#ifdef MODE_polyominoes
|
|
"polyominoes",
|
|
#endif
|
|
#ifdef MODE_qix
|
|
"qix",
|
|
#endif
|
|
#ifdef MODE_shape
|
|
"shape",
|
|
#endif
|
|
#ifdef MODE_sphere
|
|
"sphere",
|
|
#endif
|
|
#ifdef MODE_spiral
|
|
"spiral",
|
|
#endif
|
|
#ifdef MODE_spline
|
|
"spline",
|
|
#endif
|
|
#ifdef MODE_tik_tak
|
|
"tik_tak",
|
|
#endif
|
|
#ifdef MODE_toneclock
|
|
"toneclock"
|
|
#endif
|
|
};
|
|
|
|
#define NUMGEOMETRY (int) (sizeof (geometry_modes) / sizeof (geometry_modes[0]))
|
|
|
|
static char space_modes[][MAXMODECHARS] =
|
|
{
|
|
#ifdef MODE_bouboule
|
|
"bouboule",
|
|
#endif
|
|
#ifdef MODE_galaxy
|
|
"galaxy",
|
|
#endif
|
|
#ifdef MODE_grav
|
|
"grav",
|
|
#endif
|
|
#ifdef MODE_star
|
|
"star",
|
|
#endif
|
|
#ifdef MODE_world
|
|
"world"
|
|
#endif
|
|
};
|
|
|
|
#define NUMSPACE (int) (sizeof (space_modes) / sizeof (space_modes[0]))
|
|
|
|
typedef struct {
|
|
XGCValues gcvs;
|
|
int fix;
|
|
} randomstruct;
|
|
|
|
static int currentmode = -1;
|
|
static int previousmode = -1;
|
|
static unsigned long starttime;
|
|
static int *modes;
|
|
static int nmodes;
|
|
static Bool change_now = False;
|
|
|
|
static randomstruct *randoms;
|
|
|
|
static int
|
|
pickMode(void)
|
|
{
|
|
static int *mode_indexes = (int *) NULL;
|
|
static int mode_count = 0;
|
|
static int last_mode = -1, last_index = -1;
|
|
int mode, i;
|
|
|
|
if (mode_indexes == NULL) {
|
|
if (!nmodes)
|
|
return 0;
|
|
if ((mode_indexes = (int *) calloc(nmodes,
|
|
sizeof (int))) == NULL) {
|
|
if (sequential)
|
|
return modes[0];
|
|
else
|
|
return modes[NRAND(nmodes)];
|
|
}
|
|
}
|
|
if (mode_count == 0) {
|
|
for (i = 0; i < nmodes; i++) {
|
|
mode_indexes[i] = modes[i];
|
|
}
|
|
mode_count = nmodes;
|
|
}
|
|
if (mode_count == 1) {
|
|
/* only one left, let's use that one */
|
|
last_index = -1;
|
|
return (last_mode = mode_indexes[--mode_count]);
|
|
} else {
|
|
/* pick a random slot in the list, check for last */
|
|
if (sequential) {
|
|
last_index = i = (last_index + 1) % nmodes;
|
|
} else
|
|
while (mode_indexes[i = NRAND(mode_count)] == last_mode);
|
|
}
|
|
|
|
mode = mode_indexes[i]; /* copy out chosen mode */
|
|
/* move mode at end of list to slot vacated by chosen mode, dec count */
|
|
mode_indexes[i] = mode_indexes[--mode_count];
|
|
return (last_mode = mode); /* remember last mode picked */
|
|
}
|
|
|
|
static char *
|
|
strpmtok(int *sign, char *str)
|
|
{
|
|
static int nextsign = 0;
|
|
static char *loc;
|
|
char *p, *r;
|
|
|
|
if (str)
|
|
loc = str;
|
|
if (nextsign) {
|
|
*sign = nextsign;
|
|
nextsign = 0;
|
|
}
|
|
p = loc - 1;
|
|
for (;;) {
|
|
switch (*++p) {
|
|
case '+':
|
|
*sign = 1;
|
|
continue;
|
|
case '-':
|
|
*sign = -1;
|
|
continue;
|
|
case ' ':
|
|
case ',':
|
|
case '\t':
|
|
case '\n':
|
|
continue;
|
|
case 0:
|
|
loc = p;
|
|
return (char *) NULL;
|
|
}
|
|
break;
|
|
}
|
|
r = p;
|
|
|
|
for (;;) {
|
|
switch (*++p) {
|
|
case '+':
|
|
nextsign = 1;
|
|
break;
|
|
case '-':
|
|
nextsign = -1;
|
|
break;
|
|
case ' ':
|
|
case ',':
|
|
case '\t':
|
|
case '\n':
|
|
case 0:
|
|
break;
|
|
default:
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
if (*p) {
|
|
*p = 0;
|
|
loc = p + 1;
|
|
} else
|
|
loc = p;
|
|
|
|
return r;
|
|
}
|
|
|
|
static Bool
|
|
parsemodelist(ModeInfo * mi)
|
|
{
|
|
int i, sign = 1, j, found;
|
|
char *p;
|
|
|
|
if ((modes = (int *) calloc(numprocs - 1, sizeof (int))) == NULL) {
|
|
return False;
|
|
}
|
|
p = strpmtok(&sign, (modelist) ? modelist : (char *) "");
|
|
|
|
while (p) {
|
|
if (!strcmp(p, "all")) {
|
|
for (i = 0; i < numprocs; i++) {
|
|
found = 0;
|
|
for (j = 0; j < NUMSPECIAL; j++)
|
|
if (!strcmp(special_modes[j], LockProcs[i].cmdline_arg)) {
|
|
found = 1; /* if found do not want on list nomatter sign */
|
|
break;
|
|
}
|
|
if (!found)
|
|
modes[i] = (sign > 0);
|
|
}
|
|
} else if (!strcmp(p, "allgl")) {
|
|
for (i = 0; i < numprocs; i++)
|
|
for (j = 0; j < NUMGL; j++)
|
|
if (!strcmp(gl_modes[j], LockProcs[i].cmdline_arg))
|
|
modes[i] = (sign > 0);
|
|
} else if (!strcmp(p, "allxpm")) {
|
|
for (i = 0; i < numprocs; i++)
|
|
for (j = 0; j < NUMXPM; j++)
|
|
if (!strcmp(xpm_modes[j], LockProcs[i].cmdline_arg))
|
|
modes[i] = (sign > 0);
|
|
} else if (!strcmp(p, "allwrite")) {
|
|
for (i = 0; i < numprocs; i++)
|
|
for (j = 0; j < NUMWRITE; j++)
|
|
if (!strcmp(write_modes[j], LockProcs[i].cmdline_arg))
|
|
modes[i] = (sign > 0);
|
|
} else if (!strcmp(p, "allnice")) {
|
|
for (i = 0; i < numprocs; i++)
|
|
for (j = 0; j < NUMNICE; j++)
|
|
if (!strcmp(nice_modes[j], LockProcs[i].cmdline_arg))
|
|
modes[i] = (sign > 0);
|
|
} else if (!strcmp(p, "all3d")) {
|
|
for (i = 0; i < numprocs; i++)
|
|
for (j = 0; j < NUMUSE3D; j++)
|
|
if (!strcmp(use3d_modes[j], LockProcs[i].cmdline_arg))
|
|
modes[i] = (sign > 0);
|
|
} else if (!strcmp(p, "allmouse")) {
|
|
for (i = 0; i < numprocs; i++)
|
|
for (j = 0; j < NUMMOUSE; j++)
|
|
if (!strcmp(mouse_modes[j], LockProcs[i].cmdline_arg))
|
|
modes[i] = (sign > 0);
|
|
} else if (!strcmp(p, "allautomata")) {
|
|
for (i = 0; i < numprocs; i++)
|
|
for (j = 0; j < NUMAUTOMATA; j++)
|
|
if (!strcmp(automata_modes[j], LockProcs[i].cmdline_arg))
|
|
modes[i] = (sign > 0);
|
|
} else if (!strcmp(p, "allfractal")) {
|
|
for (i = 0; i < numprocs; i++)
|
|
for (j = 0; j < NUMFRACTAL; j++)
|
|
if (!strcmp(fractal_modes[j], LockProcs[i].cmdline_arg))
|
|
modes[i] = (sign > 0);
|
|
} else if (!strcmp(p, "allgeometry")) {
|
|
for (i = 0; i < numprocs; i++)
|
|
for (j = 0; j < NUMGEOMETRY; j++)
|
|
if (!strcmp(geometry_modes[j], LockProcs[i].cmdline_arg))
|
|
modes[i] = (sign > 0);
|
|
} else if (!strcmp(p, "allspace")) {
|
|
for (i = 0; i < numprocs; i++)
|
|
for (j = 0; j < NUMSPACE; j++)
|
|
if (!strcmp(space_modes[j], LockProcs[i].cmdline_arg))
|
|
modes[i] = (sign > 0);
|
|
} else {
|
|
for (i = 0; i < numprocs - 1; i++)
|
|
if (!strcmp(p, LockProcs[i].cmdline_arg))
|
|
break;
|
|
if (i < numprocs - 1)
|
|
modes[i] = (sign > 0);
|
|
else
|
|
(void) fprintf(stderr, "unrecognized mode \"%s\"\n", p);
|
|
}
|
|
p = strpmtok(&sign, (char *) NULL);
|
|
}
|
|
|
|
nmodes = 0;
|
|
for (i = 0; i < numprocs - 1; i++)
|
|
if (modes[i])
|
|
modes[nmodes++] = i;
|
|
if (!nmodes) { /* empty list */
|
|
for (i = 0; i < numprocs; i++) {
|
|
found = 0;
|
|
for (j = 0; j < NUMSPECIAL; j++)
|
|
if (!strcmp(special_modes[j], LockProcs[i].cmdline_arg)) {
|
|
found = 1;
|
|
break;
|
|
}
|
|
if (!found)
|
|
modes[i] = i;
|
|
}
|
|
nmodes = numprocs - NUMSPECIAL;
|
|
}
|
|
if (MI_IS_DEBUG(mi)) {
|
|
(void) fprintf(stderr, "%d mode%s: ", nmodes, ((nmodes == 1) ? "" : "s"));
|
|
for (i = 0; i < nmodes; i++)
|
|
(void) fprintf(stderr, "%d ", modes[i]);
|
|
(void) fprintf(stderr, "\n");
|
|
}
|
|
return True;
|
|
}
|
|
#ifdef WIN32
|
|
extern int showtext;/* from xlock.c */
|
|
extern char* xlock95_get_modelist(void);/* from xlock95.c */
|
|
#endif
|
|
|
|
static void
|
|
setMode(ModeInfo * mi, int newmode)
|
|
{
|
|
randomstruct *rp = &randoms[MI_SCREEN(mi)];
|
|
int i;
|
|
|
|
previousmode = currentmode;
|
|
currentmode = newmode;
|
|
|
|
/* FIX THIS GLOBAL ACCESS */
|
|
delay = MI_DELAY(mi) = LockProcs[currentmode].def_delay;
|
|
count = MI_COUNT(mi) = LockProcs[currentmode].def_count;
|
|
cycles = MI_CYCLES(mi) = LockProcs[currentmode].def_cycles;
|
|
size = MI_SIZE(mi) = LockProcs[currentmode].def_size;
|
|
ncolors = MI_NCOLORS(mi) = LockProcs[currentmode].def_ncolors;
|
|
saturation = MI_SATURATION(mi) = LockProcs[currentmode].def_saturation;
|
|
bitmap = MI_BITMAP(mi) = LockProcs[currentmode].def_bitmap;
|
|
|
|
#ifndef WIN32
|
|
for (i = startscreen; i < MI_NUM_SCREENS(mi); i++) {
|
|
|
|
XChangeGC(MI_DISPLAY(mi), MI_GC(mi), GC_SAVE_VALUES,
|
|
&(rp->gcvs)); /* Not sure if this is right for multiscreens */
|
|
randoms[i].fix = True;
|
|
}
|
|
#endif
|
|
if (MI_IS_VERBOSE(mi))
|
|
(void) fprintf(stderr, "mode %d: %s\n", currentmode, LockProcs[currentmode].cmdline_arg);
|
|
#ifdef WIN32
|
|
{
|
|
ModeSpecOpt *ms = LockProcs[currentmode].msopt;
|
|
/*MI_COLORMAP_SIZE(mi) = ncolors = mi->screeninfo->npixels = colorcount;*/
|
|
XFreeGC(MI_DISPLAY(mi), MI_GC(mi));
|
|
MI_GC(mi) = GCCreate();
|
|
xlockmore_set_mode_options(ms);
|
|
|
|
/* Needed because WIN32 sections of xlock.c use these as
|
|
globals */
|
|
/*randommode = currentmode;
|
|
showtext=0;*/
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void
|
|
init_random(ModeInfo * mi)
|
|
{
|
|
randomstruct *rp;
|
|
int i;
|
|
|
|
if (randoms == NULL) {
|
|
if ((randoms = (randomstruct *) calloc(MI_NUM_SCREENS(mi),
|
|
sizeof (randomstruct))) == NULL)
|
|
return;
|
|
}
|
|
rp = &randoms[MI_SCREEN(mi)];
|
|
#ifdef WIN32
|
|
/* Fetch current modelist from registry */
|
|
modelist = xlock95_get_modelist();
|
|
#endif
|
|
MI_SET_FLAG_STATE(mi, WI_FLAG_FULLRANDOM, fullrandom);
|
|
if (currentmode < 0) {
|
|
if (!parsemodelist(mi))
|
|
return;
|
|
for (i = startscreen; i < MI_NUM_SCREENS(mi); i++) {
|
|
(void) XGetGCValues(MI_DISPLAY(mi), MI_GC(mi),
|
|
GC_SAVE_VALUES, &(rp->gcvs));
|
|
}
|
|
setMode(mi, pickMode());
|
|
starttime = seconds();
|
|
if (duration < 0)
|
|
duration = 0;
|
|
}
|
|
if (rp->fix) {
|
|
fixColormap(mi, MI_NCOLORS(mi),
|
|
MI_SATURATION(mi), MI_IS_MONO(mi), MI_IS_INSTALL(mi),
|
|
MI_IS_INROOT(mi), MI_IS_INWINDOW(mi), MI_IS_VERBOSE(mi));
|
|
rp->fix = False;
|
|
}
|
|
call_init_hook(&LockProcs[currentmode], mi);
|
|
}
|
|
|
|
void
|
|
draw_random(ModeInfo * mi)
|
|
{
|
|
int scrn = MI_SCREEN(mi);
|
|
int newmode;
|
|
unsigned long now = seconds();
|
|
int has_run = (duration == 0) ? 0 : (int) (now - starttime);
|
|
static int do_init = 0;
|
|
randomstruct *rp;
|
|
|
|
if (randoms == NULL)
|
|
return;
|
|
rp = &randoms[scrn];
|
|
if (currentmode < 0)
|
|
return;
|
|
|
|
if ((scrn == startscreen) && do_init) {
|
|
do_init = 0;
|
|
}
|
|
if ((scrn == startscreen) && (change_now || (has_run > duration))) {
|
|
newmode = pickMode();
|
|
|
|
MI_CLEARWINDOW(mi);
|
|
|
|
setMode(mi, newmode);
|
|
starttime = now;
|
|
do_init = 1;
|
|
change_now = False;
|
|
}
|
|
if (rp->fix) {
|
|
fixColormap(mi, MI_NCOLORS(mi),
|
|
MI_SATURATION(mi), MI_IS_MONO(mi), MI_IS_INSTALL(mi),
|
|
MI_IS_INROOT(mi), MI_IS_INWINDOW(mi), MI_IS_VERBOSE(mi));
|
|
rp->fix = False;
|
|
}
|
|
if (do_init) {
|
|
call_init_hook(&LockProcs[currentmode], mi);
|
|
}
|
|
call_callback_hook(&LockProcs[currentmode], mi);
|
|
}
|
|
|
|
void
|
|
refresh_random(ModeInfo * mi)
|
|
{
|
|
if (currentmode < 0)
|
|
return;
|
|
call_refresh_hook(&LockProcs[currentmode], mi);
|
|
}
|
|
|
|
void
|
|
change_random(ModeInfo * mi)
|
|
{
|
|
if (currentmode < 0)
|
|
return;
|
|
if (MI_SCREEN(mi) == startscreen)
|
|
change_now = True; /* force a change on next draw callback */
|
|
draw_random(mi);
|
|
}
|
|
|
|
void
|
|
release_random(ModeInfo * mi)
|
|
{
|
|
if (previousmode >= 0 && previousmode != currentmode)
|
|
call_release_hook(&LockProcs[previousmode], mi);
|
|
previousmode = currentmode;
|
|
}
|