/* * 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) 1990, 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. */ /*- * rotor.c - A swirly rotor for xlock, the X Window System lockscreen. * * Copyright (c) 1991 by Patrick J. Naughton. * * See xlock.c for copying information. * * Revision History: * 11-Nov-90: put into xlock (by Steve Zellers, zellers@sun.com) * 16-Oct-90: Received from Tom Lawrence (tcl@cs.brown.edu: 'flight' simulator) */ /* * A 'batchcount' of 3 or 4 works best! */ #include #include #include "xlock.h" #define SAVE 100 /* this is a good constant to tweak */ #define REPS 50 #define MAXANGLE 10000.0 /* irrectangular */ #define DEFAULTCOUNT 3 typedef unsigned char Boolean; #define IDENT(X) X #ifdef __STDC__ #define CAT(X,Y) X##Y #else #define CAT(X,Y) IDENT(X)Y #endif struct elem { float angle; float radius; float start_radius; float end_radius; float radius_drift_max; float radius_drift_now; float ratio; float start_ratio; float end_ratio; float ratio_drift_max; float ratio_drift_now; }; typedef struct flightstruct { struct elem *elements; int pix; int lastx, lasty; int num, rotor, prev; int savex[SAVE], savey[SAVE]; float angle; int centerx, centery; Boolean firsttime; Boolean smallscreen; /* for iconified view */ Boolean forward; Boolean unused; } flightstruct; static flightstruct flights[MAXSCREENS]; void initrotor(Window win) { flightstruct *fs = &flights[screen]; XWindowAttributes xgwa; int x; struct elem *pelem; Boolean wassmall; XGetWindowAttributes(dsp, win, &xgwa); fs->centerx = xgwa.width / 2; fs->centery = xgwa.height / 2; /* * sometimes, you go into small view, only to see a really whizzy pattern * that you would like to look more closely at. Normally, clicking in the * icon reinitializes everything - but I don't, cuz I'm that kind of guy. * HENCE, the wassmall stuff you see here. */ wassmall = fs->smallscreen; fs->smallscreen = (Boolean) (xgwa.width < 100); if (wassmall && !fs->smallscreen) fs->firsttime = True; else { if ((batchcount < 1) || (batchcount > 12)) batchcount = DEFAULTCOUNT; fs->num = batchcount; if (fs->elements == NULL) { fs->elements = calloc(fs->num, sizeof(struct elem)); if (fs->elements == NULL) error("allocation failed, unable to motor our rotor\n"); } memset(fs->savex, 0, sizeof(fs->savex)); pelem = fs->elements; for (x = fs->num; --x >= 0; pelem++) { pelem->radius_drift_max = 1.0; pelem->radius_drift_now = 1.0; pelem->end_radius = 100.0; pelem->ratio_drift_max = 1.0; pelem->ratio_drift_now = 1.0; pelem->end_ratio = 10.0; } fs->rotor = 0; fs->prev = 1; fs->lastx = fs->centerx; fs->lasty = fs->centery; fs->angle = (random() % (long) MAXANGLE) / 3; fs->forward = fs->firsttime = True; } XSetForeground(dsp, Scr[screen].gc, ssblack[screen].pixel); XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, xgwa.width, xgwa.height); } void drawrotor(Window win) { register flightstruct *fs = &flights[screen]; register struct elem *pelem; int thisx, thisy; int i, rp; int x1, y1, x2, y2; #define SCALE(W,N) CAT(W,N)/=12; CAT(W,N)+=(CAT(fs->center,W)-2) #define SCALEIFSMALL() if (fs->smallscreen) { \ SCALE(x,1); SCALE(x,2); \ SCALE(y,1); SCALE(y,2); \ } for (rp = 0; rp < REPS; rp++) { thisx = fs->centerx; thisy = fs->centery; for (i = fs->num, pelem = fs->elements; --i >= 0; pelem++) { if (pelem->radius_drift_max <= pelem->radius_drift_now) { pelem->start_radius = pelem->end_radius; pelem->end_radius = (float) (random() % 40000) / 100.0 - 200.0; pelem->radius_drift_max = (float) (random() % 100000) + 10000.0; pelem->radius_drift_now = 0.0; } if (pelem->ratio_drift_max <= pelem->ratio_drift_now) { pelem->start_ratio = pelem->end_ratio; pelem->end_ratio = (float) (random() % 2000) / 100.0 - 10.0; pelem->ratio_drift_max = (float) (random() % 100000) + 10000.0; pelem->ratio_drift_now = 0.0; } pelem->ratio = pelem->start_ratio + (pelem->end_ratio - pelem->start_ratio) / pelem->ratio_drift_max * pelem->ratio_drift_now; pelem->angle = fs->angle * pelem->ratio; pelem->radius = pelem->start_radius + (pelem->end_radius - pelem->start_radius) / pelem->radius_drift_max * pelem->radius_drift_now; thisx += (int) (cos(pelem->angle) * pelem->radius); thisy += (int) (sin(pelem->angle) * pelem->radius); pelem->ratio_drift_now += 1.0; pelem->radius_drift_now += 1.0; } if (fs->firsttime) fs->firsttime = False; else { XSetForeground(dsp, Scr[screen].gc, ssblack[screen].pixel); x1 = (int) fs->savex[fs->rotor]; y1 = (int) fs->savey[fs->rotor]; x2 = (int) fs->savex[fs->prev]; y2 = (int) fs->savey[fs->prev]; SCALEIFSMALL(); XDrawLine(dsp, win, Scr[screen].gc, x1, y1, x2, y2); if (!mono && Scr[screen].npixels > 2) { XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[fs->pix]); if (++fs->pix >= Scr[screen].npixels) fs->pix = 0; } else XSetForeground(dsp, Scr[screen].gc, sswhite[screen].pixel); x1 = fs->lastx; y1 = fs->lasty; x2 = thisx; y2 = thisy; SCALEIFSMALL(); XDrawLine(dsp, win, Scr[screen].gc, x1, y1, x2, y2); } fs->savex[fs->rotor] = fs->lastx = thisx; fs->savey[fs->rotor] = fs->lasty = thisy; ++fs->rotor; fs->rotor %= SAVE; ++fs->prev; fs->prev %= SAVE; if (fs->forward) { fs->angle += 0.01; if (fs->angle >= MAXANGLE) { fs->angle = MAXANGLE; fs->forward = False; } } else { fs->angle -= 0.1; if (fs->angle <= 0) { fs->angle = 0.0; fs->forward = True; } } } }