aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorS. Gilles <sgilles@math.umd.edu>2017-01-01 12:39:36 -0500
committerS. Gilles <sgilles@math.umd.edu>2017-01-01 16:09:34 -0500
commit79565b0f7a843dd772c2601c9e6a3f7fbd7c655d (patch)
tree9bfceaf0d38e36d750883c1afaed772b5b2bcd54
parent71419dc5405644de562c6036a4d2c41c7f91fd1b (diff)
downloadvis-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.
-rw-r--r--ui-curses.c45
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);