dtscreen: Resolve a -Wformat-security warning.
[oweals/cde.git] / cde / programs / dtscreen / worm.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
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)
10  * any later version.
11  *
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
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: worm.c /main/3 1995/11/02 16:09:04 rswiston $ */
24 /*
25  */
26 /*                                                                      *
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.                                *
31  */
32 /*-
33  * worm.c - draw wiggly worms.
34  *
35  * Copyright (c) 1991 by Patrick J. Naughton.
36  *
37  * See dtscreen.c for copying information.
38  *
39  * Revision History:
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.
42  *
43  * Adapted from a concept in the Dec 87 issue of Scientific American.
44  *
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)
48  *
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.
52  * 
53  */
54
55 #include "dtscreen.h"
56 #include <math.h>
57 #include <stdlib.h>
58
59 #define MAXCOLORS 64
60 #define MAXWORMS 64
61 #define CIRCSIZE 2
62 #define MAXWORMLEN 50
63
64 #define PI 3.14159265358979323844
65 #define SEGMENTS  36
66 static int  sintab[SEGMENTS];
67 static int  costab[SEGMENTS];
68 static int  init_table = 0;
69
70 typedef struct {
71     int         xcirc[MAXWORMLEN];
72     int         ycirc[MAXWORMLEN];
73     int         dir;
74     int         tail;
75     int         x;
76     int         y;
77 }           wormstuff;
78
79 typedef struct {
80     int         xsize;
81     int         ysize;
82     int         wormlength;
83     int         monopix;
84     int         nc;
85     int         nw;
86     wormstuff   worm[MAXWORMS];
87     XRectangle  rects[MAXCOLORS][MAXWORMS];
88     int         size[MAXCOLORS];
89 }           wormstruct;
90
91 #if !defined(CSRG_BASED)
92 int
93 round(x)
94     float       x;
95 {
96     return ((int) floor((double) x));
97 }
98 #endif
99
100
101 void
102 worm_doit(pwin, wp, which, color)
103     perwindow *pwin;
104     wormstruct *wp;
105     int         which;
106     unsigned long color;
107 {
108     wormstuff  *ws = &wp->worm[which];
109     int         x, y;
110
111     ws->tail++;
112     if (ws->tail == wp->wormlength)
113         ws->tail = 0;
114
115     x = ws->xcirc[ws->tail];
116     y = ws->ycirc[ws->tail];
117     XClearArea(dsp, pwin->w, x, y, CIRCSIZE, CIRCSIZE, False);
118
119     if (random() & 1) {
120         ws->dir = (ws->dir + 1) % SEGMENTS;
121     } else {
122         ws->dir = (ws->dir + SEGMENTS - 1) % SEGMENTS;
123     }
124
125     x = (ws->x + costab[ws->dir] + wp->xsize) % wp->xsize;
126     y = (ws->y + sintab[ws->dir] + wp->ysize) % wp->ysize;
127
128     ws->xcirc[ws->tail] = x;
129     ws->ycirc[ws->tail] = y;
130     ws->x = x;
131     ws->y = y;
132
133     wp->rects[color][wp->size[color]].x = x;
134     wp->rects[color][wp->size[color]].y = y;
135     wp->size[color]++;
136 }
137
138
139 void
140 initworm(pwin)
141     perwindow *pwin;
142 {
143     int         i, j;
144     wormstruct *wp;
145     XWindowAttributes xwa;
146
147     if (pwin->data) free(pwin->data);
148     pwin->data = (void *)malloc(sizeof(wormstruct));
149     memset(pwin->data, '\0', sizeof(wormstruct));
150     wp = (wormstruct *)pwin->data;
151     wp->nc = pwin->perscreen->npixels;
152     if (wp->nc > MAXCOLORS)
153         wp->nc = MAXCOLORS;
154
155     wp->nw = batchcount;
156     if (wp->nw > MAXWORMS)
157         wp->nw = MAXWORMS;
158
159     if (!init_table) {
160         init_table = 1;
161         for (i = 0; i < SEGMENTS; i++) {
162             sintab[i] = round(CIRCSIZE * sin(i * 2 * PI / SEGMENTS));
163             costab[i] = round(CIRCSIZE * cos(i * 2 * PI / SEGMENTS));
164         }
165     }
166     XGetWindowAttributes(dsp, pwin->w, &xwa);
167     wp->xsize = xwa.width;
168     wp->ysize = xwa.height;
169
170     if (xwa.width < 100) {
171         wp->monopix = BlackPixelOfScreen(pwin->perscreen->screen);
172         wp->wormlength = MAXWORMLEN / 10;
173     } else {
174         wp->monopix = WhitePixelOfScreen(pwin->perscreen->screen);
175         wp->wormlength = MAXWORMLEN;
176     }
177
178     for (i = 0; i < wp->nc; i++) {
179         for (j = 0; j < wp->nw / wp->nc + 1; j++) {
180             wp->rects[i][j].width = CIRCSIZE;
181             wp->rects[i][j].height = CIRCSIZE;
182         }
183     }
184     memset(wp->size, '\0', wp->nc * sizeof(int));
185
186     for (i = 0; i < wp->nw; i++) {
187         for (j = 0; j < wp->wormlength; j++) {
188             wp->worm[i].xcirc[j] = wp->xsize / 2;
189             wp->worm[i].ycirc[j] = wp->ysize / 2;
190         }
191         wp->worm[i].dir = (unsigned) random() % SEGMENTS;
192         wp->worm[i].tail = 0;
193         wp->worm[i].x = wp->xsize / 2;
194         wp->worm[i].y = wp->ysize / 2;
195     }
196
197     XClearWindow(dsp, pwin->w);
198 }
199
200
201 void
202 drawworm(pwin)
203     perwindow *pwin;
204 {
205     int         i;
206     wormstruct *wp = (wormstruct *)pwin->data;
207     unsigned int wcolor;
208     static unsigned int chromo = 0;
209
210     memset(wp->size, '\0', wp->nc * sizeof(int));
211
212     for (i = 0; i < wp->nw; i++) {
213         if (!mono && wp->nc > 2) {
214             wcolor = (i + chromo) % wp->nc;
215
216             worm_doit(pwin, wp, i, wcolor);
217         } else
218             worm_doit(pwin, wp, i, 0);
219     }
220
221     if (!mono && wp->nc > 2) {
222         for (i = 0; i < wp->nc; i++) {
223             XSetForeground(dsp, pwin->gc, pwin->perscreen->pixels[i]);
224             XFillRectangles(dsp, pwin->w, pwin->gc, wp->rects[i],
225                             wp->size[i]);
226         }
227     } else {
228         XSetForeground(dsp, pwin->gc, wp->monopix);
229         XFillRectangles(dsp, pwin->w, pwin->gc, wp->rects[0],
230                         wp->size[0]);
231     }
232
233     if (++chromo == wp->nc)
234         chromo = 0;
235 }