blob: 78761534d7c5efdac70f6ea19b6f8d2fc5066bdf [file] [log] [blame]
Steve Kondikae271bc2015-11-15 02:50:53 +01001/*
2 * newdemo.c - A demo program using PDCurses. The program illustrate
3 * the use of colours for text output.
4 *
micky3879b9f5e72025-07-08 18:04:53 -04005 * $Id: newdemo.c,v 1.48 2022/12/10 23:36:05 tom Exp $
Steve Kondikae271bc2015-11-15 02:50:53 +01006 */
7
8#include <test.priv.h>
9
10#include <time.h>
11
12/*
13 * The Australian map
14 */
15static 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
36static 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 */
50static void
51trap(int sig GCC_UNUSED)
52{
micky3879b9f5e72025-07-08 18:04:53 -040053 stop_curses();
Steve Kondikae271bc2015-11-15 02:50:53 +010054 ExitProgram(EXIT_FAILURE);
55}
56
57/*
58 * Wait for user
59 */
60static int
61WaitForUser(WINDOW *win)
62{
63 time_t t;
Steve Kondikae271bc2015-11-15 02:50:53 +010064
65 nodelay(win, TRUE);
66 t = time((time_t *) 0);
micky3879b9f5e72025-07-08 18:04:53 -040067
Steve Kondikae271bc2015-11-15 02:50:53 +010068 while (1) {
micky3879b9f5e72025-07-08 18:04:53 -040069 chtype key;
Steve Kondikae271bc2015-11-15 02:50:53 +010070 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
81static void
82set_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
92static chtype
93use_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 */
107static int
108SubWinTest(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
153static int
154bounce(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 */
168static int
169BouncingBalls(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
micky3879b9f5e72025-07-08 18:04:53 -0400218static void
219usage(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* */
235VERSION_COMMON()
236/* *INDENT-ON* */
237
Steve Kondikae271bc2015-11-15 02:50:53 +0100238/*
239 * Main driver
240 */
241int
micky3879b9f5e72025-07-08 18:04:53 -0400242main(int argc, char *argv[])
Steve Kondikae271bc2015-11-15 02:50:53 +0100243{
244 WINDOW *win;
micky3879b9f5e72025-07-08 18:04:53 -0400245 int x, y, i, k;
Steve Kondikae271bc2015-11-15 02:50:53 +0100246 char buffer[SIZEOF(messages) * 80];
Steve Kondikae271bc2015-11-15 02:50:53 +0100247 int width, height;
248 chtype save[80];
micky3879b9f5e72025-07-08 18:04:53 -0400249 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);
Steve Kondikae271bc2015-11-15 02:50:53 +0100263
264 setlocale(LC_ALL, "");
265
micky3879b9f5e72025-07-08 18:04:53 -0400266 InitAndCatch(initscr(), trap);
Steve Kondikae271bc2015-11-15 02:50:53 +0100267 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) {
micky3879b9f5e72025-07-08 18:04:53 -0400275 stop_curses();
Steve Kondikae271bc2015-11-15 02:50:53 +0100276 ExitProgram(EXIT_FAILURE);
277 }
278
279 while (1) {
micky3879b9f5e72025-07-08 18:04:53 -0400280 int w;
281 int j;
282 chtype c;
283 const char *message;
284
Steve Kondikae271bc2015-11-15 02:50:53 +0100285 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;
micky3879b9f5e72025-07-08 18:04:53 -0400338 _nc_STRCPY(buffer, message, sizeof(buffer));
Steve Kondikae271bc2015-11-15 02:50:53 +0100339 while (j < NMESSAGES) {
340 while ((int) strlen(buffer) < w) {
micky3879b9f5e72025-07-08 18:04:53 -0400341 _nc_STRCAT(buffer, " ... ", sizeof(buffer));
342 _nc_STRCAT(buffer, messages[++j % NMESSAGES], sizeof(buffer));
Steve Kondikae271bc2015-11-15 02:50:53 +0100343 }
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 }
micky3879b9f5e72025-07-08 18:04:53 -0400399 stop_curses();
Steve Kondikae271bc2015-11-15 02:50:53 +0100400 ExitProgram(EXIT_SUCCESS);
401}