This source file includes following definitions.
- get_ncurses_color_pair
- tty_color_init_lib
- tty_color_deinit_lib
- tty_color_try_alloc_lib_pair
- tty_setcolor
- tty_set_normal_attrs
- tty_use_256colors
- tty_use_truecolors
- tty_colorize_area
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 #include <config.h>
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/types.h>
38
39 #include "lib/global.h"
40
41 #include "tty.h"
42 #include "tty-ncurses.h"
43 #include "color.h"
44 #include "color-internal.h"
45
46
47
48
49
50
51
52 typedef struct
53 {
54 int pair;
55 int attrs;
56 } mc_tty_ncurses_color_pair_and_attrs_t;
57
58
59
60
61
62
63
64
65 static GHashTable *mc_tty_ncurses_color_pairs = NULL;
66
67
68
69
70
71
72
73
74
75
76
77 static GArray *mc_tty_ncurses_color_pair_and_attrs = NULL;
78
79 static int mc_tty_ncurses_next_color_pair = 0;
80
81 static int overlay_colors = 0;
82
83
84
85
86
87 static int
88 get_ncurses_color_pair (int ifg, int ibg)
89 {
90 char *color_pair_str;
91 int *ncurses_color_pair;
92 int init_pair_ret;
93
94 color_pair_str = g_strdup_printf ("%d.%d", ifg, ibg);
95
96 ncurses_color_pair =
97 (int *) g_hash_table_lookup (mc_tty_ncurses_color_pairs, (gpointer) color_pair_str);
98
99 if (ncurses_color_pair == NULL)
100 {
101 ncurses_color_pair = g_try_new0 (int, 1);
102 *ncurses_color_pair = mc_tty_ncurses_next_color_pair;
103 #if NCURSES_VERSION_PATCH >= 20170401 && defined(NCURSES_EXT_COLORS) && defined(NCURSES_EXT_FUNCS) \
104 && defined(HAVE_NCURSES_WIDECHAR)
105 init_pair_ret = init_extended_pair (*ncurses_color_pair, ifg, ibg);
106 #else
107 init_pair_ret = init_pair (*ncurses_color_pair, ifg, ibg);
108 #endif
109
110 if (init_pair_ret == ERR)
111 {
112 g_free (ncurses_color_pair);
113 g_free (color_pair_str);
114 return 0;
115 }
116
117 g_hash_table_insert (mc_tty_ncurses_color_pairs, color_pair_str, ncurses_color_pair);
118 mc_tty_ncurses_next_color_pair++;
119 }
120 else
121 g_free (color_pair_str);
122
123 return *ncurses_color_pair;
124 }
125
126
127
128
129
130 void
131 tty_color_init_lib (gboolean disable, gboolean force)
132 {
133 int default_color_pair_id;
134
135 (void) force;
136
137 if (has_colors () && !disable)
138 {
139 use_colors = TRUE;
140 start_color ();
141 use_default_colors ();
142
143
144 tty_use_256colors (NULL);
145 tty_use_truecolors (NULL);
146 }
147
148
149 mc_tty_ncurses_color_pairs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
150
151
152 mc_tty_ncurses_next_color_pair = 0;
153 default_color_pair_id = get_ncurses_color_pair (-1, -1);
154 g_assert (default_color_pair_id == 0);
155 (void) default_color_pair_id;
156
157
158 mc_tty_ncurses_color_pair_and_attrs =
159 g_array_new (FALSE, FALSE, sizeof (mc_tty_ncurses_color_pair_and_attrs_t));
160 }
161
162
163
164 void
165 tty_color_deinit_lib (void)
166 {
167 g_hash_table_destroy (mc_tty_ncurses_color_pairs);
168 mc_tty_ncurses_color_pairs = NULL;
169
170 g_array_free (mc_tty_ncurses_color_pair_and_attrs, TRUE);
171 mc_tty_ncurses_color_pair_and_attrs = NULL;
172
173 mc_tty_ncurses_next_color_pair = 0;
174 }
175
176
177
178 void
179 tty_color_try_alloc_lib_pair (tty_color_lib_pair_t *mc_color_pair)
180 {
181 int ifg, ibg, attr;
182
183 ifg = mc_color_pair->fg;
184 ibg = mc_color_pair->bg;
185 attr = mc_color_pair->attr;
186
187
188
189 if (COLORS <= 8 || (tty_use_truecolors (NULL) && overlay_colors <= 8))
190 {
191 if (ifg >= 8 && ifg < 16)
192 {
193 ifg &= 0x07;
194 attr |= A_BOLD;
195 }
196
197 if (ibg >= 8 && ibg < 16)
198 {
199 ibg &= 0x07;
200 }
201 }
202
203
204
205 if (ifg >= 0 && (ifg & FLAG_TRUECOLOR) != 0)
206 {
207 ifg &= ~FLAG_TRUECOLOR;
208 if (ifg <= overlay_colors)
209 ifg += (1 << 16);
210 }
211
212 if (ibg >= 0 && (ibg & FLAG_TRUECOLOR) != 0)
213 {
214 ibg &= ~FLAG_TRUECOLOR;
215 if (ibg <= overlay_colors)
216 ibg += (1 << 16);
217 }
218
219 const int ncurses_color_pair = get_ncurses_color_pair (ifg, ibg);
220 const mc_tty_ncurses_color_pair_and_attrs_t pair_and_attrs = { .pair = ncurses_color_pair,
221 .attrs = attr };
222
223 g_array_insert_val (mc_tty_ncurses_color_pair_and_attrs, mc_color_pair->pair_index,
224 pair_and_attrs);
225 }
226
227
228
229 void
230 tty_setcolor (int color)
231 {
232 mc_tty_ncurses_color_pair_and_attrs_t *pair_and_attrs;
233
234 color = tty_maybe_map_color (color);
235 pair_and_attrs = &g_array_index (mc_tty_ncurses_color_pair_and_attrs,
236 mc_tty_ncurses_color_pair_and_attrs_t, color);
237 attr_set (pair_and_attrs->attrs, pair_and_attrs->pair, NULL);
238 }
239
240
241
242 void
243 tty_set_normal_attrs (void)
244 {
245 standend ();
246 }
247
248
249
250 gboolean
251 tty_use_256colors (GError **error)
252 {
253 (void) error;
254
255 overlay_colors = tty_tigetnum ("CO", NULL);
256
257 if (COLORS == 256 || (COLORS > 256 && overlay_colors == 256))
258 return TRUE;
259
260 if (tty_use_truecolors (NULL))
261 {
262 need_convert_256color = TRUE;
263 return TRUE;
264 }
265
266 g_set_error (error, MC_ERROR, -1,
267 _ ("\nIf your terminal supports 256 colors, you need to set your TERM\n"
268 "environment variable to match your terminal, perhaps using\n"
269 "a *-256color or *-direct256 variant. Use the 'toe -a'\n"
270 "command to list all available variants on your system.\n"));
271 return FALSE;
272 }
273
274
275
276 gboolean
277 tty_use_truecolors (GError **error)
278 {
279
280
281 #if !(NCURSES_VERSION_PATCH >= 20170401 && defined(NCURSES_EXT_COLORS) \
282 && defined(NCURSES_EXT_FUNCS) && defined(HAVE_NCURSES_WIDECHAR))
283 g_set_error (error, MC_ERROR, -1,
284 _ ("For true color support, you need version 6.1 or later of the ncurses\n"
285 "library with wide character and ABI 6 or higher support.\n"
286 "Please upgrade your system.\n"));
287 return FALSE;
288 #else
289
290
291 if (!(tty_tigetflag ("RGB", NULL) && COLORS == COLORS_TRUECOLOR))
292 {
293 g_set_error (
294 error, MC_ERROR, -1,
295 _ ("\nIf your terminal supports true colors, you need to set your TERM\n"
296 "environment variable to a *-direct256, *-direct16, or *-direct variant.\n"
297 "Use the 'toe -a' command to list all available variants on your system.\n"));
298 return FALSE;
299 }
300
301 overlay_colors = tty_tigetnum ("CO", NULL);
302
303 return TRUE;
304 #endif
305 }
306
307
308
309 void
310 tty_colorize_area (int y, int x, int rows, int cols, int color)
311 {
312 #ifdef ENABLE_SHADOWS
313 cchar_t *ctext;
314 wchar_t wch[CCHARW_MAX + 1];
315 attr_t attrs;
316 short color_pair;
317
318 if (!use_colors || !tty_clip (&y, &x, &rows, &cols))
319 return;
320
321 color = tty_maybe_map_color (color);
322 color = g_array_index (mc_tty_ncurses_color_pair_and_attrs,
323 mc_tty_ncurses_color_pair_and_attrs_t, color)
324 .pair;
325
326 ctext = g_malloc (sizeof (cchar_t) * (cols + 1));
327
328 for (int row = 0; row < rows; row++)
329 {
330 mvin_wchnstr (y + row, x, ctext, cols);
331
332 for (int col = 0; col < cols; col++)
333 {
334 getcchar (&ctext[col], wch, &attrs, &color_pair, NULL);
335 setcchar (&ctext[col], wch, attrs, color, NULL);
336 }
337
338 mvadd_wchnstr (y + row, x, ctext, cols);
339 }
340
341 g_free (ctext);
342 #else
343 (void) y;
344 (void) x;
345 (void) rows;
346 (void) cols;
347 (void) color;
348 #endif
349 }
350
351