* non-negative exponent are colored differently.
*
* The algorithm was taken from the September 1991 Scientific American article
- * by A. K. Dewdney who gives credit to Mario Markus of the Max Planck Institute
- * for its creation. Additional information and ideas were gleaned from the
- * discussion on alt.fractals involving Stephen Hall, Ed Kubaitis, Dave Platt
- * and Baback Moghaddam. Assistance with colormaps and spinning color wheels
- * and X was gleaned from Hiram Clawson. Rubber banding code was adapted from
- * an existing Mandelbrot program written by Stacey Campbell.
+ * by A. K. Dewdney who gives credit to Mario Markus of the Max Planck
+ * Institute for its creation. Additional information and ideas were gleaned
+ * from the discussion on alt.fractals involving Stephen Hall, Ed Kubaitis,
+ * Dave Platt and Baback Moghaddam. Assistance with colormaps and spinning
+ * color wheels and X was gleaned from Hiram Clawson. Rubber banding code was
+ * adapted from an existing Mandelbrot program written by Stacey Campbell.
*/
#define LYAP_PATCHLEVEL 4
#include "yarandom.h"
#include "hsv.h"
-#include <X11/cursorfont.h>
-#include <X11/Xutil.h>
-
-char *progclass = "XLyap";
-
-char *defaults [] = {
- ".background: black",
- ".foreground: white",
- "*randomize: false",
- "*builtin: -1",
- "*minColor: 1",
- "*maxColor: 256",
- "*dwell: 50",
- "*useLog: false",
- "*colorExponent: 1.0",
- "*colorOffset: 0",
- "*randomForce: ", /* 0.5 */
- "*settle: 50",
- "*minA: 2.0",
- "*minB: 2.0",
- "*wheels: 7",
- "*function: 10101010",
- "*forcingFunction: abbabaab",
- "*bRange: ", /* 2.0 */
- "*startX: 0.65",
- "*mapIndex: ", /* 0 */
- "*outputFile: ",
- "*beNegative: false",
- "*rgbMax: 65000",
- "*spinLength: 256",
- "*show: false",
- "*aRange: ", /* 2.0 */
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+#ifndef HAVE_COCOA
+# include <X11/cursorfont.h>
+#endif
+
+static const char *xlyap_defaults [] = {
+ ".background: black",
+ ".foreground: white",
+ "*randomize: true",
+ "*builtin: -1",
+ "*minColor: 1",
+ "*maxColor: 256",
+ "*dwell: 50",
+ "*useLog: false",
+ "*colorExponent: 1.0",
+ "*colorOffset: 0",
+ "*randomForce: ", /* 0.5 */
+ "*settle: 50",
+ "*minA: 2.0",
+ "*minB: 2.0",
+ "*wheels: 7",
+ "*function: 10101010",
+ "*forcingFunction: abbabaab",
+ "*bRange: ", /* 2.0 */
+ "*startX: 0.65",
+ "*mapIndex: ", /* 0 */
+ "*outputFile: ",
+ "*beNegative: false",
+ "*rgbMax: 65000",
+ "*spinLength: 256",
+ "*show: false",
+ "*aRange: ", /* 2.0 */
+ "*delay: 10000",
+ "*linger: 5",
+ "*colors: 200",
0
};
-XrmOptionDescRec options [] = {
- { "-randomize", ".randomize", XrmoptionNoArg, "true" },
- { "-builtin", ".builtin", XrmoptionSepArg, 0 },
- { "-C", ".minColor", XrmoptionSepArg, 0 }, /* n */
- { "-D", ".dwell", XrmoptionSepArg, 0 }, /* n */
- { "-L", ".useLog", XrmoptionNoArg, "true" },
- { "-M", ".colorExponent", XrmoptionSepArg, 0 }, /* r */
- { "-O", ".colorOffset", XrmoptionSepArg, 0 }, /* n */
- { "-R", ".randomForce", XrmoptionSepArg, 0 }, /* p */
- { "-S", ".settle", XrmoptionSepArg, 0 }, /* n */
- { "-a", ".minA", XrmoptionSepArg, 0 }, /* r */
- { "-b", ".minB", XrmoptionSepArg, 0 }, /* n */
- { "-c", ".wheels", XrmoptionSepArg, 0 }, /* n */
- { "-F", ".function", XrmoptionSepArg, 0 }, /* 10101010 */
- { "-f", ".forcingFunction", XrmoptionSepArg, 0 }, /* abbabaab */
- { "-h", ".bRange", XrmoptionSepArg, 0 }, /* r */
- { "-i", ".startX", XrmoptionSepArg, 0 }, /* r */
- { "-m", ".mapIndex", XrmoptionSepArg, 0 }, /* n */
- { "-o", ".outputFile", XrmoptionSepArg, 0 }, /* filename */
- { "-p", ".beNegative", XrmoptionNoArg, "true" },
- { "-r", ".rgbMax", XrmoptionSepArg, 0 }, /* n */
- { "-s", ".spinLength", XrmoptionSepArg, 0 }, /* n */
- { "-v", ".show", XrmoptionNoArg, "true" },
- { "-w", ".aRange", XrmoptionSepArg, 0 }, /* r */
+static XrmOptionDescRec xlyap_options [] = {
+ { "-randomize", ".randomize", XrmoptionNoArg, "true" },
+ { "-builtin", ".builtin", XrmoptionSepArg, 0 },
+ { "-C", ".minColor", XrmoptionSepArg, 0 }, /* n */
+ { "-D", ".dwell", XrmoptionSepArg, 0 }, /* n */
+ { "-L", ".useLog", XrmoptionNoArg, "true" },
+ { "-M", ".colorExponent", XrmoptionSepArg, 0 }, /* r */
+ { "-O", ".colorOffset", XrmoptionSepArg, 0 }, /* n */
+ { "-R", ".randomForce", XrmoptionSepArg, 0 }, /* p */
+ { "-S", ".settle", XrmoptionSepArg, 0 }, /* n */
+ { "-a", ".minA", XrmoptionSepArg, 0 }, /* r */
+ { "-b", ".minB", XrmoptionSepArg, 0 }, /* n */
+ { "-c", ".wheels", XrmoptionSepArg, 0 }, /* n */
+ { "-F", ".function", XrmoptionSepArg, 0 }, /* 10101010 */
+ { "-f", ".forcingFunction", XrmoptionSepArg, 0 }, /* abbabaab */
+ { "-h", ".bRange", XrmoptionSepArg, 0 }, /* r */
+ { "-i", ".startX", XrmoptionSepArg, 0 }, /* r */
+ { "-m", ".mapIndex", XrmoptionSepArg, 0 }, /* n */
+ { "-o", ".outputFile", XrmoptionSepArg, 0 }, /* filename */
+ { "-p", ".beNegative", XrmoptionNoArg, "true" },
+ { "-r", ".rgbMax", XrmoptionSepArg, 0 }, /* n */
+ { "-s", ".spinLength", XrmoptionSepArg, 0 }, /* n */
+ { "-v", ".show", XrmoptionNoArg, "true" },
+ { "-w", ".aRange", XrmoptionSepArg, 0 }, /* r */
+ { "-delay", ".delay", XrmoptionSepArg, 0 }, /* delay */
+ { "-linger", ".linger", XrmoptionSepArg, 0 }, /* linger */
{ 0, 0, 0, 0 }
};
-#define ABS(a) (((a)<0) ? (0-(a)) : (a) )
+#define ABS(a) (((a)<0) ? (0-(a)) : (a) )
#define Min(x,y) ((x < y)?x:y)
#define Max(x,y) ((x > y)?x:y)
#ifdef SIXTEEN_COLORS
-#define MAXPOINTS 128
-#ifdef BIGMEM
-#define MAXFRAMES 4
-#else
-#define MAXFRAMES 2
-#endif
-#define MAXCOLOR 16
-static int maxcolor=16, startcolor=0, color_offset=0, mincolindex=1;
-static int dwell=50, settle=25;
-static int width=128, height=128, xposition=128, yposition=128;
-#else
-#define MAXPOINTS 256
-#ifdef BIGMEM
-#define MAXFRAMES 8
-#else
-#define MAXFRAMES 2
-#endif
-#define MAXCOLOR 256
-static int maxcolor=256, startcolor=17, color_offset=96, mincolindex=33;
-static int dwell=100, settle=50;
-static int width=256, height=256;
-#endif
+# define MAXPOINTS 128
+# ifdef BIGMEM
+# define MAXFRAMES 4
+# else /* !BIGMEM */
+# define MAXFRAMES 2
+# endif /* !BIGMEM */
+# define MAXCOLOR 16
+#else /* !SIXTEEN_COLORS */
+# define MAXPOINTS 256
+# ifdef BIGMEM
+# define MAXFRAMES 8
+# else /* !BIGMEM */
+# define MAXFRAMES 2
+# endif /* !BIGMEM */
+# define MAXCOLOR 256
+#endif /* !SIXTEEN_COLORS */
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
-static int screen;
-static Display* dpy;
-static Visual *visual;
+#define MAXINDEX 64
+#define FUNCMAXINDEX 16
+#define MAXWHEELS 7
+#define NUMMAPS 5
+#define NBUILTINS 22
-static unsigned long foreground, background;
+#ifndef TRUE
+# define TRUE 1
+# define FALSE 0
+#endif
-static Window canvas;
typedef struct {
- int x, y;
+ int x, y;
} xy_t;
+#if 0
typedef struct {
- int start_x, start_y;
- int last_x, last_y;
- } rubber_band_data_t;
+ int start_x, start_y;
+ int last_x, last_y;
+} rubber_band_data_t;
+#endif
typedef struct {
- Cursor band_cursor;
- double p_min, p_max, q_min, q_max;
- rubber_band_data_t rubber_band;
- } image_data_t;
+# ifndef HAVE_COCOA
+ Cursor band_cursor;
+# endif
+ double p_min, p_max, q_min, q_max;
+/* rubber_band_data_t rubber_band;*/
+} image_data_t;
typedef struct points_t {
- XPoint data[MAXCOLOR][MAXPOINTS];
- int npoints[MAXCOLOR];
- } points_t;
+ XPoint data[MAXCOLOR][MAXPOINTS];
+ int npoints[MAXCOLOR];
+} points_t;
-static points_t Points;
-static image_data_t rubber_data;
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
+typedef double (*PFD)(double,double);
+
+/* #### What was this for? Everything was drawn twice, to the window and
+ to this, and this was never displayed! */
+/*#define BACKING_PIXMAP*/
+
+struct state {
+ int screen;
+ Display *dpy;
+ Visual *visual;
+ Colormap cmap;
+
+ unsigned long foreground, background;
+
+ Window canvas;
+ int delay, linger;
+
+ unsigned int maxcolor, startcolor, mincolindex;
+ int color_offset;
+ int dwell, settle;
+ int width, height, xposition, yposition;
+
+ points_t Points;
+/* image_data_t rubber_data;*/
+
+ GC Data_GC[MAXCOLOR]/*, RubberGC*/;
+ PFD map, deriv;
+
+ int aflag, bflag, wflag, hflag, Rflag;
+
+ int maxindex;
+ int funcmaxindex;
+ double min_a, min_b, a_range, b_range, minlyap;
+ double max_a, max_b;
+ double start_x, lyapunov, a_inc, b_inc, a, b;
+ int numcolors, numfreecols, lowrange;
+ xy_t point;
+#ifdef BACKING_PIXMAP
+ Pixmap pixmap;
#endif
+/* XColor Colors[MAXCOLOR];*/
+ double *exponents[MAXFRAMES];
+ double a_minimums[MAXFRAMES], b_minimums[MAXFRAMES];
+ double a_maximums[MAXFRAMES], b_maximums[MAXFRAMES];
+ double minexp, maxexp, prob;
+ int expind[MAXFRAMES], resized[MAXFRAMES];
+ int numwheels, force, Force, negative;
+ int rgb_max, nostart, stripe_interval;
+ int save, show, useprod, spinlength;
+ int maxframe, frame, dorecalc, mapindex, run;
+ char *outname;
+
+ int sendpoint_index;
+
+ int forcing[MAXINDEX];
+ int Forcing[FUNCMAXINDEX];
+
+ int reset_countdown;
+
+ int ncolors;
+ XColor colors[MAXCOLOR];
+};
-static GC Data_GC[MAXCOLOR], RubberGC;
-#define MAXINDEX 64
-#define FUNCMAXINDEX 16
-#define MAXWHEELS 7
-#define NUMMAPS 5
+static const double pmins[NUMMAPS] = { 2.0, 0.0, 0.0, 0.0, 0.0 };
+static const double pmaxs[NUMMAPS] = { 4.0, 1.0, 6.75, 6.75, 16.0 };
+static const double amins[NUMMAPS] = { 2.0, 0.0, 0.0, 0.0, 0.0 };
+static const double aranges[NUMMAPS] = { 2.0, 1.0, 6.75, 6.75, 16.0 };
+static const double bmins[NUMMAPS] = { 2.0, 0.0, 0.0, 0.0, 0.0 };
+static const double branges[NUMMAPS] = { 2.0, 1.0, 6.75, 6.75, 16.0 };
-typedef double (*PFD)(double,double);
+/****************************************************************************/
-static double logistic(double,double), circle(double,double), leftlog(double,double), rightlog(double,double), doublelog(double,double);
-static double dlogistic(double,double), dcircle(double,double), dleftlog(double,double), drightlog(double,double), ddoublelog(double,double);
-static PFD map, deriv;
-static PFD Maps[NUMMAPS] = { logistic, circle, leftlog, rightlog, doublelog };
-static PFD Derivs[NUMMAPS] = { dlogistic, dcircle, dleftlog, drightlog, ddoublelog };
-
-static int aflag=0, bflag=0, wflag=0, hflag=0, Rflag=0;
-static double pmins[NUMMAPS] = { 2.0, 0.0, 0.0, 0.0, 0.0 };
-static double pmaxs[NUMMAPS] = { 4.0, 1.0, 6.75, 6.75, 16.0 };
-static double amins[NUMMAPS] = { 2.0, 0.0, 0.0, 0.0, 0.0 };
-static double aranges[NUMMAPS] = { 2.0, 1.0, 6.75, 6.75, 16.0 };
-static double bmins[NUMMAPS] = { 2.0, 0.0, 0.0, 0.0, 0.0 };
-static double branges[NUMMAPS] = { 2.0, 1.0, 6.75, 6.75, 16.0 };
-
-static int forcing[MAXINDEX] = { 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
- 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
- 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1 };
-static int Forcing[FUNCMAXINDEX] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
-
-static int maxindex = MAXINDEX;
-static int funcmaxindex = FUNCMAXINDEX;
-static double min_a=2.0, min_b=2.0, a_range=2.0, b_range=2.0, minlyap=1.0;
-static double max_a=4.0, max_b=4.0;
-static double start_x=0.65, lyapunov, a_inc, b_inc, a, b;
-static int numcolors=16, numfreecols, displayplanes, lowrange;
-static xy_t point;
-static Pixmap pixmap;
-static Colormap cmap;
-static XColor Colors[MAXCOLOR];
-static double *exponents[MAXFRAMES];
-static double a_minimums[MAXFRAMES], b_minimums[MAXFRAMES];
-static double a_maximums[MAXFRAMES], b_maximums[MAXFRAMES];
-static double minexp, maxexp, prob=0.5;
-static int expind[MAXFRAMES]={0}, resized[MAXFRAMES]={0};
-static int numwheels=MAXWHEELS, force=0, Force=0, negative=1;
-static int rgb_max=65000, nostart=1, stripe_interval=7;
-static int save=1, show=0, useprod=1, spinlength=256, savefile=0;
-static int maxframe=0, frame=0, dorecalc=0, mapindex=0, run=1;
-static char *outname="lyap.out";
-
-
-const char * const version = LYAP_VERSION;
-
-static void resize(void);
-static void redisplay(Window w, XExposeEvent *event);
-static void Spin(Window w);
-static void show_defaults(void);
-static void StartRubberBand(Window w, image_data_t *data, XEvent *event);
-static void TrackRubberBand(Window w, image_data_t *data, XEvent *event);
-static void EndRubberBand(Window w, image_data_t *data, XEvent *event);
-static void CreateXorGC(void);
-static void InitBuffer(void);
-static void BufferPoint(Display *display, Window window, int color,
- int x, int y);
-static void FlushBuffer(void);
-static void init_canvas(void);
-static void init_data(void);
-static void init_color(void);
-static void parseargs(void);
-static void Clear(void);
-static void setupmem(void);
-static void main_event(void);
-static int complyap(void);
-static void Getkey(XKeyEvent *event);
-static int sendpoint(double expo);
-static void save_to_file(void);
-static void setforcing(void);
-static void check_params(int mapnum, int parnum);
-static void usage(void);
-static void Destroy_frame(void);
-static void freemem(void);
-static void Redraw(void);
-static void redraw(double *exparray, int index, int cont);
-static void recalc(void);
-static void SetupCorners(XPoint *corners, image_data_t *data);
-static void set_new_params(Window w, image_data_t *data);
-static void go_down(void);
-static void go_back(void);
-static void go_init(void);
-static void jumpwin(void);
-static void print_help(void);
-static void print_values(void);
-
-
-void
-screenhack (Display *d, Window window)
-{
- XWindowAttributes xgwa;
- int builtin = -1;
- dpy = d;
- XGetWindowAttributes (dpy, window, &xgwa);
- width = xgwa.width;
- height = xgwa.height;
- visual = xgwa.visual;
- cmap = xgwa.colormap;
+/* callback function declarations
+ */
- parseargs();
+static double logistic(double,double);
+static double circle(double,double);
+static double leftlog(double,double);
+static double rightlog(double,double);
+static double doublelog(double,double);
+static double dlogistic(double,double);
+static double dcircle(double,double);
+static double dleftlog(double,double);
+static double drightlog(double,double);
+static double ddoublelog(double,double);
- if (get_boolean_resource("randomize", "Boolean"))
- builtin = random() % 22;
- else {
- char *s = get_string_resource("builtin", "Integer");
- if (s && *s)
- builtin = atoi(s);
- if (s) free (s);
- }
-
- if (builtin >= 0)
- {
- char *ff = 0;
- switch (builtin) {
- case 0:
- min_a = 3.75; aflag++;
- min_b = 3.299999; bflag++;
- a_range = 0.05; wflag++;
- b_range = 0.05; hflag++;
- dwell = 200;
- settle = 100;
- ff = "abaabbaaabbb";
- break;
-
- case 1:
- min_a = 3.8; aflag++;
- min_b = 3.2; bflag++;
- b_range = .05; hflag++;
- a_range = .05; wflag++;
- ff = "bbbbbaaaaa";
- break;
-
- case 2:
- min_a = 3.4; aflag++;
- min_b = 3.04; bflag++;
- a_range = .5; wflag++;
- b_range = .5; hflag++;
- ff = "abbbbbbbbb";
- settle = 500;
- dwell = 1000;
- break;
-
- case 3:
- min_a = 3.5; aflag++;
- min_b = 3.0; bflag++;
- a_range = 0.2; wflag++;
- b_range = 0.2; hflag++;
- dwell = 600;
- settle = 300;
- ff = "aaabbbab";
- break;
-
- case 4:
- min_a = 3.55667; aflag++;
- min_b = 3.2; bflag++;
- b_range = .05; hflag++;
- a_range = .05; wflag++;
- ff = "bbbbbaaaaa";
- break;
-
- case 5:
- min_a = 3.79; aflag++;
- min_b = 3.22; bflag++;
- b_range = .02999; hflag++;
- a_range = .02999; wflag++;
- ff = "bbbbbaaaaa";
- break;
-
- case 6:
- min_a = 3.7999; aflag++;
- min_b = 3.299999; bflag++;
- a_range = 0.2; wflag++;
- b_range = 0.2; hflag++;
- dwell = 300;
- settle = 150;
- ff = "abaabbaaabbb";
- break;
-
- case 7:
- min_a = 3.89; aflag++;
- min_b = 3.22; bflag++;
- b_range = .028; hflag++;
- a_range = .02999; wflag++;
- ff = "bbbbbaaaaa";
- settle = 600;
- dwell = 1000;
- break;
-
- case 8:
- min_a = 3.2; aflag++;
- min_b = 3.7; bflag++;
- a_range = 0.05; wflag++;
- b_range = .005; hflag++;
- ff = "abbbbaa";
- break;
-
- case 9:
- ff = "aaaaaabbbbbb";
- mapindex = 1;
- dwell = 400;
- settle = 200;
- minlyap = maxexp = ABS(-0.85);
- minexp = -1.0 * minlyap;
- break;
-
- case 10:
- ff = "aaaaaabbbbbb";
- mapindex = 1;
- dwell = 400;
- settle = 200;
- minlyap = maxexp = ABS(-0.85);
- minexp = -1.0 * minlyap;
- break;
-
- case 11:
- mapindex = 1;
- dwell = 400;
- settle = 200;
- minlyap = maxexp = ABS(-0.85);
- minexp = -1.0 * minlyap;
- break;
-
- case 12:
- ff = "abbb";
- mapindex = 1;
- dwell = 400;
- settle = 200;
- minlyap = maxexp = ABS(-0.85);
- minexp = -1.0 * minlyap;
- break;
-
- case 13:
- ff = "abbabaab";
- mapindex = 1;
- dwell = 400;
- settle = 200;
- minlyap = maxexp = ABS(-0.85);
- minexp = -1.0 * minlyap;
- break;
-
- case 14:
- ff = "abbabaab";
- dwell = 800;
- settle = 200;
- minlyap = maxexp = ABS(-0.85);
- minexp = -1.0 * minlyap;
- /* #### -x 0.05 */
- min_a = 3.91; aflag++;
- a_range = 0.0899999999; wflag++;
- min_b = 3.28; bflag++;
- b_range = 0.35; hflag++;
- break;
-
- case 15:
- ff = "aaaaaabbbbbb";
- dwell = 400;
- settle = 200;
- minlyap = maxexp = ABS(-0.85);
- minexp = -1.0 * minlyap;
- break;
-
- case 16:
- dwell = 400;
- settle = 200;
- minlyap = maxexp = ABS(-0.85);
- minexp = -1.0 * minlyap;
- break;
-
- case 17:
- ff = "abbb";
- dwell = 400;
- settle = 200;
- minlyap = maxexp = ABS(-0.85);
- minexp = -1.0 * minlyap;
- break;
-
- case 18:
- ff = "abbabaab";
- dwell = 400;
- settle = 200;
- minlyap = maxexp = ABS(-0.85);
- minexp = -1.0 * minlyap;
- break;
-
- case 19:
- mapindex = 2;
- ff = "aaaaaabbbbbb";
- dwell = 400;
- settle = 200;
- minlyap = maxexp = ABS(-0.85);
- minexp = -1.0 * minlyap;
- break;
-
- case 20:
- mapindex = 2;
- dwell = 400;
- settle = 200;
- minlyap = maxexp = ABS(-0.85);
- minexp = -1.0 * minlyap;
- break;
-
- case 21:
- mapindex = 2;
- ff = "abbb";
- dwell = 400;
- settle = 200;
- minlyap = maxexp = ABS(-0.85);
- minexp = -1.0 * minlyap;
- break;
-
- case 22:
- mapindex = 2;
- ff = "abbabaab";
- dwell = 400;
- settle = 200;
- minlyap = maxexp = ABS(-0.85);
- minexp = -1.0 * minlyap;
- break;
- }
+static const PFD Maps[NUMMAPS] = { logistic, circle, leftlog, rightlog,
+ doublelog };
+static const PFD Derivs[NUMMAPS] = { dlogistic, dcircle, dleftlog,
+ drightlog, ddoublelog };
- if (ff) {
- char *ch;
- int bindex = 0;
- maxindex = strlen(ff);
- if (maxindex > MAXINDEX)
- usage();
- ch = ff;
- force++;
- while (bindex < maxindex) {
- if (*ch == 'a')
- forcing[bindex++] = 0;
- else if (*ch == 'b')
- forcing[bindex++] = 1;
- else
- usage();
- ch++;
- }
- }
- }
- screen = DefaultScreen(dpy);
- background = BlackPixel(dpy, screen);
- setupmem();
- init_data();
- if (displayplanes > 1)
- foreground = startcolor;
- else
- foreground = WhitePixel(dpy, screen);
+/****************************************************************************/
- /*
- * Create the window to display the Lyapunov exponents
- */
- canvas = window;
- init_canvas();
-
- if (displayplanes > 1) {
- init_color();
- } else {
- XQueryColors(dpy, DefaultColormap(dpy, DefaultScreen(dpy)),
- Colors, numcolors);
- }
- pixmap = XCreatePixmap(dpy, window, width, height, xgwa.depth);
- rubber_data.band_cursor = XCreateFontCursor(dpy, XC_hand2);
- CreateXorGC();
- Clear();
- for(;;)
- main_event();
-}
+/* other function declarations
+ */
+
+static void resize(struct state *);
+/*static void Spin(struct state *);*/
+static void show_defaults(struct state *);
+/*static void StartRubberBand(struct state *, image_data_t *, XEvent *);
+static void TrackRubberBand(struct state *, image_data_t *, XEvent *);
+static void EndRubberBand(struct state *, image_data_t *, XEvent *);*/
+/*static void CreateXorGC(struct state *);*/
+static void InitBuffer(struct state *);
+static void BufferPoint(struct state *, int color, int x, int y);
+static void FlushBuffer(struct state *);
+static void init_data(struct state *);
+static void init_color(struct state *);
+static void parseargs(struct state *);
+static void Clear(struct state *);
+static void setupmem(struct state *);
+static int complyap(struct state *);
+static Bool Getkey(struct state *, XKeyEvent *);
+static int sendpoint(struct state *, double expo);
+/*static void save_to_file(struct state *);*/
+static void setforcing(struct state *);
+static void check_params(struct state *, int mapnum, int parnum);
+static void usage(struct state *);
+static void Destroy_frame(struct state *);
+static void freemem(struct state *);
+static void Redraw(struct state *);
+static void redraw(struct state *, double *exparray, int index, int cont);
+static void recalc(struct state *);
+/*static void SetupCorners(XPoint *, image_data_t *);
+static void set_new_params(struct state *, image_data_t *);*/
+static void go_down(struct state *);
+static void go_back(struct state *);
+static void go_init(struct state *);
+static void jumpwin(struct state *);
+static void print_help(struct state *);
+static void print_values(struct state *);
+
+
+/****************************************************************************/
-static void
-main_event(void)
-{
- int n;
- XEvent event;
-
- if (complyap() == TRUE)
- run=0;
- n = XEventsQueued(dpy, QueuedAfterFlush);
- while (n--) {
- XNextEvent(dpy, &event);
- switch(event.type)
- {
- case KeyPress:
- Getkey(&event.xkey);
- break;
- case Expose:
- redisplay(canvas, &event.xexpose);
- break;
- case ConfigureNotify:
- resize();
- break;
- case ButtonPress:
- StartRubberBand(canvas, &rubber_data, &event);
- break;
- case MotionNotify:
- TrackRubberBand(canvas, &rubber_data, &event);
- break;
- case ButtonRelease:
- EndRubberBand(canvas, &rubber_data, &event);
- break;
- default:
- screenhack_handle_event (dpy, &event);
- break;
- }
- }
-}
/* complyap() is the guts of the program. This is where the Lyapunov exponent
* is calculated. For each iteration (past some large number of iterations)
* speed up is achieved by utilizing the fact that log(a*b) = log(a) + log(b).
*/
static int
-complyap(void)
+complyap(struct state *st)
{
int i, bindex;
double total, prod, x, dx, r;
- if (!run)
+ if (st->maxcolor > MAXCOLOR)
+ abort();
+
+ if (!st->run)
return TRUE;
- a += a_inc;
- if (a >= max_a) {
- if (sendpoint(lyapunov) == TRUE)
+ st->a += st->a_inc;
+ if (st->a >= st->max_a) {
+ if (sendpoint(st, st->lyapunov) == TRUE)
return FALSE;
else {
- FlushBuffer();
- if (savefile)
- save_to_file();
+ FlushBuffer(st);
+ /* if (savefile)
+ save_to_file(); */
return TRUE;
}
}
- if (b >= max_b) {
- FlushBuffer();
- if (savefile)
- save_to_file();
+ if (st->b >= st->max_b) {
+ FlushBuffer(st);
+ /* if (savefile)
+ save_to_file();*/
return TRUE;
}
prod = 1.0;
total = 0.0;
bindex = 0;
- x = start_x;
- r = (forcing[bindex]) ? b : a;
+ x = st->start_x;
+ r = (st->forcing[bindex]) ? st->b : st->a;
#ifdef MAPS
findex = 0;
- map = Maps[Forcing[findex]];
+ map = Maps[st->Forcing[findex]];
#endif
- for (i=0;i<settle;i++) { /* Here's where we let the thing */
- x = (*map)(x, r); /* "settle down". There is usually */
- if (++bindex >= maxindex) { /* some initial "noise" in the */
+ for (i=0;i<st->settle;i++) { /* Here's where we let the thing */
+ x = st->map (x, r); /* "settle down". There is usually */
+ if (++bindex >= st->maxindex) { /* some initial "noise" in the */
bindex = 0; /* iterations. How can we optimize */
- if (Rflag) /* the value of settle ??? */
- setforcing();
+ if (st->Rflag) /* the value of settle ??? */
+ setforcing(st);
}
- r = (forcing[bindex]) ? b : a;
+ r = (st->forcing[bindex]) ? st->b : st->a;
#ifdef MAPS
if (++findex >= funcmaxindex)
findex = 0;
- map = Maps[Forcing[findex]];
+ map = Maps[st->Forcing[findex]];
#endif
}
#ifdef MAPS
- deriv = Derivs[Forcing[findex]];
+ deriv = Derivs[st->Forcing[findex]];
#endif
- if (useprod) { /* using log(a*b) */
- for (i=0;i<dwell;i++) {
- x = (*map)(x, r);
- dx = (*deriv)(x, r); /* ABS is a macro, so don't be fancy */
+ if (st->useprod) { /* using log(a*b) */
+ for (i=0;i<st->dwell;i++) {
+ x = st->map (x, r);
+ dx = st->deriv (x, r); /* ABS is a macro, so don't be fancy */
dx = ABS(dx);
if (dx == 0.0) /* log(0) is nasty so break out. */
- {
- i++;
- break;
- }
+ {
+ i++;
+ break;
+ }
prod *= dx;
/* we need to prevent overflow and underflow */
if ((prod > 1.0e12) || (prod < 1.0e-12)) {
- total += log(prod);
- prod = 1.0;
+ total += log(prod);
+ prod = 1.0;
}
- if (++bindex >= maxindex) {
- bindex = 0;
- if (Rflag)
- setforcing();
+ if (++bindex >= st->maxindex) {
+ bindex = 0;
+ if (st->Rflag)
+ setforcing(st);
}
- r = (forcing[bindex]) ? b : a;
+ r = (st->forcing[bindex]) ? st->b : st->a;
#ifdef MAPS
if (++findex >= funcmaxindex)
- findex = 0;
- map = Maps[Forcing[findex]];
- deriv = Derivs[Forcing[findex]];
+ findex = 0;
+ map = Maps[st->Forcing[findex]];
+ deriv = Derivs[st->Forcing[findex]];
#endif
}
total += log(prod);
- lyapunov = (total * M_LOG2E) / (double)i;
+ st->lyapunov = (total * M_LOG2E) / (double)i;
}
- else { /* use log(a) + log(b) */
- for (i=0;i<dwell;i++) {
- x = (*map)(x, r);
- dx = (*deriv)(x, r); /* ABS is a macro, so don't be fancy */
+ else { /* use log(a) + log(b) */
+ for (i=0;i<st->dwell;i++) {
+ x = st->map (x, r);
+ dx = st->deriv (x, r); /* ABS is a macro, so don't be fancy */
dx = ABS(dx);
if (x == 0.0) /* log(0) check */
- {
- i++;
- break;
- }
+ {
+ i++;
+ break;
+ }
total += log(dx);
- if (++bindex >= maxindex) {
- bindex = 0;
- if (Rflag)
- setforcing();
+ if (++bindex >= st->maxindex) {
+ bindex = 0;
+ if (st->Rflag)
+ setforcing(st);
}
- r = (forcing[bindex]) ? b : a;
+ r = (st->forcing[bindex]) ? st->b : st->a;
#ifdef MAPS
if (++findex >= funcmaxindex)
- findex = 0;
- map = Maps[Forcing[findex]];
- deriv = Derivs[Forcing[findex]];
+ findex = 0;
+ map = Maps[st->Forcing[findex]];
+ deriv = Derivs[st->Forcing[findex]];
#endif
}
- lyapunov = (total * M_LOG2E) / (double)i;
+ st->lyapunov = (total * M_LOG2E) / (double)i;
}
- if (sendpoint(lyapunov) == TRUE)
+ if (sendpoint(st, st->lyapunov) == TRUE)
return FALSE;
else {
- FlushBuffer();
- if (savefile)
- save_to_file();
+ FlushBuffer(st);
+ /* if (savefile)
+ save_to_file();*/
return TRUE;
}
}
static double
-logistic(double x, double r) /* the familiar logistic map */
+logistic(double x, double r) /* the familiar logistic map */
{
return(r * x * (1.0 - x));
}
static double
-dlogistic(double x, double r) /* the derivative of logistic map */
+dlogistic(double x, double r) /* the derivative of logistic map */
{
return(r - (2.0 * r * x));
}
static double
-circle(double x, double r) /* sin() hump or sorta like the circle map */
+circle(double x, double r) /* sin() hump or sorta like the circle map */
{
return(r * sin(M_PI * x));
}
static double
-dcircle(double x, double r) /* derivative of the "sin() hump" */
+dcircle(double x, double r) /* derivative of the "sin() hump" */
{
return(r * M_PI * cos(M_PI * x));
}
static double
-leftlog(double x, double r) /* left skewed logistic */
+leftlog(double x, double r) /* left skewed logistic */
{
double d;
}
static void
-init_data(void)
-{
- numcolors = XDisplayCells(dpy, XDefaultScreen(dpy));
- displayplanes = DisplayPlanes(dpy, XDefaultScreen(dpy));
- if (numcolors > maxcolor)
- numcolors = maxcolor;
- numfreecols = numcolors - mincolindex;
- lowrange = mincolindex - startcolor;
- a_inc = a_range / (double)width;
- b_inc = b_range / (double)height;
- point.x = -1;
- point.y = 0;
- a = rubber_data.p_min = min_a;
- b = rubber_data.q_min = min_b;
- rubber_data.p_max = max_a;
- rubber_data.q_max = max_b;
- if (show)
- show_defaults();
- InitBuffer();
-}
-
-static void
-init_canvas(void)
+init_data(struct state *st)
{
- static int i;
-
- /*
- * create default, writable, graphics contexts for the canvas.
- */
- for (i=0; i<maxcolor; i++) {
- Data_GC[i] = XCreateGC(dpy, canvas,
- (unsigned long) NULL, (XGCValues *) NULL);
- /* set the background to black */
- XSetBackground(dpy,Data_GC[i],BlackPixel(dpy,XDefaultScreen(dpy)));
- /* set the foreground of the ith context to i */
- XSetForeground(dpy, Data_GC[i], i);
- }
- if (displayplanes == 1) {
- XSetForeground(dpy,Data_GC[0],BlackPixel(dpy,XDefaultScreen(dpy)));
- XSetForeground(dpy,Data_GC[1],WhitePixel(dpy,XDefaultScreen(dpy)));
- }
+ st->numcolors = get_integer_resource (st->dpy, "colors", "Integer");
+ if (st->numcolors < 2)
+ st->numcolors = 2;
+ if (st->numcolors > st->maxcolor)
+ st->numcolors = st->maxcolor;
+ st->numfreecols = st->numcolors - st->mincolindex;
+ st->lowrange = st->mincolindex - st->startcolor;
+ st->a_inc = st->a_range / (double)st->width;
+ st->b_inc = st->b_range / (double)st->height;
+ st->point.x = -1;
+ st->point.y = 0;
+ st->a = /*st->rubber_data.p_min = */st->min_a;
+ st->b = /*st->rubber_data.q_min = */st->min_b;
+/* st->rubber_data.p_max = st->max_a;
+ st->rubber_data.q_max = st->max_b;*/
+ if (st->show)
+ show_defaults(st);
+ InitBuffer(st);
}
#if 0
static void
hls2rgb(int hue_light_sat[3],
- int rgb[3]) /* Each in range [0..65535] */
+ int rgb[3]) /* Each in range [0..65535] */
{
unsigned short r, g, b;
- hsv_to_rgb((int) (hue_light_sat[0] / 10), /* 0-3600 -> 0-360 */
- (int) ((hue_light_sat[2]/1000.0) * 64435), /* 0-1000 -> 0-65535 */
- (int) ((hue_light_sat[1]/1000.0) * 64435), /* 0-1000 -> 0-65535 */
- &r, &g, &b);
+ hsv_to_rgb((int) (hue_light_sat[0] / 10), /* 0-3600 -> 0-360 */
+ (int) ((hue_light_sat[2]/1000.0) * 64435), /* 0-1000 -> 0-65535 */
+ (int) ((hue_light_sat[1]/1000.0) * 64435), /* 0-1000 -> 0-65535 */
+ &r, &g, &b);
rgb[0] = r;
rgb[1] = g;
rgb[2] = b;
static void
-init_color(void)
+init_color(struct state *st)
{
-#if 1
-
int i;
- XColor colors[256];
- int ncolors = maxcolor;
- Bool writable = False;
- make_smooth_colormap(dpy, visual, cmap,
- colors, &ncolors, True, &writable, True);
-
- for (i = 0; i < maxcolor; i++)
- XSetForeground(dpy, Data_GC[i],
- colors[((int) ((i / ((float)maxcolor)) * ncolors))].pixel);
-
-#else
- static int i, j, colgap, leg, step;
- static Visual *visual;
- Colormap def_cmap;
- int hls[3], rgb[3];
-
- def_cmap = DefaultColormap(dpy, DefaultScreen(dpy));
- for (i=0; i<numcolors; i++) {
- Colors[i].pixel = i;
- Colors[i].flags = DoRed|DoGreen|DoBlue;
- }
-
- /* Try to write into a new color map */
- visual = DefaultVisual(dpy, DefaultScreen(dpy));
- cmap = XCreateColormap(dpy, canvas, visual, AllocAll);
- XQueryColors(dpy, def_cmap, Colors, numcolors);
- if (mincolindex)
- colgap = rgb_max / mincolindex;
- else
- colgap = rgb_max;
- hls[0] = 50; /* Hue in low range */
- hls[2] = 1000; /* Fully saturated */
- for (i=startcolor; i<lowrange + startcolor; i++) {
- hls[1] = 1000L * (i-startcolor) / lowrange;
- hls2rgb(hls, rgb);
- Colors[i].red = rgb[0];
- Colors[i].green = rgb[1];
- Colors[i].blue = rgb[2];
- }
- colgap = rgb_max / numcolors;
- if (numwheels == 0)
- XQueryColors(dpy, def_cmap, Colors, numcolors);
- else if (numwheels == 1) {
- colgap = 2*rgb_max/(numcolors - color_offset);
- for (i=mincolindex; i<(numcolors/2); i++) {
- Colors[i].blue = 0;
- Colors[i].green=((i+color_offset)*colgap);
- Colors[i].red=((i+color_offset)*colgap);
- }
- for (i=(numcolors/2); i<(numcolors); i++) {
- Colors[i].blue = 0;
- Colors[i].green=(((numcolors-i)+color_offset)*colgap);
- Colors[i].red=(((numcolors-i)+color_offset)*colgap);
- }
- }
- else if (numwheels == 2) {
- hls[0] = 800; /* Hue in mid range */
- hls[2] = 1000; /* Fully saturated */
- for (i=startcolor; i<lowrange + startcolor; i++) {
- hls[1] = 1000L * (i-startcolor) / lowrange;
- hls2rgb(hls, rgb);
- Colors[i].red = rgb[0];
- Colors[i].green = rgb[1];
- Colors[i].blue = rgb[2];
- }
- for (i=mincolindex; i<(numcolors/2); i++) {
- Colors[i].blue = rgb_max;
- Colors[i].green = 0;
- Colors[i].red=(i*2*rgb_max/numcolors);
- }
- for (i=(numcolors/2); i<numcolors; i++) {
- Colors[i].blue = rgb_max;
- Colors[i].green = 0;
- Colors[i].red=((numcolors - i)*2*rgb_max/numcolors);
+ if (st->ncolors)
+ free_colors (st->dpy, st->cmap, st->colors, st->ncolors);
+ st->ncolors = st->maxcolor;
+ make_smooth_colormap(st->dpy, st->visual, st->cmap,
+ st->colors, &st->ncolors, True, NULL, True);
+
+ for (i = 0; i < st->maxcolor; i++) {
+ if (! st->Data_GC[i]) {
+ XGCValues gcv;
+ gcv.background = BlackPixel(st->dpy, st->screen);
+ st->Data_GC[i] = XCreateGC(st->dpy, st->canvas, GCBackground, &gcv);
}
+ XSetForeground(st->dpy, st->Data_GC[i],
+ st->colors[((int) ((i / ((float)st->maxcolor)) *
+ st->ncolors))].pixel);
}
- else if (numwheels == 3) {
- hls[0] = 800; /* Hue in mid range */
- hls[2] = 1000; /* Fully saturated */
- for (i=startcolor; i<lowrange + startcolor; i++) {
- hls[1] = 1000L * (i-startcolor) / lowrange;
- hls2rgb(hls, rgb);
- Colors[i].red = rgb[0];
- Colors[i].green = rgb[1];
- Colors[i].blue = rgb[2];
- }
- colgap = 4*rgb_max/numcolors;
- for (i=mincolindex; i<(numcolors/4); i++) {
- Colors[i].blue = rgb_max;
- Colors[i].green = 0;
- Colors[i].red=(i*colgap);
- }
- for (i=(numcolors/4); i<(numcolors/2); i++) {
- Colors[i].red = rgb_max;
- Colors[i].green = 0;
- Colors[i].blue=((numcolors/2) - i) * colgap;
- }
- for (i=(numcolors/2); i<(0.75*numcolors); i++) {
- Colors[i].red = rgb_max;
- Colors[i].blue=(i * colgap);
- Colors[i].green = 0;
- }
- for (i=(0.75*numcolors); i<numcolors; i++) {
- Colors[i].blue = rgb_max;
- Colors[i].green = 0;
- Colors[i].red=(numcolors-i)*colgap;
- }
- }
- else if (numwheels == 4) {
- hls[0] = 800; /* Hue in mid range */
- hls[2] = 1000; /* Fully saturated */
- for (i=startcolor; i<lowrange + startcolor; i++) {
- hls[1] = 1000L * (i-startcolor) / lowrange;
- hls2rgb(hls, rgb);
- Colors[i].red = rgb[0];
- Colors[i].green = rgb[1];
- Colors[i].blue = rgb[2];
- }
- colgap = numwheels * rgb_max / numcolors;
- for (i=mincolindex; i<(numcolors/numwheels); i++) {
- Colors[i].blue = rgb_max;
- Colors[i].green = 0;
- Colors[i].red=(i*colgap);
- }
- for (i=(numcolors/numwheels); i<(2*numcolors/numwheels); i++) {
- Colors[i].red = rgb_max;
- Colors[i].green = 0;
- Colors[i].blue=((2*numcolors/numwheels) - i) * colgap;
- }
- for (i=(2*numcolors/numwheels); i<numcolors; i++) {
- Colors[i].red = rgb_max;
- Colors[i].green=(i - (2*numcolors/numwheels)) * colgap;
- Colors[i].blue = 0;
- }
- }
- else if (numwheels == 5) {
- hls[1] = 700; /* Lightness in midrange */
- hls[2] = 1000; /* Fully saturated */
- for (i=mincolindex; i<numcolors; i++) {
- hls[0] = 3600L * i / numcolors;
- hls2rgb(hls, rgb);
- Colors[i].red = rgb[0];
- Colors[i].green = rgb[1];
- Colors[i].blue = rgb[2];
- }
- for (i=mincolindex; i<numcolors; i+=stripe_interval) {
- hls[0] = 3600L * i / numcolors;
- hls2rgb(hls, rgb);
- Colors[i].red = rgb[0] / 2;
- Colors[i].green = rgb[1] / 2;
- Colors[i].blue = rgb[2] / 2;
- }
- }
- else if (numwheels == 6) {
- hls[0] = 800; /* Hue in mid range */
- hls[2] = 1000; /* Fully saturated */
- for (i=startcolor; i<lowrange + startcolor; i++) {
- hls[1] = 1000L * (i-startcolor) / lowrange;
- hls2rgb(hls, rgb);
- Colors[i].red = rgb[0];
- Colors[i].green = rgb[1];
- Colors[i].blue = rgb[2];
- }
- step = numfreecols / 3;
- leg = step+mincolindex;
- for (i = mincolindex; i < leg; ++i)
- {
- Colors[i].pixel = i;
- Colors[i].red = fabs(65535 - (double)i / step * 65535.0);
- Colors[i].blue = (double)i / step * 65535.0;
- Colors[i].green = 0;
- Colors[i].flags = DoRed | DoGreen | DoBlue;
- }
- for (j = 0, i = leg, leg += step; i < leg; ++i, ++j)
- {
- Colors[i].pixel = i;
- Colors[i].red = (double)j / step * 65535.0;
- Colors[i].blue = 65535;
- Colors[i].green = Colors[i].red;
- Colors[i].flags = DoRed | DoGreen | DoBlue;
- }
- for (j = 0, i = leg, leg += step; i < leg; ++i, ++j)
- {
- Colors[i].pixel = i;
- Colors[i].red = 65535;
- Colors[i].blue = fabs(65535 - (double)j / step * 65535.0);
- Colors[i].green = Colors[i].blue;
- Colors[i].flags = DoRed | DoGreen | DoBlue;
- }
- }
- else if (numwheels == MAXWHEELS) { /* rainbow palette */
- hls[1] = 500; /* Lightness in midrange */
- hls[2] = 1000; /* Fully saturated */
- for (i=mincolindex; i<numcolors; i++) {
- hls[0] = 3600L * i / numcolors;
- hls2rgb(hls, rgb);
- Colors[i].red = rgb[0];
- Colors[i].green = rgb[1];
- Colors[i].blue = rgb[2];
- }
- }
- XStoreColors(dpy, cmap, Colors, numcolors);
-
- XSetWindowColormap(dpy, canvas, cmap);
-#endif
}
+
static void
-parseargs()
+parseargs(struct state *st)
{
- static int i;
+ int i;
int bindex=0, findex;
char *s, *ch;
- map = Maps[0];
- deriv = Derivs[0];
- maxexp=minlyap; minexp= -1.0 * minlyap;
+ st->map = Maps[0];
+ st->deriv = Derivs[0];
+ st->maxexp=st->minlyap; st->minexp= -1.0 * st->minlyap;
- mincolindex = get_integer_resource("minColor", "Integer");
- dwell = get_integer_resource("dwell", "Integer");
+ st->mincolindex = get_integer_resource(st->dpy, "minColor", "Integer");
+ st->dwell = get_integer_resource(st->dpy, "dwell", "Integer");
#ifdef MAPS
{
- char *optarg = get_string_resource("function", "String");
+ char *optarg = get_string_resource(st->dpy, "function", "String");
funcmaxindex = strlen(optarg);
if (funcmaxindex > FUNCMAXINDEX)
usage();
ch = optarg;
- Force++;
+ st->Force++;
for (findex=0;findex<funcmaxindex;findex++) {
- Forcing[findex] = (int)(*ch++ - '0');;
- if (Forcing[findex] >= NUMMAPS)
- usage();
+ st->Forcing[findex] = (int)(*ch++ - '0');;
+ if (st->Forcing[findex] >= NUMMAPS)
+ usage();
}
}
#endif
- if (get_boolean_resource("useLog", "Boolean"))
- useprod=0;
-
- minlyap=ABS(get_float_resource("colorExponent", "Float"));
- maxexp=minlyap;
- minexp= -1.0 * minlyap;
-
- color_offset = get_integer_resource("colorOffset", "Integer");
-
- maxcolor=ABS(get_integer_resource("maxColor", "Integer"));
- if ((maxcolor - startcolor) <= 0)
- startcolor = 0;
- if ((maxcolor - mincolindex) <= 0) {
- mincolindex = 1;
- color_offset = 0;
+ if (get_boolean_resource(st->dpy, "useLog", "Boolean"))
+ st->useprod=0;
+
+ st->minlyap=ABS(get_float_resource(st->dpy, "colorExponent", "Float"));
+ st->maxexp=st->minlyap;
+ st->minexp= -1.0 * st->minlyap;
+
+ st->color_offset = get_integer_resource(st->dpy, "colorOffset", "Integer");
+
+ st->maxcolor=ABS(get_integer_resource(st->dpy, "maxColor", "Integer"));
+ if ((st->maxcolor - st->startcolor) <= 0)
+ st->startcolor = get_pixel_resource(st->dpy, st->cmap,
+ "background", "Background");
+ if ((st->maxcolor - st->mincolindex) <= 0) {
+ st->mincolindex = 1;
+ st->color_offset = 0;
}
- s = get_string_resource("randomForce", "Float");
+ s = get_string_resource(st->dpy, "randomForce", "Float");
if (s && *s) {
- prob=atof(s); Rflag++; setforcing();
+ st->prob=atof(s); st->Rflag++; setforcing(st);
}
- settle = get_integer_resource("settle", "Integer");
+ st->settle = get_integer_resource(st->dpy, "settle", "Integer");
- s = get_string_resource("minA", "Float");
+#if 0
+ s = get_string_resource(st->dpy, "minA", "Float");
if (s && *s) {
- min_a = atof(s);
- aflag++;
+ st->min_a = atof(s);
+ st->aflag++;
}
- s = get_string_resource("minB", "Float");
+ s = get_string_resource(st->dpy, "minB", "Float");
if (s && *s) {
- min_b=atof(s); bflag++;
+ st->min_b=atof(s); st->bflag++;
}
+#else
+ st->min_a = get_float_resource (st->dpy, "minA", "Float");
+ st->aflag++;
+ st->min_b = get_float_resource (st->dpy, "minB", "Float");
+ st->bflag++;
+#endif
+
- numwheels = get_integer_resource("wheels", "Integer");
+ st->numwheels = get_integer_resource(st->dpy, "wheels", "Integer");
- s = get_string_resource("forcingFunction", "String");
+ s = get_string_resource(st->dpy, "forcingFunction", "String");
if (s && *s) {
- maxindex = strlen(s);
- if (maxindex > MAXINDEX)
- usage();
+ st->maxindex = strlen(s);
+ if (st->maxindex > MAXINDEX)
+ usage(st);
ch = s;
- force++;
- while (bindex < maxindex) {
+ st->force++;
+ while (bindex < st->maxindex) {
if (*ch == 'a')
- forcing[bindex++] = 0;
+ st->forcing[bindex++] = 0;
else if (*ch == 'b')
- forcing[bindex++] = 1;
+ st->forcing[bindex++] = 1;
else
- usage();
+ usage(st);
ch++;
}
}
- s = get_string_resource("bRange", "Float");
+ s = get_string_resource(st->dpy, "bRange", "Float");
if (s && *s) {
- b_range = atof(s);
- hflag++;
+ st->b_range = atof(s);
+ st->hflag++;
}
- start_x = get_float_resource("startX", "Float");
+ st->start_x = get_float_resource(st->dpy, "startX", "Float");
- s = get_string_resource("mapIndex", "Integer");
+ s = get_string_resource(st->dpy, "mapIndex", "Integer");
if (s && *s) {
- mapindex=atoi(s);
- if ((mapindex >= NUMMAPS) || (mapindex < 0))
- usage();
- map = Maps[mapindex];
- deriv = Derivs[mapindex];
- if (!aflag)
- min_a = amins[mapindex];
- if (!wflag)
- a_range = aranges[mapindex];
- if (!bflag)
- min_b = bmins[mapindex];
- if (!hflag)
- b_range = branges[mapindex];
- if (!Force)
+ st->mapindex=atoi(s);
+ if ((st->mapindex >= NUMMAPS) || (st->mapindex < 0))
+ usage(st);
+ st->map = Maps[st->mapindex];
+ st->deriv = Derivs[st->mapindex];
+ if (!st->aflag)
+ st->min_a = amins[st->mapindex];
+ if (!st->wflag)
+ st->a_range = aranges[st->mapindex];
+ if (!st->bflag)
+ st->min_b = bmins[st->mapindex];
+ if (!st->hflag)
+ st->b_range = branges[st->mapindex];
+ if (!st->Force)
for (i=0;i<FUNCMAXINDEX;i++)
- Forcing[i] = mapindex;
+ st->Forcing[i] = st->mapindex;
}
- outname = get_string_resource("outputFile", "Integer");
+ st->outname = get_string_resource(st->dpy, "outputFile", "Integer");
- if (get_boolean_resource("beNegative", "Boolean"))
- negative--;
+ if (get_boolean_resource(st->dpy, "beNegative", "Boolean"))
+ st->negative--;
- rgb_max = get_integer_resource("rgbMax", "Integer");
- spinlength = get_integer_resource("spinLength", "Integer");
- show = get_boolean_resource("show", "Boolean");
+ st->rgb_max = get_integer_resource(st->dpy, "rgbMax", "Integer");
+ st->spinlength = get_integer_resource(st->dpy, "spinLength", "Integer");
+ st->show = get_boolean_resource(st->dpy, "show", "Boolean");
- s = get_string_resource("aRange", "Float");
+ s = get_string_resource(st->dpy, "aRange", "Float");
if (s && *s) {
- a_range = atof(s); wflag++;
+ st->a_range = atof(s); st->wflag++;
}
- max_a = min_a + a_range;
- max_b = min_b + b_range;
+ st->max_a = st->min_a + st->a_range;
+ st->max_b = st->min_b + st->b_range;
- a_minimums[0] = min_a; b_minimums[0] = min_b;
- a_maximums[0] = max_a; b_maximums[0] = max_b;
+ st->a_minimums[0] = st->min_a; st->b_minimums[0] = st->min_b;
+ st->a_maximums[0] = st->max_a; st->b_maximums[0] = st->max_b;
- if (Force)
- if (maxindex == funcmaxindex)
- for (findex=0;findex<funcmaxindex;findex++)
- check_params(Forcing[findex],forcing[findex]);
+ if (st->Force)
+ if (st->maxindex == st->funcmaxindex)
+ for (findex=0;findex<st->funcmaxindex;findex++)
+ check_params(st, st->Forcing[findex],st->forcing[findex]);
else
fprintf(stderr, "Warning! Unable to check parameters\n");
else
- check_params(mapindex,2);
+ check_params(st, st->mapindex,2);
}
static void
-check_params(int mapnum, int parnum)
+check_params(struct state *st, int mapnum, int parnum)
{
if (parnum != 1) {
- if ((max_a > pmaxs[mapnum]) || (min_a < pmins[mapnum])) {
- fprintf(stderr, "Warning! Parameter 'a' out of range.\n");
- fprintf(stderr, "You have requested a range of (%f,%f).\n",
- min_a,max_a);
- fprintf(stderr, "Valid range is (%f,%f).\n",
- pmins[mapnum],pmaxs[mapnum]);
- }
+ if ((st->max_a > pmaxs[mapnum]) || (st->min_a < pmins[mapnum])) {
+ fprintf(stderr, "Warning! Parameter 'a' out of range.\n");
+ fprintf(stderr, "You have requested a range of (%f,%f).\n",
+ st->min_a,st->max_a);
+ fprintf(stderr, "Valid range is (%f,%f).\n",
+ pmins[mapnum],pmaxs[mapnum]);
+ }
}
if (parnum != 0) {
- if ((max_b > pmaxs[mapnum]) || (min_b < pmins[mapnum])) {
- fprintf(stderr, "Warning! Parameter 'b' out of range.\n");
- fprintf(stderr, "You have requested a range of (%f,%f).\n",
- min_b,max_b);
- fprintf(stderr, "Valid range is (%f,%f).\n",
- pmins[mapnum],pmaxs[mapnum]);
- }
+ if ((st->max_b > pmaxs[mapnum]) || (st->min_b < pmins[mapnum])) {
+ fprintf(stderr, "Warning! Parameter 'b' out of range.\n");
+ fprintf(stderr, "You have requested a range of (%f,%f).\n",
+ st->min_b,st->max_b);
+ fprintf(stderr, "Valid range is (%f,%f).\n",
+ pmins[mapnum],pmaxs[mapnum]);
+ }
}
}
static void
-usage(void)
+usage(struct state *st)
{
- fprintf(stderr,"lyap [-BLs][-W#][-H#][-a#][-b#][-w#][-h#][-x xstart]\n");
- fprintf(stderr,"\t[-M#][-S#][-D#][-f string][-r#][-O#][-C#][-c#][-m#]\n");
+ fprintf(stderr,"lyap [-BLs][-W#][-H#][-a#][-b#][-w#][-h#][-x xstart]\n");
+ fprintf(stderr,"\t[-M#][-S#][-D#][-f string][-r#][-O#][-C#][-c#][-m#]\n");
#ifdef MAPS
- fprintf(stderr,"\t[-F string]\n");
+ fprintf(stderr,"\t[-F string]\n");
#endif
- fprintf(stderr,"\tWhere: -C# specifies the minimum color index\n");
- fprintf(stderr,"\t -r# specifies the maxzimum rgb value\n");
- fprintf(stderr,"\t -u displays this message\n");
- fprintf(stderr,"\t -a# specifies the minimum horizontal parameter\n");
- fprintf(stderr,"\t -b# specifies the minimum vertical parameter\n");
- fprintf(stderr,"\t -w# specifies the horizontal parameter range\n");
- fprintf(stderr,"\t -h# specifies the vertical parameter range\n");
- fprintf(stderr,"\t -D# specifies the dwell\n");
- fprintf(stderr,"\t -S# specifies the settle\n");
- fprintf(stderr,"\t -H# specifies the initial window height\n");
- fprintf(stderr,"\t -W# specifies the initial window width\n");
- fprintf(stderr,"\t -O# specifies the color offset\n");
- fprintf(stderr,"\t -c# specifies the desired color wheel\n");
- fprintf(stderr,"\t -m# specifies the desired map (0-4)\n");
- fprintf(stderr,"\t -f aabbb specifies a forcing function of 00111\n");
+ fprintf(stderr,"\tWhere: -C# specifies the minimum color index\n");
+ fprintf(stderr,"\t -r# specifies the maxzimum rgb value\n");
+ fprintf(stderr,"\t -u displays this message\n");
+ fprintf(stderr,"\t -a# specifies the minimum horizontal parameter\n");
+ fprintf(stderr,"\t -b# specifies the minimum vertical parameter\n");
+ fprintf(stderr,"\t -w# specifies the horizontal parameter range\n");
+ fprintf(stderr,"\t -h# specifies the vertical parameter range\n");
+ fprintf(stderr,"\t -D# specifies the dwell\n");
+ fprintf(stderr,"\t -S# specifies the settle\n");
+ fprintf(stderr,"\t -H# specifies the initial window height\n");
+ fprintf(stderr,"\t -W# specifies the initial window width\n");
+ fprintf(stderr,"\t -O# specifies the color offset\n");
+ fprintf(stderr,"\t -c# specifies the desired color wheel\n");
+ fprintf(stderr,"\t -m# specifies the desired map (0-4)\n");
+ fprintf(stderr,"\t -f aabbb specifies a forcing function of 00111\n");
#ifdef MAPS
- fprintf(stderr,"\t -F 00111 specifies the function forcing function\n");
+ fprintf(stderr,"\t -F 00111 specifies the function forcing function\n");
#endif
- fprintf(stderr,"\t -L indicates use log(x)+log(y) rather than log(xy)\n");
- fprintf(stderr,"\tDuring display :\n");
- fprintf(stderr,"\t Use the mouse to zoom in on an area\n");
- fprintf(stderr,"\t e or E recalculates color indices\n");
- fprintf(stderr,"\t f or F saves exponents to a file\n");
- fprintf(stderr,"\t KJmn increase/decrease minimum negative exponent\n");
- fprintf(stderr,"\t r or R redraws\n");
- fprintf(stderr,"\t s or S spins the colorwheel\n");
- fprintf(stderr,"\t w or W changes the color wheel\n");
- fprintf(stderr,"\t x or X clears the window\n");
- fprintf(stderr,"\t q or Q exits\n");
- exit(1);
+ fprintf(stderr,"\t -L indicates use log(x)+log(y) rather than log(xy)\n");
+ fprintf(stderr,"\tDuring display :\n");
+ fprintf(stderr,"\t Use the mouse to zoom in on an area\n");
+ fprintf(stderr,"\t e or E recalculates color indices\n");
+ fprintf(stderr,"\t f or F saves exponents to a file\n");
+ fprintf(stderr,"\t KJmn increase/decrease minimum negative exponent\n");
+ fprintf(stderr,"\t r or R redraws\n");
+ fprintf(stderr,"\t s or S spins the colorwheel\n");
+ fprintf(stderr,"\t w or W changes the color wheel\n");
+ fprintf(stderr,"\t x or X clears the window\n");
+ fprintf(stderr,"\t q or Q exits\n");
+ exit(1);
}
static void
-Cycle_frames(void)
+Cycle_frames(struct state *st)
{
- static int i;
- for (i=0;i<=maxframe;i++)
- redraw(exponents[i], expind[i], 1);
+ int i;
+ for (i=0;i<=st->maxframe;i++)
+ redraw(st, st->exponents[i], st->expind[i], 1);
}
+#if 0
static void
-Spin(Window w)
+Spin(struct state *st)
{
- static int i, j;
+ int i, j;
long tmpxcolor;
- if (displayplanes > 1) {
- for (j=0;j<spinlength;j++) {
- tmpxcolor = Colors[mincolindex].pixel;
- for (i=mincolindex;i<numcolors-1;i++)
- Colors[i].pixel = Colors[i+1].pixel;
- Colors[numcolors-1].pixel = tmpxcolor;
- XStoreColors(dpy, cmap, Colors, numcolors);
+ if (!mono_p) {
+ for (j=0;j<st->spinlength;j++) {
+ tmpxcolor = st->Colors[st->mincolindex].pixel;
+ for (i=st->mincolindex;i<st->numcolors-1;i++)
+ st->Colors[i].pixel = st->Colors[i+1].pixel;
+ st->Colors[st->numcolors-1].pixel = tmpxcolor;
+ XStoreColors(st->dpy, st->cmap, st->Colors, st->numcolors);
}
- for (j=0;j<spinlength;j++) {
- tmpxcolor = Colors[numcolors-1].pixel;
- for (i=numcolors-1;i>mincolindex;i--)
- Colors[i].pixel = Colors[i-1].pixel;
- Colors[mincolindex].pixel = tmpxcolor;
- XStoreColors(dpy, cmap, Colors, numcolors);
+ for (j=0;j<st->spinlength;j++) {
+ tmpxcolor = st->Colors[st->numcolors-1].pixel;
+ for (i=st->numcolors-1;i>st->mincolindex;i--)
+ st->Colors[i].pixel = st->Colors[i-1].pixel;
+ st->Colors[st->mincolindex].pixel = tmpxcolor;
+ XStoreColors(st->dpy, st->cmap, st->Colors, st->numcolors);
}
}
}
+#endif
-static void
-Getkey(XKeyEvent *event)
+static Bool
+Getkey(struct state *st, XKeyEvent *event)
{
unsigned char key;
- static int i;
+ int i;
if (XLookupString(event, (char *)&key, sizeof(key), (KeySym *)0,
- (XComposeStatus *) 0) > 0)
+ (XComposeStatus *) 0) > 0)
+
+ if (st->reset_countdown)
+ st->reset_countdown = st->linger;
+
switch (key) {
- case '<': dwell /= 2; if (dwell < 1) dwell = 1; break;
- case '>': dwell *= 2; break;
- case '[': settle /= 2; if (settle < 1) settle = 1; break;
- case ']': settle *= 2; break;
- case 'd': go_down(); break;
- case 'D': FlushBuffer(); break;
- case 'e':
- case 'E': FlushBuffer();
- dorecalc = (!dorecalc);
- if (dorecalc)
- recalc();
+ case '<': st->dwell /= 2; if (st->dwell < 1) st->dwell = 1; return True;
+ case '>': st->dwell *= 2; return True;
+ case '[': st->settle /= 2; if (st->settle < 1) st->settle = 1; return True;
+ case ']': st->settle *= 2; return True;
+ case 'd': go_down(st); return True;
+ case 'D': FlushBuffer(st); return True;
+ case 'e':
+ case 'E': FlushBuffer(st);
+ st->dorecalc = (!st->dorecalc);
+ if (st->dorecalc)
+ recalc(st);
else {
- maxexp = minlyap; minexp = -1.0 * minlyap;
+ st->maxexp = st->minlyap; st->minexp = -1.0 * st->minlyap;
}
- redraw(exponents[frame], expind[frame], 1);
- break;
- case 'f':
- case 'F': save_to_file(); break;
- case 'i': if (stripe_interval > 0) {
- stripe_interval--;
- if (displayplanes > 1) {
- init_color();
- }
+ redraw(st, st->exponents[st->frame], st->expind[st->frame], 1);
+ return True;
+ case 'f':
+ /* case 'F': save_to_file(); return True;*/
+ case 'i': if (st->stripe_interval > 0) {
+ st->stripe_interval--;
+ if (!mono_p) {
+ init_color(st);
+ }
}
- break;
- case 'I': stripe_interval++;
- if (displayplanes > 1) {
- init_color();
+ return True;
+ case 'I': st->stripe_interval++;
+ if (!mono_p) {
+ init_color(st);
}
- break;
- case 'K': if (minlyap > 0.05)
- minlyap -= 0.05;
- break;
- case 'J': minlyap += 0.05;
- break;
- case 'm': mapindex++;
- if (mapindex >= NUMMAPS)
- mapindex=0;
- map = Maps[mapindex];
- deriv = Derivs[mapindex];
- if (!aflag)
- min_a = amins[mapindex];
- if (!wflag)
- a_range = aranges[mapindex];
- if (!bflag)
- min_b = bmins[mapindex];
- if (!hflag)
- b_range = branges[mapindex];
- if (!Force)
- for (i=0;i<FUNCMAXINDEX;i++)
- Forcing[i] = mapindex;
- max_a = min_a + a_range;
- max_b = min_b + b_range;
- a_minimums[0] = min_a; b_minimums[0] = min_b;
- a_maximums[0] = max_a; b_maximums[0] = max_b;
- a_inc = a_range / (double)width;
- b_inc = b_range / (double)height;
- point.x = -1;
- point.y = 0;
- a = rubber_data.p_min = min_a;
- b = rubber_data.q_min = min_b;
- rubber_data.p_max = max_a;
- rubber_data.q_max = max_b;
- Clear();
- break;
- case 'M': if (minlyap > 0.005)
- minlyap -= 0.005;
- break;
- case 'N': minlyap += 0.005;
- break;
- case 'p':
- case 'P': negative = (!negative);
- FlushBuffer(); redraw(exponents[frame], expind[frame], 1);
- break;
- case 'r': FlushBuffer(); redraw(exponents[frame], expind[frame], 1);
- break;
- case 'R': FlushBuffer(); Redraw(); break;
- case 's':
- spinlength=spinlength/2;
- case 'S': if (displayplanes > 1)
- Spin(canvas);
- spinlength=spinlength*2; break;
- case 'u': go_back(); break;
- case 'U': go_init(); break;
- case 'v':
- case 'V': print_values(); break;
- case 'W': if (numwheels < MAXWHEELS)
- numwheels++;
- else
- numwheels = 0;
- if (displayplanes > 1) {
- init_color();
- }
- break;
- case 'w': if (numwheels > 0)
- numwheels--;
- else
- numwheels = MAXWHEELS;
- if (displayplanes > 1) {
- init_color();
- }
- break;
- case 'x': Clear(); break;
- case 'X': Destroy_frame(); break;
- case 'z': Cycle_frames(); redraw(exponents[frame], expind[frame], 1);
- break;
- case 'Z': while (!XPending(dpy)) Cycle_frames();
- redraw(exponents[frame], expind[frame], 1); break;
- case 'q':
- case 'Q': exit(0); break;
- case '?':
- case 'h':
- case 'H': print_help(); break;
- default: break;
- }
+ return True;
+ case 'K': if (st->minlyap > 0.05)
+ st->minlyap -= 0.05;
+ return True;
+ case 'J': st->minlyap += 0.05;
+ return True;
+ case 'm': st->mapindex++;
+ if (st->mapindex >= NUMMAPS)
+ st->mapindex=0;
+ st->map = Maps[st->mapindex];
+ st->deriv = Derivs[st->mapindex];
+ if (!st->aflag)
+ st->min_a = amins[st->mapindex];
+ if (!st->wflag)
+ st->a_range = aranges[st->mapindex];
+ if (!st->bflag)
+ st->min_b = bmins[st->mapindex];
+ if (!st->hflag)
+ st->b_range = branges[st->mapindex];
+ if (!st->Force)
+ for (i=0;i<FUNCMAXINDEX;i++)
+ st->Forcing[i] = st->mapindex;
+ st->max_a = st->min_a + st->a_range;
+ st->max_b = st->min_b + st->b_range;
+ st->a_minimums[0] = st->min_a; st->b_minimums[0] = st->min_b;
+ st->a_maximums[0] = st->max_a; st->b_maximums[0] = st->max_b;
+ st->a_inc = st->a_range / (double)st->width;
+ st->b_inc = st->b_range / (double)st->height;
+ st->point.x = -1;
+ st->point.y = 0;
+ st->a = /*st->rubber_data.p_min = */st->min_a;
+ st->b = /*st->rubber_data.q_min = */st->min_b;
+/* st->rubber_data.p_max = st->max_a;
+ st->rubber_data.q_max = st->max_b;*/
+ Clear(st);
+ return True;
+ case 'M': if (st->minlyap > 0.005)
+ st->minlyap -= 0.005;
+ return True;
+ case 'N': st->minlyap += 0.005;
+ return True;
+ case 'p':
+ case 'P': st->negative = (!st->negative);
+ FlushBuffer(st); redraw(st, st->exponents[st->frame],
+ st->expind[st->frame], 1);
+ return True;
+ case 'r': FlushBuffer(st); redraw(st, st->exponents[st->frame],
+ st->expind[st->frame], 1);
+ return True;
+ case 'R': FlushBuffer(st); Redraw(st); return True;
+ case 's':
+ st->spinlength=st->spinlength/2;
+#if 0
+ case 'S': if (!mono_p)
+ Spin(st);
+ st->spinlength=st->spinlength*2; return True;
+#endif
+ case 'u': go_back(st); return True;
+ case 'U': go_init(st); return True;
+ case 'v':
+ case 'V': print_values(st); return True;
+ case 'W': if (st->numwheels < MAXWHEELS)
+ st->numwheels++;
+ else
+ st->numwheels = 0;
+ if (!mono_p) {
+ init_color(st);
+ }
+ return True;
+ case 'w': if (st->numwheels > 0)
+ st->numwheels--;
+ else
+ st->numwheels = MAXWHEELS;
+ if (!mono_p) {
+ init_color(st);
+ }
+ return True;
+ case 'x': Clear(st); return True;
+ case 'X': Destroy_frame(st); return True;
+ case 'z': Cycle_frames(st); redraw(st, st->exponents[st->frame],
+ st->expind[st->frame], 1);
+ return True;
+#if 0
+ case 'Z': while (!XPending(st->dpy)) Cycle_frames(st);
+ redraw(st, st->exponents[st->frame], st->expind[st->frame], 1);
+ return True;
+#endif
+ case 'q':
+ case 'Q': exit(0); return True;
+ case '?':
+ case 'h':
+ case 'H': print_help(st); return True;
+ default: return False;
+ }
+
+ return False;
}
/* Here's where we index into a color map. After the Lyapunov exponent is
- * calculated, it is used to determine what color to use for that point.
- * I suppose there are a lot of ways to do this. I used the following :
- * if it's non-negative then there's a reserved area at the lower range
- * of the color map that i index into. The ratio of some "minimum exponent
- * value" and the calculated value is used as a ratio of how high to index
- * into this reserved range. Usually these colors are dark red (see init_color).
- * If the exponent is negative, the same ratio (expo/minlyap) is used to index
- * into the remaining portion of the colormap (which is usually some light
- * shades of color or a rainbow wheel). The coloring scheme can actually make
- * a great deal of difference in the quality of the picture. Different colormaps
- * bring out different details of the dynamics while different indexing
- * algorithms also greatly effect what details are seen. Play around with this.
+ * calculated, it is used to determine what color to use for that point. I
+ * suppose there are a lot of ways to do this. I used the following : if it's
+ * non-negative then there's a reserved area at the lower range of the color
+ * map that i index into. The ratio of some "minimum exponent value" and the
+ * calculated value is used as a ratio of how high to index into this reserved
+ * range. Usually these colors are dark red (see init_color). If the exponent
+ * is negative, the same ratio (expo/minlyap) is used to index into the
+ * remaining portion of the colormap (which is usually some light shades of
+ * color or a rainbow wheel). The coloring scheme can actually make a great
+ * deal of difference in the quality of the picture. Different colormaps bring
+ * out different details of the dynamics while different indexing algorithms
+ * also greatly effect what details are seen. Play around with this.
*/
static int
-sendpoint(double expo)
+sendpoint(struct state *st, double expo)
{
- static int index;
- static double tmpexpo;
+ double tmpexpo;
+
+ if (st->maxcolor > MAXCOLOR)
+ abort();
#if 0
-/* The relationship minexp <= expo <= maxexp should always be true. This test
- enforces that. But maybe not enforcing it makes better pictures. */
- if (expo < minexp)
- expo = minexp;
+ /* The relationship st->minexp <= expo <= maxexp should always be true. This
+ test enforces that. But maybe not enforcing it makes better pictures. */
+ if (expo < st->minexp)
+ expo = st->minexp;
else if (expo > maxexp)
expo = maxexp;
#endif
- point.x++;
- tmpexpo = (negative) ? expo : -1.0 * expo;
+ st->point.x++;
+ tmpexpo = (st->negative) ? expo : -1.0 * expo;
if (tmpexpo > 0) {
- if (displayplanes >1) {
- index = (int)(tmpexpo*lowrange/maxexp);
- index = (index % lowrange) + startcolor;
+ if (!mono_p) {
+ st->sendpoint_index = (int)(tmpexpo*st->lowrange/st->maxexp);
+ st->sendpoint_index = ((st->sendpoint_index % st->lowrange) +
+ st->startcolor);
}
else
- index = 0;
+ st->sendpoint_index = 0;
}
else {
- if (displayplanes >1) {
- index = (int)(tmpexpo*numfreecols/minexp);
- index = (index % numfreecols) + mincolindex;
+ if (!mono_p) {
+ st->sendpoint_index = (int)(tmpexpo*st->numfreecols/st->minexp);
+ st->sendpoint_index = ((st->sendpoint_index % st->numfreecols)
+ + st->mincolindex);
}
else
- index = 1;
+ st->sendpoint_index = 1;
}
- BufferPoint(dpy, canvas, index, point.x, point.y);
- if (save)
- exponents[frame][expind[frame]++] = expo;
- if (point.x >= width) {
- point.y++;
- point.x = 0;
- if (save) {
- b += b_inc;
- a = min_a;
+ BufferPoint(st, st->sendpoint_index, st->point.x, st->point.y);
+ if (st->save) {
+ if (st->frame > MAXFRAMES)
+ abort();
+ st->exponents[st->frame][st->expind[st->frame]++] = expo;
+ }
+ if (st->point.x >= st->width) {
+ st->point.y++;
+ st->point.x = 0;
+ if (st->save) {
+ st->b += st->b_inc;
+ st->a = st->min_a;
}
- if (point.y >= height)
+ if (st->point.y >= st->height)
return FALSE;
else
return TRUE;
return TRUE;
}
-static void
-redisplay (Window w, XExposeEvent *event)
-{
- /*
- * Extract the exposed area from the event and copy
- * from the saved pixmap to the window.
- */
- XCopyArea(dpy, pixmap, canvas, Data_GC[0],
- event->x, event->y, event->width, event->height,
- event->x, event->y);
-}
static void
-resize(void)
+resize(struct state *st)
{
Window r;
int n, x, y;
unsigned int bw, d, new_w, new_h;
- XGetGeometry(dpy,canvas,&r,&x,&y,&new_w,&new_h,&bw,&d);
- if ((new_w == width) && (new_h == height))
+ XGetGeometry(st->dpy,st->canvas,&r,&x,&y,&new_w,&new_h,&bw,&d);
+ if ((new_w == st->width) && (new_h == st->height))
return;
- width = new_w; height = new_h;
- XClearWindow(dpy, canvas);
- if (pixmap)
- XFreePixmap(dpy, pixmap);
- pixmap = XCreatePixmap(dpy, canvas, width, height, d);
- a_inc = a_range / (double)width;
- b_inc = b_range / (double)height;
- point.x = -1;
- point.y = 0;
- run = 1;
- a = rubber_data.p_min = min_a;
- b = rubber_data.q_min = min_b;
- rubber_data.p_max = max_a;
- rubber_data.q_max = max_b;
- freemem();
- setupmem();
- for (n=0;n<MAXFRAMES;n++)
- if ((n <= maxframe) && (n != frame))
- resized[n] = 1;
- InitBuffer();
- Clear();
- Redraw();
+ st->width = new_w; st->height = new_h;
+ XClearWindow(st->dpy, st->canvas);
+#ifdef BACKING_PIXMAP
+ if (st->pixmap)
+ XFreePixmap(st->dpy, st->pixmap);
+ st->pixmap = XCreatePixmap(st->dpy, st->canvas, st->width, st->height, d);
+#endif
+ st->a_inc = st->a_range / (double)st->width;
+ st->b_inc = st->b_range / (double)st->height;
+ st->point.x = -1;
+ st->point.y = 0;
+ st->run = 1;
+ st->a = /*st->rubber_data.p_min = */st->min_a;
+ st->b = /*st->rubber_data.q_min = */st->min_b;
+/* st->rubber_data.p_max = st->max_a;
+ st->rubber_data.q_max = st->max_b;*/
+ freemem(st);
+ setupmem(st);
+ for (n=0;n<MAXFRAMES;n++)
+ if ((n <= st->maxframe) && (n != st->frame))
+ st->resized[n] = 1;
+ InitBuffer(st);
+ Clear(st);
+ Redraw(st);
}
static void
-redraw(double *exparray, int index, int cont)
+redraw(struct state *st, double *exparray, int index, int cont)
{
- static int i;
- static int x_sav, y_sav;
+ int i, x_sav, y_sav;
- x_sav = point.x;
- y_sav = point.y;
+ x_sav = st->point.x;
+ y_sav = st->point.y;
- point.x = -1;
- point.y = 0;
+ st->point.x = -1;
+ st->point.y = 0;
- save=0;
+ st->save=0;
for (i=0;i<index;i++)
- sendpoint(exparray[i]);
- save=1;
+ sendpoint(st, exparray[i]);
+ st->save=1;
if (cont) {
- point.x = x_sav;
- point.y = y_sav;
+ st->point.x = x_sav;
+ st->point.y = y_sav;
}
else {
- a = point.x * a_inc + min_a;
- b = point.y * b_inc + min_b;
+ st->a = st->point.x * st->a_inc + st->min_a;
+ st->b = st->point.y * st->b_inc + st->min_b;
}
- FlushBuffer();
+ FlushBuffer(st);
}
static void
-Redraw(void)
+Redraw(struct state *st)
{
- FlushBuffer();
- point.x = -1;
- point.y = 0;
- run = 1;
- a = min_a;
- b = min_b;
- expind[frame] = 0;
- resized[frame] = 0;
+ FlushBuffer(st);
+ st->point.x = -1;
+ st->point.y = 0;
+ st->run = 1;
+ st->a = st->min_a;
+ st->b = st->min_b;
+ st->expind[st->frame] = 0;
+ st->resized[st->frame] = 0;
}
-/* Store color pics in PPM format and monochrome in PGM */
static void
-save_to_file(void)
+recalc(struct state *st)
{
- FILE *outfile;
- unsigned char c;
- XImage *ximage;
- static int i,j;
- struct Colormap {
- unsigned char red;
- unsigned char green;
- unsigned char blue;
- };
- struct Colormap *colormap=NULL;
-
- if (colormap)
- free(colormap);
- if ((colormap=
- (struct Colormap *)malloc(sizeof(struct Colormap)*maxcolor))
- == NULL) {
- fprintf(stderr,"Error malloc'ing colormap array\n");
- exit(-1);
- }
- outfile = fopen(outname,"w");
- if(!outfile) {
- perror(outname);
- exit(-1);
- }
-
- ximage=XGetImage(dpy, pixmap, 0, 0, width, height, AllPlanes, XYPixmap);
-
- if (displayplanes > 1) {
- for (i=0;i<maxcolor;i++) {
- colormap[i].red=(unsigned char)(Colors[i].red >> 8);
- colormap[i].green=(unsigned char)(Colors[i].green >> 8);
- colormap[i].blue =(unsigned char)(Colors[i].blue >> 8);
- }
- fprintf(outfile,"P%d %d %d\n",6,width,height);
- }
- else
- fprintf(outfile,"P%d %d %d\n",5,width,height);
- fprintf(outfile,"# settle=%d dwell=%d start_x=%f\n",settle,dwell,
- start_x);
- fprintf(outfile,"# min_a=%f a_rng=%f max_a=%f\n",min_a,a_range,max_a);
- fprintf(outfile,"# min_b=%f b_rng=%f max_b=%f\n",min_b,b_range,max_b);
- if (Rflag)
- fprintf(outfile,"# pseudo-random forcing\n");
- else if (force) {
- fprintf(outfile,"# periodic forcing=");
- for (i=0;i<maxindex;i++) {
- fprintf(outfile,"%d",forcing[i]);
- }
- fprintf(outfile,"\n");
- }
- else
- fprintf(outfile,"# periodic forcing=01\n");
- if (Force) {
- fprintf(outfile,"# function forcing=");
- for (i=0;i<funcmaxindex;i++) {
- fprintf(outfile,"%d",Forcing[i]);
- }
- fprintf(outfile,"\n");
- }
- fprintf(outfile,"%d\n",numcolors-1);
-
- for (j=0;j<height;j++)
- for (i=0;i<width;i++) {
- c = (unsigned char)XGetPixel(ximage,i,j);
- if (displayplanes > 1)
- fwrite((char *)&colormap[c],sizeof colormap[0],1,outfile);
- else
- fwrite((char *)&c,sizeof c,1,outfile);
- }
- fclose(outfile);
-}
+ int i;
-static void
-recalc(void)
-{
- static int i, x, y;
-
- minexp = maxexp = 0.0;
- x = y = 0;
- for (i=0;i<expind[frame];i++) {
- if (exponents[frame][i] < minexp)
- minexp = exponents[frame][i];
- if (exponents[frame][i] > maxexp)
- maxexp = exponents[frame][i];
+ st->minexp = st->maxexp = 0.0;
+ for (i=0;i<st->expind[st->frame];i++) {
+ if (st->exponents[st->frame][i] < st->minexp)
+ st->minexp = st->exponents[st->frame][i];
+ if (st->exponents[st->frame][i] > st->maxexp)
+ st->maxexp = st->exponents[st->frame][i];
}
}
static void
-Clear(void)
+Clear(struct state *st)
{
- XClearWindow(dpy, canvas);
- XCopyArea(dpy, canvas, pixmap, Data_GC[0],
- 0, 0, width, height, 0, 0);
- InitBuffer();
+ XClearWindow(st->dpy, st->canvas);
+#ifdef BACKING_PIXMAP
+ XCopyArea(st->dpy, st->canvas, st->pixmap, st->Data_GC[0],
+ 0, 0, st->width, st->height, 0, 0);
+#endif
+ InitBuffer(st);
}
static void
-show_defaults(void)
+show_defaults(struct state *st)
{
- printf("Width=%d Height=%d numcolors=%d settle=%d dwell=%d\n",
- width,height,numcolors,settle,dwell);
- printf("min_a=%f a_range=%f max_a=%f\n", min_a,a_range,max_a);
- printf("min_b=%f b_range=%f max_b=%f\n", min_b,b_range,max_b);
- printf("minlyap=%f minexp=%f maxexp=%f\n", minlyap,minexp,maxexp);
+ printf("Width=%d Height=%d numcolors=%d settle=%d dwell=%d\n",
+ st->width,st->height,st->numcolors,st->settle,st->dwell);
+ printf("min_a=%f a_range=%f max_a=%f\n", st->min_a,st->a_range,st->max_a);
+ printf("min_b=%f b_range=%f max_b=%f\n", st->min_b,st->b_range,st->max_b);
+ printf("minlyap=%f minexp=%f maxexp=%f\n", st->minlyap,st->minexp,
+ st->maxexp);
exit(0);
}
+#if 0
static void
-CreateXorGC(void)
+CreateXorGC(struct state *st)
{
XGCValues values;
- values.foreground = foreground;
- values.line_style = LineSolid;
+ values.foreground = st->foreground;
values.function = GXxor;
- RubberGC = XCreateGC(dpy, canvas,
- GCForeground | GCBackground | GCFunction | GCLineStyle, &values);
+ st->RubberGC = XCreateGC(st->dpy, st->canvas,
+ GCForeground | GCFunction, &values);
}
static void
-StartRubberBand(Window w, image_data_t *data, XEvent *event)
+StartRubberBand(struct state *st, image_data_t *data, XEvent *event)
{
XPoint corners[5];
- nostart = 0;
+ st->nostart = 0;
data->rubber_band.last_x = data->rubber_band.start_x = event->xbutton.x;
data->rubber_band.last_y = data->rubber_band.start_y = event->xbutton.y;
SetupCorners(corners, data);
- XDrawLines(dpy, canvas, RubberGC,
- corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
+ XDrawLines(st->dpy, st->canvas, st->RubberGC,
+ corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
}
static void
}
static void
-TrackRubberBand(Window w, image_data_t *data, XEvent *event)
+TrackRubberBand(struct state *st, image_data_t *data, XEvent *event)
{
XPoint corners[5];
int xdiff, ydiff;
- if (nostart)
+ if (st->nostart)
return;
SetupCorners(corners, data);
- XDrawLines(dpy, canvas, RubberGC,
- corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
+ XDrawLines(st->dpy, st->canvas, st->RubberGC,
+ corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
ydiff = event->xbutton.y - data->rubber_band.start_y;
xdiff = event->xbutton.x - data->rubber_band.start_x;
data->rubber_band.last_x = data->rubber_band.start_x + xdiff;
data->rubber_band.last_y = data->rubber_band.start_y + ydiff;
if (data->rubber_band.last_y < data->rubber_band.start_y ||
data->rubber_band.last_x < data->rubber_band.start_x)
- {
- data->rubber_band.last_y = data->rubber_band.start_y;
- data->rubber_band.last_x = data->rubber_band.start_x;
- }
+ {
+ data->rubber_band.last_y = data->rubber_band.start_y;
+ data->rubber_band.last_x = data->rubber_band.start_x;
+ }
SetupCorners(corners, data);
- XDrawLines(dpy, canvas, RubberGC,
- corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
+ XDrawLines(st->dpy, st->canvas, st->RubberGC,
+ corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
}
static void
-EndRubberBand(Window w, image_data_t *data, XEvent *event)
+EndRubberBand(struct state *st, image_data_t *data, XEvent *event)
{
XPoint corners[5];
XPoint top, bot;
double delta, diff;
- nostart = 1;
+ st->nostart = 1;
SetupCorners(corners, data);
- XDrawLines(dpy, canvas, RubberGC,
- corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
+ XDrawLines(st->dpy, st->canvas, st->RubberGC,
+ corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
if (data->rubber_band.start_x >= data->rubber_band.last_x ||
data->rubber_band.start_y >= data->rubber_band.last_y)
return;
top.y = data->rubber_band.start_y;
bot.y = data->rubber_band.last_y;
diff = data->q_max - data->q_min;
- delta = (double)top.y / (double)height;
+ delta = (double)top.y / (double)st->height;
data->q_min += diff * delta;
- delta = (double)(height - bot.y) / (double)height;
+ delta = (double)(st->height - bot.y) / (double)st->height;
data->q_max -= diff * delta;
diff = data->p_max - data->p_min;
- delta = (double)top.x / (double)width;
+ delta = (double)top.x / (double)st->width;
data->p_min += diff * delta;
- delta = (double)(width - bot.x) / (double)width;
+ delta = (double)(st->width - bot.x) / (double)st->width;
data->p_max -= diff * delta;
fflush(stdout);
- set_new_params(w, data);
+ set_new_params(st, data);
}
static void
-set_new_params(Window w, image_data_t *data)
+set_new_params(struct state *st, image_data_t *data)
{
- frame = (maxframe + 1) % MAXFRAMES;
- if (frame > maxframe)
- maxframe = frame;
- a_range = data->p_max - data->p_min;
- b_range = data->q_max - data->q_min;
- a_minimums[frame] = min_a = data->p_min;
- b_minimums[frame] = min_b = data->q_min;
- a_inc = a_range / (double)width;
- b_inc = b_range / (double)height;
- point.x = -1;
- point.y = 0;
- run = 1;
- a = min_a;
- b = min_b;
- a_maximums[frame] = max_a = data->p_max;
- b_maximums[frame] = max_b = data->q_max;
- expind[frame] = 0;;
- Clear();
+ st->frame = (st->maxframe + 1) % MAXFRAMES;
+ if (st->frame > st->maxframe)
+ st->maxframe = st->frame;
+ st->a_range = data->p_max - data->p_min;
+ st->b_range = data->q_max - data->q_min;
+ st->a_minimums[st->frame] = st->min_a = data->p_min;
+ st->b_minimums[st->frame] = st->min_b = data->q_min;
+ st->a_inc = st->a_range / (double)st->width;
+ st->b_inc = st->b_range / (double)st->height;
+ st->point.x = -1;
+ st->point.y = 0;
+ st->run = 1;
+ st->a = st->min_a;
+ st->b = st->min_b;
+ st->a_maximums[st->frame] = st->max_a = data->p_max;
+ st->b_maximums[st->frame] = st->max_b = data->q_max;
+ st->expind[st->frame] = 0;
+ Clear(st);
}
+#endif
static void
-go_down(void)
+go_down(struct state *st)
{
- frame++;
- if (frame > maxframe)
- frame = 0;
- jumpwin();
+ st->frame++;
+ if (st->frame > st->maxframe)
+ st->frame = 0;
+ jumpwin(st);
}
static void
-go_back(void)
+go_back(struct state *st)
{
- frame--;
- if (frame < 0)
- frame = maxframe;
- jumpwin();
+ st->frame--;
+ if (st->frame < 0)
+ st->frame = st->maxframe;
+ jumpwin(st);
}
static void
-jumpwin(void)
+jumpwin(struct state *st)
{
- rubber_data.p_min = min_a = a_minimums[frame];
- rubber_data.q_min = min_b = b_minimums[frame];
- rubber_data.p_max = max_a = a_maximums[frame];
- rubber_data.q_max = max_b = b_maximums[frame];
- a_range = max_a - min_a;
- b_range = max_b - min_b;
- a_inc = a_range / (double)width;
- b_inc = b_range / (double)height;
- point.x = -1;
- point.y = 0;
- a = min_a;
- b = min_b;
- Clear();
- if (resized[frame])
- Redraw();
+ /*st->rubber_data.p_min =*/ st->min_a = st->a_minimums[st->frame];
+ /*st->rubber_data.q_min =*/ st->min_b = st->b_minimums[st->frame];
+ /*st->rubber_data.p_max =*/ st->max_a = st->a_maximums[st->frame];
+ /*st->rubber_data.q_max =*/ st->max_b = st->b_maximums[st->frame];
+ st->a_range = st->max_a - st->min_a;
+ st->b_range = st->max_b - st->min_b;
+ st->a_inc = st->a_range / (double)st->width;
+ st->b_inc = st->b_range / (double)st->height;
+ st->point.x = -1;
+ st->point.y = 0;
+ st->a = st->min_a;
+ st->b = st->min_b;
+ Clear(st);
+ if (st->resized[st->frame])
+ Redraw(st);
else
- redraw(exponents[frame], expind[frame], 0);
+ redraw(st, st->exponents[st->frame], st->expind[st->frame], 0);
}
static void
-go_init(void)
+go_init(struct state *st)
{
- frame = 0;
- jumpwin();
+ st->frame = 0;
+ jumpwin(st);
}
static void
-Destroy_frame(void)
+Destroy_frame(struct state *st)
{
- static int i;
-
- for (i=frame; i<maxframe; i++) {
- exponents[frame] = exponents[frame+1];
- expind[frame] = expind[frame+1];
- a_minimums[frame] = a_minimums[frame+1];
- b_minimums[frame] = b_minimums[frame+1];
- a_maximums[frame] = a_maximums[frame+1];
- b_maximums[frame] = b_maximums[frame+1];
+ int i;
+
+ for (i=st->frame; i<st->maxframe; i++) {
+ st->exponents[st->frame] = st->exponents[st->frame+1];
+ st->expind[st->frame] = st->expind[st->frame+1];
+ st->a_minimums[st->frame] = st->a_minimums[st->frame+1];
+ st->b_minimums[st->frame] = st->b_minimums[st->frame+1];
+ st->a_maximums[st->frame] = st->a_maximums[st->frame+1];
+ st->b_maximums[st->frame] = st->b_maximums[st->frame+1];
}
- maxframe--;
- go_back();
+ st->maxframe--;
+ go_back(st);
}
static void
-InitBuffer(void)
+InitBuffer(struct state *st)
{
int i;
- for (i = 0 ; i < maxcolor; ++i)
- Points.npoints[i] = 0;
+ for (i = 0 ; i < st->maxcolor; ++i)
+ st->Points.npoints[i] = 0;
}
static void
-BufferPoint(Display *display, Window window, int color, int x, int y)
+BufferPoint(struct state *st, int color, int x, int y)
{
+ if (st->maxcolor > MAXCOLOR)
+ abort();
-/* Guard against bogus color values. Shouldn't be necessary but paranoia
- is good. */
+ /* Guard against bogus color values. Shouldn't be necessary but paranoia
+ is good. */
if (color < 0)
color = 0;
- else if (color >= maxcolor)
- color = maxcolor - 1;
+ else if (color >= st->maxcolor)
+ color = st->maxcolor - 1;
- if (Points.npoints[color] == MAXPOINTS)
- {
- XDrawPoints(display, window, Data_GC[color],
- Points.data[color], Points.npoints[color], CoordModeOrigin);
- XDrawPoints(display, pixmap, Data_GC[color],
- Points.data[color], Points.npoints[color], CoordModeOrigin);
- Points.npoints[color] = 0;
- }
- Points.data[color][Points.npoints[color]].x = x;
- Points.data[color][Points.npoints[color]].y = y;
- ++Points.npoints[color];
+ if (st->Points.npoints[color] == MAXPOINTS)
+ {
+ XDrawPoints(st->dpy, st->canvas, st->Data_GC[color],
+ st->Points.data[color], st->Points.npoints[color],
+ CoordModeOrigin);
+#ifdef BACKING_PIXMAP
+ XDrawPoints(st->dpy, st->pixmap, st->Data_GC[color],
+ st->Points.data[color], st->Points.npoints[color],
+ CoordModeOrigin);
+#endif
+ st->Points.npoints[color] = 0;
+ }
+ st->Points.data[color][st->Points.npoints[color]].x = x;
+ st->Points.data[color][st->Points.npoints[color]].y = y;
+ ++st->Points.npoints[color];
}
static void
-FlushBuffer(void)
+FlushBuffer(struct state *st)
{
int color;
- for (color = 0; color < maxcolor; ++color)
- if (Points.npoints[color])
- {
- XDrawPoints(dpy, canvas, Data_GC[color],
- Points.data[color], Points.npoints[color],
- CoordModeOrigin);
- XDrawPoints(dpy, pixmap, Data_GC[color],
- Points.data[color], Points.npoints[color],
- CoordModeOrigin);
- Points.npoints[color] = 0;
- }
+ for (color = 0; color < st->maxcolor; ++color)
+ if (st->Points.npoints[color])
+ {
+ XDrawPoints(st->dpy, st->canvas, st->Data_GC[color],
+ st->Points.data[color], st->Points.npoints[color],
+ CoordModeOrigin);
+#ifdef BACKING_PIXMAP
+ XDrawPoints(st->dpy, st->pixmap, st->Data_GC[color],
+ st->Points.data[color], st->Points.npoints[color],
+ CoordModeOrigin);
+#endif
+ st->Points.npoints[color] = 0;
+ }
}
static void
-print_help(void)
+print_help(struct state *st)
{
- printf("During run-time, interactive control can be exerted via : \n");
- printf("Mouse buttons allow rubber-banding of a zoom box\n");
- printf("< halves the 'dwell', > doubles the 'dwell'\n");
- printf("[ halves the 'settle', ] doubles the 'settle'\n");
- printf("D flushes the drawing buffer\n");
- printf("e or E recalculates color indices\n");
- printf("f or F saves exponents to a file\n");
- printf("h or H or ? displays this message\n");
- printf("i decrements, I increments the stripe interval\n");
- printf("KJMN increase/decrease minimum negative exponent\n");
- printf("m increments the map index, changing maps\n");
- printf("p or P reverses the colormap for negative/positive exponents\n");
- printf("r redraws without recalculating\n");
- printf("R redraws, recalculating with new dwell and settle values\n");
- printf("s or S spins the colorwheel\n");
- printf("u pops back up to the last zoom\n");
- printf("U pops back up to the first picture\n");
- printf("v or V displays the values of various settings\n");
- printf("w decrements, W increments the color wheel index\n");
- printf("x or X clears the window\n");
- printf("q or Q exits\n");
+ printf("During run-time, interactive control can be exerted via : \n");
+ printf("Mouse buttons allow rubber-banding of a zoom box\n");
+ printf("< halves the 'dwell', > doubles the 'dwell'\n");
+ printf("[ halves the 'settle', ] doubles the 'settle'\n");
+ printf("D flushes the drawing buffer\n");
+ printf("e or E recalculates color indices\n");
+ printf("f or F saves exponents to a file\n");
+ printf("h or H or ? displays this message\n");
+ printf("i decrements, I increments the stripe interval\n");
+ printf("KJMN increase/decrease minimum negative exponent\n");
+ printf("m increments the map index, changing maps\n");
+ printf("p or P reverses the colormap for negative/positive exponents\n");
+ printf("r redraws without recalculating\n");
+ printf("R redraws, recalculating with new dwell and settle values\n");
+ printf("s or S spins the colorwheel\n");
+ printf("u pops back up to the last zoom\n");
+ printf("U pops back up to the first picture\n");
+ printf("v or V displays the values of various settings\n");
+ printf("w decrements, W increments the color wheel index\n");
+ printf("x or X clears the window\n");
+ printf("q or Q exits\n");
}
static void
-print_values(void)
+print_values(struct state *st)
{
- static int i;
-
- printf("\nminlyap=%f minexp=%f maxexp=%f\n",minlyap,minexp,maxexp);
- printf("width=%d height=%d\n",width,height);
- printf("settle=%d dwell=%d start_x=%f\n",settle,dwell, start_x);
- printf("min_a=%f a_rng=%f max_a=%f\n",min_a,a_range,max_a);
- printf("min_b=%f b_rng=%f max_b=%f\n",min_b,b_range,max_b);
- if (Rflag)
- printf("pseudo-random forcing\n");
- else if (force) {
- printf("periodic forcing=");
- for (i=0;i<maxindex;i++)
- printf("%d",forcing[i]);
- printf("\n");
+ int i;
+ printf("\nminlyap=%f minexp=%f maxexp=%f\n",
+ st->minlyap,st->minexp, st->maxexp);
+ printf("width=%d height=%d\n",st->width,st->height);
+ printf("settle=%d dwell=%d st->start_x=%f\n",
+ st->settle,st->dwell, st->start_x);
+ printf("min_a=%f a_rng=%f max_a=%f\n",
+ st->min_a,st->a_range,st->max_a);
+ printf("min_b=%f b_rng=%f max_b=%f\n",
+ st->min_b,st->b_range,st->max_b);
+ if (st->Rflag)
+ printf("pseudo-random forcing\n");
+ else if (st->force) {
+ printf("periodic forcing=");
+ for (i=0;i<st->maxindex;i++)
+ printf("%d",st->forcing[i]);
+ printf("\n");
+ }
+ else
+ printf("periodic forcing=01\n");
+ if (st->Force) {
+ printf("function forcing=");
+ for (i=0;i<st->funcmaxindex;i++) {
+ printf("%d",st->Forcing[i]);
}
- else
- printf("periodic forcing=01\n");
- if (Force) {
- printf("function forcing=");
- for (i=0;i<funcmaxindex;i++) {
- printf("%d",Forcing[i]);
+ printf("\n");
}
- printf("\n");
+ printf("numcolors=%d\n",st->numcolors-1);
+}
+
+static void
+freemem(struct state *st)
+{
+ int i;
+ for (i=0;i<MAXFRAMES;i++)
+ free(st->exponents[i]);
+}
+
+static void
+setupmem(struct state *st)
+{
+ int i;
+ for (i=0;i<MAXFRAMES;i++) {
+ if((st->exponents[i]=
+ (double *)malloc(sizeof(double)*st->width*(st->height+1)))==NULL){
+ fprintf(stderr,"Error malloc'ing exponent array.\n");
+ exit(-1);
}
- printf("numcolors=%d\n",numcolors-1);
+ }
+}
+
+static void
+setforcing(struct state *st)
+{
+ int i;
+ for (i=0;i<MAXINDEX;i++)
+ st->forcing[i] = (random() > st->prob) ? 0 : 1;
+}
+
+/****************************************************************************/
+
+static void
+do_defaults (struct state *st)
+{
+ int i;
+
+ memset (st->expind, 0, sizeof(st->expind));
+ memset (st->resized, 0, sizeof(st->resized));
+
+ st->aflag = 0;
+ st->bflag = 0;
+ st->hflag = 0;
+ st->wflag = 0;
+ st->minexp = 0;
+ st->mapindex = 0;
+
+# ifdef SIXTEEN_COLORS
+ st->maxcolor=16;
+ st->startcolor=0;
+ st->color_offset=0;
+ st->mincolindex=1;
+ st->dwell=50;
+ st->settle=25;
+ st->xposition=128;
+ st->yposition=128;
+# else /* !SIXTEEN_COLORS */
+ st->maxcolor=256;
+ st->startcolor=17;
+ st->color_offset=96;
+ st->mincolindex=33;
+ st->dwell=100;
+ st->settle=50;
+# endif /* !SIXTEEN_COLORS */
+
+ st->maxindex = MAXINDEX;
+ st->funcmaxindex = FUNCMAXINDEX;
+ st->min_a=2.0;
+ st->min_b=2.0;
+ st->a_range=2.0;
+ st->b_range=2.0;
+ st->minlyap=1.0;
+ st->max_a=4.0;
+ st->max_b=4.0;
+ st->numcolors=16;
+ st->prob=0.5;
+ st->numwheels=MAXWHEELS;
+ st->negative=1;
+ st->rgb_max=65000;
+ st->nostart=1;
+ st->stripe_interval=7;
+ st->save=1;
+ st->useprod=1;
+ st->spinlength=256;
+ st->run=1;
+
+ for (i = 0; i < countof(st->forcing); i++)
+ st->forcing[i] = (i & 1) ? 1 : 0;
}
static void
-freemem(void)
+do_preset (struct state *st, int builtin)
+{
+ char *ff = 0;
+ switch (builtin) {
+ case 0:
+ st->min_a = 3.75; st->aflag++;
+ st->min_b = 3.299999; st->bflag++;
+ st->a_range = 0.05; st->wflag++;
+ st->b_range = 0.05; st->hflag++;
+ st->dwell = 200;
+ st->settle = 100;
+ ff = "abaabbaaabbb";
+ break;
+
+ case 1:
+ st->min_a = 3.8; st->aflag++;
+ st->min_b = 3.2; st->bflag++;
+ st->b_range = .05; st->hflag++;
+ st->a_range = .05; st->wflag++;
+ ff = "bbbbbaaaaa";
+ break;
+
+ case 2:
+ st->min_a = 3.4; st->aflag++;
+ st->min_b = 3.04; st->bflag++;
+ st->a_range = .5; st->wflag++;
+ st->b_range = .5; st->hflag++;
+ ff = "abbbbbbbbb";
+ st->settle = 500;
+ st->dwell = 1000;
+ break;
+
+ case 3:
+ st->min_a = 3.5; st->aflag++;
+ st->min_b = 3.0; st->bflag++;
+ st->a_range = 0.2; st->wflag++;
+ st->b_range = 0.2; st->hflag++;
+ st->dwell = 600;
+ st->settle = 300;
+ ff = "aaabbbab";
+ break;
+
+ case 4:
+ st->min_a = 3.55667; st->aflag++;
+ st->min_b = 3.2; st->bflag++;
+ st->b_range = .05; st->hflag++;
+ st->a_range = .05; st->wflag++;
+ ff = "bbbbbaaaaa";
+ break;
+
+ case 5:
+ st->min_a = 3.79; st->aflag++;
+ st->min_b = 3.22; st->bflag++;
+ st->b_range = .02999; st->hflag++;
+ st->a_range = .02999; st->wflag++;
+ ff = "bbbbbaaaaa";
+ break;
+
+ case 6:
+ st->min_a = 3.7999; st->aflag++;
+ st->min_b = 3.299999; st->bflag++;
+ st->a_range = 0.2; st->wflag++;
+ st->b_range = 0.2; st->hflag++;
+ st->dwell = 300;
+ st->settle = 150;
+ ff = "abaabbaaabbb";
+ break;
+
+ case 7:
+ st->min_a = 3.89; st->aflag++;
+ st->min_b = 3.22; st->bflag++;
+ st->b_range = .028; st->hflag++;
+ st->a_range = .02999; st->wflag++;
+ ff = "bbbbbaaaaa";
+ st->settle = 600;
+ st->dwell = 1000;
+ break;
+
+ case 8:
+ st->min_a = 3.2; st->aflag++;
+ st->min_b = 3.7; st->bflag++;
+ st->a_range = 0.05; st->wflag++;
+ st->b_range = .005; st->hflag++;
+ ff = "abbbbaa";
+ break;
+
+ case 9:
+ ff = "aaaaaabbbbbb";
+ st->mapindex = 1;
+ st->dwell = 400;
+ st->settle = 200;
+ st->minlyap = st->maxexp = ABS(-0.85);
+ st->minexp = -1.0 * st->minlyap;
+ break;
+
+ case 10:
+ ff = "aaaaaabbbbbb";
+ st->mapindex = 1;
+ st->dwell = 400;
+ st->settle = 200;
+ st->minlyap = st->maxexp = ABS(-0.85);
+ st->minexp = -1.0 * st->minlyap;
+ break;
+
+ case 11:
+ st->mapindex = 1;
+ st->dwell = 400;
+ st->settle = 200;
+ st->minlyap = st->maxexp = ABS(-0.85);
+ st->minexp = -1.0 * st->minlyap;
+ break;
+
+ case 12:
+ ff = "abbb";
+ st->mapindex = 1;
+ st->dwell = 400;
+ st->settle = 200;
+ st->minlyap = st->maxexp = ABS(-0.85);
+ st->minexp = -1.0 * st->minlyap;
+ break;
+
+ case 13:
+ ff = "abbabaab";
+ st->mapindex = 1;
+ st->dwell = 400;
+ st->settle = 200;
+ st->minlyap = st->maxexp = ABS(-0.85);
+ st->minexp = -1.0 * st->minlyap;
+ break;
+
+ case 14:
+ ff = "abbabaab";
+ st->dwell = 800;
+ st->settle = 200;
+ st->minlyap = st->maxexp = ABS(-0.85);
+ st->minexp = -1.0 * st->minlyap;
+ /* #### -x 0.05 */
+ st->min_a = 3.91; st->aflag++;
+ st->a_range = 0.0899999999; st->wflag++;
+ st->min_b = 3.28; st->bflag++;
+ st->b_range = 0.35; st->hflag++;
+ break;
+
+ case 15:
+ ff = "aaaaaabbbbbb";
+ st->dwell = 400;
+ st->settle = 200;
+ st->minlyap = st->maxexp = ABS(-0.85);
+ st->minexp = -1.0 * st->minlyap;
+ break;
+
+ case 16:
+ st->dwell = 400;
+ st->settle = 200;
+ st->minlyap = st->maxexp = ABS(-0.85);
+ st->minexp = -1.0 * st->minlyap;
+ break;
+
+ case 17:
+ ff = "abbb";
+ st->dwell = 400;
+ st->settle = 200;
+ st->minlyap = st->maxexp = ABS(-0.85);
+ st->minexp = -1.0 * st->minlyap;
+ break;
+
+ case 18:
+ ff = "abbabaab";
+ st->dwell = 400;
+ st->settle = 200;
+ st->minlyap = st->maxexp = ABS(-0.85);
+ st->minexp = -1.0 * st->minlyap;
+ break;
+
+ case 19:
+ st->mapindex = 2;
+ ff = "aaaaaabbbbbb";
+ st->dwell = 400;
+ st->settle = 200;
+ st->minlyap = st->maxexp = ABS(-0.85);
+ st->minexp = -1.0 * st->minlyap;
+ break;
+
+ case 20:
+ st->mapindex = 2;
+ st->dwell = 400;
+ st->settle = 200;
+ st->minlyap = st->maxexp = ABS(-0.85);
+ st->minexp = -1.0 * st->minlyap;
+ break;
+
+ case 21:
+ st->mapindex = 2;
+ ff = "abbb";
+ st->dwell = 400;
+ st->settle = 200;
+ st->minlyap = st->maxexp = ABS(-0.85);
+ st->minexp = -1.0 * st->minlyap;
+ break;
+
+ case 22:
+ st->mapindex = 2;
+ ff = "abbabaab";
+ st->dwell = 400;
+ st->settle = 200;
+ st->minlyap = st->maxexp = ABS(-0.85);
+ st->minexp = -1.0 * st->minlyap;
+ break;
+
+ default:
+ abort();
+ break;
+ }
+
+ if (ff) {
+ char *ch;
+ int bindex = 0;
+ st->maxindex = strlen(ff);
+ if (st->maxindex > MAXINDEX)
+ usage(st);
+ ch = ff;
+ st->force++;
+ while (bindex < st->maxindex) {
+ if (*ch == 'a')
+ st->forcing[bindex++] = 0;
+ else if (*ch == 'b')
+ st->forcing[bindex++] = 1;
+ else
+ usage(st);
+ ch++;
+ }
+ }
+}
+
+
+static void *
+xlyap_init (Display *d, Window window)
{
- static int i;
+ struct state *st = (struct state *) calloc (1, sizeof(*st));
+ XWindowAttributes xgwa;
+ int builtin = -1;
+ XGetWindowAttributes (d, window, &xgwa);
+ st->dpy = d;
+ st->width = xgwa.width;
+ st->height = xgwa.height;
+ st->visual = xgwa.visual;
+ st->cmap = xgwa.colormap;
+
+ do_defaults(st);
+ parseargs(st);
+
+ if (get_boolean_resource(st->dpy, "randomize", "Boolean"))
+ builtin = random() % NBUILTINS;
+ else {
+ char *s = get_string_resource(st->dpy, "builtin", "Integer");
+ if (s && *s)
+ builtin = atoi(s);
+ if (s) free (s);
+ }
+
+ if (builtin >= 0)
+ do_preset (st, builtin);
+
+ st->screen = DefaultScreen(st->dpy);
+ st->background = BlackPixel(st->dpy, st->screen);
+ setupmem(st);
+ init_data(st);
+ if (!mono_p)
+ st->foreground = st->startcolor;
+ else
+ st->foreground = WhitePixel(st->dpy, st->screen);
+
+ /*
+ * Create the window to display the Lyapunov exponents
+ */
+ st->canvas = window;
+ init_color(st);
+
+#ifdef BACKING_PIXMAP
+ st->pixmap = XCreatePixmap(st->dpy, window, st->width, st->height,
+ xgwa.depth);
+#endif
+/* st->rubber_data.band_cursor = XCreateFontCursor(st->dpy, XC_hand2);*/
+/* CreateXorGC(st);*/
+ Clear(st);
+
+ st->delay = get_integer_resource(st->dpy, "delay", "Delay");
+ st->linger = get_integer_resource(st->dpy, "linger", "Linger");
+ if (st->linger < 1) st->linger = 1;
+
+ return st;
+}
+
+
+static unsigned long
+xlyap_draw (Display *dpy, Window window, void *closure)
+{
+ struct state *st = (struct state *) closure;
+ int i;
+
+ if (!st->run && st->reset_countdown) {
+ st->reset_countdown--;
+ if (st->reset_countdown)
+ return 1000000;
+ else {
+ do_defaults (st);
+ do_preset (st, (random() % NBUILTINS));
+ Clear (st);
+ init_data(st);
+ init_color(st);
+ resize (st);
+ st->frame = 0;
+ st->run = 1;
+ }
+ }
- for (i=0;i<MAXFRAMES;i++)
- free(exponents[i]);
+ for (i = 0; i < 1000; i++)
+ if (complyap(st) == TRUE)
+ {
+ st->run = 0;
+ st->reset_countdown = st->linger;
+ break;
+ }
+ return st->delay;
}
static void
-setupmem(void)
+xlyap_reshape (Display *dpy, Window window, void *closure,
+ unsigned int w, unsigned int h)
+{
+ struct state *st = (struct state *) closure;
+ resize(st);
+}
+
+static Bool
+xlyap_event (Display *dpy, Window window, void *closure, XEvent *event)
{
- static int i;
-
- for (i=0;i<MAXFRAMES;i++) {
- if((exponents[i]=
- (double *)malloc(sizeof(double)*width*height))==NULL){
- fprintf(stderr,"Error malloc'ing exponent array.\n");
- exit(-1);
- }
- }
+ struct state *st = (struct state *) closure;
+ switch(event->type)
+ {
+ case KeyPress:
+ return Getkey(st, &event->xkey);
+ return True;
+#if 0
+ case ButtonPress:
+ StartRubberBand(st, &st->rubber_data, event);
+ return True;
+ case MotionNotify:
+ TrackRubberBand(st, &st->rubber_data, event);
+ return True;
+ case ButtonRelease:
+ EndRubberBand(st, &st->rubber_data, event);
+ return True;
+#endif
+ default:
+ break;
+ }
+ return False;
}
static void
-setforcing(void)
+xlyap_free (Display *dpy, Window window, void *closure)
{
- static int i;
- for (i=0;i<MAXINDEX;i++)
- forcing[i] = (random() > prob) ? 0 : 1;
+ int i;
+ struct state *st = (struct state *) closure;
+
+ freemem (st);
+
+#ifdef BACKING_PIXMAP
+ XFreePixmap (st->dpy, st->pixmap);
+#endif
+/* XFreeGC (st->dpy, st->RubberGC);*/
+ for (i = 0; i < st->maxcolor; i++)
+ XFreeGC (st->dpy, st->Data_GC[i]);
+
+ free (st);
}
+
+
+XSCREENSAVER_MODULE ("XLyap", xlyap)