1e6942693ff8329f8b33b85d8faf61da220cbd48
[ncurses.git] / test / newdemo.c
1 /*
2  *  newdemo.c   -       A demo program using PDCurses. The program illustrate
3  *                      the use of colours for text output.
4  *
5  * $Id: newdemo.c,v 1.29 2006/12/03 00:15:28 tom Exp $
6  */
7
8 #include <test.priv.h>
9
10 #include <time.h>
11
12 /*
13  *  The Australian map
14  */
15 static const char *AusMap[16] =
16 {
17     "           A           A ",
18     "    N.T. AAAAA       AAAA ",
19     "     AAAAAAAAAAA  AAAAAAAA ",
20     "   AAAAAAAAAAAAAAAAAAAAAAAAA Qld.",
21     "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA ",
22     "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ",
23     " AAAAAAAAAAAAAAAAAAAAAAAAAAAA ",
24     "   AAAAAAAAAAAAAAAAAAAAAAAAA N.S.W.",
25     "W.A. AAAAAAAAA      AAAAAA Vic.",
26     "       AAA   S.A.     AA",
27     "                       A  Tas.",
28     ""
29 };
30
31 /*
32  *  Funny messages
33  */
34 #define NMESSAGES   6
35
36 static NCURSES_CONST char *messages[] =
37 {
38     "Hello from the Land Down Under",
39     "The Land of crocs. and a big Red Rock",
40     "Where the sunflower runs along the highways",
41     "the dusty red roads lead one to loneliness",
42     "Blue sky in the morning and",
43     "freezing nights and twinkling stars",
44     ""
45 };
46
47 /*
48  *  Trap interrupt
49  */
50 static RETSIGTYPE
51 trap(int sig GCC_UNUSED)
52 {
53     endwin();
54     ExitProgram(EXIT_FAILURE);
55 }
56
57 /*
58  *  Wait for user
59  */
60 static int
61 WaitForUser(WINDOW *win)
62 {
63     time_t t;
64     chtype key;
65
66     nodelay(win, TRUE);
67     t = time((time_t *) 0);
68     while (1) {
69         if ((int) (key = wgetch(win)) != ERR) {
70             if (key == 'q' || key == 'Q')
71                 return 1;
72             else
73                 return 0;
74         }
75         if (time((time_t *) 0) - t > 5)
76             return 0;
77     }
78 }
79
80 static void
81 set_colors(WINDOW *win, int pair, int foreground, int background)
82 {
83     if (has_colors()) {
84         if (pair > COLOR_PAIRS)
85             pair = COLOR_PAIRS;
86         init_pair(pair, foreground, background);
87         wattrset(win, COLOR_PAIR(pair));
88     }
89 }
90
91 static chtype
92 use_colors(WINDOW *win, int pair, chtype attrs)
93 {
94     if (has_colors()) {
95         if (pair > COLOR_PAIRS)
96             pair = COLOR_PAIRS;
97         attrs |= COLOR_PAIR(pair);
98     }
99     wattrset(win, attrs);
100     return attrs;
101 }
102
103 /*
104  * Test sub windows
105  */
106 static int
107 SubWinTest(WINDOW *win)
108 {
109     int w, h, sw, sh, bx, by;
110     WINDOW *swin1, *swin2, *swin3;
111
112     getmaxyx(win, h, w);
113     getbegyx(win, by, bx);
114     sw = w / 3;
115     sh = h / 3;
116     if ((swin1 = subwin(win, sh, sw, by + 3, bx + 5)) == NULL)
117         return 1;
118     if ((swin2 = subwin(win, sh, sw, by + 4, bx + 8)) == NULL)
119         return 1;
120     if ((swin3 = subwin(win, sh, sw, by + 5, bx + 11)) == NULL)
121         return 1;
122
123     set_colors(swin1, 8, COLOR_RED, COLOR_BLUE);
124     werase(swin1);
125     mvwaddstr(swin1, 0, 3, "Sub-window 1");
126     wrefresh(swin1);
127
128     set_colors(swin2, 9, COLOR_CYAN, COLOR_MAGENTA);
129     werase(swin2);
130     mvwaddstr(swin2, 0, 3, "Sub-window 2");
131     wrefresh(swin2);
132
133     set_colors(swin3, 10, COLOR_YELLOW, COLOR_GREEN);
134     werase(swin3);
135     mvwaddstr(swin3, 0, 3, "Sub-window 3");
136     wrefresh(swin3);
137
138     delwin(swin1);
139     delwin(swin2);
140     delwin(swin3);
141     WaitForUser(win);
142     return 0;
143 }
144
145 static int
146 bounce(int n, int *dir, int len)
147 {
148     if (*dir > 0)
149         ++n;
150     else
151         --n;
152     if (n <= 1 || n >= len - 2)
153         *dir = *dir ? 0 : 1;
154     return n;
155 }
156
157 /*
158  *  Bouncing balls
159  */
160 static int
161 BouncingBalls(WINDOW *win)
162 {
163     int w, h;
164     int x1, y1, xd1, yd1;
165     int x2, y2, xd2, yd2;
166     int x3, y3, xd3, yd3;
167
168     getmaxyx(win, h, w);
169
170     x1 = 2 + rand() % (w - 4);
171     y1 = 2 + rand() % (h - 4);
172     x2 = 2 + rand() % (w - 4);
173     y2 = 2 + rand() % (h - 4);
174     x3 = 2 + rand() % (w - 4);
175     y3 = 2 + rand() % (h - 4);
176
177     xd1 = 1;
178     yd1 = 1;
179     xd2 = 1;
180     yd2 = 0;
181     xd3 = 0;
182     yd3 = 1;
183
184     nodelay(win, TRUE);
185
186     while (wgetch(win) == ERR) {
187         x1 = bounce(x1, &xd1, w);
188         y1 = bounce(y1, &yd1, h);
189         x2 = bounce(x2, &xd2, w);
190         y2 = bounce(y2, &yd2, h);
191         x3 = bounce(x3, &xd3, w);
192         y3 = bounce(y3, &yd3, h);
193
194         set_colors(win, 11, COLOR_RED, COLOR_BLUE);
195         mvwaddch(win, y1, x1, 'O');
196
197         set_colors(win, 12, COLOR_BLUE, COLOR_RED);
198         mvwaddch(win, y2, x2, '*');
199
200         set_colors(win, 13, COLOR_YELLOW, COLOR_WHITE);
201         mvwaddch(win, y3, x3, '@');
202
203         wmove(win, 0, 0);
204         wrefresh(win);
205         delay_output(100);
206     }
207     return 0;
208 }
209
210 /*
211  *  Main driver
212  */
213 int
214 main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
215 {
216     WINDOW *win;
217     int w, x, y, i, j, k;
218     char buffer[200];
219     const char *message;
220     int width, height;
221     chtype save[80];
222     chtype c;
223
224     setlocale(LC_ALL, "");
225
226     CATCHALL(trap);
227
228     initscr();
229     if (has_colors())
230         start_color();
231     cbreak();
232     curs_set(0);
233     width = 48;
234     height = 14;                /* Create a drawing window */
235     win = newwin(height, width, (LINES - height) / 2, (COLS - width) / 2);
236     if (win == NULL) {
237         endwin();
238         ExitProgram(EXIT_FAILURE);
239     }
240
241     while (1) {
242         set_colors(win, 1, COLOR_WHITE, COLOR_BLUE);
243         werase(win);
244
245         set_colors(win, 2, COLOR_RED, COLOR_RED);
246         box(win, ACS_VLINE, ACS_HLINE);
247         wrefresh(win);
248         /* Do ramdom output of a character */
249         use_colors(win, 1, A_NORMAL);
250         c = 'a';
251         for (i = 0; i < 5000; ++i) {
252             x = rand() % (width - 2) + 1;
253             y = rand() % (height - 2) + 1;
254             mvwaddch(win, y, x, c);
255             wrefresh(win);
256             nodelay(win, TRUE);
257             if (wgetch(win) != ERR)
258                 break;
259             if (i == 2000) {
260                 c = 'b';
261                 set_colors(win, 3, COLOR_CYAN, COLOR_YELLOW);
262             }
263         }
264
265         SubWinTest(win);
266         /* Erase and draw green window */
267         set_colors(win, 4, COLOR_YELLOW, COLOR_GREEN);
268         wbkgd(win, use_colors(win, 4, A_BOLD));
269         werase(win);
270         wrefresh(win);
271         /* Draw RED bounding box */
272         use_colors(win, 2, A_NORMAL);
273         box(win, ' ', ' ');
274         wrefresh(win);
275         /* Display Australia map */
276         use_colors(win, 4, A_BOLD);
277         i = 0;
278         while (*AusMap[i]) {
279             mvwaddstr(win, i + 1, 8, AusMap[i]);
280             wrefresh(win);
281             delay_output(50);
282             ++i;
283         }
284
285         set_colors(win, 5, COLOR_BLUE, COLOR_WHITE);
286         use_colors(win, 5, A_BLINK);
287         mvwaddstr(win, height - 2, 6, " PDCurses 2.1 for DOS, OS/2 and Unix");
288         wrefresh(win);
289
290         /* Draw running messages */
291         set_colors(win, 6, COLOR_YELLOW, COLOR_WHITE);
292         message = messages[j = 0];
293         i = 1;
294         w = width - 2;
295         strcpy(buffer, message);
296         while (j < NMESSAGES) {
297             while ((int) strlen(buffer) < w) {
298                 strcat(buffer, " ... ");
299                 strcat(buffer, messages[++j % NMESSAGES]);
300             }
301
302             if (i < w)
303                 mvwaddnstr(win, height / 2, w - i, buffer, i);
304             else
305                 mvwaddnstr(win, height / 2, 1, buffer, w);
306
307             wrefresh(win);
308             nodelay(win, TRUE);
309             if (wgetch(win) != ERR) {
310                 flushinp();
311                 break;
312             }
313             if (i++ >= w) {
314                 for (k = 0; (buffer[k] = buffer[k + 1]) != '\0'; k++) ;
315             }
316             delay_output(100);
317         }
318
319         j = 0;
320         /*  Draw running As across in RED */
321         set_colors(win, 7, COLOR_RED, COLOR_GREEN);
322         for (i = 2; i < width - 4; ++i) {
323             k = mvwinch(win, 4, i);
324             if (k == ERR)
325                 break;
326             save[j++] = c = k;
327             c &= A_CHARTEXT;
328             mvwaddch(win, 4, i, c);
329         }
330         wrefresh(win);
331
332         /* Put a message up wait for a key */
333         i = height - 2;
334         use_colors(win, 5, A_NORMAL);
335         mvwaddstr(win, i, 5, " Type a key to continue or 'Q' to quit ");
336         wrefresh(win);
337
338         if (WaitForUser(win) == 1)
339             break;
340
341         j = 0;                  /* Restore the old line */
342         for (i = 2; i < width - 4; ++i)
343             mvwaddch(win, 4, i, save[j++]);
344         wrefresh(win);
345
346         BouncingBalls(win);
347         /* Put a message up wait for a key */
348         i = height - 2;
349         use_colors(win, 5, A_NORMAL);
350         mvwaddstr(win, i, 5, " Type a key to continue or 'Q' to quit ");
351         wrefresh(win);
352         if (WaitForUser(win) == 1)
353             break;
354     }
355     endwin();
356     ExitProgram(EXIT_SUCCESS);
357 }