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.31 2008/08/03 20:19:38 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 NCURSES_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 RETSIGTYPE 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 = 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(pair, foreground, background); 87 wattrset(win, COLOR_PAIR(pair)); 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 |= COLOR_PAIR(pair); 98 } 99 wattrset(win, attrs); 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 if ((swin1 = subwin(win, sh, sw, by + 3, bx + 5)) == NULL) 117 return 1; 118 if ((swin2 = subwin(win, sh, sw, by + 4, bx + 8)) == NULL) 119 return 1; 120 if ((swin3 = subwin(win, sh, sw, by + 5, bx + 11)) == NULL) 121 return 1; 122 123 set_colors(swin1, 8, COLOR_RED, COLOR_BLUE); 124 werase(swin1); 125 mvwaddstr(swin1, 0, 3, "Sub-window 1"); 126 wrefresh(swin1); 127 128 set_colors(swin2, 9, COLOR_CYAN, COLOR_MAGENTA); 129 werase(swin2); 130 mvwaddstr(swin2, 0, 3, "Sub-window 2"); 131 wrefresh(swin2); 132 133 set_colors(swin3, 10, COLOR_YELLOW, COLOR_GREEN); 134 werase(swin3); 135 mvwaddstr(swin3, 0, 3, "Sub-window 3"); 136 wrefresh(swin3); 137 138 delwin(swin1); 139 delwin(swin2); 140 delwin(swin3); 141 WaitForUser(win); 142 return 0; 143} 144 145static int 146bounce(int n, int *dir, int len) 147{ 148 if (*dir > 0) 149 ++n; 150 else 151 --n; 152 if (n <= 1 || n >= len - 2) 153 *dir = *dir ? 0 : 1; 154 return n; 155} 156 157/* 158 * Bouncing balls 159 */ 160static int 161BouncingBalls(WINDOW *win) 162{ 163 int w, h; 164 int x1, y1, xd1, yd1; 165 int x2, y2, xd2, yd2; 166 int x3, y3, xd3, yd3; 167 168 getmaxyx(win, h, w); 169 170 x1 = 2 + rand() % (w - 4); 171 y1 = 2 + rand() % (h - 4); 172 x2 = 2 + rand() % (w - 4); 173 y2 = 2 + rand() % (h - 4); 174 x3 = 2 + rand() % (w - 4); 175 y3 = 2 + rand() % (h - 4); 176 177 xd1 = 1; 178 yd1 = 1; 179 xd2 = 1; 180 yd2 = 0; 181 xd3 = 0; 182 yd3 = 1; 183 184 nodelay(win, TRUE); 185 186 while (wgetch(win) == ERR) { 187 x1 = bounce(x1, &xd1, w); 188 y1 = bounce(y1, &yd1, h); 189 x2 = bounce(x2, &xd2, w); 190 y2 = bounce(y2, &yd2, h); 191 x3 = bounce(x3, &xd3, w); 192 y3 = bounce(y3, &yd3, h); 193 194 set_colors(win, 11, COLOR_RED, COLOR_BLUE); 195 mvwaddch(win, y1, x1, 'O'); 196 197 set_colors(win, 12, COLOR_BLUE, COLOR_RED); 198 mvwaddch(win, y2, x2, '*'); 199 200 set_colors(win, 13, COLOR_YELLOW, COLOR_WHITE); 201 mvwaddch(win, y3, x3, '@'); 202 203 wmove(win, 0, 0); 204 wrefresh(win); 205 delay_output(100); 206 } 207 return 0; 208} 209 210/* 211 * Main driver 212 */ 213int 214main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED) 215{ 216 WINDOW *win; 217 int w, x, y, i, j, k; 218 char buffer[200]; 219 const char *message; 220 int width, height; 221 chtype save[80]; 222 chtype c; 223 224 setlocale(LC_ALL, ""); 225 226 CATCHALL(trap); 227 228 initscr(); 229 if (has_colors()) 230 start_color(); 231 cbreak(); 232 curs_set(0); 233 width = 48; 234 height = 14; /* Create a drawing window */ 235 win = newwin(height, width, (LINES - height) / 2, (COLS - width) / 2); 236 if (win == NULL) { 237 endwin(); 238 ExitProgram(EXIT_FAILURE); 239 } 240 241 while (1) { 242 set_colors(win, 1, COLOR_WHITE, COLOR_BLUE); 243 werase(win); 244 245 set_colors(win, 2, COLOR_RED, COLOR_RED); 246 box(win, ACS_VLINE, ACS_HLINE); 247 wrefresh(win); 248 /* Do ramdom output of a character */ 249 use_colors(win, 1, A_NORMAL); 250 c = 'a'; 251 for (i = 0; i < 5000; ++i) { 252 x = rand() % (width - 2) + 1; 253 y = rand() % (height - 2) + 1; 254 mvwaddch(win, y, x, c); 255 wrefresh(win); 256 nodelay(win, TRUE); 257 if (wgetch(win) != ERR) 258 break; 259 if (i == 2000) { 260 c = 'b'; 261 set_colors(win, 3, COLOR_CYAN, COLOR_YELLOW); 262 } 263 } 264 265 SubWinTest(win); 266 /* Erase and draw green window */ 267 set_colors(win, 4, COLOR_YELLOW, COLOR_GREEN); 268 wbkgd(win, use_colors(win, 4, A_BOLD)); 269 werase(win); 270 wrefresh(win); 271 /* Draw RED bounding box */ 272 use_colors(win, 2, A_NORMAL); 273 box(win, ' ', ' '); 274 wrefresh(win); 275 /* Display Australia map */ 276 use_colors(win, 4, A_BOLD); 277 i = 0; 278 while (*AusMap[i]) { 279 mvwaddstr(win, i + 1, 8, AusMap[i]); 280 wrefresh(win); 281 delay_output(50); 282 ++i; 283 } 284 285 set_colors(win, 5, COLOR_BLUE, COLOR_WHITE); 286 use_colors(win, 5, A_BLINK); 287 mvwaddstr(win, height - 2, 6, " PDCurses 2.1 for DOS, OS/2 and Unix"); 288 wrefresh(win); 289 290 /* Draw running messages */ 291 set_colors(win, 6, COLOR_YELLOW, COLOR_WHITE); 292 message = messages[j = 0]; 293 i = 1; 294 w = width - 2; 295 strcpy(buffer, message); 296 while (j < NMESSAGES) { 297 while ((int) strlen(buffer) < w) { 298 strcat(buffer, " ... "); 299 strcat(buffer, messages[++j % NMESSAGES]); 300 } 301 302 if (i < w) 303 mvwaddnstr(win, height / 2, w - i, buffer, i); 304 else 305 mvwaddnstr(win, height / 2, 1, buffer, w); 306 307 wrefresh(win); 308 nodelay(win, TRUE); 309 if (wgetch(win) != ERR) { 310 flushinp(); 311 break; 312 } 313 if (i++ >= w) { 314 for (k = 0; (buffer[k] = buffer[k + 1]) != '\0'; k++) ; 315 } 316 delay_output(100); 317 } 318 319 j = 0; 320 /* Draw running As across in RED */ 321 set_colors(win, 7, COLOR_RED, COLOR_GREEN); 322 memset(save, ' ', sizeof(save)); 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