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. tty_color_init_lib
  3. tty_color_deinit_lib
  4. tty_color_try_alloc_lib_pair
  5. tty_setcolor
  6. tty_lowlevel_setcolor
  7. tty_set_normal_attrs
  8. tty_use_256colors
  9. 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 /*** public functions ****************************************************************************/
 105 /* --------------------------------------------------------------------------------------------- */
 106 
 107 void
 108 tty_color_init_lib (gboolean disable, gboolean force)
     /* [previous][next][first][last][top][bottom][index][help]  */
 109 {
 110     /* FIXME: if S-Lang is used, has_colors() must be called regardless
 111        of whether we are interested in its result */
 112     if (has_colors (disable, force) && !disable)
 113     {
 114         use_colors = TRUE;
 115 
 116         // Extended color mode detection routines must first be called before loading any skin
 117         tty_use_256colors (NULL);
 118         tty_use_truecolors (NULL);
 119     }
 120 }
 121 
 122 /* --------------------------------------------------------------------------------------------- */
 123 
 124 void
 125 tty_color_deinit_lib (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 126 {
 127 }
 128 
 129 /* --------------------------------------------------------------------------------------------- */
 130 
 131 void
 132 tty_color_try_alloc_lib_pair (tty_color_lib_pair_t *mc_color_pair)
     /* [previous][next][first][last][top][bottom][index][help]  */
 133 {
 134     /*
 135      * According to the S-Lang Library C Programmer's Guide (v2.3.0)
 136      * (https://www.jedsoft.org/slang/doc/pdf/cslang.pdf), ยง7.4.4:
 137      *
 138      * "[for SLtt_set_color] When the SLtt_Use_Ansi_Colors variable is zero, all objects with
 139      * numbers greater than one will be displayed in inverse video." Footnote: "This behavior can be
 140      * modifed by using the SLtt_set_mono function call."
 141      */
 142     if (SLtt_Use_Ansi_Colors)
 143     {
 144         const char *fg, *bg;
 145 
 146         fg = tty_color_get_name_by_index (mc_color_pair->fg);
 147         bg = tty_color_get_name_by_index (mc_color_pair->bg);
 148         SLtt_set_color (mc_color_pair->pair_index, (char *) "", (char *) fg, (char *) bg);
 149         SLtt_add_color_attribute (mc_color_pair->pair_index, mc_color_pair->attr);
 150     }
 151     else
 152         SLtt_set_mono (mc_color_pair->pair_index, NULL, mc_color_pair->attr);
 153 }
 154 
 155 /* --------------------------------------------------------------------------------------------- */
 156 
 157 void
 158 tty_setcolor (int color)
     /* [previous][next][first][last][top][bottom][index][help]  */
 159 {
 160     SLsmg_set_color (color);
 161 }
 162 
 163 /* --------------------------------------------------------------------------------------------- */
 164 /**
 165  * Set colorpair by index, don't interpret S-Lang "emulated attributes"
 166  */
 167 
 168 void
 169 tty_lowlevel_setcolor (int color)
     /* [previous][next][first][last][top][bottom][index][help]  */
 170 {
 171     SLsmg_set_color (color & 0x7F);
 172 }
 173 
 174 /* --------------------------------------------------------------------------------------------- */
 175 
 176 void
 177 tty_set_normal_attrs (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 178 {
 179     SLsmg_normal_video ();
 180 }
 181 
 182 /* --------------------------------------------------------------------------------------------- */
 183 
 184 gboolean
 185 tty_use_256colors (GError **error)
     /* [previous][next][first][last][top][bottom][index][help]  */
 186 {
 187     int colors, overlay_colors;
 188 
 189     colors = tty_tigetnum ("colors", "Co");
 190     overlay_colors = tty_tigetnum ("CO", NULL);
 191 
 192     if (SLtt_Use_Ansi_Colors && (colors == 256 || (colors > 256 && overlay_colors == 256)))
 193         return TRUE;
 194 
 195     if (tty_use_truecolors (NULL))
 196     {
 197         need_convert_256color = TRUE;
 198         return TRUE;
 199     }
 200 
 201     g_set_error (error, MC_ERROR, -1,
 202                  _ ("\nIf your terminal supports 256 colors, you need to set your TERM\n"
 203                     "environment variable to match your terminal, perhaps using\n"
 204                     "a *-256color or *-direct256 variant. Use the 'toe -a'\n"
 205                     "command to list all available variants on your system.\n"));
 206 
 207     return FALSE;
 208 }
 209 
 210 /* --------------------------------------------------------------------------------------------- */
 211 
 212 gboolean
 213 tty_use_truecolors (GError **error)
     /* [previous][next][first][last][top][bottom][index][help]  */
 214 {
 215     char *colorterm;
 216 
 217     /* True color is supported since slang-2.3.1 on 64-bit machines,
 218        and expected to be supported from slang-3 on 32-bit machines:
 219        https://lists.jedsoft.org/lists/slang-users/2016/0000014.html
 220        Check for sizeof (long) being 8, exactly as slang does. */
 221     if (SLang_Version < 20301 || (sizeof (long) != 8 && SLang_Version < 30000))
 222     {
 223         g_set_error (error, MC_ERROR, -1, _ ("True color not supported in this slang version."));
 224         return FALSE;
 225     }
 226 
 227     /* Duplicate slang's check so that we can pop up an error message
 228        rather than silently use wrong colors. */
 229     colorterm = getenv ("COLORTERM");
 230     if (!((tty_tigetflag ("RGB", NULL) && tty_tigetnum ("colors", "Co") == COLORS_TRUECOLOR)
 231           || (colorterm != NULL
 232               && (strcmp (colorterm, "truecolor") == 0 || strcmp (colorterm, "24bit") == 0))))
 233     {
 234         g_set_error (error, MC_ERROR, -1,
 235                      _ ("\nIf your terminal supports true colors, you need to set your TERM\n"
 236                         "environment variable to a *-direct256, *-direct16, or *-direct variant.\n"
 237                         "Use the 'toe -a' command to list all available variants on your system.\n"
 238                         "Alternatively, you can set COLORTERM=truecolor.\n"));
 239         return FALSE;
 240     }
 241 
 242     return TRUE;
 243 }
 244 
 245 /* --------------------------------------------------------------------------------------------- */

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