chiark / gitweb /
@@@ tty cleanup
[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 (y-abs, x-rel) 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;            /* operations table (opaque) */
235   FILE *fpin, *fpout;                   /* input and output streams */
236   unsigned baud;                        /* (output) baud rate (bits/s) */
237   unsigned ht, wd;                      /* terminal dimensions */
238   unsigned f;                           /* flags */
239 #define TTF_BORROW 1u                   /*   don't close the streams */
240   uint32 acaps, ocaps;                 /* attribute and other capabilities */
241   struct tty_state st;                  /* current terminal state */
242 };
243
244 /*----- Lifecycle and maintenance -----------------------------------------*/
245
246 /* --- @tty_open@ --- *
247  *
248  * Arguments:   @FILE *fp@ = stream open on terminal, or null
249  *              @unsigned f@ = flags (@TTF_...@)
250  *              @const unsigned *backends@ = ordered list of backends to try
251  *
252  * Returns:     Pointer to terminal control block, or null on error.
253  *
254  * Use:         Open a terminal and return a @struct tty *@ terminal control
255  *              block pointer.
256  *
257  *              If @fp@ is provided, then it will be used for terminal
258  *              output.  If @fp@ is @stdout@, then input (not currently
259  *              supported) will come from @stdin@; otherwise, input comes
260  *              from @fp@.  If @fp@ is null and @TTF_OPEN@ is set, then
261  *              @tty_open@ will attempt to open a terminal for itself: if
262  *              @stdin@ is interactive then it used for input; if @stdout@ --
263  *              or, failing that, @stderr@ -- is interactive, then it is used
264  *              for output; otherwise %|/dev/tty|% is opened and used.  If
265  *              @fp@ is null and @TTF_OPEN@ is not set, then a usable
266  *              terminal control block is still returned, but output cannot
267  *              be sent directly to the terminal -- since there isn't one.
268  *
269  *              If @TTF_BORROW@ is set, then the stream will not be closed by
270  *              @tty_close@.  (This flag is ignored if @fp@ is null.)
271  *
272  *              If @beckends@ is provided, then it points to a vector of
273  *              @TTBK_...@ constants describing the backends to be tried in
274  *              order.  The vector is terminated by @TTBK_END@; if this is
275  *              found, then a null pointer is returned.
276  *
277  *              A null control block pointer is valid for all @tty@
278  *              functions: most will just immediately report failure, but
279  *              there won't be any crashing.
280  */
281
282 #define TTF_OPEN 256u                   /* open terminal if @fp@ is null */
283 extern struct tty *tty_open(FILE */*fp*/, unsigned /*f*/,
284                             const unsigned */*backends*/);
285
286 /* --- @tty_close@ --- *
287  *
288  * Arguments:   @struct tty *tty@ = control block pointer
289  *
290  * Returns:     ---
291  *
292  * Use:         Closes a terminal, releasing the control block and any
293  *              resources it held.  In particular, if the terminal was opened
294  *              without @TTF_BORROW@, then the output stream is closed.
295  */
296
297 extern void tty_close(struct tty */*tty*/);
298
299 /* --- @tty_resized@ --- *
300  *
301  * Arguments:   @struct tty *tty@ = control block pointer
302  *
303  * Returns:     Zero if the size hasn't changed, %$+1$% if the size has
304  *              changed, or %$-1$% on error.
305  *
306  * Use:         Update the terminal width and height.  Call this after
307  *              receiving @SIGWINCH@, or otherwise periodically, to avoid
308  *              making a mess.
309  */
310
311 extern int tty_resized(struct tty */*tty*/);
312
313 /*----- Output and control functions --------------------------------------*/
314
315 /* These functions come in pairs.  The unmarked version sends output directly
316  * to the terminal's output stream, and will obviously fail (though not
317  * crash) if this is null; the version whose names ends with @...g@ accepts
318  * an additional pair of arguments @gops@ and @go@ giving an alternative
319  * destination for output.
320  */
321
322 /* --- @tty_setattr@, @tty_setattrg@--- *
323  *
324  * Arguments:   @struct tty *tty@ = control block pointer
325  *              @const struct gprintf_ops *gops, void *go@ = output
326  *                      destination
327  *              @const struct tty_attr *a@ = pointer to attributes to set, or
328  *                      null
329  *
330  * Returns:     Zero on success, %$-1$% on error.
331  *
332  * Use:         Set the indicated formatting attributes on following output.
333  *              If @a@ is null, then clear all attributes, just as if
334  *              @a->f == 0@.
335  *
336  *              If you only ever request attributes which are advertised in
337  *              the terminals capapbility masked, then you'll always get what
338  *              you asked for.  Otherwise, the provided attributes will be
339  *              `clamped', i.e., modified so as to accommodate the terminal's
340  *              shortcomings.  In simple cases, unsupported attributes may
341  *              just be dropped; but they can also be substituted, e.g.,
342  *              single underlining for double, or approximate colours for
343  *              unsupported colours.
344  */
345
346 extern int tty_setattr(struct tty */*tty*/, const struct tty_attr */*a*/);
347 extern int tty_setattrg(struct tty */*tty*/,
348                         const struct gprintf_ops */*gops*/, void */*go*/,
349                         const struct tty_attr */*a*/);
350
351 /* --- @tty_setattrlist@, @tty_setattrlistg@ --- *
352  *
353  * Arguments:   @struct tty *tty@ = control block pointer
354  *              @const struct gprintf_ops *gops, void *go@ = output
355  *                      destination
356  *              @const struct tty_attrlist *aa@ = pointer to attribute list
357  *                      `menu'
358  *
359  * Returns:     Zero on success, %$-1$% on error.
360  *
361  * Use:         Search the list for an entry matching the terminal's
362  *              capabilities, i.e., @tty->acaps&a->cap_mask == a->cap_eq@.
363  *              The attributes in the first such entry are set, as if by
364  *              @tty_setattr@.
365  *
366  *              The list is terminated by an entry with @cap_mask == 0@ --
367  *              though it will be checked like any other before ending the
368  *              search.  In particular, this means that an entry with
369  *              @cap_mask == cap_eq == 0@ is a `catch-all', and its
370  *              attributes will be set if no earlier matching entry could be
371  *              found, while an entry with @cap_mask == 0@ and @cap_eq != 0@
372  *              terminates the search without setting any attributes.
373  */
374
375 extern int tty_setattrlist(struct tty */*tty*/,
376                            const struct tty_attrlist */*aa*/);
377 extern int tty_setattrlistg(struct tty */*tty*/,
378                             const struct gprintf_ops */*gops*/, void */*go*/,
379                             const struct tty_attrlist */*aa*/);
380
381 /* --- @tty_setmodes@, @tty_setmodesg@ --- *
382  *
383  * Arguments:   @struct tty *tty@ = control block pointer
384  *              @const struct gprintf_ops *gops, void *go@ = output
385  *                      destination
386  *              @uint32 modes_bic, modes_xor@ = masks to apply to the modes
387  *                      settings
388  *
389  * Returns:     Zero on success, %$-1$% on error.
390  *
391  * Use:         Adjust the terminal display modes: specifically, the modes
392  *              are adjusted to be @(modes&~modes_bic) ^ modes_xor@.
393  *              Mode bits which aren't supported by the terminal are
394  *              ignored.
395  */
396
397 extern int tty_setmodes(struct tty */*tty*/,
398                         uint32 /*modes_bic*/, uint32 /*modes_xor*/);
399 extern int tty_setmodesg(struct tty */*tty*/,
400                          const struct gprintf_ops */*gops*/, void */*go*/,
401                          uint32 /*modes_bic*/, uint32 /*modes_xor*/);
402
403 /* --- @tty_move@, @tty_moveg@ --- *
404  *
405  * Arguments:   @struct tty *tty@ = control block pointer
406  *              @const struct gprintf_ops *gops, void *go@ = output
407  *                      destination
408  *              @unsigned orig@ = origin
409  *              @int y, x@ = new cursor position
410  *
411  * Returns:     Zero on success, %$-1$% on error.
412  *
413  * Use:         Move the cursor.  Coordinates are numbered starting with 0.
414  *
415  *              The @y@ position is interpreted relative to the origin given
416  *              by @orig@: if @TTOF_YCUR@ is set, then the motion is relative
417  *              to the current cursor row; otherwise, it is relative to
418  *              the top `home' row.  Similarly, the @x@ position is
419  *              interpreted relative to the current cursor column if
420  *              @TTOF_XCUR is set, otherwise relative to the leftmost
421  *              column.
422  *
423  *              Not all terminals are capable of all kinds of motions:
424  *              @TTCF_ABSMV@ is set if absolute motion is possible, and
425  *              @TTCF_RELMV@ is set if relative motion is possible.  The
426  *              @TTCF_MIXMV@ bit indicates that the combination of absolute-y
427  *              and relative-x motion is possible; note that the combination
428  *              of relative-y and absolute-x is always possible if relative
429  *              motion is possible at all.
430  *
431  *              The above notwithstanding, all terminals are assumed capable
432  *              of moving the cursor to the start of either the current line
433  *              @tty_move(tty, TTOF_YCUR | TTOF_XHOME, 0, 0)@, or of the next
434  *              line @tty_move(tty, TTOF_YCUR | TTOF_XHOME, +1, 0)@.
435  */
436
437 extern int tty_move(struct tty */*tty*/,
438                     unsigned /*orig*/, int /*y*/, int /*x*/);
439 extern int tty_moveg(struct tty */*tty*/,
440                      const struct gprintf_ops */*gops*/, void */*go*/,
441                      unsigned /*orig*/, int /*y*/, int /*x*/);
442
443 /* --- @tty_repeat@, @tty_repeatg@ --- *
444  *
445  * Arguments:   @struct tty *tty@ = control block pointer
446  *              @const struct gprintf_ops *gops, void *go@ = output
447  *                      destination
448  *              @int ch@ = character to write
449  *              @unsigned n@ = number of copies
450  *
451  * Returns:     Zero on success, %$-1$% on error.
452  *
453  * Use:         Write @n@ copies of the character @ch@ to the terminal.
454  *              (Some terminals have a special control sequence for doing
455  *              this.)
456  */
457
458 extern int tty_repeat(struct tty */*tty*/, int /*ch*/, unsigned /*n*/);
459 extern int tty_repeatg(struct tty */*tty*/,
460                        const struct gprintf_ops */*gops*/, void */*go*/,
461                        int /*ch*/, unsigned /*n*/);
462
463 /* --- @tty_erase@, @tty_eraseg@ --- *
464  *
465  * Arguments:   @struct tty *tty@ = control block pointer
466  *              @const struct gprintf_ops *gops, void *go@ = output
467  *                      destination
468  *              @unsigned f@ = flags
469  *
470  * Returns:     Zero on success, %$-1$% on error.
471  *
472  * Use:         Erase portions of the current line or the whole display.
473  *
474  *              If @TTEF_DSP@ is set, then the whole display is affected.  If
475  *              @TTEF_BEGIN@ is set, then the display is erased starting from
476  *              the top left and ending at and including the cursor
477  *              position.  If @TTEF_END@ is set, then the display is erased
478  *              starting from and including the cursor position, and ending
479  *              at the bottom right.  If both flags are set, then,
480  *              additionally, the cursor is moved to its `home' position at
481  *              the top left.
482  *
483  *              If @TTF_DSP@ is not set, then the current line is affected.
484  *              If @TTEF_BEGIN@ is set, then the line is erased starting from
485  *              the left and ending at and including the cursor position.  If
486  *              @TTEF_END@ is set, then the line is erased starting from and
487  *              including the cursor position, and ending at the right hand
488  *              side.
489  *
490  *              If the @TTCF_BGER@ capability is set, then the erased
491  *              positions take on the current background colour; otherwise,
492  *              they have the default background colour.
493  */
494
495 extern int tty_erase(struct tty */*tty*/, unsigned /*f*/);
496 extern int tty_eraseg(struct tty */*tty*/,
497                       const struct gprintf_ops */*gops*/, void */*go*/,
498                       unsigned /*f*/);
499
500 /* --- @tty_erch@, @tty_erchg@ --- *
501  *
502  * Arguments:   @struct tty *tty@ = control block pointer
503  *              @const struct gprintf_ops *gops, void *go@ = output
504  *                      destination
505  *              @unsigned n@ = number of characters to erase
506  *
507  * Returns:     Zero on success, %$-1$% on error.
508  *
509  * Use:         Erase a number of characters, starting from and including the
510  *              current cursor position.
511  *
512  *              If the @TTCF_BGER@ capability is set, then the erased
513  *              positions take on the current background colour; otherwise,
514  *              they have the default background colour.
515  */
516
517 extern int tty_erch(struct tty */*tty*/, unsigned /*n*/);
518 extern int tty_erchg(struct tty */*tty*/,
519                      const struct gprintf_ops */*gops*/, void */*go*/,
520                      unsigned /*n*/);
521
522 /* --- @tty_ins@, @tty_insg@ --- *
523  *
524  * Arguments:   @struct tty *tty@ = control block pointer
525  *              @const struct gprintf_ops *gops, void *go@ = output
526  *                      destination
527  *              @unsigned f@ = flags
528  *              @unsigned n@ = number of items to insert
529  *
530  * Returns:     Zero on success, %$-1$% on error.
531  *
532  * Use:         Insert a number of blank characters or lines.
533  *
534  *              If @TTIDF_LN@ is set, then insert @n@ blank lines above the
535  *              current line.  The cursor must be at the far left of the
536  *              line.
537  *
538  *              Otherwise, insert @n@ empty character spaces at the cursor
539  *              position.
540  */
541
542 extern int tty_ins(struct tty */*tty*/, unsigned /*f*/, unsigned /*n*/);
543 extern int tty_insg(struct tty */*tty*/,
544                     const struct gprintf_ops */*gops*/, void */*go*/,
545                     unsigned /*f*/, unsigned /*n*/);
546
547 /* --- @tty_inch@ --- *
548  *
549  * Arguments:   @struct tty *tty@ = control block pointer
550  *              @const struct gprintf_ops *gops, void *go@ = output
551  *                      destination
552  *              @int ch@ = character to insert
553  *
554  * Returns:     Zero on success, %$-1$% on error.
555  *
556  * Use:         Insert a single character.
557  *
558  *              If the @TTMF_INS@ mode is advertised, then insert mode must
559  *              be set before calling this function.
560  */
561
562 extern int tty_inch(struct tty */*tty*/, int /*ch*/);
563 extern int tty_inchg(struct tty */*tty*/,
564                      const struct gprintf_ops */*gops*/, void */*go*/,
565                      int /*ch*/);
566
567 /* --- @tty_del@, @tty_delg@ --- *
568  *
569  * Arguments:   @struct tty *tty@ = control block pointer
570  *              @const struct gprintf_ops *gops, void *go@ = output
571  *                      destination
572  *              @unsigned f@ = flags
573  *              @unsigned n@ = number of items to delete
574  *
575  * Returns:     Zero on success, %$-1$% on error.
576  *
577  * Use:         Delete a number of characters or lines.
578  *
579  *              If @TTIDF_LN@ is set, then delete @n@ blank lines, starting
580  *              with the current line line.  The cursor must be at the far
581  *              left of the line.
582  *
583  *              Otherwise, delete @n@ characters at the cursor position.
584  */
585
586 extern int tty_del(struct tty */*tty*/, unsigned /*f*/, unsigned /*n*/);
587 extern int tty_delg(struct tty */*tty*/,
588                     const struct gprintf_ops */*gops*/, void */*go*/,
589                     unsigned /*f*/, unsigned /*n*/);
590
591 /* --- @tty_restore@, @tty_restoreg@ --- *
592  *
593  * Arguments:   @struct tty *tty@ = control block pointer
594  *              @const struct gprintf_ops *gops, void *go@ = output
595  *                      destination
596  *              @const struct tty_state *st@ = state to restore
597  *
598  * Returns:     Zero on success, %$-1$% on error.
599  *
600  * Use:         Restore the terminal modes and attributes to match a
601  *              state previously captured by copying @tty->st@.
602  */
603
604 extern int tty_restore(struct tty */*tty*/, const struct tty_state */*st*/);
605 extern int tty_restoreg(struct tty */*tty*/,
606                         const struct gprintf_ops */*gops*/, void */*go*/,
607                         const struct tty_state */*st*/);
608
609 /*----- That's all, folks -------------------------------------------------*/
610
611 #ifdef __cplusplus
612   }
613 #endif
614
615 #endif