X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fwormhole.c;h=631b42b86ad3f336c02e10f4639e950d4cff1ee1;hp=09ebf7cf890be6f160c4d6f8ca1d2cc2f7a6122b;hb=49f5b54f312fe4ac2e9bc47581a72451bd0e8439;hpb=ccb7f4903325f92555a9722bba74b58346654ba0 diff --git a/hacks/wormhole.c b/hacks/wormhole.c index 09ebf7cf..631b42b8 100644 --- a/hacks/wormhole.c +++ b/hacks/wormhole.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997, 1998, 2004 +/* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997, 1998, 2004, 2006 * Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its @@ -17,19 +17,13 @@ * date: 1/19/04 */ -#include #include -#include #include "screenhack.h" #ifndef debug #define debug printf("File:%s Line:%d\n", __FILE__, __LINE__ ); #endif -int SCREEN_X, SCREEN_Y; -int z_speed; -int make_stars; - typedef struct STAR{ int x, y; int calc_x, calc_y; @@ -76,13 +70,30 @@ typedef struct WORMHOLE{ Pixmap work; } wormhole; -/*inline*/ static int rnd( int q ){ +struct state { + Display *dpy; + Window window; + + int SCREEN_X, SCREEN_Y; + int z_speed; + int make_stars; + + int delay; + wormhole worm; + GC gc; + Colormap cmap; +}; + + +/*inline*/ static int rnd( int q ) +{ return random() % q; } -static int gang( int x1, int y1, int x2, int y2 ){ +static int gang( int x1, int y1, int x2, int y2 ) +{ int tang = 0; if ( x1 == x2 ) { @@ -107,7 +118,8 @@ static int gang( int x1, int y1, int x2, int y2 ){ } -void blend_palette( XColor * pal, int max, XColor * sc, XColor * ec ) { +static void blend_palette( XColor * pal, int max, XColor * sc, XColor * ec ) +{ int q; @@ -134,7 +146,8 @@ void blend_palette( XColor * pal, int max, XColor * sc, XColor * ec ) { /* -static void initHandle( RGBHandle * handle ){ +static void initHandle( RGBHandle * handle ) +{ handle->mine.red = rnd( 65536 ); handle->mine.green = rnd( 65536 ); @@ -146,13 +159,15 @@ static void initHandle( RGBHandle * handle ){ } */ -static void initXColor( XColor * color ){ +static void initXColor( XColor * color ) +{ color->red = rnd( 50000 ) + 10000; color->blue = rnd( 50000 ) + 10000; color->green = rnd( 50000 ) + 10000; } -static void initColorChanger( color_changer * ch, Display * display, Colormap * cmap ){ +static void initColorChanger( struct state *st, color_changer * ch ) +{ int q; int min, max; @@ -180,7 +195,7 @@ static void initColorChanger( color_changer * ch, Display * display, Colormap * } for ( q = 0; q < ch->shade_max; q++ ) - XAllocColor( display, *cmap, &( ch->shade[q] ) ); + XAllocColor( st->dpy, st->cmap, &( ch->shade[q] ) ); /* initHandle( &(ch->handle_begin) ); @@ -191,13 +206,14 @@ static void initColorChanger( color_changer * ch, Display * display, Colormap * blend_palette( ch->shade, ch->max, &(ch->handle_begin.mine), &(ch->handle_end.mine) ); for ( q = 0; q < ch->max; q++ ) - XAllocColor( display, *cmap, &( ch->shade[q] ) ); + XAllocColor( st->dpy, *cmap, &( ch->shade[q] ) ); */ } /* -static void changeColor( unsigned short * col, unsigned short * change, int min, int max ){ +static void changeColor( unsigned short * col, unsigned short * change, int min, int max ) +{ int RGB_GO_BLACK = 30; if ( *col < *change ) *col++; if ( *col > *change ) *col--; @@ -210,7 +226,8 @@ static void changeColor( unsigned short * col, unsigned short * change, int min, */ /* -static void moveRGBHandle( RGBHandle * handle, int min, int max ){ +static void moveRGBHandle( RGBHandle * handle, int min, int max ) +{ unsigned short * want[ 3 ]; int q; @@ -239,7 +256,8 @@ static void moveRGBHandle( RGBHandle * handle, int min, int max ){ } */ -static void moveColorChanger( color_changer * ch, Display * display, Colormap * cmap ){ +static void moveColorChanger( color_changer * ch ) +{ /* int q; */ @@ -256,58 +274,65 @@ static void moveColorChanger( color_changer * ch, Display * display, Colormap * /* for ( q = 0; q < ch->max; q++ ) - XFreeColors( display, *cmap, &( ch->shade[q].pixel ), 1, 0 ); + XFreeColors( st->dpy, *cmap, &( ch->shade[q].pixel ), 1, 0 ); moveRGBHandle( &( ch->handle_begin ), 5000, 65500 ); moveRGBHandle( &( ch->handle_end ), 5000, 65500 ); blend_palette( ch->shade, ch->max, &(ch->handle_begin.mine), &(ch->handle_end.mine) ); for ( q = 0; q < ch->max; q++ ) - XAllocColor( display, *cmap, &( ch->shade[q] ) ); + XAllocColor( st->dpy, *cmap, &( ch->shade[q] ) ); */ } #if 0 -static void destroyColorChanger( color_changer * ch, Display * display, Colormap * cmap ){ +static void destroyColorChanger( color_changer * ch ) +{ int q; for ( q = 0; q < ch->max; q++ ) - XFreeColors( display, *cmap, &( ch->shade[q].pixel ), 1, 0 ); + XFreeColors( st->dpy, *cmap, &( ch->shade[q].pixel ), 1, 0 ); free( ch->shade ); } #endif -static void resizeWormhole( wormhole * worm, Display * display, Window * win ){ +static void resizeWormhole( struct state *st, wormhole * worm ) +{ XWindowAttributes attr; - Colormap cmap; - XGetWindowAttributes( display, *win, &attr ); + XGetWindowAttributes( st->dpy, st->window, &attr ); - cmap = attr.colormap; + st->cmap = attr.colormap; - SCREEN_X = attr.width; - SCREEN_Y = attr.height; + st->SCREEN_X = attr.width; + st->SCREEN_Y = attr.height; - XFreePixmap( display, worm->work ); - worm->work = XCreatePixmap( display, *win, SCREEN_X, SCREEN_Y, attr.depth ); +# ifndef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */ + XFreePixmap( st->dpy, worm->work ); + worm->work = XCreatePixmap( st->dpy, st->window, st->SCREEN_X, st->SCREEN_Y, attr.depth ); +# endif } -static void initWormhole( wormhole * worm, Display * display, Window * win ){ +static void initWormhole( struct state *st, wormhole * worm, Display * display, Window win ) +{ int i; XWindowAttributes attr; - Colormap cmap; - XGetWindowAttributes( display, *win, &attr ); + XGetWindowAttributes( st->dpy, st->window, &attr ); - cmap = attr.colormap; + st->cmap = attr.colormap; - SCREEN_X = attr.width; - SCREEN_Y = attr.height; + st->SCREEN_X = attr.width; + st->SCREEN_Y = attr.height; - worm->work = XCreatePixmap( display, *win, SCREEN_X, SCREEN_Y, attr.depth ); +# ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */ + worm->work = st->window; +# else + worm->work = XCreatePixmap( st->dpy, st->window, st->SCREEN_X, st->SCREEN_Y, attr.depth ); +# endif worm->diameter = rnd( 10 ) + 15; worm->diameter_change = rnd( 10 ) + 15; @@ -317,10 +342,10 @@ static void initWormhole( wormhole * worm, Display * display, Window * win ){ worm->actualy = attr.height / 2; worm->virtualx = worm->actualx; worm->virtualy = worm->actualy; - worm->speed = (float)SCREEN_X / 180.0; + worm->speed = (float)st->SCREEN_X / 180.0; /* z_speed = SCREEN_X / 120; */ worm->spiral = 0; - worm->addStar = make_stars; + worm->addStar = st->make_stars; worm->want_x = rnd( attr.width - 50 ) + 25; worm->want_y = rnd( attr.height - 50 ) + 25; worm->want_ang = gang( worm->actualx, worm->actualy, worm->want_x, worm->want_y ); @@ -329,8 +354,8 @@ static void initWormhole( wormhole * worm, Display * display, Window * win ){ worm->black.red = 0; worm->black.green = 0; worm->black.blue = 0; - XAllocColor( display, cmap, &worm->black ); - initColorChanger( &(worm->changer), display, &cmap ); + XAllocColor( st->dpy, st->cmap, &worm->black ); + initColorChanger( st, &(worm->changer) ); worm->num_stars = 64; worm->stars = (starline **)malloc( sizeof(starline *) * worm->num_stars ); @@ -340,24 +365,29 @@ static void initWormhole( wormhole * worm, Display * display, Window * win ){ } #if 0 -static void destroyWormhole( wormhole * worm, Display * display, Colormap * cmap ){ - destroyColorChanger( &(worm->changer), display, cmap ); - XFreePixmap( display, worm->work ); +static void destroyWormhole( wormhole * worm ) +{ + destroyColorChanger( &(worm->changer), st->dpy, cmap ); + if (work->work != st->window) + XFreePixmap( st->dpy, worm->work ); free( worm->stars ); } #endif -static double Cos( int a ){ +static double Cos( int a ) +{ return cos( a * 180.0 / M_PI ); } -static double Sine( int a ){ +static double Sine( int a ) +{ return sin( a * 180.0 / M_PI ); } -static void calcStar( star * st ){ +static void calcStar( star * st ) +{ if ( st->center_x == 0 || st->center_y == 0 ){ st->Z = 0; return; @@ -371,7 +401,8 @@ static void calcStar( star * st ){ } } -static void initStar( star * st, int Z, int ang, wormhole * worm ){ +static void initStar( star * st, int Z, int ang, wormhole * worm ) +{ st->x = Cos( ang ) * worm->diameter; st->y = Sine( ang ) * worm->diameter; @@ -382,7 +413,8 @@ static void initStar( star * st, int Z, int ang, wormhole * worm ){ } -static void addStar( wormhole * worm ){ +static void addStar( wormhole * worm ) +{ starline * star_new; starline ** xstars; @@ -416,10 +448,11 @@ static void addStar( wormhole * worm ){ } -static int moveStar( starline * stl ){ +static int moveStar( struct state *st, starline * stl ) +{ - stl->begin.Z -= z_speed; - stl->end.Z -= z_speed; + stl->begin.Z -= st->z_speed; + stl->end.Z -= st->z_speed; calcStar( &stl->begin ); calcStar( &stl->end ); @@ -428,14 +461,16 @@ static int moveStar( starline * stl ){ } -static int dist( int x1, int y1, int x2, int y2 ){ +static int dist( int x1, int y1, int x2, int y2 ) +{ int xs, ys; xs = x1-x2; ys = y1-y2; return (int)sqrt( xs*xs + ys*ys ); } -static void moveWormhole( wormhole * worm, Display * display, Colormap * cmap ){ +static void moveWormhole( struct state *st, wormhole * worm ) +{ int q; double dx, dy; @@ -475,13 +510,13 @@ static void moveWormhole( wormhole * worm, Display * display, Colormap * cmap ){ worm->virtualy = worm->actualy; find = 1; } - if ( worm->actualx > SCREEN_X - min_dist ){ - worm->actualx = SCREEN_X - min_dist; + if ( worm->actualx > st->SCREEN_X - min_dist ){ + worm->actualx = st->SCREEN_X - min_dist; worm->virtualx = worm->actualx; find = 1; } - if ( worm->actualy > SCREEN_Y - min_dist ){ - worm->actualy = SCREEN_Y - min_dist; + if ( worm->actualy > st->SCREEN_Y - min_dist ){ + worm->actualy = st->SCREEN_Y - min_dist; worm->virtualy = worm->actualy; find = 1; } @@ -490,8 +525,8 @@ static void moveWormhole( wormhole * worm, Display * display, Colormap * cmap ){ } if ( find ){ - worm->want_x = rnd( SCREEN_X - min_dist * 2 ) + min_dist; - worm->want_y = rnd( SCREEN_Y - min_dist * 2 ) + min_dist; + worm->want_x = rnd( st->SCREEN_X - min_dist * 2 ) + min_dist; + worm->want_y = rnd( st->SCREEN_Y - min_dist * 2 ) + min_dist; worm->ang = gang( worm->actualx, worm->actualy, worm->want_x, worm->want_y ); } @@ -540,14 +575,14 @@ static void moveWormhole( wormhole * worm, Display * display, Colormap * cmap ){ for ( q = 0; q < worm->num_stars; q++ ){ if ( worm->stars[q] != NULL ){ - if ( moveStar( worm->stars[q] ) ){ + if ( moveStar( st, worm->stars[q] ) ){ free( worm->stars[q] ); worm->stars[q] = NULL; } } } - moveColorChanger( &worm->changer, display, cmap ); + moveColorChanger( &worm->changer ); if ( worm->diameter < worm->diameter_change ) worm->diameter++; @@ -561,11 +596,13 @@ static void moveWormhole( wormhole * worm, Display * display, Colormap * cmap ){ } -static XColor * getColorShade( color_changer * ch ){ +static XColor * getColorShade( color_changer * ch ) +{ return ch->shade + ch->min; } -static void drawWormhole( Display * display, Window * win, GC * gc, wormhole * worm ){ +static void drawWormhole( struct state *st, wormhole * worm ) +{ int i; int color; @@ -573,6 +610,10 @@ static void drawWormhole( Display * display, Window * win, GC * gc, wormhole * w starline * current; XColor * xcol; XColor * shade; + + XSetForeground( st->dpy, st->gc, worm->black.pixel ); + XFillRectangle( st->dpy, worm->work, st->gc, 0, 0, st->SCREEN_X, st->SCREEN_Y ); + for ( i = 0; i < worm->num_stars; i++ ) if ( worm->stars[i] != NULL ){ @@ -584,19 +625,17 @@ static void drawWormhole( Display * display, Window * win, GC * gc, wormhole * w /* xcol = &worm->changer.shade[ color ]; */ xcol = &shade[ color ]; - XSetForeground( display, *gc, xcol->pixel ); - /* XDrawLine( display, *win, *gc, current->begin.calc_x, current->begin.calc_y, current->end.calc_x, current->end.calc_y ); */ - XDrawLine( display, worm->work, *gc, current->begin.calc_x, current->begin.calc_y, current->end.calc_x, current->end.calc_y ); + XSetForeground( st->dpy, st->gc, xcol->pixel ); + /* XDrawLine( st->dpy, st->window, *gc, current->begin.calc_x, current->begin.calc_y, current->end.calc_x, current->end.calc_y ); */ + XDrawLine( st->dpy, worm->work, st->gc, current->begin.calc_x, current->begin.calc_y, current->end.calc_x, current->end.calc_y ); } - XCopyArea( display, worm->work, *win, *gc, 0, 0, SCREEN_X, SCREEN_Y, 0, 0 ); - XSetForeground( display, *gc, worm->black.pixel ); - XFillRectangle( display, worm->work, *gc, 0, 0, SCREEN_X, SCREEN_Y ); - + if (worm->work != st->window) + XCopyArea( st->dpy, worm->work, st->window, st->gc, 0, 0, st->SCREEN_X, st->SCREEN_Y, 0, 0 ); } /* -static void eraseWormhole( Display * display, Window * win, GC * gc, wormhole * worm ){ +static void eraseWormhole( Display * display, Window * st->window, wormhole * worm ){ starline * current; int i; XColor * xcol; @@ -604,83 +643,84 @@ static void eraseWormhole( Display * display, Window * win, GC * gc, wormhole * if ( worm->stars[i] != NULL ){ xcol = &worm->black; current = worm->stars[i]; - XSetForeground( display, *gc, xcol->pixel ); - XDrawLine( display, *win, *gc, current->begin.calc_x, current->begin.calc_y, current->end.calc_x, current->end.calc_y ); + XSetForeground( st->dpy, *gc, xcol->pixel ); + XDrawLine( st->dpy, st->window, *gc, current->begin.calc_x, current->begin.calc_y, current->end.calc_x, current->end.calc_y ); } } */ -char *progclass = "Wormhole"; -char *defaults [] = { - ".background: Black", - ".foreground: #E9967A", - "*delay: 10000", - "*zspeed: 10", - "*stars: 20", - 0 -}; -XrmOptionDescRec options [] = { - { "-delay", ".delay", XrmoptionSepArg, 0 }, - { "-zspeed", ".zspeed", XrmoptionSepArg, 0 }, - { "-stars", ".stars", XrmoptionSepArg, 0 }, - { 0, 0, 0, 0 } -}; +static void * +wormhole_init (Display *dpy, Window window) +{ + struct state *st = (struct state *) calloc (1, sizeof(*st)); + XGCValues gcv; + XWindowAttributes attr; -static int handle_event( Display * display, XEvent * event ){ + st->dpy = dpy; + st->window = window; + st->delay = get_integer_resource(st->dpy, "delay", "Integer" ); + st->make_stars = get_integer_resource(st->dpy, "stars", "Integer" ); + st->z_speed = get_integer_resource(st->dpy, "zspeed", "Integer" ); - if ( event->xany.type == ConfigureNotify ){ - return 1; - } - screenhack_handle_event( display, event ); + initWormhole( st, &st->worm, st->dpy, st->window ); - return 0; + st->gc = XCreateGC( st->dpy, st->window, 0, &gcv ); + XGetWindowAttributes( st->dpy, st->window, &attr ); + st->cmap = attr.colormap; + + return st; } -void screenhack (Display *dpy, Window window) { +static unsigned long +wormhole_draw (Display *dpy, Window window, void *closure) +{ + struct state *st = (struct state *) closure; - wormhole worm; - GC gc; - XGCValues gcv; - XWindowAttributes attr; - Colormap cmap; + moveWormhole( st, &st->worm ); + drawWormhole( st, &st->worm ); + return st->delay; +} - int delay = get_integer_resource( "delay", "Integer" ); - make_stars = get_integer_resource( "stars", "Integer" ); - z_speed = get_integer_resource( "zspeed", "Integer" ); +static void +wormhole_reshape (Display *dpy, Window window, void *closure, + unsigned int w, unsigned int h) +{ + struct state *st = (struct state *) closure; + resizeWormhole( st, &st->worm ); +} - initWormhole( &worm, dpy, &window ); +static Bool +wormhole_event (Display *dpy, Window window, void *closure, XEvent *event) +{ + return False; +} - gcv.foreground = 1; - gcv.background = 1; - gc = XCreateGC( dpy, window, GCForeground, &gcv ); - XGetWindowAttributes( dpy, window, &attr ); - cmap = attr.colormap; +static void +wormhole_free (Display *dpy, Window window, void *closure) +{ + struct state *st = (struct state *) closure; + free (st); +} - while (1){ - moveWormhole( &worm, dpy, &cmap ); - drawWormhole( dpy, &window, &gc, &worm ); - XSync (dpy, False); - /* handle my own friggin events. mmmlaaaa */ - while ( XPending(dpy) ){ - XEvent event; - XNextEvent( dpy, &event ); - if ( handle_event( dpy, &event ) == 1 ){ - resizeWormhole( &worm, dpy, &window ); - } - } - /* screenhack_handle_events (dpy); */ - - if (delay) usleep (delay); - /* eraseWormhole( dpy, &window, &gc, &worm ); */ - /* - XSetForeground( dpy, gc, worm.black.pixel ); - XFillRectangle( dpy, window, gc, 0, 0, SCREEN_X, SCREEN_Y ); - */ - } -/* not reached: destroyWormhole( &worm, dpy, &cmap ); */ -} +static const char *wormhole_defaults [] = { + ".background: Black", + ".foreground: #E9967A", + "*delay: 10000", + "*zspeed: 10", + "*stars: 20", + 0 +}; + +static XrmOptionDescRec wormhole_options [] = { + { "-delay", ".delay", XrmoptionSepArg, 0 }, + { "-zspeed", ".zspeed", XrmoptionSepArg, 0 }, + { "-stars", ".stars", XrmoptionSepArg, 0 }, + { 0, 0, 0, 0 } +}; + +XSCREENSAVER_MODULE ("Wormhole", wormhole)