From a3116cb6c3caee368bb1ccbfbe43a4fab823bfa1 Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Sun, 18 Jan 2026 22:06:05 +0100 Subject: Curses: fixed colors on emulators with less than 256 color pairs * For instance on TERM=rxvt. Generally 8-color emulators will usually support only 65 color pairs. * On emulators that support more than 256 pairs, we must still limit them to 256 (or 128 for Scinterm and SciTECO) since we still use a single attribute for colors and misc. attributes (see COLOR_PAIR()). --- src/interface-curses/interface.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/interface-curses/interface.c b/src/interface-curses/interface.c index d07ff21..6c8b231 100644 --- a/src/interface-curses/interface.c +++ b/src/interface-curses/interface.c @@ -232,12 +232,12 @@ static struct { * * Scinterm no longer initializes all color pairs for all combinations of * the builtin foreground and background colors. - * Since curses guarantees only 256 color pairs, we cannot do that either. - * Instead we allocate color pairs beginnig at 128 on demand - * (similar to what Scinterm does). + * Since curses does not guarantee any number of color pairs, we cannot do that either. + * Instead we allocate color pairs beginnig at the second half of + * color pair space on demand (similar to what Scinterm does). * * @note Scinterm now also has scintilla_set_color_offsets(), - * so we could use the lower 127 color pairs as well. + * so we could use the color pairs beginning with 1 as well. * * @param fg curses foreground color * @param bg curses background color @@ -246,16 +246,24 @@ static struct { static gshort teco_color_pair(gshort fg, gshort bg) { - static gshort last_pair = 127; + static gshort allocated_pairs = 0; G_STATIC_ASSERT(sizeof(gshort)*2 <= sizeof(guint)); - gpointer key = GUINT_TO_POINTER(((guint)fg << 16) | bg); + gpointer key = GUINT_TO_POINTER(((guint)fg << 8*sizeof(bg)) | bg); gpointer value = g_hash_table_lookup(teco_interface.pair_table, key); if (G_LIKELY(value != NULL)) return GPOINTER_TO_UINT(value); - init_pair(++last_pair, fg, bg); - g_hash_table_insert(teco_interface.pair_table, key, GUINT_TO_POINTER(last_pair)); - return last_pair; + /* + * We are still adding colors with COLOR_PAIR(), which allows + * at most 256 color pairs (1-255). + */ + gshort new_pair = MIN(COLOR_PAIRS, 256)/2 + allocated_pairs; + if (G_UNLIKELY(new_pair >= 256)) + return 0; + allocated_pairs++; + init_pair(new_pair, fg, bg); + g_hash_table_insert(teco_interface.pair_table, key, GUINT_TO_POINTER(new_pair)); + return new_pair; } /** -- cgit v1.2.3