chiark / gitweb /
e026c15a18de847d565e4512ba1ff4c85dd5d0d9
[mLib] / ui / tty.h
1 /* -*-c-*-
2  *
3  * Terminal handling
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_TTY_H
29 #define MLIB_TTY_H
30
31 #ifdef __cplusplus
32   extern "C" {
33 #endif
34
35 /*----- Header files ------------------------------------------------------*/
36
37 #include <stdio.h>
38
39 #ifndef MLIB_BITS_H
40 #  include "bits.h"
41 #endif
42
43 #ifndef MLIB_GPRINTF_H
44 #  include "gprintf.h"
45 #endif
46
47 /*----- Attribute flags ---------------------------------------------------*/
48
49 /* Line style attributes. */
50 #define TTAF_LNMASK     0x0003u         /* line style mask */
51 #define TTAF_LNSHIFT    0               /* line style shift */
52 enum {
53   TTLN_NONE,                            /*   no line */
54   TTLN_ULINE,                           /*   underline */
55   TTLN_UULINE,                          /*   double underline */
56   TTLN_LIMIT
57 };
58
59 /* Weight attributes. */
60 #define TTAF_WTMASK     0x000cu         /* weight mask */
61 #define TTAF_WTSHIFT    2               /* weight shift */
62 enum {
63   TTWT_MED,                             /*   medium */
64   TTWT_BOLD,                            /*   bold/bright */
65   TTWT_DIM,                             /*   light/dim */
66   TTWT_LIMIT
67 };
68
69 /* Miscellaneous attributes. */
70 #define TTAF_INVV       0x0010u         /* inverse video */
71 #define TTAF_STRIKE     0x0020u         /* strike out */
72 #define TTAF_ITAL       0x0040u         /* italic/oblique */
73
74 /* Colour space attributes. */
75 #define TTAF_FGSPCMASK  0x1c00u         /* foreground space mask */
76 #define TTAF_FGSPCSHIFT 10              /* foreground space shift */
77 #define TTAF_BGSPCMASK  0xe000u         /* background space mask */
78 #define TTAF_BGSPCSHIFT 13              /* background space shift */
79 enum {
80   TTCSPC_NONE,                          /* no colour */
81   TTCSPC_1BPC,                          /* one bit per channel */
82   TTCSPC_1BPCBR,                        /* one bit per channel, brighter */
83   TTCSPC_4LPC,                          /* four levels per channel */
84   TTCSPC_8LGS,                          /* eight levels greyscale */
85   TTCSPC_6LPC,                          /* six levels per channel */
86   TTCSPC_24LGS,                         /* 24 levels greyscale */
87   TTCSPC_8BPC,                          /* eight bits per channel */
88   TTCSPC_LIMIT
89 };
90
91 /*----- Specifying colours ------------------------------------------------*/
92
93 /* One-bit-per-channel colours. */
94 #define TT1BPC_RED      1u
95 #define TT1BPC_GRN      2u
96 #define TT1BPC_BLU      4u
97 #define TT1BPC_BRI      8u
98 #define TTCOL_BLK       0u
99 #define TTCOL_RED       (TT1BPC_RED)
100 #define TTCOL_GRN       (TT1BPC_GRN)
101 #define TTCOL_YLW       (TT1BPC_RED | TT1BPC_GRN)
102 #define TTCOL_BLU       (TT1BPC_BLU)
103 #define TTCOL_MGN       (TT1BPC_RED | TT1BPC_BLU)
104 #define TTCOL_CYN       (TT1BPC_GRN | TT1BPC_BLU)
105 #define TTCOL_WHT       (TT1BPC_RED | TT1BPC_GRN | TT1BPC_BLU)
106 #define TTCOL_BRBLK     (TTCOL_BLK | TT1BPC_BRI)
107 #define TTCOL_BRRED     (TTCOL_RED | TT1BPC_BRI)
108 #define TTCOL_BRGRN     (TTCOL_GRN | TT1BPC_BRI)
109 #define TTCOL_BRYLW     (TTCOL_YLW | TT1BPC_BRI)
110 #define TTCOL_BRBLU     (TTCOL_BLU | TT1BPC_BRI)
111 #define TTCOL_BRMGN     (TTCOL_MGN | TT1BPC_BRI)
112 #define TTCOL_BRCYN     (TTCOL_CYN | TT1BPC_BRI)
113 #define TTCOL_BRWHT     (TTCOL_WHT | TT1BPC_BRI)
114
115 /* Two-bits-per-channel colours. */
116 #define TTCOL_MK2B(r, g, b) (((r) << 4) | ((g) <<  2) | ((b) <<  0))
117 #define TTCOL_2BR(col) (((col) >> 4)&0x03)
118 #define TTCOL_2BG(col) (((col) >> 2)&0x03)
119 #define TTCOL_2BB(col) (((col) >> 0)&0x03)
120
121 /* Six-levels-per-channel colours. */
122 #define TTCOL_MK6L(r, g, b) (36*(r) + 6*(g) + (b))
123 #define TTCOL_6LR(col) ((col)/36)
124 #define TTCOL_6LG(col) (((col)/6)%6)
125 #define TTCOL_6LB(col) ((col)%6)
126
127 /* Eight-bits-per-channel colours. */
128 #define TTCOL_MK8B(r, g, b)                                             \
129   (((uint32)(r) << 16) | ((g) <<  8) | ((b) <<  0))
130 #define TTCOL_8BR(col) (((col) >> 16)&0xff)
131 #define TTCOL_8BG(col) (((col) >>  8)&0xff)
132 #define TTCOL_8BB(col) (((col) >>  0)&0xff)
133
134 /*----- Terminal capabilities ---------------------------------------------*/
135
136 /* Attribute capabilities. */
137 #define TTACF_ULINE     0x00000001u     /* underline */
138 #define TTACF_UULINE    0x00000002u     /* double underline */
139 #define TTACF_BOLD      0x00000004u     /* bold/bright */
140 #define TTACF_DIM       0x00000008u     /* light/dim */
141 #define TTACF_INVV      0x00000010u     /* inverse video */
142 #define TTACF_STRIKE    0x00000020u     /* strikeout */
143 #define TTACF_ITAL      0x00000040u     /* italic/oblique */
144 #define TTACF_FG        0x00000080u     /* set foreground colour */
145 #define TTACF_BG        0x00000100u     /* set background colour */
146 #define TTACF_1BPC      0x00100000u     /* one-bit-per-channel space */
147 #define TTACF_1BPCBR    0x00200000u    /* one-bit-per-channel bright space */
148 #define TTACF_4LPC      0x00400000u     /* four-levels-per-channel space */
149 #define TTACF_8LGS      0x00800000u     /* 8-levels-greyscale space */
150 #define TTACF_6LPC      0x01000000u     /* six-levels-per-channel space */
151 #define TTACF_24LGS     0x02000000u     /* 24-levels-greyscale space */
152 #define TTACF_8BPC      0x04000000u     /* eight-bits-per-channel space */
153 #define TTACF_CSPCMASK  0xfff00000u
154
155 /* Mode settings. */
156 #define TTMF_AUTOM      0x00000001u     /* automatic margins */
157 #define TTMF_FSCRN      0x00000002u     /* full-screen mode */
158 #define TTMF_CVIS       0x00000004u     /* visible cursor */
159 #define TTMF_INS        0x00000008u     /* insert mode */
160 #define TTMF_DEL        0x00000010u     /* delete mode */
161
162 /* Other capabilities. */
163 #define TTCF_RELMV      0x00000100u     /* relative cursor motion */
164 #define TTCF_ABSMV      0x00000200u     /* absolute cursor motion */
165 #define TTCF_MIXMV      0x00000400u     /* mixed cursor motion */
166 #define TTCF_MMARG      0x00000800u     /* proper magic margins */
167 #define TTCF_BGER       0x00001000u     /* erasure uses background colour */
168 #define TTCF_ERCH       0x00002000u     /* erase characters */
169 #define TTCF_ERBOL      0x00004000u     /* erase from beginning of line */
170 #define TTCF_EREOL      0x00008000u     /* erase to end of line */
171 #define TTCF_ERBOD      0x00010000u     /* erase from beginning of display */
172 #define TTCF_EREOD      0x00020000u     /* erase to end of display */
173 #define TTCF_ERDSP      0x00040000u     /* erase display */
174 #define TTCF_INSCH      0x00080000u     /* insert character */
175 #define TTCF_INSLN      0x00100000u     /* insert line */
176 #define TTCF_DELCH      0x00200000u     /* delete character */
177 #define TTCF_DELLN      0x00400000u     /* delete line */
178
179 /*----- Other constants ---------------------------------------------------*/
180
181 /* Motion origin. */
182 #define TTOF_XHOME 0u                   /* absolute horizontal motion */
183 #define TTOF_XCUR 1u                    /* relative horizontal motion */
184 #define TTOF_YHOME 0u                   /* absolute vertical motion */
185 #define TTOF_YCUR 2u                    /* relative vertical motion */
186 #define TTORG_HOME (TTOF_XHOME | TTOF_YHOME)
187 #define TTORG_CUR (TTOF_XCUR | TTOF_YCUR)
188
189 /* Erasure scope. */
190 #define TTEF_LINE 0u                    /* erase within line */
191 #define TTEF_DSP 1u                     /* erase whole display */
192 #define TTEF_BEGIN 2u                   /* erase from beginning */
193 #define TTEF_END 4u                     /* erase to end */
194
195 /* Insertion and deletion. */
196 #define TTIDF_CH 0u                     /* insert/delete characters */
197 #define TTIDF_LN 1u                     /* insert/delete lines */
198
199 /* Backend implementations. */
200 enum {
201   TTBK_END,                             /* list end marker */
202   TTBK_TERMCAP,                         /* traditional `termcap' */
203   TTBK_TERMINFO,                        /* standard `terminfo' */
204   TTBK_UNIBI,                           /* modern `Unibilium' */
205   TTBK_ANSI,                         /* assume modern terminal conventions */
206   TTBK_LIMIT
207 };
208
209 /*----- Data structures ---------------------------------------------------*/
210
211 /* An attribute setting. */
212 struct tty_attr {
213   uint32 f, _res0;                      /* attribute flags, reserved */
214   uint32 fg, bg;                        /* foreground/background colours */
215 };
216 #define TTY_ATTR_INIT { 0, 0, 0, 0 }
217
218 /* A menu of attribute requests. */
219 struct tty_attrlist {
220   uint32 cap_mask, cap_eq;              /* capabilities to select */
221   struct tty_attr attr;                 /* attributes to set */
222 };
223 #define TTY_ATTRLIST_CLEAR { 0, 0, TTY_ATTR_INIT }
224 #define TTY_ATTRLIST_END { 0, 1, TTY_ATTR_INIT }
225
226 /* A terminal logical state. */
227 struct tty_state {
228   uint32 modes;
229   struct tty_attr attr;
230 };
231
232 /* Terminal control state. */
233 struct tty {
234   const struct tty_ops *ops;
235   FILE *fpin, *fpout;
236   unsigned baud, ht, wd, f;
237 #define TTF_BORROW 1u
238   uint32 acaps, ocaps;
239   struct tty_state st;
240 };
241
242 struct tty_ops {
243   void (*release)(struct tty */*tty*/);
244   int (*setattr)(struct tty */*tty*/,
245                  const struct gprintf_ops */*gops*/, void */*go*/,
246                  const struct tty_attr */*a*/);
247   int (*setmodes)(struct tty */*tty*/,
248                   const struct gprintf_ops */*gops*/, void */*go*/,
249                   uint32 /*modes_bic*/, uint32 /*modes_xor*/);
250   int (*move)(struct tty */*tty*/,
251               const struct gprintf_ops */*gops*/, void */*go*/,
252               unsigned /*orig*/, int /*y*/, int /*x*/);
253   int (*repeat)(struct tty */*tty*/,
254                 const struct gprintf_ops */*gops*/, void */*go*/,
255                 int /*ch*/, unsigned /*n*/);
256   int (*erase)(struct tty */*tty*/,
257                const struct gprintf_ops */*gops*/, void */*go*/,
258                unsigned /*f*/);
259   int (*erch)(struct tty */*tty*/,
260               const struct gprintf_ops */*gops*/, void */*go*/,
261               unsigned /*n*/);
262   int (*ins)(struct tty */*tty*/,
263              const struct gprintf_ops */*gops*/, void */*go*/,
264              unsigned /*f*/, unsigned /*n*/);
265   int (*inch)(struct tty */*tty*/,
266               const struct gprintf_ops */*gops*/, void */*go*/,
267               int /*ch*/);
268   int (*del)(struct tty */*tty*/,
269              const struct gprintf_ops */*gops*/, void */*go*/,
270              unsigned /*f*/, unsigned /*n*/);
271   int (*_res0)(void), (*_res1)(void), (*_res2)(void), (*_res3)(void);
272 };
273
274 /*----- Functions provided ------------------------------------------------*/
275
276 /* --- @tty_clampattr@ --- *
277  *
278  * Arguments:   @struct tty_attr *a_out@ = selected attributes
279  *              @const struct tty_attr *a@ = requested attributes
280  *              @uint32 acaps@ = terminal's attribute capability mask
281  *
282  * Returns:     ---
283  *
284  * Use:         Select the closest approximation to the requested attributes
285  *              which can be accommodated by the terminal.
286  */
287
288 extern void tty_clampattr(struct tty_attr */*a_out*/,
289                           const struct tty_attr */*a*/, uint32 /*acaps*/);
290
291
292
293 extern int tty_resized(struct tty */*tty*/);
294
295 #define TTF_OPEN 256u
296 extern struct tty *tty_open(FILE */*fp*/, unsigned /*f*/,
297                             const unsigned */*backends*/);
298
299 extern void tty_close(struct tty */*tty*/);
300
301 extern int tty_setattrg(struct tty */*tty*/,
302                         const struct gprintf_ops */*gops*/, void */*go*/,
303                         const struct tty_attr */*a*/);
304
305 extern int tty_setattr(struct tty */*tty*/, const struct tty_attr */*a*/);
306
307 extern int tty_setattrlistg(struct tty */*tty*/,
308                             const struct gprintf_ops */*gops*/, void */*go*/,
309                             const struct tty_attrlist */*aa*/);
310
311 extern int tty_setattrlist(struct tty */*tty*/,
312                            const struct tty_attrlist */*aa*/);
313
314 extern int tty_setmodesg(struct tty */*tty*/,
315                          const struct gprintf_ops */*gops*/, void */*go*/,
316                          uint32 /*modes_bic*/, uint32 /*modes_xor*/);
317
318 extern int tty_setmodes(struct tty */*tty*/,
319                         uint32 /*modes_bic*/, uint32 /*modes_xor*/);
320
321 extern int tty_moveg(struct tty */*tty*/,
322                      const struct gprintf_ops */*gops*/, void */*go*/,
323                      unsigned /*orig*/, int /*y*/, int /*x*/);
324
325 extern int tty_move(struct tty */*tty*/,
326                     unsigned /*orig*/, int /*y*/, int /*x*/);
327
328 extern int tty_repeatg(struct tty */*tty*/,
329                        const struct gprintf_ops */*gops*/, void */*go*/,
330                        int /*ch*/, unsigned /*n*/);
331
332 extern int tty_repeat(struct tty */*tty*/, int /*ch*/, unsigned /*n*/);
333
334 extern int tty_eraseg(struct tty */*tty*/,
335                       const struct gprintf_ops */*gops*/, void */*go*/,
336                       unsigned /*f*/);
337
338 extern int tty_erase(struct tty */*tty*/, unsigned /*f*/);
339
340 extern int tty_erchg(struct tty */*tty*/,
341                      const struct gprintf_ops */*gops*/, void */*go*/,
342                      unsigned /*n*/);
343
344 extern int tty_erch(struct tty */*tty*/, unsigned /*n*/);
345
346 extern int tty_insg(struct tty */*tty*/,
347                     const struct gprintf_ops */*gops*/, void */*go*/,
348                     unsigned /*f*/, unsigned /*n*/);
349
350 extern int tty_ins(struct tty */*tty*/, unsigned /*f*/, unsigned /*n*/);
351
352 extern int tty_inchg(struct tty */*tty*/,
353                      const struct gprintf_ops */*gops*/, void */*go*/,
354                      int /*ch*/);
355
356 extern int tty_inch(struct tty */*tty*/, int /*ch*/);
357
358 extern int tty_delg(struct tty */*tty*/,
359                     const struct gprintf_ops */*gops*/, void */*go*/,
360                     unsigned /*f*/, unsigned /*n*/);
361
362 extern int tty_del(struct tty */*tty*/, unsigned /*f*/, unsigned /*n*/);
363
364 /*----- That's all, folks -------------------------------------------------*/
365
366 #ifdef __cplusplus
367   }
368 #endif
369
370 #endif