chiark / gitweb /
@@@ tty cleanup
[mLib] / ui / ttycolour.h
1 /* -*-c-*-
2  *
3  * Configurable terminal colour support
4  *
5  * (c) 2024 Straylight/Edgeware
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
9  *
10  * This file is part of the mLib utilities library.
11  *
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.
16  *
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.
21  *
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,
25  * USA.
26  */
27
28 #ifndef MLIB_TTYCOLOUR_H
29 #define MLIB_TTYCOLOUR_H
30
31 #ifdef __cplusplus
32   extern "C" {
33 #endif
34
35 /*----- Header files ------------------------------------------------------*/
36
37 #ifndef MLIB_GPRINTF_H
38 #  include "gprintf.h"
39 #endif
40
41 #ifndef MLIB_MACROS_H
42 #  include "macros.h"
43 #endif
44
45 #ifndef MLIB_TTY_H
46 #  include "tty.h"
47 #endif
48
49 /*----- Functions provided ------------------------------------------------*/
50
51 struct ttycolour_style {
52   /* Table of style tokens and their defaults.  The table is terminated with
53    * a null @tok@ pointer.
54    */
55
56   const char *tok;                      /* style token name */
57   const struct tty_attrlist *dflt;      /* default attribute value */
58 };
59
60 /* Machinery for building the constants and tables.
61  *
62  * The caller should define the styles it supports in a macro taking two
63  * arguments, conventionally named @_st@ and @_@.  It should apply the second
64  * argument, @_@, to quadruples @(_st, tag, tok, dflt)@, where @_st@ is the
65  * argument provided, @tag@ is a constant-name suffix, @tok@ is a string
66  * naming the capability token to be read from the user string, and @dflt@ is
67  * the default attribute for the style.
68  */
69
70 /* --- @TTYCOLOUR_DEFENUM@ --- *
71  *
72  * Arguments:   @styles@ = style-list macro, as described above
73  *              @pre@ = prefix for constant names
74  *
75  * Use:         Define constants @pretag@ for each @tag@ listed in the list
76  *              macro @styles@, having sequential values starting from zero,
77  *              in the same order as the list macro.
78  */
79
80 #define TTYCOLOUR__ENUMPREFIX(pre) pre
81 #define TTYCOLOUR__FULLENUM(_st, tag) GLUE(TTYCOLOUR__ENUMPREFIX _st, tag)
82
83 #define TTYCOLOUR__DEFENUM(_st, tag, tok, dflt)                         \
84   TTYCOLOUR__FULLENUM(_st, tag),
85 #define TTYCOLOUR_DEFENUM(styles, pre) enum {                           \
86   styles((pre), TTYCOLOUR__DEFENUM)                                     \
87   pre##_LIMIT                                                           \
88 }
89
90 /* --- @TTYCOLOUR_INITTAB@ --- *
91  *
92  * Arguments:   @styles@ = style-list macro, as described above
93  *
94  * Use:         Expand to an initializer for a table of
95  *              @struct ttycolour_style@ values.  The table entries
96  *              correspond one-for-one with the entries in the list macro, in
97  *              the same order.
98  */
99
100 #define TTYCOLOUR__DEFENTRY(_st, tag, tok, dflt) { tok, dflt },
101 #define TTYCOLOUR_INITTAB(styles) {                                     \
102   styles((pre), TTYCOLOUR__DEFENTRY)                                    \
103   { 0, 0 }                                                              \
104 }
105
106 /* --- @ttycolour_enablep@ --- *
107  *
108  * Arguments:   @unsigned f@ = flags
109  *
110  * Returns:     Nonzero if colours should be applied to output, otherwise
111  *              zero.
112  *
113  * Use:         This function determines whether it's generally a good idea
114  *              to produce output in pretty colours.  Set @TCEF_TTY@ if the
115  *              output stream is -- or should be considered to be --
116  *              interactive (e.g., according to @isatty@); set @TCEF_DFLT@ if
117  *              the application prefers to produce coloured output if
118  *              possible.
119  *
120  *              The detailed behaviour is as follows.  (Since the purpose of
121  *              this function is to abide by common conventions and to be
122  *              convenient for users, these details may change in future.)
123  *
124  *                * If the %|NO_COLOR|% environment variable is non-empty,
125  *                  colour is disabled (%%\url{https://no-color.org/}%%).
126  *
127  *                * If the %|TERM|% variable is set to %|dumb|%, then colour
128  *                  is disabled (Emacs).
129  *
130  *                * If the %|FORCE_COLOR|% environment variable is non-empty,
131  *                  then colour is enabled, unless the value is 0, in which
132  *                  case colour is disabled (apparently from the Node
133  *                  community, %%\url{%%https://force-color.org/}%% and
134  *                  %%\url{https://nodejs.org/api/tty.html#writestreamgetcolordepthenv}%%).
135  *
136  *                * If the %|CLICOLOR_FORCE|% environment variable is
137  *                  non-empty, then colour is enabled (apparently from
138  *                  Mac OS, (%%\url{http://bixense.com/clicolors/}%%).
139  *
140  *                * If the @TCEF_TTY@ flag is clear, then colour is disabled.
141  *
142  *                * If the @TCEF_DFLT@ flag is set, then colour is enabled.
143  *
144  *                * If the %|CLICOLOR|% environment variable is non-empty,
145  *                  then colour is enabled (again, apparently from Mac OS,
146  *                  (%%\url{http://bixense.com/clicolors/}%%).
147  *
148  *                * Otherwise, colour is disabled.
149  */
150
151 #define TCEF_TTY 1u                     /*   output is interactive */
152 #define TCEF_DFLT 2u                    /*   turn on by default */
153 extern int ttycolour_enablep(unsigned /*f*/);
154
155 /* --- @ttycolour_config@ --- *
156  *
157  * Arguments:   @ttycolour_attr *attr@ = pointer to attribute table
158  *              @const char *user@ = the user-specified string or environment
159  *                      variable name
160  *              @unsigned f@ = flags (@TCIF_...@)
161  *              @const struct ttycolour_style *tab@ = table initialized using
162  *                      @TTYCOLOUR_INITTAB@
163  *
164  * Returns:     Zero on success, %$-1$% on error.
165  *
166  * Use:         Initialize the table @attr@ with the attributes configured
167  *              for the styles defined in the table.
168  *
169  *              A user string is determined.  If @f@ has @TCIF_GETENV@ set,
170  *              then the user string is the value of the environment variable
171  *              named by @user@; otherwise, the user string is @user@ itself.
172  *              The user string consists of a sequence of capability
173  *              defintiions separated by colons.  Each definition has the
174  *              form %%\syntax{<tok>"="<codes>}%%,                      
175  */
176
177 #define TCIF_GETENV 1u
178 #define TCIF_REPORT 2u
179 extern int ttycolour_config(struct tty_attr */*attr*/,
180                             const char */*user*/, unsigned /*f*/,
181                             struct tty */*tty*/,
182                             const struct ttycolour_style */*tab*/);
183
184 /*----- That's all, folks -------------------------------------------------*/
185
186 #ifdef __cplusplus
187   }
188 #endif
189
190 #endif