1117N/A/*
1117N/A * Copyright (c) 1988-91 by Patrick J. Naughton.
1117N/A *
1117N/A * Permission to use, copy, modify, and distribute this software and its
1117N/A * documentation for any purpose and without fee is hereby granted,
1117N/A * provided that the above copyright notice appear in all copies and that
1117N/A * both that copyright notice and this permission notice appear in
1117N/A * supporting documentation.
1117N/A *
1117N/A * This file is provided AS IS with no warranties of any kind. The author
1117N/A * shall have no liability with respect to the infringement of copyrights,
1117N/A * trade secrets or any patents by this file or any part thereof. In no
1117N/A * event will the author be liable for any lost revenue or profits or
1117N/A * other special, indirect and consequential damages.
1117N/A */
1117N/A
1117N/A/*
1117N/A * Copyright (c) 1990, 1994, Oracle and/or its affiliates. All rights reserved.
1117N/A *
1117N/A * Permission is hereby granted, free of charge, to any person obtaining a
1117N/A * copy of this software and associated documentation files (the "Software"),
1117N/A * to deal in the Software without restriction, including without limitation
1117N/A * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1117N/A * and/or sell copies of the Software, and to permit persons to whom the
1117N/A * Software is furnished to do so, subject to the following conditions:
1117N/A *
1117N/A * The above copyright notice and this permission notice (including the next
1117N/A * paragraph) shall be included in all copies or substantial portions of the
1117N/A * Software.
1117N/A *
1117N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1117N/A * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1117N/A * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1117N/A * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1117N/A * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1117N/A * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
1117N/A * DEALINGS IN THE SOFTWARE.
1117N/A */
1117N/A/*-
1117N/A * rotor.c - A swirly rotor for xlock, the X Window System lockscreen.
1117N/A *
1117N/A * Copyright (c) 1991 by Patrick J. Naughton.
1117N/A *
1117N/A * See xlock.c for copying information.
1117N/A *
1117N/A * Revision History:
1117N/A * 11-Nov-90: put into xlock (by Steve Zellers, zellers@sun.com)
1117N/A * 16-Oct-90: Received from Tom Lawrence (tcl@cs.brown.edu: 'flight' simulator)
1117N/A */
1117N/A
1117N/A/*
1117N/A * A 'batchcount' of 3 or 4 works best!
1117N/A */
1117N/A
1117N/A#include <stdio.h>
1117N/A#include <math.h>
1117N/A#include "xlock.h"
1117N/A
1117N/A#define SAVE 100 /* this is a good constant to tweak */
1117N/A#define REPS 50
1117N/A
1117N/A#define MAXANGLE 10000.0 /* irrectangular */
1117N/A#define DEFAULTCOUNT 3
1117N/A
1117N/Atypedef unsigned char Boolean;
1117N/A
1117N/A#define IDENT(X) X
1117N/A#ifdef __STDC__
1117N/A#define CAT(X,Y) X##Y
1117N/A#else
1117N/A#define CAT(X,Y) IDENT(X)Y
1117N/A#endif
1117N/A
1117N/Astruct elem {
1117N/A float angle;
1117N/A float radius;
1117N/A float start_radius;
1117N/A float end_radius;
1117N/A float radius_drift_max;
1117N/A float radius_drift_now;
1117N/A
1117N/A float ratio;
1117N/A float start_ratio;
1117N/A float end_ratio;
1117N/A float ratio_drift_max;
1117N/A float ratio_drift_now;
1117N/A};
1117N/A
1117N/Atypedef struct flightstruct {
1117N/A struct elem *elements;
1117N/A int pix;
1117N/A int lastx,
1117N/A lasty;
1117N/A int num,
1117N/A rotor,
1117N/A prev;
1117N/A int savex[SAVE],
1117N/A savey[SAVE];
1117N/A float angle;
1117N/A int centerx,
1117N/A centery;
1117N/A Boolean firsttime;
1117N/A Boolean smallscreen; /* for iconified view */
1117N/A Boolean forward;
1117N/A Boolean unused;
1117N/A} flightstruct;
1117N/A
1117N/A
1117N/Aextern XColor ssblack[];
1117N/Aextern XColor sswhite[];
1117N/A
1117N/Astatic flightstruct flights[MAXSCREENS];
1117N/A
1117N/Avoid
1117N/Ainitrotor(win)
1117N/A Window win;
1117N/A{
1117N/A flightstruct *fs = &flights[screen];
1117N/A XWindowAttributes xgwa;
1117N/A int x;
1117N/A struct elem *pelem;
1117N/A Boolean wassmall;
1117N/A
1117N/A XGetWindowAttributes(dsp, win, &xgwa);
1117N/A fs->centerx = xgwa.width / 2;
1117N/A fs->centery = xgwa.height / 2;
1117N/A
1117N/A /*
1117N/A * sometimes, you go into small view, only to see a really whizzy pattern
1117N/A * that you would like to look more closely at. Normally, clicking in the
1117N/A * icon reinitializes everything - but I don't, cuz I'm that kind of guy.
1117N/A * HENCE, the wassmall stuff you see here.
1117N/A */
1117N/A
1117N/A wassmall = fs->smallscreen;
1117N/A fs->smallscreen = (xgwa.width < 100);
1117N/A
1117N/A if (wassmall && !fs->smallscreen)
1117N/A fs->firsttime = True;
1117N/A else {
1117N/A if (batchcount > 12)
1117N/A batchcount = DEFAULTCOUNT;
1117N/A fs->num = batchcount;
1117N/A
1117N/A if (fs->elements == NULL) {
1117N/A if ((fs->elements = (struct elem *)
1117N/A malloc(sizeof(struct elem) * fs->num)) == 0) {
1117N/A perror("malloc");
1117N/A exit(1);
1117N/A }
1117N/A }
1117N/A memset(fs->savex, 0, sizeof(fs->savex));
1117N/A
1117N/A pelem = fs->elements;
1117N/A
1117N/A for (x = fs->num; --x >= 0; pelem++) {
1117N/A pelem->radius_drift_max = 1.0;
1117N/A pelem->radius_drift_now = 1.0;
1117N/A
1117N/A pelem->end_radius = 100.0;
1117N/A
1117N/A pelem->ratio_drift_max = 1.0;
1117N/A pelem->ratio_drift_now = 1.0;
1117N/A pelem->end_ratio = 10.0;
1117N/A }
1117N/A
1117N/A fs->rotor = 0;
1117N/A fs->prev = 1;
1117N/A fs->lastx = fs->centerx;
1117N/A fs->lasty = fs->centery;
1117N/A fs->angle = (random() % (long) MAXANGLE) / 3;
1117N/A fs->forward = fs->firsttime = True;
1117N/A }
1117N/A XSetForeground(dsp, Scr[screen].gc, ssblack[screen].pixel);
1117N/A XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, xgwa.width, xgwa.height);
1117N/A}
1117N/A
1117N/Avoid
1117N/Adrawrotor(win)
1117N/A Window win;
1117N/A{
1117N/A register flightstruct *fs = &flights[screen];
1117N/A register struct elem *pelem;
1117N/A int thisx,
1117N/A thisy;
1117N/A int i,
1117N/A rp;
1117N/A int x1,
1117N/A y1,
1117N/A x2,
1117N/A y2;
1117N/A
1117N/A
1117N/A#define SCALE(W,N) CAT(W,N)/=12; CAT(W,N)+=(CAT(fs->center,W)-2)
1117N/A#define SCALEIFSMALL() if (fs->smallscreen) { \
1117N/A SCALE(x,1); SCALE(x,2); \
1117N/A SCALE(y,1); SCALE(y,2); \
1117N/A }
1117N/A
1117N/A for (rp = 0; rp < REPS; rp++) {
1117N/A thisx = fs->centerx;
1117N/A thisy = fs->centery;
1117N/A
1117N/A for (i = fs->num, pelem = fs->elements; --i >= 0; pelem++) {
1117N/A if (pelem->radius_drift_max <= pelem->radius_drift_now) {
1117N/A pelem->start_radius = pelem->end_radius;
1117N/A pelem->end_radius =
1117N/A (float) (random() % 40000) / 100.0 - 200.0;
1117N/A pelem->radius_drift_max =
1117N/A (float) (random() % 100000) + 10000.0;
1117N/A pelem->radius_drift_now = 0.0;
1117N/A }
1117N/A if (pelem->ratio_drift_max <= pelem->ratio_drift_now) {
1117N/A pelem->start_ratio = pelem->end_ratio;
1117N/A pelem->end_ratio =
1117N/A (float) (random() % 2000) / 100.0 - 10.0;
1117N/A pelem->ratio_drift_max =
1117N/A (float) (random() % 100000) + 10000.0;
1117N/A pelem->ratio_drift_now = 0.0;
1117N/A }
1117N/A pelem->ratio = pelem->start_ratio +
1117N/A (pelem->end_ratio - pelem->start_ratio) /
1117N/A pelem->ratio_drift_max * pelem->ratio_drift_now;
1117N/A pelem->angle = fs->angle * pelem->ratio;
1117N/A pelem->radius = pelem->start_radius +
1117N/A (pelem->end_radius - pelem->start_radius) /
1117N/A pelem->radius_drift_max * pelem->radius_drift_now;
1117N/A
1117N/A thisx += (int) (cos(pelem->angle) * pelem->radius);
1117N/A thisy += (int) (sin(pelem->angle) * pelem->radius);
1117N/A
1117N/A pelem->ratio_drift_now += 1.0;
1117N/A pelem->radius_drift_now += 1.0;
1117N/A }
1117N/A if (fs->firsttime)
1117N/A fs->firsttime = False;
1117N/A else {
1117N/A XSetForeground(dsp, Scr[screen].gc, ssblack[screen].pixel);
1117N/A
1117N/A x1 = (int) fs->savex[fs->rotor];
1117N/A y1 = (int) fs->savey[fs->rotor];
1117N/A x2 = (int) fs->savex[fs->prev];
1117N/A y2 = (int) fs->savey[fs->prev];
1117N/A
1117N/A SCALEIFSMALL();
1117N/A
1117N/A XDrawLine(dsp, win, Scr[screen].gc, x1, y1, x2, y2);
1117N/A
1117N/A if (!mono && Scr[screen].npixels > 2) {
1117N/A XSetForeground(dsp, Scr[screen].gc,
1117N/A Scr[screen].pixels[fs->pix]);
1117N/A if (++fs->pix >= Scr[screen].npixels)
1117N/A fs->pix = 0;
1117N/A } else
1117N/A XSetForeground(dsp, Scr[screen].gc, sswhite[screen].pixel);
1117N/A
1117N/A x1 = fs->lastx;
1117N/A y1 = fs->lasty;
1117N/A x2 = thisx;
1117N/A y2 = thisy;
1117N/A
1117N/A SCALEIFSMALL();
1117N/A
1117N/A XDrawLine(dsp, win, Scr[screen].gc, x1, y1, x2, y2);
1117N/A }
1117N/A fs->savex[fs->rotor] = fs->lastx = thisx;
1117N/A fs->savey[fs->rotor] = fs->lasty = thisy;
1117N/A
1117N/A ++fs->rotor;
1117N/A fs->rotor %= SAVE;
1117N/A ++fs->prev;
1117N/A fs->prev %= SAVE;
1117N/A if (fs->forward) {
1117N/A fs->angle += 0.01;
1117N/A if (fs->angle >= MAXANGLE) {
1117N/A fs->angle = MAXANGLE;
1117N/A fs->forward = False;
1117N/A }
1117N/A } else {
1117N/A fs->angle -= 0.1;
1117N/A if (fs->angle <= 0) {
1117N/A fs->angle = 0.0;
1117N/A fs->forward = True;
1117N/A }
1117N/A }
1117N/A }
1117N/A}
1117N/A