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