terminal.c revision 157188
1136758Speter/* $FreeBSD: head/contrib/libreadline/terminal.c 157188 2006-03-27 23:11:32Z ache $ */ 221308Sache/* terminal.c -- controlling the terminal with termcap. */ 321308Sache 4157188Sache/* Copyright (C) 1996-2005 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 70119614Sache#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay) 71119614Sache#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc) 72119614Sache 73157188Sacheint rl_prefer_env_winsize; 74157188Sache 7521308Sache/* **************************************************************** */ 7621308Sache/* */ 7721308Sache/* Terminal and Termcap */ 7821308Sache/* */ 7921308Sache/* **************************************************************** */ 8021308Sache 8121308Sachestatic char *term_buffer = (char *)NULL; 8221308Sachestatic char *term_string_buffer = (char *)NULL; 8321308Sache 8421308Sachestatic int tcap_initialized; 8521308Sache 8621308Sache#if !defined (__linux__) 8726497Sache# if defined (__EMX__) || defined (NEED_EXTERN_PC) 8826497Sacheextern 8926497Sache# endif /* __EMX__ || NEED_EXTERN_PC */ 9026497Sachechar PC, *BC, *UP; 9121308Sache#endif /* __linux__ */ 9221308Sache 9321308Sache/* Some strings to control terminal actions. These are output by tputs (). */ 9475409Sachechar *_rl_term_clreol; 9575409Sachechar *_rl_term_clrpag; 9675409Sachechar *_rl_term_cr; 9775409Sachechar *_rl_term_backspace; 9875409Sachechar *_rl_term_goto; 9975409Sachechar *_rl_term_pc; 10021308Sache 10121308Sache/* Non-zero if we determine that the terminal can do character insertion. */ 10275409Sacheint _rl_terminal_can_insert = 0; 10321308Sache 10421308Sache/* How to insert characters. */ 10575409Sachechar *_rl_term_im; 10675409Sachechar *_rl_term_ei; 10775409Sachechar *_rl_term_ic; 10875409Sachechar *_rl_term_ip; 10975409Sachechar *_rl_term_IC; 11021308Sache 11121308Sache/* How to delete characters. */ 11275409Sachechar *_rl_term_dc; 11375409Sachechar *_rl_term_DC; 11421308Sache 11521308Sache#if defined (HACK_TERMCAP_MOTION) 11675409Sachechar *_rl_term_forward_char; 11721308Sache#endif /* HACK_TERMCAP_MOTION */ 11821308Sache 11921308Sache/* How to go up a line. */ 12075409Sachechar *_rl_term_up; 12121308Sache 12275409Sache/* A visible bell; char if the terminal can be made to flash the screen. */ 12375409Sachestatic char *_rl_visible_bell; 12421308Sache 12521308Sache/* Non-zero means the terminal can auto-wrap lines. */ 12621308Sacheint _rl_term_autowrap; 12721308Sache 12821308Sache/* Non-zero means that this terminal has a meta key. */ 12921308Sachestatic int term_has_meta; 13021308Sache 13121308Sache/* The sequences to write to turn on and off the meta key, if this 13275409Sache terminal has one. */ 13375409Sachestatic char *_rl_term_mm; 13475409Sachestatic char *_rl_term_mo; 13521308Sache 13621308Sache/* The key sequences output by the arrow keys, if this terminal has any. */ 13775409Sachestatic char *_rl_term_ku; 13875409Sachestatic char *_rl_term_kd; 13975409Sachestatic char *_rl_term_kr; 14075409Sachestatic char *_rl_term_kl; 14121308Sache 14221308Sache/* How to initialize and reset the arrow keys, if this terminal has any. */ 14375409Sachestatic char *_rl_term_ks; 14475409Sachestatic char *_rl_term_ke; 14521308Sache 14621308Sache/* The key sequences sent by the Home and End keys, if any. */ 14775409Sachestatic char *_rl_term_kh; 14875409Sachestatic char *_rl_term_kH; 149119614Sachestatic char *_rl_term_at7; /* @7 */ 15021308Sache 151157188Sache/* Delete key */ 152157188Sachestatic char *_rl_term_kD; 153157188Sache 154119614Sache/* Insert key */ 155119614Sachestatic char *_rl_term_kI; 156119614Sache 157119614Sache/* Cursor control */ 158119614Sachestatic char *_rl_term_vs; /* very visible */ 159119614Sachestatic char *_rl_term_ve; /* normal */ 160119614Sache 161119614Sachestatic void bind_termcap_arrow_keys PARAMS((Keymap)); 162119614Sache 16321308Sache/* Variables that hold the screen dimensions, used by the display code. */ 16475409Sacheint _rl_screenwidth, _rl_screenheight, _rl_screenchars; 16521308Sache 16621308Sache/* Non-zero means the user wants to enable the keypad. */ 16721308Sacheint _rl_enable_keypad; 16821308Sache 16921308Sache/* Non-zero means the user wants to enable a meta key. */ 17021308Sacheint _rl_enable_meta = 1; 17121308Sache 17258314Sache#if defined (__EMX__) 17358314Sachestatic void 17458314Sache_emx_get_screensize (swp, shp) 17558314Sache int *swp, *shp; 17658314Sache{ 17758314Sache int sz[2]; 17858314Sache 17958314Sache _scrsize (sz); 18058314Sache 18158314Sache if (swp) 18258314Sache *swp = sz[0]; 18358314Sache if (shp) 18458314Sache *shp = sz[1]; 18558314Sache} 18658314Sache#endif 18758314Sache 18821308Sache/* Get readline's idea of the screen size. TTY is a file descriptor open 18921308Sache to the terminal. If IGNORE_ENV is true, we do not pay attention to the 19021308Sache values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being 19121308Sache non-null serve to check whether or not we have initialized termcap. */ 19221308Sachevoid 19321308Sache_rl_get_screen_size (tty, ignore_env) 19421308Sache int tty, ignore_env; 19521308Sache{ 19621308Sache char *ss; 19721308Sache#if defined (TIOCGWINSZ) 19821308Sache struct winsize window_size; 19921308Sache#endif /* TIOCGWINSZ */ 200157188Sache int wr, wc; 20121308Sache 202157188Sache wr = wc = -1; 20321308Sache#if defined (TIOCGWINSZ) 20421308Sache if (ioctl (tty, TIOCGWINSZ, &window_size) == 0) 20521308Sache { 206157188Sache wc = (int) window_size.ws_col; 207157188Sache wr = (int) window_size.ws_row; 20821308Sache } 20921308Sache#endif /* TIOCGWINSZ */ 21021308Sache 21126497Sache#if defined (__EMX__) 21275409Sache _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight); 21326497Sache#endif 21426497Sache 215157188Sache if (ignore_env || rl_prefer_env_winsize == 0) 216157188Sache { 217157188Sache _rl_screenwidth = wc; 218157188Sache _rl_screenheight = wr; 219157188Sache } 220157188Sache else 221157188Sache _rl_screenwidth = _rl_screenheight = -1; 222157188Sache 22321308Sache /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV 224157188Sache is unset. If we prefer the environment, check it first before 225157188Sache assigning the value returned by the kernel. */ 22675409Sache if (_rl_screenwidth <= 0) 22721308Sache { 22875409Sache if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS"))) 22975409Sache _rl_screenwidth = atoi (ss); 23021308Sache 231157188Sache if (_rl_screenwidth <= 0) 232157188Sache _rl_screenwidth = wc; 233157188Sache 23458314Sache#if !defined (__DJGPP__) 23575409Sache if (_rl_screenwidth <= 0 && term_string_buffer) 23675409Sache _rl_screenwidth = tgetnum ("co"); 23758314Sache#endif 23821308Sache } 23921308Sache 24021308Sache /* Environment variable LINES overrides setting of "li" if IGNORE_ENV 24121308Sache is unset. */ 24275409Sache if (_rl_screenheight <= 0) 24321308Sache { 24475409Sache if (ignore_env == 0 && (ss = sh_get_env_value ("LINES"))) 24575409Sache _rl_screenheight = atoi (ss); 24621308Sache 247157188Sache if (_rl_screenheight <= 0) 248157188Sache _rl_screenheight = wr; 249157188Sache 25058314Sache#if !defined (__DJGPP__) 25175409Sache if (_rl_screenheight <= 0 && term_string_buffer) 25275409Sache _rl_screenheight = tgetnum ("li"); 25358314Sache#endif 25421308Sache } 25521308Sache 25621308Sache /* If all else fails, default to 80x24 terminal. */ 25775409Sache if (_rl_screenwidth <= 1) 25875409Sache _rl_screenwidth = 80; 25921308Sache 26075409Sache if (_rl_screenheight <= 0) 26175409Sache _rl_screenheight = 24; 26221308Sache 26321308Sache /* If we're being compiled as part of bash, set the environment 26421308Sache variables $LINES and $COLUMNS to new values. Otherwise, just 26521308Sache do a pair of putenv () or setenv () calls. */ 26675409Sache sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth); 26721308Sache 26858314Sache if (_rl_term_autowrap == 0) 26975409Sache _rl_screenwidth--; 27021308Sache 27175409Sache _rl_screenchars = _rl_screenwidth * _rl_screenheight; 27221308Sache} 27321308Sache 27421308Sachevoid 27521308Sache_rl_set_screen_size (rows, cols) 27621308Sache int rows, cols; 27721308Sache{ 278157188Sache if (rows > 0) 279157188Sache _rl_screenheight = rows; 280157188Sache if (cols > 0) 281157188Sache { 282157188Sache _rl_screenwidth = cols; 283157188Sache if (_rl_term_autowrap == 0) 284157188Sache _rl_screenwidth--; 285157188Sache } 28621308Sache 287157188Sache if (rows > 0 || cols > 0) 288157188Sache _rl_screenchars = _rl_screenwidth * _rl_screenheight; 28921308Sache} 29021308Sache 29147558Sachevoid 29275409Sacherl_set_screen_size (rows, cols) 29375409Sache int rows, cols; 29475409Sache{ 29575409Sache _rl_set_screen_size (rows, cols); 29675409Sache} 29775409Sache 29875409Sachevoid 29975409Sacherl_get_screen_size (rows, cols) 30075409Sache int *rows, *cols; 30175409Sache{ 30275409Sache if (rows) 30375409Sache *rows = _rl_screenheight; 30475409Sache if (cols) 30575409Sache *cols = _rl_screenwidth; 30675409Sache} 307157188Sache 308157188Sachevoid 309157188Sacherl_reset_screen_size () 310157188Sache{ 311157188Sache _rl_get_screen_size (fileno (rl_instream), 0); 312157188Sache} 31375409Sache 31475409Sachevoid 31547558Sacherl_resize_terminal () 31647558Sache{ 31747558Sache if (readline_echoing_p) 31847558Sache { 31947558Sache _rl_get_screen_size (fileno (rl_instream), 1); 320119614Sache if (CUSTOM_REDISPLAY_FUNC ()) 321119614Sache rl_forced_update_display (); 322119614Sache else 323119614Sache _rl_redisplay_after_sigwinch (); 32447558Sache } 32547558Sache} 32647558Sache 32721308Sachestruct _tc_string { 32875409Sache const char *tc_var; 32921308Sache char **tc_value; 33021308Sache}; 33121308Sache 33221308Sache/* This should be kept sorted, just in case we decide to change the 33321308Sache search algorithm to something smarter. */ 33421308Sachestatic struct _tc_string tc_strings[] = 33521308Sache{ 336119614Sache { "@7", &_rl_term_at7 }, 33775409Sache { "DC", &_rl_term_DC }, 33875409Sache { "IC", &_rl_term_IC }, 33975409Sache { "ce", &_rl_term_clreol }, 34075409Sache { "cl", &_rl_term_clrpag }, 34175409Sache { "cr", &_rl_term_cr }, 34275409Sache { "dc", &_rl_term_dc }, 34375409Sache { "ei", &_rl_term_ei }, 34475409Sache { "ic", &_rl_term_ic }, 34575409Sache { "im", &_rl_term_im }, 346157188Sache { "kD", &_rl_term_kD }, /* delete */ 347119614Sache { "kH", &_rl_term_kH }, /* home down ?? */ 348119614Sache { "kI", &_rl_term_kI }, /* insert */ 34975409Sache { "kd", &_rl_term_kd }, 350119614Sache { "ke", &_rl_term_ke }, /* end keypad mode */ 35175409Sache { "kh", &_rl_term_kh }, /* home */ 35275409Sache { "kl", &_rl_term_kl }, 35375409Sache { "kr", &_rl_term_kr }, 354119614Sache { "ks", &_rl_term_ks }, /* start keypad mode */ 35575409Sache { "ku", &_rl_term_ku }, 35675409Sache { "le", &_rl_term_backspace }, 35775409Sache { "mm", &_rl_term_mm }, 35875409Sache { "mo", &_rl_term_mo }, 35921308Sache#if defined (HACK_TERMCAP_MOTION) 36075409Sache { "nd", &_rl_term_forward_char }, 36121308Sache#endif 36275409Sache { "pc", &_rl_term_pc }, 36375409Sache { "up", &_rl_term_up }, 36475409Sache { "vb", &_rl_visible_bell }, 365119614Sache { "vs", &_rl_term_vs }, 366119614Sache { "ve", &_rl_term_ve }, 36721308Sache}; 36821308Sache 36921308Sache#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string)) 37021308Sache 37121308Sache/* Read the desired terminal capability strings into BP. The capabilities 37221308Sache are described in the TC_STRINGS table. */ 37321308Sachestatic void 37421308Sacheget_term_capabilities (bp) 37521308Sache char **bp; 37621308Sache{ 37758314Sache#if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */ 37821308Sache register int i; 37921308Sache 38021308Sache for (i = 0; i < NUM_TC_STRINGS; i++) 381119614Sache *(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp); 38258314Sache#endif 38321308Sache tcap_initialized = 1; 38421308Sache} 38521308Sache 38621308Sacheint 38721308Sache_rl_init_terminal_io (terminal_name) 38875409Sache const char *terminal_name; 38921308Sache{ 39075409Sache const char *term; 39175409Sache char *buffer; 39258314Sache int tty, tgetent_ret; 39321308Sache 39475409Sache term = terminal_name ? terminal_name : sh_get_env_value ("TERM"); 39575409Sache _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL; 39658314Sache tty = rl_instream ? fileno (rl_instream) : 0; 39721308Sache 39858314Sache if (term == 0) 39958314Sache term = "dumb"; 40021308Sache 40158314Sache /* I've separated this out for later work on not calling tgetent at all 40258314Sache if the calling application has supplied a custom redisplay function, 40358314Sache (and possibly if the application has supplied a custom input function). */ 40458314Sache if (CUSTOM_REDISPLAY_FUNC()) 40558314Sache { 40658314Sache tgetent_ret = -1; 40758314Sache } 40858314Sache else 40958314Sache { 41058314Sache if (term_string_buffer == 0) 411119614Sache term_string_buffer = (char *)xmalloc(2032); 41221308Sache 41358314Sache if (term_buffer == 0) 414119614Sache term_buffer = (char *)xmalloc(4080); 41521308Sache 41658314Sache buffer = term_string_buffer; 41721308Sache 41858314Sache tgetent_ret = tgetent (term_buffer, term); 41958314Sache } 42021308Sache 42158314Sache if (tgetent_ret <= 0) 42221308Sache { 42358314Sache FREE (term_string_buffer); 42458314Sache FREE (term_buffer); 42558314Sache buffer = term_buffer = term_string_buffer = (char *)NULL; 42658314Sache 42758314Sache _rl_term_autowrap = 0; /* used by _rl_get_screen_size */ 42858314Sache 429157188Sache /* Allow calling application to set default height and width, using 430157188Sache rl_set_screen_size */ 431157188Sache if (_rl_screenwidth <= 0 || _rl_screenheight <= 0) 432157188Sache { 43358314Sache#if defined (__EMX__) 434157188Sache _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight); 435157188Sache _rl_screenwidth--; 43658314Sache#else /* !__EMX__ */ 437157188Sache _rl_get_screen_size (tty, 0); 43858314Sache#endif /* !__EMX__ */ 439157188Sache } 44058314Sache 44158314Sache /* Defaults. */ 44275409Sache if (_rl_screenwidth <= 0 || _rl_screenheight <= 0) 44358314Sache { 44475409Sache _rl_screenwidth = 79; 44575409Sache _rl_screenheight = 24; 44658314Sache } 44758314Sache 44858314Sache /* Everything below here is used by the redisplay code (tputs). */ 44975409Sache _rl_screenchars = _rl_screenwidth * _rl_screenheight; 45075409Sache _rl_term_cr = "\r"; 45175409Sache _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL; 45275409Sache _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL; 45375409Sache _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL; 454157188Sache _rl_term_kh = _rl_term_kH = _rl_term_kI = _rl_term_kD = (char *)NULL; 455119614Sache _rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL; 45675409Sache _rl_term_mm = _rl_term_mo = (char *)NULL; 457119614Sache _rl_term_ve = _rl_term_vs = (char *)NULL; 45821308Sache#if defined (HACK_TERMCAP_MOTION) 45921308Sache term_forward_char = (char *)NULL; 46021308Sache#endif 46175409Sache _rl_terminal_can_insert = term_has_meta = 0; 46258314Sache 46358314Sache /* Reasonable defaults for tgoto(). Readline currently only uses 46475409Sache tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we 46558314Sache change that later... */ 46658314Sache PC = '\0'; 46775409Sache BC = _rl_term_backspace = "\b"; 46875409Sache UP = _rl_term_up; 46958314Sache 47021308Sache return 0; 47121308Sache } 47221308Sache 47321308Sache get_term_capabilities (&buffer); 47421308Sache 47521308Sache /* Set up the variables that the termcap library expects the application 47621308Sache to provide. */ 47775409Sache PC = _rl_term_pc ? *_rl_term_pc : 0; 47875409Sache BC = _rl_term_backspace; 47975409Sache UP = _rl_term_up; 48021308Sache 48175409Sache if (!_rl_term_cr) 48275409Sache _rl_term_cr = "\r"; 48321308Sache 48421308Sache _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn"); 48521308Sache 486157188Sache /* Allow calling application to set default height and width, using 487157188Sache rl_set_screen_size */ 488157188Sache if (_rl_screenwidth <= 0 || _rl_screenheight <= 0) 489157188Sache _rl_get_screen_size (tty, 0); 49021308Sache 49121308Sache /* "An application program can assume that the terminal can do 49221308Sache character insertion if *any one of* the capabilities `IC', 49321308Sache `im', `ic' or `ip' is provided." But we can't do anything if 49421308Sache only `ip' is provided, so... */ 49575409Sache _rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic); 49621308Sache 49721308Sache /* Check to see if this terminal has a meta key and clear the capability 49821308Sache variables if there is none. */ 49921308Sache term_has_meta = (tgetflag ("km") || tgetflag ("MT")); 50021308Sache if (!term_has_meta) 50175409Sache _rl_term_mm = _rl_term_mo = (char *)NULL; 50221308Sache 50321308Sache /* Attempt to find and bind the arrow keys. Do not override already 50421308Sache bound keys in an overzealous attempt, however. */ 50521308Sache 506119614Sache bind_termcap_arrow_keys (emacs_standard_keymap); 50721308Sache 508119614Sache#if defined (VI_MODE) 509119614Sache bind_termcap_arrow_keys (vi_movement_keymap); 510119614Sache bind_termcap_arrow_keys (vi_insertion_keymap); 511119614Sache#endif /* VI_MODE */ 51221308Sache 513119614Sache return 0; 514119614Sache} 515119614Sache 516119614Sache/* Bind the arrow key sequences from the termcap description in MAP. */ 517119614Sachestatic void 518119614Sachebind_termcap_arrow_keys (map) 519119614Sache Keymap map; 520119614Sache{ 521119614Sache Keymap xkeymap; 522119614Sache 523119614Sache xkeymap = _rl_keymap; 524119614Sache _rl_keymap = map; 525119614Sache 526136758Speter rl_bind_keyseq_if_unbound (_rl_term_ku, rl_get_previous_history); 527136758Speter rl_bind_keyseq_if_unbound (_rl_term_kd, rl_get_next_history); 528136758Speter rl_bind_keyseq_if_unbound (_rl_term_kr, rl_forward_char); 529136758Speter rl_bind_keyseq_if_unbound (_rl_term_kl, rl_backward_char); 53021308Sache 531136758Speter rl_bind_keyseq_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */ 532136758Speter rl_bind_keyseq_if_unbound (_rl_term_at7, rl_end_of_line); /* End */ 53321308Sache 534157188Sache rl_bind_keyseq_if_unbound (_rl_term_kD, rl_delete); 535157188Sache 53621308Sache _rl_keymap = xkeymap; 53721308Sache} 53821308Sache 53921308Sachechar * 54021308Sacherl_get_termcap (cap) 54175409Sache const char *cap; 54221308Sache{ 54321308Sache register int i; 54421308Sache 54521308Sache if (tcap_initialized == 0) 54621308Sache return ((char *)NULL); 54721308Sache for (i = 0; i < NUM_TC_STRINGS; i++) 54821308Sache { 54921308Sache if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0) 55021308Sache return *(tc_strings[i].tc_value); 55121308Sache } 55221308Sache return ((char *)NULL); 55321308Sache} 55421308Sache 55526497Sache/* Re-initialize the terminal considering that the TERM/TERMCAP variable 55626497Sache has changed. */ 55726497Sacheint 55826497Sacherl_reset_terminal (terminal_name) 55975409Sache const char *terminal_name; 56026497Sache{ 561157188Sache _rl_screenwidth = _rl_screenheight = 0; 56226497Sache _rl_init_terminal_io (terminal_name); 56326497Sache return 0; 56426497Sache} 56526497Sache 56621308Sache/* A function for the use of tputs () */ 56735486Sache#ifdef _MINIX 56835486Sachevoid 56935486Sache_rl_output_character_function (c) 57035486Sache int c; 57135486Sache{ 57235486Sache putc (c, _rl_out_stream); 57335486Sache} 57435486Sache#else /* !_MINIX */ 57521308Sacheint 57621308Sache_rl_output_character_function (c) 57721308Sache int c; 57821308Sache{ 57921308Sache return putc (c, _rl_out_stream); 58021308Sache} 58135486Sache#endif /* !_MINIX */ 58258314Sache 58321308Sache/* Write COUNT characters from STRING to the output stream. */ 58421308Sachevoid 58521308Sache_rl_output_some_chars (string, count) 58675409Sache const char *string; 58721308Sache int count; 58821308Sache{ 58921308Sache fwrite (string, 1, count, _rl_out_stream); 59021308Sache} 59121308Sache 59221308Sache/* Move the cursor back. */ 59321308Sacheint 59421308Sache_rl_backspace (count) 59521308Sache int count; 59621308Sache{ 59721308Sache register int i; 59821308Sache 59975409Sache if (_rl_term_backspace) 60021308Sache for (i = 0; i < count; i++) 60175409Sache tputs (_rl_term_backspace, 1, _rl_output_character_function); 60221308Sache else 60321308Sache for (i = 0; i < count; i++) 60421308Sache putc ('\b', _rl_out_stream); 60521308Sache return 0; 60621308Sache} 60721308Sache 60821308Sache/* Move to the start of the next line. */ 60921308Sacheint 61075409Sacherl_crlf () 61121308Sache{ 61221308Sache#if defined (NEW_TTY_DRIVER) 61375409Sache if (_rl_term_cr) 61475409Sache tputs (_rl_term_cr, 1, _rl_output_character_function); 61521308Sache#endif /* NEW_TTY_DRIVER */ 61621308Sache putc ('\n', _rl_out_stream); 61721308Sache return 0; 61821308Sache} 61921308Sache 62021308Sache/* Ring the terminal bell. */ 62121308Sacheint 62275409Sacherl_ding () 62321308Sache{ 62421308Sache if (readline_echoing_p) 62521308Sache { 62621308Sache switch (_rl_bell_preference) 62721308Sache { 62821308Sache case NO_BELL: 62921308Sache default: 63021308Sache break; 63121308Sache case VISIBLE_BELL: 63275409Sache if (_rl_visible_bell) 63321308Sache { 63475409Sache tputs (_rl_visible_bell, 1, _rl_output_character_function); 63521308Sache break; 63621308Sache } 63721308Sache /* FALLTHROUGH */ 63821308Sache case AUDIBLE_BELL: 63921308Sache fprintf (stderr, "\007"); 64021308Sache fflush (stderr); 64121308Sache break; 64221308Sache } 64321308Sache return (0); 64421308Sache } 64521308Sache return (-1); 64621308Sache} 64721308Sache 64821308Sache/* **************************************************************** */ 64921308Sache/* */ 65021308Sache/* Controlling the Meta Key and Keypad */ 65121308Sache/* */ 65221308Sache/* **************************************************************** */ 65321308Sache 65426497Sachevoid 65521308Sache_rl_enable_meta_key () 65621308Sache{ 65758314Sache#if !defined (__DJGPP__) 65875409Sache if (term_has_meta && _rl_term_mm) 65975409Sache tputs (_rl_term_mm, 1, _rl_output_character_function); 66058314Sache#endif 66121308Sache} 66221308Sache 66321308Sachevoid 66421308Sache_rl_control_keypad (on) 66521308Sache int on; 66621308Sache{ 66758314Sache#if !defined (__DJGPP__) 66875409Sache if (on && _rl_term_ks) 66975409Sache tputs (_rl_term_ks, 1, _rl_output_character_function); 67075409Sache else if (!on && _rl_term_ke) 67175409Sache tputs (_rl_term_ke, 1, _rl_output_character_function); 67258314Sache#endif 67321308Sache} 674119614Sache 675119614Sache/* **************************************************************** */ 676119614Sache/* */ 677119614Sache/* Controlling the Cursor */ 678119614Sache/* */ 679119614Sache/* **************************************************************** */ 680119614Sache 681119614Sache/* Set the cursor appropriately depending on IM, which is one of the 682119614Sache insert modes (insert or overwrite). Insert mode gets the normal 683119614Sache cursor. Overwrite mode gets a very visible cursor. Only does 684119614Sache anything if we have both capabilities. */ 685119614Sachevoid 686119614Sache_rl_set_cursor (im, force) 687119614Sache int im, force; 688119614Sache{ 689119614Sache if (_rl_term_ve && _rl_term_vs) 690119614Sache { 691119614Sache if (force || im != rl_insert_mode) 692119614Sache { 693119614Sache if (im == RL_IM_OVERWRITE) 694119614Sache tputs (_rl_term_vs, 1, _rl_output_character_function); 695119614Sache else 696119614Sache tputs (_rl_term_ve, 1, _rl_output_character_function); 697119614Sache } 698119614Sache } 699119614Sache} 700