ncurses 5.9 - patch 20130209
[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.39 2012/12/29 23:39:08 tom Exp $
6  */
7
8 #include <test.priv.h>
9
10 #include <time.h>
11
12 /*
13  *  The Australian map
14  */
15 static CONST_MENUS 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 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 = (chtype) 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((short) pair, (short) foreground, (short) background);
87         (void) wattrset(win, (int) 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 |= (chtype) COLOR_PAIR(pair);
98     }
99     (void) wattrset(win, (int) 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
117     if ((swin1 = subwin(win, sh, sw, by + 3, bx + 5)) == NULL) {
118         return 1;
119     }
120     if ((swin2 = subwin(win, sh, sw, by + 4, bx + 8)) == NULL) {
121         delwin(swin1);
122         return 1;
123     }
124     if ((swin3 = subwin(win, sh, sw, by + 5, bx + 11)) == NULL) {
125         delwin(swin1);
126         delwin(swin2);
127         return 1;
128     }
129
130     set_colors(swin1, 8, COLOR_RED, COLOR_BLUE);
131     werase(swin1);
132     MvWAddStr(swin1, 0, 3, "Sub-window 1");
133     wrefresh(swin1);
134
135     set_colors(swin2, 9, COLOR_CYAN, COLOR_MAGENTA);
136     werase(swin2);
137     MvWAddStr(swin2, 0, 3, "Sub-window 2");
138     wrefresh(swin2);
139
140     set_colors(swin3, 10, COLOR_YELLOW, COLOR_GREEN);
141     werase(swin3);
142     MvWAddStr(swin3, 0, 3, "Sub-window 3");
143     wrefresh(swin3);
144
145     delwin(swin1);
146     delwin(swin2);
147     delwin(swin3);
148     WaitForUser(win);
149     return 0;
150 }
151
152 static int
153 bounce(int n, int *dir, int len)
154 {
155     if (*dir > 0)
156         ++n;
157     else
158         --n;
159     if (n <= 1 || n >= len - 2)
160         *dir = *dir ? 0 : 1;
161     return n;
162 }
163
164 /*
165  *  Bouncing balls
166  */
167 static int
168 BouncingBalls(WINDOW *win)
169 {
170     int w, h;
171     int x1, y1, xd1, yd1;
172     int x2, y2, xd2, yd2;
173     int x3, y3, xd3, yd3;
174
175     getmaxyx(win, h, w);
176
177     x1 = 2 + rand() % (w - 4);
178     y1 = 2 + rand() % (h - 4);
179     x2 = 2 + rand() % (w - 4);
180     y2 = 2 + rand() % (h - 4);
181     x3 = 2 + rand() % (w - 4);
182     y3 = 2 + rand() % (h - 4);
183
184     xd1 = 1;
185     yd1 = 1;
186     xd2 = 1;
187     yd2 = 0;
188     xd3 = 0;
189     yd3 = 1;
190
191     nodelay(win, TRUE);
192
193     while (wgetch(win) == ERR) {
194         x1 = bounce(x1, &xd1, w);
195         y1 = bounce(y1, &yd1, h);
196         x2 = bounce(x2, &xd2, w);
197         y2 = bounce(y2, &yd2, h);
198         x3 = bounce(x3, &xd3, w);
199         y3 = bounce(y3, &yd3, h);
200
201         set_colors(win, 11, COLOR_RED, COLOR_BLUE);
202         MvWAddCh(win, y1, x1, 'O');
203
204         set_colors(win, 12, COLOR_BLUE, COLOR_RED);
205         MvWAddCh(win, y2, x2, '*');
206
207         set_colors(win, 13, COLOR_YELLOW, COLOR_WHITE);
208         MvWAddCh(win, y3, x3, '@');
209
210         wmove(win, 0, 0);
211         wrefresh(win);
212         delay_output(100);
213     }
214     return 0;
215 }
216
217 /*
218  *  Main driver
219  */
220 int
221 main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
222 {
223     WINDOW *win;
224     int w, x, y, i, j, k;
225     char buffer[SIZEOF(messages) * 80];
226     const char *message;
227     int width, height;
228     chtype save[80];
229     chtype c;
230
231     setlocale(LC_ALL, "");
232
233     CATCHALL(trap);
234
235     initscr();
236     if (has_colors())
237         start_color();
238     cbreak();
239     curs_set(0);
240     width = 48;
241     height = 14;                /* Create a drawing window */
242     win = newwin(height, width, (LINES - height) / 2, (COLS - width) / 2);
243     if (win == NULL) {
244         endwin();
245         ExitProgram(EXIT_FAILURE);
246     }
247
248     while (1) {
249         set_colors(win, 1, COLOR_WHITE, COLOR_BLUE);
250         werase(win);
251
252         set_colors(win, 2, COLOR_RED, COLOR_RED);
253         box(win, ACS_VLINE, ACS_HLINE);
254         wrefresh(win);
255         /* Do ramdom output of a character */
256         use_colors(win, 1, A_NORMAL);
257         c = 'a';
258         for (i = 0; i < 5000; ++i) {
259             x = rand() % (width - 2) + 1;
260             y = rand() % (height - 2) + 1;
261             MvWAddCh(win, y, x, c);
262             wrefresh(win);
263             nodelay(win, TRUE);
264             if (wgetch(win) != ERR)
265                 break;
266             if (i == 2000) {
267                 c = 'b';
268                 set_colors(win, 3, COLOR_CYAN, COLOR_YELLOW);
269             }
270         }
271
272         SubWinTest(win);
273         /* Erase and draw green window */
274         set_colors(win, 4, COLOR_YELLOW, COLOR_GREEN);
275         wbkgd(win, use_colors(win, 4, A_BOLD));
276         werase(win);
277         wrefresh(win);
278         /* Draw RED bounding box */
279         use_colors(win, 2, A_NORMAL);
280         box(win, ' ', ' ');
281         wrefresh(win);
282         /* Display Australia map */
283         use_colors(win, 4, A_BOLD);
284         i = 0;
285         while (*AusMap[i]) {
286             MvWAddStr(win, i + 1, 8, AusMap[i]);
287             wrefresh(win);
288             delay_output(50);
289             ++i;
290         }
291
292         set_colors(win, 5, COLOR_BLUE, COLOR_WHITE);
293         use_colors(win, 5, A_BLINK);
294         MvWAddStr(win, height - 2, 6, " PDCurses 2.1 for DOS, OS/2 and Unix");
295         wrefresh(win);
296
297         /* Draw running messages */
298         set_colors(win, 6, COLOR_YELLOW, COLOR_WHITE);
299         message = messages[j = 0];
300         i = 1;
301         w = width - 2;
302         strcpy(buffer, message);
303         while (j < NMESSAGES) {
304             while ((int) strlen(buffer) < w) {
305                 strcat(buffer, " ... ");
306                 strcat(buffer, messages[++j % NMESSAGES]);
307             }
308
309             if (i < w)
310                 (void) mvwaddnstr(win, height / 2, w - i, buffer, i);
311             else
312                 (void) mvwaddnstr(win, height / 2, 1, buffer, w);
313
314             wrefresh(win);
315             nodelay(win, TRUE);
316             if (wgetch(win) != ERR) {
317                 flushinp();
318                 break;
319             }
320             if (i++ >= w) {
321                 for (k = 0; (buffer[k] = buffer[k + 1]) != '\0'; k++) ;
322             }
323             delay_output(100);
324         }
325
326         j = 0;
327         /*  Draw running As across in RED */
328         set_colors(win, 7, COLOR_RED, COLOR_GREEN);
329         memset(save, ' ', sizeof(save));
330         for (i = 2; i < width - 4; ++i) {
331             k = (int) mvwinch(win, 4, i);
332             if (k == ERR)
333                 break;
334             save[j++] = c = (chtype) k;
335             c &= A_CHARTEXT;
336             MvWAddCh(win, 4, i, c);
337         }
338         wrefresh(win);
339
340         /* Put a message up wait for a key */
341         i = height - 2;
342         use_colors(win, 5, A_NORMAL);
343         MvWAddStr(win, i, 5, " Type a key to continue or 'Q' to quit ");
344         wrefresh(win);
345
346         if (WaitForUser(win) == 1)
347             break;
348
349         j = 0;                  /* Restore the old line */
350         for (i = 2; i < width - 4; ++i)
351             MvWAddCh(win, 4, i, save[j++]);
352         wrefresh(win);
353
354         BouncingBalls(win);
355         /* Put a message up wait for a key */
356         i = height - 2;
357         use_colors(win, 5, A_NORMAL);
358         MvWAddStr(win, i, 5, " Type a key to continue or 'Q' to quit ");
359         wrefresh(win);
360         if (WaitForUser(win) == 1)
361             break;
362     }
363     endwin();
364     ExitProgram(EXIT_SUCCESS);
365 }