aboutsummaryrefslogtreecommitdiff
path: root/contrib/ncurses/tack/color.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ncurses/tack/color.c')
-rw-r--r--contrib/ncurses/tack/color.c767
1 files changed, 767 insertions, 0 deletions
diff --git a/contrib/ncurses/tack/color.c b/contrib/ncurses/tack/color.c
new file mode 100644
index 000000000000..710538aef48c
--- /dev/null
+++ b/contrib/ncurses/tack/color.c
@@ -0,0 +1,767 @@
+/*
+** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
+**
+** This file is part of TACK.
+**
+** TACK is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2, or (at your option)
+** any later version.
+**
+** TACK is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with TACK; see the file COPYING. If not, write to
+** the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+** Boston, MA 02111-1307, USA.
+*/
+
+#include <tack.h>
+
+MODULE_ID("$Id: color.c,v 1.1 1999/04/18 01:24:45 tom Exp $")
+
+/*
+ * Color terminal tests. Has only one entry point: test_color().
+ */
+
+static void color_check(struct test_list *, int *, int *);
+static void color_setf(struct test_list *, int *, int *);
+static void color_matrix(struct test_list *, int *, int *);
+static void color_ncv(struct test_list *, int *, int *);
+static void color_ccc(struct test_list *, int *, int *);
+static void color_bce(struct test_list *, int *, int *);
+
+struct test_list color_test_list[] = {
+ {0, 0, 0, 0, "e) edit terminfo", 0, &edit_menu},
+ {MENU_NEXT, 2, "colors) (pairs", 0, 0, color_check, 0},
+ {MENU_NEXT, 12, "setf) (setb) (scp", 0, 0, color_setf, 0},
+ {MENU_NEXT, 24, "op", 0, 0, color_matrix, 0},
+ {MENU_NEXT, 16, "ncv", 0, 0, color_ncv, 0},
+ {MENU_NEXT, 0, "bce", 0, 0, color_bce, 0},
+ {MENU_NEXT | MENU_CLEAR, 0, "ccc) (initc) (initp", "hls op oc", 0, color_ccc, 0},
+ {MENU_LAST, 0, 0, 0, 0, 0, 0}
+};
+
+#ifndef COLOR_BLACK
+#define COLOR_BLACK 0
+#define COLOR_BLUE 1
+#define COLOR_GREEN 2
+#define COLOR_CYAN 3
+#define COLOR_RED 4
+#define COLOR_MAGENTA 5
+#define COLOR_YELLOW 6
+#define COLOR_WHITE 7
+#endif
+
+struct color_table {
+ const char *name;
+ int index;
+ int r, g, b;
+ int h, l, s;
+};
+
+static struct color_table def_colors[8] = {
+ {"black ", COLOR_BLACK, 0, 0, 0, 0, 0, 0},
+ {"blue ", COLOR_BLUE, 0, 0, 1000, 330, 50, 100},
+ {"green ", COLOR_GREEN, 0, 1000, 0, 240, 50, 100},
+ {"cyan ", COLOR_CYAN, 0, 1000, 1000, 300, 50, 100},
+ {"red ", COLOR_RED, 1000, 0, 0, 120, 50, 100},
+ {"magenta", COLOR_MAGENTA, 1000, 0, 1000, 60, 50, 100},
+ {"yellow ", COLOR_YELLOW, 1000, 1000, 0, 180, 50, 100},
+ {"white ", COLOR_WHITE, 1000, 1000, 1000, 0, 100, 0}
+};
+
+#define MAX_PAIR 256
+static int fg_color[MAX_PAIR] = {COLOR_BLACK, COLOR_BLUE, COLOR_GREEN,
+COLOR_CYAN, COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE};
+static int bg_color[MAX_PAIR] = {COLOR_BLACK, COLOR_BLACK, COLOR_BLACK,
+COLOR_BLACK, COLOR_BLACK, COLOR_BLACK, COLOR_BLACK, COLOR_BLACK};
+static int pairs_used = 8;
+static int a_bright_color, bright_value;
+static int cookie_monster, color_step, colors_per_line;
+static int R, G, B;
+
+static int
+color_trans(int c)
+{ /* translate or load the color */
+ int i;
+
+ for (i = 0; i < pairs_used; i++) {
+ if (fg_color[i] == c) {
+ return i;
+ }
+ }
+ if (!can_change) {
+ return 0;
+ }
+ if (pairs_used > max_colors || pairs_used >= MAX_PAIR) {
+ pairs_used = 0;
+ ptextln("Ran out of colors");
+ }
+ fg_color[pairs_used] = c;
+ bg_color[pairs_used] = c;
+ if (hue_lightness_saturation) {
+ tc_putp(tparm(initialize_color, pairs_used,
+ def_colors[c].h, def_colors[c].l, def_colors[c].s));
+ } else {
+ tc_putp(tparm(initialize_color, pairs_used,
+ def_colors[c].r, def_colors[c].g, def_colors[c].b));
+ }
+ return pairs_used++;
+}
+
+static void
+new_color(
+ int fg,
+ int bg,
+ int hungry)
+{ /* change the color to fg and bg. */
+ int i;
+
+ if (hungry) {
+ eat_cookie();
+ }
+ if (set_a_foreground) {
+ /* set ANSI color (setaf) (setab) */
+ tc_putp(tparm(set_a_foreground, fg));
+ tc_putp(tparm(set_a_background, bg));
+ } else if (set_foreground) {
+ /* make sure black is zero */
+ (void) color_trans(COLOR_BLACK);
+ tc_putp(tparm(set_foreground, color_trans(fg)));
+ tc_putp(tparm(set_background, color_trans(bg)));
+ } else { /* set color pair */
+ for (i = 0; i < pairs_used; i++) {
+ if (fg_color[i] == fg && bg_color[i] == bg) {
+ tc_putp(tparm(set_color_pair, i));
+ if (hungry) {
+ eat_cookie();
+ }
+ return;
+ }
+ }
+ if (!can_change) {
+ /* try to set just the foreground */
+ for (i = pairs_used - 1; i; i--) {
+ if (fg_color[i] == fg)
+ break;
+ }
+ tc_putp(tparm(set_color_pair, i));
+ if (hungry) {
+ eat_cookie();
+ }
+ return;
+ }
+ if (pairs_used > max_pairs || pairs_used >= MAX_PAIR) {
+ pairs_used = 0;
+ ptextln("Ran out of color pairs");
+ }
+ fg_color[pairs_used] = fg;
+ bg_color[pairs_used] = bg;
+ if (hue_lightness_saturation) {
+ tc_putp(tparm(initialize_pair, pairs_used,
+ def_colors[fg].h, def_colors[fg].l, def_colors[fg].s,
+ def_colors[bg].h, def_colors[bg].l, def_colors[bg].s));
+ } else {
+ tc_putp(tparm(initialize_pair, pairs_used,
+ def_colors[fg].r, def_colors[fg].g, def_colors[fg].b,
+ def_colors[bg].r, def_colors[bg].g, def_colors[bg].b));
+ }
+ tc_putp(tparm(set_color_pair, pairs_used));
+ pairs_used++;
+ }
+ if (hungry) {
+ eat_cookie();
+ }
+}
+
+
+static void
+set_color_step(void)
+{ /* set the color_step for the (ccc) display */
+ int i;
+
+ for (i = 2; i < 1000; i++) {
+ if ((i * i * i) >= max_colors) {
+ break;
+ }
+ }
+ color_step = 1000 / (i - 1);
+}
+
+
+static void
+rgb_2_hls(int r, int g, int b, int *h, int *l, int *s)
+{ /* convert RGB to HLS system */
+ int min, max, t;
+
+ if ((min = g < r ? g : r) > b) {
+ min = b;
+ }
+ if ((max = g > r ? g : r) < b) {
+ max = b;
+ }
+
+ /* calculate lightness */
+ *l = (min + max) / 20;
+
+ if (min == max) { /* black, white and all shades of gray */
+ *h = 0;
+ *s = 0;
+ return;
+ }
+ /* calculate saturation */
+ if (*l < 50) {
+ *s = ((max - min) * 100) / (max + min);
+ } else {
+ *s = ((max - min) * 100) / (2000 - max - min);
+ }
+
+ /* calculate hue */
+ if (r == max) {
+ t = 120 + ((g - b) * 60) / (max - min);
+ } else if (g == max) {
+ t = 240 + ((b - r) * 60) / (max - min);
+ } else {
+ t = 360 + ((r - g) * 60) / (max - min);
+ }
+ *h = t % 360;
+}
+
+
+static void
+send_color(int p, int r, int g, int b)
+{ /* send the initialize_color (initc) command */
+ int h, l, s;
+
+ if (hue_lightness_saturation) {
+ rgb_2_hls(r, g, b, &h, &l, &s);
+ tc_putp(tparm(initialize_color, p, h, l, s));
+ } else {
+ tc_putp(tparm(initialize_color, p, r, g, b));
+ }
+}
+
+
+static void
+send_pair(int p, int fr, int fg, int fb, int br, int bg, int bb)
+{ /* send the initialize_pair (initp) command */
+ int fh, fl, fs, bh, bl, bs;
+
+ if (hue_lightness_saturation) {
+ rgb_2_hls(fr, fg, fb, &fh, &fl, &fs);
+ rgb_2_hls(br, bg, bb, &bh, &bl, &bs);
+ tc_putp(tparm(initialize_pair, p, fh, fl, fs, bh, bl, bs));
+ } else {
+ tc_putp(tparm(initialize_pair, p, fr, fg, fb, bb, bg, bb));
+ }
+}
+
+
+static int
+load_palette(int n)
+{ /* load the color palette */
+ int rgb;
+
+ for (;;) {
+ if (pairs_used >= n) {
+ return FALSE;
+ }
+ if (set_a_foreground || set_foreground) {
+ if (pairs_used >= max_colors) {
+ return FALSE;
+ }
+ send_color(pairs_used, R, G, B);
+ rgb = R + G + B;
+ if (rgb > bright_value) {
+ bright_value = rgb;
+ a_bright_color = pairs_used;
+ }
+ } else {
+ if (pairs_used >= max_pairs) {
+ return FALSE;
+ }
+ if (pairs_used == 0) {
+ send_pair(pairs_used, 1000, 1000, 1000, R, G, B);
+ } else {
+ send_pair(pairs_used, R, G, B, R, G, B);
+ }
+ }
+ pairs_used++;
+ if ((B += color_step) > 1000) {
+ B = 0;
+ if ((G += color_step) > 1000) {
+ G = 0;
+ if ((R += color_step) > 1000) {
+ return TRUE;
+ }
+ }
+ }
+ }
+}
+
+
+static int
+rainbow(int n)
+{ /* print the programable color display */
+ int i, c, d, palette_full, initial_pair;
+ static const struct {
+ const char *name;
+ char ch;
+ } splat[] = {
+ {"Bg normal", ' '},
+ {"Fg normal", ' '},
+ {0, 0}
+ };
+
+ if ((set_a_foreground || set_foreground)
+ ? pairs_used >= max_colors
+ : pairs_used >= max_pairs) {
+ ptext("New palette: ");
+ (void) wait_here();
+ initial_pair = pairs_used = 1;
+ bright_value = 0;
+ } else if (line_count + 3 >= lines) {
+ ptext("Go: ");
+ (void) wait_here();
+ put_clear();
+ initial_pair = pairs_used = 1;
+ bright_value = 0;
+ n++;
+ } else {
+ initial_pair = pairs_used;
+ n += initial_pair;
+ }
+ palette_full = load_palette(n);
+ for (d = 0; splat[d].name; d++) {
+ c = splat[d].ch;
+ if (d == 1) {
+ put_mode(enter_reverse_mode);
+ }
+ for (i = initial_pair; i < n; i++) {
+ if (i >= pairs_used) {
+ break;
+ }
+ if (set_a_foreground) {
+ if (i >= max_colors) {
+ break;
+ }
+ tc_putp(tparm(set_a_foreground, i));
+ tc_putp(tparm(set_a_background, i));
+ } else if (set_foreground) {
+ if (i >= max_colors) {
+ break;
+ }
+ tc_putp(tparm(set_foreground, i));
+ tc_putp(tparm(set_background, i));
+ } else {
+ if (i >= max_pairs) {
+ break;
+ }
+ tc_putp(tparm(set_color_pair, i));
+ }
+ putchp(c);
+ }
+ if (d == 1) {
+ put_mode(exit_attribute_mode);
+ }
+ if (set_a_foreground) {
+ tc_putp(tparm(set_a_foreground, a_bright_color));
+ tc_putp(tparm(set_a_background, 0));
+ } else if (set_foreground) {
+ tc_putp(tparm(set_foreground, a_bright_color));
+ tc_putp(tparm(set_background, 0));
+ } else {
+ tc_putp(tparm(set_color_pair, 0));
+ }
+ put_str(" ");
+ put_str(splat[d].name);
+ put_crlf();
+ }
+ return palette_full;
+}
+
+
+static void
+ncv_display(int m)
+{ /* print the no_color_video (ncv) test line */
+ putchp('0' + m);
+ putchp(' ');
+ eat_cookie();
+ set_attr(1 << m);
+ sprintf(temp, "%-11s", alt_modes[m].name);
+ put_str(temp);
+
+ new_color(COLOR_BLUE, COLOR_BLACK, TRUE);
+ put_str("blue");
+
+ new_color(COLOR_BLACK, COLOR_GREEN, TRUE);
+ put_str("green");
+
+ new_color(COLOR_WHITE, COLOR_BLACK, TRUE);
+ put_str(alt_modes[m].name);
+ eat_cookie();
+ set_attr(0);
+ put_crlf();
+}
+
+
+static void
+dump_colors(void)
+{ /* display the colors in some esthetic
+ pattern */
+ static int xmap[8] = {0, 3, 4, 7, 1, 2, 5, 6};
+ int i, j, k, xi, xj, width, p, cs;
+ int found_one;
+
+ cs = color_step <= 125 ? 125 : color_step;
+ width = (1000 / cs) + 1;
+ for (xi = 0; xi < 16; xi++) {
+ i = (xi & 8) ? xi ^ 15 : xi;
+ R = i * cs;
+ if (R <= 1000) {
+ found_one = FALSE;
+ for (xj = 0; xj < 32; xj++) {
+ j = ((xj & 8) ? xj ^ 15 : xj) & 7;
+ k = xmap[((xi >> 1) & 4) + (xj >> 3)];
+ G = j * cs;
+ B = k * cs;
+ if (G <= 1000 && B <= 1000) {
+ p = (k * width + j) * width + i;
+ if (set_a_background) {
+ if (p >= max_colors) {
+ continue;
+ }
+ send_color(p, R, G, B);
+ tc_putp(tparm(set_a_background, p));
+ } else if (set_background) {
+ if (p >= max_colors) {
+ continue;
+ }
+ send_color(p, R, G, B);
+ tc_putp(tparm(set_background, p));
+ } else {
+ if (p >= max_pairs) {
+ continue;
+ }
+ send_pair(p, R, G, B, R, G, B);
+ tc_putp(tparm(set_color_pair, p));
+ }
+ found_one = TRUE;
+ putchp(' ');
+ putchp(' ');
+ }
+ }
+ if (found_one) {
+ put_crlf();
+ }
+ }
+ }
+}
+
+/*
+** color_check(test_list, status, ch)
+**
+** test (colors) and (pairs)
+*/
+static void
+color_check(
+ struct test_list *t,
+ int *state,
+ int *ch)
+{
+ if (max_colors <= 0 && max_pairs <= 0) {
+ ptext("This is not a color terminal; (colors) and (pairs) are missing. ");
+ *state |= MENU_STOP;
+ } else {
+ sprintf(temp, "This terminal can display %d colors and %d color pairs. (colors) (pairs)",
+ max_colors, max_pairs);
+ ptextln(temp);
+ }
+ generic_done_message(t, state, ch);
+}
+
+/*
+** color_setf(test_list, status, ch)
+**
+** test (setf) (setb) and (scp)
+*/
+static void
+color_setf(
+ struct test_list *t,
+ int *state,
+ int *ch)
+{
+ int i, j;
+
+ if (max_colors <= 0 && max_pairs <= 0) {
+ ptext("This is not a color terminal; (colors) and (pairs) are missing. ");
+ generic_done_message(t, state, ch);
+ *state |= MENU_STOP;
+ return;
+ }
+ if ((set_a_foreground == NULL || set_a_background == NULL)
+ && (set_foreground == NULL || set_background == NULL)
+ && set_color_pair == NULL) {
+ ptextln("Both set foreground (setaf/setf) and set color pair (scp) are not present.");
+ if (!set_a_background || !set_background) {
+ ptextln("(setab/setb) set background not present");
+ }
+ ptext("These must be defined for color testing. ");
+ generic_done_message(t, state, ch);
+ *state |= MENU_STOP;
+ return;
+ }
+ /* initialize the color palette */
+ pairs_used = max_colors >= 8 ? 8 : max_colors;
+ if (can_change) {
+ tc_putp(orig_colors);
+ }
+ tc_putp(tparm(orig_pair));
+ new_color(COLOR_WHITE, COLOR_BLACK, FALSE);
+
+ ptextln("(setf) (setb) (scp) The following colors are predefined:");
+ ptextln("\n Foreground Background");
+ put_crlf();
+ j = max_colors > 8 ? 8 : max_colors;
+ /*
+ the black on white test is the same as the white on black test.
+ */
+ for (i = 1; i < j; i++) {
+ putchp('0' + def_colors[i].index);
+ putchp(' ');
+ sprintf(temp, " %s ", def_colors[i].name);
+
+ new_color(def_colors[i].index, COLOR_BLACK, TRUE);
+ put_str(temp);
+
+ new_color(COLOR_BLACK, COLOR_BLACK, TRUE);
+ put_str(" ");
+
+ new_color(COLOR_BLACK, def_colors[i].index, TRUE);
+ put_str(temp);
+
+ new_color(COLOR_WHITE, COLOR_BLACK, FALSE);
+ put_crlf();
+ }
+ put_crlf();
+ generic_done_message(t, state, ch);
+}
+
+/*
+** color_matrix(test_list, status, ch)
+**
+** test (pairs) (op)
+*/
+static void
+color_matrix(
+ struct test_list *t,
+ int *state,
+ int *ch)
+{
+ int i, j, matrix_size, matrix_area, brightness;
+
+ matrix_size = max_colors > 8 ? 8 : max_colors;
+
+ sprintf(temp, "(pairs) There are %d color pairs.", max_pairs);
+ ptextln(temp);
+
+ for ( ; matrix_size; matrix_size--) {
+ if (matrix_size * matrix_size <= max_pairs) {
+ break;
+ }
+ }
+ matrix_area = matrix_size * matrix_size;
+ for (brightness = 0; brightness < 2; brightness++) {
+ put_crlf();
+ sprintf(temp,
+ "%dx%d matrix of foreground/background colors, bright *o%s*",
+ matrix_size, matrix_size, brightness ? "n" : "ff");
+ put_str(temp);
+
+ put_str("\n ");
+ for (i = 0; i < matrix_size; i++) {
+ (void) sprintf(temp, "%-8s", def_colors[i].name);
+ put_str(temp);
+ }
+ for (j = 0; j < matrix_area; j++) {
+ if (j % matrix_size == 0) {
+ tc_putp(tparm(orig_pair));
+ put_crlf();
+ if (brightness) {
+ tc_putp(exit_standout_mode);
+ }
+ (void) sprintf(temp, "%-8s", def_colors[j / matrix_size].name);
+ put_str(temp);
+ if (brightness) {
+ put_mode(enter_bold_mode);
+ }
+ }
+ new_color(def_colors[j % matrix_size].index,
+ def_colors[j / matrix_size].index,
+ FALSE);
+ put_str(" Hello ");
+ }
+ tc_putp(tparm(orig_pair));
+ if (brightness) {
+ tc_putp(exit_standout_mode);
+ }
+ put_crlf();
+ }
+ generic_done_message(t, state, ch);
+}
+
+/*
+** color_ncv(test_list, status, ch)
+**
+** test (ncv)
+*/
+static void
+color_ncv(
+ struct test_list *t,
+ int *state,
+ int *ch)
+{
+ int i;
+
+ if (no_color_video == -1) {
+ /* I have no idea what this means */
+ return;
+ }
+ sprintf(temp, "According to no_color_video (ncv) which is %d, the following attributes should work correctly with color.", no_color_video);
+ ptextln(temp);
+ put_crlf();
+ set_attr(0);
+ ncv_display(0);
+ for (i = 1; i <= 9; i++) {
+ if (((no_color_video >> (mode_map[i] - 1)) & 1) == 0) {
+ ncv_display(mode_map[i]);
+ }
+ }
+ if (no_color_video & 0x3ff) {
+ ptextln("\nThe following attributes should not work correctly with color. (ncv)\n");
+ for (i = 1; i <= 9; i++) {
+ if ((no_color_video >> (mode_map[i] - 1)) & 1) {
+ ncv_display(mode_map[i]);
+ }
+ }
+ }
+ tc_putp(orig_pair);
+ put_crlf();
+ generic_done_message(t, state, ch);
+}
+
+/*
+** color_bce(test_list, status, ch)
+**
+** test (bce) background color erase
+*/
+static void
+color_bce(
+ struct test_list *t,
+ int *state,
+ int *ch)
+{
+ new_color(COLOR_BLACK, COLOR_WHITE, FALSE);
+ put_clear();
+ put_newlines(2);
+ new_color(COLOR_WHITE, COLOR_BLACK, FALSE);
+ ptextln("If the two lines above are black then back_color_erase (bce) should be false.");
+ sprintf(temp, "(bce) is %s in the data base.", back_color_erase ? "true" : "false");
+ ptextln(temp);
+ generic_done_message(t, state, ch);
+}
+
+/*
+** color_ccc(test_list, status, ch)
+**
+** test (ccc) color palette test (oc) (op) (initc) (initp)
+*/
+static void
+color_ccc(
+ struct test_list *t,
+ int *state,
+ int *ch)
+{
+ int i, j;
+
+ if (!can_change) {
+ ptextln("Terminal can not change colors (ccc)");
+ generic_done_message(t, state, ch);
+ return;
+ }
+ tc_putp(orig_colors);
+ pairs_used = 0;
+ new_color(COLOR_WHITE, COLOR_BLACK, FALSE);
+ sprintf(temp, "Reloading colors (init%c) using %s method",
+ set_foreground ? 'c' : 'p',
+ hue_lightness_saturation ? "HLS" : "RGB");
+ ptextln(temp);
+ put_crlf();
+ j = max_colors > 7 ? 7 : max_colors;
+ /* redisplay the above test with reinitialized colors */
+ /* If these colors don't look right to you... */
+ for (i = 0; i < j; i++) {
+ sprintf(temp, " %s ", def_colors[i ^ 7].name);
+
+ new_color(i ^ 7, COLOR_BLACK, TRUE);
+ put_str(temp);
+
+ new_color(COLOR_BLACK, COLOR_BLACK, TRUE);
+ put_str(" ");
+
+ new_color(COLOR_BLACK, i ^ 7, TRUE);
+ put_str(temp);
+
+ new_color(COLOR_WHITE, COLOR_BLACK, FALSE);
+ put_crlf();
+ }
+ generic_done_message(t, state, ch);
+ if (*ch != 0 && *ch != 'n') {
+ tc_putp(orig_colors);
+ tc_putp(tparm(orig_pair));
+ return;
+ }
+
+ pairs_used = 0;
+ cookie_monster = 0;
+ if (magic_cookie_glitch > 0) {
+ cookie_monster =
+ ((set_a_foreground || set_foreground)
+ ? magic_cookie_glitch : 0) +
+ ((set_a_background || set_background)
+ ? magic_cookie_glitch : 0) +
+ (set_color_pair ? magic_cookie_glitch : 0);
+ }
+ set_color_step();
+ colors_per_line = max_colors > max_pairs
+ ? max_pairs : max_colors;
+ j = (columns - 14) / (cookie_monster + 1);
+ if (colors_per_line > j) {
+ colors_per_line = (j / i) * i;
+ }
+ sprintf(temp, "RGB color step %d, cookies %d", color_step,
+ cookie_monster);
+ ptextln(temp);
+
+ R = G = B = 0;
+ pairs_used = 0;
+ for (;;) {
+ if (rainbow(colors_per_line)) {
+ break;
+ }
+ }
+ generic_done_message(t, state, ch);
+ if (*ch != 0 && *ch != 'n') {
+ tc_putp(orig_colors);
+ tc_putp(tparm(orig_pair));
+ return;
+ }
+ dump_colors();
+ tc_putp(orig_colors);
+ tc_putp(tparm(orig_pair));
+ generic_done_message(t, state, ch);
+}