mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 20:36:50 +03:00
fe42478b97
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
245 lines
7.3 KiB
C
245 lines
7.3 KiB
C
/*
|
|
Internal stuff of color setup
|
|
|
|
Copyright (C) 1994-2024
|
|
Free Software Foundation, Inc.
|
|
|
|
Written by:
|
|
Andrew Borodin <aborodin@vmail.ru>, 2009
|
|
Slava Zanko <slavazanko@gmail.com>, 2009, 2013
|
|
Egmont Koblinger <egmont@gmail.com>, 2010
|
|
|
|
This file is part of the Midnight Commander.
|
|
|
|
The Midnight Commander is free software: you can redistribute it
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation, either version 3 of the License,
|
|
or (at your option) any later version.
|
|
|
|
The Midnight Commander is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/** \file color-internal.c
|
|
* \brief Source: Internal stuff of color setup
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include <string.h> /* strcmp */
|
|
|
|
#include "color.h" /* colors and attributes */
|
|
#include "color-internal.h"
|
|
|
|
/*** global variables ****************************************************************************/
|
|
|
|
gboolean mc_tty_color_disable;
|
|
|
|
/*** file scope macro definitions ****************************************************************/
|
|
|
|
#define COLOR_INTENSITY 8
|
|
|
|
/*** file scope type declarations ****************************************************************/
|
|
|
|
typedef struct mc_tty_color_table_struct
|
|
{
|
|
const char *name;
|
|
int value;
|
|
} mc_tty_color_table_t;
|
|
|
|
/*** forward declarations (file scope functions) *************************************************/
|
|
|
|
/*** file scope variables ************************************************************************/
|
|
|
|
static mc_tty_color_table_t const color_table[] = {
|
|
{"black", COLOR_BLACK},
|
|
{"gray", COLOR_BLACK + COLOR_INTENSITY},
|
|
{"red", COLOR_RED},
|
|
{"brightred", COLOR_RED + COLOR_INTENSITY},
|
|
{"green", COLOR_GREEN},
|
|
{"brightgreen", COLOR_GREEN + COLOR_INTENSITY},
|
|
{"brown", COLOR_YELLOW},
|
|
{"yellow", COLOR_YELLOW + COLOR_INTENSITY},
|
|
{"blue", COLOR_BLUE},
|
|
{"brightblue", COLOR_BLUE + COLOR_INTENSITY},
|
|
{"magenta", COLOR_MAGENTA},
|
|
{"brightmagenta", COLOR_MAGENTA + COLOR_INTENSITY},
|
|
{"cyan", COLOR_CYAN},
|
|
{"brightcyan", COLOR_CYAN + COLOR_INTENSITY},
|
|
{"lightgray", COLOR_WHITE},
|
|
{"white", COLOR_WHITE + COLOR_INTENSITY},
|
|
{"default", -1}, /* default color of the terminal */
|
|
/* special colors */
|
|
{"A_REVERSE", SPEC_A_REVERSE},
|
|
{"A_BOLD", SPEC_A_BOLD},
|
|
{"A_BOLD_REVERSE", SPEC_A_BOLD_REVERSE},
|
|
{"A_UNDERLINE", SPEC_A_UNDERLINE},
|
|
/* End of list */
|
|
{NULL, 0}
|
|
};
|
|
|
|
static mc_tty_color_table_t const attributes_table[] = {
|
|
{"bold", A_BOLD},
|
|
#ifdef A_ITALIC /* available since ncurses-5.9-20130831 / slang-pre2.3.0-107 */
|
|
{"italic", A_ITALIC},
|
|
#endif /* A_ITALIC */
|
|
{"underline", A_UNDERLINE},
|
|
{"reverse", A_REVERSE},
|
|
{"blink", A_BLINK},
|
|
/* End of list */
|
|
{NULL, 0}
|
|
};
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
/*** file scope functions ************************************************************************/
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
static inline int
|
|
parse_hex_digit (char c)
|
|
{
|
|
if (c >= '0' && c <= '9')
|
|
return c - '0';
|
|
c |= 0x20;
|
|
if (c >= 'a' && c <= 'f')
|
|
return c - 'a' + 10;
|
|
return -1;
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
static int
|
|
parse_256_or_true_color_name (const char *color_name)
|
|
{
|
|
int i;
|
|
char dummy;
|
|
|
|
/* cppcheck-suppress invalidscanf */
|
|
if (sscanf (color_name, "color%d%c", &i, &dummy) == 1 && i >= 0 && i < 256)
|
|
{
|
|
return i;
|
|
}
|
|
/* cppcheck-suppress invalidscanf */
|
|
if (sscanf (color_name, "gray%d%c", &i, &dummy) == 1 && i >= 0 && i < 24)
|
|
{
|
|
return 232 + i;
|
|
}
|
|
if (strncmp (color_name, "rgb", 3) == 0 &&
|
|
color_name[3] >= '0' && color_name[3] < '6' &&
|
|
color_name[4] >= '0' && color_name[4] < '6' &&
|
|
color_name[5] >= '0' && color_name[5] < '6' && color_name[6] == '\0')
|
|
{
|
|
return 16 + 36 * (color_name[3] - '0') + 6 * (color_name[4] - '0') + (color_name[5] - '0');
|
|
}
|
|
if (color_name[0] == '#')
|
|
{
|
|
int len;
|
|
|
|
color_name++;
|
|
len = (int) strlen (color_name);
|
|
if (len == 3 || len == 6)
|
|
{
|
|
int h[6];
|
|
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
h[i] = parse_hex_digit (color_name[i]);
|
|
if (h[i] == -1)
|
|
return -1;
|
|
}
|
|
|
|
if (i == 3)
|
|
i = (h[0] << 20) | (h[0] << 16) | (h[1] << 12) | (h[1] << 8) | (h[2] << 4) | h[2];
|
|
else
|
|
i = (h[0] << 20) | (h[1] << 16) | (h[2] << 12) | (h[3] << 8) | (h[4] << 4) | h[5];
|
|
return (1 << 24) | i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
/*** public functions ****************************************************************************/
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
const char *
|
|
tty_color_get_name_by_index (int idx)
|
|
{
|
|
int i;
|
|
|
|
/* Find the real English name of the first 16 colors, */
|
|
/* as well as the A_* special values. */
|
|
for (i = 0; color_table[i].name != NULL; i++)
|
|
if (idx == color_table[i].value)
|
|
return color_table[i].name;
|
|
|
|
/* Create and return the strings in "colorNNN" or "#rrggbb" format. */
|
|
if ((idx >= 16 && idx < 256) || (idx & (1 << 24)) != 0)
|
|
{
|
|
char name[9];
|
|
|
|
if (idx < 256)
|
|
g_snprintf (name, sizeof (name), "color%d", idx);
|
|
else
|
|
g_snprintf (name, sizeof (name), "#%06X", (unsigned int) idx & 0xFFFFFF);
|
|
return g_intern_string (name);
|
|
}
|
|
return "default";
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
int
|
|
tty_color_get_index_by_name (const char *color_name)
|
|
{
|
|
if (color_name != NULL)
|
|
{
|
|
size_t i;
|
|
|
|
for (i = 0; color_table[i].name != NULL; i++)
|
|
if (strcmp (color_name, color_table[i].name) == 0)
|
|
return color_table[i].value;
|
|
return parse_256_or_true_color_name (color_name);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
int
|
|
tty_attr_get_bits (const char *attrs)
|
|
{
|
|
int attr_bits = 0;
|
|
|
|
if (attrs != NULL)
|
|
{
|
|
gchar **attr_list;
|
|
int i;
|
|
|
|
attr_list = g_strsplit (attrs, "+", -1);
|
|
|
|
for (i = 0; attr_list[i] != NULL; i++)
|
|
{
|
|
int j;
|
|
|
|
for (j = 0; attributes_table[j].name != NULL; j++)
|
|
{
|
|
if (strcmp (attr_list[i], attributes_table[j].name) == 0)
|
|
{
|
|
attr_bits |= attributes_table[j].value;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
g_strfreev (attr_list);
|
|
}
|
|
return attr_bits;
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|