diff options
| author | S. Gilles <sgilles@math.umd.edu> | 2017-01-01 12:39:36 -0500 |
|---|---|---|
| committer | S. Gilles <sgilles@math.umd.edu> | 2017-01-01 16:09:34 -0500 |
| commit | 79565b0f7a843dd772c2601c9e6a3f7fbd7c655d (patch) | |
| tree | 9bfceaf0d38e36d750883c1afaed772b5b2bcd54 /ui-curses.c | |
| parent | 71419dc5405644de562c6036a4d2c41c7f91fd1b (diff) | |
| download | vis-79565b0f7a843dd772c2601c9e6a3f7fbd7c655d.tar.gz vis-79565b0f7a843dd772c2601c9e6a3f7fbd7c655d.tar.xz | |
ui: use accurate colors when available
When ncurses reports can_change_color(), have color_find_rgb() define
use the exact color requested by modifying ncurses' current palette.
Make an honest effort at restoring this palette on shutdown, though we
can't be positive it's correct.
Diffstat (limited to 'ui-curses.c')
| -rw-r--r-- | ui-curses.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/ui-curses.c b/ui-curses.c index 17867bf..27d8e10 100644 --- a/ui-curses.c +++ b/ui-curses.c @@ -247,6 +247,10 @@ static const Color color_from_256[] = { { 238, 0xe4, 0xe4, 0xe4 }, { 239, 0xee, 0xee, 0xee }, }; +#define MAX_COLOR_CLOBBER (240) +static short color_clobber_idx = 0; +static uint32_t clobbering_colors[MAX_COLOR_CLOBBER]; + static int color_compare(const void *lhs0, const void *rhs0) { const Color *lhs = lhs0, *rhs = rhs0; @@ -268,9 +272,29 @@ static int color_compare(const void *lhs0, const void *rhs0) { return 0; } -/* Work out the nearest color from the 256 color set. */ +/* Work out the nearest color from the 256 color set, or perhaps exactly. */ static int color_find_rgb(unsigned char r, unsigned char g, unsigned char b) { + if (can_change_color() && COLORS >= 256) { + uint32_t hexrep = ((r << 16) | (g << 8) | b) + 1; + for (short i = 0; i < MAX_COLOR_CLOBBER; ++i) { + if (clobbering_colors[i] == hexrep) + return i + 16; + else if (!clobbering_colors[i]) + break; + } + + short i = color_clobber_idx; + clobbering_colors[i] = hexrep; + init_color(i + 16, (r * 1000) / 0xff, (g * 1000) / 0xff, + (b * 1000) / 0xff); + + /* in the unlikely case a user requests this many colors, reuse old slots */ + if (++color_clobber_idx >= MAX_COLOR_CLOBBER) + color_clobber_idx = 0; + + return i + 16; + } static const Color color_to_256[] = { { 0, 0x00, 0x00, 0x00 }, { 1, 0x00, 0x00, 0x5f }, @@ -1180,6 +1204,25 @@ void ui_curses_free(Ui *ui) { return; while (uic->windows) ui_window_free((UiWin*)uic->windows); + + /* we must manually reset color palette, and flicker is undesirable */ + if (can_change_color() && COLORS >= 256) { + clear(); + refresh(); + for (short i = 0; i < MAX_COLOR_CLOBBER; ++i) { + if (!clobbering_colors[i]) + break; + + /* + * ncurses has no way of knowing what the color was; + * color_content() is insufficient. This is the best guess. + */ + Color c = color_from_256[i]; + init_color(i + 16, (c.r * 1000) / 0xff, (c.g * 1000) / 0xff, + (c.b * 1000) / 0xff); + } + } + endwin(); if (uic->termkey) termkey_destroy(uic->termkey); |
