version 1.1.1.1, 2014/07/30 08:16:45
|
version 1.1.1.2, 2021/03/17 01:01:01
|
Line 1
|
Line 1
|
/* terminal.c -- controlling the terminal with termcap. */ |
/* terminal.c -- controlling the terminal with termcap. */ |
|
|
/* Copyright (C) 1996-2009 Free Software Foundation, Inc. | /* Copyright (C) 1996-2017 Free Software Foundation, Inc. |
|
|
This file is part of the GNU Readline Library (Readline), a library |
This file is part of the GNU Readline Library (Readline), a library |
for reading lines of text with interactive input and history editing. |
for reading lines of text with interactive input and history editing. |
Line 51
|
Line 51
|
/* System-specific feature definitions and include files. */ |
/* System-specific feature definitions and include files. */ |
#include "rldefs.h" |
#include "rldefs.h" |
|
|
#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ) |
|
# include <sys/ioctl.h> |
|
#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */ |
|
|
|
#ifdef __MSDOS__ |
#ifdef __MSDOS__ |
# include <pc.h> |
# include <pc.h> |
#endif |
#endif |
|
|
#include "rltty.h" |
#include "rltty.h" |
|
#if defined (HAVE_SYS_IOCTL_H) |
|
# include <sys/ioctl.h> /* include for declaration of ioctl */ |
|
#endif |
#include "tcap.h" |
#include "tcap.h" |
|
|
/* Some standard library routines. */ |
/* Some standard library routines. */ |
Line 113 char PC, *BC, *UP;
|
Line 112 char PC, *BC, *UP;
|
/* Some strings to control terminal actions. These are output by tputs (). */ |
/* Some strings to control terminal actions. These are output by tputs (). */ |
char *_rl_term_clreol; |
char *_rl_term_clreol; |
char *_rl_term_clrpag; |
char *_rl_term_clrpag; |
|
char *_rl_term_clrscroll; |
char *_rl_term_cr; |
char *_rl_term_cr; |
char *_rl_term_backspace; |
char *_rl_term_backspace; |
char *_rl_term_goto; |
char *_rl_term_goto; |
Line 132 char *_rl_term_IC;
|
Line 132 char *_rl_term_IC;
|
char *_rl_term_dc; |
char *_rl_term_dc; |
char *_rl_term_DC; |
char *_rl_term_DC; |
|
|
|
/* How to move forward a char, non-destructively */ |
char *_rl_term_forward_char; |
char *_rl_term_forward_char; |
|
|
/* How to go up a line. */ |
/* How to go up a line. */ |
Line 151 static int term_has_meta;
|
Line 152 static int term_has_meta;
|
static char *_rl_term_mm; |
static char *_rl_term_mm; |
static char *_rl_term_mo; |
static char *_rl_term_mo; |
|
|
|
/* The sequences to enter and exit standout mode. */ |
|
static char *_rl_term_so; |
|
static char *_rl_term_se; |
|
|
/* The key sequences output by the arrow keys, if this terminal has any. */ |
/* The key sequences output by the arrow keys, if this terminal has any. */ |
static char *_rl_term_ku; |
static char *_rl_term_ku; |
static char *_rl_term_kd; |
static char *_rl_term_kd; |
Line 176 static char *_rl_term_kI;
|
Line 181 static char *_rl_term_kI;
|
static char *_rl_term_vs; /* very visible */ |
static char *_rl_term_vs; /* very visible */ |
static char *_rl_term_ve; /* normal */ |
static char *_rl_term_ve; /* normal */ |
|
|
|
/* It's not clear how HPUX is so broken here. */ |
|
#ifdef TGETENT_BROKEN |
|
# define TGETENT_SUCCESS 0 |
|
#else |
|
# define TGETENT_SUCCESS 1 |
|
#endif |
|
#ifdef TGETFLAG_BROKEN |
|
# define TGETFLAG_SUCCESS 0 |
|
#else |
|
# define TGETFLAG_SUCCESS 1 |
|
#endif |
|
#define TGETFLAG(cap) (tgetflag (cap) == TGETFLAG_SUCCESS) |
|
|
static void bind_termcap_arrow_keys PARAMS((Keymap)); |
static void bind_termcap_arrow_keys PARAMS((Keymap)); |
|
|
/* Variables that hold the screen dimensions, used by the display code. */ |
/* Variables that hold the screen dimensions, used by the display code. */ |
Line 189 int _rl_enable_meta = 1;
|
Line 207 int _rl_enable_meta = 1;
|
|
|
#if defined (__EMX__) |
#if defined (__EMX__) |
static void |
static void |
_emx_get_screensize (swp, shp) | _emx_get_screensize (int *swp, int *shp) |
int *swp, *shp; | |
{ |
{ |
int sz[2]; |
int sz[2]; |
|
|
Line 205 _emx_get_screensize (swp, shp)
|
Line 222 _emx_get_screensize (swp, shp)
|
|
|
#if defined (__MINGW32__) |
#if defined (__MINGW32__) |
static void |
static void |
_win_get_screensize (swp, shp) | _win_get_screensize (int *swp, int *shp) |
int *swp, *shp; | |
{ |
{ |
HANDLE hConOut; |
HANDLE hConOut; |
CONSOLE_SCREEN_BUFFER_INFO scr; |
CONSOLE_SCREEN_BUFFER_INFO scr; |
Line 228 _win_get_screensize (swp, shp)
|
Line 244 _win_get_screensize (swp, shp)
|
values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being |
values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being |
non-null serve to check whether or not we have initialized termcap. */ |
non-null serve to check whether or not we have initialized termcap. */ |
void |
void |
_rl_get_screen_size (tty, ignore_env) | _rl_get_screen_size (int tty, int ignore_env) |
int tty, ignore_env; | |
{ |
{ |
char *ss; |
char *ss; |
#if defined (TIOCGWINSZ) |
#if defined (TIOCGWINSZ) |
Line 319 _rl_get_screen_size (tty, ignore_env)
|
Line 334 _rl_get_screen_size (tty, ignore_env)
|
} |
} |
|
|
void |
void |
_rl_set_screen_size (rows, cols) | _rl_set_screen_size (int rows, int cols) |
int rows, cols; | |
{ |
{ |
if (_rl_term_autowrap == -1) |
if (_rl_term_autowrap == -1) |
_rl_init_terminal_io (rl_terminal_name); |
_rl_init_terminal_io (rl_terminal_name); |
Line 339 _rl_set_screen_size (rows, cols)
|
Line 353 _rl_set_screen_size (rows, cols)
|
} |
} |
|
|
void |
void |
rl_set_screen_size (rows, cols) | rl_set_screen_size (int rows, int cols) |
int rows, cols; | |
{ |
{ |
_rl_set_screen_size (rows, cols); |
_rl_set_screen_size (rows, cols); |
} |
} |
|
|
void |
void |
rl_get_screen_size (rows, cols) | rl_get_screen_size (int *rows, int *cols) |
int *rows, *cols; | |
{ |
{ |
if (rows) |
if (rows) |
*rows = _rl_screenheight; |
*rows = _rl_screenheight; |
Line 356 rl_get_screen_size (rows, cols)
|
Line 368 rl_get_screen_size (rows, cols)
|
} |
} |
|
|
void |
void |
rl_reset_screen_size () | rl_reset_screen_size (void) |
{ |
{ |
_rl_get_screen_size (fileno (rl_instream), 0); |
_rl_get_screen_size (fileno (rl_instream), 0); |
} |
} |
|
|
void |
void |
_rl_sigwinch_resize_terminal () | _rl_sigwinch_resize_terminal (void) |
{ |
{ |
_rl_get_screen_size (fileno (rl_instream), 1); |
_rl_get_screen_size (fileno (rl_instream), 1); |
} |
} |
|
|
void |
void |
rl_resize_terminal () | rl_resize_terminal (void) |
{ |
{ |
_rl_get_screen_size (fileno (rl_instream), 1); |
_rl_get_screen_size (fileno (rl_instream), 1); |
if (_rl_echoing_p) |
if (_rl_echoing_p) |
Line 391 static const struct _tc_string tc_strings[] =
|
Line 403 static const struct _tc_string tc_strings[] =
|
{ |
{ |
{ "@7", &_rl_term_at7 }, |
{ "@7", &_rl_term_at7 }, |
{ "DC", &_rl_term_DC }, |
{ "DC", &_rl_term_DC }, |
|
{ "E3", &_rl_term_clrscroll }, |
{ "IC", &_rl_term_IC }, |
{ "IC", &_rl_term_IC }, |
{ "ce", &_rl_term_clreol }, |
{ "ce", &_rl_term_clreol }, |
{ "cl", &_rl_term_clrpag }, |
{ "cl", &_rl_term_clrpag }, |
Line 414 static const struct _tc_string tc_strings[] =
|
Line 427 static const struct _tc_string tc_strings[] =
|
{ "mo", &_rl_term_mo }, |
{ "mo", &_rl_term_mo }, |
{ "nd", &_rl_term_forward_char }, |
{ "nd", &_rl_term_forward_char }, |
{ "pc", &_rl_term_pc }, |
{ "pc", &_rl_term_pc }, |
|
{ "se", &_rl_term_se }, |
|
{ "so", &_rl_term_so }, |
{ "up", &_rl_term_up }, |
{ "up", &_rl_term_up }, |
{ "vb", &_rl_visible_bell }, |
{ "vb", &_rl_visible_bell }, |
{ "vs", &_rl_term_vs }, |
{ "vs", &_rl_term_vs }, |
Line 425 static const struct _tc_string tc_strings[] =
|
Line 440 static const struct _tc_string tc_strings[] =
|
/* Read the desired terminal capability strings into BP. The capabilities |
/* Read the desired terminal capability strings into BP. The capabilities |
are described in the TC_STRINGS table. */ |
are described in the TC_STRINGS table. */ |
static void |
static void |
get_term_capabilities (bp) | get_term_capabilities (char **bp) |
char **bp; | |
{ |
{ |
#if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */ |
#if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */ |
register int i; |
register int i; |
Line 438 get_term_capabilities (bp)
|
Line 452 get_term_capabilities (bp)
|
} |
} |
|
|
int |
int |
_rl_init_terminal_io (terminal_name) | _rl_init_terminal_io (const char *terminal_name) |
const char *terminal_name; | |
{ |
{ |
const char *term; |
const char *term; |
char *buffer; |
char *buffer; |
int tty, tgetent_ret; | int tty, tgetent_ret, dumbterm; |
|
|
term = terminal_name ? terminal_name : sh_get_env_value ("TERM"); |
term = terminal_name ? terminal_name : sh_get_env_value ("TERM"); |
_rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL; | _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = _rl_term_clrscroll = (char *)NULL; |
tty = rl_instream ? fileno (rl_instream) : 0; |
tty = rl_instream ? fileno (rl_instream) : 0; |
|
|
if (term == 0) |
if (term == 0) |
term = "dumb"; |
term = "dumb"; |
|
|
|
dumbterm = STREQ (term, "dumb"); |
|
|
#ifdef __MSDOS__ |
#ifdef __MSDOS__ |
_rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL; |
_rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL; |
_rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL; |
_rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL; |
Line 459 _rl_init_terminal_io (terminal_name)
|
Line 474 _rl_init_terminal_io (terminal_name)
|
_rl_term_mm = _rl_term_mo = (char *)NULL; |
_rl_term_mm = _rl_term_mo = (char *)NULL; |
_rl_terminal_can_insert = term_has_meta = _rl_term_autowrap = 0; |
_rl_terminal_can_insert = term_has_meta = _rl_term_autowrap = 0; |
_rl_term_cr = "\r"; |
_rl_term_cr = "\r"; |
_rl_term_clreol = _rl_term_clrpag = _rl_term_backspace = (char *)NULL; | _rl_term_backspace = (char *)NULL; |
_rl_term_goto = _rl_term_pc = _rl_term_ip = (char *)NULL; |
_rl_term_goto = _rl_term_pc = _rl_term_ip = (char *)NULL; |
_rl_term_ks = _rl_term_ke =_rl_term_vs = _rl_term_ve = (char *)NULL; |
_rl_term_ks = _rl_term_ke =_rl_term_vs = _rl_term_ve = (char *)NULL; |
_rl_term_kh = _rl_term_kH = _rl_term_at7 = _rl_term_kI = (char *)NULL; |
_rl_term_kh = _rl_term_kH = _rl_term_at7 = _rl_term_kI = (char *)NULL; |
|
_rl_term_so = _rl_term_se = (char *)NULL; |
#if defined(HACK_TERMCAP_MOTION) |
#if defined(HACK_TERMCAP_MOTION) |
_rl_term_forward_char = (char *)NULL; |
_rl_term_forward_char = (char *)NULL; |
#endif |
#endif |
Line 489 _rl_init_terminal_io (terminal_name)
|
Line 505 _rl_init_terminal_io (terminal_name)
|
tgetent_ret = tgetent (term_buffer, term); |
tgetent_ret = tgetent (term_buffer, term); |
} |
} |
|
|
if (tgetent_ret <= 0) | if (tgetent_ret != TGETENT_SUCCESS) |
{ |
{ |
FREE (term_string_buffer); |
FREE (term_string_buffer); |
FREE (term_buffer); |
FREE (term_buffer); |
Line 527 _rl_init_terminal_io (terminal_name)
|
Line 543 _rl_init_terminal_io (terminal_name)
|
_rl_term_mm = _rl_term_mo = (char *)NULL; |
_rl_term_mm = _rl_term_mo = (char *)NULL; |
_rl_term_ve = _rl_term_vs = (char *)NULL; |
_rl_term_ve = _rl_term_vs = (char *)NULL; |
_rl_term_forward_char = (char *)NULL; |
_rl_term_forward_char = (char *)NULL; |
|
_rl_term_so = _rl_term_se = (char *)NULL; |
_rl_terminal_can_insert = term_has_meta = 0; |
_rl_terminal_can_insert = term_has_meta = 0; |
|
|
|
/* Assume generic unknown terminal can't handle the enable/disable |
|
escape sequences */ |
|
_rl_enable_bracketed_paste = 0; |
|
|
/* Reasonable defaults for tgoto(). Readline currently only uses |
/* Reasonable defaults for tgoto(). Readline currently only uses |
tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we |
tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we |
change that later... */ |
change that later... */ |
Line 547 _rl_init_terminal_io (terminal_name)
|
Line 568 _rl_init_terminal_io (terminal_name)
|
BC = _rl_term_backspace; |
BC = _rl_term_backspace; |
UP = _rl_term_up; |
UP = _rl_term_up; |
|
|
if (!_rl_term_cr) | if (_rl_term_cr == 0) |
_rl_term_cr = "\r"; |
_rl_term_cr = "\r"; |
|
|
_rl_term_autowrap = tgetflag ("am") && tgetflag ("xn"); | _rl_term_autowrap = TGETFLAG ("am") && TGETFLAG ("xn"); |
|
|
/* Allow calling application to set default height and width, using |
/* Allow calling application to set default height and width, using |
rl_set_screen_size */ |
rl_set_screen_size */ |
Line 565 _rl_init_terminal_io (terminal_name)
|
Line 586 _rl_init_terminal_io (terminal_name)
|
|
|
/* Check to see if this terminal has a meta key and clear the capability |
/* Check to see if this terminal has a meta key and clear the capability |
variables if there is none. */ |
variables if there is none. */ |
term_has_meta = tgetflag ("km") != 0; | term_has_meta = TGETFLAG ("km"); |
if (term_has_meta == 0) |
if (term_has_meta == 0) |
_rl_term_mm = _rl_term_mo = (char *)NULL; |
_rl_term_mm = _rl_term_mo = (char *)NULL; |
#endif /* !__MSDOS__ */ |
#endif /* !__MSDOS__ */ |
Line 580 _rl_init_terminal_io (terminal_name)
|
Line 601 _rl_init_terminal_io (terminal_name)
|
bind_termcap_arrow_keys (vi_insertion_keymap); |
bind_termcap_arrow_keys (vi_insertion_keymap); |
#endif /* VI_MODE */ |
#endif /* VI_MODE */ |
|
|
|
/* There's no way to determine whether or not a given terminal supports |
|
bracketed paste mode, so we assume a terminal named "dumb" does not. */ |
|
if (dumbterm) |
|
_rl_enable_bracketed_paste = 0; |
|
|
return 0; |
return 0; |
} |
} |
|
|
/* Bind the arrow key sequences from the termcap description in MAP. */ |
/* Bind the arrow key sequences from the termcap description in MAP. */ |
static void |
static void |
bind_termcap_arrow_keys (map) | bind_termcap_arrow_keys (Keymap map) |
Keymap map; | |
{ |
{ |
Keymap xkeymap; |
Keymap xkeymap; |
|
|
Line 602 bind_termcap_arrow_keys (map)
|
Line 627 bind_termcap_arrow_keys (map)
|
rl_bind_keyseq_if_unbound (_rl_term_at7, rl_end_of_line); /* End */ |
rl_bind_keyseq_if_unbound (_rl_term_at7, rl_end_of_line); /* End */ |
|
|
rl_bind_keyseq_if_unbound (_rl_term_kD, rl_delete); |
rl_bind_keyseq_if_unbound (_rl_term_kD, rl_delete); |
|
rl_bind_keyseq_if_unbound (_rl_term_kI, rl_overwrite_mode); /* Insert */ |
|
|
_rl_keymap = xkeymap; |
_rl_keymap = xkeymap; |
} |
} |
|
|
char * |
char * |
rl_get_termcap (cap) | rl_get_termcap (const char *cap) |
const char *cap; | |
{ |
{ |
register int i; |
register int i; |
|
|
Line 625 rl_get_termcap (cap)
|
Line 650 rl_get_termcap (cap)
|
/* Re-initialize the terminal considering that the TERM/TERMCAP variable |
/* Re-initialize the terminal considering that the TERM/TERMCAP variable |
has changed. */ |
has changed. */ |
int |
int |
rl_reset_terminal (terminal_name) | rl_reset_terminal (const char *terminal_name) |
const char *terminal_name; | |
{ |
{ |
_rl_screenwidth = _rl_screenheight = 0; |
_rl_screenwidth = _rl_screenheight = 0; |
_rl_init_terminal_io (terminal_name); |
_rl_init_terminal_io (terminal_name); |
Line 636 rl_reset_terminal (terminal_name)
|
Line 660 rl_reset_terminal (terminal_name)
|
/* A function for the use of tputs () */ |
/* A function for the use of tputs () */ |
#ifdef _MINIX |
#ifdef _MINIX |
void |
void |
_rl_output_character_function (c) | _rl_output_character_function (int c) |
int c; | |
{ |
{ |
putc (c, _rl_out_stream); |
putc (c, _rl_out_stream); |
} |
} |
#else /* !_MINIX */ |
#else /* !_MINIX */ |
int |
int |
_rl_output_character_function (c) | _rl_output_character_function (int c) |
int c; | |
{ |
{ |
return putc (c, _rl_out_stream); |
return putc (c, _rl_out_stream); |
} |
} |
Line 652 _rl_output_character_function (c)
|
Line 674 _rl_output_character_function (c)
|
|
|
/* Write COUNT characters from STRING to the output stream. */ |
/* Write COUNT characters from STRING to the output stream. */ |
void |
void |
_rl_output_some_chars (string, count) | _rl_output_some_chars (const char *string, int count) |
const char *string; | |
int count; | |
{ |
{ |
fwrite (string, 1, count, _rl_out_stream); |
fwrite (string, 1, count, _rl_out_stream); |
} |
} |
|
|
/* Move the cursor back. */ |
/* Move the cursor back. */ |
int |
int |
_rl_backspace (count) | _rl_backspace (int count) |
int count; | |
{ |
{ |
register int i; |
register int i; |
|
|
Line 679 _rl_backspace (count)
|
Line 698 _rl_backspace (count)
|
|
|
/* Move to the start of the next line. */ |
/* Move to the start of the next line. */ |
int |
int |
rl_crlf () | rl_crlf (void) |
{ |
{ |
#if defined (NEW_TTY_DRIVER) || defined (__MINT__) |
#if defined (NEW_TTY_DRIVER) || defined (__MINT__) |
if (_rl_term_cr) |
if (_rl_term_cr) |
Line 689 rl_crlf ()
|
Line 708 rl_crlf ()
|
return 0; |
return 0; |
} |
} |
|
|
|
void |
|
_rl_cr (void) |
|
{ |
|
#if defined (__MSDOS__) |
|
putc ('\r', rl_outstream); |
|
#else |
|
tputs (_rl_term_cr, 1, _rl_output_character_function); |
|
#endif |
|
} |
|
|
/* Ring the terminal bell. */ |
/* Ring the terminal bell. */ |
int |
int |
rl_ding () | rl_ding (void) |
{ |
{ |
if (_rl_echoing_p) |
if (_rl_echoing_p) |
{ |
{ |
Line 723 rl_ding ()
|
Line 752 rl_ding ()
|
|
|
/* **************************************************************** */ |
/* **************************************************************** */ |
/* */ |
/* */ |
|
/* Entering and leaving terminal standout mode */ |
|
/* */ |
|
/* **************************************************************** */ |
|
|
|
void |
|
_rl_standout_on (void) |
|
{ |
|
#ifndef __MSDOS__ |
|
if (_rl_term_so && _rl_term_se) |
|
tputs (_rl_term_so, 1, _rl_output_character_function); |
|
#endif |
|
} |
|
|
|
void |
|
_rl_standout_off (void) |
|
{ |
|
#ifndef __MSDOS__ |
|
if (_rl_term_so && _rl_term_se) |
|
tputs (_rl_term_se, 1, _rl_output_character_function); |
|
#endif |
|
} |
|
|
|
/* **************************************************************** */ |
|
/* */ |
/* Controlling the Meta Key and Keypad */ |
/* Controlling the Meta Key and Keypad */ |
/* */ |
/* */ |
/* **************************************************************** */ |
/* **************************************************************** */ |
Line 730 rl_ding ()
|
Line 783 rl_ding ()
|
static int enabled_meta = 0; /* flag indicating we enabled meta mode */ |
static int enabled_meta = 0; /* flag indicating we enabled meta mode */ |
|
|
void |
void |
_rl_enable_meta_key () | _rl_enable_meta_key (void) |
{ |
{ |
#if !defined (__DJGPP__) |
#if !defined (__DJGPP__) |
if (term_has_meta && _rl_term_mm) |
if (term_has_meta && _rl_term_mm) |
Line 742 _rl_enable_meta_key ()
|
Line 795 _rl_enable_meta_key ()
|
} |
} |
|
|
void |
void |
_rl_disable_meta_key () | _rl_disable_meta_key (void) |
{ |
{ |
#if !defined (__DJGPP__) |
#if !defined (__DJGPP__) |
if (term_has_meta && _rl_term_mo && enabled_meta) |
if (term_has_meta && _rl_term_mo && enabled_meta) |
Line 754 _rl_disable_meta_key ()
|
Line 807 _rl_disable_meta_key ()
|
} |
} |
|
|
void |
void |
_rl_control_keypad (on) | _rl_control_keypad (int on) |
int on; | |
{ |
{ |
#if !defined (__DJGPP__) |
#if !defined (__DJGPP__) |
if (on && _rl_term_ks) |
if (on && _rl_term_ks) |
Line 776 _rl_control_keypad (on)
|
Line 828 _rl_control_keypad (on)
|
cursor. Overwrite mode gets a very visible cursor. Only does |
cursor. Overwrite mode gets a very visible cursor. Only does |
anything if we have both capabilities. */ |
anything if we have both capabilities. */ |
void |
void |
_rl_set_cursor (im, force) | _rl_set_cursor (int im, int force) |
int im, force; | |
{ |
{ |
#ifndef __MSDOS__ |
#ifndef __MSDOS__ |
if (_rl_term_ve && _rl_term_vs) |
if (_rl_term_ve && _rl_term_vs) |