]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - test/ncurses.c
ncurses 6.0 - patch 20160507
[ncurses.git] / test / ncurses.c
index a6a87d7f79d21c4fe62a4729a99b1d91f405c7c4..664311ccfb07da3805daff3b6df4ec8686df714e 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2013,2014 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 <esr@snark.thyrsus.com> 1993
            Thomas E. Dickey (beginning revision 1.27 in 1996).
 
-$Id: ncurses.c,v 1.414 2014/08/02 23:10:26 tom Exp $
+$Id: ncurses.c,v 1.437 2016/05/07 23:56:59 tom Exp $
 
 ***************************************************************************/
 
@@ -636,15 +636,22 @@ 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']);
+}
+
 static void
 wgetch_help(WINDOW *win, GetchFlags flags)
 {
@@ -655,7 +662,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"
@@ -810,9 +818,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 +831,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,7 +839,7 @@ 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)) {
@@ -860,6 +868,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 +943,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
@@ -943,7 +955,7 @@ begin_getch_test(void)
     refresh();
 
 #ifdef NCURSES_MOUSE_VERSION
-    mousemask(ALL_MOUSE_EVENTS, (mmask_t *) 0);
+    mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, (mmask_t *) 0);
 #endif
 
     (void) printw("Delay in 10ths of a second (<CR> for blocking input)? ");
@@ -958,7 +970,7 @@ begin_getch_test(void)
        delay = -1;
     }
     raw();
-    move(5, 0);
+    move(6, 0);
     return delay;
 }
 
@@ -1060,11 +1072,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 +1087,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,7 +1095,7 @@ 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)) {
@@ -1125,6 +1137,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 +1200,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
@@ -1255,9 +1271,10 @@ my_termattrs(void)
 #define ATTRSTRING_1ST 32      /* ' ' */
 #define ATTRSTRING_END 126     /* '~' */
 
-#define COL_ATTRSTRING 25
-#define MARGIN_4_ATTRS (COL_ATTRSTRING + 8)
-#define LEN_ATTRSTRING (COLS - MARGIN_4_ATTRS)
+#define COLS_PRE_ATTRS 5
+#define COLS_AFT_ATTRS 15
+#define COL_ATTRSTRING (COLS_PRE_ATTRS + 17)
+#define LEN_ATTRSTRING (COLS - (COL_ATTRSTRING + COLS_AFT_ATTRS))
 #define MAX_ATTRSTRING (ATTRSTRING_END + 1 - ATTRSTRING_1ST)
 
 static char attr_test_string[MAX_ATTRSTRING + 1];
@@ -1412,11 +1429,11 @@ 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, 5, "-->");
-    MvPrintw(row, 8, "%s mode:", name);
+       MvPrintw(row, COLS_PRE_ATTRS - 3, "-->");
+    MvPrintw(row, COLS_PRE_ATTRS, "%s mode:", name);
     MvPrintw(row, COL_ATTRSTRING - 1, "|");
     if (skip)
        printw("%*s", skip, " ");
@@ -1477,8 +1494,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;
@@ -1640,6 +1658,7 @@ attr_test(void)
                        beep();
                    } else {
                        extras |= (chtype) COLOR_PAIR(pair);
+                       normal &= ~A_COLOR;
                    }
                }
            }
@@ -1653,16 +1672,17 @@ attr_test(void)
            for (j = 0; j < my_size; ++j) {
                bool arrow = (j == k);
                row = show_attr(my_wins[j], row, n, arrow,
+                               normal |
                                extras |
                                my_list[j].attr |
                                my_list[k].attr,
                                my_list[j].name);
            }
 
