-/* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997, 1998, 2004
- * Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1992-2011 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* date: 1/19/04
*/
-#include <stdio.h>
#include <math.h>
-#include <string.h>
#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;
Pixmap work;
} wormhole;
-inline 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 )
+{
+ if (q < 1) q = 1;
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 ) {
tang = 90;
else
tang = 270;
- }
- if ( y1 == y2 ) {
+ } else if ( y1 == y2 ) {
if ( x1 < x2 )
tang = 0;
else
tang = 180;
- } else
- tang = (int)(0.5+atan2( -(y2-y1), x2 - x1 ) * 180.0 / M_PI );
+ } else {
+ tang = (int)(0.5+atan2( -(y2-y1), x2 - x1 ) * 180.0 / M_PI );
+ }
while ( tang < 0 )
tang += 360;
}
-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;
/*
-static void initHandle( RGBHandle * handle ){
+static void initHandle( RGBHandle * handle )
+{
handle->mine.red = rnd( 65536 );
handle->mine.green = rnd( 65536 );
}
*/
-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;
XColor old_color, new_color;
ch->shade_max = 2048;
initXColor( &new_color );
for ( q = 0; q < ch->shade_max; q += ch->shade_use ){
- min = q;
- max = q + ch->shade_use;
- if ( max >= ch->shade_max ) max = ch->shade_max-1;
blend_palette( ch->shade + q, ch->shade_use, &old_color, &new_color );
old_color = new_color;
}
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) );
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--;
*/
/*
-static void moveRGBHandle( RGBHandle * handle, int min, int max ){
+static void moveRGBHandle( RGBHandle * handle, int min, int max )
+{
unsigned short * want[ 3 ];
int q;
}
*/
-static void moveColorChanger( color_changer * ch, Display * display, Colormap * cmap ){
+static void moveColorChanger( 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 );
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] ) );
*/
}
-static void destroyColorChanger( color_changer * ch, Display * display, Colormap * cmap ){
+#if 0
+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_JWXYZ /* 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_JWXYZ /* 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;
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 );
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 );
}
-static void destroyWormhole( wormhole * worm, Display * display, Colormap * cmap ){
- destroyColorChanger( &(worm->changer), display, cmap );
- XFreePixmap( display, worm->work );
+#if 0
+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;
}
}
-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;
}
-static void addStar( wormhole * worm ){
+static void addStar( wormhole * worm )
+{
starline * star_new;
starline ** xstars;
}
-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 );
}
-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;
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;
}
}
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 );
}
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++;
}
-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;
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 ){
/* 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;
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 );
+
+ st->gc = XCreateGC( st->dpy, st->window, 0, &gcv );
+ XGetWindowAttributes( st->dpy, st->window, &attr );
+ st->cmap = attr.colormap;
- return 0;
+ 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 );
- */
- }
- destroyWormhole( &worm, dpy, &cmap );
-}
+static const char *wormhole_defaults [] = {
+ ".background: Black",
+ ".foreground: #E9967A",
+ "*delay: 10000",
+ "*zspeed: 10",
+ "*stars: 20",
+#ifdef HAVE_MOBILE
+ "*ignoreRotation: True",
+#endif
+ 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)