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