X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=test%2Fncurses.c;h=5764dd75c2451d15da18f53507d7077e393995f8;hp=bb7f77c690541e80f8ab95824827e66da14818fb;hb=3e0f770501852be3a2cb05d8044219d7b04dbfad;hpb=a0b91dc27f0c411e343161b0a4b5459d15a43f85 diff --git a/test/ncurses.c b/test/ncurses.c index bb7f77c6..5764dd75 100644 --- a/test/ncurses.c +++ b/test/ncurses.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2014,2015 Free Software Foundation, Inc. * + * Copyright (c) 1998-2015,2016 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -40,7 +40,7 @@ AUTHOR Author: Eric S. Raymond 1993 Thomas E. Dickey (beginning revision 1.27 in 1996). -$Id: ncurses.c,v 1.421 2015/10/24 23:32:57 tom Exp $ +$Id: ncurses.c,v 1.438 2016/06/11 21:05:48 tom Exp $ ***************************************************************************/ @@ -200,9 +200,9 @@ Repaint(void) } static bool -isQuit(int c) +isQuit(int c, bool escape) { - return ((c) == QUIT || (c) == ESCAPE); + return ((c) == QUIT || (escape && ((c) == ESCAPE))); } #define case_QUIT QUIT: case ESCAPE @@ -636,15 +636,24 @@ setup_getch(WINDOW *win, GetchFlags flags) } static void -init_getch(WINDOW *win, GetchFlags flags) +init_getch(WINDOW *win, GetchFlags flags, int delay) { memset(flags, FALSE, NUM_GETCH_FLAGS); flags[UChar('k')] = (win == stdscr); flags[UChar('m')] = TRUE; + flags[UChar('t')] = (delay != 0); setup_getch(win, flags); } +static bool +blocking_getch(GetchFlags flags, int delay) +{ + return ((delay < 0) && flags['t']); +} + +#define ExitOnEscape() (flags[UChar('k')] && flags[UChar('t')]) + static void wgetch_help(WINDOW *win, GetchFlags flags) { @@ -655,7 +664,8 @@ wgetch_help(WINDOW *win, GetchFlags flags) ,"k -- toggle keypad/literal mode" ,"m -- toggle meta (7-bit/8-bit) mode" ,"^q -- quit" - ,"s -- shell out\n" + ,"s -- shell out" + ,"t -- toggle timeout" ,"w -- create a new window" #ifdef SIGTSTP ,"z -- suspend this process" @@ -670,13 +680,16 @@ wgetch_help(WINDOW *win, GetchFlags flags) printw("Type any key to see its %s value. Also:\n", flags['k'] ? "keypad" : "literal"); for (n = 0; n < SIZEOF(help); ++n) { + const char *msg = help[n]; int row = 1 + (int) (n % chk); int col = (n >= chk) ? COLS / 2 : 0; - int flg = ((strstr(help[n], "toggle") != 0) - && (flags[UChar(*help[n])] != FALSE)); + int flg = ((strstr(msg, "toggle") != 0) + && (flags[UChar(*msg)] != FALSE)); + if (*msg == '^' && ExitOnEscape()) + msg = "^[,^q -- quit"; if (flg) (void) standout(); - MvPrintw(row, col, "%s", help[n]); + MvPrintw(row, col, "%s", msg); if (col == 0) clrtoeol(); if (flg) @@ -810,9 +823,9 @@ wgetch_test(unsigned level, WINDOW *win, int delay) int c; int incount = 0; GetchFlags flags; - bool blocking = (delay < 0); - init_getch(win, flags); + init_getch(win, flags, delay); + notimeout(win, FALSE); wtimeout(win, delay); getyx(win, first_y, first_x); @@ -823,7 +836,7 @@ wgetch_test(unsigned level, WINDOW *win, int delay) for (;;) { while ((c = wGetchar(win)) == ERR) { incount++; - if (blocking) { + if (blocking_getch(flags, delay)) { (void) wprintw(win, "%05d: input error", incount); break; } else { @@ -831,10 +844,10 @@ wgetch_test(unsigned level, WINDOW *win, int delay) } wgetch_wrap(win, first_y); } - if (c == ERR && blocking) { + if (c == ERR && blocking_getch(flags, delay)) { wprintw(win, "ERR"); wgetch_wrap(win, first_y); - } else if (isQuit(c)) { + } else if (isQuit(c, ExitOnEscape())) { break; } else if (c == 'e') { flags[UChar('e')] = !flags[UChar('e')]; @@ -860,6 +873,10 @@ wgetch_test(unsigned level, WINDOW *win, int delay) wgetch_help(win, flags); } else if (c == 's') { ShellOut(TRUE); + } else if (c == 't') { + notimeout(win, flags[UChar('t')]); + flags[UChar('t')] = !flags[UChar('t')]; + wgetch_help(win, flags); } else if (c == 'w') { int high = getmaxy(win) - 1 - first_y + 1; int wide = getmaxx(win) - first_x; @@ -931,7 +948,7 @@ wgetch_test(unsigned level, WINDOW *win, int delay) wtimeout(win, -1); if (!level) - init_getch(win, flags); + init_getch(win, flags, delay); } static int @@ -958,7 +975,7 @@ begin_getch_test(void) delay = -1; } raw(); - move(5, 0); + move(6, 0); return delay; } @@ -1060,11 +1077,11 @@ wget_wch_test(unsigned level, WINDOW *win, int delay) wint_t c; int incount = 0; GetchFlags flags; - bool blocking = (delay < 0); int code; char *temp; - init_getch(win, flags); + init_getch(win, flags, delay); + notimeout(win, FALSE); wtimeout(win, delay); getyx(win, first_y, first_x); @@ -1075,7 +1092,7 @@ wget_wch_test(unsigned level, WINDOW *win, int delay) for (;;) { while ((code = wGet_wchar(win, &c)) == ERR) { incount++; - if (blocking) { + if (blocking_getch(flags, delay)) { (void) wprintw(win, "%05d: input error", incount); break; } else { @@ -1083,10 +1100,10 @@ wget_wch_test(unsigned level, WINDOW *win, int delay) } wgetch_wrap(win, first_y); } - if (code == ERR && blocking) { + if (code == ERR && blocking_getch(flags, delay)) { wprintw(win, "ERR"); wgetch_wrap(win, first_y); - } else if (isQuit((int) c)) { + } else if (isQuit((int) c, ExitOnEscape())) { break; } else if (c == 'e') { flags[UChar('e')] = !flags[UChar('e')]; @@ -1125,6 +1142,10 @@ wget_wch_test(unsigned level, WINDOW *win, int delay) wgetch_help(win, flags); } else if (c == 's') { ShellOut(TRUE); + } else if (c == 't') { + notimeout(win, flags[UChar('t')]); + flags[UChar('t')] = !flags[UChar('t')]; + wgetch_help(win, flags); } else if (c == 'w') { int high = getmaxy(win) - 1 - first_y + 1; int wide = getmaxx(win) - first_x; @@ -1184,7 +1205,7 @@ wget_wch_test(unsigned level, WINDOW *win, int delay) wtimeout(win, -1); if (!level) - init_getch(win, flags); + init_getch(win, flags, delay); } static void @@ -1413,7 +1434,7 @@ static int show_attr(WINDOW *win, int row, int skip, bool arrow, chtype attr, const char *name) { int ncv = get_ncv(); - chtype test = attr & (chtype) (~A_ALTCHARSET); + chtype test = attr & (chtype) (~(A_ALTCHARSET | A_CHARTEXT)); if (arrow) MvPrintw(row, COLS_PRE_ATTRS - 3, "-->"); @@ -1478,8 +1499,9 @@ show_attr(WINDOW *win, int row, int skip, bool arrow, chtype attr, const char *n if (found) printw(" (NCV)"); } - if ((termattrs() & test) != test) + if ((termattrs() & test) != test) { printw(" (Part)"); + } } } return row + 2; @@ -1868,8 +1890,9 @@ wide_show_attr(WINDOW *win, if (found) printw(" (NCV)"); } - if ((term_attrs() & test) != test) + if ((term_attrs() & test) != test) { printw(" (Part)"); + } } } return row + 2; @@ -2167,9 +2190,10 @@ color_test(void) int page_size = (LINES - grid_top); int pairs_max; int colors_max = COLORS; + int col_limit; int row_limit; int per_row; - char numbered[80]; + char *numbered = 0; const char *hello; bool done = FALSE; bool opt_acsc = FALSE; @@ -2179,6 +2203,15 @@ color_test(void) bool opt_wide = FALSE; WINDOW *helpwin; + numbered = (char *) calloc((size_t) (COLS + 1), sizeof(char)); + done = ((COLS < 16) || (numbered == 0)); + + /* + * Because the number of colors is usually a power of two, we also use + * a power of two for the number of colors shown per line (to be tidy). + */ + for (col_limit = 1; col_limit * 2 < COLS; col_limit *= 2) ; + while (!done) { int shown = 0; @@ -2196,11 +2229,11 @@ color_test(void) if (opt_wide) { width = 4; hello = "Test"; - per_row = (colors_max > 8) ? 16 : 8; + per_row = (col_limit / ((colors_max > 8) ? 4 : 8)); } else { width = 8; hello = "Hello"; - per_row = 8; + per_row = (col_limit / 8); } per_row -= min_colors; @@ -2231,6 +2264,9 @@ color_test(void) int col = (i % per_row + 1) * width; NCURSES_PAIRS_T pair = i; + if ((i / per_row) > row_limit) + break; + #define InxToFG(i) (NCURSES_COLOR_T) ((i % (colors_max - min_colors)) + min_colors) #define InxToBG(i) (NCURSES_COLOR_T) ((i / (colors_max - min_colors)) + min_colors) if (row >= 0 && move(row, col) != ERR) { @@ -2357,6 +2393,8 @@ color_test(void) erase(); endwin(); + + free(numbered); } #if USE_WIDEC_SUPPORT @@ -2371,9 +2409,10 @@ wide_color_test(void) int page_size = (LINES - grid_top); int pairs_max = (unsigned short) (-1); int colors_max = COLORS; + int col_limit; int row_limit; int per_row; - char numbered[80]; + char *numbered = 0; const char *hello; bool done = FALSE; bool opt_acsc = FALSE; @@ -2382,9 +2421,19 @@ wide_color_test(void) bool opt_wide = FALSE; bool opt_nums = FALSE; bool opt_xchr = FALSE; - wchar_t buffer[80]; + wchar_t *buffer = 0; WINDOW *helpwin; + numbered = (char *) calloc((size_t) (COLS + 1), sizeof(char)); + buffer = (wchar_t *) calloc((size_t) (COLS + 1), sizeof(wchar_t)); + done = ((COLS < 16) || (numbered == 0) || (buffer == 0)); + + /* + * Because the number of colors is usually a power of two, we also use + * a power of two for the number of colors shown per line (to be tidy). + */ + for (col_limit = 1; col_limit * 2 < COLS; col_limit *= 2) ; + while (!done) { int shown = 0; @@ -2398,15 +2447,14 @@ wide_color_test(void) pairs_max = COLOR_PAIRS; } - /* this assumes an 80-column line */ if (opt_wide) { width = 4; hello = "Test"; - per_row = (colors_max > 8) ? 16 : 8; + per_row = (col_limit / ((colors_max > 8) ? 4 : 8)); } else { width = 8; hello = "Hello"; - per_row = 8; + per_row = (col_limit / 8); } per_row -= min_colors; @@ -2445,6 +2493,9 @@ wide_color_test(void) int col = (i % per_row + 1) * width; NCURSES_PAIRS_T pair = (NCURSES_PAIRS_T) i; + if ((i / per_row) > row_limit) + break; + if (row >= 0 && move(row, col) != ERR) { init_pair(pair, InxToFG(i), InxToBG(i)); (void) color_set(pair, NULL); @@ -2576,6 +2627,9 @@ wide_color_test(void) erase(); endwin(); + + free(numbered); + free(buffer); } #endif /* USE_WIDEC_SUPPORT */ @@ -2603,7 +2657,7 @@ change_color(NCURSES_PAIRS_T current, int field, int value, int usebase) } static void -init_all_colors(void) +reset_all_colors(void) { NCURSES_PAIRS_T c; @@ -2614,6 +2668,85 @@ init_all_colors(void) all_colors[c].blue); } +#define okCOLOR(n) ((n) >= 0 && (n) < max_colors) +#define okRGB(n) ((n) >= 0 && (n) <= 1000) +#define DecodeRGB(n) (NCURSES_COLOR_T) ((n * 1000) / 0xffff) + +static void +init_all_colors(bool xterm_colors, char *palette_file) +{ + NCURSES_PAIRS_T cp; + all_colors = typeMalloc(RGB_DATA, (unsigned) max_colors); + if (!all_colors) + failed("all_colors"); + for (cp = 0; cp < max_colors; ++cp) { + color_content(cp, + &all_colors[cp].red, + &all_colors[cp].green, + &all_colors[cp].blue); + } + /* xterm and compatible terminals can read results of an OSC string + * asking for the current color palette. + */ + if (xterm_colors) { + int n; + int got; + char result[BUFSIZ]; + int check_n, check_r, check_g, check_b; + + raw(); + noecho(); + for (n = 0; n < max_colors; ++n) { + fprintf(stderr, "\033]4;%d;?\007", n); + got = (int) read(0, result, sizeof(result) - 1); + if (got < 0) + break; + result[got] = '\0'; + if (sscanf(result, "\033]4;%d;rgb:%x/%x/%x\007", + &check_n, + &check_r, + &check_g, + &check_b) == 4 && + check_n == n) { + all_colors[n].red = DecodeRGB(check_r); + all_colors[n].green = DecodeRGB(check_g); + all_colors[n].blue = DecodeRGB(check_b); + } else { + break; + } + } + reset_prog_mode(); + } + if (palette_file != 0) { + FILE *fp = fopen(palette_file, "r"); + if (fp != 0) { + char buffer[BUFSIZ]; + int red, green, blue; + int scale = 1000; + int c; + while (fgets(buffer, sizeof(buffer), fp) != 0) { + if (sscanf(buffer, "scale:%d", &c) == 1) { + scale = c; + } else if (sscanf(buffer, "%d:%d %d %d", + &c, + &red, + &green, + &blue) == 4 + && okCOLOR(c) + && okRGB(red) + && okRGB(green) + && okRGB(blue)) { +#define Scaled(n) (NCURSES_COLOR_T) (((n) * 1000) / scale) + all_colors[c].red = Scaled(red); + all_colors[c].green = Scaled(green); + all_colors[c].blue = Scaled(blue); + } + } + fclose(fp); + } + } +} + #define scaled_rgb(n) ((255 * (n)) / 1000) static void @@ -2621,14 +2754,23 @@ color_edit(void) /* display the color test pattern, without trying to edit colors */ { int i; - int current = 0; - int this_c = 0, value = 0, field = 0; + int current; + int this_c, value, field; int last_c; - int top_color = 0; - int page_size = (LINES - 6); - - init_all_colors(); - refresh(); + int top_color; + int page_size; + + reset_all_colors(); +#ifdef KEY_RESIZE + retry: +#endif + current = 0; + this_c = 0; + value = 0; + field = 0; + top_color = 0; + page_size = (LINES - 6); + erase(); for (i = 0; i < max_colors; i++) init_pair((NCURSES_PAIRS_T) i, @@ -2697,6 +2839,21 @@ color_edit(void) value = 0; switch (this_c) { +#ifdef KEY_RESIZE + case KEY_RESIZE: + move(0, 0); + goto retry; +#endif + case '!': + ShellOut(FALSE); + /* FALLTHRU */ + case CTRL('r'): + endwin(); + refresh(); + break; + case CTRL('l'): + refresh(); + break; case CTRL('b'): case KEY_PPAGE: if (current > 0) @@ -2723,10 +2880,12 @@ color_edit(void) current = (current == (max_colors - 1) ? 0 : current + 1); break; + case '\t': case KEY_RIGHT: field = (field == 2 ? 0 : field + 1); break; + case KEY_BTAB: case KEY_LEFT: field = (field == 0 ? 2 : field - 1); break; @@ -2769,6 +2928,8 @@ color_edit(void) P("To increment or decrement a value, use the same procedure, but finish"); P("with a `+' or `-'."); P(""); + P("Use `!' to shell-out, ^R or ^L to repaint the screen."); + P(""); P("Press 'm' to invoke the top-level menu with the current color settings."); P("To quit, do ESC"); @@ -2806,14 +2967,14 @@ color_edit(void) MvPrintw(LINES - 1, 0, "Number: %d", value); clrtoeol(); } while - (!isQuit(this_c)); + (!isQuit(this_c, TRUE)); erase(); /* * ncurses does not reset each color individually when calling endwin(). */ - init_all_colors(); + reset_all_colors(); endwin(); } @@ -3066,7 +3227,7 @@ slk_test(void) beep(); break; } - } while (!isQuit(c = Getchar())); + } while (!isQuit(c = Getchar(), TRUE)); done: slk_clear(); @@ -3220,7 +3381,7 @@ wide_slk_test(void) beep(); break; } - } while (!isQuit(c = Getchar())); + } while (!isQuit(c = Getchar(), TRUE)); done: slk_clear(); @@ -3560,7 +3721,7 @@ acs_display(void) my_list[at_code].name); } refresh(); - } while (!isQuit(c = Getchar())); + } while (!isQuit(c = Getchar(), TRUE)); Pause(); erase(); @@ -4095,7 +4256,7 @@ wide_acs_display(void) my_list[at_code].name); } refresh(); - } while (!isQuit(c = Getchar())); + } while (!isQuit(c = Getchar(), TRUE)); Pause(); erase(); @@ -4205,13 +4366,10 @@ FRAME WINDOW *wind; }; -#if defined(NCURSES_VERSION) -#if (NCURSES_VERSION_PATCH < 20070331) && NCURSES_EXT_FUNCS +#if defined(NCURSES_VERSION) && NCURSES_EXT_FUNCS +#if (NCURSES_VERSION_PATCH < 20070331) #define is_keypad(win) (win)->_use_keypad #define is_scrollok(win) (win)->_scroll -#elif !defined(is_keypad) -#define is_keypad(win) FALSE -#define is_scrollok(win) FALSE #endif #else #define is_keypad(win) FALSE @@ -4247,46 +4405,26 @@ HaveScroll(FRAME * curp) static void newwin_legend(FRAME * curp) { +#define DATA(num, name) { name, num } static const struct { const char *msg; int code; } legend[] = { - { - "^C = create window", 0 - }, - { - "^N = next window", 0 - }, - { - "^P = previous window", 0 - }, - { - "^F = scroll forward", 0 - }, - { - "^B = scroll backward", 0 - }, - { - "^K = keypad(%s)", 1 - }, - { - "^S = scrollok(%s)", 2 - }, - { - "^W = save window to file", 0 - }, - { - "^R = restore window", 0 - }, + DATA(0, "^C = create window"), + DATA(0, "^N = next window"), + DATA(0, "^P = previous window"), + DATA(0, "^F = scroll forward"), + DATA(0, "^B = scroll backward"), + DATA(1, "^K = keypad(%s)"), + DATA(2, "^S = scrollok(%s)"), + DATA(0, "^W = save window"), + DATA(0, "^R = restore window"), #if HAVE_WRESIZE - { - "^X = resize", 0 - }, + DATA(0, "^X = resize"), #endif - { - "^Q%s = exit", 3 - } + DATA(3, "^Q%s = exit") }; +#undef DATA size_t n; int x; bool do_keypad = HaveKeypad(curp); @@ -4596,10 +4734,14 @@ acs_and_scroll(void) } else if ((fp = fopen(DUMPFILE, "w")) == (FILE *) 0) { transient(current, "Can't open screen dump file"); } else { - (void) putwin(frame_win(current), fp); + int rc = putwin(frame_win(current), fp); (void) fclose(fp); - current = delete_framed(current, TRUE); + if (rc == OK) { + current = delete_framed(current, TRUE); + } else { + transient(current, "Can't write screen dump file"); + } } break; @@ -4685,12 +4827,6 @@ acs_and_scroll(void) break; #endif /* HAVE_WRESIZE */ - case KEY_F(10): /* undocumented --- use this to test area clears */ - selectcell(0, 0, LINES - 1, COLS - 1); - clrtobot(); - refresh(); - break; - case KEY_UP: newwin_move(current, -1, 0); break; @@ -4734,7 +4870,7 @@ acs_and_scroll(void) usescr = frame_win(current); wrefresh(usescr); } while - (!isQuit(c = wGetchar(usescr)) + (!isQuit(c = wGetchar(usescr), TRUE) && (c != ERR)); breakout: @@ -6626,7 +6762,7 @@ overlap_test(void) memset(flavor, 0, sizeof(flavor)); state = overlap_help(0, flavor); - while (!isQuit(ch = Getchar())) + while (!isQuit(ch = Getchar(), TRUE)) switch (ch) { case 'a': /* refresh window A first, then B */ overlap_test_0(win1, win2); @@ -6874,6 +7010,7 @@ usage(void) #ifdef TRACE ," -t mask specify default trace-level (may toggle with ^T)" #endif + ," -x use xterm-compatible control for reading color palette" }; size_t n; for (n = 0; n < SIZEOF(tbl); n++) @@ -7039,9 +7176,6 @@ main_menu(bool top) main(argc,argv) --------------------------------------------------------------------------*/ -#define okCOLOR(n) ((n) >= 0 && (n) < max_colors) -#define okRGB(n) ((n) >= 0 && (n) <= 1000) - int main(int argc, char *argv[]) { @@ -7055,10 +7189,11 @@ main(int argc, char *argv[]) #endif char *palette_file = 0; bool monochrome = FALSE; + bool xterm_colors = FALSE; setlocale(LC_ALL, ""); - while ((c = getopt(argc, argv, "a:dEe:fhmp:s:Tt:")) != -1) { + while ((c = getopt(argc, argv, "a:dEe:fhmp:s:Tt:x")) != -1) { switch (c) { #ifdef NCURSES_VERSION case 'a': @@ -7120,6 +7255,9 @@ main(int argc, char *argv[]) save_trace = (unsigned) strtol(optarg, 0, 0); break; #endif + case 'x': + xterm_colors = TRUE; + break; default: usage(); } @@ -7154,6 +7292,9 @@ main(int argc, char *argv[]) initscr(); bkgdset(BLANK); + set_terminal_modes(); + def_prog_mode(); + /* tests, in general, will want these modes */ use_colors = (bool) (monochrome ? FALSE : has_colors()); @@ -7177,47 +7318,9 @@ main(int argc, char *argv[]) max_pairs = COLOR_PAIRS; /* was > 256 ? 256 : COLOR_PAIRS */ if (can_change_color()) { - NCURSES_PAIRS_T cp; - all_colors = typeMalloc(RGB_DATA, (unsigned) max_colors); - if (!all_colors) - failed("all_colors"); - for (cp = 0; cp < max_colors; ++cp) { - color_content(cp, - &all_colors[cp].red, - &all_colors[cp].green, - &all_colors[cp].blue); - } - if (palette_file != 0) { - FILE *fp = fopen(palette_file, "r"); - if (fp != 0) { - char buffer[BUFSIZ]; - int red, green, blue; - int scale = 1000; - while (fgets(buffer, sizeof(buffer), fp) != 0) { - if (sscanf(buffer, "scale:%d", &c) == 1) { - scale = c; - } else if (sscanf(buffer, "%d:%d %d %d", - &c, - &red, - &green, - &blue) == 4 - && okCOLOR(c) - && okRGB(red) - && okRGB(green) - && okRGB(blue)) { -#define Scaled(n) (NCURSES_COLOR_T) (((n) * 1000) / scale) - all_colors[c].red = Scaled(red); - all_colors[c].green = Scaled(green); - all_colors[c].blue = Scaled(blue); - } - } - fclose(fp); - } - } + init_all_colors(xterm_colors, palette_file); } } - set_terminal_modes(); - def_prog_mode(); /* * Return to terminal mode, so we're guaranteed of being able to