diff options
Diffstat (limited to 'texinfo/info/terminal.c')
-rw-r--r-- | texinfo/info/terminal.c | 837 |
1 files changed, 0 insertions, 837 deletions
diff --git a/texinfo/info/terminal.c b/texinfo/info/terminal.c deleted file mode 100644 index d77d89e90f6..00000000000 --- a/texinfo/info/terminal.c +++ /dev/null @@ -1,837 +0,0 @@ -/* terminal.c -- How to handle the physical terminal for Info. - $Id: terminal.c,v 1.1.1.3 1998/03/24 18:20:18 law Exp $ - - Copyright (C) 1988, 89, 90, 91, 92, 93, 96, 97, 98 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - Written by Brian Fox (bfox@ai.mit.edu). */ - -#include "info.h" -#include "terminal.h" -#include "termdep.h" - -#include <sys/types.h> -#include <signal.h> - -/* The Unix termcap interface code. */ -#ifdef HAVE_NCURSES_TERMCAP_H -#include <ncurses/termcap.h> -#else -#ifdef HAVE_TERMCAP_H -#include <termcap.h> -#else -/* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC. - Unfortunately, PC is a global variable used by the termcap library. */ -#undef PC - -/* Termcap requires these variables, whether we access them or not. */ -char *BC, *UP; -char PC; /* Pad character */ -short ospeed; /* Terminal output baud rate */ -extern int tgetnum (), tgetflag (), tgetent (); -extern char *tgetstr (), *tgoto (); -extern void tputs (); -#endif /* not HAVE_TERMCAP_H */ -#endif /* not HAVE_NCURSES_TERMCAP_H */ - -/* Function "hooks". If you make one of these point to a function, that - function is called when appropriate instead of its namesake. Your - function is called with exactly the same arguments that were passed - to the namesake function. */ -VFunction *terminal_begin_inverse_hook = (VFunction *)NULL; -VFunction *terminal_end_inverse_hook = (VFunction *)NULL; -VFunction *terminal_prep_terminal_hook = (VFunction *)NULL; -VFunction *terminal_unprep_terminal_hook = (VFunction *)NULL; -VFunction *terminal_up_line_hook = (VFunction *)NULL; -VFunction *terminal_down_line_hook = (VFunction *)NULL; -VFunction *terminal_clear_screen_hook = (VFunction *)NULL; -VFunction *terminal_clear_to_eol_hook = (VFunction *)NULL; -VFunction *terminal_get_screen_size_hook = (VFunction *)NULL; -VFunction *terminal_goto_xy_hook = (VFunction *)NULL; -VFunction *terminal_initialize_terminal_hook = (VFunction *)NULL; -VFunction *terminal_new_terminal_hook = (VFunction *)NULL; -VFunction *terminal_put_text_hook = (VFunction *)NULL; -VFunction *terminal_ring_bell_hook = (VFunction *)NULL; -VFunction *terminal_write_chars_hook = (VFunction *)NULL; -VFunction *terminal_scroll_terminal_hook = (VFunction *)NULL; - -/* **************************************************************** */ -/* */ -/* Terminal and Termcap */ -/* */ -/* **************************************************************** */ - -/* A buffer which holds onto the current terminal description, and a pointer - used to float within it. */ -static char *term_buffer = (char *)NULL; -static char *term_string_buffer = (char *)NULL; - -/* Some strings to control terminal actions. These are output by tputs (). */ -static char *term_goto, *term_clreol, *term_cr, *term_clrpag; -static char *term_begin_use, *term_end_use; -static char *term_AL, *term_DL, *term_al, *term_dl; - -static char *term_keypad_on, *term_keypad_off; - -/* How to go up a line. */ -static char *term_up; - -/* How to go down a line. */ -static char *term_dn; - -/* An audible bell, if the terminal can be made to make noise. */ -static char *audible_bell; - -/* A visible bell, if the terminal can be made to flash the screen. */ -static char *visible_bell; - -/* The string to write to turn on the meta key, if this term has one. */ -static char *term_mm; - -/* The string to write to turn off the meta key, if this term has one. */ -static char *term_mo; - -/* The string to turn on inverse mode, if this term has one. */ -static char *term_invbeg; - -/* The string to turn off inverse mode, if this term has one. */ -static char *term_invend; - -/* Although I can't find any documentation that says this is supposed to - return its argument, all the code I've looked at (termutils, less) - does so, so fine. */ -static int -output_character_function (c) - int c; -{ - putc (c, stdout); - return c; -} - -/* Macro to send STRING to the terminal. */ -#define send_to_terminal(string) \ - do { \ - if (string) \ - tputs (string, 1, output_character_function); \ - } while (0) - -/* Tell the terminal that we will be doing cursor addressable motion. */ -static void -terminal_begin_using_terminal () -{ - RETSIGTYPE (*sigsave) (); - - if (term_keypad_on) - send_to_terminal (term_keypad_on); - - if (!term_begin_use || !*term_begin_use) - return; - -#ifdef SIGWINCH - sigsave = signal (SIGWINCH, SIG_IGN); -#endif - - send_to_terminal (term_begin_use); - /* Without this fflush and sleep, running info in a shelltool or - cmdtool (TERM=sun-cmd) with scrollbars loses -- the scrollbars are - not restored properly. - From: strube@physik3.gwdg.de (Hans Werner Strube). */ - fflush (stdout); - sleep (1); - -#ifdef SIGWINCH - signal (SIGWINCH, sigsave); -#endif -} - -/* Tell the terminal that we will not be doing any more cursor - addressable motion. */ -static void -terminal_end_using_terminal () -{ - RETSIGTYPE (*sigsave) (); - - if (term_keypad_off) - send_to_terminal (term_keypad_off); - - if (!term_end_use || !*term_end_use) - return; - -#ifdef SIGWINCH - sigsave = signal (SIGWINCH, SIG_IGN); -#endif - - send_to_terminal (term_end_use); - fflush (stdout); - sleep (1); - -#ifdef SIGWINCH - signal (SIGWINCH, sigsave); -#endif -} - -/* **************************************************************** */ -/* */ -/* Necessary Terminal Functions */ -/* */ -/* **************************************************************** */ - -/* The functions and variables on this page implement the user visible - portion of the terminal interface. */ - -/* The width and height of the terminal. */ -int screenwidth, screenheight; - -/* Non-zero means this terminal can't really do anything. */ -int terminal_is_dumb_p = 0; - -/* Non-zero means that this terminal has a meta key. */ -int terminal_has_meta_p = 0; - -/* Non-zero means that this terminal can produce a visible bell. */ -int terminal_has_visible_bell_p = 0; - -/* Non-zero means to use that visible bell if at all possible. */ -int terminal_use_visible_bell_p = 0; - -/* Non-zero means that the terminal can do scrolling. */ -int terminal_can_scroll = 0; - -/* The key sequences output by the arrow keys, if this terminal has any. */ -char *term_ku = (char *)NULL; -char *term_kd = (char *)NULL; -char *term_kr = (char *)NULL; -char *term_kl = (char *)NULL; -char *term_kP = (char *)NULL; /* page-up */ -char *term_kN = (char *)NULL; /* page-down */ - -/* Move the cursor to the terminal location of X and Y. */ -void -terminal_goto_xy (x, y) - int x, y; -{ - if (terminal_goto_xy_hook) - (*terminal_goto_xy_hook) (x, y); - else - { - if (term_goto) - tputs (tgoto (term_goto, x, y), 1, output_character_function); - } -} - -/* Print STRING to the terminal at the current position. */ -void -terminal_put_text (string) - char *string; -{ - if (terminal_put_text_hook) - (*terminal_put_text_hook) (string); - else - { - printf ("%s", string); - } -} - -/* Print NCHARS from STRING to the terminal at the current position. */ -void -terminal_write_chars (string, nchars) - char *string; - int nchars; -{ - if (terminal_write_chars_hook) - (*terminal_write_chars_hook) (string, nchars); - else - { - if (nchars) - fwrite (string, 1, nchars, stdout); - } -} - -/* Clear from the current position of the cursor to the end of the line. */ -void -terminal_clear_to_eol () -{ - if (terminal_clear_to_eol_hook) - (*terminal_clear_to_eol_hook) (); - else - { - send_to_terminal (term_clreol); - } -} - -/* Clear the entire terminal screen. */ -void -terminal_clear_screen () -{ - if (terminal_clear_screen_hook) - (*terminal_clear_screen_hook) (); - else - { - send_to_terminal (term_clrpag); - } -} - -/* Move the cursor up one line. */ -void -terminal_up_line () -{ - if (terminal_up_line_hook) - (*terminal_up_line_hook) (); - else - { - send_to_terminal (term_up); - } -} - -/* Move the cursor down one line. */ -void -terminal_down_line () -{ - if (terminal_down_line_hook) - (*terminal_down_line_hook) (); - else - { - send_to_terminal (term_dn); - } -} - -/* Turn on reverse video if possible. */ -void -terminal_begin_inverse () -{ - if (terminal_begin_inverse_hook) - (*terminal_begin_inverse_hook) (); - else - { - send_to_terminal (term_invbeg); - } -} - -/* Turn off reverse video if possible. */ -void -terminal_end_inverse () -{ - if (terminal_end_inverse_hook) - (*terminal_end_inverse_hook) (); - else - { - send_to_terminal (term_invend); - } -} - -/* Ring the terminal bell. The bell is run visibly if it both has one and - terminal_use_visible_bell_p is non-zero. */ -void -terminal_ring_bell () -{ - if (terminal_ring_bell_hook) - (*terminal_ring_bell_hook) (); - else - { - if (terminal_has_visible_bell_p && terminal_use_visible_bell_p) - send_to_terminal (visible_bell); - else - send_to_terminal (audible_bell); - } -} - -/* At the line START, delete COUNT lines from the terminal display. */ -static void -terminal_delete_lines (start, count) - int start, count; -{ - int lines; - - /* Normalize arguments. */ - if (start < 0) - start = 0; - - lines = screenheight - start; - terminal_goto_xy (0, start); - if (term_DL) - tputs (tgoto (term_DL, 0, count), lines, output_character_function); - else - { - while (count--) - tputs (term_dl, lines, output_character_function); - } - - fflush (stdout); -} - -/* At the line START, insert COUNT lines in the terminal display. */ -static void -terminal_insert_lines (start, count) - int start, count; -{ - int lines; - - /* Normalize arguments. */ - if (start < 0) - start = 0; - - lines = screenheight - start; - terminal_goto_xy (0, start); - - if (term_AL) - tputs (tgoto (term_AL, 0, count), lines, output_character_function); - else - { - while (count--) - tputs (term_al, lines, output_character_function); - } - - fflush (stdout); -} - -/* Scroll an area of the terminal, starting with the region from START - to END, AMOUNT lines. If AMOUNT is negative, the lines are scrolled - towards the top of the screen, else they are scrolled towards the - bottom of the screen. */ -void -terminal_scroll_terminal (start, end, amount) - int start, end, amount; -{ - if (!terminal_can_scroll) - return; - - /* Any scrolling at all? */ - if (amount == 0) - return; - - if (terminal_scroll_terminal_hook) - (*terminal_scroll_terminal_hook) (start, end, amount); - else - { - /* If we are scrolling down, delete AMOUNT lines at END. Then insert - AMOUNT lines at START. */ - if (amount > 0) - { - terminal_delete_lines (end, amount); - terminal_insert_lines (start, amount); - } - - /* If we are scrolling up, delete AMOUNT lines before START. This - actually does the upwards scroll. Then, insert AMOUNT lines - after the already scrolled region (i.e., END - AMOUNT). */ - if (amount < 0) - { - int abs_amount = -amount; - terminal_delete_lines (start - abs_amount, abs_amount); - terminal_insert_lines (end - abs_amount, abs_amount); - } - } -} - -/* Re-initialize the terminal considering that the TERM/TERMCAP variable - has changed. */ -void -terminal_new_terminal (terminal_name) - char *terminal_name; -{ - if (terminal_new_terminal_hook) - (*terminal_new_terminal_hook) (terminal_name); - else - { - terminal_initialize_terminal (terminal_name); - } -} - -/* Set the global variables SCREENWIDTH and SCREENHEIGHT. */ -void -terminal_get_screen_size () -{ - if (terminal_get_screen_size_hook) - (*terminal_get_screen_size_hook) (); - else - { - screenwidth = screenheight = 0; - -#if defined (TIOCGWINSZ) - { - struct winsize window_size; - - if (ioctl (fileno (stdout), TIOCGWINSZ, &window_size) == 0) - { - screenwidth = (int) window_size.ws_col; - screenheight = (int) window_size.ws_row; - } - } -#endif /* TIOCGWINSZ */ - - /* Environment variable COLUMNS overrides setting of "co". */ - if (screenwidth <= 0) - { - char *sw = getenv ("COLUMNS"); - - if (sw) - screenwidth = atoi (sw); - - if (screenwidth <= 0) - screenwidth = tgetnum ("co"); - } - - /* Environment variable LINES overrides setting of "li". */ - if (screenheight <= 0) - { - char *sh = getenv ("LINES"); - - if (sh) - screenheight = atoi (sh); - - if (screenheight <= 0) - screenheight = tgetnum ("li"); - } - - /* If all else fails, default to 80x24 terminal. */ - if (screenwidth <= 0) - screenwidth = 80; - - if (screenheight <= 0) - screenheight = 24; - } -} - -/* Initialize the terminal which is known as TERMINAL_NAME. If this - terminal doesn't have cursor addressability, `terminal_is_dumb_p' - becomes nonzero. The variables SCREENHEIGHT and SCREENWIDTH are set - to the dimensions that this terminal actually has. The variable - TERMINAL_HAS_META_P becomes nonzero if this terminal supports a Meta - key. Finally, the terminal screen is cleared. */ -void -terminal_initialize_terminal (terminal_name) - char *terminal_name; -{ - char *term, *buffer; - - terminal_is_dumb_p = 0; - - if (terminal_initialize_terminal_hook) - { - (*terminal_initialize_terminal_hook) (terminal_name); - return; - } - - term = terminal_name ? terminal_name : getenv ("TERM"); - - if (!term_string_buffer) - term_string_buffer = (char *)xmalloc (2048); - - if (!term_buffer) - term_buffer = (char *)xmalloc (2048); - - buffer = term_string_buffer; - - term_clrpag = term_cr = term_clreol = (char *)NULL; - - if (!term) - term = "dumb"; - - if (tgetent (term_buffer, term) <= 0) - { - terminal_is_dumb_p = 1; - screenwidth = 80; - screenheight = 24; - term_cr = "\r"; - term_up = term_dn = audible_bell = visible_bell = (char *)NULL; - term_ku = term_kd = term_kl = term_kr = (char *)NULL; - term_kP = term_kN = (char *)NULL; - return; - } - - BC = tgetstr ("pc", &buffer); - PC = BC ? *BC : 0; - -#if defined (TIOCGETP) - { - struct sgttyb sg; - - if (ioctl (fileno (stdout), TIOCGETP, &sg) != -1) - ospeed = sg.sg_ospeed; - else - ospeed = B9600; - } -#else - ospeed = B9600; -#endif /* !TIOCGETP */ - - term_cr = tgetstr ("cr", &buffer); - term_clreol = tgetstr ("ce", &buffer); - term_clrpag = tgetstr ("cl", &buffer); - term_goto = tgetstr ("cm", &buffer); - - /* Find out about this terminals scrolling capability. */ - term_AL = tgetstr ("AL", &buffer); - term_DL = tgetstr ("DL", &buffer); - term_al = tgetstr ("al", &buffer); - term_dl = tgetstr ("dl", &buffer); - - terminal_can_scroll = ((term_AL || term_al) && (term_DL || term_dl)); - - term_invbeg = tgetstr ("mr", &buffer); - if (term_invbeg) - term_invend = tgetstr ("me", &buffer); - else - term_invend = (char *)NULL; - - if (!term_cr) - term_cr = "\r"; - - terminal_get_screen_size (); - - term_up = tgetstr ("up", &buffer); - term_dn = tgetstr ("dn", &buffer); - visible_bell = tgetstr ("vb", &buffer); - terminal_has_visible_bell_p = (visible_bell != (char *)NULL); - audible_bell = tgetstr ("bl", &buffer); - if (!audible_bell) - audible_bell = "\007"; - term_begin_use = tgetstr ("ti", &buffer); - term_end_use = tgetstr ("te", &buffer); - - term_keypad_on = tgetstr ("ks", &buffer); - term_keypad_off = tgetstr ("ke", &buffer); - - /* Check to see if this terminal has a meta key. */ - terminal_has_meta_p = (tgetflag ("km") || tgetflag ("MT")); - if (terminal_has_meta_p) - { - term_mm = tgetstr ("mm", &buffer); - term_mo = tgetstr ("mo", &buffer); - } - else - { - term_mm = (char *)NULL; - term_mo = (char *)NULL; - } - - /* Attempt to find the arrow keys. */ - term_ku = tgetstr ("ku", &buffer); - term_kd = tgetstr ("kd", &buffer); - term_kr = tgetstr ("kr", &buffer); - term_kl = tgetstr ("kl", &buffer); - - term_kP = tgetstr ("kP", &buffer); - term_kN = tgetstr ("kN", &buffer); - - /* If this terminal is not cursor addressable, then it is really dumb. */ - if (!term_goto) - terminal_is_dumb_p = 1; -} - -/* **************************************************************** */ -/* */ -/* How to Read Characters From the Terminal */ -/* */ -/* **************************************************************** */ - -#if defined (TIOCGETC) -/* A buffer containing the terminal interrupt characters upon entry - to Info. */ -struct tchars original_tchars; -#endif - -#if defined (TIOCGLTC) -/* A buffer containing the local terminal mode characters upon entry - to Info. */ -struct ltchars original_ltchars; -#endif - -#if defined (HAVE_TERMIOS_H) -struct termios original_termios, ttybuff; -#else -# if defined (HAVE_TERMIO_H) -/* A buffer containing the terminal mode flags upon entry to info. */ -struct termio original_termio, ttybuff; -# else /* !HAVE_TERMIO_H */ -/* Buffers containing the terminal mode flags upon entry to info. */ -int original_tty_flags = 0; -int original_lmode; -struct sgttyb ttybuff; -# endif /* !HAVE_TERMIO_H */ -#endif /* !HAVE_TERMIOS_H */ - -/* Prepare to start using the terminal to read characters singly. */ -void -terminal_prep_terminal () -{ - int tty; - - if (terminal_prep_terminal_hook) - { - (*terminal_prep_terminal_hook) (); - return; - } - - terminal_begin_using_terminal (); - - tty = fileno (stdin); - -#if defined (HAVE_TERMIOS_H) - tcgetattr (tty, &original_termios); - tcgetattr (tty, &ttybuff); -#else -# if defined (HAVE_TERMIO_H) - ioctl (tty, TCGETA, &original_termio); - ioctl (tty, TCGETA, &ttybuff); -# endif -#endif - -#if defined (HAVE_TERMIOS_H) || defined (HAVE_TERMIO_H) - ttybuff.c_iflag &= (~ISTRIP & ~INLCR & ~IGNCR & ~ICRNL & ~IXON); -/* These output flags are not part of POSIX, so only use them if they - are defined. */ -#ifdef ONLCR - ttybuff.c_oflag &= ~ONLCR ; -#endif -#ifdef OCRNL - ttybuff.c_oflag &= ~OCRNL; -#endif - ttybuff.c_lflag &= (~ICANON & ~ECHO); - - ttybuff.c_cc[VMIN] = 1; - ttybuff.c_cc[VTIME] = 0; - - if (ttybuff.c_cc[VINTR] == '\177') - ttybuff.c_cc[VINTR] = -1; - - if (ttybuff.c_cc[VQUIT] == '\177') - ttybuff.c_cc[VQUIT] = -1; - -#ifdef VLNEXT - if (ttybuff.c_cc[VLNEXT] == '\026') - ttybuff.c_cc[VLNEXT] = -1; -#endif /* VLNEXT */ -#endif /* TERMIOS or TERMIO */ - -#if defined (HAVE_TERMIOS_H) - tcsetattr (tty, TCSANOW, &ttybuff); -#else -# if defined (HAVE_TERMIO_H) - ioctl (tty, TCSETA, &ttybuff); -# endif -#endif - -#if !defined (HAVE_TERMIOS_H) && !defined (HAVE_TERMIO_H) - ioctl (tty, TIOCGETP, &ttybuff); - - if (!original_tty_flags) - original_tty_flags = ttybuff.sg_flags; - - /* Make this terminal pass 8 bits around while we are using it. */ -# if defined (PASS8) - ttybuff.sg_flags |= PASS8; -# endif /* PASS8 */ - -# if defined (TIOCLGET) && defined (LPASS8) - { - int flags; - ioctl (tty, TIOCLGET, &flags); - original_lmode = flags; - flags |= LPASS8; - ioctl (tty, TIOCLSET, &flags); - } -# endif /* TIOCLGET && LPASS8 */ - -# if defined (TIOCGETC) - { - struct tchars temp; - - ioctl (tty, TIOCGETC, &original_tchars); - temp = original_tchars; - - /* C-s and C-q. */ - temp.t_startc = temp.t_stopc = -1; - - /* Often set to C-d. */ - temp.t_eofc = -1; - - /* If the a quit or interrupt character conflicts with one of our - commands, then make it go away. */ - if (temp.t_intrc == '\177') - temp.t_intrc = -1; - - if (temp.t_quitc == '\177') - temp.t_quitc = -1; - - ioctl (tty, TIOCSETC, &temp); - } -# endif /* TIOCGETC */ - -# if defined (TIOCGLTC) - { - struct ltchars temp; - - ioctl (tty, TIOCGLTC, &original_ltchars); - temp = original_ltchars; - - /* Make the interrupt keys go away. Just enough to make people happy. */ - temp.t_lnextc = -1; /* C-v. */ - temp.t_dsuspc = -1; /* C-y. */ - temp.t_flushc = -1; /* C-o. */ - ioctl (tty, TIOCSLTC, &temp); - } -# endif /* TIOCGLTC */ - - ttybuff.sg_flags &= ~ECHO; - ttybuff.sg_flags |= CBREAK; - ioctl (tty, TIOCSETN, &ttybuff); -#endif /* !HAVE_TERMIOS_H && !HAVE_TERMIO_H */ -} - -/* Restore the tty settings back to what they were before we started using - this terminal. */ -void -terminal_unprep_terminal () -{ - int tty; - - if (terminal_unprep_terminal_hook) - { - (*terminal_unprep_terminal_hook) (); - return; - } - - tty = fileno (stdin); - -#if defined (HAVE_TERMIOS_H) - tcsetattr (tty, TCSANOW, &original_termios); -#else -# if defined (HAVE_TERMIO_H) - ioctl (tty, TCSETA, &original_termio); -# else /* !HAVE_TERMIO_H */ - ioctl (tty, TIOCGETP, &ttybuff); - ttybuff.sg_flags = original_tty_flags; - ioctl (tty, TIOCSETN, &ttybuff); - -# if defined (TIOCGETC) - ioctl (tty, TIOCSETC, &original_tchars); -# endif /* TIOCGETC */ - -# if defined (TIOCGLTC) - ioctl (tty, TIOCSLTC, &original_ltchars); -# endif /* TIOCGLTC */ - -# if defined (TIOCLGET) && defined (LPASS8) - ioctl (tty, TIOCLSET, &original_lmode); -# endif /* TIOCLGET && LPASS8 */ - -# endif /* !HAVE_TERMIO_H */ -#endif /* !HAVE_TERMIOS_H */ - terminal_end_using_terminal (); -} - |