17f2ac410Schristos /* Styling for ui_file 2*6881a400Schristos Copyright (C) 2018-2023 Free Software Foundation, Inc. 37f2ac410Schristos 47f2ac410Schristos This file is part of GDB. 57f2ac410Schristos 67f2ac410Schristos This program is free software; you can redistribute it and/or modify 77f2ac410Schristos it under the terms of the GNU General Public License as published by 87f2ac410Schristos the Free Software Foundation; either version 3 of the License, or 97f2ac410Schristos (at your option) any later version. 107f2ac410Schristos 117f2ac410Schristos This program is distributed in the hope that it will be useful, 127f2ac410Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 137f2ac410Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 147f2ac410Schristos GNU General Public License for more details. 157f2ac410Schristos 167f2ac410Schristos You should have received a copy of the GNU General Public License 177f2ac410Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 187f2ac410Schristos 197f2ac410Schristos #ifndef UI_STYLE_H 207f2ac410Schristos #define UI_STYLE_H 217f2ac410Schristos 227f2ac410Schristos /* Styles that can be applied to a ui_file. */ 237f2ac410Schristos struct ui_file_style 247f2ac410Schristos { 257f2ac410Schristos /* One of the basic colors that can be handled by ANSI 267f2ac410Schristos terminals. */ 277f2ac410Schristos enum basic_color 287f2ac410Schristos { 297f2ac410Schristos NONE = -1, 307f2ac410Schristos BLACK, 317f2ac410Schristos RED, 327f2ac410Schristos GREEN, 337f2ac410Schristos YELLOW, 347f2ac410Schristos BLUE, 357f2ac410Schristos MAGENTA, 367f2ac410Schristos CYAN, 377f2ac410Schristos WHITE 387f2ac410Schristos }; 397f2ac410Schristos 407f2ac410Schristos /* Representation of a terminal color. */ 417f2ac410Schristos class color 427f2ac410Schristos { 437f2ac410Schristos public: 447f2ac410Schristos 457f2ac410Schristos color (basic_color c) 467f2ac410Schristos : m_simple (true), 477f2ac410Schristos m_value (c) 487f2ac410Schristos { 497f2ac410Schristos } 507f2ac410Schristos 517f2ac410Schristos color (int c) 527f2ac410Schristos : m_simple (true), 537f2ac410Schristos m_value (c) 547f2ac410Schristos { 557f2ac410Schristos gdb_assert (c >= -1 && c <= 255); 567f2ac410Schristos } 577f2ac410Schristos 587f2ac410Schristos color (uint8_t r, uint8_t g, uint8_t b) 597f2ac410Schristos : m_simple (false), 607f2ac410Schristos m_red (r), 617f2ac410Schristos m_green (g), 627f2ac410Schristos m_blue (b) 637f2ac410Schristos { 647f2ac410Schristos } 657f2ac410Schristos 667f2ac410Schristos bool operator== (const color &other) const 677f2ac410Schristos { 687f2ac410Schristos if (m_simple != other.m_simple) 697f2ac410Schristos return false; 707f2ac410Schristos if (m_simple) 717f2ac410Schristos return m_value == other.m_value; 727f2ac410Schristos return (m_red == other.m_red && m_green == other.m_green 737f2ac410Schristos && m_blue == other.m_blue); 747f2ac410Schristos } 757f2ac410Schristos 767f2ac410Schristos bool operator< (const color &other) const 777f2ac410Schristos { 787f2ac410Schristos if (m_simple != other.m_simple) 797f2ac410Schristos return m_simple < other.m_simple; 807f2ac410Schristos if (m_simple) 817f2ac410Schristos return m_value < other.m_value; 827f2ac410Schristos if (m_red < other.m_red) 837f2ac410Schristos return true; 847f2ac410Schristos if (m_red == other.m_red) 857f2ac410Schristos { 867f2ac410Schristos if (m_green < other.m_green) 877f2ac410Schristos return true; 887f2ac410Schristos if (m_green == other.m_green) 897f2ac410Schristos return m_blue < other.m_blue; 907f2ac410Schristos } 917f2ac410Schristos return false; 927f2ac410Schristos } 937f2ac410Schristos 947f2ac410Schristos /* Return true if this is the "NONE" color, false otherwise. */ 957f2ac410Schristos bool is_none () const 967f2ac410Schristos { 977f2ac410Schristos return m_simple && m_value == NONE; 987f2ac410Schristos } 997f2ac410Schristos 1007f2ac410Schristos /* Return true if this is one of the basic colors, false 1017f2ac410Schristos otherwise. */ 1027f2ac410Schristos bool is_basic () const 1037f2ac410Schristos { 1047f2ac410Schristos return m_simple && m_value >= BLACK && m_value <= WHITE; 1057f2ac410Schristos } 1067f2ac410Schristos 1077f2ac410Schristos /* Return the value of a basic color. */ 1087f2ac410Schristos int get_value () const 1097f2ac410Schristos { 1107f2ac410Schristos gdb_assert (is_basic ()); 1117f2ac410Schristos return m_value; 1127f2ac410Schristos } 1137f2ac410Schristos 1147f2ac410Schristos /* Fill in RGB with the red/green/blue values for this color. 1157f2ac410Schristos This may not be called for basic colors or for the "NONE" 1167f2ac410Schristos color. */ 1177f2ac410Schristos void get_rgb (uint8_t *rgb) const; 1187f2ac410Schristos 1197f2ac410Schristos /* Append the ANSI terminal escape sequence for this color to STR. 1207f2ac410Schristos IS_FG indicates whether this is a foreground or background 1217f2ac410Schristos color. Returns true if any characters were written; returns 1227f2ac410Schristos false otherwise (which can only happen for the "NONE" 1237f2ac410Schristos color). */ 1247f2ac410Schristos bool append_ansi (bool is_fg, std::string *str) const; 1257f2ac410Schristos 1267f2ac410Schristos private: 1277f2ac410Schristos 1287f2ac410Schristos bool m_simple; 1297d62b00eSchristos union 1307d62b00eSchristos { 1317f2ac410Schristos int m_value; 1327d62b00eSchristos struct 1337d62b00eSchristos { 1347f2ac410Schristos uint8_t m_red, m_green, m_blue; 1357f2ac410Schristos }; 1367d62b00eSchristos }; 1377d62b00eSchristos }; 1387f2ac410Schristos 1397f2ac410Schristos /* Intensity settings that are available. */ 1407f2ac410Schristos enum intensity 1417f2ac410Schristos { 1427f2ac410Schristos NORMAL = 0, 1437f2ac410Schristos BOLD, 1447f2ac410Schristos DIM 1457f2ac410Schristos }; 1467f2ac410Schristos 1477f2ac410Schristos ui_file_style () = default; 1487f2ac410Schristos 1497f2ac410Schristos ui_file_style (color f, color b, intensity i = NORMAL) 1507f2ac410Schristos : m_foreground (f), 1517f2ac410Schristos m_background (b), 1527f2ac410Schristos m_intensity (i) 1537f2ac410Schristos { 1547f2ac410Schristos } 1557f2ac410Schristos 1567f2ac410Schristos bool operator== (const ui_file_style &other) const 1577f2ac410Schristos { 1587f2ac410Schristos return (m_foreground == other.m_foreground 1597f2ac410Schristos && m_background == other.m_background 1607f2ac410Schristos && m_intensity == other.m_intensity 1617f2ac410Schristos && m_reverse == other.m_reverse); 1627f2ac410Schristos } 1637f2ac410Schristos 1647f2ac410Schristos bool operator!= (const ui_file_style &other) const 1657f2ac410Schristos { 1667f2ac410Schristos return !(*this == other); 1677f2ac410Schristos } 1687f2ac410Schristos 1697f2ac410Schristos /* Return the ANSI escape sequence for this style. */ 1707f2ac410Schristos std::string to_ansi () const; 1717f2ac410Schristos 1727f2ac410Schristos /* Return true if this style is the default style; false 1737f2ac410Schristos otherwise. */ 1747f2ac410Schristos bool is_default () const 1757f2ac410Schristos { 1767f2ac410Schristos return (m_foreground == NONE 1777f2ac410Schristos && m_background == NONE 1787f2ac410Schristos && m_intensity == NORMAL 1797f2ac410Schristos && !m_reverse); 1807f2ac410Schristos } 1817f2ac410Schristos 1827f2ac410Schristos /* Return true if this style specified reverse display; false 1837f2ac410Schristos otherwise. */ 1847f2ac410Schristos bool is_reverse () const 1857f2ac410Schristos { 1867f2ac410Schristos return m_reverse; 1877f2ac410Schristos } 1887f2ac410Schristos 1897f2ac410Schristos /* Set/clear the reverse display flag. */ 1907f2ac410Schristos void set_reverse (bool reverse) 1917f2ac410Schristos { 1927f2ac410Schristos m_reverse = reverse; 1937f2ac410Schristos } 1947f2ac410Schristos 1957f2ac410Schristos /* Return the foreground color of this style. */ 1967f2ac410Schristos const color &get_foreground () const 1977f2ac410Schristos { 1987f2ac410Schristos return m_foreground; 1997f2ac410Schristos } 2007f2ac410Schristos 2017f2ac410Schristos /* Set the foreground color of this style. */ 2027f2ac410Schristos void set_fg (color c) 2037f2ac410Schristos { 2047f2ac410Schristos m_foreground = c; 2057f2ac410Schristos } 2067f2ac410Schristos 2077f2ac410Schristos /* Return the background color of this style. */ 2087f2ac410Schristos const color &get_background () const 2097f2ac410Schristos { 2107f2ac410Schristos return m_background; 2117f2ac410Schristos } 2127f2ac410Schristos 2137f2ac410Schristos /* Set the background color of this style. */ 2147f2ac410Schristos void set_bg (color c) 2157f2ac410Schristos { 2167f2ac410Schristos m_background = c; 2177f2ac410Schristos } 2187f2ac410Schristos 2197f2ac410Schristos /* Return the intensity of this style. */ 2207f2ac410Schristos intensity get_intensity () const 2217f2ac410Schristos { 2227f2ac410Schristos return m_intensity; 2237f2ac410Schristos } 2247f2ac410Schristos 2257f2ac410Schristos /* Parse an ANSI escape sequence in BUF, modifying this style. BUF 2267f2ac410Schristos must begin with an ESC character. Return true if an escape 2277f2ac410Schristos sequence was successfully parsed; false otherwise. In either 2287f2ac410Schristos case, N_READ is updated to reflect the number of chars read from 2297f2ac410Schristos BUF. */ 2307f2ac410Schristos bool parse (const char *buf, size_t *n_read); 2317f2ac410Schristos 2327d62b00eSchristos /* We need this because we can't pass a reference via va_args. */ 2337d62b00eSchristos const ui_file_style *ptr () const 2347d62b00eSchristos { 2357d62b00eSchristos return this; 2367d62b00eSchristos } 2377d62b00eSchristos 2387f2ac410Schristos private: 2397f2ac410Schristos 2407f2ac410Schristos color m_foreground = NONE; 2417f2ac410Schristos color m_background = NONE; 2427f2ac410Schristos intensity m_intensity = NORMAL; 2437f2ac410Schristos bool m_reverse = false; 2447f2ac410Schristos }; 2457f2ac410Schristos 2467f2ac410Schristos /* Skip an ANSI escape sequence in BUF. BUF must begin with an ESC 2477f2ac410Schristos character. Return true if an escape sequence was successfully 2487d62b00eSchristos skipped; false otherwise. If an escape sequence was skipped, 2497d62b00eSchristos N_READ is updated to reflect the number of chars read from BUF. */ 2507f2ac410Schristos 2517f2ac410Schristos extern bool skip_ansi_escape (const char *buf, int *n_read); 2527f2ac410Schristos 2537f2ac410Schristos #endif /* UI_STYLE_H */ 254