1136758Speter/* $FreeBSD: releng/10.2/contrib/libreadline/terminal.c 165675 2006-12-31 09:22:31Z ache $ */ 221308Sache/* terminal.c -- controlling the terminal with termcap. */ 321308Sache 4165675Sache/* Copyright (C) 1996-2006 Free Software Foundation, Inc. 521308Sache 621308Sache This file is part of the GNU Readline Library, a library for 721308Sache reading lines of text with interactive input and history editing. 821308Sache 921308Sache The GNU Readline Library is free software; you can redistribute it 1021308Sache and/or modify it under the terms of the GNU General Public License 1158314Sache as published by the Free Software Foundation; either version 2, or 1221308Sache (at your option) any later version. 1321308Sache 1421308Sache The GNU Readline Library is distributed in the hope that it will be 1521308Sache useful, but WITHOUT ANY WARRANTY; without even the implied warranty 1621308Sache of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1721308Sache GNU General Public License for more details. 1821308Sache 1921308Sache The GNU General Public License is often shipped with GNU software, and 2021308Sache is generally kept in a file called COPYING or LICENSE. If you do not 2121308Sache have a copy of the license, write to the Free Software Foundation, 2258314Sache 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ 2321308Sache#define READLINE_LIBRARY 2421308Sache 2521308Sache#if defined (HAVE_CONFIG_H) 2621308Sache# include <config.h> 2721308Sache#endif 2821308Sache 2921308Sache#include <sys/types.h> 3021308Sache#include "posixstat.h" 3121308Sache#include <fcntl.h> 3221308Sache#if defined (HAVE_SYS_FILE_H) 3321308Sache# include <sys/file.h> 3421308Sache#endif /* HAVE_SYS_FILE_H */ 3521308Sache 3621308Sache#if defined (HAVE_UNISTD_H) 3721308Sache# include <unistd.h> 3821308Sache#endif /* HAVE_UNISTD_H */ 3921308Sache 4021308Sache#if defined (HAVE_STDLIB_H) 4121308Sache# include <stdlib.h> 4221308Sache#else 4321308Sache# include "ansi_stdlib.h" 4421308Sache#endif /* HAVE_STDLIB_H */ 4521308Sache 4621308Sache#if defined (HAVE_LOCALE_H) 4721308Sache# include <locale.h> 4821308Sache#endif 4921308Sache 5021308Sache#include <stdio.h> 5121308Sache 5221308Sache/* System-specific feature definitions and include files. */ 5321308Sache#include "rldefs.h" 5421308Sache 5526497Sache#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ) 5626497Sache# include <sys/ioctl.h> 5726497Sache#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */ 5826497Sache 5926497Sache#include "rltty.h" 6021308Sache#include "tcap.h" 6121308Sache 6221308Sache/* Some standard library routines. */ 6321308Sache#include "readline.h" 6421308Sache#include "history.h" 6521308Sache 6658314Sache#include "rlprivate.h" 6758314Sache#include "rlshell.h" 68119614Sache#include "xmalloc.h" 6921308Sache 70165675Sache#if defined (__MINGW32__) 71165675Sache# include <windows.h> 72165675Sache# include <wincon.h> 73165675Sache 74165675Sachestatic void _win_get_screensize PARAMS((int *, int *)); 75165675Sache#endif 76165675Sache 77165675Sache#if defined (__EMX__) 78165675Sachestatic void _emx_get_screensize PARAMS((int *, int *)); 79165675Sache#endif 80165675Sache 81119614Sache#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay) 82119614Sache#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc) 83119614Sache 84165675Sache/* If the calling application sets this to a non-zero value, readline will 85165675Sache use the $LINES and $COLUMNS environment variables to set its idea of the 86165675Sache window size before interrogating the kernel. */ 87165675Sacheint rl_prefer_env_winsize = 0; 88157188Sache 8921308Sache/* **************************************************************** */ 9021308Sache/* */ 9121308Sache/* Terminal and Termcap */ 9221308Sache/* */ 9321308Sache/* **************************************************************** */ 9421308Sache 9521308Sachestatic char *term_buffer = (char *)NULL; 9621308Sachestatic char *term_string_buffer = (char *)NULL; 9721308Sache 9821308Sachestatic int tcap_initialized; 9921308Sache 10021308Sache#if !defined (__linux__) 10126497Sache# if defined (__EMX__) || defined (NEED_EXTERN_PC) 10226497Sacheextern 10326497Sache# endif /* __EMX__ || NEED_EXTERN_PC */ 10426497Sachechar PC, *BC, *UP; 10521308Sache#endif /* __linux__ */ 10621308Sache 10721308Sache/* Some strings to control terminal actions. These are output by tputs (). */ 10875409Sachechar *_rl_term_clreol; 10975409Sachechar *_rl_term_clrpag; 11075409Sachechar *_rl_term_cr; 11175409Sachechar *_rl_term_backspace; 11275409Sachechar *_rl_term_goto; 11375409Sachechar *_rl_term_pc; 11421308Sache 11521308Sache/* Non-zero if we determine that the terminal can do character insertion. */ 11675409Sacheint _rl_terminal_can_insert = 0; 11721308Sache 11821308Sache/* How to insert characters. */ 11975409Sachechar *_rl_term_im; 12075409Sachechar *_rl_term_ei; 12175409Sachechar *_rl_term_ic; 12275409Sachechar *_rl_term_ip; 12375409Sachechar *_rl_term_IC; 12421308Sache 12521308Sache/* How to delete characters. */ 12675409Sachechar *_rl_term_dc; 12775409Sachechar *_rl_term_DC; 12821308Sache 12975409Sachechar *_rl_term_forward_char; 13021308Sache 13121308Sache/* How to go up a line. */ 13275409Sachechar *_rl_term_up; 13321308Sache 13475409Sache/* A visible bell; char if the terminal can be made to flash the screen. */ 13575409Sachestatic char *_rl_visible_bell; 13621308Sache 13721308Sache/* Non-zero means the terminal can auto-wrap lines. */ 138157195Sacheint _rl_term_autowrap = -1; 13921308Sache 14021308Sache/* Non-zero means that this terminal has a meta key. */ 14121308Sachestatic int term_has_meta; 14221308Sache 14321308Sache/* The sequences to write to turn on and off the meta key, if this 14475409Sache terminal has one. */ 14575409Sachestatic char *_rl_term_mm; 14675409Sachestatic char *_rl_term_mo; 14721308Sache 14821308Sache/* The key sequences output by the arrow keys, if this terminal has any. */ 14975409Sachestatic char *_rl_term_ku; 15075409Sachestatic char *_rl_term_kd; 15175409Sachestatic char *_rl_term_kr; 15275409Sachestatic char *_rl_term_kl; 15321308Sache 15421308Sache/* How to initialize and reset the arrow keys, if this terminal has any. */ 15575409Sachestatic char *_rl_term_ks; 15675409Sachestatic char *_rl_term_ke; 15721308Sache 15821308Sache/* The key sequences sent by the Home and End keys, if any. */ 15975409Sachestatic char *_rl_term_kh; 16075409Sachestatic char *_rl_term_kH; 161119614Sachestatic char *_rl_term_at7; /* @7 */ 16221308Sache 163157188Sache/* Delete key */ 164157188Sachestatic char *_rl_term_kD; 165157188Sache 166119614Sache/* Insert key */ 167119614Sachestatic char *_rl_term_kI; 168119614Sache 169119614Sache/* Cursor control */ 170119614Sachestatic char *_rl_term_vs; /* very visible */ 171119614Sachestatic char *_rl_term_ve; /* normal */ 172119614Sache 173119614Sachestatic void bind_termcap_arrow_keys PARAMS((Keymap)); 174119614Sache 17521308Sache/* Variables that hold the screen dimensions, used by the display code. */ 17675409Sacheint _rl_screenwidth, _rl_screenheight, _rl_screenchars; 17721308Sache 17821308Sache/* Non-zero means the user wants to enable the keypad. */ 17921308Sacheint _rl_enable_keypad; 18021308Sache 18121308Sache/* Non-zero means the user wants to enable a meta key. */ 18221308Sacheint _rl_enable_meta = 1; 18321308Sache 18458314Sache#if defined (__EMX__) 18558314Sachestatic void 18658314Sache_emx_get_screensize (swp, shp) 18758314Sache int *swp, *shp; 18858314Sache{ 18958314Sache int sz[2]; 19058314Sache 19158314Sache _scrsize (sz); 19258314Sache 19358314Sache if (swp) 19458314Sache *swp = sz[0]; 19558314Sache if (shp) 19658314Sache *shp = sz[1]; 19758314Sache} 19858314Sache#endif 19958314Sache 200165675Sache#if defined (__MINGW32__) 201165675Sachestatic void 202165675Sache_win_get_screensize (swp, shp) 203165675Sache int *swp, *shp; 204165675Sache{ 205165675Sache HANDLE hConOut; 206165675Sache CONSOLE_SCREEN_BUFFER_INFO scr; 207165675Sache 208165675Sache hConOut = GetStdHandle (STD_OUTPUT_HANDLE); 209165675Sache if (hConOut != INVALID_HANDLE_VALUE) 210165675Sache { 211165675Sache if (GetConsoleScreenBufferInfo (hConOut, &scr)) 212165675Sache { 213165675Sache *swp = scr.dwSize.X; 214165675Sache *shp = scr.srWindow.Bottom - scr.srWindow.Top + 1; 215165675Sache } 216165675Sache } 217165675Sache} 218165675Sache#endif 219165675Sache 22021308Sache/* Get readline's idea of the screen size. TTY is a file descriptor open 22121308Sache to the terminal. If IGNORE_ENV is true, we do not pay attention to the 22221308Sache values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being 22321308Sache non-null serve to check whether or not we have initialized termcap. */ 22421308Sachevoid 22521308Sache_rl_get_screen_size (tty, ignore_env) 22621308Sache int tty, ignore_env; 22721308Sache{ 22821308Sache char *ss; 22921308Sache#if defined (TIOCGWINSZ) 23021308Sache struct winsize window_size; 23121308Sache#endif /* TIOCGWINSZ */ 232157188Sache int wr, wc; 23321308Sache 234157188Sache wr = wc = -1; 23521308Sache#if defined (TIOCGWINSZ) 23621308Sache if (ioctl (tty, TIOCGWINSZ, &window_size) == 0) 23721308Sache { 238157188Sache wc = (int) window_size.ws_col; 239157188Sache wr = (int) window_size.ws_row; 24021308Sache } 24121308Sache#endif /* TIOCGWINSZ */ 24221308Sache 24326497Sache#if defined (__EMX__) 244165675Sache _emx_get_screensize (&wc, &wr); 245165675Sache#elif defined (__MINGW32__) 246165675Sache _win_get_screensize (&wc, &wr); 24726497Sache#endif 24826497Sache 249157188Sache if (ignore_env || rl_prefer_env_winsize == 0) 250157188Sache { 251157188Sache _rl_screenwidth = wc; 252157188Sache _rl_screenheight = wr; 253157188Sache } 254157188Sache else 255157188Sache _rl_screenwidth = _rl_screenheight = -1; 256157188Sache 25721308Sache /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV 258157188Sache is unset. If we prefer the environment, check it first before 259157188Sache assigning the value returned by the kernel. */ 26075409Sache if (_rl_screenwidth <= 0) 26121308Sache { 26275409Sache if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS"))) 26375409Sache _rl_screenwidth = atoi (ss); 26421308Sache 265157188Sache if (_rl_screenwidth <= 0) 266157188Sache _rl_screenwidth = wc; 267157188Sache 26858314Sache#if !defined (__DJGPP__) 26975409Sache if (_rl_screenwidth <= 0 && term_string_buffer) 27075409Sache _rl_screenwidth = tgetnum ("co"); 27158314Sache#endif 27221308Sache } 27321308Sache 27421308Sache /* Environment variable LINES overrides setting of "li" if IGNORE_ENV 27521308Sache is unset. */ 27675409Sache if (_rl_screenheight <= 0) 27721308Sache { 27875409Sache if (ignore_env == 0 && (ss = sh_get_env_value ("LINES"))) 27975409Sache _rl_screenheight = atoi (ss); 28021308Sache 281157188Sache if (_rl_screenheight <= 0) 282157188Sache _rl_screenheight = wr; 283157188Sache 28458314Sache#if !defined (__DJGPP__) 28575409Sache if (_rl_screenheight <= 0 && term_string_buffer) 28675409Sache _rl_screenheight = tgetnum ("li"); 28758314Sache#endif 28821308Sache } 28921308Sache 29021308Sache /* If all else fails, default to 80x24 terminal. */ 29175409Sache if (_rl_screenwidth <= 1) 29275409Sache _rl_screenwidth = 80; 29321308Sache 29475409Sache if (_rl_screenheight <= 0) 29575409Sache _rl_screenheight = 24; 29621308Sache 29721308Sache /* If we're being compiled as part of bash, set the environment 29821308Sache variables $LINES and $COLUMNS to new values. Otherwise, just 29921308Sache do a pair of putenv () or setenv () calls. */ 30075409Sache sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth); 30121308Sache 30258314Sache if (_rl_term_autowrap == 0) 30375409Sache _rl_screenwidth--; 30421308Sache 30575409Sache _rl_screenchars = _rl_screenwidth * _rl_screenheight; 30621308Sache} 30721308Sache 30821308Sachevoid 30921308Sache_rl_set_screen_size (rows, cols) 31021308Sache int rows, cols; 31121308Sache{ 312157195Sache if (_rl_term_autowrap == -1) 313157195Sache _rl_init_terminal_io (rl_terminal_name); 314157195Sache 315157188Sache if (rows > 0) 316157188Sache _rl_screenheight = rows; 317157188Sache if (cols > 0) 318157188Sache { 319157188Sache _rl_screenwidth = cols; 320157188Sache if (_rl_term_autowrap == 0) 321157188Sache _rl_screenwidth--; 322157188Sache } 32321308Sache 324157188Sache if (rows > 0 || cols > 0) 325157188Sache _rl_screenchars = _rl_screenwidth * _rl_screenheight; 32621308Sache} 32721308Sache 32847558Sachevoid 32975409Sacherl_set_screen_size (rows, cols) 33075409Sache int rows, cols; 33175409Sache{ 33275409Sache _rl_set_screen_size (rows, cols); 33375409Sache} 33475409Sache 33575409Sachevoid 33675409Sacherl_get_screen_size (rows, cols) 33775409Sache int *rows, *cols; 33875409Sache{ 33975409Sache if (rows) 34075409Sache *rows = _rl_screenheight; 34175409Sache if (cols) 34275409Sache *cols = _rl_screenwidth; 34375409Sache} 344157188Sache 345157188Sachevoid 346157188Sacherl_reset_screen_size () 347157188Sache{ 348157188Sache _rl_get_screen_size (fileno (rl_instream), 0); 349157188Sache} 35075409Sache 35175409Sachevoid 35247558Sacherl_resize_terminal () 35347558Sache{ 35447558Sache if (readline_echoing_p) 35547558Sache { 35647558Sache _rl_get_screen_size (fileno (rl_instream), 1); 357119614Sache if (CUSTOM_REDISPLAY_FUNC ()) 358119614Sache rl_forced_update_display (); 359119614Sache else 360119614Sache _rl_redisplay_after_sigwinch (); 36147558Sache } 36247558Sache} 36347558Sache 36421308Sachestruct _tc_string { 36575409Sache const char *tc_var; 36621308Sache char **tc_value; 36721308Sache}; 36821308Sache 36921308Sache/* This should be kept sorted, just in case we decide to change the 37021308Sache search algorithm to something smarter. */ 37121308Sachestatic struct _tc_string tc_strings[] = 37221308Sache{ 373119614Sache { "@7", &_rl_term_at7 }, 37475409Sache { "DC", &_rl_term_DC }, 37575409Sache { "IC", &_rl_term_IC }, 37675409Sache { "ce", &_rl_term_clreol }, 37775409Sache { "cl", &_rl_term_clrpag }, 37875409Sache { "cr", &_rl_term_cr }, 37975409Sache { "dc", &_rl_term_dc }, 38075409Sache { "ei", &_rl_term_ei }, 38175409Sache { "ic", &_rl_term_ic }, 38275409Sache { "im", &_rl_term_im }, 383157188Sache { "kD", &_rl_term_kD }, /* delete */ 384119614Sache { "kH", &_rl_term_kH }, /* home down ?? */ 385119614Sache { "kI", &_rl_term_kI }, /* insert */ 38675409Sache { "kd", &_rl_term_kd }, 387119614Sache { "ke", &_rl_term_ke }, /* end keypad mode */ 38875409Sache { "kh", &_rl_term_kh }, /* home */ 38975409Sache { "kl", &_rl_term_kl }, 39075409Sache { "kr", &_rl_term_kr }, 391119614Sache { "ks", &_rl_term_ks }, /* start keypad mode */ 39275409Sache { "ku", &_rl_term_ku }, 39375409Sache { "le", &_rl_term_backspace }, 39475409Sache { "mm", &_rl_term_mm }, 39575409Sache { "mo", &_rl_term_mo }, 39675409Sache { "nd", &_rl_term_forward_char }, 39775409Sache { "pc", &_rl_term_pc }, 39875409Sache { "up", &_rl_term_up }, 39975409Sache { "vb", &_rl_visible_bell }, 400119614Sache { "vs", &_rl_term_vs }, 401119614Sache { "ve", &_rl_term_ve }, 40221308Sache}; 40321308Sache 40421308Sache#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string)) 40521308Sache 40621308Sache/* Read the desired terminal capability strings into BP. The capabilities 40721308Sache are described in the TC_STRINGS table. */ 40821308Sachestatic void 40921308Sacheget_term_capabilities (bp) 41021308Sache char **bp; 41121308Sache{ 41258314Sache#if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */ 41321308Sache register int i; 41421308Sache 41521308Sache for (i = 0; i < NUM_TC_STRINGS; i++) 416119614Sache *(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp); 41758314Sache#endif 41821308Sache tcap_initialized = 1; 41921308Sache} 42021308Sache 42121308Sacheint 42221308Sache_rl_init_terminal_io (terminal_name) 42375409Sache const char *terminal_name; 42421308Sache{ 42575409Sache const char *term; 42675409Sache char *buffer; 42758314Sache int tty, tgetent_ret; 42821308Sache 42975409Sache term = terminal_name ? terminal_name : sh_get_env_value ("TERM"); 43075409Sache _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL; 43158314Sache tty = rl_instream ? fileno (rl_instream) : 0; 43221308Sache 43358314Sache if (term == 0) 43458314Sache term = "dumb"; 43521308Sache 43658314Sache /* I've separated this out for later work on not calling tgetent at all 43758314Sache if the calling application has supplied a custom redisplay function, 43858314Sache (and possibly if the application has supplied a custom input function). */ 43958314Sache if (CUSTOM_REDISPLAY_FUNC()) 44058314Sache { 44158314Sache tgetent_ret = -1; 44258314Sache } 44358314Sache else 44458314Sache { 44558314Sache if (term_string_buffer == 0) 446119614Sache term_string_buffer = (char *)xmalloc(2032); 44721308Sache 44858314Sache if (term_buffer == 0) 449119614Sache term_buffer = (char *)xmalloc(4080); 45021308Sache 45158314Sache buffer = term_string_buffer; 45221308Sache 45358314Sache tgetent_ret = tgetent (term_buffer, term); 45458314Sache } 45521308Sache 45658314Sache if (tgetent_ret <= 0) 45721308Sache { 45858314Sache FREE (term_string_buffer); 45958314Sache FREE (term_buffer); 46058314Sache buffer = term_buffer = term_string_buffer = (char *)NULL; 46158314Sache 46258314Sache _rl_term_autowrap = 0; /* used by _rl_get_screen_size */ 46358314Sache 464157188Sache /* Allow calling application to set default height and width, using 465157188Sache rl_set_screen_size */ 466157188Sache if (_rl_screenwidth <= 0 || _rl_screenheight <= 0) 467157188Sache { 46858314Sache#if defined (__EMX__) 469157188Sache _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight); 470157188Sache _rl_screenwidth--; 47158314Sache#else /* !__EMX__ */ 472157188Sache _rl_get_screen_size (tty, 0); 47358314Sache#endif /* !__EMX__ */ 474157188Sache } 47558314Sache 47658314Sache /* Defaults. */ 47775409Sache if (_rl_screenwidth <= 0 || _rl_screenheight <= 0) 47858314Sache { 47975409Sache _rl_screenwidth = 79; 48075409Sache _rl_screenheight = 24; 48158314Sache } 48258314Sache 48358314Sache /* Everything below here is used by the redisplay code (tputs). */ 48475409Sache _rl_screenchars = _rl_screenwidth * _rl_screenheight; 48575409Sache _rl_term_cr = "\r"; 48675409Sache _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL; 48775409Sache _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL; 48875409Sache _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL; 489157188Sache _rl_term_kh = _rl_term_kH = _rl_term_kI = _rl_term_kD = (char *)NULL; 490119614Sache _rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL; 49175409Sache _rl_term_mm = _rl_term_mo = (char *)NULL; 492119614Sache _rl_term_ve = _rl_term_vs = (char *)NULL; 493165675Sache _rl_term_forward_char = (char *)NULL; 49475409Sache _rl_terminal_can_insert = term_has_meta = 0; 49558314Sache 49658314Sache /* Reasonable defaults for tgoto(). Readline currently only uses 49775409Sache tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we 49858314Sache change that later... */ 49958314Sache PC = '\0'; 50075409Sache BC = _rl_term_backspace = "\b"; 50175409Sache UP = _rl_term_up; 50258314Sache 50321308Sache return 0; 50421308Sache } 50521308Sache 50621308Sache get_term_capabilities (&buffer); 50721308Sache 50821308Sache /* Set up the variables that the termcap library expects the application 50921308Sache to provide. */ 51075409Sache PC = _rl_term_pc ? *_rl_term_pc : 0; 51175409Sache BC = _rl_term_backspace; 51275409Sache UP = _rl_term_up; 51321308Sache 51475409Sache if (!_rl_term_cr) 51575409Sache _rl_term_cr = "\r"; 51621308Sache 51721308Sache _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn"); 51821308Sache 519157188Sache /* Allow calling application to set default height and width, using 520157188Sache rl_set_screen_size */ 521157188Sache if (_rl_screenwidth <= 0 || _rl_screenheight <= 0) 522157188Sache _rl_get_screen_size (tty, 0); 52321308Sache 52421308Sache /* "An application program can assume that the terminal can do 52521308Sache character insertion if *any one of* the capabilities `IC', 52621308Sache `im', `ic' or `ip' is provided." But we can't do anything if 52721308Sache only `ip' is provided, so... */ 52875409Sache _rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic); 52921308Sache 53021308Sache /* Check to see if this terminal has a meta key and clear the capability 53121308Sache variables if there is none. */ 53221308Sache term_has_meta = (tgetflag ("km") || tgetflag ("MT")); 53321308Sache if (!term_has_meta) 53475409Sache _rl_term_mm = _rl_term_mo = (char *)NULL; 53521308Sache 53621308Sache /* Attempt to find and bind the arrow keys. Do not override already 53721308Sache bound keys in an overzealous attempt, however. */ 53821308Sache 539119614Sache bind_termcap_arrow_keys (emacs_standard_keymap); 54021308Sache 541119614Sache#if defined (VI_MODE) 542119614Sache bind_termcap_arrow_keys (vi_movement_keymap); 543119614Sache bind_termcap_arrow_keys (vi_insertion_keymap); 544119614Sache#endif /* VI_MODE */ 54521308Sache 546119614Sache return 0; 547119614Sache} 548119614Sache 549119614Sache/* Bind the arrow key sequences from the termcap description in MAP. */ 550119614Sachestatic void 551119614Sachebind_termcap_arrow_keys (map) 552119614Sache Keymap map; 553119614Sache{ 554119614Sache Keymap xkeymap; 555119614Sache 556119614Sache xkeymap = _rl_keymap; 557119614Sache _rl_keymap = map; 558119614Sache 559136758Speter rl_bind_keyseq_if_unbound (_rl_term_ku, rl_get_previous_history); 560136758Speter rl_bind_keyseq_if_unbound (_rl_term_kd, rl_get_next_history); 561136758Speter rl_bind_keyseq_if_unbound (_rl_term_kr, rl_forward_char); 562136758Speter rl_bind_keyseq_if_unbound (_rl_term_kl, rl_backward_char); 56321308Sache 564136758Speter rl_bind_keyseq_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */ 565136758Speter rl_bind_keyseq_if_unbound (_rl_term_at7, rl_end_of_line); /* End */ 56621308Sache 567157188Sache rl_bind_keyseq_if_unbound (_rl_term_kD, rl_delete); 568157188Sache 56921308Sache _rl_keymap = xkeymap; 57021308Sache} 57121308Sache 57221308Sachechar * 57321308Sacherl_get_termcap (cap) 57475409Sache const char *cap; 57521308Sache{ 57621308Sache register int i; 57721308Sache 57821308Sache if (tcap_initialized == 0) 57921308Sache return ((char *)NULL); 58021308Sache for (i = 0; i < NUM_TC_STRINGS; i++) 58121308Sache { 58221308Sache if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0) 58321308Sache return *(tc_strings[i].tc_value); 58421308Sache } 58521308Sache return ((char *)NULL); 58621308Sache} 58721308Sache 58826497Sache/* Re-initialize the terminal considering that the TERM/TERMCAP variable 58926497Sache has changed. */ 59026497Sacheint 59126497Sacherl_reset_terminal (terminal_name) 59275409Sache const char *terminal_name; 59326497Sache{ 594157188Sache _rl_screenwidth = _rl_screenheight = 0; 59526497Sache _rl_init_terminal_io (terminal_name); 59626497Sache return 0; 59726497Sache} 59826497Sache 59921308Sache/* A function for the use of tputs () */ 60035486Sache#ifdef _MINIX 60135486Sachevoid 60235486Sache_rl_output_character_function (c) 60335486Sache int c; 60435486Sache{ 60535486Sache putc (c, _rl_out_stream); 60635486Sache} 60735486Sache#else /* !_MINIX */ 60821308Sacheint 60921308Sache_rl_output_character_function (c) 61021308Sache int c; 61121308Sache{ 61221308Sache return putc (c, _rl_out_stream); 61321308Sache} 61435486Sache#endif /* !_MINIX */ 61558314Sache 61621308Sache/* Write COUNT characters from STRING to the output stream. */ 61721308Sachevoid 61821308Sache_rl_output_some_chars (string, count) 61975409Sache const char *string; 62021308Sache int count; 62121308Sache{ 62221308Sache fwrite (string, 1, count, _rl_out_stream); 62321308Sache} 62421308Sache 62521308Sache/* Move the cursor back. */ 62621308Sacheint 62721308Sache_rl_backspace (count) 62821308Sache int count; 62921308Sache{ 63021308Sache register int i; 63121308Sache 63275409Sache if (_rl_term_backspace) 63321308Sache for (i = 0; i < count; i++) 63475409Sache tputs (_rl_term_backspace, 1, _rl_output_character_function); 63521308Sache else 63621308Sache for (i = 0; i < count; i++) 63721308Sache putc ('\b', _rl_out_stream); 63821308Sache return 0; 63921308Sache} 64021308Sache 64121308Sache/* Move to the start of the next line. */ 64221308Sacheint 64375409Sacherl_crlf () 64421308Sache{ 64521308Sache#if defined (NEW_TTY_DRIVER) 64675409Sache if (_rl_term_cr) 64775409Sache tputs (_rl_term_cr, 1, _rl_output_character_function); 64821308Sache#endif /* NEW_TTY_DRIVER */ 64921308Sache putc ('\n', _rl_out_stream); 65021308Sache return 0; 65121308Sache} 65221308Sache 65321308Sache/* Ring the terminal bell. */ 65421308Sacheint 65575409Sacherl_ding () 65621308Sache{ 65721308Sache if (readline_echoing_p) 65821308Sache { 65921308Sache switch (_rl_bell_preference) 66021308Sache { 66121308Sache case NO_BELL: 66221308Sache default: 66321308Sache break; 66421308Sache case VISIBLE_BELL: 66575409Sache if (_rl_visible_bell) 66621308Sache { 66775409Sache tputs (_rl_visible_bell, 1, _rl_output_character_function); 66821308Sache break; 66921308Sache } 67021308Sache /* FALLTHROUGH */ 67121308Sache case AUDIBLE_BELL: 67221308Sache fprintf (stderr, "\007"); 67321308Sache fflush (stderr); 67421308Sache break; 67521308Sache } 67621308Sache return (0); 67721308Sache } 67821308Sache return (-1); 67921308Sache} 68021308Sache 68121308Sache/* **************************************************************** */ 68221308Sache/* */ 68321308Sache/* Controlling the Meta Key and Keypad */ 68421308Sache/* */ 68521308Sache/* **************************************************************** */ 68621308Sache 68726497Sachevoid 68821308Sache_rl_enable_meta_key () 68921308Sache{ 69058314Sache#if !defined (__DJGPP__) 69175409Sache if (term_has_meta && _rl_term_mm) 69275409Sache tputs (_rl_term_mm, 1, _rl_output_character_function); 69358314Sache#endif 69421308Sache} 69521308Sache 69621308Sachevoid 69721308Sache_rl_control_keypad (on) 69821308Sache int on; 69921308Sache{ 70058314Sache#if !defined (__DJGPP__) 70175409Sache if (on && _rl_term_ks) 70275409Sache tputs (_rl_term_ks, 1, _rl_output_character_function); 70375409Sache else if (!on && _rl_term_ke) 70475409Sache tputs (_rl_term_ke, 1, _rl_output_character_function); 70558314Sache#endif 70621308Sache} 707119614Sache 708119614Sache/* **************************************************************** */ 709119614Sache/* */ 710119614Sache/* Controlling the Cursor */ 711119614Sache/* */ 712119614Sache/* **************************************************************** */ 713119614Sache 714119614Sache/* Set the cursor appropriately depending on IM, which is one of the 715119614Sache insert modes (insert or overwrite). Insert mode gets the normal 716119614Sache cursor. Overwrite mode gets a very visible cursor. Only does 717119614Sache anything if we have both capabilities. */ 718119614Sachevoid 719119614Sache_rl_set_cursor (im, force) 720119614Sache int im, force; 721119614Sache{ 722119614Sache if (_rl_term_ve && _rl_term_vs) 723119614Sache { 724119614Sache if (force || im != rl_insert_mode) 725119614Sache { 726119614Sache if (im == RL_IM_OVERWRITE) 727119614Sache tputs (_rl_term_vs, 1, _rl_output_character_function); 728119614Sache else 729119614Sache tputs (_rl_term_ve, 1, _rl_output_character_function); 730119614Sache } 731119614Sache } 732119614Sache} 733