• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
trap(int sig GCC_UNUSED)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
WaitForUser(WINDOW * win)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
set_colors(WINDOW * win,int pair,int foreground,int background)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
use_colors(WINDOW * win,int pair,chtype attrs)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
SubWinTest(WINDOW * win)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
bounce(int n,int * dir,int len)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
BouncingBalls(WINDOW * win)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
usage(int ok)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* */
VERSION_COMMON()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 }
402