Manual pages: mcmcdiffmceditmcview

root/lib/tty/color-slang.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. has_colors
  2. mc_tty_color_pair_init_special
  3. tty_color_init_lib
  4. tty_color_deinit_lib
  5. tty_color_try_alloc_lib_pair
  6. tty_setcolor
  7. tty_lowlevel_setcolor
  8. tty_set_normal_attrs
  9. tty_use_256colors
  10. tty_use_truecolors

   1 /*
   2    Color setup for S_Lang screen library
   3 
   4    Copyright (C) 1994-2025
   5    Free Software Foundation, Inc.
   6 
   7    Written by:
   8    Andrew Borodin <aborodin@vmail.ru>, 2009
   9    Egmont Koblinger <egmont@gmail.com>, 2010
  10 
  11    This file is part of the Midnight Commander.
  12 
  13    The Midnight Commander is free software: you can redistribute it
  14    and/or modify it under the terms of the GNU General Public License as
  15    published by the Free Software Foundation, either version 3 of the License,
  16    or (at your option) any later version.
  17 
  18    The Midnight Commander is distributed in the hope that it will be useful,
  19    but WITHOUT ANY WARRANTY; without even the implied warranty of
  20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21    GNU General Public License for more details.
  22 
  23    You should have received a copy of the GNU General Public License
  24    along with this program.  If not, see <https://www.gnu.org/licenses/>.
  25  */
  26 
  27 /** \file color-slang.c
  28  *  \brief Source: S-Lang-specific color setup
  29  */
  30 
  31 #include <config.h>
  32 
  33 #include <stdio.h>
  34 #include <stdlib.h>
  35 #include <string.h>
  36 #include <sys/types.h>  // size_t
  37 
  38 #include "lib/global.h"
  39 #include "lib/util.h"  // whitespace()
  40 
  41 #include "tty.h"
  42 #include "tty-slang.h"
  43 #include "color.h"  // variables
  44 #include "color-internal.h"
  45 
  46 /*** global variables ****************************************************************************/
  47 
  48 /*** file scope macro definitions ****************************************************************/
  49 
  50 /*** file scope type declarations ****************************************************************/
  51 
  52 /*** forward declarations (file scope functions) *************************************************/
  53 
  54 /*** file scope variables ************************************************************************/
  55 
  56 /* --------------------------------------------------------------------------------------------- */
  57 /*** file scope functions ************************************************************************/
  58 /* --------------------------------------------------------------------------------------------- */
  59 
  60 static int
  61 has_colors (gboolean disable, gboolean force)
     /* [previous][next][first][last][top][bottom][index][help]  */
  62 {
  63     mc_tty_color_disable = disable;
  64 
  65     // S-Lang enables color if the setaf/setab/setf/setb terminfo capabilities are set or
  66     // the COLORTERM environment variable is set
  67 
  68     if (force)
  69         SLtt_Use_Ansi_Colors = 1;
  70 
  71     if (!mc_tty_color_disable)
  72     {
  73         const char *terminal = getenv ("TERM");
  74         const size_t len = strlen (terminal);
  75         char *cts = mc_global.tty.color_terminal_string;
  76 
  77         // check mc_global.tty.color_terminal_string
  78         while (*cts != '\0')
  79         {
  80             char *s;
  81             size_t i = 0;
  82 
  83             while (whitespace (*cts))
  84                 cts++;
  85             s = cts;
  86 
  87             while (*cts != '\0' && *cts != ',')
  88             {
  89                 cts++;
  90                 i++;
  91             }
  92 
  93             if ((i != 0) && (i == len) && (strncmp (s, terminal, i) == 0))
  94                 SLtt_Use_Ansi_Colors = 1;
  95 
  96             if (*cts == ',')
  97                 cts++;
  98         }
  99     }
 100     return SLtt_Use_Ansi_Colors;
 101 }
 102 
 103 /* --------------------------------------------------------------------------------------------- */
 104 
 105 static void
 106 mc_tty_color_pair_init_special (tty_color_lib_pair_t *mc_color_pair, const char *fg1,
     /* [previous][next][first][last][top][bottom][index][help]  */
 107                                 const char *bg1, const char *fg2, const char *bg2,
 108                                 SLtt_Char_Type mask)
 109 {
 110     if (SLtt_Use_Ansi_Colors != 0)
 111     {
 112         if (!mc_tty_color_disable)
 113         {
 114             SLtt_set_color (mc_color_pair->pair_index, (char *) "", (char *) fg1, (char *) bg1);
 115         }
 116         else
 117         {
 118             SLtt_set_color (mc_color_pair->pair_index, (char *) "", (char *) fg2, (char *) bg2);
 119         }
 120     }
 121     else
 122     {
 123         SLtt_set_mono (mc_color_pair->pair_index, NULL, mask);
 124     }
 125 }
 126 
 127 /* --------------------------------------------------------------------------------------------- */
 128 /*** public functions ****************************************************************************/
 129 /* --------------------------------------------------------------------------------------------- */
 130 
 131 void
 132 tty_color_init_lib (gboolean disable, gboolean force)
     /* [previous][next][first][last][top][bottom][index][help]  */
 133 {
 134     /* FIXME: if S-Lang is used, has_colors() must be called regardless
 135        of whether we are interested in its result */
 136     if (has_colors (disable, force) && !disable)
 137     {
 138         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);
 143     }
 144 }
 145 
 146 /* --------------------------------------------------------------------------------------------- */
 147 
 148 void
 149 tty_color_deinit_lib (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 150 {
 151 }
 152 
 153 /* --------------------------------------------------------------------------------------------- */
 154 
 155 void
 156 tty_color_try_alloc_lib_pair (tty_color_lib_pair_t *mc_color_pair)
     /* [previous][next][first][last][top][bottom][index][help]  */
 157 {
 158     if (mc_color_pair->fg <= (int) SPEC_A_REVERSE)
 159     {
 160         switch (mc_color_pair->fg)
 161         {
 162         case SPEC_A_REVERSE:
 163             mc_tty_color_pair_init_special (mc_color_pair, "black", "white", "black", "lightgray",
 164                                             SLTT_REV_MASK);
 165             break;
 166         case SPEC_A_BOLD:
 167             mc_tty_color_pair_init_special (mc_color_pair, "white", "black", "white", "black",
 168                                             SLTT_BOLD_MASK);
 169             break;
 170         case SPEC_A_BOLD_REVERSE:
 171             mc_tty_color_pair_init_special (mc_color_pair, "white", "white", "white", "white",
 172                                             SLTT_BOLD_MASK | SLTT_REV_MASK);
 173             break;
 174         case SPEC_A_UNDERLINE:
 175             mc_tty_color_pair_init_special (mc_color_pair, "white", "black", "white", "black",
 176                                             SLTT_ULINE_MASK);
 177             break;
 178         default:
 179             break;
 180         }
 181     }
 182     else
 183     {
 184         const char *fg, *bg;
 185 
 186         fg = tty_color_get_name_by_index (mc_color_pair->fg);
 187         bg = tty_color_get_name_by_index (mc_color_pair->bg);
 188         SLtt_set_color (mc_color_pair->pair_index, (char *) "", (char *) fg, (char *) bg);
 189         SLtt_add_color_attribute (mc_color_pair->pair_index, mc_color_pair->attr);
 190     }
 191 }
 192 
 193 /* --------------------------------------------------------------------------------------------- */
 194 
 195 void
 196 tty_setcolor (int color)
     /* [previous][next][first][last][top][bottom][index][help]  */
 197 {
 198     SLsmg_set_color (color);
 199 }
 200 
 201 /* --------------------------------------------------------------------------------------------- */
 202 /**
 203  * Set colorpair by index, don't interpret S-Lang "emulated attributes"
 204  */
 205 
 206 void
 207 tty_lowlevel_setcolor (int color)
     /* [previous][next][first][last][top][bottom][index][help]  */
 208 {
 209     SLsmg_set_color (color & 0x7F);
 210 }
 211 
 212 /* --------------------------------------------------------------------------------------------- */
 213 
 214 void
 215 tty_set_normal_attrs (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 216 {
 217     SLsmg_normal_video ();
 218 }
 219 
 220 /* --------------------------------------------------------------------------------------------- */
 221 
 222 gboolean
 223 tty_use_256colors (GError **error)
     /* [previous][next][first][last][top][bottom][index][help]  */
 224 {
 225     int colors, overlay_colors;
 226 
 227     colors = tty_tigetnum ("colors", "Co");
 228     overlay_colors = tty_tigetnum ("CO", NULL);
 229 
 230     if (SLtt_Use_Ansi_Colors && (colors == 256 || (colors > 256 && overlay_colors == 256)))
 231         return TRUE;
 232 
 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"));
 244 
 245     return FALSE;
 246 }
 247 
 248 /* --------------------------------------------------------------------------------------------- */
 249 
 250 gboolean
 251 tty_use_truecolors (GError **error)
     /* [previous][next][first][last][top][bottom][index][help]  */
 252 {
 253     char *colorterm;
 254 
 255     /* True color is supported since slang-2.3.1 on 64-bit machines,
 256        and expected to be supported from slang-3 on 32-bit machines:
 257        https://lists.jedsoft.org/lists/slang-users/2016/0000014.html
 258        Check for sizeof (long) being 8, exactly as slang does. */
 259     if (SLang_Version < 20301 || (sizeof (long) != 8 && SLang_Version < 30000))
 260     {
 261         g_set_error (error, MC_ERROR, -1, _ ("True color not supported in this slang version."));
 262         return FALSE;
 263     }
 264 
 265     /* Duplicate slang's check so that we can pop up an error message
 266        rather than silently use wrong colors. */
 267     colorterm = getenv ("COLORTERM");
 268     if (!((tty_tigetflag ("RGB", NULL) && tty_tigetnum ("colors", "Co") == COLORS_TRUECOLOR)
 269           || (colorterm != NULL
 270               && (strcmp (colorterm, "truecolor") == 0 || strcmp (colorterm, "24bit") == 0))))
 271     {
 272         g_set_error (error, MC_ERROR, -1,
 273                      _ ("\nIf your terminal supports true colors, you need to set your TERM\n"
 274                         "environment variable to a *-direct256, *-direct16, or *-direct variant.\n"
 275                         "Use the 'toe -a' command to list all available variants on your system.\n"
 276                         "Alternatively, you can set COLORTERM=truecolor.\n"));
 277         return FALSE;
 278     }
 279 
 280     return TRUE;
 281 }
 282 
 283 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */