http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.01.tar.gz
[xscreensaver] / hacks / braid.c
index 9d9c4e5fd37d7191520da055279ae13f4e204f3e..55e4fa7ea77ba6d023b15bd4a4651318fdc8c7d4 100644 (file)
@@ -1,11 +1,15 @@
-/* -*- Mode: C; tab-width: 4 -*-
- * braid --- draws random color-cyling rotating braids around a circle.
+/* -*- Mode: C; tab-width: 4 -*- */
+/*-
+ * braid --- random braids around a circle and then changes the color in
+ *           a rotational pattern
  */
+
 #if !defined( lint ) && !defined( SABER )
-static const char sccsid[] = "@(#)braid.c      4.00 97/01/01 xlockmore";
+static const char sccsid[] = "@(#)braid.c      5.00 2000/11/01 xlockmore";
+
 #endif
 
-/*
+/*-
  * Copyright (c) 1995 by John Neil.
  *
  * Permission to use, copy, modify, and distribute this software and its
@@ -21,31 +25,44 @@ static const char sccsid[] = "@(#)braid.c   4.00 97/01/01 xlockmore";
  * other special, indirect and consequential damages.
  *
  * Revision History:
- * 10-May-97: jwz@jwz.org: turned into a standalone program.
- * 01-Sep-95: color knotted components differently, J. Neil.
- * 29-Aug-95: Written.  John Neil <neil@math.idbsu.edu>
+ * 01-Nov-2000: Allocation checks
+ * 10-May-1997: Jamie Zawinski <jwz@jwz.org> compatible with xscreensaver
+ * 01-Sep-1995: color knotted components differently, J. Neil.
+ * 29-Aug-1995: Written.  John Neil <neil@math.idbsu.edu>
  */
 
 #ifdef STANDALONE
