X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Ffiberlamp.c;h=43157751415f3b7c128f88b4bec3ff9b2c793d8f;hb=aa75c7476aeaa84cf3abc192b376a8b03c325213;hp=9e27e7ead3c51cda30e8d56cc52e04ddfa73a62d;hpb=2d04c4f22466851aedb6ed0f2919d148f726b889;p=xscreensaver diff --git a/hacks/fiberlamp.c b/hacks/fiberlamp.c index 9e27e7ea..43157751 100644 --- a/hacks/fiberlamp.c +++ b/hacks/fiberlamp.c @@ -1,13 +1,13 @@ /* -*- Mode: C; tab-width: 4 -*- */ /* fiberlamp --- A Fiber Optic Lamp */ -#if !defined( lint ) && !defined( SABER ) +#if 0 static const char sccsid[] = "@(#)fiberlamp.c 5.00 2000/11/01 xlockmore"; #endif /*- - * Copyright (c) 2005 by Tim Auckland + * Copyright (c) 2005 by Tim Auckland * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, @@ -31,28 +31,22 @@ static const char sccsid[] = "@(#)fiberlamp.c 5.00 2000/11/01 xlockmore"; #ifdef STANDALONE #define MODE_fiberlamp -#define PROGCLASS "Fiberlamp" -#define HACK_INIT init_fiberlamp -#define HACK_DRAW draw_fiberlamp -#define HACK_RESHAPE reshape_fiberlamp -#define _no_HACK_FREE release_fiberlamp -#define fiberlamp_opts xlockmore_opts -#define DEFAULTS "*delay: 10000 \n" \ - "*count: 500 \n" \ - "*cycles: 10000 \n" \ - "*ncolors: 64 \n" -#define UNIFORM_COLORS -#include "xlockmore.h" /* in xscreensaver distribution */ -# ifndef MI_DEPTH -# define MI_DEPTH MI_WIN_DEPTH -# endif +#define DEFAULTS "*delay: 10000 \n" \ + "*count: 500 \n" \ + "*cycles: 10000 \n" \ + "*ncolors: 64 \n" \ + "*fpsTop: true \n" \ + +# define UNIFORM_COLORS +# define fiberlamp_handle_event 0 +# include "xlockmore.h" /* in xscreensaver distribution */ #else /* STANDALONE */ -#include "xlock.h" /* in xlockmore distribution */ +# include "xlock.h" /* in xlockmore distribution */ #endif /* STANDALONE */ #ifdef MODE_fiberlamp -ModeSpecOpt fiberlamp_opts = +ENTRYPOINT ModeSpecOpt fiberlamp_opts = {0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; #ifdef USE_MODULES @@ -65,7 +59,7 @@ ModStruct fiberlamp_description = #define SPREAD (30.0) /* Angular spread at the base */ #define SCALE (MI_WIDTH(mi)/2) /* Screen size */ -#define NODES (20) /* Number of nodes in a fiber. Variable with range +#define NODES (20L) /* Number of nodes in a fiber. Variable with range 10 .. 30, if desired. High values have stability problems unless you use small DT */ @@ -83,6 +77,7 @@ ModStruct fiberlamp_description = colour highlights. Sum from 0..NODES-1 should exactly 1.0 */ #define LEN(A) ((Acx = (DRAND(SCALE/4)-SCALE/8)/SCALE; /* Knock the lamp */ fl->count = 0; /* Reset counter */ - XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_BLACK_PIXEL(mi)); - XFillRectangle(MI_DISPLAY(mi), fl->buffer, MI_GC(mi), 0, 0, - MI_WIDTH(mi), MI_HEIGHT(mi)); + if (fl->dbufp) { + XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_BLACK_PIXEL(mi)); + XFillRectangle(MI_DISPLAY(mi), fl->buffer, MI_GC(mi), 0, 0, + MI_WIDTH(mi), MI_HEIGHT(mi)); + } } static void @@ -137,8 +135,6 @@ free_fiber(fiberlampstruct *fl) free(fs->node); if (fs->draw) free(fs->draw); - if (fs->erase) - free(fs->erase); } free(fl->fiber); fl->fiber = NULL; @@ -146,23 +142,21 @@ free_fiber(fiberlampstruct *fl) } static void -free_fiberlamp(Display *display, fiberlampstruct *fl) +free_fiberlamp(ModeInfo *mi, fiberlampstruct *fl) { - if (fl->buffer != None) { - XFreePixmap(display, fl->buffer); + if (fl->buffer != None && fl->dbufp) { + XFreePixmap(MI_DISPLAY(mi), fl->buffer); fl->buffer = None; } free_fiber(fl); } -void +ENTRYPOINT void init_fiberlamp(ModeInfo * mi) { fiberlampstruct *fl; - Bool init = False; if (fiberlamps == NULL) { - init = True; if ((fiberlamps = (fiberlampstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (fiberlampstruct))) == NULL) @@ -171,26 +165,39 @@ init_fiberlamp(ModeInfo * mi) fl = &fiberlamps[MI_SCREEN(mi)]; /* Create or Resize double buffer */ - if(fl->buffer != None) - XFreePixmap(MI_DISPLAY(mi), fl->buffer); - fl->buffer = XCreatePixmap(MI_DISPLAY(mi), MI_WINDOW(mi), - MI_WIDTH(mi), MI_HEIGHT(mi), MI_DEPTH(mi)); - if (fl->buffer == None) { - free_fiberlamp(MI_DISPLAY(mi), fl); - return; +#ifdef HAVE_JWXYZ /* Don't second-guess Quartz's double-buffering */ + fl->dbufp = False; +#else + fl->dbufp = True; +#endif + + if(fl->buffer != None && fl->buffer != MI_WINDOW(mi) && fl->dbufp) + XFreePixmap(MI_DISPLAY(mi), fl->buffer); + + if(fl->dbufp) { + fl->buffer = XCreatePixmap(MI_DISPLAY(mi), MI_WINDOW(mi), + MI_WIDTH(mi), MI_HEIGHT(mi), MI_DEPTH(mi)); + if (fl->buffer == None) { + free_fiberlamp(mi, fl); + return; + } + } else { + fl->buffer = MI_WINDOW(mi); } + XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_BLACK_PIXEL(mi)); XFillRectangle(MI_DISPLAY(mi), fl->buffer, MI_GC(mi), 0, 0, MI_WIDTH(mi), MI_HEIGHT(mi)); - if(!init) /* Nothing else to do (probably a resize) */ + if(fl->init) /* Nothing else to do (probably a resize) */ return; + fl->init = True; fl->nfibers = MI_COUNT(mi); /* Allocate fibers */ if((fl->fiber = (fiberstruct*) calloc(fl->nfibers, sizeof (fiberstruct))) == NULL) { - free_fiberlamp(MI_DISPLAY(mi), fl); + free_fiberlamp(mi, fl); return; } else { int f; @@ -199,10 +206,8 @@ init_fiberlamp(ModeInfo * mi) if((fs->node = (nodestruct*) calloc(NODES, sizeof (nodestruct))) == NULL ||(fs->draw = - (XPoint*) calloc(NODES, sizeof (XPoint))) == NULL - ||(fs->erase = - (XPoint*) calloc(NODES, sizeof (XPoint))) == NULL) { - free_fiberlamp(MI_DISPLAY(mi), fl); + (XPoint*) calloc(NODES, sizeof (XPoint))) == NULL) { + free_fiberlamp(mi, fl); return; } } @@ -271,17 +276,31 @@ init_fiberlamp(ModeInfo * mi) change_fiberlamp(mi); } -#ifdef STANDALONE /* Used by xscreensaver. xlock just uses init_fiberlamp */ -void +ENTRYPOINT void reshape_fiberlamp(ModeInfo * mi, int width, int height) { init_fiberlamp(mi); } -#endif -void -draw_fiberlamp(ModeInfo * mi) +/* sort fibers so they get drawn back-to-front, one bubble pass is + enough as the order only changes slowly */ +static void +sort_fibers(fiberlampstruct *fl) +{ + int i; + + for(i = 1; i < fl->nfibers; i++) { + if (fl->fiber[i - 1].node[NODES - 1].z > fl->fiber[i].node[NODES - 1].z) { + fiberstruct tmp = fl->fiber[i - 1]; + fl->fiber[i - 1] = fl->fiber[i]; + fl->fiber[i] = tmp; + } + } +} + +ENTRYPOINT void +draw_fiberlamp (ModeInfo * mi) { fiberlampstruct *fl; int f, i; @@ -302,8 +321,9 @@ draw_fiberlamp(ModeInfo * mi) fl->psi += fl->dpsi; /* turn colorwheel */ XTranslateCoordinates(MI_DISPLAY(mi), MI_WINDOW(mi), - RootWindow(MI_DISPLAY(mi),MI_SCREEN(mi)), + RootWindow(MI_DISPLAY(mi),0/*#### MI_SCREEN(mi)*/), cx, cy, &x, &y, &unused); + sort_fibers(fl); for(f = 0; f < fl->nfibers; f++) { fiberstruct *fs = fl->fiber + f; @@ -374,18 +394,26 @@ draw_fiberlamp(ModeInfo * mi) /* Erase: this may only be erasing an off-screen buffer, but on a slow system it may still be faster than XFillRectangle() */ - XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_BLACK_PIXEL(mi)); - XDrawLines(MI_DISPLAY(mi), fl->buffer, MI_GC(mi), - fs->erase, NODES-1, CoordModeOrigin); + /* That's unpossible. -jwz */ + } + + XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_BLACK_PIXEL(mi)); + XFillRectangle(MI_DISPLAY(mi), fl->buffer, MI_GC(mi), + 0, 0, MI_WIDTH(mi), MI_HEIGHT(mi)); + + for(f = 0; f < fl->nfibers; f++) { + fiberstruct *fs = fl->fiber + f; { double x = fs->node[1].x - fl->cx + 0.025; double y = fs->node[1].z + 0.02; double angle = atan2(y, x) + fl->psi; - int tipcolor = MI_PIXEL(mi, - (int)(MI_NPIXELS(mi)*angle/(2*M_PI)) % MI_NPIXELS(mi)); - int fibercolor; - int tiplen; + long tipcolor = (int)(MI_NPIXELS(mi)*angle/(2*M_PI)) % MI_NPIXELS(mi); + long fibercolor; + long tiplen; + + if (tipcolor < 0) tipcolor += MI_NPIXELS(mi); + tipcolor = MI_PIXEL(mi, tipcolor); if(fs->node[1].z < 0.0) { /* Back */ tiplen = 2; @@ -406,17 +434,12 @@ draw_fiberlamp(ModeInfo * mi) XDrawLines(MI_DISPLAY(mi), fl->buffer, MI_GC(mi), fs->draw+NODES-1-tiplen, tiplen, CoordModeOrigin); } - - { /* Switch buffers */ - XPoint *buffer = fs->draw; - fs->draw = fs->erase; - fs->erase = buffer; - } } /* Update the screen from the double-buffer */ - XCopyArea(MI_DISPLAY(mi), fl->buffer, MI_WINDOW(mi), MI_GC(mi), 0, 0, - MI_WIDTH(mi), MI_HEIGHT(mi), 0, 0); + if (fl->dbufp) + XCopyArea(MI_DISPLAY(mi), fl->buffer, MI_WINDOW(mi), MI_GC(mi), 0, 0, + MI_WIDTH(mi), MI_HEIGHT(mi), 0, 0); fl->rx = x; fl->ry = y; @@ -426,24 +449,25 @@ draw_fiberlamp(ModeInfo * mi) } } -void +ENTRYPOINT void release_fiberlamp(ModeInfo * mi) { if (fiberlamps != NULL) { int screen; for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) - free_fiberlamp(MI_DISPLAY(mi), &fiberlamps[screen]); + free_fiberlamp(mi, &fiberlamps[screen]); free(fiberlamps); fiberlamps = (fiberlampstruct *) NULL; } } -#if 0 -void +ENTRYPOINT void refresh_fiberlamp(ModeInfo * mi) { MI_CLEARWINDOW(mi); } -#endif + +XSCREENSAVER_MODULE ("Fiberlamp", fiberlamp) + #endif /* MODE_fiberlamp */