color-internal.c 7.6 KB

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