-# define PROGCLASS                                     "Braid"
-# define HACK_INIT                                     init_braid
-# define HACK_DRAW                                     draw_braid
-# define braid_opts                                    xlockmore_opts
-# define DEFAULTS      "*count:                15    \n"                       \
-                                       "*size:            -7     \n"                   \
-                                       "*cycles:               100   \n"                       \
-                                       "*delay:                1000  \n"                       \
-                                       "*ncolors:              64    \n"
-# define UNIFORM_COLORS
-# include "xlockmore.h"                                /* from the xscreensaver distribution */
-# include "erase.h"
-#else  /* !STANDALONE */
-# include "xlock.h"                                    /* from the xlockmore distribution */
-#endif /* !STANDALONE */
-
-ModeSpecOpt braid_opts = {
-  0, NULL, 0, NULL, NULL };
+#define MODE_braid
+#define PROGCLASS "Braid"
+#define HACK_INIT init_braid
+#define HACK_DRAW draw_braid
+#define braid_opts xlockmore_opts
+#define DEFAULTS "*delay: 1000 \n" \
+ "*count: 15 \n" \
+ "*cycles: 100 \n" \
+ "*size: -7 \n" \
+ "*ncolors: 64 \n"
+#define UNIFORM_COLORS
+#include "xlockmore.h"
+#include "erase.h"
+#else /* STANDALONE */
+#include "xlock.h"
+
+#endif /* STANDALONE */
+
+#ifdef MODE_braid
+
+ModeSpecOpt braid_opts =
+{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
+
+#ifdef USE_MODULES
+ModStruct   braid_description =
+{"braid", "init_braid", "draw_braid", "release_braid",
+ "refresh_braid", "init_braid", (char *) NULL, &braid_opts,
+ 1000, 15, 100, 1, 64, 1.0, "",
+ "Shows random braids and knots", 0, NULL};
 
+#endif
 
 #if defined( COLORROUND ) && defined( COLORCOMP )
 #undef COLORROUND
@@ -72,6 +89,7 @@ ModeSpecOpt braid_opts = {
 #define FLOATRAND(min,max) ((min)+((double) LRAND()/((double) MAXRAND))*((max)-(min)))
 
 typedef struct {
+       int         linewidth;
        int         braidword[MAXLENGTH];
        int         components[MAXSTRANDS];
        int         startcomp[MAXLENGTH][MAXSTRANDS];
@@ -84,10 +102,10 @@ typedef struct {
        float       max_radius;
        float       top, bottom, left, right;
        int         age;
-    int         color_direction;
+       int         color_direction;
 } braidtype;
 
-static braidtype *braids = NULL;
+static braidtype *braids = (braidtype *) NULL;
 
 static int
 applyword(braidtype * braid, int string, int position)
@@ -147,7 +165,6 @@ applywordbackto(braidtype * braid, int string, int position)
 void
 init_braid(ModeInfo * mi)
 {
-       Display    *display = MI_DISPLAY(mi);
        braidtype  *braid;
        int         used[MAXSTRANDS];
        int         i, count, comp, c;
@@ -160,25 +177,26 @@ init_braid(ModeInfo * mi)
        }
        braid = &braids[MI_SCREEN(mi)];
 
-       braid->center_x = MI_WIN_WIDTH(mi) / 2;
-       braid->center_y = MI_WIN_HEIGHT(mi) / 2;
+       braid->center_x = MI_WIDTH(mi) / 2;
+       braid->center_y = MI_HEIGHT(mi) / 2;
        braid->age = 0;
 
        /* jwz: go in the other direction sometimes. */
        braid->color_direction = ((LRAND() & 1) ? 1 : -1);
-       XClearWindow(display, MI_WINDOW(mi));
+
+       MI_CLEARWINDOW(mi);
 
        min_length = (braid->center_x > braid->center_y) ?
                braid->center_y : braid->center_x;
        braid->min_radius = min_length * 0.30;
        braid->max_radius = min_length * 0.90;
 
-       if (MI_BATCHCOUNT(mi) < MINSTRANDS)
+       if (MI_COUNT(mi) < MINSTRANDS)
                braid->nstrands = MINSTRANDS;
        else
                braid->nstrands = INTRAND(MINSTRANDS,
-                                 MAX(MIN(MIN(MAXSTRANDS, MI_BATCHCOUNT(mi)),
-                                         (int) ((braid->max_radius - braid->min_radius) / 5.0)), MINSTRANDS));
+                                      MAX(MIN(MIN(MAXSTRANDS, MI_COUNT(mi)),
+                                              (int) ((braid->max_radius - braid->min_radius) / 5.0)), MINSTRANDS));
        braid->braidlength = INTRAND(MINLENGTH, MIN(MAXLENGTH, braid->nstrands * 6));
 
        for (i = 0; i < braid->braidlength; i++) {
@@ -214,7 +232,7 @@ init_braid(ModeInfo * mi)
 
        braid->startcolor = (MI_NPIXELS(mi) > 2) ?
                (float) NRAND(MI_NPIXELS(mi)) : 0.0;
-       /* XSetLineAttributes (display, MI_GC(mi), 2, LineSolid, CapRound, 
+       /* XSetLineAttributes (display, MI_GC(mi), 2, LineSolid, CapRound,
           JoinRound); */
 
        (void) memset((char *) braid->components, 0, sizeof (braid->components));
@@ -237,21 +255,12 @@ init_braid(ModeInfo * mi)
                }
        } while (count > 0);
 
-       {
-         int line_width = MI_SIZE(mi);
-         if (line_width == 0)
-               line_width = -8;
-         if (line_width < 0)
-               line_width = NRAND(-line_width)+1;
-         if (line_width == 1)
-               line_width = 0;
-         XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), line_width,
-                                                LineSolid,
-                                                (line_width <= 3 ? CapButt : CapRound),
-                                                JoinMiter);
-       }
-
+       braid->linewidth = MI_SIZE(mi);
 
+       if (braid->linewidth < 0)
+               braid->linewidth = NRAND(-braid->linewidth) + 1;
+       if (braid->linewidth * braid->linewidth * 8 > MIN(MI_WIDTH(mi), MI_HEIGHT(mi)))
+       braid->linewidth = MIN(1, (int) sqrt((double) MIN(MI_WIDTH(mi), MI_HEIGHT(mi)) / 8));
        for (i = 0; i < braid->nstrands; i++)
                if (!(braid->components[i] & 1))
                        braid->components[i] *= -1;
