"Fossies" - the Fresh Open Source Software Archive

Member "xlockmore-5.59/modes/laser.c" (8 Sep 2019, 8539 Bytes) of package /linux/misc/xlockmore-5.59.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "laser.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 5.58_vs_5.59.

    1 /* -*- Mode: C; tab-width: 4 -*- */
    2 /* laser --- spinning lasers */
    3 
    4 #if 0
    5 static const char sccsid[] = "@(#)laser.c   5.00 2000/11/01 xlockmore";
    6 
    7 #endif
    8 
    9 /*-
   10  * Copyright (c) 1995 Pascal Pensa <pensa@aurora.unice.fr>
   11  *
   12  * Permission to use, copy, modify, and distribute this software and its
   13  * documentation for any purpose and without fee is hereby granted,
   14  * provided that the above copyright notice appear in all copies and that
   15  * both that copyright notice and this permission notice appear in
   16  * supporting documentation.
   17  *
   18  * This file is provided AS IS with no warranties of any kind.  The author
   19  * shall have no liability with respect to the infringement of copyrights,
   20  * trade secrets or any patents by this file or any part thereof.  In no
   21  * event will the author be liable for any lost revenue or profits or
   22  * other special, indirect and consequential damages.
   23  *
   24  * Revision History:
   25  * 01-Nov-2000: Allocation checks
   26  * 10-May-1997: Compatible with xscreensaver
   27  * 1995: Written.
   28  */
   29 
   30 #ifdef STANDALONE
   31 #define MODE_laser
   32 #define laser_opts xlockmore_opts
   33 #define DEFAULTS "*delay: 20000 \n" \
   34     "*count: -10 \n" \
   35     "*cycles: 200 \n" \
   36     "*ncolors: 200 \n" \
   37 
   38 # define reshape_laser 0
   39 # define laser_handle_event 0
   40 #define BRIGHT_COLORS
   41 #include "xlockmore.h"      /* in xscreensaver distribution */
   42 #else /* STANDALONE */
   43 #include "xlock.h"      /* in xlockmore distribution */
   44 #endif /* STANDALONE */
   45 
   46 #ifdef MODE_laser
   47 
   48 ENTRYPOINT ModeSpecOpt laser_opts =
   49 {0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
   50 
   51 #ifdef USE_MODULES
   52 ModStruct   laser_description =
   53 {"laser", "init_laser", "draw_laser", "release_laser",
   54  "refresh_laser", "init_laser", "free_laser", &laser_opts,
   55  20000, -10, 200, 1, 64, 1.0, "",
   56  "Shows spinning lasers", 0, NULL};
   57 
   58 #endif
   59 
   60 #define MINREDRAW 3     /* Number of redrawn on each frame */
   61 #define MAXREDRAW 8
   62 
   63 #define MINLASER  1     /* Laser number */
   64 
   65 #define MINWIDTH  2     /* Laser ray width range */
   66 #define MAXWIDTH 40
   67 
   68 #define MINSPEED  2     /* Speed range */
   69 #define MAXSPEED 17
   70 
   71 #define MINDIST  10     /* Minimal distance from edges */
   72 
   73 #define COLORSTEP 2     /* Laser color step */
   74 
   75 #define RANGE_RAND(min,max) (int) ((min) + LRAND() % ((max) - (min)))
   76 
   77 typedef enum {
   78     TOP, RIGHT, BOTTOM, LEFT
   79 } border;
   80 
   81 typedef struct {
   82     int         bx;     /* border x */
   83     int         by;     /* border y */
   84     border      bn;     /* active border */
   85     int         dir;    /* direction */
   86     int         speed;  /* laser velocity from MINSPEED to MAXSPEED */
   87     int         sx[MAXWIDTH];   /* x stack */
   88     int         sy[MAXWIDTH];   /* x stack */
   89     XGCValues   gcv;    /* for color */
   90 } laserstruct;
   91 
   92 typedef struct {
   93     int         width;
   94     int         height;
   95     int         cx;     /* center x */
   96     int         cy;     /* center y */
   97     int         lw;     /* laser width */
   98     int         ln;     /* laser number */
   99     int         lr;     /* laser redraw */
  100     int         sw;     /* stack width */
  101     int         so;     /* stack offset */
  102     int         time;   /* up time */
  103     GC          stippledGC;
  104     XGCValues   gcv_black;  /* for black color */
  105     laserstruct *laser;
  106 } lasersstruct;
  107 
  108 static lasersstruct *lasers = (lasersstruct *) NULL;
  109 
  110 static void
  111 free_laser_screen(Display *display, lasersstruct *lp)
  112 {
  113     if (lp == NULL) {
  114         return;
  115     }
  116     if (lp->laser != NULL) {
  117         free(lp->laser);
  118         lp->laser = (laserstruct *) NULL;
  119     }
  120     if (lp->stippledGC != None) {
  121         XFreeGC(display, lp->stippledGC);
  122         lp->stippledGC = None;
  123     }
  124     lp = NULL;
  125 }
  126 
  127 ENTRYPOINT void
  128 free_laser(ModeInfo * mi)
  129 {
  130     free_laser_screen(MI_DISPLAY(mi), &lasers[MI_SCREEN(mi)]);
  131 }
  132 
  133 ENTRYPOINT void
  134 init_laser(ModeInfo * mi)
  135 {
  136     Display *display = MI_DISPLAY(mi);
  137     int         i, c = 0;
  138     lasersstruct *lp;
  139 
  140     MI_INIT(mi, lasers);
  141     lp = &lasers[MI_SCREEN(mi)];
  142 
  143     lp->width = MI_WIDTH(mi);
  144     lp->height = MI_HEIGHT(mi);
  145     lp->time = 0;
  146 
  147     lp->ln = MI_COUNT(mi);
  148     if (lp->ln < -MINLASER) {
  149         /* if lp->ln is random ... the size can change */
  150         if (lp->laser != NULL) {
  151             free(lp->laser);
  152             lp->laser = (laserstruct *) NULL;
  153         }
  154         lp->ln = NRAND(-lp->ln - MINLASER + 1) + MINLASER;
  155     } else if (lp->ln < MINLASER)
  156         lp->ln = MINLASER;
  157 
  158     if (lp->laser == NULL) {
  159         if ((lp->laser = (laserstruct *) malloc(lp->ln *
  160                 sizeof (laserstruct))) == NULL) {
  161             free_laser_screen(display, lp);
  162             return;
  163         }
  164     }
  165     if (lp->stippledGC == None) {
  166         XGCValues   gcv;
  167 
  168         gcv.foreground = MI_WHITE_PIXEL(mi);
  169         gcv.background = MI_BLACK_PIXEL(mi);
  170         lp->gcv_black.foreground = MI_BLACK_PIXEL(mi);
  171         if ((lp->stippledGC = XCreateGC(display, MI_WINDOW(mi),
  172                 GCForeground | GCBackground, &gcv)) == None) {
  173             free_laser_screen(display, lp);
  174             return;
  175         }
  176     }
  177     MI_CLEARWINDOWCOLORMAPFAST(mi, MI_GC(mi), MI_BLACK_PIXEL(mi));
  178 
  179     if (MINDIST < lp->width - MINDIST)
  180         lp->cx = RANGE_RAND(MINDIST, lp->width - MINDIST);
  181     else
  182         lp->cx = RANGE_RAND(0, lp->width);
  183     if (MINDIST < lp->height - MINDIST)
  184         lp->cy = RANGE_RAND(MINDIST, lp->height - MINDIST);
  185     else
  186         lp->cy = RANGE_RAND(0, lp->height);
  187     lp->lw = RANGE_RAND(MINWIDTH, MAXWIDTH);
  188     lp->lr = RANGE_RAND(MINREDRAW, MAXREDRAW);
  189     lp->sw = 0;
  190     lp->so = 0;
  191 
  192     if (MI_NPIXELS(mi) > 2)
  193         c = NRAND(MI_NPIXELS(mi));
  194 
  195     for (i = 0; i < lp->ln; i++) {
  196         laserstruct *l = &lp->laser[i];
  197 
  198         l->bn = (border) NRAND(4);
  199 
  200         switch (l->bn) {
  201             case TOP:
  202                 l->bx = NRAND(lp->width);
  203                 l->by = 0;
  204                 break;
  205             case RIGHT:
  206                 l->bx = lp->width;
  207                 l->by = NRAND(lp->height);
  208                 break;
  209             case BOTTOM:
  210                 l->bx = NRAND(lp->width);
  211                 l->by = lp->height;
  212                 break;
  213             case LEFT:
  214                 l->bx = 0;
  215                 l->by = NRAND(lp->height);
  216         }
  217 
  218         l->dir = (int) (LRAND() & 1);
  219         l->speed = ((RANGE_RAND(MINSPEED, MAXSPEED) * lp->width) / 1000) + 1;
  220         if (MI_NPIXELS(mi) > 2) {
  221             l->gcv.foreground = MI_PIXEL(mi, c);
  222             c = (c + COLORSTEP) % MI_NPIXELS(mi);
  223         } else
  224             l->gcv.foreground = MI_WHITE_PIXEL(mi);
  225     }
  226 }
  227 
  228 ENTRYPOINT void
  229 draw_laser_once(ModeInfo * mi)
  230 {
  231     Display    *display = MI_DISPLAY(mi);
  232     lasersstruct *lp = &lasers[MI_SCREEN(mi)];
  233     int         i;
  234 
  235     for (i = 0; i < lp->ln; i++) {
  236         laserstruct *l = &lp->laser[i];
  237 
  238         if (lp->sw >= lp->lw) {
  239             XChangeGC(display, lp->stippledGC, GCForeground, &(lp->gcv_black));
  240             XDrawLine(display, MI_WINDOW(mi), lp->stippledGC,
  241                   lp->cx, lp->cy,
  242                   l->sx[lp->so], l->sy[lp->so]);
  243         }
  244         if (l->dir) {
  245             switch (l->bn) {
  246                 case TOP:
  247                     l->bx -= l->speed;
  248                     if (l->bx < 0) {
  249                         l->by = -l->bx;
  250                         l->bx = 0;
  251                         l->bn = LEFT;
  252                     }
  253                     break;
  254                 case RIGHT:
  255                     l->by -= l->speed;
  256                     if (l->by < 0) {
  257                         l->bx = lp->width + l->by;
  258                         l->by = 0;
  259                         l->bn = TOP;
  260                     }
  261                     break;
  262                 case BOTTOM:
  263                     l->bx += l->speed;
  264                     if (l->bx >= lp->width) {
  265                         l->by = lp->height - l->bx % lp->width;
  266                         l->bx = lp->width;
  267                         l->bn = RIGHT;
  268                     }
  269                     break;
  270                 case LEFT:
  271                     l->by += l->speed;
  272                     if (l->by >= lp->height) {
  273                         l->bx = l->by % lp->height;
  274                         l->by = lp->height;
  275                         l->bn = BOTTOM;
  276                     }
  277             }
  278         } else {
  279             switch (l->bn) {
  280                 case TOP:
  281                     l->bx += l->speed;
  282                     if (l->bx >= lp->width) {
  283                         l->by = l->bx % lp->width;
  284                         l->bx = lp->width;
  285                         l->bn = RIGHT;
  286                     }
  287                     break;
  288                 case RIGHT:
  289                     l->by += l->speed;
  290                     if (l->by >= lp->height) {
  291                         l->bx = lp->width - l->by % lp->height;
  292                         l->by = lp->height;
  293                         l->bn = BOTTOM;
  294                     }
  295                     break;
  296                 case BOTTOM:
  297                     l->bx -= l->speed;
  298                     if (l->bx < 0) {
  299                         l->by = lp->height + l->bx;
  300                         l->bx = 0;
  301                         l->bn = LEFT;
  302                     }
  303                     break;
  304                 case LEFT:
  305                     l->by -= l->speed;
  306                     if (l->by < 0) {
  307                         l->bx = -l->bx;
  308                         l->by = 0;
  309                         l->bn = TOP;
  310                     }
  311             }
  312         }
  313 
  314         XChangeGC(display, lp->stippledGC, GCForeground, &l->gcv);
  315         XDrawLine(display, MI_WINDOW(mi), lp->stippledGC,
  316               lp->cx, lp->cy, l->bx, l->by);
  317 
  318         l->sx[lp->so] = l->bx;
  319         l->sy[lp->so] = l->by;
  320 
  321     }
  322 
  323     if (lp->sw < lp->lw)
  324         ++lp->sw;
  325 
  326     lp->so = (lp->so + 1) % lp->lw;
  327 }
  328 
  329 ENTRYPOINT void
  330 draw_laser(ModeInfo * mi)
  331 {
  332     int         i;
  333     lasersstruct *lp;
  334 
  335     if (lasers == NULL)
  336         return;
  337     lp = &lasers[MI_SCREEN(mi)];
  338     if (lp->laser == NULL)
  339         return;
  340 
  341     MI_IS_DRAWN(mi) = True;
  342     for (i = 0; i < lp->lr; i++)
  343         draw_laser_once(mi);
  344 
  345     if (++lp->time > MI_CYCLES(mi))
  346         init_laser(mi);
  347 }
  348 
  349 ENTRYPOINT void
  350 release_laser(ModeInfo * mi)
  351 {
  352     if (lasers != NULL) {
  353         int         screen;
  354 
  355         for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
  356             free_laser_screen(MI_DISPLAY(mi), &lasers[screen]);
  357         free(lasers);
  358         lasers = (lasersstruct *) NULL;
  359     }
  360 }
  361 
  362 #ifndef STANDALONE
  363 ENTRYPOINT void
  364 refresh_laser(ModeInfo * mi)
  365 {
  366     MI_CLEARWINDOW(mi);
  367 }
  368 #endif
  369 
  370 XSCREENSAVER_MODULE ("Laser", laser)
  371 
  372 #endif /* MODE_laser */