aboutsummaryrefslogtreecommitdiff
path: root/colors.c
diff options
context:
space:
mode:
Diffstat (limited to 'colors.c')
-rw-r--r--colors.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/colors.c b/colors.c
new file mode 100644
index 0000000..d1a0357
--- /dev/null
+++ b/colors.c
@@ -0,0 +1,106 @@
+#include <stdbool.h>
+#include <stdlib.h>
+#include <curses.h>
+
+#include "editor.h"
+#include "util.h"
+
+#ifdef NCURSES_VERSION
+# ifndef NCURSES_EXT_COLORS
+# define NCURSES_EXT_COLORS 0
+# endif
+# if !NCURSES_EXT_COLORS
+# define MAX_COLOR_PAIRS 256
+# endif
+#endif
+#ifndef MAX_COLOR_PAIRS
+# define MAX_COLOR_PAIRS COLOR_PAIRS
+#endif
+
+static bool has_default_colors;
+static short *color2palette, default_fg, default_bg;
+static short color_pairs_reserved, color_pairs_max, color_pair_current;
+
+static unsigned int color_hash(short fg, short bg)
+{
+ if (fg == -1)
+ fg = COLORS;
+ if (bg == -1)
+ bg = COLORS + 1;
+ return fg * (COLORS + 2) + bg;
+}
+
+short editor_color_get(short fg, short bg)
+{
+ if (fg >= COLORS)
+ fg = default_fg;
+ if (bg >= COLORS)
+ bg = default_bg;
+
+ if (!has_default_colors) {
+ if (fg == -1)
+ fg = default_fg;
+ if (bg == -1)
+ bg = default_bg;
+ }
+
+ if (!color2palette || (fg == -1 && bg == -1))
+ return 0;
+ unsigned int index = color_hash(fg, bg);
+ if (color2palette[index] == 0) {
+ short oldfg, oldbg;
+ for (;;) {
+ if (++color_pair_current >= color_pairs_max)
+ color_pair_current = color_pairs_reserved + 1;
+ pair_content(color_pair_current, &oldfg, &oldbg);
+ unsigned int old_index = color_hash(oldfg, oldbg);
+ if (color2palette[old_index] >= 0) {
+ if (init_pair(color_pair_current, fg, bg) == OK) {
+ color2palette[old_index] = 0;
+ color2palette[index] = color_pair_current;
+ }
+ break;
+ }
+ }
+ }
+
+ short color_pair = color2palette[index];
+ return color_pair >= 0 ? color_pair : -color_pair;
+}
+
+short editor_color_reserve(short fg, short bg)
+{
+ if (!color2palette)
+ editor_init();
+ if (!color2palette || fg >= COLORS || bg >= COLORS)
+ return 0;
+ if (!has_default_colors && fg == -1)
+ fg = default_fg;
+ if (!has_default_colors && bg == -1)
+ bg = default_bg;
+ if (fg == -1 && bg == -1)
+ return 0;
+ unsigned int index = color_hash(fg, bg);
+ if (color2palette[index] >= 0) {
+ if (init_pair(++color_pairs_reserved, fg, bg) == OK)
+ color2palette[index] = -color_pairs_reserved;
+ }
+ short color_pair = color2palette[index];
+ return color_pair >= 0 ? color_pair : -color_pair;
+}
+
+void editor_init(void)
+{
+ if (color2palette)
+ return;
+ pair_content(0, &default_fg, &default_bg);
+ if (default_fg == -1)
+ default_fg = COLOR_WHITE;
+ if (default_bg == -1)
+ default_bg = COLOR_BLACK;
+ has_default_colors = (use_default_colors() == OK);
+ color_pairs_max = MIN(COLOR_PAIRS, MAX_COLOR_PAIRS);
+ if (COLORS)
+ color2palette = calloc((COLORS + 2) * (COLORS + 2), sizeof(short));
+ editor_color_reserve(COLOR_WHITE, COLOR_BLACK);
+}