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-slang.h"
  42 #include "color.h"  // variables
  43 #include "color-internal.h"
  44 
  45 /*** global variables ****************************************************************************/
  46 
  47 /*** file scope macro definitions ****************************************************************/
  48 
  49 /*** file scope type declarations ****************************************************************/
  50 
  51 /*** forward declarations (file scope functions) *************************************************/
  52 
  53 /*** file scope variables ************************************************************************/
  54 
  55 /* --------------------------------------------------------------------------------------------- */
  56 /*** file scope functions ************************************************************************/
  57 /* --------------------------------------------------------------------------------------------- */
  58 
  59 static int
  60 has_colors (gboolean disable, gboolean force)
     /* [previous][next][first][last][top][bottom][index][help]  */
  61 {
  62     mc_tty_color_disable = disable;
  63 
  64     if (force || (getenv ("COLORTERM") != NULL))
  65         SLtt_Use_Ansi_Colors = 1;
  66 
  67     if (!mc_tty_color_disable)
  68     {
  69         const char *terminal = getenv ("TERM");
  70         const size_t len = strlen (terminal);
  71         char *cts = mc_global.tty.color_terminal_string;
  72 
  73         // check mc_global.tty.color_terminal_string
  74         while (*cts != '\0')
  75         {
  76             char *s;
  77             size_t i = 0;
  78 
  79             while (whitespace (*cts))
  80                 cts++;
  81             s = cts;
  82 
  83             while (*cts != '\0' && *cts != ',')
  84             {
  85                 cts++;
  86                 i++;
  87             }
  88 
  89             if ((i != 0) && (i == len) && (strncmp (s, terminal, i) == 0))
  90                 SLtt_Use_Ansi_Colors = 1;
  91 
  92             if (*cts == ',')
  93                 cts++;
  94         }
  95     }
  96     return SLtt_Use_Ansi_Colors;
  97 }
  98 
  99 /* --------------------------------------------------------------------------------------------- */
 100 
 101 static void
 102 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]  */
 103                                 const char *bg1, const char *fg2, const char *bg2,
 104                                 SLtt_Char_Type mask)
 105 {
 106     if (SLtt_Use_Ansi_Colors != 0)
 107     {
 108         if (!mc_tty_color_disable)
 109         {
 110             SLtt_set_color (mc_color_pair->pair_index, (char *) "", (char *) fg1, (char *) bg1);
 111         }
 112         else
 113         {
 114             SLtt_set_color (mc_color_pair->pair_index, (char *) "", (char *) fg2, (char *) bg2);
 115         }
 116     }
 117     else
 118     {
 119         SLtt_set_mono (mc_color_pair->pair_index, NULL, mask);
 120     }
 121 }
 122 
 123 /* --------------------------------------------------------------------------------------------- */
 124 /*** public functions ****************************************************************************/
 125 /* --------------------------------------------------------------------------------------------- */
 126 
 127 void
 128 tty_color_init_lib (gboolean disable, gboolean force)
     /* [previous][next][first][last][top][bottom][index][help]  */
 129 {
 130     /* FIXME: if S-Lang is used, has_colors() must be called regardless
 131        of whether we are interested in its result */
 132     if (has_colors (disable, force) && !disable)
 133     {
 134         use_colors = TRUE;
 135     }
 136 }
 137 
 138 /* --------------------------------------------------------------------------------------------- */
 139 
 140 void
 141 tty_color_deinit_lib (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 142 {
 143 }
 144 
 145 /* --------------------------------------------------------------------------------------------- */
 146 
 147 void
 148 tty_color_try_alloc_lib_pair (tty_color_lib_pair_t *mc_color_pair)
     /* [previous][next][first][last][top][bottom][index][help]  */
 149 {
 150     if (mc_color_pair->fg <= (int) SPEC_A_REVERSE)
 151     {
 152         switch (mc_color_pair->fg)
 153         {
 154         case SPEC_A_REVERSE:
 155             mc_tty_color_pair_init_special (mc_color_pair, "black", "white", "black", "lightgray",
 156                                             SLTT_REV_MASK);
 157             break;
 158         case SPEC_A_BOLD:
 159             mc_tty_color_pair_init_special (mc_color_pair, "white", "black", "white", "black",
 160                                             SLTT_BOLD_MASK);
 161             break;
 162         case SPEC_A_BOLD_REVERSE:
 163             mc_tty_color_pair_init_special (mc_color_pair, "white", "white", "white", "white",
 164                                             SLTT_BOLD_MASK | SLTT_REV_MASK);
 165             break;
 166         case SPEC_A_UNDERLINE:
 167             mc_tty_color_pair_init_special (mc_color_pair, "white", "black", "white", "black",
 168                                             SLTT_ULINE_MASK);
 169             break;
 170         default:
 171             break;
 172         }
 173     }
 174     else
 175     {
 176         const char *fg, *bg;
 177 
 178         fg = tty_color_get_name_by_index (mc_color_pair->fg);
 179         bg = tty_color_get_name_by_index (mc_color_pair->bg);
 180         SLtt_set_color (mc_color_pair->pair_index, (char *) "", (char *) fg, (char *) bg);
 181         SLtt_add_color_attribute (mc_color_pair->pair_index, mc_color_pair->attr);
 182     }
 183 }
 184 
 185 /* --------------------------------------------------------------------------------------------- */
 186 
 187 void
 188 tty_setcolor (int color)
     /* [previous][next][first][last][top][bottom][index][help]  */
 189 {
 190     SLsmg_set_color (color);
 191 }
 192 
 193 /* --------------------------------------------------------------------------------------------- */
 194 /**
 195  * Set colorpair by index, don't interpret S-Lang "emulated attributes"
 196  */
 197 
 198 void
 199 tty_lowlevel_setcolor (int color)
     /* [previous][next][first][last][top][bottom][index][help]  */
 200 {
 201     SLsmg_set_color (color & 0x7F);
 202 }
 203 
 204 /* --------------------------------------------------------------------------------------------- */
 205 
 206 void
 207 tty_set_normal_attrs (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 208 {
 209     SLsmg_normal_video ();
 210 }
 211 
 212 /* --------------------------------------------------------------------------------------------- */
 213 
 214 gboolean
 215 tty_use_256colors (GError **error)
     /* [previous][next][first][last][top][bottom][index][help]  */
 216 {
 217     gboolean ret;
 218 
 219     ret = (SLtt_Use_Ansi_Colors && SLtt_tgetnum ((char *) "Co") == 256);
 220 
 221     if (!ret)
 222         g_set_error (error, MC_ERROR, -1,
 223                      _ ("Your terminal doesn't even seem to support 256 colors."));
 224 
 225     return ret;
 226 }
 227 
 228 /* --------------------------------------------------------------------------------------------- */
 229 
 230 gboolean
 231 tty_use_truecolors (GError **error)
     /* [previous][next][first][last][top][bottom][index][help]  */
 232 {
 233     char *colorterm;
 234 
 235     /* True color is supported since slang-2.3.1 on 64-bit machines,
 236        and expected to be supported from slang-3 on 32-bit machines:
 237        https://lists.jedsoft.org/lists/slang-users/2016/0000014.html
 238        Check for sizeof (long) being 8, exactly as slang does. */
 239     if (SLang_Version < 20301 || (sizeof (long) != 8 && SLang_Version < 30000))
 240     {
 241         g_set_error (error, MC_ERROR, -1, _ ("True color not supported in this slang version."));
 242         return FALSE;
 243     }
 244 
 245     /* Duplicate slang's check so that we can pop up an error message
 246        rather than silently use wrong colors. */
 247     colorterm = getenv ("COLORTERM");
 248     if (colorterm == NULL
 249         || (strcmp (colorterm, "truecolor") != 0 && strcmp (colorterm, "24bit") != 0))
 250     {
 251         g_set_error (error, MC_ERROR, -1,
 252                      _ ("Set COLORTERM=truecolor if your terminal really supports true colors."));
 253         return FALSE;
 254     }
 255 
 256     return TRUE;
 257 }
 258 
 259 /* --------------------------------------------------------------------------------------------- */

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