2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: swarm.c /main/3 1995/11/02 16:08:42 rswiston $ */
27 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
28 * (c) Copyright 1993, 1994 International Business Machines Corp. *
29 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
30 * (c) Copyright 1993, 1994 Novell, Inc. *
33 * swarm.c - swarm of bees for dtscreen, the X Window System lockscreen.
35 * Copyright (c) 1991 by Patrick J. Naughton.
38 * 31-Aug-90: Adapted from xswarm by Jeff Butterworth. (butterwo@ncsc.org)
44 #define TIMES 4 /* number of time positions recorded */
45 #define BEEACC 3 /* acceleration of bees */
46 #define WASPACC 5 /* maximum acceleration of wasp */
47 #define BEEVEL 11 /* maximum bee velocity */
48 #define WASPVEL 12 /* maximum wasp velocity */
49 #define BORDER 50 /* wasp won't go closer than this to the edge */
52 #define X(t,b) (sp->x[(t)*sp->beecount+(b)])
53 #define Y(t,b) (sp->y[(t)*sp->beecount+(b)])
54 #define RAND(v) ((random()%(v))-((v)/2)) /* random number around 0 */
61 int beecount; /* number of bees */
62 XSegment *segs; /* bee lines */
63 XSegment *old_segs; /* old bee lines */
65 short *y; /* bee positions x[time][bee#] */
67 short *yv; /* bee velocities xv[bee#] */
75 initswarm(perwindow *pwin)
77 XWindowAttributes xgwa;
81 if (pwin->data) free(pwin->data);
82 pwin->data = (void *)malloc(sizeof(swarmstruct));
83 memset(pwin->data, '\0', sizeof(swarmstruct));
84 sp = (swarmstruct *)pwin->data;
85 sp->startTime = seconds();
86 sp->beecount = batchcount;
88 XGetWindowAttributes(dsp, pwin->w, &xgwa);
89 sp->width = xgwa.width;
90 sp->height = xgwa.height;
92 /* Clear the background. */
93 XSetForeground(dsp, pwin->gc, BlackPixelOfScreen(pwin->perscreen->screen));
94 XFillRectangle(dsp, pwin->w, pwin->gc, 0, 0, sp->width, sp->height);
96 /* Allocate memory. */
98 sp->segs = (XSegment *) malloc(sizeof(XSegment) * sp->beecount);
99 sp->old_segs = (XSegment *) malloc(sizeof(XSegment) * sp->beecount);
100 sp->x = (short *) malloc(sizeof(short) * sp->beecount * TIMES);
101 sp->y = (short *) malloc(sizeof(short) * sp->beecount * TIMES);
102 sp->xv = (short *) malloc(sizeof(short) * sp->beecount);
103 sp->yv = (short *) malloc(sizeof(short) * sp->beecount);
105 /* Initialize point positions, velocities, etc. */
108 sp->wx[0] = BORDER + random() % (sp->width - 2 * BORDER);
109 sp->wy[0] = BORDER + random() % (sp->height - 2 * BORDER);
110 sp->wx[1] = sp->wx[0];
111 sp->wy[1] = sp->wy[0];
116 for (b = 0; b < sp->beecount; b++) {
117 X(0, b) = random() % sp->width;
119 Y(0, b) = random() % sp->height;
129 drawswarm(perwindow *pwin)
134 sp = (swarmstruct *)pwin->data;
136 /* Age the arrays. */
137 sp->wx[2] = sp->wx[1];
138 sp->wx[1] = sp->wx[0];
139 sp->wy[2] = sp->wy[1];
140 sp->wy[1] = sp->wy[0];
142 sp->wxv += RAND(WASPACC);
143 sp->wyv += RAND(WASPACC);
145 /* Speed Limit Checks */
146 if (sp->wxv > WASPVEL)
148 if (sp->wxv < -WASPVEL)
150 if (sp->wyv > WASPVEL)
152 if (sp->wyv < -WASPVEL)
156 sp->wx[0] = sp->wx[1] + sp->wxv;
157 sp->wy[0] = sp->wy[1] + sp->wyv;
160 if ((sp->wx[0] < BORDER) || (sp->wx[0] > sp->width - BORDER - 1)) {
162 sp->wx[0] += sp->wxv;
164 if ((sp->wy[0] < BORDER) || (sp->wy[0] > sp->height - BORDER - 1)) {
166 sp->wy[0] += sp->wyv;
168 /* Don't let things settle down. */
169 sp->xv[random() % sp->beecount] += RAND(3);
170 sp->yv[random() % sp->beecount] += RAND(3);
173 for (b = 0; b < sp->beecount; b++) {
177 /* Age the arrays. */
184 dx = sp->wx[1] - X(1, b);
185 dy = sp->wy[1] - Y(1, b);
186 distance = abs(dx) + abs(dy); /* approximation */
189 sp->xv[b] += (dx * BEEACC) / distance;
190 sp->yv[b] += (dy * BEEACC) / distance;
192 /* Speed Limit Checks */
193 if (sp->xv[b] > BEEVEL)
195 if (sp->xv[b] < -BEEVEL)
197 if (sp->yv[b] > BEEVEL)
199 if (sp->yv[b] < -BEEVEL)
203 X(0, b) = X(1, b) + sp->xv[b];
204 Y(0, b) = Y(1, b) + sp->yv[b];
206 /* Fill the segment lists. */
207 sp->segs[b].x1 = X(0, b);
208 sp->segs[b].y1 = Y(0, b);
209 sp->segs[b].x2 = X(1, b);
210 sp->segs[b].y2 = Y(1, b);
211 sp->old_segs[b].x1 = X(1, b);
212 sp->old_segs[b].y1 = Y(1, b);
213 sp->old_segs[b].x2 = X(2, b);
214 sp->old_segs[b].y2 = Y(2, b);
217 XSetForeground(dsp, pwin->gc, BlackPixelOfScreen(pwin->perscreen->screen));
218 XDrawLine(dsp, pwin->w, pwin->gc,
219 sp->wx[1], sp->wy[1], sp->wx[2], sp->wy[2]);
220 XDrawSegments(dsp, pwin->w, pwin->gc, sp->old_segs, sp->beecount);
222 XSetForeground(dsp, pwin->gc, WhitePixelOfScreen(pwin->perscreen->screen));
223 XDrawLine(dsp, pwin->w, pwin->gc,
224 sp->wx[0], sp->wy[0], sp->wx[1], sp->wy[1]);
225 if (!mono && pwin->perscreen->npixels > 2) {
226 XSetForeground(dsp, pwin->gc, pwin->perscreen->pixels[sp->pix]);
227 if (++sp->pix >= pwin->perscreen->npixels)
230 XDrawSegments(dsp, pwin->w, pwin->gc, sp->segs, sp->beecount);