Skip to content

Commit 5d0c98f

Browse files
author
Jakub Horký
committed
lib/tty: Add compatibility translation from 256 colors to true colors
If the terminal does not support 256 colors but does support true color, allow the use of 256-color skins by adding a translation layer that computes direct color values from 256-color palette. Signed-off-by: Jakub Horký <[email protected]>
1 parent 901dfc2 commit 5d0c98f

File tree

9 files changed

+93
-29
lines changed

9 files changed

+93
-29
lines changed

doc/FAQ

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -432,12 +432,12 @@ Frequently Asked Questions
432432

433433
If your terminal supports 256 colors, the correct entry name may be
434434
appended with -256color. If your terminal supports true color, it
435-
should be appended with -direct, -direct16, or -direct256. The best
436-
backwards compatibility option is -direct256 variant, which provides
437-
both 256-color and true color support simultaneously. The -direct16
438-
variant supports bright versions of the basic colors along with true
439-
color support, in contrast to the -direct variant, which supports
440-
only basic 8 colors together with true color when used in a skin.
435+
should be appended with -direct, -direct16, or -direct256. All three
436+
variants provide both 256-color and true color support simultaneously.
437+
The latter two variants make no difference in mc, and they support
438+
basic colors including their bright versions along with true color
439+
support, in contrast to the -direct variant, which supports only basic
440+
8 colors together with true color when used in a skin.
441441

442442
If there is no 256-color or true-color terminfo variant for your
443443
terminal, even though your terminal supports it, send an e-mail to

lib/tty/color-internal.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,3 +241,37 @@ tty_attr_get_bits (const char *attrs)
241241
}
242242

243243
/* --------------------------------------------------------------------------------------------- */
244+
245+
int
246+
convert_256color_to_truecolor (int color)
247+
{
248+
int r, g, b;
249+
250+
// Invalid color
251+
if (color > 255)
252+
return 0;
253+
254+
if (color >= 232) // Gray scale
255+
r = g = b = (color - 231) * 10 + 8;
256+
else if (color >= 16) // 6x6x6 color cube
257+
{
258+
color -= 16;
259+
260+
r = (color / (6 * 6) % 6);
261+
r = r > 0 ? r * 40 + 55 : 0;
262+
263+
g = (color / 6 % 6);
264+
g = g > 0 ? g * 40 + 55 : 0;
265+
266+
b = (color % 6);
267+
b = b > 0 ? b * 40 + 55 : 0;
268+
}
269+
else // We don't convert basic 16 colors as they are terminal-dependent and user-configurable
270+
return color;
271+
272+
color = FLAG_TRUECOLOR | (r << 16) | (g << 8) | b;
273+
274+
return color;
275+
}
276+
277+
/* --------------------------------------------------------------------------------------------- */

lib/tty/color-internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,14 @@ typedef struct
4747

4848
extern gboolean use_colors;
4949
extern gboolean mc_tty_color_disable;
50+
extern gboolean need_convert_256color;
5051

5152
/*** declarations of public functions ************************************************************/
5253

5354
const char *tty_color_get_name_by_index (int idx);
5455
int tty_color_get_index_by_name (const char *color_name);
5556
int tty_attr_get_bits (const char *attrs);
57+
int convert_256color_to_truecolor (int color);
5658

5759
void tty_color_init_lib (gboolean disable, gboolean force);
5860
void tty_color_deinit_lib (void);

lib/tty/color-ncurses.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ tty_color_init_lib (gboolean disable, gboolean force)
129129
use_colors = TRUE;
130130
start_color ();
131131
use_default_colors ();
132+
133+
// Extended color mode detection routines must first be called before loading any skin
134+
tty_use_256colors (NULL);
135+
tty_use_truecolors (NULL);
132136
}
133137

134138
mc_tty_color_color_pair_attrs = g_hash_table_new_full (
@@ -256,17 +260,21 @@ tty_use_256colors (GError **error)
256260

257261
overlay_colors = tty_tigetnum ("CO", NULL);
258262

259-
if (COLORS != 256 && !(COLORS > 256 && overlay_colors == 256))
263+
if (COLORS == 256 || (COLORS > 256 && overlay_colors == 256))
264+
return TRUE;
265+
266+
if (tty_use_truecolors (NULL))
260267
{
261-
g_set_error (error, MC_ERROR, -1,
262-
_ ("\nIf your terminal supports 256 colors, you need to set your TERM\n"
263-
"environment variable to match your terminal, perhaps using\n"
264-
"a *-256color or *-direct256 variant. Use the 'toe -a'\n"
265-
"command to list all available variants on your system.\n"));
266-
return FALSE;
268+
need_convert_256color = TRUE;
269+
return TRUE;
267270
}
268271

269-
return TRUE;
272+
g_set_error (error, MC_ERROR, -1,
273+
_ ("\nIf your terminal supports 256 colors, you need to set your TERM\n"
274+
"environment variable to match your terminal, perhaps using\n"
275+
"a *-256color or *-direct256 variant. Use the 'toe -a'\n"
276+
"command to list all available variants on your system.\n"));
277+
return FALSE;
270278
}
271279

