/*
* Copyright (c) 1988-91 by Patrick J. Naughton.
*
* 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.
*/
/*
* Copyright (c) 1988, 2015, Oracle and/or its affiliates. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*-
* hopalong.c - Real Plane Fractals for xlock, the X Window System lockscreen.
*
* Copyright (c) 1991 by Patrick J. Naughton.
*
* See xlock.c for copying information.
*
* Revision History:
* 29-Oct-90: fix bad (int) cast.
* 29-Jul-90: support for multiple screens.
* 08-Jul-90: new timing and colors and new algorithm for fractals.
* 15-Dec-89: Fix for proper skipping of {White,Black}Pixel() in colors.
* 08-Oct-89: Fixed long standing typo bug in RandomInitHop();
* Fixed bug in memory allocation in inithop();
* Moved seconds() to an extern.
* Got rid of the % mod since .mod is slow on a sparc.
* 20-Sep-89: Lint.
* 31-Aug-88: Forked from xlock.c for modularity.
* 23-Mar-88: Coded HOPALONG routines from Scientific American Sept. 86 p. 14.
*/
#include "xlock.h"
#include <math.h>
typedef struct {
int centerx;
int centery; /* center of the screen */
double a;
double b;
double c;
double i;
double j; /* hopalong parameters */
int inc;
int pix;
long startTime;
} hopstruct;
static hopstruct hops[MAXSCREENS];
static XPoint *pointBuffer = 0; /* pointer for XDrawPoints */
#define TIMEOUT 30
void
inithop(Window win)
{
double range;
XWindowAttributes xgwa;
hopstruct *hp = &hops[screen];
XGetWindowAttributes(dsp, win, &xgwa);
hp->centerx = xgwa.width / 2;
hp->centery = xgwa.height / 2;
range = sqrt((double) hp->centerx * hp->centerx +
(double) hp->centery * hp->centery) /
(10.0 + random() % 10);
hp->pix = 0;
hp->inc = (int) ((random() / MAXRAND) * 200) - 100;
hp->a = (random() / MAXRAND) * range - range / 2.0;
hp->b = (random() / MAXRAND) * range - range / 2.0;
hp->c = (random() / MAXRAND) * range - range / 2.0;
if (!(random() % 2))
hp->c = 0.0;
hp->i = hp->j = 0.0;
if ((batchcount < 1) || (batchcount > 131072))
batchcount = 1000;
if (pointBuffer == NULL) {
pointBuffer = calloc(batchcount, sizeof(XPoint));
if (pointBuffer == NULL)
error("allocation failed, unable to hopalong now\n");
}
XSetForeground(dsp, Scr[screen].gc, ssblack[screen].pixel);
XFillRectangle(dsp, win, Scr[screen].gc, 0, 0,
hp->centerx * 2, hp->centery * 2);
XSetForeground(dsp, Scr[screen].gc, sswhite[screen].pixel);
hp->startTime = seconds();
}
void
drawhop(Window win)
{
double oldj;
int k = batchcount;
XPoint *xp = pointBuffer;
hopstruct *hp = &hops[screen];
hp->inc++;
if (!mono && Scr[screen].npixels > 2) {
XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[hp->pix]);
if (++hp->pix >= Scr[screen].npixels)
hp->pix = 0;
}
while (k--) {
oldj = hp->j;
hp->j = hp->a - hp->i;
hp->i = oldj + (hp->i < 0
? sqrt(fabs(hp->b * (hp->i + hp->inc) - hp->c))
: -sqrt(fabs(hp->b * (hp->i + hp->inc) - hp->c)));
xp->x = (short) (hp->centerx + (int) (hp->i + hp->j));
xp->y = (short) (hp->centery - (int) (hp->i - hp->j));
xp++;
}
XDrawPoints(dsp, win, Scr[screen].gc,
pointBuffer, batchcount, CoordModeOrigin);
if (seconds() - hp->startTime > TIMEOUT)
inithop(win);
}