blob: f9b6f82f6038099c042f88b03055bc4e8bb45bdc [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 *
5 * $Id: newdemo.c,v 1.41 2014/08/02 23:10:56 tom Exp $
6 */
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{
53 endwin();
54 ExitProgram(EXIT_FAILURE);
55}
56
57/*
58 * Wait for user
59 */
60static int
61WaitForUser(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
80static void
81set_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, AttrArg(COLOR_PAIR(pair), 0));
88 }
89}
90
91static chtype
92use_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, AttrArg(attrs, 0));
100 return attrs;
101}
102
103/*
104 * Test sub windows
105 */
106static int
107SubWinTest(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
152static int
153bounce(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 */
167static int
168BouncingBalls(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 */
220int
221main(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}