root/maint/gnulib/lib/term-style-control.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


   1 /* Terminal control for outputting styled text to a terminal.
   2    Copyright (C) 2019-2021 Free Software Foundation, Inc.
   3    Written by Bruno Haible <bruno@clisp.org>, 2019.
   4 
   5    This program is free software: you can redistribute it and/or modify
   6    it under the terms of the GNU General Public License as published by
   7    the Free Software Foundation; either version 3 of the License, or
   8    (at your option) any later version.
   9 
  10    This program is distributed in the hope that it will be useful,
  11    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13    GNU General Public License for more details.
  14 
  15    You should have received a copy of the GNU General Public License
  16    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  17 
  18 #ifndef _TERM_STYLE_CONTROL_H
  19 #define _TERM_STYLE_CONTROL_H
  20 
  21 #include <stdbool.h>
  22 
  23 /* The user of this file will define a macro 'term_style_user_data', such that
  24    'struct term_style_user_data' is a user-defined struct.  */
  25 
  26 
  27 /* The amount of control to take over the underlying tty in order to avoid
  28    garbled output on the screen, due to interleaved output of escape sequences
  29    and output from the kernel (such as when the kernel echoes user's input
  30    or when the kernel prints '^C' after the user pressed Ctrl-C).  */
  31 typedef enum
  32 {
  33   TTYCTL_AUTO = 0,  /* Automatic best-possible choice.  */
  34   TTYCTL_NONE,      /* No control.
  35                        Result: Garbled output can occur, and the terminal can
  36                        be left in any state when the program is interrupted.  */
  37   TTYCTL_PARTIAL,   /* Signal handling.
  38                        Result: Garbled output can occur, but the terminal will
  39                        be left in the default state when the program is
  40                        interrupted.  */
  41   TTYCTL_FULL       /* Signal handling and disabling echo and flush-upon-signal.
  42                        Result: No garbled output, and the the terminal will
  43                        be left in the default state when the program is
  44                        interrupted.  */
  45 } ttyctl_t;
  46 
  47 /* This struct contains data, used by implementation of this module.
  48    You should not access the members of this struct; they may be renamed or
  49    removed without notice.  */
  50 struct term_style_control_data
  51 {
  52   int volatile fd;
  53   ttyctl_t volatile tty_control;     /* Signal handling and tty control.  */
  54   #if HAVE_TCGETATTR
  55   bool volatile same_as_stderr;
  56   #endif
  57   bool non_default_active;           /* True if activate_term_non_default_mode()
  58                                         is in effect.  */
  59 };
  60 
  61 /* Forward declaration.  */
  62 struct term_style_user_data;
  63 
  64 /* This struct contains function pointers.  You implement these functions
  65    in your application; this module invokes them when it needs to.  */
  66 struct term_style_controller
  67 {
  68   /* This function returns a pointer to the embedded
  69      'struct term_style_control_data' contained in a
  70      'struct term_style_user_data'.  */
  71   struct term_style_control_data * (*get_control_data) (struct term_style_user_data *);
  72 
  73   /* This function brings the terminal's state back to the default state
  74      (no styling attributes set).  It is invoked when the process terminates
  75      through exit().  */
  76   void (*restore) (struct term_style_user_data *);
  77 
  78   /* This function brings the terminal's state back to the default state
  79      (no styling attributes set).  It is async-safe (see gnulib-common.m4 for
  80      the precise definition).  It is invoked when the process receives a fatal
  81      or stopping signal.  */
  82   _GL_ASYNC_SAFE void (*async_restore) (struct term_style_user_data *);
  83 
  84   /* This function brings the terminal's state, from the default state, back
  85      to the state where it has the desired attributes set.  It is async-safe
  86      (see gnulib-common.m4 for the precise definition).  It is invoked when
  87      the process receives a SIGCONT signal.  */
  88   _GL_ASYNC_SAFE void (*async_set_attributes_from_default) (struct term_style_user_data *);
  89 };
  90 
  91 
  92 #ifdef __cplusplus
  93 extern "C" {
  94 #endif
  95 
  96 /* This module is used as follows:
  97    1. You fill a 'struct term_style_controller' with function pointers.
  98       You create a 'struct term_style_user_data' that contains, among other
  99       members, a 'struct term_style_control_data'.
 100       You will pass these two objects to all API functions below.
 101    2. You call activate_term_style_controller to activate this controller.
 102       Activation of the controller is the prerequisite for activating
 103       the non-default mode, which in turn is the prerequisite for changing
 104       the terminal's attributes.
 105       When you are done with the styled output, you may deactivate the
 106       controller.  This is not required before exiting the program, but is
 107       required before activating a different controller.
 108       You cannot have more than one controller activated at the same time.
 109    3. Once the controller is activated, you may turn on the non-default mode.
 110       The non-default mode is the prerequisite for changing the terminal's
 111       attributes.  Once the terminal's attributes are in the default state
 112       again, you may turn off the non-default mode again.
 113       In other words:
 114         - In the default mode, the terminal's attributes MUST be in the default
 115           state; no styled output is possible.
 116         - In the non-default mode, the terminal's attributes MAY switch among
 117           the default state and other states.
 118       This module exercises a certain amount of control over the terminal
 119       during the non-default mode phases; see above (ttyctl_t) for details.
 120       You may switch between the default and the non-default modes any number
 121       of times.
 122       The idea is that you switch back to the default mode before doing large
 123       amounts of output of unstyled text.  However, this is not a requirement:
 124       You may leave the non-default mode turned on all the time until the
 125       the program exits.
 126    4. Once the non-default mode is activated, you may change the attributes
 127       (foreground color, background color, font weight, font posture, underline
 128       decoration, etc.) of the terminal.  On Unix, this is typically done by
 129       outputting appropriate escape sequences.
 130    5. Once attributes are set, text output to the terminal will be rendered
 131       with these attributes.
 132       Note: You MUST return the terminal to the default state before outputting
 133       a newline.
 134  */
 135 
 136 /* Activates a controller.  The CONTROLLER and its USER_DATA controls the
 137    terminal associated with FD.  FD is usually STDOUT_FILENO.
 138    TTY_CONTROL specifies the amount of control to take over the underlying tty.
 139    The effects of this functions are undone by calling
 140    deactivate_term_style_controller.
 141    You cannot have more than one controller activated at the same time.
 142    You must not close FD while the controller is active.  */
 143 extern void
 144        activate_term_style_controller (const struct term_style_controller *controller,
 145                                        struct term_style_user_data *user_data,
 146                                        int fd, ttyctl_t tty_control);
 147 
 148 /* Activates the non-default mode.
 149    CONTROLLER and its USER_DATA must be a currently active controller.
 150    This function fiddles with the signals of the current process and with
 151    the underlying tty, to an extent described by TTY_CONTROL.
 152    This function is idempotent: When you call it twice in a row, the second
 153    invocation does nothing.
 154    The effects of this function are undone by calling
 155    deactivate_term_non_default_mode.  */
 156 extern void
 157        activate_term_non_default_mode (const struct term_style_controller *controller,
 158                                        struct term_style_user_data *user_data);
 159 
 160 /* Deactivates the non-default mode.
 161    CONTROLLER and its USER_DATA must be a currently active controller.
 162    This function is idempotent: When you call it twice in a row, the second
 163    invocation does nothing.
 164    Before invoking this function, you must put the terminal's attributes in
 165    the default state.  */
 166 extern void
 167        deactivate_term_non_default_mode (const struct term_style_controller *controller,
 168                                          struct term_style_user_data *user_data);
 169 
 170 /* Deactivates a controller.
 171    CONTROLLER and its USER_DATA must be a currently active controller.
 172    Before invoking this function, you must ensure that the non-default mode
 173    is deactivated.  */
 174 extern void
 175        deactivate_term_style_controller (const struct term_style_controller *controller,
 176                                          struct term_style_user_data *user_data);
 177 
 178 #ifdef __cplusplus
 179 }
 180 #endif
 181 
 182 #endif /* _TERM_STYLE_CONTROL_H */

/* [previous][next][first][last][top][bottom][index][help] */