root/lib/tty/color-internal.c

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

DEFINITIONS

This source file includes following definitions.
  1. parse_hex_digit
  2. parse_256_or_true_color_name
  3. tty_color_get_name_by_index
  4. tty_color_get_index_by_name
  5. tty_attr_get_bits

   1 /*
   2    Internal stuff of color setup
   3 
   4    Copyright (C) 1994-2025
   5    Free Software Foundation, Inc.
   6 
   7    Written by:
   8    Andrew Borodin <aborodin@vmail.ru>, 2009
   9    Slava Zanko <slavazanko@gmail.com>, 2009, 2013
  10    Egmont Koblinger <egmont@gmail.com>, 2010
  11 
  12    This file is part of the Midnight Commander.
  13 
  14    The Midnight Commander is free software: you can redistribute it
  15    and/or modify it under the terms of the GNU General Public License as
  16    published by the Free Software Foundation, either version 3 of the License,
  17    or (at your option) any later version.
  18 
  19    The Midnight Commander is distributed in the hope that it will be useful,
  20    but WITHOUT ANY WARRANTY; without even the implied warranty of
  21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22    GNU General Public License for more details.
  23 
  24    You should have received a copy of the GNU General Public License
  25    along with this program.  If not, see <https://www.gnu.org/licenses/>.
  26  */
  27 
  28 /** \file color-internal.c
  29  *  \brief Source: Internal stuff of color setup
  30  */
  31 
  32 #include <config.h>
  33 
  34 #include <string.h>  // strcmp
  35 
  36 #include "color.h"  // colors and attributes
  37 #include "color-internal.h"
  38 
  39 /*** global variables ****************************************************************************/
  40 
  41 gboolean mc_tty_color_disable;
  42 
  43 /*** file scope macro definitions ****************************************************************/
  44 
  45 #define COLOR_INTENSITY 8
  46 
  47 /*** file scope type declarations ****************************************************************/
  48 
  49 typedef struct mc_tty_color_table_struct
  50 {
  51     const char *name;
  52     int value;
  53 } mc_tty_color_table_t;
  54 
  55 /*** forward declarations (file scope functions) *************************************************/
  56 
  57 /*** file scope variables ************************************************************************/
  58 
  59 static mc_tty_color_table_t const color_table[] = {
  60     { "black", COLOR_BLACK },
  61     { "gray", COLOR_BLACK + COLOR_INTENSITY },
  62     { "red", COLOR_RED },
  63     { "brightred", COLOR_RED + COLOR_INTENSITY },
  64     { "green", COLOR_GREEN },
  65     { "brightgreen", COLOR_GREEN + COLOR_INTENSITY },
  66     { "brown", COLOR_YELLOW },
  67     { "yellow", COLOR_YELLOW + COLOR_INTENSITY },
  68     { "blue", COLOR_BLUE },
  69     { "brightblue", COLOR_BLUE + COLOR_INTENSITY },
  70     { "magenta", COLOR_MAGENTA },
  71     { "brightmagenta", COLOR_MAGENTA + COLOR_INTENSITY },
  72     { "cyan", COLOR_CYAN },
  73     { "brightcyan", COLOR_CYAN + COLOR_INTENSITY },
  74     { "lightgray", COLOR_WHITE },
  75     { "white", COLOR_WHITE + COLOR_INTENSITY },
  76     { "default", -1 },  // default color of the terminal
  77     // special colors
  78     { "A_REVERSE", SPEC_A_REVERSE },
  79     { "A_BOLD", SPEC_A_BOLD },
  80     { "A_BOLD_REVERSE", SPEC_A_BOLD_REVERSE },
  81     { "A_UNDERLINE", SPEC_A_UNDERLINE },
  82     // End of list
  83     { NULL, 0 },
  84 };
  85 
  86 static mc_tty_color_table_t const attributes_table[] = {
  87     { "bold", A_BOLD },
  88 #ifdef A_ITALIC  // available since ncurses-5.9-20130831 / slang-pre2.3.0-107
  89     { "italic", A_ITALIC },
  90 #endif
  91     { "underline", A_UNDERLINE },
  92     { "reverse", A_REVERSE },
  93     { "blink", A_BLINK },
  94     // End of list
  95     { NULL, 0 },
  96 };
  97 
  98 /* --------------------------------------------------------------------------------------------- */
  99 /*** file scope functions ************************************************************************/
 100 /* --------------------------------------------------------------------------------------------- */
 101 
 102 static inline int
 103 parse_hex_digit (char c)
     /* [previous][next][first][last][top][bottom][index][help]  */
 104 {
 105     if (c >= '0' && c <= '9')
 106         return c - '0';
 107     c |= 0x20;
 108     if (c >= 'a' && c <= 'f')
 109         return c - 'a' + 10;
 110     return -1;
 111 }
 112 
 113 /* --------------------------------------------------------------------------------------------- */
 114 
 115 static int
 116 parse_256_or_true_color_name (const char *color_name)
     /* [previous][next][first][last][top][bottom][index][help]  */
 117 {
 118     int i;
 119     char dummy;
 120 
 121     // cppcheck-suppress invalidscanf
 122     if (sscanf (color_name, "color%d%c", &i, &dummy) == 1 && i >= 0 && i < 256)
 123     {
 124         return i;
 125     }
 126     // cppcheck-suppress invalidscanf
 127     if (sscanf (color_name, "gray%d%c", &i, &dummy) == 1 && i >= 0 && i < 24)
 128     {
 129         return 232 + i;
 130     }
 131     if (strncmp (color_name, "rgb", 3) == 0             //
 132         && color_name[3] >= '0' && color_name[3] < '6'  //
 133         && color_name[4] >= '0' && color_name[4] < '6'  //
 134         && color_name[5] >= '0' && color_name[5] < '6'  //
 135         && color_name[6] == '\0')
 136     {
 137         return 16 + 36 * (color_name[3] - '0') + 6 * (color_name[4] - '0') + (color_name[5] - '0');
 138     }
 139     if (color_name[0] == '#')
 140     {
 141         int len;
 142 
 143         color_name++;
 144         len = (int) strlen (color_name);
 145         if (len == 3 || len == 6)
 146         {
 147             int h[6];
 148 
 149             for (i = 0; i < len; i++)
 150             {
 151                 h[i] = parse_hex_digit (color_name[i]);
 152                 if (h[i] == -1)
 153                     return -1;
 154             }
 155 
 156             if (i == 3)
 157                 i = (h[0] << 20) | (h[0] << 16) | (h[1] << 12) | (h[1] << 8) | (h[2] << 4) | h[2];
 158             else
 159                 i = (h[0] << 20) | (h[1] << 16) | (h[2] << 12) | (h[3] << 8) | (h[4] << 4) | h[5];
 160             return (1 << 24) | i;
 161         }
 162     }
 163 
 164     return -1;
 165 }
 166 
 167 /* --------------------------------------------------------------------------------------------- */
 168 /*** public functions ****************************************************************************/
 169 /* --------------------------------------------------------------------------------------------- */
 170 
 171 const char *
 172 tty_color_get_name_by_index (int idx)
     /* [previous][next][first][last][top][bottom][index][help]  */
 173 {
 174     int i;
 175 
 176     // Find the real English name of the first 16 colors,
 177     // as well as the A_* special values.
 178     for (i = 0; color_table[i].name != NULL; i++)
 179         if (idx == color_table[i].value)
 180             return color_table[i].name;
 181 
 182     // Create and return the strings in "colorNNN" or "#rrggbb" format.
 183     if ((idx >= 16 && idx < 256) || (idx & (1 << 24)) != 0)
 184     {
 185         char name[9];
 186 
 187         if (idx < 256)
 188             g_snprintf (name, sizeof (name), "color%d", idx);
 189         else
 190             g_snprintf (name, sizeof (name), "#%06X", (unsigned int) idx & 0xFFFFFF);
 191         return g_intern_string (name);
 192     }
 193     return "default";
 194 }
 195 
 196 /* --------------------------------------------------------------------------------------------- */
 197 
 198 int
 199 tty_color_get_index_by_name (const char *color_name)
     /* [previous][next][first][last][top][bottom][index][help]  */
 200 {
 201     if (color_name != NULL)
 202     {
 203         size_t i;
 204 
 205         for (i = 0; color_table[i].name != NULL; i++)
 206             if (strcmp (color_name, color_table[i].name) == 0)
 207                 return color_table[i].value;
 208         return parse_256_or_true_color_name (color_name);
 209     }
 210     return -1;
 211 }
 212 
 213 /* --------------------------------------------------------------------------------------------- */
 214 
 215 int
 216 tty_attr_get_bits (const char *attrs)
     /* [previous][next][first][last][top][bottom][index][help]  */
 217 {
 218     int attr_bits = 0;
 219 
 220     if (attrs != NULL)
 221     {
 222         gchar **attr_list;
 223         int i;
 224 
 225         attr_list = g_strsplit (attrs, "+", -1);
 226 
 227         for (i = 0; attr_list[i] != NULL; i++)
 228         {
 229             int j;
 230 
 231             for (j = 0; attributes_table[j].name != NULL; j++)
 232             {
 233                 if (strcmp (attr_list[i], attributes_table[j].name) == 0)
 234                 {
 235                     attr_bits |= attributes_table[j].value;
 236                     break;
 237                 }
 238             }
 239         }
 240         g_strfreev (attr_list);
 241     }
 242     return attr_bits;
 243 }
 244 
 245 /* --------------------------------------------------------------------------------------------- */

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