-           MvPrintw(row, 8,
+           MvPrintw(row, COLS_PRE_ATTRS,
                     "This terminal does %shave the magic-cookie glitch",
                     get_xmc() > -1 ? "" : "not ");
-           MvPrintw(row + 1, 8, "Enter '?' for help.");
+           MvPrintw(row + 1, COLS_PRE_ATTRS, "Enter '?' for help.");
            show_color_attr(fg, bg, tx);
            printw("  ACS (%d)", ac != 0);
 
@@ -1800,8 +1820,8 @@ wide_show_attr(WINDOW *win,
     chtype test = attr & ~WA_ALTCHARSET;
 
     if (arrow)
-       MvPrintw(row, 5, "-->");
-    MvPrintw(row, 8, "%s mode:", name);
+       MvPrintw(row, COLS_PRE_ATTRS - 3, "-->");
+    MvPrintw(row, COLS_PRE_ATTRS, "%s mode:", name);
     MvPrintw(row, COL_ATTRSTRING - 1, "|");
     if (skip)
        printw("%*s", skip, " ");
@@ -1865,8 +1885,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;
@@ -2010,10 +2031,10 @@ wide_attr_test(void)
                                     my_list[j].name);
            }
 
-           MvPrintw(row, 8,
+           MvPrintw(row, COLS_PRE_ATTRS,
                     "This terminal does %shave the magic-cookie glitch",
                     get_xmc() > -1 ? "" : "not ");
-           MvPrintw(row + 1, 8, "Enter '?' for help.");
+           MvPrintw(row + 1, COLS_PRE_ATTRS, "Enter '?' for help.");
            show_color_attr(fg, bg, tx);
            printw("  ACS (%d)", ac != 0);
 
@@ -2164,9 +2185,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;
@@ -2176,6 +2198,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;
 
@@ -2193,11 +2224,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;
 
@@ -2228,6 +2259,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) {
@@ -2235,13 +2269,13 @@ color_test(void)
                NCURSES_COLOR_T bg = InxToBG(i);
 
                init_pair(pair, fg, bg);
-               attron((attr_t) COLOR_PAIR(pair));
+               attron(COLOR_PAIR(pair));
                if (opt_acsc)
-                   attron((attr_t) A_ALTCHARSET);
+                   attron(A_ALTCHARSET);
                if (opt_bold)
-                   attron((attr_t) A_BOLD);
+                   attron(A_BOLD);
                if (opt_revs)
-                   attron((attr_t) A_REVERSE);
+                   attron(A_REVERSE);
 
                if (opt_nums) {
                    sprintf(numbered, "{%02X}", (int) i);
@@ -2354,6 +2388,8 @@ color_test(void)
 
     erase();
     endwin();
+
+    free(numbered);
 }
 
 #if USE_WIDEC_SUPPORT
@@ -2368,9 +2404,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;
@@ -2379,9 +2416,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;
 
@@ -2395,15 +2442,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;
 
@@ -2442,15 +2488,18 @@ 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);
                if (opt_acsc)
-                   attr_on((attr_t) A_ALTCHARSET, NULL);
+                   attr_on(A_ALTCHARSET, NULL);
                if (opt_bold)
-                   attr_on((attr_t) A_BOLD, NULL);
+                   attr_on(A_BOLD, NULL);
                if (opt_revs)
-                   attr_on((attr_t) A_REVERSE, NULL);
+                   attr_on(A_REVERSE, NULL);
 
                if (opt_nums) {
                    sprintf(numbered, "{%02X}", i);
@@ -2573,6 +2622,9 @@ wide_color_test(void)
 
     erase();
     endwin();
+
+    free(numbered);
+    free(buffer);
 }
 #endif /* USE_WIDEC_SUPPORT */
 
@@ -2600,7 +2652,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;
 
@@ -2611,6 +2663,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
@@ -2618,14 +2749,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,
@@ -2694,6 +2834,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)
@@ -2720,10 +2875,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;
@@ -2766,6 +2923,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");
 
@@ -2810,7 +2969,7 @@ color_edit(void)
     /*
      * ncurses does not reset each color individually when calling endwin().
      */
-    init_all_colors();
+    reset_all_colors();
 
     endwin();
 }
@@ -4202,13 +4361,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
@@ -4244,46 +4400,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);
@@ -4593,10 +4729,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;
 
@@ -4682,12 +4822,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;
@@ -5141,10 +5275,15 @@ panner_v_cleanup(int from_y, int from_x, int to_y)
 }
 
 static void
