X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fanemone.c;h=652e4770659dd4fa780aa7dc65a0ddcdeece5deb;hp=630ea034bc144b4b4f300d6252eb5e6e195b6c94;hb=49f5b54f312fe4ac2e9bc47581a72451bd0e8439;hpb=ccb7f4903325f92555a9722bba74b58346654ba0 diff --git a/hacks/anemone.c b/hacks/anemone.c index 630ea034..652e4770 100644 --- a/hacks/anemone.c +++ b/hacks/anemone.c @@ -25,10 +25,6 @@ +----------------------------------------------------------------------*/ - -#include -#include -#include #include #include "screenhack.h" @@ -50,33 +46,12 @@ #define TRUE 1 #define FALSE 0 -static Display *dpy; -static Window window; - -static Pixmap b,ba,bb; - -#ifdef HAVE_DOUBLE_BUFFER_EXTENSION -static XdbeBackBuffer backb; -#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ - -static int -arms, /* number of arms */ - finpoints; /* final number of points in each array. */ -static long delay; /* usecs to wait between updates. */ - -static int scrWidth, scrHeight; -static GC gcDraw, gcClear; typedef struct { double x,y,z; int sx,sy,sz; } vPend; -typedef unsigned short bool; - -static bool dbuf; -static int width; - typedef struct { long col; int numpt; @@ -84,52 +59,47 @@ typedef struct { unsigned short rate; } appDef; -static vPend *vPendage; /* 3D representation of appendages */ -static appDef *appD; /* defaults */ -static vPend *vCurr, *vNext; -static appDef *aCurr; +struct state { + Display *dpy; + Pixmap b, ba, bb; -static double turn, turndelta; +#ifdef HAVE_DOUBLE_BUFFER_EXTENSION + XdbeBackBuffer backb; +#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ -static int mx, my; /* max screen coordinates. */ -static int withdraw; + int arms; /* number of arms */ + int finpoints; /* final number of points in each array. */ + long delay; /* usecs to wait between updates. */ -static XGCValues gcv; -static Colormap cmap; + int scrWidth, scrHeight; + GC gcDraw, gcClear; + Bool dbuf; + int width; + vPend *vPendage; /* 3D representation of appendages */ + appDef *appD; /* defaults */ + vPend *vCurr, *vNext; + appDef *aCurr; -/*-----------------------------------------------------------------------+ - | PUBLIC DATA | - +-----------------------------------------------------------------------*/ + double turn, turndelta; -char *progclass = "Anemone"; + int mx, my; /* max screen coordinates. */ + int withdraw; -char *defaults [] = { - ".background: black", - "*arms: 128", - "*width: 2", - "*finpoints: 64", - "*delay: 40000", - "*withdraw: 1200", - "*turnspeed: 50", -#ifdef HAVE_DOUBLE_BUFFER_EXTENSION - "*useDBE: True", -#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ - 0 + XGCValues gcv; + Colormap cmap; + XColor *colors; + int ncolors; }; -XrmOptionDescRec options [] = { - { "-arms", ".arms", XrmoptionSepArg, 0 }, - { "-finpoints", ".finpoints", XrmoptionSepArg, 0 }, - { "-delay", ".delay", XrmoptionSepArg, 0 }, - { "-width", ".width", XrmoptionSepArg, 0 }, - { "-withdraw", ".withdraw", XrmoptionSepArg, 0 }, - { "-turnspeed", ".turnspeed", XrmoptionSepArg, 0 }, - { 0, 0, 0, 0 } -}; -int options_size = (sizeof (options) / sizeof (options[0])); + +/*-----------------------------------------------------------------------+ + | PUBLIC DATA | + +-----------------------------------------------------------------------*/ + + /*-----------------------------------------------------------------------+ | PRIVATE FUNCTIONS | @@ -149,7 +119,7 @@ xmalloc(size_t size) static void -initAppendages(void) +initAppendages(struct state *st) { int i; /*int marginx, marginy; */ @@ -158,8 +128,8 @@ initAppendages(void) double x,y,z,dist; - mx = scrWidth - 1; - my = scrHeight - 1; + st->mx = st->scrWidth - 1; + st->my = st->scrHeight - 1; /* each appendage will have: colour, number of points, and a grow or shrink indicator */ @@ -168,129 +138,144 @@ initAppendages(void) /* each appendage needs virtual coords (x,y,z) with y and z combining to give the screen y */ - vPendage = (vPend *) xmalloc((finpoints + 1) * sizeof(vPend) * arms); - appD = (appDef *) xmalloc(sizeof(appDef) * arms); + st->vPendage = (vPend *) xmalloc((st->finpoints + 1) * sizeof(vPend) * st->arms); + st->appD = (appDef *) xmalloc(sizeof(appDef) * st->arms); - for (i = 0; i < arms; i++) { - aCurr = appD + i; - vCurr = vPendage + (finpoints + 1) * i; - vNext = vCurr + 1; + for (i = 0; i < st->arms; i++) { + st->aCurr = st->appD + i; + st->vCurr = st->vPendage + (st->finpoints + 1) * i; + st->vNext = st->vCurr + 1; - aCurr->col = (long)RND(256)*RND(256)+32768; - aCurr->numpt = 1; - aCurr->growth=finpoints/2+RND(finpoints/2); - aCurr->rate=RND(11)*RND(11); + st->aCurr->col = st->colors[random() % st->ncolors].pixel; + st->aCurr->numpt = 1; + st->aCurr->growth = st->finpoints / 2 + RND(st->finpoints / 2); + st->aCurr->rate = RND(11) * RND(11); - dist=1.; + dist = 1.; do { - x=(1-RND(1001)/500); - y=(1-RND(1001)/500); - z=(1-RND(1001)/500); - dist=x*x+y*y+z*z; - } while (dist>=1.); + x = (1 - RND(1001) / 500); + y = (1 - RND(1001) / 500); + z = (1 - RND(1001) / 500); + dist = x * x + y * y + z * z; + } while (dist >= 1.); - vCurr->x=x*200; - vCurr->y=my/2+y*200; - vCurr->z=0+z*200; + st->vCurr->x = x * 200; + st->vCurr->y = st->my / 2 + y * 200; + st->vCurr->z = 0 + z * 200; /* start the arm going outwards */ - vCurr->sx=vCurr->x/5; - vCurr->sy=(vCurr->y-my/2)/5; - vCurr->sz=(vCurr->z)/5; + st->vCurr->sx = st->vCurr->x / 5; + st->vCurr->sy = (st->vCurr->y - st->my / 2) / 5; + st->vCurr->sz = (st->vCurr->z) / 5; - vNext->x=vCurr->x+vCurr->sx; - vNext->y=vCurr->y+vCurr->sy; - vNext->z=vCurr->z+vCurr->sz; + st->vNext->x = st->vCurr->x + st->vCurr->sx; + st->vNext->y = st->vCurr->y + st->vCurr->sy; + st->vNext->z = st->vCurr->z + st->vCurr->sz; } } -static void -initAnemone(void) +static void * +anemone_init (Display *disp, Window window) { + struct state *st = (struct state *) calloc (1, sizeof(*st)); XWindowAttributes wa; - turn = 0.; + st->dpy = disp; + st->turn = 0.; - width = get_integer_resource("width", "Integer"); - arms = get_integer_resource("arms", "Integer"); - finpoints = get_integer_resource("finpoints", "Integer"); - delay = get_integer_resource("delay", "Integer"); - withdraw = get_integer_resource("withdraw", "Integer"); - turndelta = get_float_resource("turnspeed", "float")/100000; + st->width = get_integer_resource(st->dpy, "width", "Integer"); + st->arms = get_integer_resource(st->dpy, "arms", "Integer"); + st->finpoints = get_integer_resource(st->dpy, "finpoints", "Integer"); + st->delay = get_integer_resource(st->dpy, "delay", "Integer"); + st->withdraw = get_integer_resource(st->dpy, "withdraw", "Integer"); + st->turndelta = get_float_resource(st->dpy, "turnspeed", "float") / 100000; - dbuf=TRUE; + st->dbuf = TRUE; +# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */ + st->dbuf = False; +# endif - b=ba=bb=0; /* double-buffer to reduce flicker */ + st->b = st->ba = st->bb = 0; /* double-buffer to reduce flicker */ #ifdef HAVE_DOUBLE_BUFFER_EXTENSION - b = backb = xdbe_get_backbuffer (dpy, window, XdbeUndefined); + st->b = st->backb = xdbe_get_backbuffer (st->dpy, window, XdbeUndefined); #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ - XGetWindowAttributes(dpy, window, &wa); - scrWidth = wa.width; - scrHeight = wa.height; - cmap = wa.colormap; - gcDraw = XCreateGC(dpy, window, GCForeground, &gcv); - gcv.foreground = get_pixel_resource("background", "Background", dpy, cmap); - gcClear = XCreateGC(dpy, window, GCForeground, &gcv); + XGetWindowAttributes(st->dpy, window, &wa); + st->scrWidth = wa.width; + st->scrHeight = wa.height; + st->cmap = wa.colormap; + + st->ncolors = get_integer_resource (st->dpy, "colors", "Colors"); + st->ncolors += 3; + st->colors = (XColor *) malloc(sizeof(*st->colors) * (st->ncolors+1)); + make_smooth_colormap (st->dpy, wa.visual, st->cmap, st->colors, &st->ncolors, + True, 0, True); - if (dbuf) { - if (!b) + st->gcDraw = XCreateGC(st->dpy, window, 0, &st->gcv); + st->gcv.foreground = get_pixel_resource(st->dpy, st->cmap, + "background", "Background"); + st->gcClear = XCreateGC(st->dpy, window, GCForeground, &st->gcv); + + if (st->dbuf) { + if (!st->b) { - ba = XCreatePixmap (dpy, window, scrWidth, scrHeight, wa.depth); - bb = XCreatePixmap (dpy, window, scrWidth, scrHeight, wa.depth); - b = ba; + st->ba = XCreatePixmap (st->dpy, window, st->scrWidth, st->scrHeight, wa.depth); + st->bb = XCreatePixmap (st->dpy, window, st->scrWidth, st->scrHeight, wa.depth); + st->b = st->ba; } } else { - b = window; + st->b = window; } - if (ba) XFillRectangle (dpy, ba, gcClear, 0, 0, scrWidth, scrHeight); - if (bb) XFillRectangle (dpy, bb, gcClear, 0, 0, scrWidth, scrHeight); + if (st->ba) XFillRectangle (st->dpy, st->ba, st->gcClear, 0, 0, st->scrWidth, st->scrHeight); + if (st->bb) XFillRectangle (st->dpy, st->bb, st->gcClear, 0, 0, st->scrWidth, st->scrHeight); + + XClearWindow(st->dpy, window); + XSetLineAttributes(st->dpy, st->gcDraw, st->width, LineSolid, CapRound, JoinBevel); - XClearWindow(dpy, window); - XSetLineAttributes(dpy, gcDraw, width, LineSolid, CapRound, JoinBevel); + initAppendages(st); - initAppendages(); + return st; } static void -createPoints(void) +createPoints(struct state *st) { int i; - int withdrawall=RND(withdraw); + int withdrawall = RND(st->withdraw); - for (i = 0; i< arms; i++) { - aCurr = appD + i; + for (i = 0; i< st->arms; i++) { + st->aCurr = st->appD + i; if (!withdrawall) { - aCurr->growth=-finpoints; - turndelta=-turndelta; + st->aCurr->growth = -st->finpoints; + st->turndelta = -st->turndelta; } - else if (withdrawall<11) aCurr->growth=-aCurr->numpt; + else if (withdrawall<11) st->aCurr->growth = -st->aCurr->numpt; - else if (RND(100)rate) { - if (aCurr->growth>0) { - if (!(--aCurr->growth)) aCurr->growth=-RND(finpoints)-1; - vCurr = vPendage + (finpoints + 1) * i + aCurr->numpt-1; - if (aCurr->numptaCurr->rate) { + if (st->aCurr->growth>0) { + if (!(--st->aCurr->growth)) st->aCurr->growth = -RND(st->finpoints) - 1; + st->vCurr = st->vPendage + (st->finpoints + 1) * i + st->aCurr->numpt - 1; + if (st->aCurr->numptfinpoints - 1) { /* add a piece */ - vNext=vCurr + 1; - aCurr->numpt++; - vNext->sx=vCurr->sx+RND(3)-1; - vNext->sy=vCurr->sy+RND(3)-1; - vNext->sz=vCurr->sz+RND(3)-1; - vCurr=vNext+1; - vCurr->x=vNext->x+vNext->sx; - vCurr->y=vNext->y+vNext->sy; - vCurr->z=vNext->z+vNext->sz; + st->vNext = st->vCurr + 1; + st->aCurr->numpt++; + st->vNext->sx = st->vCurr->sx + RND(3) - 1; + st->vNext->sy = st->vCurr->sy + RND(3) - 1; + st->vNext->sz = st->vCurr->sz + RND(3) - 1; + st->vCurr = st->vNext + 1; + st->vCurr->x = st->vNext->x + st->vNext->sx; + st->vCurr->y = st->vNext->y + st->vNext->sy; + st->vCurr->z = st->vNext->z + st->vNext->sz; } } } @@ -299,116 +284,154 @@ createPoints(void) static void -drawImage(Drawable curr_window, double sint, double cost) +drawImage(struct state *st, Drawable curr_window, double sint, double cost) { - int q,numpt,mx2=mx/2; - double cx,cy,cz,nx=0,ny=0,nz=0; + int q,numpt,mx2 = st->mx / 2; + double cx,cy,cz,nx = 0,ny = 0,nz = 0; - if ((numpt=aCurr->numpt)==1) return; - XSetForeground(dpy, gcDraw, aCurr->col); + if ((numpt = st->aCurr->numpt)==1) return; + XSetForeground(st->dpy, st->gcDraw, st->aCurr->col); - vNext=vCurr+1; + st->vNext = st->vCurr + 1; - cx=vCurr->x; - cy=vCurr->y; - cz=vCurr->z; + cx = st->vCurr->x; + cy = st->vCurr->y; + cz = st->vCurr->z; - for (q = 0; q < numpt-1; q++) { - nx=vNext->x+2-RND(5); - ny=vNext->y+2-RND(5); - nz=vNext->z+2-RND(5); + for (q = 0; q < numpt - 1; q++) { + nx = st->vNext->x + 2 - RND(5); + ny = st->vNext->y + 2 - RND(5); + nz = st->vNext->z + 2 - RND(5); - XDrawLine(dpy, curr_window, gcDraw,mx2+cx*cost-cz*sint, cy, mx2+nx*cost-nz*sint, ny); - vCurr++; - vNext++; + XDrawLine(st->dpy, curr_window, st->gcDraw, + mx2 + cx * cost - cz * sint, cy, + mx2 + nx * cost - nz * sint, ny); + st->vCurr++; + st->vNext++; - cx=nx; - cy=ny; - cz=nz; + cx = nx; + cy = ny; + cz = nz; } - XSetLineAttributes(dpy, gcDraw, width*3, LineSolid, CapRound, JoinBevel); - XDrawLine(dpy, curr_window, gcDraw,mx/2+cx*cost-cz*sint, cy, mx/2+nx*cost-nz*sint, ny); - XSetLineAttributes(dpy, gcDraw, width, LineSolid, CapRound, JoinBevel); + XSetLineAttributes(st->dpy, st->gcDraw, st->width * 3, + LineSolid, CapRound, JoinBevel); + XDrawLine(st->dpy, curr_window, st->gcDraw, + st->mx / 2 + cx * cost - cz * sint, cy, + st->mx / 2 + nx * cost - nz * sint, ny); + XSetLineAttributes(st->dpy, st->gcDraw, st->width, + LineSolid, CapRound, JoinBevel); } static void -animateAnemone(Drawable curr_window) +animateAnemone(struct state *st, Drawable curr_window) { int i; - double sint=sin(turn),cost=cos(turn); - - aCurr = appD; - for (i = 0; i< arms; i++) { - vCurr=vPendage + (finpoints + 1) * i; - if (RND(25)rate) { - if (aCurr->growth<0) { - aCurr->numpt-=aCurr->numpt>1; - if (!(++aCurr->growth)) aCurr->growth=RND(finpoints-aCurr->numpt)+1; + double sint = sin(st->turn),cost = cos(st->turn); + + st->aCurr = st->appD; + for (i = 0; i< st->arms; i++) { + st->vCurr = st->vPendage + (st->finpoints + 1) * i; + if (RND(25)aCurr->rate) { + if (st->aCurr->growth<0) { + st->aCurr->numpt -= st->aCurr->numpt>1; + if (!(++st->aCurr->growth)) st->aCurr->growth = RND(st->finpoints - st->aCurr->numpt) + 1; } } - drawImage(curr_window, sint, cost); - turn+=turndelta; - aCurr++; + drawImage(st, curr_window, sint, cost); + st->turn += st->turndelta; + st->aCurr++; } - createPoints(); - usleep(delay); + createPoints(st); - if (turn>=TWO_PI) turn-=TWO_PI; + if (st->turn >= TWO_PI) st->turn -= TWO_PI; } -/*-----------------------------------------------------------------------+ - | PUBLIC FUNCTIONS | - +-----------------------------------------------------------------------*/ - -void -screenhack(Display *disp, Window win) +static unsigned long +anemone_draw (Display *dpy, Window window, void *closure) { + struct state *st = (struct state *) closure; - dpy=disp; - window=win; - - initAnemone(); - for (;;) { + XFillRectangle (st->dpy, st->b, st->gcClear, 0, 0, st->scrWidth, st->scrHeight); - XFillRectangle (dpy, b, gcClear, 0, 0, scrWidth, scrHeight); - - animateAnemone(b); + animateAnemone(st, st->b); #ifdef HAVE_DOUBLE_BUFFER_EXTENSION - if (backb) + if (st->backb) { XdbeSwapInfo info[1]; info[0].swap_window = window; info[0].swap_action = XdbeUndefined; - XdbeSwapBuffers (dpy, info, 1); + XdbeSwapBuffers (st->dpy, info, 1); } else #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ - if (dbuf) + if (st->dbuf) { - XCopyArea (dpy, b, window, gcClear, 0, 0, - scrWidth, scrHeight, 0, 0); - b = (b == ba ? bb : ba); + XCopyArea (st->dpy, st->b, window, st->gcClear, 0, 0, + st->scrWidth, st->scrHeight, 0, 0); + st->b = (st->b == st->ba ? st->bb : st->ba); } - screenhack_handle_events (dpy); - } - + return st->delay; } +static void +anemone_reshape (Display *dpy, Window window, void *closure, + unsigned int w, unsigned int h) +{ + /* need to re-make pixmaps too... + struct state *st = (struct state *) closure; + st->scrWidth = w; + st->scrHeight = h; + */ +} +static Bool +anemone_event (Display *dpy, Window window, void *closure, XEvent *event) +{ + return False; +} +static void +anemone_free (Display *dpy, Window window, void *closure) +{ + struct state *st = (struct state *) closure; + if (st->vPendage) free (st->vPendage); + if (st->appD) free (st->appD); + free (st); +} +static const char *anemone_defaults [] = { + ".background: black", + "*arms: 128", + "*width: 2", + "*finpoints: 64", + "*delay: 40000", + "*withdraw: 1200", + "*turnspeed: 50", + "*colors: 20", +#ifdef HAVE_DOUBLE_BUFFER_EXTENSION + "*useDBE: True", +#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ + 0 +}; +static XrmOptionDescRec anemone_options [] = { + { "-arms", ".arms", XrmoptionSepArg, 0 }, + { "-finpoints", ".finpoints", XrmoptionSepArg, 0 }, + { "-delay", ".delay", XrmoptionSepArg, 0 }, + { "-width", ".width", XrmoptionSepArg, 0 }, + { "-withdraw", ".withdraw", XrmoptionSepArg, 0 }, + { "-turnspeed", ".turnspeed", XrmoptionSepArg, 0 }, + { "-colors", ".colors", XrmoptionSepArg, 0 }, + { 0, 0, 0, 0 } +}; - - - - +XSCREENSAVER_MODULE ("Anemone", anemone)