/* -*- 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 * Re-coded for the ModeInfo calling scheme. Added the * change hook. Get ready for 3.8 release. * 23-Dec-1995: Ron Hitchens * 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 . * */ #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; }