-fill_pad(WINDOW *panpad, bool pan_lines)
+fill_pad(WINDOW *panpad, bool pan_lines, bool colored)
 {
     int y, x;
     unsigned gridcount = 0;
+    chtype fill = 0;
+#ifdef A_COLOR
+    if (colored)
+       fill = (chtype) COLOR_PAIR(1);
+#endif
 
     wmove(panpad, 0, 0);
     for (y = 0; y < getmaxy(panpad); y++) {
@@ -5158,7 +5297,7 @@ fill_pad(WINDOW *panpad, bool pan_lines)
                    waddch(panpad, pan_lines ? ACS_LTEE : '+');
                else
                    waddch(panpad, (chtype) ((pan_lines ? 'a' : 'A') +
-                                            (int) (gridcount++ % 26)));
+                                            (int) (gridcount++ % 26)) | fill);
            } else if (y % GRIDSIZE == 0)
                waddch(panpad, pan_lines ? ACS_HLINE : '-');
            else if (x % GRIDSIZE == 0)
@@ -5172,7 +5311,8 @@ fill_pad(WINDOW *panpad, bool pan_lines)
 static void
 panner(WINDOW *pad,
        int top_x, int top_y, int porty, int portx,
-       int (*pgetc) (WINDOW *))
+       int (*pgetc) (WINDOW *),
+       bool colored)
 {
 #if HAVE_GETTIMEOFDAY
     struct timeval before, after;
@@ -5219,7 +5359,7 @@ panner(WINDOW *pad,
            break;
        case 'a':
            pan_lines = !pan_lines;
-           fill_pad(pad, pan_lines);
+           fill_pad(pad, pan_lines, colored);
            pending_pan = FALSE;
            break;
 
@@ -5506,7 +5646,7 @@ padgetch(WINDOW *win)
 #define PAD_WIDE 200
 
 static void
-demo_pad(void)
+demo_pad(bool colored)
 /* Demonstrate pads. */
 {
     WINDOW *panpad = newpad(PAD_HIGH, PAD_WIDE);
@@ -5515,8 +5655,14 @@ demo_pad(void)
        Cannot("cannot create requested pad");
        return;
     }
-
-    fill_pad(panpad, FALSE);
+#ifdef A_COLOR
+    if (colored && use_colors) {
+       init_pair(1, COLOR_BLACK, COLOR_GREEN);
+       init_pair(2, COLOR_CYAN, COLOR_BLUE);
+       wbkgd(panpad, (chtype) (COLOR_PAIR(2) | ' '));
+    }
+#endif
+    fill_pad(panpad, FALSE, colored);
 
     panner_legend(LINES - 4);
     panner_legend(LINES - 3);
@@ -5529,7 +5675,7 @@ demo_pad(void)
      * We'll still be able to widen it during a test, since that's required
      * for testing boundaries.
      */
-    panner(panpad, 2, 2, LINES - 5, COLS - 15, padgetch);
+    panner(panpad, 2, 2, LINES - 5, COLS - 15, padgetch, colored);
 
     delwin(panpad);
     endwin();
@@ -6793,7 +6939,11 @@ do_single_test(const char c)
 #endif
 
     case 'p':
-       demo_pad();
+       demo_pad(FALSE);
+       break;
+
+    case 'P':
+       demo_pad(TRUE);
        break;
 
 #if USE_LIBFORM
@@ -6855,6 +7005,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++)
@@ -6949,6 +7100,7 @@ main_menu(bool top)
 #endif
 #endif
        (void) puts("p = exercise pad features");
+       (void) puts("P = exercise pad features, using color");
        (void) puts("q = quit");
 #if USE_LIBFORM
        (void) puts("r = exercise forms code");
@@ -7019,9 +7171,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[])
 {
@@ -7035,10 +7184,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':
@@ -7100,6 +7250,9 @@ main(int argc, char *argv[])
            save_trace = (unsigned) strtol(optarg, 0, 0);
            break;
 #endif
+       case 'x':
+           xterm_colors = TRUE;
+           break;
        default:
            usage();
        }
@@ -7134,6 +7287,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());
 
@@ -7157,47 +7313,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