/* * newdemo.c - A demo program using PDCurses. The program illustrate * the use of colours for text output. * * $Id: newdemo.c,v 1.45 2017/09/30 15:43:08 tom Exp $ */ #include #include /* * The Australian map */ static CONST_MENUS char *AusMap[16] = { " A A ", " N.T. AAAAA AAAA ", " AAAAAAAAAAA AAAAAAAA ", " AAAAAAAAAAAAAAAAAAAAAAAAA Qld.", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA ", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ", " AAAAAAAAAAAAAAAAAAAAAAAAAAAA ", " AAAAAAAAAAAAAAAAAAAAAAAAA N.S.W.", "W.A. AAAAAAAAA AAAAAA Vic.", " AAA S.A. AA", " A Tas.", "" }; /* * Funny messages */ #define NMESSAGES 6 static const char *messages[] = { "Hello from the Land Down Under", "The Land of crocs. and a big Red Rock", "Where the sunflower runs along the highways", "the dusty red roads lead one to loneliness", "Blue sky in the morning and", "freezing nights and twinkling stars", "" }; /* * Trap interrupt */ static void trap(int sig GCC_UNUSED) { exit_curses(); ExitProgram(EXIT_FAILURE); } /* * Wait for user */ static int WaitForUser(WINDOW *win) { time_t t; chtype key; nodelay(win, TRUE); t = time((time_t *) 0); while (1) { if ((int) (key = (chtype) wgetch(win)) != ERR) { if (key == 'q' || key == 'Q') return 1; else return 0; } if (time((time_t *) 0) - t > 5) return 0; } } static void set_colors(WINDOW *win, int pair, int foreground, int background) { if (has_colors()) { if (pair > COLOR_PAIRS) pair = COLOR_PAIRS; init_pair((short) pair, (short) foreground, (short) background); (void) wattrset(win, AttrArg(COLOR_PAIR(pair), 0)); } } static chtype use_colors(WINDOW *win, int pair, chtype attrs) { if (has_colors()) { if (pair > COLOR_PAIRS) pair = COLOR_PAIRS; attrs |= (chtype) COLOR_PAIR(pair); } (void) wattrset(win, AttrArg(attrs, 0)); return attrs; } /* * Test sub windows */ static int SubWinTest(WINDOW *win) { int w, h, sw, sh, bx, by; WINDOW *swin1, *swin2, *swin3; getmaxyx(win, h, w); getbegyx(win, by, bx); sw = w / 3; sh = h / 3; if ((swin1 = subwin(win, sh, sw, by + 3, bx + 5)) == NULL) { return 1; } if ((swin2 = subwin(win, sh, sw, by + 4, bx + 8)) == NULL) { delwin(swin1); return 1; } if ((swin3 = subwin(win, sh, sw, by + 5, bx + 11)) == NULL) { delwin(swin1); delwin(swin2); return 1; } set_colors(swin1, 8, COLOR_RED, COLOR_BLUE); werase(swin1); MvWAddStr(swin1, 0, 3, "Sub-window 1"); wrefresh(swin1); set_colors(swin2, 9, COLOR_CYAN, COLOR_MAGENTA); werase(swin2); MvWAddStr(swin2, 0, 3, "Sub-window 2"); wrefresh(swin2); set_colors(swin3, 10, COLOR_YELLOW, COLOR_GREEN); werase(swin3); MvWAddStr(swin3, 0, 3, "Sub-window 3"); wrefresh(swin3); delwin(swin1); delwin(swin2); delwin(swin3); WaitForUser(win); return 0; } static int bounce(int n, int *dir, int len) { if (*dir > 0) ++n; else --n; if (n <= 1 || n >= len - 2) *dir = *dir ? 0 : 1; return n; } /* * Bouncing balls */ static int BouncingBalls(WINDOW *win) { int w, h; int x1, y1, xd1, yd1; int x2, y2, xd2, yd2; int x3, y3, xd3, yd3; getmaxyx(win, h, w); x1 = 2 + rand() % (w - 4); y1 = 2 + rand() % (h - 4); x2 = 2 + rand() % (w - 4); y2 = 2 + rand() % (h - 4); x3 = 2 + rand() % (w - 4); y3 = 2 + rand() % (h - 4); xd1 = 1; yd1 = 1; xd2 = 1; yd2 = 0; xd3 = 0; yd3 = 1; nodelay(win, TRUE); while (wgetch(win) == ERR) { x1 = bounce(x1, &xd1, w); y1 = bounce(y1, &yd1, h); x2 = bounce(x2, &xd2, w); y2 = bounce(y2, &yd2, h); x3 = bounce(x3, &xd3, w); y3 = bounce(y3, &yd3, h); set_colors(win, 11, COLOR_RED, COLOR_BLUE); MvWAddCh(win, y1, x1, 'O'); set_colors(win, 12, COLOR_BLUE, COLOR_RED); MvWAddCh(win, y2, x2, '*'); set_colors(win, 13, COLOR_YELLOW, COLOR_WHITE); MvWAddCh(win, y3, x3, '@'); wmove(win, 0, 0); wrefresh(win); delay_output(100); } return 0; } /* * Main driver */ int main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED) { WINDOW *win; int w, x, y, i, j, k; char buffer[SIZEOF(messages) * 80]; const char *message; int width, height; chtype save[80]; chtype c; setlocale(LC_ALL, ""); InitAndCatch(initscr(), trap); if (has_colors()) start_color(); cbreak(); curs_set(0); width = 48; height = 14; /* Create a drawing window */ win = newwin(height, width, (LINES - height) / 2, (COLS - width) / 2); if (win == NULL) { exit_curses(); ExitProgram(EXIT_FAILURE); } while (1) { set_colors(win, 1, COLOR_WHITE, COLOR_BLUE); werase(win); set_colors(win, 2, COLOR_RED, COLOR_RED); box(win, ACS_VLINE, ACS_HLINE); wrefresh(win); /* Do ramdom output of a character */ use_colors(win, 1, A_NORMAL); c = 'a'; for (i = 0; i < 5000; ++i) { x = rand() % (width - 2) + 1; y = rand() % (height - 2) + 1; MvWAddCh(win, y, x, c); wrefresh(win); nodelay(win, TRUE); if (wgetch(win) != ERR) break; if (i == 2000) { c = 'b'; set_colors(win, 3, COLOR_CYAN, COLOR_YELLOW); } } SubWinTest(win); /* Erase and draw green window */ set_colors(win, 4, COLOR_YELLOW, COLOR_GREEN); wbkgd(win, use_colors(win, 4, A_BOLD)); werase(win); wrefresh(win); /* Draw RED bounding box */ use_colors(win, 2, A_NORMAL); box(win, ' ', ' '); wrefresh(win); /* Display Australia map */ use_colors(win, 4, A_BOLD); i = 0; while (*AusMap[i]) { MvWAddStr(win, i + 1, 8, AusMap[i]); wrefresh(win); delay_output(50); ++i; } set_colors(win, 5, COLOR_BLUE, COLOR_WHITE); use_colors(win, 5, A_BLINK); MvWAddStr(win, height - 2, 6, " PDCurses 2.1 for DOS, OS/2 and Unix"); wrefresh(win); /* Draw running messages */ set_colors(win, 6, COLOR_YELLOW, COLOR_WHITE); message = messages[j = 0]; i = 1; w = width - 2; _nc_STRCPY(buffer, message, sizeof(buffer)); while (j < NMESSAGES) { while ((int) strlen(buffer) < w) { _nc_STRCAT(buffer, " ... ", sizeof(buffer)); _nc_STRCAT(buffer, messages[++j % NMESSAGES], sizeof(buffer)); } if (i < w) (void) mvwaddnstr(win, height / 2, w - i, buffer, i); else (void) mvwaddnstr(win, height / 2, 1, buffer, w); wrefresh(win); nodelay(win, TRUE); if (wgetch(win) != ERR) { flushinp(); break; } if (i++ >= w) { for (k = 0; (buffer[k] = buffer[k + 1]) != '\0'; k++) ; } delay_output(100); } j = 0; /* Draw running As across in RED */ set_colors(win, 7, COLOR_RED, COLOR_GREEN); memset(save, ' ', sizeof(save)); for (i = 2; i < width - 4; ++i) { k = (int) mvwinch(win, 4, i); if (k == ERR) break; save[j++] = c = (chtype) k; c &= A_CHARTEXT; MvWAddCh(win, 4, i, c); } wrefresh(win); /* Put a message up wait for a key */ i = height - 2; use_colors(win, 5, A_NORMAL); MvWAddStr(win, i, 5, " Type a key to continue or 'Q' to quit "); wrefresh(win); if (WaitForUser(win) == 1) break; j = 0; /* Restore the old line */ for (i = 2; i < width - 4; ++i) MvWAddCh(win, 4, i, save[j++]); wrefresh(win); BouncingBalls(win); /* Put a message up wait for a key */ i = height - 2; use_colors(win, 5, A_NORMAL); MvWAddStr(win, i, 5, " Type a key to continue or 'Q' to quit "); wrefresh(win); if (WaitForUser(win) == 1) break; } exit_curses(); ExitProgram(EXIT_SUCCESS); }