Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 30 additions & 26 deletions doc/FAQ
Original file line number Diff line number Diff line change
Expand Up @@ -403,47 +403,51 @@ Frequently Asked Questions
If you get colors, be happy.

If your terminal stays black and white, your terminal doesn't support
color. You might want to upgrade to a terminal which compatible with
color. You might want to upgrade to a terminal which is compatible with
the ANSI color sequences.

If your terminal goes completely black, see the next question.

More detailed answer:

Check that your terminal supports color. color_xterm, rxvt and Linux
console do support, most other terminals don't. You can test color
support with following simple C program:
Check that your terminal supports color. Most terminals do. You can
test color support with the following command:

#include <stdio.h>
printf "\033[32m Hello color world! \033[m\n"

int main (void){
printf ("\033[32m Hello world! \033[m\n");
return 0;
}
You can test 256 color support with the following command:

Compile and run it. If you see "Hello world!" text in green your
terminal supports color, otherwise not (however, for color_xterm see
also the next question).
printf "\033[38;5;120m Hello 256-color world! \033[m\n"

Check whether you are using Ncurses or the S-Lang library (type
"mc -V" to find out).
You can test true color support with the following command:

With S-Lang library you can force color support by setting the
environment variable COLORTERM to any value.
printf "\033[38;2;0;200;0m Hello true color world! \033[m\n"

If you use ncurses library, check that your terminfo database
supports color. If not, you should install one of the enhanced
terminfo databases included in GNU Midnight Commander source
distribution.
If you see the text in green, your terminal supports the respective
color mode.

You might want to set the TERM environment variable so that you are
using the correct terminfo database or termcap entry.
Check that you are using the proper TERM variable for your terminal.
If not, set it accordingly. You can use the 'toe -a' command to list
all available terminfo entries.

If you use color_xterm (or rxvt) the correct value might be
xterm-color, xtermc or simply xterm.
If your terminal supports 256 colors, the correct entry name may be
appended with -256color. If your terminal supports true color, it
should be appended with -direct, -direct16, or -direct256. All three
variants provide both 256-color and true color support simultaneously.
The latter two variants make no difference in mc, and they support
basic colors including their bright versions along with true color
support, in contrast to the -direct variant, which supports only basic
8 colors together with true color when used in a skin.

If you use Linux console the correct value for TERM is linux or
console.
If there is no 256-color or true-color terminfo variant for your
terminal, even though your terminal supports it, send an e-mail to
ncurses/terminfo maintainers ([email protected]) and ask them to
add one.

With the S-Lang library (you can check by 'mc -V'), you can force
color support by setting the environment variable COLORTERM to any
value, and specifically force true color support by setting it to
'truecolor'.

4.5 My color_xterm goes completely (or partially) black!

Expand Down
9 changes: 5 additions & 4 deletions lib/skin/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ mc_skin_get_default_name (void)
if (mc_global.tty.skin != NULL)
return g_strdup (mc_global.tty.skin);

// from envirovement variable
// from environment variable
tmp_str = getenv ("MC_SKIN");
if (tmp_str != NULL)
return g_strdup (tmp_str);
Expand Down Expand Up @@ -164,9 +164,10 @@ mc_skin_init (const gchar *skin_override, GError **mcerror)
if (is_good_init && mc_skin__default.have_256_colors && !tty_use_256colors (&error))
{
mc_propagate_error (mcerror, 0,
_ ("Unable to use '%s' skin with 256 colors support\non non-256 colors "
"terminal.\nDefault skin has been loaded"),
mc_skin__default.name);
_ ("Unable to use '%s' skin with 256 colors support:\n%s\nDefault "
"skin has been loaded"),
mc_skin__default.name, error->message);
g_error_free (error);
mc_skin_try_to_load_default ();
mc_skin_colors_old_configure (&mc_skin__default);
(void) mc_skin_ini_file_parse (&mc_skin__default);
Expand Down
38 changes: 36 additions & 2 deletions lib/tty/color-internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ parse_256_or_true_color_name (const char *color_name)
i = (h[0] << 20) | (h[0] << 16) | (h[1] << 12) | (h[1] << 8) | (h[2] << 4) | h[2];
else
i = (h[0] << 20) | (h[1] << 16) | (h[2] << 12) | (h[3] << 8) | (h[4] << 4) | h[5];
return (1 << 24) | i;
return FLAG_TRUECOLOR | i;
}
}

Expand All @@ -178,7 +178,7 @@ tty_color_get_name_by_index (int idx)
return color_table[i].name;

// Create and return the strings in "colorNNN" or "#rrggbb" format.
if ((idx >= 16 && idx < 256) || (idx & (1 << 24)) != 0)
if ((idx >= 16 && idx < 256) || (idx & FLAG_TRUECOLOR) != 0)
{
char name[9];

Expand Down Expand Up @@ -241,3 +241,37 @@ tty_attr_get_bits (const char *attrs)
}

