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: worm.c /main/3 1995/11/02 16:09:04 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 * worm.c - draw wiggly worms.
35 * Copyright (c) 1991 by Patrick J. Naughton.
37 * See dtscreen.c for copying information.
40 * 27-Sep-91: got rid of all malloc calls since there were no calls to free().
41 * 25-Sep-91: Integrated into X11R5 contrib dtscreen.
43 * Adapted from a concept in the Dec 87 issue of Scientific American.
45 * SunView version: Brad Taylor (brad@sun.com)
46 * X11 version: Dave Lemke (lemke@ncd.com)
47 * xlock version: Boris Putanec (bp@cs.brown.edu)
49 * This code is a static memory pig... like almost 200K... but as contributed
50 * it leaked at a massive rate, so I made everything static up front... feel
51 * free to contribute the proper memory management code.
64 #define PI 3.14159265358979323844
66 static int sintab[SEGMENTS];
67 static int costab[SEGMENTS];
68 static int init_table = 0;
71 int xcirc[MAXWORMLEN];
72 int ycirc[MAXWORMLEN];
86 wormstuff worm[MAXWORMS];
87 XRectangle rects[MAXCOLORS][MAXWORMS];
91 #if !defined(CSRG_BASED) && !defined(sun) && !defined(__linux__)
95 return ((int) floor((double) x));
101 worm_doit(perwindow *pwin, wormstruct *wp, int which, unsigned long color)
103 wormstuff *ws = &wp->worm[which];
107 if (ws->tail == wp->wormlength)
110 x = ws->xcirc[ws->tail];
111 y = ws->ycirc[ws->tail];
112 XClearArea(dsp, pwin->w, x, y, CIRCSIZE, CIRCSIZE, False);
115 ws->dir = (ws->dir + 1) % SEGMENTS;
117 ws->dir = (ws->dir + SEGMENTS - 1) % SEGMENTS;
120 x = (ws->x + costab[ws->dir] + wp->xsize) % wp->xsize;
121 y = (ws->y + sintab[ws->dir] + wp->ysize) % wp->ysize;
123 ws->xcirc[ws->tail] = x;
124 ws->ycirc[ws->tail] = y;
128 wp->rects[color][wp->size[color]].x = x;
129 wp->rects[color][wp->size[color]].y = y;
135 initworm(perwindow *pwin)
139 XWindowAttributes xwa;
141 if (pwin->data) free(pwin->data);
142 pwin->data = (void *)malloc(sizeof(wormstruct));
143 memset(pwin->data, '\0', sizeof(wormstruct));
144 wp = (wormstruct *)pwin->data;
145 wp->nc = pwin->perscreen->npixels;
146 if (wp->nc > MAXCOLORS)
150 if (wp->nw > MAXWORMS)
155 for (i = 0; i < SEGMENTS; i++) {
156 sintab[i] = round(CIRCSIZE * sin(i * 2 * PI / SEGMENTS));
157 costab[i] = round(CIRCSIZE * cos(i * 2 * PI / SEGMENTS));
160 XGetWindowAttributes(dsp, pwin->w, &xwa);
161 wp->xsize = xwa.width;
162 wp->ysize = xwa.height;
164 if (xwa.width < 100) {
165 wp->monopix = BlackPixelOfScreen(pwin->perscreen->screen);
166 wp->wormlength = MAXWORMLEN / 10;
168 wp->monopix = WhitePixelOfScreen(pwin->perscreen->screen);
169 wp->wormlength = MAXWORMLEN;
172 for (i = 0; i < wp->nc; i++) {
173 for (j = 0; j < wp->nw / wp->nc + 1; j++) {
174 wp->rects[i][j].width = CIRCSIZE;
175 wp->rects[i][j].height = CIRCSIZE;
178 memset(wp->size, '\0', wp->nc * sizeof(int));
180 for (i = 0; i < wp->nw; i++) {
181 for (j = 0; j < wp->wormlength; j++) {
182 wp->worm[i].xcirc[j] = wp->xsize / 2;
183 wp->worm[i].ycirc[j] = wp->ysize / 2;
185 wp->worm[i].dir = (unsigned) random() % SEGMENTS;
186 wp->worm[i].tail = 0;
187 wp->worm[i].x = wp->xsize / 2;
188 wp->worm[i].y = wp->ysize / 2;
191 XClearWindow(dsp, pwin->w);
196 drawworm(perwindow *pwin)
199 wormstruct *wp = (wormstruct *)pwin->data;
201 static unsigned int chromo = 0;
203 memset(wp->size, '\0', wp->nc * sizeof(int));
205 for (i = 0; i < wp->nw; i++) {
206 if (!mono && wp->nc > 2) {
207 wcolor = (i + chromo) % wp->nc;
209 worm_doit(pwin, wp, i, wcolor);
211 worm_doit(pwin, wp, i, 0);
214 if (!mono && wp->nc > 2) {
215 for (i = 0; i < wp->nc; i++) {
216 XSetForeground(dsp, pwin->gc, pwin->perscreen->pixels[i]);
217 XFillRectangles(dsp, pwin->w, pwin->gc, wp->rects[i],
221 XSetForeground(dsp, pwin->gc, wp->monopix);
222 XFillRectangles(dsp, pwin->w, pwin->gc, wp->rects[0],
226 if (++chromo == wp->nc)