@@ -262,22 +271,31 @@ draw_braid(ModeInfo * mi)
 {
        Display    *display = MI_DISPLAY(mi);
        Window      window = MI_WINDOW(mi);
-       braidtype  *braid = &braids[MI_SCREEN(mi)];
-       float       num_points, t_inc;
+       int         num_points = 500;
+       float       t_inc;
        float       theta, psi;
        float       t, r_diff;
        int         i, s;
        float       x_1, y_1, x_2, y_2, r1, r2;
        float       color, color_use = 0.0, color_inc;
+       braidtype  *braid;
 
-       num_points = 500.0;
-       theta = (2.0 * M_PI) / (float) (braid->braidlength);
-       t_inc = (2.0 * M_PI) / num_points;
-       color_inc = (float) MI_NPIXELS(mi) / num_points;
-       color_inc *= braid->color_direction;
+       if (braids == NULL)
+               return;
+       braid = &braids[MI_SCREEN(mi)];
 
+       MI_IS_DRAWN(mi) = True;
+       XSetLineAttributes(display, MI_GC(mi), braid->linewidth,
+                          LineSolid,
+                          (braid->linewidth <= 3 ? CapButt : CapRound),
+                          JoinMiter);
+
+       theta = (2.0 * M_PI) / (float) (braid->braidlength);
+       t_inc = (2.0 * M_PI) / (float) num_points;
+       color_inc = (float) MI_NPIXELS(mi) * braid->color_direction /
+               (float) num_points;
        braid->startcolor += SPINRATE * color_inc;
-       if (braid->startcolor >= MI_NPIXELS(mi))
+       if (((int) braid->startcolor) >= MI_NPIXELS(mi))
                braid->startcolor = 0.0;
 
        r_diff = (braid->max_radius - braid->min_radius) / (float) (braid->nstrands);
@@ -289,7 +307,7 @@ draw_braid(ModeInfo * mi)
                for (t = 0.0; t < theta; t += t_inc) {
 #ifdef COLORROUND
                        color += color_inc;
-                       if (color >= (float) (MI_NPIXELS(mi)))
+                       if (((int) color) >= MI_NPIXELS(mi))
                                color = 0.0;
                        color_use = color;
 #endif
@@ -303,16 +321,16 @@ draw_braid(ModeInfo * mi)
                                                color_use = color + SPINRATE *
                                                        braid->components[applywordbackto(braid, s, i)] +
                                                        (psi + t) / 2.0 / M_PI * (float) MI_NPIXELS(mi);
-                                               while (color_use >= (float) MI_NPIXELS(mi))
+                                               while (((int) color_use) >= MI_NPIXELS(mi))
                                                        color_use -= (float) MI_NPIXELS(mi);
-                                               while (color_use < 0.0)
+                                               while (((int) color_use) < 0)
                                                        color_use += (float) MI_NPIXELS(mi);
                                        }
 #endif
 #ifdef COLORROUND
                                        if (MI_NPIXELS(mi) > 2) {
                                                color_use += SPINRATE * color_inc;
-                                               while (color_use >= (float) (MI_NPIXELS(mi)))
+                                               while (((int) color_use) >= MI_NPIXELS(mi))
                                                        color_use -= (float) MI_NPIXELS(mi);
                                        }
 #endif
@@ -335,7 +353,7 @@ draw_braid(ModeInfo * mi)
                                                if (MI_NPIXELS(mi) > 2)
                                                        XSetForeground(display, MI_GC(mi), MI_PIXEL(mi, (int) color_use));
                                                else
-                                                       XSetForeground(display, MI_GC(mi), MI_WIN_WHITE_PIXEL(mi));
+                                                       XSetForeground(display, MI_GC(mi), MI_WHITE_PIXEL(mi));
 
                                                XDrawLine(display, window, MI_GC(mi),
                                                          (int) (x_1), (int) (y_1), (int) (x_2), (int) (y_2));
@@ -345,9 +363,9 @@ draw_braid(ModeInfo * mi)
                                                color_use = color + SPINRATE *
                                                        braid->components[applywordbackto(braid, s + 1, i)] +
                                                        (psi + t) / 2.0 / M_PI * (float) MI_NPIXELS(mi);
-                                               while (color_use >= (float) MI_NPIXELS(mi))
+                                               while (((int) color_use) >= MI_NPIXELS(mi))
                                                        color_use -= (float) MI_NPIXELS(mi);
-                                               while (color_use < 0.0)
+                                               while (((int) color_use) < 0)
                                                        color_use += (float) MI_NPIXELS(mi);
                                        }
 #endif