/* --------------------------------------------------------------------------------------------- */

int
convert_256color_to_truecolor (int color)
{
int r, g, b;

// Invalid color
if (color > 255)
return 0;

if (color >= 232) // Gray scale
r = g = b = (color - 231) * 10 + 8;
else if (color >= 16) // 6x6x6 color cube
{
color -= 16;

r = (color / (6 * 6) % 6);
r = r > 0 ? r * 40 + 55 : 0;

g = (color / 6 % 6);
g = g > 0 ? g * 40 + 55 : 0;

b = (color % 6);
b = b > 0 ? b * 40 + 55 : 0;
}
else // We don't convert basic 16 colors as they are terminal-dependent and user-configurable
return color;

color = FLAG_TRUECOLOR | (r << 16) | (g << 8) | b;

return color;
}

/* --------------------------------------------------------------------------------------------- */
5 changes: 5 additions & 0 deletions lib/tty/color-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

/*** typedefs(not structures) and defined constants **********************************************/

#define FLAG_TRUECOLOR (1 << 24)
#define COLORS_TRUECOLOR (1 << 24)

/*** enums ***************************************************************************************/

typedef enum
Expand All @@ -44,12 +47,14 @@ typedef struct

extern gboolean use_colors;
extern gboolean mc_tty_color_disable;
extern gboolean need_convert_256color;

/*** declarations of public functions ************************************************************/

const char *tty_color_get_name_by_index (int idx);
int tty_color_get_index_by_name (const char *color_name);
int tty_attr_get_bits (const char *attrs);
int convert_256color_to_truecolor (int color);

void tty_color_init_lib (gboolean disable, gboolean force);
void tty_color_deinit_lib (void);
Expand Down
78 changes: 72 additions & 6 deletions lib/tty/color-ncurses.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

#include "lib/global.h"

#include "tty.h"
#include "tty-ncurses.h"
#include "color.h" // variables
#include "color-internal.h"
Expand All @@ -53,6 +54,7 @@
/*** file scope variables ************************************************************************/

static GHashTable *mc_tty_color_color_pair_attrs = NULL;
static int overlay_colors = 0;

/* --------------------------------------------------------------------------------------------- */
/*** file scope functions ************************************************************************/
Expand Down Expand Up @@ -127,6 +129,10 @@ tty_color_init_lib (gboolean disable, gboolean force)
use_colors = TRUE;
start_color ();
use_default_colors ();

// Extended color mode detection routines must first be called before loading any skin
tty_use_256colors (NULL);
tty_use_truecolors (NULL);
}

mc_tty_color_color_pair_attrs = g_hash_table_new_full (
Expand Down Expand Up @@ -179,8 +185,9 @@ tty_color_try_alloc_lib_pair (tty_color_lib_pair_t *mc_color_pair)
ibg = mc_color_pair->bg;
attr = mc_color_pair->attr;

// In legacy color mode, change bright colors into bold
if (!tty_use_256colors (NULL) && !tty_use_truecolors (NULL))
// If we have 8 indexed colors only, change foreground bright colors into bold and
// background bright colors to basic colors
if (COLORS <= 8 || (tty_use_truecolors (NULL) && overlay_colors <= 8))
{
if (ifg >= 8 && ifg < 16)
{
Expand All @@ -191,11 +198,31 @@ tty_color_try_alloc_lib_pair (tty_color_lib_pair_t *mc_color_pair)
if (ibg >= 8 && ibg < 16)
{
ibg &= 0x07;
// attr | = A_BOLD | A_REVERSE ;
}
}

// Shady trick: if we don't have the exact color, because it is overlaid by backwards
// compatibility indexed values, just borrow one degree of red. The user won't notice :)
if ((ifg & FLAG_TRUECOLOR) != 0)
{
ifg &= ~FLAG_TRUECOLOR;
if (ifg != 0 && ifg <= overlay_colors)
ifg += (1 << 16);
}

if ((ibg & FLAG_TRUECOLOR) != 0)
{
ibg &= ~FLAG_TRUECOLOR;
if (ibg != 0 && ibg <= overlay_colors)
ibg += (1 << 16);
}

#if NCURSES_VERSION_PATCH >= 20170401 && defined(NCURSES_EXT_COLORS) && defined(NCURSES_EXT_FUNCS) \
&& defined(HAVE_NCURSES_WIDECHAR)
init_extended_pair (mc_color_pair->pair_index, ifg, ibg);
#else
init_pair (mc_color_pair->pair_index, ifg, ibg);
#endif
mc_tty_color_save_attr (mc_color_pair->pair_index, attr);
}
}
Expand Down Expand Up @@ -231,17 +258,56 @@ tty_use_256colors (GError **error)
{
(void) error;

return (COLORS == 256);
overlay_colors = tty_tigetnum ("CO", NULL);

if (COLORS == 256 || (COLORS > 256 && overlay_colors == 256))
return TRUE;

if (tty_use_truecolors (NULL))
{
need_convert_256color = TRUE;
return TRUE;
}

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

/* --------------------------------------------------------------------------------------------- */

gboolean
tty_use_truecolors (GError **error)
{
// Not yet supported in ncurses
g_set_error (error, MC_ERROR, -1, _ ("True color not supported with ncurses."));
// Low level true color is supported since ncurses 6.0 patch 20170401 preceding release
// of ncurses 6.1. It needs ABI 6 or higher.
#if !(NCURSES_VERSION_PATCH >= 20170401 && defined(NCURSES_EXT_COLORS) \
&& defined(NCURSES_EXT_FUNCS) && defined(HAVE_NCURSES_WIDECHAR))
g_set_error (error, MC_ERROR, -1,
_ ("For true color support, you need version 6.1 or later of the ncurses\n"
"library with wide character and ABI 6 or higher support.\n"
"Please upgrade your system.\n"));
return FALSE;
#else
// We support only bool RGB cap configuration (8:8:8 bits), but the other variants are so rare
// that we don't need to bother.
if (!(tty_tigetflag ("RGB", NULL) && COLORS == COLORS_TRUECOLOR))
{
g_set_error (
error, MC_ERROR, -1,
_ ("\nIf your terminal supports true colors, you need to set your TERM\n"
"environment variable to a *-direct256, *-direct16, or *-direct variant.\n"
"Use the 'toe -a' command to list all available variants on your system.\n"));
return FALSE;
}

overlay_colors = tty_tigetnum ("CO", NULL);

return TRUE;
#endif
}

