]> ncurses.scripts.mit.edu Git - ncurses.git/blob - test/newdemo.c
ncurses 6.3 - patch 20221210
[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.48 2022/12/10 23:36:05 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 void
51 trap(int sig GCC_UNUSED)
52 {
53     stop_curses();
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
65     nodelay(win, TRUE);
66     t = time((time_t *) 0);
67
68     while (1) {
69         chtype key;
70         if ((int) (key = (chtype) wgetch(win)) != ERR) {
71             if (key == 'q' || key == 'Q')
72                 return 1;
73             else
74                 return 0;
75         }
76         if (time((time_t *) 0) - t > 5)
77             return 0;
78     }
79 }
80
81 static void
82 set_colors(WINDOW *win, int pair, int foreground, int background)
83 {
84     if (has_colors()) {
85         if (pair > COLOR_PAIRS)
86             pair = COLOR_PAIRS;
87         init_pair((short) pair, (short) foreground, (short) background);
88         (void) wattrset(win, AttrArg(COLOR_PAIR(pair), 0));
89     }
90 }
91
92 static chtype
93 use_colors(WINDOW *win, int pair, chtype attrs)
94 {
95     if (has_colors()) {
96         if (pair > COLOR_PAIRS)
97             pair = COLOR_PAIRS;
98         attrs |= (chtype) COLOR_PAIR(pair);
99     }
100     (void) wattrset(win, AttrArg(attrs, 0));
101     return attrs;
102 }
103
104 /*
105  * Test sub windows
106  */
107 static int
108 SubWinTest(WINDOW *win)
109 {
110     int w, h, sw, sh, bx, by;
111     WINDOW *swin1, *swin2, *swin3;
112
113     getmaxyx(win, h, w);
114     getbegyx(win, by, bx);
115     sw = w / 3;
116     sh = h / 3;
117
118     if ((swin1 = subwin(win, sh, sw, by + 3, bx + 5)) == NULL) {
119         return 1;
120     }
121     if ((swin2 = subwin(win, sh, sw, by + 4, bx + 8)) == NULL) {
122         delwin(swin1);
123         return 1;
124     }
125     if ((swin3 = subwin(win, sh, sw, by + 5, bx + 11)) == NULL) {
126         delwin(swin1);
127         delwin(swin2);
128         return 1;
129     }
130
131     set_colors(swin1, 8, COLOR_RED, COLOR_BLUE);
132     werase(swin1);
133     MvWAddStr(swin1, 0, 3, "Sub-window 1");
134     wrefresh(swin1);
135
136     set_colors(swin2, 9, COLOR_CYAN, COLOR_MAGENTA);
137     werase(swin2);
138     MvWAddStr(swin2, 0, 3, "Sub-window 2");
139     wrefresh(swin2);
140
141     set_colors(swin3, 10, COLOR_YELLOW, COLOR_GREEN);
142     werase(swin3);
143     MvWAddStr(swin3, 0, 3, "Sub-window 3");
144     wrefresh(swin3);
145
146     delwin(swin1);
147     delwin(swin2);
148     delwin(swin3);
149     WaitForUser(win);
150     return 0;
151 }
152
153 static int
154 bounce(int n, int *dir, int len)
155 {
156     if (*dir > 0)
157         ++n;
158     else
159         --n;
160     if (n <= 1 || n >= len - 2)
161         *dir = *dir ? 0 : 1;
162     return n;
163 }
164
165 /*
166  *  Bouncing balls
167  */
168 static int
169 BouncingBalls(WINDOW *win)
170 {
171     int w, h;
172     int x1, y1, xd1, yd1;
173     int x2, y2, xd2, yd2;
174     int x3, y3, xd3, yd3;
175
176     getmaxyx(win, h, w);
177
178     x1 = 2 + rand() % (w - 4);
179     y1 = 2 + rand() % (h - 4);
180     x2 = 2 + rand() % (w - 4);
181     y2 = 2 + rand() % (h - 4);
182     x3 = 2 + rand() % (w - 4);
183     y3 = 2 + rand() % (h - 4);
184
185     xd1 = 1;
186     yd1 = 1;
187     xd2 = 1;
188     yd2 = 0;
189     xd3 = 0;
190     yd3 = 1;
191
192     nodelay(win, TRUE);
193
194     while (wgetch(win) == ERR) {
195         x1 = bounce(x1, &xd1, w);
196         y1 = bounce(y1, &yd1, h);
197         x2 = bounce(x2, &xd2, w);
198         y2 = bounce(y2, &yd2, h);
199         x3 = bounce(x3, &xd3, w);
200         y3 = bounce(y3, &yd3, h);
201
202         set_colors(win, 11, COLOR_RED, COLOR_BLUE);
203         MvWAddCh(win, y1, x1, 'O');
204
205         set_colors(win, 12, COLOR_BLUE, COLOR_RED);
206         MvWAddCh(win, y2, x2, '*');
207
208         set_colors(win, 13, COLOR_YELLOW, COLOR_WHITE);
209         MvWAddCh(win, y3, x3, '@');
210
211         wmove(win, 0, 0);
212         wrefresh(win);
213         delay_output(100);
214     }
215     return 0;
216 }
217
218 static void
219 usage(int ok)
220 {
221     static const char *msg[] =
222     {
223         "Usage: newdemo [options]"
224         ,""
225         ,USAGE_COMMON
226     };
227     size_t n;
228
229     for (n = 0; n < SIZEOF(msg); n++)
230         fprintf(stderr, "%s\n", msg[n]);
231
232     ExitProgram(ok ? EXIT_SUCCESS : EXIT_FAILURE);
233 }
234 /* *INDENT-OFF* */
235 VERSION_COMMON()
236 /* *INDENT-ON* */
237
238 /*
239  *  Main driver
240  */
241 int
242 main(int argc, char *argv[])
243 {
244     WINDOW *win;
245     int x, y, i, k;
246     char buffer[SIZEOF(messages) * 80];
247     int width, height;
248     chtype save[80];
249     int ch;
250
251     while ((ch = getopt(argc, argv, OPTS_COMMON)) != -1) {
252         switch (ch) {
253         case OPTS_VERSION:
254             show_version(argv);
255             ExitProgram(EXIT_SUCCESS);
256         default:
257             usage(ch == OPTS_USAGE);
258             /* NOTREACHED */
259         }
260     }
261     if (optind < argc)
262         usage(FALSE);
263
264     setlocale(LC_ALL, "");
265
266     InitAndCatch(initscr(), trap);
267     if (has_colors())
268         start_color();
269     cbreak();
270     curs_set(0);
271     width = 48;
272     height = 14;                /* Create a drawing window */
273     win = newwin(height, width, (LINES - height) / 2, (COLS - width) / 2);
274     if (win == NULL) {
275         stop_curses();
276         ExitProgram(EXIT_FAILURE);
277     }
278
279     while (1) {
280         int w;
281         int j;
282         chtype c;
283         const char *message;
284
285         set_colors(win, 1, COLOR_WHITE, COLOR_BLUE);
286         werase(win);
287
288         set_colors(win, 2, COLOR_RED, COLOR_RED);
289         box(win, ACS_VLINE, ACS_HLINE);
290         wrefresh(win);
291         /* Do ramdom output of a character */
292         use_colors(win, 1, A_NORMAL);
293         c = 'a';
294         for (i = 0; i < 5000; ++i) {
295             x = rand() % (width - 2) + 1;
296             y = rand() % (height - 2) + 1;
297             MvWAddCh(win, y, x, c);
298             wrefresh(win);
299             nodelay(win, TRUE);
300             if (wgetch(win) != ERR)
301                 break;
302             if (i == 2000) {
303                 c = 'b';
304                 set_colors(win, 3, COLOR_CYAN, COLOR_YELLOW);
305             }
306         }
307
308         SubWinTest(win);
309         /* Erase and draw green window */
310         set_colors(win, 4, COLOR_YELLOW, COLOR_GREEN);
311         wbkgd(win, use_colors(win, 4, A_BOLD));
312         werase(win);
313         wrefresh(win);
314         /* Draw RED bounding box */
315         use_colors(win, 2, A_NORMAL);
316         box(win, ' ', ' ');
317         wrefresh(win);
318         /* Display Australia map */
319         use_colors(win, 4, A_BOLD);
320         i = 0;
321         while (*AusMap[i]) {
322             MvWAddStr(win, i + 1, 8, AusMap[i]);
323             wrefresh(win);
324             delay_output(50);
325             ++i;
326         }
327
328         set_colors(win, 5, COLOR_BLUE, COLOR_WHITE);
329         use_colors(win, 5, A_BLINK);
330         MvWAddStr(win, height - 2, 6, " PDCurses 2.1 for DOS, OS/2 and Unix");
331         wrefresh(win);
332
333         /* Draw running messages */
334         set_colors(win, 6, COLOR_YELLOW, COLOR_WHITE);
335         message = messages[j = 0];
336         i = 1;
337         w = width - 2;
338         _nc_STRCPY(buffer, message, sizeof(buffer));
339         while (j < NMESSAGES) {
340             while ((int) strlen(buffer) < w) {
341                 _nc_STRCAT(buffer, " ... ", sizeof(buffer));
342                 _nc_STRCAT(buffer, messages[++j % NMESSAGES], sizeof(buffer));
343             }
344
345             if (i < w)
346                 (void) mvwaddnstr(win, height / 2, w - i, buffer, i);
347             else
348                 (void) mvwaddnstr(win, height / 2, 1, buffer, w);
349
350             wrefresh(win);
351             nodelay(win, TRUE);
352             if (wgetch(win) != ERR) {
353                 flushinp();
354                 break;
355             }
356             if (i++ >= w) {
357                 for (k = 0; (buffer[k] = buffer[k + 1]) != '\0'; k++) ;
358             }
359             delay_output(100);
360         }
361
362         j = 0;
363         /*  Draw running As across in RED */
364         set_colors(win, 7, COLOR_RED, COLOR_GREEN);
365         memset(save, ' ', sizeof(save));
366         for (i = 2; i < width - 4; ++i) {
367             k = (int) mvwinch(win, 4, i);
368             if (k == ERR)
369                 break;
370             save[j++] = c = (chtype) k;
371             c &= A_CHARTEXT;
372             MvWAddCh(win, 4, i, c);
373         }
374         wrefresh(win);
375
376         /* Put a message up wait for a key */
377         i = height - 2;
378         use_colors(win, 5, A_NORMAL);
379         MvWAddStr(win, i, 5, " Type a key to continue or 'Q' to quit ");
380         wrefresh(win);
381
382         if (WaitForUser(win) == 1)
383             break;
384
385         j = 0;                  /* Restore the old line */
386         for (i = 2; i < width - 4; ++i)
387             MvWAddCh(win, 4, i, save[j++]);
388         wrefresh(win);
389
390         BouncingBalls(win);
391         /* Put a message up wait for a key */
392         i = height - 2;
393         use_colors(win, 5, A_NORMAL);
394         MvWAddStr(win, i, 5, " Type a key to continue or 'Q' to quit ");
395         wrefresh(win);
396         if (WaitForUser(win) == 1)
397             break;
398     }
399     stop_curses();
400     ExitProgram(EXIT_SUCCESS);
401 }