272280
/* --------------------------------------------------------------------------------------------- */

lib/tty/color-slang.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ tty_color_init_lib (gboolean disable, gboolean force)
136136
if (has_colors (disable, force) && !disable)
137137
{
138138
use_colors = TRUE;
139+
140+
// Extended color mode detection routines must first be called before loading any skin
141+
tty_use_256colors (NULL);
142+
tty_use_truecolors (NULL);
139143
}
140144
}
141145

@@ -218,22 +222,27 @@ tty_set_normal_attrs (void)
218222
gboolean
219223
tty_use_256colors (GError **error)
220224
{
221-
gboolean ret;
222225
int colors, overlay_colors;
223226

224227
colors = tty_tigetnum ("colors", "Co");
225228
overlay_colors = tty_tigetnum ("CO", NULL);
226229

227-
ret = (SLtt_Use_Ansi_Colors && (colors == 256 || (colors > 256 && overlay_colors == 256)));
230+
if (SLtt_Use_Ansi_Colors && (colors == 256 || (colors > 256 && overlay_colors == 256)))
231+
return TRUE;
228232

229-
if (!ret)
230-
g_set_error (error, MC_ERROR, -1,
231-
_ ("\nIf your terminal supports 256 colors, you need to set your TERM\n"
232-
"environment variable to match your terminal, perhaps using\n"
233-
"a *-256color or *-direct256 variant. Use the 'toe -a'\n"
234-
"command to list all available variants on your system.\n"));
233+
if (tty_use_truecolors (NULL))
234+
{
235+
need_convert_256color = TRUE;
236+
return TRUE;
237+
}
238+
239+
g_set_error (error, MC_ERROR, -1,
240+
_ ("\nIf your terminal supports 256 colors, you need to set your TERM\n"
241+
"environment variable to match your terminal, perhaps using\n"
242+
"a *-256color or *-direct256 variant. Use the 'toe -a'\n"
243+
"command to list all available variants on your system.\n"));
235244

236-
return ret;
245+
return FALSE;
237246
}
238247

239248
/* --------------------------------------------------------------------------------------------- */

lib/tty/color.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ static tty_color_pair_t tty_color_defaults = {
5353
/* Set if we are actually using colors */
5454
gboolean use_colors = FALSE;
5555

56+
gboolean need_convert_256color = FALSE;
57+
5658
/*** file scope macro definitions ****************************************************************/
5759

5860
/*** file scope type declarations ****************************************************************/
@@ -175,6 +177,15 @@ tty_try_alloc_color_pair (const tty_color_pair_t *color, gboolean is_temp)
175177
return mc_color_pair->pair_index;
176178
}
177179

180+
if (need_convert_256color)
181+
{
182+
if ((ifg & FLAG_TRUECOLOR) == 0)
183+
ifg = convert_256color_to_truecolor (ifg);
184+
185+
if ((ibg & FLAG_TRUECOLOR) == 0)
186+
ibg = convert_256color_to_truecolor (ibg);
187+
}
188+
178189
mc_color_pair = g_try_new0 (tty_color_lib_pair_t, 1);
179190
if (mc_color_pair == NULL)
180191
{

misc/skins/seasons-spring16M.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
# True colors are referred to by the standard #rrggbb or #rgb notation, the
66
# short form is interpreted by doubling each hex digit.
77
#
8-
# In addition to these, you can use the basic 8 (non-light) colors and
9-
# the attributes. However, you can't use the 256 indexed colors.
8+
# In addition to these the 256 palette colors are still available, and
9+
# obviously so are the attributes. See the sand256.ini skin file for details.
1010

1111
[skin]
1212
# Blooming.

misc/skins/seasons-summer16M.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
# True colors are referred to by the standard #rrggbb or #rgb notation, the
66
# short form is interpreted by doubling each hex digit.
77
#
8-
# In addition to these, you can use the basic 8 (non-light) colors and
9-
# the attributes. However, you can't use the 256 indexed colors.
8+
# In addition to these the 256 palette colors are still available, and
9+
# obviously so are the attributes. See the sand256.ini skin file for details.
1010

1111
[skin]
1212
# Sunshine, ocean, beach, beachball, sunshades, ice cream.

misc/skins/seasons-winter16M.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
# True colors are referred to by the standard #rrggbb or #rgb notation, the
66
# short form is interpreted by doubling each hex digit.
77
#
8-
# In addition to these, you can use the basic 8 (non-light) colors and
9-
# the attributes. However, you can't use the 256 indexed colors.
8+
# In addition to these the 256 palette colors are still available, and
9+
# obviously so are the attributes. See the sand256.ini skin file for details.
1010

1111
[skin]
1212
# The sun is shining and the grass is green,

0 commit comments

Comments
 (0)