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.27 2005/05/28 21:40:00 tom Exp $ 6 */ 7 8#include <test.priv.h> 9 10#include <time.h> 11 12#define delay_output(x) napms(x) 13 14/* 15 * The Australian map 16 */ 17static const char *AusMap[16] = 18{ 19 " A A ", 20 " N.T. AAAAA AAAA ", 21 " AAAAAAAAAAA AAAAAAAA ", 22 " AAAAAAAAAAAAAAAAAAAAAAAAA Qld.", 23 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA ", 24 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ", 25 " AAAAAAAAAAAAAAAAAAAAAAAAAAAA ", 26 " AAAAAAAAAAAAAAAAAAAAAAAAA N.S.W.", 27 "W.A. AAAAAAAAA AAAAAA Vic.", 28 " AAA S.A. AA", 29 " A Tas.", 30 "" 31}; 32 33/* 34 * Funny messages 35 */ 36#define NMESSAGES 6 37 38static NCURSES_CONST char *messages[] = 39{ 40 "Hello from the Land Down Under", 41 "The Land of crocs. and a big Red Rock", 42 "Where the sunflower runs along the highways", 43 "the dusty red roads lead one to loneliness", 44 "Blue sky in the morning and", 45 "freezing nights and twinkling stars", 46 "" 47}; 48 49/* 50 * Trap interrupt 51 */ 52static RETSIGTYPE 53trap(int sig GCC_UNUSED) 54{ 55 endwin(); 56 ExitProgram(EXIT_FAILURE); 57} 58 59/* 60 * Wait for user 61 */ 62static int 63WaitForUser(WINDOW *win) 64{ 65 time_t t; 66 chtype key; 67 68 nodelay(win, TRUE); 69 t = time((time_t *) 0); 70 while (1) { 71 if ((int) (key = wgetch(win)) != ERR) { 72 if (key == 'q' || key == 'Q') 73 return 1; 74 else 75 return 0; 76 } 77 if (time((time_t *) 0) - t > 5) 78 return 0; 79 } 80} 81 82static void 83set_colors(WINDOW *win, int pair, int foreground, int background) 84{ 85 if (has_colors()) { 86 if (pair > COLOR_PAIRS) 87 pair = COLOR_PAIRS; 88 init_pair(pair, foreground, background); 89 wattrset(win, COLOR_PAIR(pair)); 90 } 91} 92 93static chtype 94use_colors(WINDOW *win, int pair, chtype attrs) 95{ 96 if (has_colors()) { 97 if (pair > COLOR_PAIRS) 98 pair = COLOR_PAIRS; 99 attrs |= COLOR_PAIR(pair); 100 } 101 wattrset(win, attrs); 102 return attrs; 103} 104 105/* 106 * Test sub windows 107 */ 108static int 109SubWinTest(WINDOW *win) 110{ 111 int w, h, sw, sh, bx, by; 112 WINDOW *swin1, *swin2, *swin3; 113 114 getmaxyx(win, h, w); 115 getbegyx(win, by, bx); 116 sw = w / 3; 117 sh = h / 3; 118 if ((swin1 = subwin(win, sh, sw, by + 3, bx + 5)) == NULL) 119 return 1; 120 if ((swin2 = subwin(win, sh, sw, by + 4, bx + 8)) == NULL) 121 return 1; 122 if ((swin3 = subwin(win, sh, sw, by + 5, bx + 11)) == NULL) 123 return 1; 124 125 set_colors(swin1, 8, COLOR_RED, COLOR_BLUE); 126 werase(swin1); 127 mvwaddstr(swin1, 0, 3, "Sub-window 1"); 128 wrefresh(swin1); 129 130 set_colors(swin2, 9, COLOR_CYAN, COLOR_MAGENTA); 131 werase(swin2); 132 mvwaddstr(swin2, 0, 3, "Sub-window 2"); 133 wrefresh(swin2); 134 135 set_colors(swin3, 10, COLOR_YELLOW, COLOR_GREEN); 136 werase(swin3); 137 mvwaddstr(swin3, 0, 3, "Sub-window 3"); 138 wrefresh(swin3); 139 140 delwin(swin1); 141 delwin(swin2); 142 delwin(swin3); 143 WaitForUser(win); 144 return 0; 145} 146 147static int 148bounce(int n, int *dir, int len) 149{ 150 if (*dir > 0) 151 ++n; 152 else 153 --n; 154 if (n <= 1 || n >= len - 2) 155 *dir = *dir ? 0 : 1; 156 return n; 157} 158 159/* 160 * Bouncing balls 161 */ 162static int 163BouncingBalls(WINDOW *win) 164{ 165 int w, h; 166 int x1, y1, xd1, yd1; 167 int x2, y2, xd2, yd2; 168 int x3, y3, xd3, yd3; 169 170 getmaxyx(win, h, w); 171 172 x1 = 2 + rand() % (w - 4); 173 y1 = 2 + rand() % (h - 4); 174 x2 = 2 + rand() % (w - 4); 175 y2 = 2 + rand() % (h - 4); 176 x3 = 2 + rand() % (w - 4); 177 y3 = 2 + rand() % (h - 4); 178 179 xd1 = 1; 180 yd1 = 1; 181 xd2 = 1; 182 yd2 = 0; 183 xd3 = 0; 184 yd3 = 1; 185 186 nodelay(win, TRUE); 187 188 while (wgetch(win) == ERR) { 189 x1 = bounce(x1, &xd1, w); 190 y1 = bounce(y1, &yd1, h); 191 x2 = bounce(x2, &xd2, w); 192 y2 = bounce(y2, &yd2, h); 193 x3 = bounce(x3, &xd3, w); 194 y3 = bounce(y3, &yd3, h); 195 196 set_colors(win, 11, COLOR_RED, COLOR_BLUE); 197 mvwaddch(win, y1, x1, 'O'); 198 199 set_colors(win, 12, COLOR_BLUE, COLOR_RED); 200 mvwaddch(win, y2, x2, '*'); 201 202 set_colors(win, 13, COLOR_YELLOW, COLOR_WHITE); 203 mvwaddch(win, y3, x3, '@'); 204 205 wmove(win, 0, 0); 206 wrefresh(win); 207 delay_output(100); 208 } 209 return 0; 210} 211 212/* 213 * Main driver 214 */ 215int 216main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED) 217{ 218 WINDOW *win; 219 int w, x, y, i, j, k; 220 char buffer[200]; 221 const char *message; 222 int width, height; 223 chtype save[80]; 224 chtype c; 225 226 setlocale(LC_ALL, ""); 227 228 initscr(); 229 if (has_colors()) 230 start_color(); 231 cbreak(); 232 curs_set(0); 233 signal(SIGINT, trap); 234 width = 48; 235 height = 14; /* Create a drawing window */ 236 win = newwin(height, width, (LINES - height) / 2, (COLS - width) / 2); 237 if (win == NULL) { 238 endwin(); 239 ExitProgram(EXIT_FAILURE); 240 } 241 242 while (1) { 243 set_colors(win, 1, COLOR_WHITE, COLOR_BLUE); 244 werase(win); 245 246 set_colors(win, 2, COLOR_RED, COLOR_RED); 247 box(win, ACS_VLINE, ACS_HLINE); 248 wrefresh(win); 249 /* Do ramdom output of a character */ 250 use_colors(win, 1, A_NORMAL); 251 c = 'a'; 252 for (i = 0; i < 5000; ++i) { 253 x = rand() % (width - 2) + 1; 254 y = rand() % (height - 2) + 1; 255 mvwaddch(win, y, x, c); 256 wrefresh(win); 257 nodelay(win, TRUE); 258 if (wgetch(win) != ERR) 259 break; 260 if (i == 2000) { 261 c = 'b'; 262 set_colors(win, 3, COLOR_CYAN, COLOR_YELLOW); 263 } 264 } 265 266 SubWinTest(win); 267 /* Erase and draw green window */ 268 set_colors(win, 4, COLOR_YELLOW, COLOR_GREEN); 269 wbkgd(win, use_colors(win, 4, A_BOLD)); 270 werase(win); 271 wrefresh(win); 272 /* Draw RED bounding box */ 273 use_colors(win, 2, A_NORMAL); 274 box(win, ' ', ' '); 275 wrefresh(win); 276 /* Display Australia map */ 277 use_colors(win, 4, A_BOLD); 278 i = 0; 279 while (*AusMap[i]) { 280 mvwaddstr(win, i + 1, 8, AusMap[i]); 281 wrefresh(win); 282 delay_output(50); 283 ++i; 284 } 285 286 set_colors(win, 5, COLOR_BLUE, COLOR_WHITE); 287 use_colors(win, 5, A_BLINK); 288 mvwaddstr(win, height - 2, 6, " PDCurses 2.1 for DOS, OS/2 and Unix"); 289 wrefresh(win); 290 291 /* Draw running messages */ 292 set_colors(win, 6, COLOR_YELLOW, COLOR_WHITE); 293 message = messages[j = 0]; 294 i = 1; 295 w = width - 2; 296 strcpy(buffer, message); 297 while (j < NMESSAGES) { 298 while ((int) strlen(buffer) < w) { 299 strcat(buffer, " ... "); 300 strcat(buffer, messages[++j % NMESSAGES]); 301 } 302 303 if (i < w) 304 mvwaddnstr(win, height / 2, w - i, buffer, i); 305 else 306 mvwaddnstr(win, height / 2, 1, buffer, w); 307 308 wrefresh(win); 309 nodelay(win, TRUE); 310 if (wgetch(win) != ERR) { 311 flushinp(); 312 break; 313 } 314 if (i++ >= w) { 315 for (k = 0; (buffer[k] = buffer[k + 1]) != '\0'; k++) ; 316 } 317 delay_output(100); 318 } 319 320 j = 0; 321 /* Draw running As across in RED */ 322 set_colors(win, 7, COLOR_RED, COLOR_GREEN); 323 for (i = 2; i < width - 4; ++i) { 324 k = mvwinch(win, 4, i); 325 if (k == ERR) 326 break; 327 save[j++] = c = k; 328 c &= A_CHARTEXT; 329 mvwaddch(win, 4, i, c); 330 } 331 wrefresh(win); 332 333 /* Put a message up wait for a key */ 334 i = height - 2; 335 use_colors(win, 5, A_NORMAL); 336 mvwaddstr(win, i, 5, " Type a key to continue or 'Q' to quit "); 337 wrefresh(win); 338 339 if (WaitForUser(win) == 1) 340 break; 341 342 j = 0; /* Restore the old line */ 343 for (i = 2; i < width - 4; ++i) 344 mvwaddch(win, 4, i, save[j++]); 345 wrefresh(win); 346 347 BouncingBalls(win); 348 /* Put a message up wait for a key */ 349 i = height - 2; 350 use_colors(win, 5, A_NORMAL); 351 mvwaddstr(win, i, 5, " Type a key to continue or 'Q' to quit "); 352 wrefresh(win); 353 if (WaitForUser(win) == 1) 354 break; 355 } 356 endwin(); 357 ExitProgram(EXIT_SUCCESS); 358} 359