Edit

IABSD.fr/xenocara/app/xlockmore/modes/blot.c

Branch :

  • Show log

    Commit

  • Author : matthieu
    Date : 2006-11-26 11:07:42
    Hash : 110b2a92
    Message : Importing xlockmore 5.22

  • app/xlockmore/modes/blot.c
  • /* -*- Mode: C; tab-width: 4 -*- */
    /* blot --- Rorschach's ink blot test */
    
    #if !defined( lint ) && !defined( SABER )
    static const char sccsid[] = "@(#)blot.c	5.00 2000/11/01 xlockmore";
    
    #endif
    
    /*-
     * Copyright (c) 1992 by Jamie Zawinski
     *
     * Permission to use, copy, modify, and distribute this software and its
     * documentation for any purpose and without fee is hereby granted,
     * provided that the above copyright notice appear in all copies and that
     * both that copyright notice and this permission notice appear in
     * supporting documentation.
     *
     * This file is provided AS IS with no warranties of any kind.  The author
     * shall have no liability with respect to the infringement of copyrights,
     * trade secrets or any patents by this file or any part thereof.  In no
     * event will the author be liable for any lost revenue or profits or
     * other special, indirect and consequential damages.
     *
     * 01-Nov-2000: Allocation checks
     * 10-May-1997: Compatible with xscreensaver
     * 05-Jan-1995: patch for Dual-Headed machines from Greg Onufer
     *              <Greg.Onufer@Eng.Sun.COM>
     * 07-Dec-1994: now randomly has xsym, ysym, or both.
     * 02-Sep-1993: xlock version David Bagley <bagleyd@tux.org>
     * 1992:        xscreensaver version Jamie Zawinski <jwz@jwz.org>
     */
    
    /*-
     * original copyright
     * Copyright (c) 1992 by Jamie Zawinski
     * Permission to use, copy, modify, distribute, and sell this software and
     * its documentation for any purpose is hereby granted without fee, provided
     * that the above copyright notice appear in all copies and that both that
     * copyright notice and this permission notice appear in supporting
     * documentation.  No representations are made about the suitability of this
     * software for any purpose.  It is provided "as is" without express or
     * implied warranty.
     */
    
    #ifdef STANDALONE
    #define MODE_blot
    #define PROGCLASS "Blot"
    #define HACK_INIT init_blot
    #define HACK_DRAW draw_blot
    #define blot_opts xlockmore_opts
    #define DEFAULTS "*delay: 2000000 \n" \
     "*count: 6 \n" \
     "*cycles: 30 \n" \
     "*ncolors: 200 \n"
    #include "xlockmore.h"		/* in xscreensaver distribution */
    #else /* STANDALONE */
    #include "xlock.h"		/* in xlockmore distribution */
    #endif /* STANDALONE */
    
    #ifdef MODE_blot
    
    ModeSpecOpt blot_opts =
    {0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
    
    #ifdef USE_MODULES
    const ModStruct blot_description =
    {"blot", "init_blot", "draw_blot", "release_blot",
     "refresh_blot", "init_blot", (char *) NULL, &blot_opts,
     200000, 6, 30, 1, 64, 0.3, "",
     "Shows Rorschach's ink blot test", 0, NULL};
    
    #endif
    
    typedef struct {
    	int         width;
    	int         height;
    	int         xmid, ymid;
    	int         offset;
    	int         xsym, ysym;
    	int         size;
    	int         pix;
    	int         count;
    	XPoint     *pointBuffer;
    	unsigned int pointBufferSize;
    } blotstruct;
    
    static blotstruct *blots = (blotstruct *) NULL;
    
    void
    init_blot(ModeInfo * mi)
    {
    	Display    *display = MI_DISPLAY(mi);
    	blotstruct *bp;
    
    	if (blots == NULL) {
    		if ((blots = (blotstruct *) calloc(MI_NUM_SCREENS(mi),
    					       sizeof (blotstruct))) == NULL)
    			return;
    	}
    	bp = &blots[MI_SCREEN(mi)];
    
    	bp->width = MI_WIDTH(mi);
    	bp->height = MI_HEIGHT(mi);
    	bp->xmid = bp->width / 2;
    	bp->ymid = bp->height / 2;
    
    	bp->offset = 4;
    	bp->ysym = (int) LRAND() & 1;
    	bp->xsym = (bp->ysym) ? (int) LRAND() & 1 : 1;
    	if (MI_NPIXELS(mi) > 2)
    		bp->pix = NRAND(MI_NPIXELS(mi));
    	if (bp->offset <= 0)
    		bp->offset = 3;
    	if (MI_COUNT(mi) < 0)
    		bp->size = NRAND(-MI_COUNT(mi) + 1);
    	else
    		bp->size = MI_COUNT(mi);
    
    	/* Fudge the size so it takes up the whole screen */
    	bp->size *= (bp->width / 32 + 1) * (bp->height / 32 + 1);
    	if (!bp->pointBuffer || bp->pointBufferSize < bp->size * sizeof (XPoint)) {
    		if (bp->pointBuffer != NULL)
    			free(bp->pointBuffer);
    		bp->pointBufferSize = bp->size * sizeof (XPoint);
    		if ((bp->pointBuffer = (XPoint *) malloc(bp->pointBufferSize)) ==
    				NULL) {
    			return;
    		}
    	}
    	MI_CLEARWINDOW(mi);
    	XSetForeground(display, MI_GC(mi), MI_WHITE_PIXEL(mi));
    	bp->count = 0;
    }
    
    void
    draw_blot(ModeInfo * mi)
    {
    	blotstruct *bp;
    	XPoint     *xp;
    	int         x, y, k;
    
    	if (blots == NULL)
    		return;
    	bp = &blots[MI_SCREEN(mi)];
    	xp = bp->pointBuffer;
    	if (xp == NULL)
    		init_blot(mi);
    
    	MI_IS_DRAWN(mi) = True;
    	if (MI_NPIXELS(mi) > 2) {
    		XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_PIXEL(mi, bp->pix));
    		if (++bp->pix >= MI_NPIXELS(mi))
    			bp->pix = 0;
    	}
    	x = bp->xmid;
    	y = bp->ymid;
    	k = bp->size;
    	while (k >= 4) {
    		x += (NRAND(1 + (bp->offset << 1)) - bp->offset);
    		y += (NRAND(1 + (bp->offset << 1)) - bp->offset);
    		k--;
    		xp->x = x;
    		xp->y = y;
    		xp++;
    		if (bp->xsym) {
    			k--;
    			xp->x = bp->width - x;
    			xp->y = y;
    			xp++;
    		}
    		if (bp->ysym) {
    			k--;
    			xp->x = x;
    			xp->y = bp->height - y;
    			xp++;
    		}
    		if (bp->xsym && bp->ysym) {
    			k--;
    			xp->x = bp->width - x;
    			xp->y = bp->height - y;
    			xp++;
    		}
    	}
    	XDrawPoints(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi),
    		    bp->pointBuffer, (bp->size - k), CoordModeOrigin);
    	if (++bp->count > MI_CYCLES(mi))
    		init_blot(mi);
    }
    
    
    void
    release_blot(ModeInfo * mi)
    {
    	if (blots != NULL) {
    		int         screen;
    
    		for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
    			blotstruct *bp = &blots[screen];
    
    			if (bp->pointBuffer != NULL) {
    				free(bp->pointBuffer);
    				/* bp->pointBuffer == NULL; */
    			}
    		}
    		free(blots);
    		blots = (blotstruct *) NULL;
    	}
    }
    
    void
    refresh_blot(ModeInfo * mi)
    {
    	MI_CLEARWINDOW(mi);
    }
    
    #endif /* MODE_blot */