@@ -368,7 +386,7 @@ draw_braid(ModeInfo * mi)
                                                if (MI_NPIXELS(mi) > 2)
                                                        XSetForeground(display, MI_GC(mi), MI_PIXEL(mi, (int) color_use));
                                                else
-                                                       XSetForeground(display, MI_GC(mi), MI_WIN_WHITE_PIXEL(mi));
+                                                       XSetForeground(display, MI_GC(mi), MI_WHITE_PIXEL(mi));
 
                                                XDrawLine(display, window, MI_GC(mi),
                                                          (int) (x_1), (int) (y_1), (int) (x_2), (int) (y_2));
@@ -380,16 +398,16 @@ draw_braid(ModeInfo * mi)
                                                color_use = color + SPINRATE *
                                                        braid->components[applywordbackto(braid, s, i)] +
                                                        (psi + t) / 2.0 / M_PI * (float) MI_NPIXELS(mi);
-                                               while (color_use >= (float) MI_NPIXELS(mi))
+                                               while (((int) color_use) >= MI_NPIXELS(mi))
                                                        color_use -= (float) MI_NPIXELS(mi);
-                                               while (color_use < 0.0)
+                                               while (((int) color_use) < 0)
                                                        color_use += (float) MI_NPIXELS(mi);
                                        }
 #endif
 #ifdef COLORROUND
                                        if (MI_NPIXELS(mi) > 2) {
                                                color_use += SPINRATE * color_inc;
-                                               while (color_use >= (float) MI_NPIXELS(mi))
+                                               while (((int) color_use) >= MI_NPIXELS(mi))
                                                        color_use -= (float) MI_NPIXELS(mi);
                                        }
 #endif
@@ -401,7 +419,7 @@ draw_braid(ModeInfo * mi)
                                        if (MI_NPIXELS(mi) > 2)
                                                XSetForeground(display, MI_GC(mi), MI_PIXEL(mi, (int) color_use));
                                        else
-                                               XSetForeground(display, MI_GC(mi), MI_WIN_WHITE_PIXEL(mi));
+                                               XSetForeground(display, MI_GC(mi), MI_WHITE_PIXEL(mi));
 
                                        XDrawLine(display, window, MI_GC(mi),
                                                  (int) (x_1), (int) (y_1), (int) (x_2), (int) (y_2));
@@ -409,12 +427,13 @@ draw_braid(ModeInfo * mi)
                        }
                }
        }
+       XSetLineAttributes(display, MI_GC(mi), 1, LineSolid, CapNotLast, JoinRound);
 
        if (++braid->age > MI_CYCLES(mi)) {
 #ifdef STANDALONE
          erase_full_window(MI_DISPLAY(mi), MI_WINDOW(mi));
 #endif
-         init_braid(mi);
+               init_braid(mi);
        }
 }
 
@@ -423,12 +442,14 @@ release_braid(ModeInfo * mi)
 {
        if (braids != NULL) {
                (void) free((void *) braids);
-               braids = NULL;
+               braids = (braidtype *) NULL;
        }
 }
 
 void
 refresh_braid(ModeInfo * mi)
 {
-       /* Do nothing, it will refresh by itself */
+       MI_CLEARWINDOW(mi);
 }
+
+#endif /* MODE_braid */