X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fifs.c;h=29a72c23144d59f3d0b93e42ee91ba284fc765dd;hp=3bccf872073170a619a1d67f8d570a63a0da3b97;hb=96a411663168b0ba5432b407a83be55f3df0c802;hpb=df7adbee81405e2849728a24b498ad2117784b1f diff --git a/hacks/ifs.c b/hacks/ifs.c index 3bccf872..29a72c23 100644 --- a/hacks/ifs.c +++ b/hacks/ifs.c @@ -1,12 +1,12 @@ -/* -*- Mode: C; tab-width: 4 -*- - * ifs --- Modified iterated functions system. - */ -#if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)ifs.c 4.02 97/04/01 xlockmore"; +/* -*- Mode: C; tab-width: 4 -*- */ +/* ifs --- modified iterated functions system */ + +#if 0 +static const char sccsid[] = "@(#)ifs.c 5.00 2000/11/01 xlockmore"; #endif -/* Copyright (c) 1997 by Massimino Pascal (Pascal.Massimon@ens.fr) - * +/*- + * Copyright (c) 1997 by Massimino Pascal * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, @@ -20,33 +20,50 @@ static const char sccsid[] = "@(#)ifs.c 4.02 97/04/01 xlockmore"; * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * + * If this mode is weird and you have an old MetroX server, it is buggy. + * There is a free SuSE-enhanced MetroX X server that is fine. + * + * When shown ifs, Diana Rose (4 years old) said, "It looks like dancing." + * * Revision History: - * 10-May-97: jwz@jwz.org: turned into a standalone program. - * Made it render into an offscreen bitmap and then copy - * that onto the screen, to reduce flicker. + * 01-Nov-2000: Allocation checks + * 10-May-1997: jwz@jwz.org: turned into a standalone program. + * Made it render into an offscreen bitmap and then copy + * that onto the screen, to reduce flicker. */ #ifdef STANDALONE -# define PROGCLASS "IFS" -# define HACK_INIT init_ifs -# define HACK_DRAW draw_ifs -# define ifs_opts xlockmore_opts -# define DEFAULTS "*delay: 20000 \n" \ - "*ncolors: 100 \n" -# define SMOOTH_COLORS -# include "xlockmore.h" /* from the xscreensaver distribution */ -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ -#endif /* !STANDALONE */ - -ModeSpecOpt ifs_opts = { - 0, NULL, 0, NULL, NULL }; +#define MODE_ifs +#define PROGCLASS "IFS" +#define HACK_INIT init_ifs +#define HACK_DRAW draw_ifs +#define ifs_opts xlockmore_opts +#define DEFAULTS "*delay: 20000 \n" \ + "*ncolors: 100 \n" +#define SMOOTH_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ +#else /* STANDALONE */ +#include "xlock.h" /* in xlockmore distribution */ +#endif /* STANDALONE */ + +#ifdef MODE_ifs + +ModeSpecOpt ifs_opts = +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct ifs_description = +{"ifs", "init_ifs", "draw_ifs", "release_ifs", + "init_ifs", "init_ifs", (char *) NULL, &ifs_opts, + 1000, 1, 1, 1, 64, 1.0, "", + "Shows a modified iterated function system", 0, NULL}; + +#endif -/*****************************************************/ /*****************************************************/ typedef float DBL; -typedef short int F_PT; +typedef int F_PT; /* typedef float F_PT; */ @@ -64,18 +81,6 @@ typedef short int F_PT; #define DBL_To_F_PT(x) (F_PT)( (DBL)(UNIT)*(x) ) -/*****************************************************/ - -static int Max_Colors; -static ModeInfo *The_MI; -static F_PT Lx, Ly; -static int D; -static Display *display; -static GC gc; -static Window window; - -/*****************************************************/ - typedef struct Similitude_Struct SIMI; typedef struct Fractal_Struct FRACTAL; @@ -98,16 +103,15 @@ struct Fractal_Struct { DBL r_mean, dr_mean, dr2_mean; int Cur_Pt, Max_Pt; XPoint *Buffer1, *Buffer2; - Pixmap dbuf; /* jwz */ - GC dbuf_gc; + Pixmap dbuf; + GC dbuf_gc; }; -static FRACTAL *Root = NULL, *Cur_F; +static FRACTAL *Root = (FRACTAL *) NULL, *Cur_F; static XPoint *Buf; static int Cur_Pt; -/*****************************************************/ /*****************************************************/ static DBL @@ -146,11 +150,42 @@ Random_Simis(FRACTAL * F, SIMI * Cur, int i) } } +static void +free_ifs_buffers(FRACTAL *Fractal) +{ + if (Fractal->Buffer1 != NULL) { + (void) free((void *) Fractal->Buffer1); + Fractal->Buffer1 = (XPoint *) NULL; + } + if (Fractal->Buffer2 != NULL) { + (void) free((void *) Fractal->Buffer2); + Fractal->Buffer2 = (XPoint *) NULL; + } +} + + +static void +free_ifs(Display *display, FRACTAL *Fractal) +{ + free_ifs_buffers(Fractal); + if (Fractal->dbuf != None) { + XFreePixmap(display, Fractal->dbuf); + Fractal->dbuf = None; + } + if (Fractal->dbuf_gc != None) { + XFreeGC(display, Fractal->dbuf_gc); + Fractal->dbuf_gc = None; + } +} + /***************************************************************/ void init_ifs(ModeInfo * mi) { + Display *display = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + GC gc = MI_GC(mi); int i; FRACTAL *Fractal; @@ -162,10 +197,7 @@ init_ifs(ModeInfo * mi) } Fractal = &Root[MI_SCREEN(mi)]; - if (Fractal->Max_Pt) { - free(Fractal->Buffer1); - free(Fractal->Buffer2); - } + free_ifs_buffers(Fractal); i = (NRAND(4)) + 2; /* Number of centers */ switch (i) { case 3: @@ -203,16 +235,19 @@ init_ifs(ModeInfo * mi) for (i = 0; i <= Fractal->Depth + 2; ++i) Fractal->Max_Pt *= Fractal->Nb_Simi; - Fractal->Buffer1 = (XPoint *) calloc(Fractal->Max_Pt, sizeof (XPoint)); - if (Fractal->Buffer1 == NULL) - goto Abort; - Fractal->Buffer2 = (XPoint *) calloc(Fractal->Max_Pt, sizeof (XPoint)); - if (Fractal->Buffer2 == NULL) - goto Abort; - + if ((Fractal->Buffer1 = (XPoint *) calloc(Fractal->Max_Pt, + sizeof (XPoint))) == NULL) { + free_ifs(display, Fractal); + return; + } + if ((Fractal->Buffer2 = (XPoint *) calloc(Fractal->Max_Pt, + sizeof (XPoint))) == NULL) { + free_ifs(display, Fractal); + return; + } Fractal->Speed = 6; - Fractal->Width = MI_WIN_WIDTH(mi); - Fractal->Height = MI_WIN_HEIGHT(mi); + Fractal->Width = MI_WIDTH(mi); + Fractal->Height = MI_HEIGHT(mi); Fractal->Cur_Pt = 0; Fractal->Count = 0; Fractal->Lx = (Fractal->Width - 1) / 2; @@ -221,46 +256,50 @@ init_ifs(ModeInfo * mi) Random_Simis(Fractal, Fractal->Components, 5 * MAX_SIMI); - Fractal->dbuf = XCreatePixmap(MI_DISPLAY(mi), MI_WINDOW(mi), - Fractal->Width, Fractal->Height, 1); - if (Fractal->dbuf) - { - XGCValues gcv; +#ifndef NO_DBUF + if (Fractal->dbuf != None) + XFreePixmap(display, Fractal->dbuf); + Fractal->dbuf = XCreatePixmap(display, window, + Fractal->Width, Fractal->Height, 1); + /* Allocation checked */ + if (Fractal->dbuf != None) { + XGCValues gcv; + gcv.foreground = 0; gcv.background = 0; + gcv.graphics_exposures = False; gcv.function = GXcopy; - Fractal->dbuf_gc = XCreateGC(MI_DISPLAY(mi), Fractal->dbuf, - GCForeground|GCBackground|GCFunction, - &gcv); - XFillRectangle(MI_DISPLAY(mi), Fractal->dbuf, - Fractal->dbuf_gc, 0,0, Fractal->Width, Fractal->Height); - - XSetBackground(MI_DISPLAY(mi), MI_GC(mi), MI_WIN_BLACK_PIXEL(mi)); - XSetFunction(MI_DISPLAY(mi), MI_GC(mi), GXcopy); - } - - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); - return; - - Abort: - if (Fractal->Buffer1 != NULL) - free(Fractal->Buffer1); - if (Fractal->Buffer2 != NULL) - free(Fractal->Buffer2); - Fractal->Buffer1 = NULL; - Fractal->Buffer2 = NULL; - Fractal->Max_Pt = 0; - return; + + if (Fractal->dbuf_gc != None) + XFreeGC(display, Fractal->dbuf_gc); + if ((Fractal->dbuf_gc = XCreateGC(display, Fractal->dbuf, + GCForeground | GCBackground | GCGraphicsExposures | GCFunction, + &gcv)) == None) { + XFreePixmap(display, Fractal->dbuf); + Fractal->dbuf = None; + } else { + XFillRectangle(display, Fractal->dbuf, + Fractal->dbuf_gc, 0, 0, Fractal->Width, Fractal->Height); + XSetBackground(display, gc, MI_BLACK_PIXEL(mi)); + XSetFunction(display, gc, GXcopy); + } + } +#endif + MI_CLEARWINDOW(mi); + + /* don't want any exposure events from XCopyPlane */ + XSetGraphicsExposures(display, gc, False); + } /***************************************************************/ -#ifndef __GNUC__ -# undef inline -# define inline /* */ +/* Should be taken care of already... but just in case */ +#if !defined( __GNUC__ ) && !defined(__cplusplus) && !defined(c_plusplus) +#undef inline +#define inline /* */ #endif - static inline void Transform(SIMI * Simi, F_PT xo, F_PT yo, F_PT * x, F_PT * y) { @@ -283,7 +322,7 @@ Transform(SIMI * Simi, F_PT xo, F_PT yo, F_PT * x, F_PT * y) /***************************************************************/ static void -Trace(F_PT xo, F_PT yo) +Trace(FRACTAL * F, F_PT xo, F_PT yo) { F_PT x, y, i; SIMI *Cur; @@ -291,22 +330,28 @@ Trace(F_PT xo, F_PT yo) Cur = Cur_F->Components; for (i = Cur_F->Nb_Simi; i; --i, Cur++) { Transform(Cur, xo, yo, &x, &y); - Buf->x = Lx + (x * Lx / (UNIT * 2)); - Buf->y = Ly - (y * Ly / (UNIT * 2)); + /* Buf->x = F->Lx + (x * F->Lx / (UNIT * 2)); */ + /* Buf->y = F->Ly - (y * F->Ly / (UNIT * 2)); */ + Buf->x = (UNIT * 2 + x) * F->Lx / (UNIT * 2); + Buf->y = (UNIT * 2 - y) * F->Ly / (UNIT * 2); Buf++; Cur_Pt++; - if (D && ((x - xo) >> 4) && ((y - yo) >> 4)) { - D--; - Trace(x, y); - D++; + if (F->Depth && ((x - xo) >> 4) && ((y - yo) >> 4)) { + F->Depth--; + Trace(F, x, y); + F->Depth++; } } } static void -Draw_Fractal(FRACTAL * F) +Draw_Fractal(ModeInfo * mi) { + Display *display = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + GC gc = MI_GC(mi); + FRACTAL *F = &Root[MI_SCREEN(mi)]; int i, j; F_PT x, y, xo, yo; SIMI *Cur, *Simi; @@ -328,9 +373,6 @@ Draw_Fractal(FRACTAL * F) Cur_Pt = 0; Cur_F = F; Buf = F->Buffer2; - Lx = F->Lx; - Ly = F->Ly; - D = F->Depth; for (Cur = F->Components, i = F->Nb_Simi; i; --i, Cur++) { xo = Cur->Cx; yo = Cur->Cy; @@ -338,43 +380,36 @@ Draw_Fractal(FRACTAL * F) if (Simi == Cur) continue; Transform(Simi, xo, yo, &x, &y); - Trace(x, y); + Trace(F, x, y); } } /* Erase previous */ - if (F->Cur_Pt) { - XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(The_MI)); - if (F->dbuf) /* jwz */ - { + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); + if (F->dbuf != None) { XSetForeground(display, F->dbuf_gc, 0); -/* XDrawPoints(display, F->dbuf, F->dbuf_gc, F->Buffer1, F->Cur_Pt, - CoordModeOrigin); */ - XFillRectangle(display, F->dbuf, F->dbuf_gc, 0, 0, - F->Width, F->Height); - } - else - XDrawPoints(display, window, gc, F->Buffer1, F->Cur_Pt, - CoordModeOrigin); + /* XDrawPoints(display, F->dbuf, F->dbuf_gc, F->Buffer1, F->Cur_Pt, + CoordModeOrigin); */ + XFillRectangle(display, F->dbuf, F->dbuf_gc, 0, 0, + F->Width, F->Height); + } else + XDrawPoints(display, window, gc, F->Buffer1, F->Cur_Pt, CoordModeOrigin); } - if (Max_Colors < 2) - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(The_MI)); + if (MI_NPIXELS(mi) < 2) + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); else - XSetForeground(display, gc, MI_PIXEL(The_MI, F->Col % Max_Colors)); + XSetForeground(display, gc, MI_PIXEL(mi, F->Col % MI_NPIXELS(mi))); if (Cur_Pt) { - if (F->dbuf) - { - XSetForeground(display, F->dbuf_gc, 1); - XDrawPoints(display, F->dbuf, F->dbuf_gc, F->Buffer2, Cur_Pt, - CoordModeOrigin); - } - else - XDrawPoints(display, window, gc, F->Buffer2, Cur_Pt, CoordModeOrigin); + if (F->dbuf != None) { + XSetForeground(display, F->dbuf_gc, 1); + XDrawPoints(display, F->dbuf, F->dbuf_gc, F->Buffer2, Cur_Pt, + CoordModeOrigin); + } else + XDrawPoints(display, window, gc, F->Buffer2, Cur_Pt, CoordModeOrigin); } - - if (F->dbuf) - XCopyPlane(display, F->dbuf, window, gc, 0,0,F->Width,F->Height,0,0, 1); + if (F->dbuf != None) + XCopyPlane(display, F->dbuf, window, gc, 0, 0, F->Width, F->Height, 0, 0, 1); F->Cur_Pt = Cur_Pt; Buf = F->Buffer1; @@ -387,17 +422,15 @@ void draw_ifs(ModeInfo * mi) { int i; - FRACTAL *F; DBL u, uu, v, vv, u0, u1, u2, u3; SIMI *S, *S1, *S2, *S3, *S4; + FRACTAL *F; - The_MI = mi; - display = MI_DISPLAY(mi); - window = MI_WINDOW(mi); - gc = MI_GC(mi); - Max_Colors = MI_NPIXELS(mi); - + if (Root == NULL) + return; F = &Root[MI_SCREEN(mi)]; + if (F->Buffer1 == NULL) + return; u = (DBL) (F->Count) * (DBL) (F->Speed) / 1000.0; uu = u * u; @@ -423,7 +456,9 @@ draw_ifs(ModeInfo * mi) S->A2 = u0 * S1->A2 + u1 * S2->A2 + u2 * S3->A2 + u3 * S4->A2; } - Draw_Fractal(F); + MI_IS_DRAWN(mi) = True; + + Draw_Fractal(mi); if (F->Count >= 1000 / F->Speed) { S = F->Components; @@ -459,21 +494,14 @@ draw_ifs(ModeInfo * mi) void release_ifs(ModeInfo * mi) { - int i; + if (Root != NULL) { + int screen; - if (Root == NULL) - return; - - for (i = 0; i < MI_NUM_SCREENS(mi); ++i) { - if (Root[i].Buffer1 != NULL) - free(Root[i].Buffer1); - if (Root[i].Buffer2 != NULL) - free(Root[i].Buffer2); - if (Root[i].dbuf) - XFreePixmap(MI_DISPLAY(mi), Root[i].dbuf); - if (Root[i].dbuf_gc) - XFreeGC(MI_DISPLAY(mi), Root[i].dbuf_gc); + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_ifs(MI_DISPLAY(mi), &Root[screen]); + (void) free((void *) Root); + Root = (FRACTAL *) NULL; } - free(Root); - Root = NULL; } + +#endif /* MODE_ifs */