/* --------------------------------------------------------------------------------------------- */
44 changes: 34 additions & 10 deletions lib/tty/color-slang.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "lib/global.h"
#include "lib/util.h" // whitespace()

#include "tty.h"
#include "tty-slang.h"
#include "color.h" // variables
#include "color-internal.h"
Expand All @@ -61,7 +62,10 @@ has_colors (gboolean disable, gboolean force)
{
mc_tty_color_disable = disable;

if (force || (getenv ("COLORTERM") != NULL))
// S-Lang enables color if the setaf/setab/setf/setb terminfo capabilities are set or
// the COLORTERM environment variable is set

if (force)
SLtt_Use_Ansi_Colors = 1;

if (!mc_tty_color_disable)
Expand Down Expand Up @@ -132,6 +136,10 @@ tty_color_init_lib (gboolean disable, gboolean force)
if (has_colors (disable, force) && !disable)
{
use_colors = TRUE;

// Extended color mode detection routines must first be called before loading any skin
tty_use_256colors (NULL);
tty_use_truecolors (NULL);
}
}

Expand Down Expand Up @@ -214,15 +222,27 @@ tty_set_normal_attrs (void)
gboolean
tty_use_256colors (GError **error)
{
gboolean ret;
int colors, overlay_colors;

ret = (SLtt_Use_Ansi_Colors && SLtt_tgetnum ((char *) "Co") == 256);
colors = tty_tigetnum ("colors", "Co");
overlay_colors = tty_tigetnum ("CO", NULL);

if (!ret)
g_set_error (error, MC_ERROR, -1,
_ ("Your terminal doesn't even seem to support 256 colors."));
if (SLtt_Use_Ansi_Colors && (colors == 256 || (colors > 256 && overlay_colors == 256)))
return TRUE;

if (tty_use_truecolors (NULL))
{
need_convert_256color = TRUE;
return TRUE;
}

g_set_error (error, MC_ERROR, -1,
_ ("\nIf your terminal supports 256 colors, you need to set your TERM\n"
"environment variable to match your terminal, perhaps using\n"
"a *-256color or *-direct256 variant. Use the 'toe -a'\n"
"command to list all available variants on your system.\n"));

return ret;
return FALSE;
}

/* --------------------------------------------------------------------------------------------- */
Expand All @@ -245,11 +265,15 @@ tty_use_truecolors (GError **error)
/* Duplicate slang's check so that we can pop up an error message
rather than silently use wrong colors. */
colorterm = getenv ("COLORTERM");
if (colorterm == NULL
|| (strcmp (colorterm, "truecolor") != 0 && strcmp (colorterm, "24bit") != 0))
if (!((tty_tigetflag ("RGB", NULL) && tty_tigetnum ("colors", "Co") == COLORS_TRUECOLOR)
|| (colorterm != NULL
&& (strcmp (colorterm, "truecolor") == 0 || strcmp (colorterm, "24bit") == 0))))
{
g_set_error (error, MC_ERROR, -1,
_ ("Set COLORTERM=truecolor if your terminal really supports true colors."));
_ ("\nIf your terminal supports true colors, you need to set your TERM\n"
"environment variable to a *-direct256, *-direct16, or *-direct variant.\n"
"Use the 'toe -a' command to list all available variants on your system.\n"
"Alternatively, you can set COLORTERM=truecolor.\n"));
return FALSE;
}

Expand Down
Loading
Loading