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-2021
   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 <http://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 /*** file scope variables ************************************************************************/
  56 
  57 static mc_tty_color_table_t const color_table[] = {
  58     {"black", COLOR_BLACK},
  59     {"gray", COLOR_BLACK + COLOR_INTENSITY},
  60     {"red", COLOR_RED},
  61     {"brightred", COLOR_RED + COLOR_INTENSITY},
  62     {"green", COLOR_GREEN},
  63     {"brightgreen", COLOR_GREEN + COLOR_INTENSITY},
  64     {"brown", COLOR_YELLOW},
  65     {"yellow", COLOR_YELLOW + COLOR_INTENSITY},
  66     {"blue", COLOR_BLUE},
  67     {"brightblue", COLOR_BLUE + COLOR_INTENSITY},
  68     {"magenta", COLOR_MAGENTA},
  69     {"brightmagenta", COLOR_MAGENTA + COLOR_INTENSITY},
  70     {"cyan", COLOR_CYAN},
  71     {"brightcyan", COLOR_CYAN + COLOR_INTENSITY},
  72     {"lightgray", COLOR_WHITE},
  73     {"white", COLOR_WHITE + COLOR_INTENSITY},
  74     {"default", -1},            /* default color of the terminal */
  75     /* special colors */
  76     {"A_REVERSE", SPEC_A_REVERSE},
  77     {"A_BOLD", SPEC_A_BOLD},
  78     {"A_BOLD_REVERSE", SPEC_A_BOLD_REVERSE},
  79     {"A_UNDERLINE", SPEC_A_UNDERLINE},
  80     /* End of list */
  81     {NULL, 0}
  82 };
  83 
  84 static mc_tty_color_table_t const attributes_table[] = {
  85     {"bold", A_BOLD},
  86 #ifdef A_ITALIC                 /* available since ncurses-5.9-20130831 / slang-pre2.3.0-107 */
  87     {"italic", A_ITALIC},
  88 #endif /* A_ITALIC */
  89     {"underline", A_UNDERLINE},
  90     {"reverse", A_REVERSE},
  91     {"blink", A_BLINK},
  92     /* End of list */
  93     {NULL, 0}
  94 };
  95 
  96 /* --------------------------------------------------------------------------------------------- */
  97 /*** file scope functions ************************************************************************/
  98 /* --------------------------------------------------------------------------------------------- */
  99 
 100 static inline int
 101 parse_hex_digit (char c)
     /* [previous][next][first][last][top][bottom][index][help]  */
 102 {
 103     if (c >= '0' && c <= '9')
 104         return c - '0';
 105     c |= 0x20;
 106     if (c >= 'a' && c <= 'f')
 107         return c - 'a' + 10;
 108     return -1;
 109 }
 110 
 111 /* --------------------------------------------------------------------------------------------- */
 112 
 113 static int
 114 parse_256_or_true_color_name (const char *color_name)
     /* [previous][next][first][last][top][bottom][index][help]  */
 115 {
 116     int i;
 117     char dummy;
 118 
 119     /* cppcheck-suppress invalidscanf */
 120     if (sscanf (color_name, "color%d%c", &i, &dummy) == 1 && i >= 0 && i < 256)
 121     {
 122         return i;
 123     }
 124     /* cppcheck-suppress invalidscanf */
 125     if (sscanf (color_name, "gray%d%c", &i, &dummy) == 1 && i >= 0 && i < 24)
 126     {
 127         return 232 + i;
 128     }
 129     if (strncmp (color_name, "rgb", 3) == 0 &&
 130         color_name[3] >= '0' && color_name[3] < '6' &&
 131         color_name[4] >= '0' && color_name[4] < '6' &&
 132         color_name[5] >= '0' && color_name[5] < '6' && color_name[6] == '\0')
 133     {
 134         return 16 + 36 * (color_name[3] - '0') + 6 * (color_name[4] - '0') + (color_name[5] - '0');
 135     }
 136     if (color_name[0] == '#')
 137     {
 138         int len;
 139 
 140         color_name++;
 141         len = (int) strlen (color_name);
 142         if (len == 3 || len == 6)
 143         {
 144             int h[6];
 145 
 146             for (i = 0; i < len; i++)
 147             {
 148                 h[i] = parse_hex_digit (color_name[i]);
 149                 if (h[i] == -1)
 150                     return -1;
 151             }
 152 
 153             if (i == 3)
 154                 i = (h[0] << 20) | (h[0] << 16) | (h[1] << 12) | (h[1] << 8) | (h[2] << 4) | h[2];
 155             else
 156                 i = (h[0] << 20) | (h[1] << 16) | (h[2] << 12) | (h[3] << 8) | (h[4] << 4) | h[5];
 157             return (1 << 24) | i;
 158         }
 159     }
 160 
 161     return -1;
 162 }
 163 
 164 /* --------------------------------------------------------------------------------------------- */
 165 /*** public functions ****************************************************************************/
 166 /* --------------------------------------------------------------------------------------------- */
 167 
 168 const char *
 169 tty_color_get_name_by_index (int idx)
     /* [previous][next][first][last][top][bottom][index][help]  */
 170 {
 171     int i;
 172 
 173     /* Find the real English name of the first 16 colors, */
 174     /* as well as the A_* special values. */
 175     for (i = 0; color_table[i].name != NULL; i++)
 176         if (idx == color_table[i].value)
 177             return color_table[i].name;
 178 
 179     /* Create and return the strings in "colorNNN" or "#rrggbb" format. */
 180     if ((idx >= 16 && idx < 256) || (idx & (1 << 24)) != 0)
 181     {
 182         char name[9];
 183 
 184         if (idx < 256)
 185             sprintf (name, "color%d", idx);
 186         else
 187             sprintf (name, "#%06X", (unsigned int) idx & 0xFFFFFF);
 188         return g_intern_string (name);
 189     }
 190     return "default";
 191 }
 192 
 193 /* --------------------------------------------------------------------------------------------- */
 194 
 195 int
 196 tty_color_get_index_by_name (const char *color_name)
     /* [previous][next][first][last][top][bottom][index][help]  */
 197 {
 198     if (color_name != NULL)
 199     {
 200         size_t i;
 201 
 202         for (i = 0; color_table[i].name != NULL; i++)
 203             if (strcmp (color_name, color_table[i].name) == 0)
 204                 return color_table[i].value;
 205         return parse_256_or_true_color_name (color_name);
 206     }
 207     return -1;
 208 }
 209 
 210 /* --------------------------------------------------------------------------------------------- */
 211 
 212 int
 213 tty_attr_get_bits (const char *attrs)
     /* [previous][next][first][last][top][bottom][index][help]  */
 214 {
 215     int attr_bits = 0;
 216 
 217     if (attrs != NULL)
 218     {
 219         gchar **attr_list;
 220         int i;
 221 
 222         attr_list = g_strsplit (attrs, "+", -1);
 223 
 224         for (i = 0; attr_list[i] != NULL; i++)
 225         {
 226             int j;
 227 
 228             for (j = 0; attributes_table[j].name != NULL; j++)
 229             {
 230                 if (strcmp (attr_list[i], attributes_table[j].name) == 0)
 231                 {
 232                     attr_bits |= attributes_table[j].value;
 233                     break;
 234                 }
 235             }
 236         }
 237         g_strfreev (attr_list);
 238     }
 239     return attr_bits;
 240 }
 241 
 242 /* --------------------------------------------------------------------------------------------- */

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