aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorRobin Haberkorn <rhaberkorn@fmsbw.de>2025-11-10 22:08:28 +0100
committerRobin Haberkorn <rhaberkorn@fmsbw.de>2025-11-10 22:08:28 +0100
commit5c7502cacd8d5d88454ba1a29d028ef0ec098b54 (patch)
treea963bd72c661392121b28b6e40d22dabef845019 /src
parentc39f8bdbef0cd17f4b864bbea2398f2b0f099c18 (diff)
Scinterm updated to v5.5
* This currently needs a yet unmerged patch, fixing the light colors. * Scinterm no longer systematically initializes the color pairs, so we cannot predict their numbers - instead we initialize color pairs on demand and store them in a hash map, very similar to what Scinterm does internally. * Scinterm v5.5 can use arbitrary RGB colors now by automatically allocating curses colors and pairs. We do not expose this in SciTECO yet, although that would also be possible. It has to be decided first whether the special predefined colors will continue to live in the same namespace along with "true" RGB colors.
Diffstat (limited to 'src')
-rw-r--r--src/interface-curses/interface.c146
1 files changed, 86 insertions, 60 deletions
diff --git a/src/interface-curses/interface.c b/src/interface-curses/interface.c
index ed376c2..a9f24dd 100644
--- a/src/interface-curses/interface.c
+++ b/src/interface-curses/interface.c
@@ -166,19 +166,91 @@ static gint teco_interface_blocking_getch(void);
#define COLOR_LCYAN COLOR_LIGHT(COLOR_CYAN)
#define COLOR_LWHITE COLOR_LIGHT(COLOR_WHITE)
+static struct {
+ /**
+ * Mapping of foreground and background curses color tuples
+ * (encoded into a pointer) to a color pair number.
+ */
+ GHashTable *pair_table;
+
+ /**
+ * Mapping of the first 16 curses color codes (that may or may not
+ * correspond with the standard terminal color codes) to
+ * Scintilla-compatible RGB values (red is LSB) to initialize after
+ * Curses startup.
+ * Negative values mean no color redefinition (keep the original
+ * palette entry).
+ */
+ gint32 color_table[16];
+
+ /**
+ * Mapping of the first 16 curses color codes to their
+ * original values for restoring them on shutdown.
+ * Unfortunately, this may not be supported on all
+ * curses ports, so this array may be unused.
+ */
+ struct {
+ gshort r, g, b;
+ } orig_color_table[16];
+
+ int stdin_orig, stdout_orig, stderr_orig;
+ SCREEN *screen;
+ FILE *screen_tty;
+
+ WINDOW *info_window;
+ enum {
+ TECO_INFO_TYPE_BUFFER = 0,
+ TECO_INFO_TYPE_QREG
+ } info_type;
+ teco_string_t info_current;
+ gboolean info_dirty;
+
+ WINDOW *msg_window;
+
+ /**
+ * Pad used exclusively for wgetch() as it will not
+ * result in unwanted wrefresh().
+ */
+ WINDOW *input_pad;
+ GQueue *input_queue;
+
+ teco_curses_info_popup_t popup;
+ gsize popup_prefix_len;
+
+ /**
+ * GError "thrown" by teco_interface_event_loop_iter().
+ * Having this in a variable avoids problems with EMScripten.
+ */
+ GError *event_loop_error;
+} teco_interface;
+
/**
- * Returns the curses `COLOR_PAIR` for the given curses foreground and background `COLOR`s.
- * This is used simply to enumerate every possible color combination.
- * Note: only 256 combinations are possible due to curses portability.
+ * Returns the curses color pair for the given curses foreground and background colors.
+ * Initializes a new pair if necessary.
+ *
+ * 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).
*
- * @param fg The curses foreground `COLOR`.
- * @param bg The curses background `COLOR`.
- * @return number for defining a curses `COLOR_PAIR`.
+ * @param fg curses foreground color
+ * @param bg curses background color
+ * @return curses color pair number
*/
-static inline gshort
+static gshort
teco_color_pair(gshort fg, gshort bg)
{
- return bg * (COLORS < 16 ? 8 : 16) + fg + 1;
+ static gshort last_pair = 127;
+
+ G_STATIC_ASSERT(sizeof(gshort)*2 <= sizeof(guint));
+ gpointer key = GUINT_TO_POINTER(((guint)fg << 16) | 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;
}
/**
@@ -336,58 +408,6 @@ teco_view_free(teco_view_t *ctx)
scintilla_delete(ctx);
}
-static struct {
- /**
- * Mapping of the first 16 curses color codes (that may or may not
- * correspond with the standard terminal color codes) to
- * Scintilla-compatible RGB values (red is LSB) to initialize after
- * Curses startup.
- * Negative values mean no color redefinition (keep the original
- * palette entry).
- */
- gint32 color_table[16];
-
- /**
- * Mapping of the first 16 curses color codes to their
- * original values for restoring them on shutdown.
- * Unfortunately, this may not be supported on all
- * curses ports, so this array may be unused.
- */
- struct {
- gshort r, g, b;
- } orig_color_table[16];
-
- int stdin_orig, stdout_orig, stderr_orig;
- SCREEN *screen;
- FILE *screen_tty;
-
- WINDOW *info_window;
- enum {
- TECO_INFO_TYPE_BUFFER = 0,
- TECO_INFO_TYPE_QREG
- } info_type;
- teco_string_t info_current;
- gboolean info_dirty;
-
- WINDOW *msg_window;
-
- /**
- * Pad used exclusively for wgetch() as it will not
- * result in unwanted wrefresh().
- */
- WINDOW *input_pad;
- GQueue *input_queue;
-
- teco_curses_info_popup_t popup;
- gsize popup_prefix_len;
-
- /**
- * GError "thrown" by teco_interface_event_loop_iter().
- * Having this in a variable avoids problems with EMScripten.
- */
- GError *event_loop_error;
-} teco_interface;
-
static void teco_interface_init_color_safe(guint color, guint32 rgb);
static void teco_interface_restore_colors(void);
@@ -721,6 +741,9 @@ teco_interface_init_interactive(GError **error)
teco_interface_init_screen();
+ teco_interface.pair_table = g_hash_table_new(g_direct_hash, g_direct_equal);
+ start_color();
+
/*
* On UNIX terminals, the escape key is usually
* delivered as the escape character even though function
@@ -2262,4 +2285,7 @@ teco_interface_cleanup(void)
close(teco_interface.stderr_orig);
if (teco_interface.stdout_orig >= 0)
close(teco_interface.stdout_orig);
+
+ if (teco_interface.pair_table)
+ g_hash_table_destroy(teco_interface.pair_table);
}