terminal.c revision 75409
158314Sache/* $FreeBSD: head/contrib/libreadline/terminal.c 75409 2001-04-11 03:15:56Z ache $ */
221308Sache/* terminal.c -- controlling the terminal with termcap. */
321308Sache
421308Sache/* Copyright (C) 1996 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"
6821308Sache
6921308Sache/* **************************************************************** */
7021308Sache/*								    */
7121308Sache/*			Terminal and Termcap			    */
7221308Sache/*								    */
7321308Sache/* **************************************************************** */
7421308Sache
7521308Sachestatic char *term_buffer = (char *)NULL;
7621308Sachestatic char *term_string_buffer = (char *)NULL;
7721308Sache
7821308Sachestatic int tcap_initialized;
7921308Sache
8021308Sache#if !defined (__linux__)
8126497Sache#  if defined (__EMX__) || defined (NEED_EXTERN_PC)
8226497Sacheextern
8326497Sache#  endif /* __EMX__ || NEED_EXTERN_PC */
8426497Sachechar PC, *BC, *UP;
8521308Sache#endif /* __linux__ */
8621308Sache
8721308Sache/* Some strings to control terminal actions.  These are output by tputs (). */
8875409Sachechar *_rl_term_clreol;
8975409Sachechar *_rl_term_clrpag;
9075409Sachechar *_rl_term_cr;
9175409Sachechar *_rl_term_backspace;
9275409Sachechar *_rl_term_goto;
9375409Sachechar *_rl_term_pc;
9421308Sache
9521308Sache/* Non-zero if we determine that the terminal can do character insertion. */
9675409Sacheint _rl_terminal_can_insert = 0;
9721308Sache
9821308Sache/* How to insert characters. */
9975409Sachechar *_rl_term_im;
10075409Sachechar *_rl_term_ei;
10175409Sachechar *_rl_term_ic;
10275409Sachechar *_rl_term_ip;
10375409Sachechar *_rl_term_IC;
10421308Sache
10521308Sache/* How to delete characters. */
10675409Sachechar *_rl_term_dc;
10775409Sachechar *_rl_term_DC;
10821308Sache
10921308Sache#if defined (HACK_TERMCAP_MOTION)
11075409Sachechar *_rl_term_forward_char;
11121308Sache#endif  /* HACK_TERMCAP_MOTION */
11221308Sache
11321308Sache/* How to go up a line. */
11475409Sachechar *_rl_term_up;
11521308Sache
11675409Sache/* A visible bell; char if the terminal can be made to flash the screen. */
11775409Sachestatic char *_rl_visible_bell;
11821308Sache
11921308Sache/* Non-zero means the terminal can auto-wrap lines. */
12021308Sacheint _rl_term_autowrap;
12121308Sache
12221308Sache/* Non-zero means that this terminal has a meta key. */
12321308Sachestatic int term_has_meta;
12421308Sache
12521308Sache/* The sequences to write to turn on and off the meta key, if this
12675409Sache   terminal has one. */
12775409Sachestatic char *_rl_term_mm;
12875409Sachestatic char *_rl_term_mo;
12921308Sache
13021308Sache/* The key sequences output by the arrow keys, if this terminal has any. */
13175409Sachestatic char *_rl_term_ku;
13275409Sachestatic char *_rl_term_kd;
13375409Sachestatic char *_rl_term_kr;
13475409Sachestatic char *_rl_term_kl;
13521308Sache
13621308Sache/* How to initialize and reset the arrow keys, if this terminal has any. */
13775409Sachestatic char *_rl_term_ks;
13875409Sachestatic char *_rl_term_ke;
13921308Sache
14021308Sache/* The key sequences sent by the Home and End keys, if any. */
14175409Sachestatic char *_rl_term_kh;
14275409Sachestatic char *_rl_term_kH;
14321308Sache
14421308Sache/* Variables that hold the screen dimensions, used by the display code. */
14575409Sacheint _rl_screenwidth, _rl_screenheight, _rl_screenchars;
14621308Sache
14721308Sache/* Non-zero means the user wants to enable the keypad. */
14821308Sacheint _rl_enable_keypad;
14921308Sache
15021308Sache/* Non-zero means the user wants to enable a meta key. */
15121308Sacheint _rl_enable_meta = 1;
15221308Sache
15358314Sache#if defined (__EMX__)
15458314Sachestatic void
15558314Sache_emx_get_screensize (swp, shp)
15658314Sache     int *swp, *shp;
15758314Sache{
15858314Sache  int sz[2];
15958314Sache
16058314Sache  _scrsize (sz);
16158314Sache
16258314Sache  if (swp)
16358314Sache    *swp = sz[0];
16458314Sache  if (shp)
16558314Sache    *shp = sz[1];
16658314Sache}
16758314Sache#endif
16858314Sache
16921308Sache/* Get readline's idea of the screen size.  TTY is a file descriptor open
17021308Sache   to the terminal.  If IGNORE_ENV is true, we do not pay attention to the
17121308Sache   values of $LINES and $COLUMNS.  The tests for TERM_STRING_BUFFER being
17221308Sache   non-null serve to check whether or not we have initialized termcap. */
17321308Sachevoid
17421308Sache_rl_get_screen_size (tty, ignore_env)
17521308Sache     int tty, ignore_env;
17621308Sache{
17721308Sache  char *ss;
17821308Sache#if defined (TIOCGWINSZ)
17921308Sache  struct winsize window_size;
18021308Sache#endif /* TIOCGWINSZ */
18121308Sache
18221308Sache#if defined (TIOCGWINSZ)
18321308Sache  if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
18421308Sache    {
18575409Sache      _rl_screenwidth = (int) window_size.ws_col;
18675409Sache      _rl_screenheight = (int) window_size.ws_row;
18721308Sache    }
18821308Sache#endif /* TIOCGWINSZ */
18921308Sache
19026497Sache#if defined (__EMX__)
19175409Sache  _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
19226497Sache#endif
19326497Sache
19421308Sache  /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
19521308Sache     is unset. */
19675409Sache  if (_rl_screenwidth <= 0)
19721308Sache    {
19875409Sache      if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS")))
19975409Sache	_rl_screenwidth = atoi (ss);
20021308Sache
20158314Sache#if !defined (__DJGPP__)
20275409Sache      if (_rl_screenwidth <= 0 && term_string_buffer)
20375409Sache	_rl_screenwidth = tgetnum ("co");
20458314Sache#endif
20521308Sache    }
20621308Sache
20721308Sache  /* Environment variable LINES overrides setting of "li" if IGNORE_ENV
20821308Sache     is unset. */
20975409Sache  if (_rl_screenheight <= 0)
21021308Sache    {
21175409Sache      if (ignore_env == 0 && (ss = sh_get_env_value ("LINES")))
21275409Sache	_rl_screenheight = atoi (ss);
21321308Sache
21458314Sache#if !defined (__DJGPP__)
21575409Sache      if (_rl_screenheight <= 0 && term_string_buffer)
21675409Sache	_rl_screenheight = tgetnum ("li");
21758314Sache#endif
21821308Sache    }
21921308Sache
22021308Sache  /* If all else fails, default to 80x24 terminal. */
22175409Sache  if (_rl_screenwidth <= 1)
22275409Sache    _rl_screenwidth = 80;
22321308Sache
22475409Sache  if (_rl_screenheight <= 0)
22575409Sache    _rl_screenheight = 24;
22621308Sache
22721308Sache  /* If we're being compiled as part of bash, set the environment
22821308Sache     variables $LINES and $COLUMNS to new values.  Otherwise, just
22921308Sache     do a pair of putenv () or setenv () calls. */
23075409Sache  sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth);
23121308Sache
23258314Sache  if (_rl_term_autowrap == 0)
23375409Sache    _rl_screenwidth--;
23421308Sache
23575409Sache  _rl_screenchars = _rl_screenwidth * _rl_screenheight;
23621308Sache}
23721308Sache
23821308Sachevoid
23921308Sache_rl_set_screen_size (rows, cols)
24021308Sache     int rows, cols;
24121308Sache{
24275409Sache  if (rows == 0 || cols == 0)
24375409Sache    return;
24421308Sache
24575409Sache  _rl_screenheight = rows;
24675409Sache  _rl_screenwidth = cols;
24775409Sache
24821308Sache  if (_rl_term_autowrap == 0)
24975409Sache    _rl_screenwidth--;
25021308Sache
25175409Sache  _rl_screenchars = _rl_screenwidth * _rl_screenheight;
25221308Sache}
25321308Sache
25447558Sachevoid
25575409Sacherl_set_screen_size (rows, cols)
25675409Sache     int rows, cols;
25775409Sache{
25875409Sache  _rl_set_screen_size (rows, cols);
25975409Sache}
26075409Sache
26175409Sachevoid
26275409Sacherl_get_screen_size (rows, cols)
26375409Sache     int *rows, *cols;
26475409Sache{
26575409Sache  if (rows)
26675409Sache    *rows = _rl_screenheight;
26775409Sache  if (cols)
26875409Sache    *cols = _rl_screenwidth;
26975409Sache}
27075409Sache
27175409Sachevoid
27247558Sacherl_resize_terminal ()
27347558Sache{
27447558Sache  if (readline_echoing_p)
27547558Sache    {
27647558Sache      _rl_get_screen_size (fileno (rl_instream), 1);
27747558Sache      _rl_redisplay_after_sigwinch ();
27847558Sache    }
27947558Sache}
28047558Sache
28121308Sachestruct _tc_string {
28275409Sache     const char *tc_var;
28321308Sache     char **tc_value;
28421308Sache};
28521308Sache
28621308Sache/* This should be kept sorted, just in case we decide to change the
28721308Sache   search algorithm to something smarter. */
28821308Sachestatic struct _tc_string tc_strings[] =
28921308Sache{
29075409Sache  { "DC", &_rl_term_DC },
29175409Sache  { "IC", &_rl_term_IC },
29275409Sache  { "ce", &_rl_term_clreol },
29375409Sache  { "cl", &_rl_term_clrpag },
29475409Sache  { "cr", &_rl_term_cr },
29575409Sache  { "dc", &_rl_term_dc },
29675409Sache  { "ei", &_rl_term_ei },
29775409Sache  { "ic", &_rl_term_ic },
29875409Sache  { "im", &_rl_term_im },
29975409Sache  { "kd", &_rl_term_kd },
30075409Sache  { "kh", &_rl_term_kh },	/* home */
30175409Sache  { "@7", &_rl_term_kH },	/* end */
30275409Sache  { "kl", &_rl_term_kl },
30375409Sache  { "kr", &_rl_term_kr },
30475409Sache  { "ku", &_rl_term_ku },
30575409Sache  { "ks", &_rl_term_ks },
30675409Sache  { "ke", &_rl_term_ke },
30775409Sache  { "le", &_rl_term_backspace },
30875409Sache  { "mm", &_rl_term_mm },
30975409Sache  { "mo", &_rl_term_mo },
31021308Sache#if defined (HACK_TERMCAP_MOTION)
31175409Sache  { "nd", &_rl_term_forward_char },
31221308Sache#endif
31375409Sache  { "pc", &_rl_term_pc },
31475409Sache  { "up", &_rl_term_up },
31575409Sache  { "vb", &_rl_visible_bell },
31621308Sache};
31721308Sache
31821308Sache#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
31921308Sache
32021308Sache/* Read the desired terminal capability strings into BP.  The capabilities
32121308Sache   are described in the TC_STRINGS table. */
32221308Sachestatic void
32321308Sacheget_term_capabilities (bp)
32421308Sache     char **bp;
32521308Sache{
32658314Sache#if !defined (__DJGPP__)	/* XXX - doesn't DJGPP have a termcap library? */
32721308Sache  register int i;
32821308Sache
32921308Sache  for (i = 0; i < NUM_TC_STRINGS; i++)
33021308Sache    *(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
33158314Sache#endif
33221308Sache  tcap_initialized = 1;
33321308Sache}
33421308Sache
33558314Sache#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
33658314Sache#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
33758314Sache
33821308Sacheint
33921308Sache_rl_init_terminal_io (terminal_name)
34075409Sache     const char *terminal_name;
34121308Sache{
34275409Sache  const char *term;
34375409Sache  char *buffer;
34458314Sache  int tty, tgetent_ret;
34521308Sache  Keymap xkeymap;
34621308Sache
34775409Sache  term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
34875409Sache  _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL;
34958314Sache  tty = rl_instream ? fileno (rl_instream) : 0;
35075409Sache  _rl_screenwidth = _rl_screenheight = 0;
35121308Sache
35258314Sache  if (term == 0)
35358314Sache    term = "dumb";
35421308Sache
35558314Sache  /* I've separated this out for later work on not calling tgetent at all
35658314Sache     if the calling application has supplied a custom redisplay function,
35758314Sache     (and possibly if the application has supplied a custom input function). */
35858314Sache  if (CUSTOM_REDISPLAY_FUNC())
35958314Sache    {
36058314Sache      tgetent_ret = -1;
36158314Sache    }
36258314Sache  else
36358314Sache    {
36458314Sache      if (term_string_buffer == 0)
36558314Sache	term_string_buffer = xmalloc(2032);
36621308Sache
36758314Sache      if (term_buffer == 0)
36858314Sache	term_buffer = xmalloc(4080);
36921308Sache
37058314Sache      buffer = term_string_buffer;
37121308Sache
37258314Sache      tgetent_ret = tgetent (term_buffer, term);
37358314Sache    }
37421308Sache
37558314Sache  if (tgetent_ret <= 0)
37621308Sache    {
37758314Sache      FREE (term_string_buffer);
37858314Sache      FREE (term_buffer);
37958314Sache      buffer = term_buffer = term_string_buffer = (char *)NULL;
38058314Sache
38158314Sache      _rl_term_autowrap = 0;	/* used by _rl_get_screen_size */
38258314Sache
38358314Sache#if defined (__EMX__)
38475409Sache      _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
38575409Sache      _rl_screenwidth--;
38658314Sache#else /* !__EMX__ */
38758314Sache      _rl_get_screen_size (tty, 0);
38858314Sache#endif /* !__EMX__ */
38958314Sache
39058314Sache      /* Defaults. */
39175409Sache      if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
39258314Sache        {
39375409Sache	  _rl_screenwidth = 79;
39475409Sache	  _rl_screenheight = 24;
39558314Sache        }
39658314Sache
39758314Sache      /* Everything below here is used by the redisplay code (tputs). */
39875409Sache      _rl_screenchars = _rl_screenwidth * _rl_screenheight;
39975409Sache      _rl_term_cr = "\r";
40075409Sache      _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
40175409Sache      _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
40275409Sache      _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
40375409Sache      _rl_term_mm = _rl_term_mo = (char *)NULL;
40421308Sache#if defined (HACK_TERMCAP_MOTION)
40521308Sache      term_forward_char = (char *)NULL;
40621308Sache#endif
40775409Sache      _rl_terminal_can_insert = term_has_meta = 0;
40858314Sache
40958314Sache      /* Reasonable defaults for tgoto().  Readline currently only uses
41075409Sache         tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we
41158314Sache         change that later... */
41258314Sache      PC = '\0';
41375409Sache      BC = _rl_term_backspace = "\b";
41475409Sache      UP = _rl_term_up;
41558314Sache
41621308Sache      return 0;
41721308Sache    }
41821308Sache
41921308Sache  get_term_capabilities (&buffer);
42021308Sache
42121308Sache  /* Set up the variables that the termcap library expects the application
42221308Sache     to provide. */
42375409Sache  PC = _rl_term_pc ? *_rl_term_pc : 0;
42475409Sache  BC = _rl_term_backspace;
42575409Sache  UP = _rl_term_up;
42621308Sache
42775409Sache  if (!_rl_term_cr)
42875409Sache    _rl_term_cr = "\r";
42921308Sache
43021308Sache  _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
43121308Sache
43221308Sache  _rl_get_screen_size (tty, 0);
43321308Sache
43421308Sache  /* "An application program can assume that the terminal can do
43521308Sache      character insertion if *any one of* the capabilities `IC',
43621308Sache      `im', `ic' or `ip' is provided."  But we can't do anything if
43721308Sache      only `ip' is provided, so... */
43875409Sache  _rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic);
43921308Sache
44021308Sache  /* Check to see if this terminal has a meta key and clear the capability
44121308Sache     variables if there is none. */
44221308Sache  term_has_meta = (tgetflag ("km") || tgetflag ("MT"));
44321308Sache  if (!term_has_meta)
44475409Sache    _rl_term_mm = _rl_term_mo = (char *)NULL;
44521308Sache
44621308Sache  /* Attempt to find and bind the arrow keys.  Do not override already
44721308Sache     bound keys in an overzealous attempt, however. */
44821308Sache  xkeymap = _rl_keymap;
44921308Sache
45021308Sache  _rl_keymap = emacs_standard_keymap;
45175409Sache  _rl_bind_if_unbound (_rl_term_ku, rl_get_previous_history);
45275409Sache  _rl_bind_if_unbound (_rl_term_kd, rl_get_next_history);
45375409Sache  _rl_bind_if_unbound (_rl_term_kr, rl_forward);
45475409Sache  _rl_bind_if_unbound (_rl_term_kl, rl_backward);
45521308Sache
45675409Sache  _rl_bind_if_unbound (_rl_term_kh, rl_beg_of_line);	/* Home */
45775409Sache  _rl_bind_if_unbound (_rl_term_kH, rl_end_of_line);	/* End */
45821308Sache
45921308Sache#if defined (VI_MODE)
46021308Sache  _rl_keymap = vi_movement_keymap;
46175409Sache  _rl_bind_if_unbound (_rl_term_ku, rl_get_previous_history);
46275409Sache  _rl_bind_if_unbound (_rl_term_kd, rl_get_next_history);
46375409Sache  _rl_bind_if_unbound (_rl_term_kr, rl_forward);
46475409Sache  _rl_bind_if_unbound (_rl_term_kl, rl_backward);
46521308Sache
46675409Sache  _rl_bind_if_unbound (_rl_term_kh, rl_beg_of_line);	/* Home */
46775409Sache  _rl_bind_if_unbound (_rl_term_kH, rl_end_of_line);	/* End */
46821308Sache#endif /* VI_MODE */
46921308Sache
47021308Sache  _rl_keymap = xkeymap;
47121308Sache
47221308Sache  return 0;
47321308Sache}
47421308Sache
47521308Sachechar *
47621308Sacherl_get_termcap (cap)
47775409Sache     const char *cap;
47821308Sache{
47921308Sache  register int i;
48021308Sache
48121308Sache  if (tcap_initialized == 0)
48221308Sache    return ((char *)NULL);
48321308Sache  for (i = 0; i < NUM_TC_STRINGS; i++)
48421308Sache    {
48521308Sache      if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
48621308Sache        return *(tc_strings[i].tc_value);
48721308Sache    }
48821308Sache  return ((char *)NULL);
48921308Sache}
49021308Sache
49126497Sache/* Re-initialize the terminal considering that the TERM/TERMCAP variable
49226497Sache   has changed. */
49326497Sacheint
49426497Sacherl_reset_terminal (terminal_name)
49575409Sache     const char *terminal_name;
49626497Sache{
49726497Sache  _rl_init_terminal_io (terminal_name);
49826497Sache  return 0;
49926497Sache}
50026497Sache
50121308Sache/* A function for the use of tputs () */
50235486Sache#ifdef _MINIX
50335486Sachevoid
50435486Sache_rl_output_character_function (c)
50535486Sache     int c;
50635486Sache{
50735486Sache  putc (c, _rl_out_stream);
50835486Sache}
50935486Sache#else /* !_MINIX */
51021308Sacheint
51121308Sache_rl_output_character_function (c)
51221308Sache     int c;
51321308Sache{
51421308Sache  return putc (c, _rl_out_stream);
51521308Sache}
51635486Sache#endif /* !_MINIX */
51758314Sache
51821308Sache/* Write COUNT characters from STRING to the output stream. */
51921308Sachevoid
52021308Sache_rl_output_some_chars (string, count)
52175409Sache     const char *string;
52221308Sache     int count;
52321308Sache{
52421308Sache  fwrite (string, 1, count, _rl_out_stream);
52521308Sache}
52621308Sache
52721308Sache/* Move the cursor back. */
52821308Sacheint
52921308Sache_rl_backspace (count)
53021308Sache     int count;
53121308Sache{
53221308Sache  register int i;
53321308Sache
53475409Sache  if (_rl_term_backspace)
53521308Sache    for (i = 0; i < count; i++)
53675409Sache      tputs (_rl_term_backspace, 1, _rl_output_character_function);
53721308Sache  else
53821308Sache    for (i = 0; i < count; i++)
53921308Sache      putc ('\b', _rl_out_stream);
54021308Sache  return 0;
54121308Sache}
54221308Sache
54321308Sache/* Move to the start of the next line. */
54421308Sacheint
54575409Sacherl_crlf ()
54621308Sache{
54721308Sache#if defined (NEW_TTY_DRIVER)
54875409Sache  if (_rl_term_cr)
54975409Sache    tputs (_rl_term_cr, 1, _rl_output_character_function);
55021308Sache#endif /* NEW_TTY_DRIVER */
55121308Sache  putc ('\n', _rl_out_stream);
55221308Sache  return 0;
55321308Sache}
55421308Sache
55521308Sache/* Ring the terminal bell. */
55621308Sacheint
55775409Sacherl_ding ()
55821308Sache{
55921308Sache  if (readline_echoing_p)
56021308Sache    {
56121308Sache      switch (_rl_bell_preference)
56221308Sache        {
56321308Sache	case NO_BELL:
56421308Sache	default:
56521308Sache	  break;
56621308Sache	case VISIBLE_BELL:
56775409Sache	  if (_rl_visible_bell)
56821308Sache	    {
56975409Sache	      tputs (_rl_visible_bell, 1, _rl_output_character_function);
57021308Sache	      break;
57121308Sache	    }
57221308Sache	  /* FALLTHROUGH */
57321308Sache	case AUDIBLE_BELL:
57421308Sache	  fprintf (stderr, "\007");
57521308Sache	  fflush (stderr);
57621308Sache	  break;
57721308Sache        }
57821308Sache      return (0);
57921308Sache    }
58021308Sache  return (-1);
58121308Sache}
58221308Sache
58321308Sache/* **************************************************************** */
58421308Sache/*								    */
58521308Sache/*	 	Controlling the Meta Key and Keypad		    */
58621308Sache/*								    */
58721308Sache/* **************************************************************** */
58821308Sache
58926497Sachevoid
59021308Sache_rl_enable_meta_key ()
59121308Sache{
59258314Sache#if !defined (__DJGPP__)
59375409Sache  if (term_has_meta && _rl_term_mm)
59475409Sache    tputs (_rl_term_mm, 1, _rl_output_character_function);
59558314Sache#endif
59621308Sache}
59721308Sache
59821308Sachevoid
59921308Sache_rl_control_keypad (on)
60021308Sache     int on;
60121308Sache{
60258314Sache#if !defined (__DJGPP__)
60375409Sache  if (on && _rl_term_ks)
60475409Sache    tputs (_rl_term_ks, 1, _rl_output_character_function);
60575409Sache  else if (!on && _rl_term_ke)
60675409Sache    tputs (_rl_term_ke, 1, _rl_output_character_function);
60758314Sache#endif
60821308Sache}
609