X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fwhirlwindwarp.c;h=d76d5ed250c39746a0bdc9e89a0155cf63232d2c;hp=74d0ab84f4fb44439b3dd496dd7c760c81c010fe;hb=49f5b54f312fe4ac2e9bc47581a72451bd0e8439;hpb=ccb7f4903325f92555a9722bba74b58346654ba0 diff --git a/hacks/whirlwindwarp.c b/hacks/whirlwindwarp.c index 74d0ab84..d76d5ed2 100644 --- a/hacks/whirlwindwarp.c +++ b/hacks/whirlwindwarp.c @@ -38,62 +38,79 @@ #include "erase.h" #include "hsv.h" -static GC draw_gc, erase_gc; -static unsigned int default_fg_pixel; - /* Maximum number of points, maximum tail length, and the number of forcefields/effects (hard-coded) */ #define maxps 1000 #define maxts 50 #define fs 16 /* TODO: change ps and ts arrays into pointers, for dynamic allocation at runtime. */ -/* Screen width and height */ -static int scrwid,scrhei; -static int starsize; - -/* Current x,y of stars in realspace */ -static float cx[maxps]; -static float cy[maxps]; -/* Previous x,y plots in pixelspace for removal later */ -static int tx[maxps*maxts]; -static int ty[maxps*maxts]; -/* The force fields and their parameters */ -static char *name[fs]; -static int fon[fs]; /* Is field on or off? */ -static float var[fs]; /* Current parameter */ -static float op[fs]; /* Optimum (central/mean) value */ -/* These have now become standardised across all forcefields: - static float damp[fs]; / * Dampening (how much drawn between current and optimal) * / - static float force[fs]; / * Amount of change per moment * / -*/ -static float acc[fs]; -static float vel[fs]; - -/* Number of points and tail length */ -static int ps=500; -static int ts=5; - -/* Show meters or not? */ -static Bool meters; - -static Bool init_whirlwindwarp(Display *dpy, Window window) +struct state { + Display *dpy; + Window window; + + GC draw_gc, erase_gc; + unsigned int default_fg_pixel; + + int scrwid,scrhei; + int starsize; + + float cx[maxps]; /* Current x,y of stars in realspace */ + float cy[maxps]; + int tx[maxps*maxts]; /* Previous x,y plots in pixelspace for removal later */ + int ty[maxps*maxts]; + char *name[fs]; /* The force fields and their parameters */ + + int fon[fs]; /* Is field on or off? */ + float var[fs]; /* Current parameter */ + float op[fs]; /* Optimum (central/mean) value */ + float acc[fs]; + float vel[fs]; + + int ps; /* Number of points and tail length */ + int ts; + + Bool meters; + + int initted; + XWindowAttributes xgwa; + int got_color; + XColor color[maxps]; /* The colour assigned to each star */ + XColor bgcolor; + int p,f,nt, sx,sy, resets,lastresets,cnt; + int colsavailable; + int hue; + + struct timeval lastframe; +}; + + +static void * +whirlwindwarp_init (Display *dpy, Window window) { + struct state *st = (struct state *) calloc (1, sizeof(*st)); XGCValues gcv; Colormap cmap; - XWindowAttributes xgwa; - XGetWindowAttributes (dpy, window, &xgwa); - cmap = xgwa.colormap; - gcv.foreground = default_fg_pixel = get_pixel_resource ("foreground", "Foreground", dpy, cmap); - draw_gc = XCreateGC (dpy, window, GCForeground, &gcv); - gcv.foreground = get_pixel_resource ("background", "Background", dpy, cmap); - erase_gc = XCreateGC (dpy, window, GCForeground, &gcv); - - ps = get_integer_resource ("points", "Integer"); - ts = get_integer_resource ("tails", "Integer"); - meters = get_boolean_resource ("meters", "Show meters"); - if (ps>maxps || ts>maxts) - return 0; - return 1; + + st->dpy = dpy; + st->window = window; + + st->ps=500; + st->ts=5; + + XGetWindowAttributes (st->dpy, st->window, &st->xgwa); + cmap = st->xgwa.colormap; + gcv.foreground = st->default_fg_pixel = get_pixel_resource (st->dpy, cmap, "foreground", "Foreground"); + st->draw_gc = XCreateGC (st->dpy, st->window, GCForeground, &gcv); + gcv.foreground = get_pixel_resource (st->dpy, cmap, "background", "Background"); + st->erase_gc = XCreateGC (st->dpy, st->window, GCForeground, &gcv); + + st->ps = get_integer_resource (st->dpy, "points", "Integer"); + st->ts = get_integer_resource (st->dpy, "tails", "Integer"); + st->meters = get_boolean_resource (st->dpy, "meters", "Show meters"); + if (st->ps > maxps) st->ps = maxps; + if (st->ts > maxts) st->ts = maxts; + + return st; } static float myrnd(void) @@ -101,17 +118,19 @@ static float myrnd(void) return 2.0*((float)((random()%10000000)/10000000.0)-0.5); } -float mysgn(float x) +#if 0 +static float mysgn(float x) { return ( x < 0 ? -1 : x > 0 ? +1 : 0 ); } +#endif -void stars_newp(int p) +static void stars_newp(struct state *st, int pp) { - cx[p]=myrnd(); - cy[p]=myrnd(); + st->cx[pp]=myrnd(); + st->cy[pp]=myrnd(); } /* Adjust a variable var about optimum op, @@ -124,40 +143,40 @@ void stars_newp(int p) ( (op) + (damp)*((var)-(op)) + (force)*myrnd()/4.0 ) /* Get pixel coordinates of a star */ -int stars_scrpos_x(int p) +static int stars_scrpos_x(struct state *st, int pp) { - return scrwid*(cx[p]+1.0)/2.0; + return st->scrwid*(st->cx[pp]+1.0)/2.0; } -int stars_scrpos_y(int p) +static int stars_scrpos_y(struct state *st, int pp) { - return scrhei*(cy[p]+1.0)/2.0; + return st->scrhei*(st->cy[pp]+1.0)/2.0; } /* Draw a meter of a forcefield's parameter */ -void stars_draw_meter(Display *dpy,Window window,GC draw_gc,int f) +static void stars_draw_meter(struct state *st, int ff) { int x,y,w,h; - x=scrwid/2; - y=f*10; - w=(var[f]-op[f])*scrwid*4; + x=st->scrwid/2; + y=ff*10; + w=(st->var[ff]-st->op[ff])*st->scrwid*4; h=7; if (w<0) { w=-w; x=x-w; } - if (fon[f]) - XFillRectangle(dpy,window,draw_gc,x,y,w,h); + if (st->fon[ff]) + XFillRectangle(st->dpy,st->window,st->draw_gc,x,y,w,h); /* else XDrawRectangle(dpy,window,draw_gc,x,y,w,h); */ } /* Move a star according to acting forcefields */ -void stars_move(int p) +static void stars_move(struct state *st, int pp) { float nx,ny; - float x=cx[p]; - float y=cy[p]; + float x=st->cx[pp]; + float y=st->cy[pp]; /* In theory all these if checks are unneccessary, since each forcefield effect should do nothing when its var = op. @@ -167,288 +186,300 @@ void stars_move(int p) Squirge towards edges (makes a leaf shape, previously split the screen in 4 but now only 1 :) These ones must go first, to avoid x+1.0 < 0 */ - if (fon[6]) { + if (st->fon[6]) { /* x = mysgn(x) * pow(fabs(x),var[6]); y = mysgn(y) * pow(fabs(y),var[6]);*/ - x = -1.0 + 2.0*pow((x + 1.0)/2.0,var[6]); + x = -1.0 + 2.0*pow((x + 1.0)/2.0,st->var[6]); } - if (fon[7]) { - y = -1.0 + 2.0*pow((y + 1.0)/2.0,var[7]); + if (st->fon[7]) { + y = -1.0 + 2.0*pow((y + 1.0)/2.0,st->var[7]); } /* Warping in/out */ - if (fon[1]) { - x = x * var[1]; y = y * var[1]; + if (st->fon[1]) { + x = x * st->var[1]; y = y * st->var[1]; } /* Rotation */ - if (fon[2]) { - nx=x*cos(1.1*var[2])+y*sin(1.1*var[2]); - ny=-x*sin(1.1*var[2])+y*cos(1.1*var[2]); + if (st->fon[2]) { + nx=x*cos(1.1*st->var[2])+y*sin(1.1*st->var[2]); + ny=-x*sin(1.1*st->var[2])+y*cos(1.1*st->var[2]); x=nx; y=ny; } /* Asymptotes (looks like a plane with a horizon; equivalent to 1D warp) */ - if (fon[3]) { /* Horizontal asymptote */ - y=y*var[3]; + if (st->fon[3]) { /* Horizontal asymptote */ + y=y*st->var[3]; } - if (fon[4]) { /* Vertical asymptote */ - x=x+var[4]*x; /* this is the same maths as the last, but with op=0 */ + if (st->fon[4]) { /* Vertical asymptote */ + x=x+st->var[4]*x; /* this is the same maths as the last, but with op=0 */ } - if (fon[5]) { /* Vertical asymptote at right of screen */ - x=(x-1.0)*var[5]+1.0; + if (st->fon[5]) { /* Vertical asymptote at right of screen */ + x=(x-1.0)*st->var[5]+1.0; } /* Splitting (whirlwind effect): */ - #define num_splits ( 2 + (int) (fabs(var[0]) * 1000) ) - /* #define thru ( (float)(p%num_splits)/(float)(num_splits-1) ) */ - #define thru ( (float)((int)(num_splits*(float)(p)/(float)(ps)))/(float)(num_splits-1) ) - if (fon[8]) { - x=x+0.5*var[8]*(-1.0+2.0*thru); + #define num_splits ( 2 + (int) (fabs(st->var[0]) * 1000) ) + /* #define thru ( (float)(pp%num_splits)/(float)(num_splits-1) ) */ + #define thru ( (float)((int)(num_splits*(float)(pp)/(float)(st->ps)))/(float)(num_splits-1) ) + if (st->fon[8]) { + x=x+0.5*st->var[8]*(-1.0+2.0*thru); } - if (fon[9]) { - y=y+0.5*var[9]*(-1.0+2.0*thru); + if (st->fon[9]) { + y=y+0.5*st->var[9]*(-1.0+2.0*thru); } /* Waves */ - if (fon[10]) { - y = y + 0.4*var[10]*sin(300.0*var[12]*x + 600.0*var[11]); + if (st->fon[10]) { + y = y + 0.4*st->var[10]*sin(300.0*st->var[12]*x + 600.0*st->var[11]); } - if (fon[13]) { - x = x + 0.4*var[13]*sin(300.0*var[15]*y + 600.0*var[14]); + if (st->fon[13]) { + x = x + 0.4*st->var[13]*sin(300.0*st->var[15]*y + 600.0*st->var[14]); } - cx[p]=x; - cy[p]=y; + st->cx[pp]=x; + st->cy[pp]=y; } /* Turns a forcefield on, and ensures its vars are suitable. */ -void turn_on_field(int f) +static void turn_on_field(struct state *st, int ff) { - if (!fon[f]) { - /* acc[f]=0.0; */ - acc[f]=0.02 * myrnd(); - vel[f]=0.0; - var[f]=op[f]; + if (!st->fon[ff]) { + /* acc[ff]=0.0; */ + st->acc[ff]=0.02 * myrnd(); + st->vel[ff]=0.0; + st->var[ff]=st->op[ff]; } - fon[f] = 1; - if (f == 10) { - turn_on_field(11); - turn_on_field(12); + st->fon[ff] = 1; + if (ff == 10) { + turn_on_field(st, 11); + turn_on_field(st, 12); } - if (f == 13) { - turn_on_field(14); - turn_on_field(15); + if (ff == 13) { + turn_on_field(st, 14); + turn_on_field(st, 15); } } -static void do_whirlwindwarp(Display *dpy, Window window) +static unsigned long +whirlwindwarp_draw (Display *dpy, Window window, void *closure) { - Colormap cmap; - XWindowAttributes xgwa; - int got_color = 0; - XColor color[maxps]; /* The colour assigned to each star */ - XColor bgcolor; - int p,f,nt, sx,sy, resets,lastresets,cnt; - int colsavailable; - int hue; + struct state *st = (struct state *) closure; /* time_t lastframe = time((time_t) 0); */ - struct timeval lastframe; - XClearWindow (dpy, window); - XGetWindowAttributes (dpy, window, &xgwa); - cmap = xgwa.colormap; - scrwid = xgwa.width; - scrhei = xgwa.height; - - starsize=scrhei/480; - if (starsize<=0) - starsize=1; - - /* Setup colours */ - hsv_to_rgb (0.0, 0.0, 0.0, &bgcolor.red, &bgcolor.green, &bgcolor.blue); - got_color = XAllocColor (dpy, cmap, &bgcolor); - colsavailable=0; - for (p=0;p0) /* assign colours from those already allocated */ - color[p]=color[ p % colsavailable ]; - else - color[p].pixel=default_fg_pixel; - } - } + if (!st->initted) { + st->initted = 1; + + XClearWindow (st->dpy, st->window); + XGetWindowAttributes (st->dpy, st->window, &st->xgwa); + st->scrwid = st->xgwa.width; + st->scrhei = st->xgwa.height; + + st->starsize=st->scrhei/480; + if (st->starsize<=0) + st->starsize=1; + + /* Setup colours */ + hsv_to_rgb (0.0, 0.0, 0.0, &st->bgcolor.red, &st->bgcolor.green, &st->bgcolor.blue); + st->got_color = XAllocColor (st->dpy, st->xgwa.colormap, &st->bgcolor); + st->colsavailable=0; + for (st->p=0;st->pps;st->p++) { + if (!mono_p) + hsv_to_rgb (random()%360, .6+.4*myrnd(), .6+.4*myrnd(), &st->color[st->p].red, &st->color[st->p].green, &st->color[st->p].blue); + /* hsv_to_rgb (random()%360, 1.0, 1.0, &color[p].red, &color[p].green, &color[p].blue); for stronger colours! */ + if ((!mono_p) && (st->got_color = XAllocColor (st->dpy, st->xgwa.colormap, &st->color[st->p]))) { + st->colsavailable=st->p; + } else { + if (st->colsavailable>0) /* assign colours from those already allocated */ + st->color[st->p]=st->color[ st->p % st->colsavailable ]; + else + st->color[st->p].pixel=st->default_fg_pixel; + } + } /* Set up central (optimal) points for each different forcefield */ - op[1] = 1; name[1] = "Warp"; - op[2] = 0; name[2] = "Rotation"; - op[3] = 1; name[3] = "Horizontal asymptote"; - op[4] = 0; name[4] = "Vertical asymptote"; - op[5] = 1; name[5] = "Vertical asymptote right"; - op[6] = 1; name[6] = "Squirge x"; - op[7] = 1; name[7] = "Squirge y"; - op[0] = 0; name[0] = "Split number (inactive)"; - op[8] = 0; name[8] = "Split velocity x"; - op[9] = 0; name[9] = "Split velocity y"; - op[10] = 0; name[10] = "Horizontal wave amplitude"; - op[11] = myrnd()*3.141; name[11] = "Horizontal wave phase (inactive)"; - op[12] = 0.01; name[12] = "Horizontal wave frequency (inactive)"; - op[13] = 0; name[13] = "Vertical wave amplitude"; - op[14] = myrnd()*3.141; name[14] = "Vertical wave phase (inactive)"; - op[15] = 0.01; name[15] = "Vertical wave frequency (inactive)"; + st->op[1] = 1; st->name[1] = "Warp"; + st->op[2] = 0; st->name[2] = "Rotation"; + st->op[3] = 1; st->name[3] = "Horizontal asymptote"; + st->op[4] = 0; st->name[4] = "Vertical asymptote"; + st->op[5] = 1; st->name[5] = "Vertical asymptote right"; + st->op[6] = 1; st->name[6] = "Squirge x"; + st->op[7] = 1; st->name[7] = "Squirge y"; + st->op[0] = 0; st->name[0] = "Split number (inactive)"; + st->op[8] = 0; st->name[8] = "Split velocity x"; + st->op[9] = 0; st->name[9] = "Split velocity y"; + st->op[10] = 0; st->name[10] = "Horizontal wave amplitude"; + st->op[11] = myrnd()*3.141; st->name[11] = "Horizontal wave phase (inactive)"; + st->op[12] = 0.01; st->name[12] = "Horizontal wave frequency (inactive)"; + st->op[13] = 0; st->name[13] = "Vertical wave amplitude"; + st->op[14] = myrnd()*3.141; st->name[14] = "Vertical wave phase (inactive)"; + st->op[15] = 0.01; st->name[15] = "Vertical wave frequency (inactive)"; /* Initialise parameters to optimum, all off */ - for (f=0;f0.5 ? 1 : 0 ); - acc[f]=0.02 * myrnd(); - vel[f]=0; + for (st->f=0;st->ff++) { + st->var[st->f]=st->op[st->f]; + st->fon[st->f]=( myrnd()>0.5 ? 1 : 0 ); + st->acc[st->f]=0.02 * myrnd(); + st->vel[st->f]=0; } /* Initialise stars */ - for (p=0;pp=0;st->pps;st->p++) + stars_newp(st, st->p); /* tx[nt],ty[nt] remember earlier screen plots (tails of stars) which are deleted when nt comes round again */ - nt = 0; - resets = 0; + st->nt = 0; + st->resets = 0; - hue = 180 + 180*myrnd(); + st->hue = 180 + 180*myrnd(); - gettimeofday(&lastframe, NULL); + gettimeofday(&st->lastframe, NULL); + + } - while (1) { if (myrnd()>0.75) { /* Change one of the allocated colours to something near the current hue. */ /* By changing a random colour, we sometimes get a tight colour spread, sometime a diverse one. */ - int p = colsavailable * (0.5+myrnd()/2); - hsv_to_rgb (hue, .6+.4*myrnd(), .6+.4*myrnd(), &color[p].red, &color[p].green, &color[p].blue); - if ((!mono_p) && (got_color = XAllocColor (dpy, cmap, &color[p]))) { + int pp = st->colsavailable * (0.5+myrnd()/2); + hsv_to_rgb (st->hue, .6+.4*myrnd(), .6+.4*myrnd(), &st->color[pp].red, &st->color[pp].green, &st->color[pp].blue); + if ((!mono_p) && (st->got_color = XAllocColor (st->dpy, st->xgwa.colormap, &st->color[pp]))) { } - hue = hue + 0.5 + myrnd()*9.0; - if (hue<0) hue+=360; - if (hue>=360) hue-=360; + st->hue = st->hue + 0.5 + myrnd()*9.0; + if (st->hue<0) st->hue+=360; + if (st->hue>=360) st->hue-=360; } /* Move current points */ - lastresets=resets; - resets=0; - for (p=0;plastresets=st->resets; + st->resets=0; + for (st->p=0;st->pps;st->p++) { /* Erase old */ - XSetForeground (dpy, draw_gc, bgcolor.pixel); + XSetForeground (st->dpy, st->draw_gc, st->bgcolor.pixel); /* XDrawPoint(dpy,window,draw_gc,tx[nt],ty[nt]); */ - XFillRectangle(dpy,window,draw_gc,tx[nt],ty[nt],starsize,starsize); + XFillRectangle(st->dpy,st->window,st->draw_gc,st->tx[st->nt],st->ty[st->nt],st->starsize,st->starsize); /* Move */ - stars_move(p); + stars_move(st, st->p); /* If moved off screen, create a new one */ - if (cx[p]<=-0.9999 || cx[p]>=+0.9999 || - cy[p]<=-0.9999 || cy[p]>=+0.9999 || - fabs(cx[p])<.0001 || fabs(cy[p])<.0001) { - stars_newp(p); - resets++; + if (st->cx[st->p]<=-0.9999 || st->cx[st->p]>=+0.9999 || + st->cy[st->p]<=-0.9999 || st->cy[st->p]>=+0.9999 || + fabs(st->cx[st->p])<.0001 || fabs(st->cy[st->p])<.0001) { + stars_newp(st, st->p); + st->resets++; } else if (myrnd()>0.99) /* Reset at random */ - stars_newp(p); + stars_newp(st, st->p); /* Draw point */ - sx=stars_scrpos_x(p); - sy=stars_scrpos_y(p); - XSetForeground (dpy, draw_gc, color[p].pixel); + st->sx=stars_scrpos_x(st, st->p); + st->sy=stars_scrpos_y(st, st->p); + XSetForeground (st->dpy, st->draw_gc, st->color[st->p].pixel); /* XDrawPoint(dpy,window,draw_gc,sx,sy); */ - XFillRectangle(dpy,window,draw_gc,sx,sy,starsize,starsize); + XFillRectangle(st->dpy,st->window,st->draw_gc,st->sx,st->sy,st->starsize,st->starsize); /* Remember it for removal later */ - tx[nt]=sx; - ty[nt]=sy; - nt=(nt+1)%(ps*ts); + st->tx[st->nt]=st->sx; + st->ty[st->nt]=st->sy; + st->nt=(st->nt+1)%(st->ps*st->ts); } /* Adjust force fields */ - cnt=0; - for (f=0;fcnt=0; + for (st->f=0;st->ff++) { - if (meters) { /* Remove meter from display */ - XSetForeground(dpy, draw_gc, bgcolor.pixel); - stars_draw_meter(dpy,window,draw_gc,f); + if (st->meters) { /* Remove meter from display */ + XSetForeground(st->dpy, st->draw_gc, st->bgcolor.pixel); + stars_draw_meter(st,st->f); } /* Adjust forcefield's parameter */ - if (fon[f]) { + if (st->fon[st->f]) { /* This configuration produces var[f]s usually below 0.01 */ - acc[f]=stars_perturb(acc[f],0,0.98,0.005); - vel[f]=stars_perturb(vel[f]+0.03*acc[f],0,0.995,0.0); - var[f]=op[f]+(var[f]-op[f])*0.9995+0.001*vel[f]; + st->acc[st->f]=stars_perturb(st->acc[st->f],0,0.98,0.005); + st->vel[st->f]=stars_perturb(st->vel[st->f]+0.03*st->acc[st->f],0,0.995,0.0); + st->var[st->f]=st->op[st->f]+(st->var[st->f]-st->op[st->f])*0.9995+0.001*st->vel[st->f]; } /* fprintf(stderr,"f=%i fon=%i acc=%f vel=%f var=%f\n",f,fon[f],acc[f],vel[f],var[f]); */ /* Decide whether to turn this forcefield on or off. */ /* prob_on makes the "splitting" effects less likely than the rest */ - #define prob_on ( f==8 || f==9 ? 0.999975 : 0.9999 ) - if ( fon[f]==0 && myrnd()>prob_on ) { - turn_on_field(f); - } else if ( fon[f]!=0 && myrnd()>0.99 && fabs(var[f]-op[f])<0.0005 && fabs(vel[f])<0.005 /* && fabs(acc[f])<0.01 */ ) { + #define prob_on ( st->f==8 || st->f==9 ? 0.999975 : 0.9999 ) + if ( st->fon[st->f]==0 && myrnd()>prob_on ) { + turn_on_field(st, st->f); + } else if ( st->fon[st->f]!=0 && myrnd()>0.99 && fabs(st->var[st->f]-st->op[st->f])<0.0005 && fabs(st->vel[st->f])<0.005 /* && fabs(acc[f])<0.01 */ ) { /* We only turn it off if it has gently returned to its optimal (as opposed to rapidly passing through it). */ - fon[f] = 0; + st->fon[st->f] = 0; } - if (meters) { /* Redraw the meter */ - XSetForeground(dpy, draw_gc, color[f].pixel); - stars_draw_meter(dpy,window,draw_gc,f); + if (st->meters) { /* Redraw the meter */ + XSetForeground(st->dpy, st->draw_gc, st->color[st->f].pixel); + stars_draw_meter(st,st->f); } - if (fon[f]) - cnt++; + if (st->fon[st->f]) + st->cnt++; } /* Ensure at least three forcefields are on. * BUG: Picking randomly might not be enough since 0,11,12,14 and 15 do nothing! * But then what's wrong with a rare gentle twinkle?! */ - if (cnt<3) { - f=random() % fs; - turn_on_field(f); + if (st->cnt<3) { + st->f=random() % fs; + turn_on_field(st, st->f); } - if (meters) { - XSetForeground(dpy, draw_gc, bgcolor.pixel); - XDrawRectangle(dpy,window,draw_gc,0,0,lastresets*5,3); - XSetForeground(dpy, draw_gc, default_fg_pixel); - XDrawRectangle(dpy,window,draw_gc,0,0,resets*5,3); + if (st->meters) { + XSetForeground(st->dpy, st->draw_gc, st->bgcolor.pixel); + XDrawRectangle(st->dpy,st->window,st->draw_gc,0,0,st->lastresets*5,3); + XSetForeground(st->dpy, st->draw_gc, st->default_fg_pixel); + XDrawRectangle(st->dpy,st->window,st->draw_gc,0,0,st->resets*5,3); } /* Cap frames per second; do not go above specified fps: */ { + unsigned long this_delay = 0; int maxfps = 200; long utimeperframe = 1000000/maxfps; struct timeval now; long timediff; gettimeofday(&now, NULL); - timediff = now.tv_sec*1000000 + now.tv_usec - lastframe.tv_sec*1000000 - lastframe.tv_usec; + timediff = now.tv_sec*1000000 + now.tv_usec - st->lastframe.tv_sec*1000000 - st->lastframe.tv_usec; if (timediff < utimeperframe) { /* fprintf(stderr,"sleeping for %i\n",utimeperframe-timediff); */ - usleep(utimeperframe-timediff); + this_delay = (utimeperframe-timediff); } - lastframe = now; + st->lastframe = now; - XSync (dpy, False); - screenhack_handle_events (dpy); + return this_delay; } - } +} + +static void +whirlwindwarp_reshape (Display *dpy, Window window, void *closure, + unsigned int w, unsigned int h) +{ } +static Bool +whirlwindwarp_event (Display *dpy, Window window, void *closure, XEvent *event) +{ + return False; +} + +static void +whirlwindwarp_free (Display *dpy, Window window, void *closure) +{ + struct state *st = (struct state *) closure; + free (st); +} -char *progclass = "WhirlwindWarp"; -char *defaults [] = { +static const char *whirlwindwarp_defaults [] = { ".background: black", ".foreground: white", "*points: 400", @@ -457,15 +488,11 @@ char *defaults [] = { 0 }; -XrmOptionDescRec options [] = { +static XrmOptionDescRec whirlwindwarp_options [] = { { "-points", ".points", XrmoptionSepArg, 0 }, { "-tails", ".tails", XrmoptionSepArg, 0 }, { "-meters", ".meters", XrmoptionNoArg, "true" }, { 0, 0, 0, 0 } }; -void screenhack(Display *dpy, Window window) -{ - if (init_whirlwindwarp(dpy, window)) - do_whirlwindwarp(dpy, window); -} +XSCREENSAVER_MODULE ("Whirlwindwarp", whirlwindwarp)