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-2024
   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 <http://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,
     /* [previous][next][first][last][top][bottom][index][help]  */
 103                                 const char *fg1, const char *bg1,
 104                                 const char *fg2, const char *bg2, 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,
 156                                             "black", "white", "black", "lightgray", SLTT_REV_MASK);
 157             break;
 158         case SPEC_A_BOLD:
 159             mc_tty_color_pair_init_special (mc_color_pair,
 160                                             "white", "black", "white", "black", SLTT_BOLD_MASK);
 161             break;
 162         case SPEC_A_BOLD_REVERSE:
 163             mc_tty_color_pair_init_special (mc_color_pair,
 164                                             "white", "white",
 165                                             "white", "white", SLTT_BOLD_MASK | SLTT_REV_MASK);
 166             break;
 167         case SPEC_A_UNDERLINE:
 168             mc_tty_color_pair_init_special (mc_color_pair,
 169                                             "white", "black", "white", "black", SLTT_ULINE_MASK);
 170             break;
 171         default:
 172             break;
 173         }
 174     }
 175     else
 176     {
 177         const char *fg, *bg;
 178 
 179         fg = tty_color_get_name_by_index (mc_color_pair->fg);
 180         bg = tty_color_get_name_by_index (mc_color_pair->bg);
 181         SLtt_set_color (mc_color_pair->pair_index, (char *) "", (char *) fg, (char *) bg);
 182         SLtt_add_color_attribute (mc_color_pair->pair_index, mc_color_pair->attr);
 183     }
 184 }
 185 
 186 /* --------------------------------------------------------------------------------------------- */
 187 
 188 void
 189 tty_setcolor (int color)
     /* [previous][next][first][last][top][bottom][index][help]  */
 190 {
 191     SLsmg_set_color (color);
 192 }
 193 
 194 /* --------------------------------------------------------------------------------------------- */
 195 /**
 196  * Set colorpair by index, don't interpret S-Lang "emulated attributes"
 197  */
 198 
 199 void
 200 tty_lowlevel_setcolor (int color)
     /* [previous][next][first][last][top][bottom][index][help]  */
 201 {
 202     SLsmg_set_color (color & 0x7F);
 203 }
 204 
 205 /* --------------------------------------------------------------------------------------------- */
 206 
 207 void
 208 tty_set_normal_attrs (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 209 {
 210     SLsmg_normal_video ();
 211 }
 212 
 213 /* --------------------------------------------------------------------------------------------- */
 214 
 215 gboolean
 216 tty_use_256colors (GError ** error)
     /* [previous][next][first][last][top][bottom][index][help]  */
 217 {
 218     gboolean ret;
 219 
 220     ret = (SLtt_Use_Ansi_Colors && SLtt_tgetnum ((char *) "Co") == 256);
 221 
 222     if (!ret)
 223         g_set_error (error, MC_ERROR, -1,
 224                      _("Your terminal doesn't even seem to support 256 colors."));
 225 
 226     return ret;
 227 }
 228 
 229 /* --------------------------------------------------------------------------------------------- */
 230 
 231 gboolean
 232 tty_use_truecolors (GError ** error)
     /* [previous][next][first][last][top][bottom][index][help]  */
 233 {
 234     char *colorterm;
 235 
 236     /* True color is supported since slang-2.3.1 on 64-bit machines,
 237        and expected to be supported from slang-3 on 32-bit machines:
 238        http://lists.jedsoft.org/lists/slang-users/2016/0000014.html.
 239        Check for sizeof (long) being 8, exactly as slang does. */
 240     if (SLang_Version < 20301 || (sizeof (long) != 8 && SLang_Version < 30000))
 241     {
 242         g_set_error (error, MC_ERROR, -1, _("True color not supported in this slang version."));
 243         return FALSE;
 244     }
 245 
 246     /* Duplicate slang's check so that we can pop up an error message
 247        rather than silently use wrong colors. */
 248     colorterm = getenv ("COLORTERM");
 249     if (colorterm == NULL
 250         || (strcmp (colorterm, "truecolor") != 0 && strcmp (colorterm, "24bit") != 0))
 251     {
 252         g_set_error (error, MC_ERROR, -1,
 253                      _("Set COLORTERM=truecolor if your terminal really supports true colors."));
 254         return FALSE;
 255     }
 256 
 257     return TRUE;
 258 }
 259 
 260 /* --------------------------------------------------------------------------------------------- */

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