3 * Configurable terminal colour support
5 * (c) 2024 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of the mLib utilities library.
12 * mLib is free software: you can redistribute it and/or modify it under
13 * the terms of the GNU Library General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or (at
15 * your option) any later version.
17 * mLib is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
20 * License for more details.
22 * You should have received a copy of the GNU Library General Public
23 * License along with mLib. If not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
28 #ifndef MLIB_TTYCOLOUR_H
29 #define MLIB_TTYCOLOUR_H
35 /*----- Header files ------------------------------------------------------*/
37 #ifndef MLIB_GPRINTF_H
45 /*----- Functions provided ------------------------------------------------*/
47 /* Attributes for colour output.
49 * An attribute word holds a foreground colour in the low nibble, a
50 * background colour in the next nibble, and some flags in the next few bits.
51 * A colour is expressed in classic 1-bit-per-channel style, with red, green,
52 * and blue in bits 0, 1, and 2, and a `bright' flag in bit 3.
54 typedef unsigned short ttycolour_attr; /* type of an attribute */
56 #define TCAF_FGMASK 0x0f /* foreground colour mask */
57 #define TCAF_FGSHIFT 0 /* foreground colour shift */
58 #define TCAF_BGMASK 0xf0 /* background colour mask */
59 #define TCAF_BGSHIFT 4 /* background colour shift */
60 #define TCAF_FG 256u /* set foreground? */
61 #define TCAF_BG 512u /* set background? */
62 #define TCAF_BOLD 1024u /* set bold? */
64 #define TCCF_RED 1u /* red channel */
65 #define TCCF_GREEN 2u /* green channel */
66 #define TCCF_BLUE 4u /* blue channel */
67 #define TCCF_RGBMASK (TCCF_RED | TCCF_GREEN | TCCF_BLUE)
68 #define TCCF_BRIGHT 8u /* bright colour flag */
70 #define TTYCOL_BLACK 0u /* colour codes... */
71 #define TTYCOL_RED (TCCF_RED)
72 #define TTYCOL_GREEN (TCCF_GREEN)
73 #define TTYCOL_YELLOW (TCCF_RED | TCCF_GREEN)
74 #define TTYCOL_BLUE (TCCF_BLUE)
75 #define TTYCOL_MAGENTA (TCCF_RED | TCCF_BLUE)
76 #define TTYCOL_CYAN (TCCF_GREEN | TCCF_BLUE)
77 #define TTYCOL_WHITE (TCCF_RED | TCCF_GREEN | TCCF_BLUE)
79 #define TTYCOL_BRBLACK (TTYCOL_BLACK | TCCF_BRIGHT)
80 #define TTYCOL_BRRED (TTYCOL_RED | TCCF_BRIGHT)
81 #define TTYCOL_BRGREEN (TTYCOL_GREEN | TCCF_BRIGHT)
82 #define TTYCOL_BRYELLOW (TTYCOL_YELLOW | TCCF_BRIGHT)
83 #define TTYCOL_BRBLUE (TTYCOL_BLUE | TCCF_BRIGHT)
84 #define TTYCOL_BRMAGENTA (TTYCOL_MAGENTA | TCCF_BRIGHT)
85 #define TTYCOL_BRCYAN (TTYCOL_CYAN | TCCF_BRIGHT)
86 #define TTYCOL_BRWHITE (TTYCOL_WHITE | TCCF_BRIGHT)
88 #define TC_FG(col) (TCAF_FG | (TTYCOL_##col) << TCAF_FGSHIFT) /* set fg */
89 #define TC_BG(col) (TCAF_BG | (TTYCOL_##col) << TCAF_BGSHIFT) /* set bg */
91 struct ttycolour_style {
92 /* Table of style tokens and their defaults. The table is terminated with
93 * a null @tok@ pointer.
96 const char *tok; /* style token name */
97 ttycolour_attr dflt; /* default attribute value */
100 struct ttycolour_state {
101 /* State maintained by @ttycolour_setattr@. */
103 ttycolour_attr attr; /* current attribute value */
105 #define TTYCOLOUR_STATE_INIT { 0 } /* initializer for state */
107 /* Machinery for building the constants and tables.
109 * The caller should define the styles it supports in a macro taking two
110 * arguments, conventionally named @_st@ and @_@. It should apply the second
111 * argument, @_@, to quadruples @(_st, tag, tok, dflt)@, where @_st@ is the
112 * argument provided, @tag@ is a constant-name suffix, @tok@ is a string
113 * naming the capability token to be read from the user string, and @dflt@ is
114 * the default attribute for the style.
117 /* --- @TTYCOLOUR_DEFENUM@ --- *
119 * Arguments: @styles@ = style-list macro, as described above
120 * @pre@ = prefix for constant names
122 * Use: Define constants @pretag@ for each @tag@ listed in the list
123 * macro @styles@, having sequential values starting from zero,
124 * in the same order as the list macro.
127 #define TTYCOLOUR__ENUMPREFIX(pre) pre
128 #define TTYCOLOUR__FULLENUM(_st, tag) GLUE(TTYCOLOUR__ENUMPREFIX _st, tag)
130 #define TTYCOLOUR__DEFENUM(_st, tag, tok, dflt) \
131 TTYCOLOUR__FULLENUM(_st, tag),
132 #define TTYCOLOUR_DEFENUM(styles, pre) enum { \
133 styles((pre), TTYCOLOUR__DEFENUM) \
137 /* --- @TTYCOLOUR_INITTAB@ --- *
139 * Arguments: @styles@ = style-list macro, as described above
141 * Use: Expand to an initializer for a table of
142 * @struct ttycolour_style@ values. The table entries
143 * correspond one-for-one with the entries in the list macro, in
147 #define TTYCOLOUR__DEFENTRY(_st, tag, tok, dflt) { tok, dflt },
148 #define TTYCOLOUR_INITTAB(styles) { \
149 styles((pre), TTYCOLOUR__DEFENTRY) \
153 /* --- @ttycolour_config@ --- *
155 * Arguments: @ttycolour_attr *attr@ = pointer to attribute table
156 * @const char *user@ = the user-specified string or environment
158 * @unsigned f@ = flags (@TCIF_...@)
159 * @const struct ttycolour_style *tab@ = table initialized using
160 * @TTYCOLOUR_INITTAB@
162 * Returns: Zero on success, %$-1$% on error.
164 * Use: Initialize the table @attr@ with the attributes configured
165 * for the styles defined in the table.
167 * A user string is determined. If @f@ has @TCIF_GETENV@ set,
168 * then the user string is the value of the environment variable
169 * named by @user@; otherwise, the user string is @user@ itself.
170 * The user string consists of a sequence of capability
171 * defintiions separated by colons. Each definition has the
172 * form %%\syntax{<tok>"="<codes>}%%,
175 #define TCIF_GETENV 1u
176 #define TCIF_REPORT 2u
177 extern int ttycolour_config(ttycolour_attr */*attr*/,
178 const char */*user*/, unsigned /*f*/,
179 const struct ttycolour_style */*tab*/);
181 extern void ttycolour_init(struct ttycolour_state */*tc*/);
183 extern int ttycolour_setattr
184 (const struct gprintf_ops */*gops*/, void */*go*/,
185 struct ttycolour_state */*tc*/, ttycolour_attr /*attr*/);
187 /*----- That's all, folks -------------------------------------------------*/