terminal.c revision 119614
121308Sache/* terminal.c -- controlling the terminal with termcap. */
221308Sache
321308Sache/* Copyright (C) 1996 Free Software Foundation, Inc.
421308Sache
521308Sache   This file is part of the GNU Readline Library, a library for
621308Sache   reading lines of text with interactive input and history editing.
721308Sache
821308Sache   The GNU Readline Library is free software; you can redistribute it
921308Sache   and/or modify it under the terms of the GNU General Public License
1058314Sache   as published by the Free Software Foundation; either version 2, or
1121308Sache   (at your option) any later version.
1221308Sache
1321308Sache   The GNU Readline Library is distributed in the hope that it will be
1421308Sache   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
1521308Sache   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1621308Sache   GNU General Public License for more details.
1721308Sache
1821308Sache   The GNU General Public License is often shipped with GNU software, and
1921308Sache   is generally kept in a file called COPYING or LICENSE.  If you do not
2021308Sache   have a copy of the license, write to the Free Software Foundation,
2158314Sache   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
22119614Sache/* $FreeBSD: head/contrib/libreadline/terminal.c 119614 2003-08-31 18:29:38Z ache $ */
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
7321308Sache/* **************************************************************** */
7421308Sache/*								    */
7521308Sache/*			Terminal and Termcap			    */
7621308Sache/*								    */
7721308Sache/* **************************************************************** */
7821308Sache
7921308Sachestatic char *term_buffer = (char *)NULL;
8021308Sachestatic char *term_string_buffer = (char *)NULL;
8121308Sache
8221308Sachestatic int tcap_initialized;
8321308Sache
8421308Sache#if !defined (__linux__)
8526497Sache#  if defined (__EMX__) || defined (NEED_EXTERN_PC)
8626497Sacheextern
8726497Sache#  endif /* __EMX__ || NEED_EXTERN_PC */
8826497Sachechar PC, *BC, *UP;
8921308Sache#endif /* __linux__ */
9021308Sache
9121308Sache/* Some strings to control terminal actions.  These are output by tputs (). */
9275409Sachechar *_rl_term_clreol;
9375409Sachechar *_rl_term_clrpag;
9475409Sachechar *_rl_term_cr;
9575409Sachechar *_rl_term_backspace;
9675409Sachechar *_rl_term_goto;
9775409Sachechar *_rl_term_pc;
9821308Sache
9921308Sache/* Non-zero if we determine that the terminal can do character insertion. */
10075409Sacheint _rl_terminal_can_insert = 0;
10121308Sache
10221308Sache/* How to insert characters. */
10375409Sachechar *_rl_term_im;
10475409Sachechar *_rl_term_ei;
10575409Sachechar *_rl_term_ic;
10675409Sachechar *_rl_term_ip;
10775409Sachechar *_rl_term_IC;
10821308Sache
10921308Sache/* How to delete characters. */
11075409Sachechar *_rl_term_dc;
11175409Sachechar *_rl_term_DC;
11221308Sache
11321308Sache#if defined (HACK_TERMCAP_MOTION)
11475409Sachechar *_rl_term_forward_char;
11521308Sache#endif  /* HACK_TERMCAP_MOTION */
11621308Sache
11721308Sache/* How to go up a line. */
11875409Sachechar *_rl_term_up;
11921308Sache
12075409Sache/* A visible bell; char if the terminal can be made to flash the screen. */
12175409Sachestatic char *_rl_visible_bell;
12221308Sache
12321308Sache/* Non-zero means the terminal can auto-wrap lines. */
12421308Sacheint _rl_term_autowrap;
12521308Sache
12621308Sache/* Non-zero means that this terminal has a meta key. */
12721308Sachestatic int term_has_meta;
12821308Sache
12921308Sache/* The sequences to write to turn on and off the meta key, if this
13075409Sache   terminal has one. */
13175409Sachestatic char *_rl_term_mm;
13275409Sachestatic char *_rl_term_mo;
13321308Sache
13421308Sache/* The key sequences output by the arrow keys, if this terminal has any. */
13575409Sachestatic char *_rl_term_ku;
13675409Sachestatic char *_rl_term_kd;
13775409Sachestatic char *_rl_term_kr;
13875409Sachestatic char *_rl_term_kl;
13921308Sache
14021308Sache/* How to initialize and reset the arrow keys, if this terminal has any. */
14175409Sachestatic char *_rl_term_ks;
14275409Sachestatic char *_rl_term_ke;
14321308Sache
14421308Sache/* The key sequences sent by the Home and End keys, if any. */
14575409Sachestatic char *_rl_term_kh;
14675409Sachestatic char *_rl_term_kH;
147119614Sachestatic char *_rl_term_at7;	/* @7 */
14821308Sache
149119614Sache/* Insert key */
150119614Sachestatic char *_rl_term_kI;
151119614Sache
152119614Sache/* Cursor control */
153119614Sachestatic char *_rl_term_vs;	/* very visible */
154119614Sachestatic char *_rl_term_ve;	/* normal */
155119614Sache
156119614Sachestatic void bind_termcap_arrow_keys PARAMS((Keymap));
157119614Sache
15821308Sache/* Variables that hold the screen dimensions, used by the display code. */
15975409Sacheint _rl_screenwidth, _rl_screenheight, _rl_screenchars;
16021308Sache
16121308Sache/* Non-zero means the user wants to enable the keypad. */
16221308Sacheint _rl_enable_keypad;
16321308Sache
16421308Sache/* Non-zero means the user wants to enable a meta key. */
16521308Sacheint _rl_enable_meta = 1;
16621308Sache
16758314Sache#if defined (__EMX__)
16858314Sachestatic void
16958314Sache_emx_get_screensize (swp, shp)
17058314Sache     int *swp, *shp;
17158314Sache{
17258314Sache  int sz[2];
17358314Sache
17458314Sache  _scrsize (sz);
17558314Sache
17658314Sache  if (swp)
17758314Sache    *swp = sz[0];
17858314Sache  if (shp)
17958314Sache    *shp = sz[1];
18058314Sache}
18158314Sache#endif
18258314Sache
18321308Sache/* Get readline's idea of the screen size.  TTY is a file descriptor open
18421308Sache   to the terminal.  If IGNORE_ENV is true, we do not pay attention to the
18521308Sache   values of $LINES and $COLUMNS.  The tests for TERM_STRING_BUFFER being
18621308Sache   non-null serve to check whether or not we have initialized termcap. */
18721308Sachevoid
18821308Sache_rl_get_screen_size (tty, ignore_env)
18921308Sache     int tty, ignore_env;
19021308Sache{
19121308Sache  char *ss;
19221308Sache#if defined (TIOCGWINSZ)
19321308Sache  struct winsize window_size;
19421308Sache#endif /* TIOCGWINSZ */
19521308Sache
19621308Sache#if defined (TIOCGWINSZ)
19721308Sache  if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
19821308Sache    {
19975409Sache      _rl_screenwidth = (int) window_size.ws_col;
20075409Sache      _rl_screenheight = (int) window_size.ws_row;
20121308Sache    }
20221308Sache#endif /* TIOCGWINSZ */
20321308Sache
20426497Sache#if defined (__EMX__)
20575409Sache  _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
20626497Sache#endif
20726497Sache
20821308Sache  /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
20921308Sache     is unset. */
21075409Sache  if (_rl_screenwidth <= 0)
21121308Sache    {
21275409Sache      if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS")))
21375409Sache	_rl_screenwidth = atoi (ss);
21421308Sache
21558314Sache#if !defined (__DJGPP__)
21675409Sache      if (_rl_screenwidth <= 0 && term_string_buffer)
21775409Sache	_rl_screenwidth = tgetnum ("co");
21858314Sache#endif
21921308Sache    }
22021308Sache
22121308Sache  /* Environment variable LINES overrides setting of "li" if IGNORE_ENV
22221308Sache     is unset. */
22375409Sache  if (_rl_screenheight <= 0)
22421308Sache    {
22575409Sache      if (ignore_env == 0 && (ss = sh_get_env_value ("LINES")))
22675409Sache	_rl_screenheight = atoi (ss);
22721308Sache
22858314Sache#if !defined (__DJGPP__)
22975409Sache      if (_rl_screenheight <= 0 && term_string_buffer)
23075409Sache	_rl_screenheight = tgetnum ("li");
23158314Sache#endif
23221308Sache    }
23321308Sache
23421308Sache  /* If all else fails, default to 80x24 terminal. */
23575409Sache  if (_rl_screenwidth <= 1)
23675409Sache    _rl_screenwidth = 80;
23721308Sache
23875409Sache  if (_rl_screenheight <= 0)
23975409Sache    _rl_screenheight = 24;
24021308Sache
24121308Sache  /* If we're being compiled as part of bash, set the environment
24221308Sache     variables $LINES and $COLUMNS to new values.  Otherwise, just
24321308Sache     do a pair of putenv () or setenv () calls. */
24475409Sache  sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth);
24521308Sache
24658314Sache  if (_rl_term_autowrap == 0)
24775409Sache    _rl_screenwidth--;
24821308Sache
24975409Sache  _rl_screenchars = _rl_screenwidth * _rl_screenheight;
25021308Sache}
25121308Sache
25221308Sachevoid
25321308Sache_rl_set_screen_size (rows, cols)
25421308Sache     int rows, cols;
25521308Sache{
25675409Sache  if (rows == 0 || cols == 0)
25775409Sache    return;
25821308Sache
25975409Sache  _rl_screenheight = rows;
26075409Sache  _rl_screenwidth = cols;
26175409Sache
26221308Sache  if (_rl_term_autowrap == 0)
26375409Sache    _rl_screenwidth--;
26421308Sache
26575409Sache  _rl_screenchars = _rl_screenwidth * _rl_screenheight;
26621308Sache}
26721308Sache
26847558Sachevoid
26975409Sacherl_set_screen_size (rows, cols)
27075409Sache     int rows, cols;
27175409Sache{
27275409Sache  _rl_set_screen_size (rows, cols);
27375409Sache}
27475409Sache
27575409Sachevoid
27675409Sacherl_get_screen_size (rows, cols)
27775409Sache     int *rows, *cols;
27875409Sache{
27975409Sache  if (rows)
28075409Sache    *rows = _rl_screenheight;
28175409Sache  if (cols)
28275409Sache    *cols = _rl_screenwidth;
28375409Sache}
28475409Sache
28575409Sachevoid
28647558Sacherl_resize_terminal ()
28747558Sache{
28847558Sache  if (readline_echoing_p)
28947558Sache    {
29047558Sache      _rl_get_screen_size (fileno (rl_instream), 1);
291119614Sache      if (CUSTOM_REDISPLAY_FUNC ())
292119614Sache	rl_forced_update_display ();
293119614Sache      else
294119614Sache	_rl_redisplay_after_sigwinch ();
29547558Sache    }
29647558Sache}
29747558Sache
29821308Sachestruct _tc_string {
29975409Sache     const char *tc_var;
30021308Sache     char **tc_value;
30121308Sache};
30221308Sache
30321308Sache/* This should be kept sorted, just in case we decide to change the
30421308Sache   search algorithm to something smarter. */
30521308Sachestatic struct _tc_string tc_strings[] =
30621308Sache{
307119614Sache  { "@7", &_rl_term_at7 },
30875409Sache  { "DC", &_rl_term_DC },
30975409Sache  { "IC", &_rl_term_IC },
31075409Sache  { "ce", &_rl_term_clreol },
31175409Sache  { "cl", &_rl_term_clrpag },
31275409Sache  { "cr", &_rl_term_cr },
31375409Sache  { "dc", &_rl_term_dc },
31475409Sache  { "ei", &_rl_term_ei },
31575409Sache  { "ic", &_rl_term_ic },
31675409Sache  { "im", &_rl_term_im },
317119614Sache  { "kH", &_rl_term_kH },	/* home down ?? */
318119614Sache  { "kI", &_rl_term_kI },	/* insert */
31975409Sache  { "kd", &_rl_term_kd },
320119614Sache  { "ke", &_rl_term_ke },	/* end keypad mode */
32175409Sache  { "kh", &_rl_term_kh },	/* home */
32275409Sache  { "kl", &_rl_term_kl },
32375409Sache  { "kr", &_rl_term_kr },
324119614Sache  { "ks", &_rl_term_ks },	/* start keypad mode */
32575409Sache  { "ku", &_rl_term_ku },
32675409Sache  { "le", &_rl_term_backspace },
32775409Sache  { "mm", &_rl_term_mm },
32875409Sache  { "mo", &_rl_term_mo },
32921308Sache#if defined (HACK_TERMCAP_MOTION)
33075409Sache  { "nd", &_rl_term_forward_char },
33121308Sache#endif
33275409Sache  { "pc", &_rl_term_pc },
33375409Sache  { "up", &_rl_term_up },
33475409Sache  { "vb", &_rl_visible_bell },
335119614Sache  { "vs", &_rl_term_vs },
336119614Sache  { "ve", &_rl_term_ve },
33721308Sache};
33821308Sache
33921308Sache#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
34021308Sache
34121308Sache/* Read the desired terminal capability strings into BP.  The capabilities
34221308Sache   are described in the TC_STRINGS table. */
34321308Sachestatic void
34421308Sacheget_term_capabilities (bp)
34521308Sache     char **bp;
34621308Sache{
34758314Sache#if !defined (__DJGPP__)	/* XXX - doesn't DJGPP have a termcap library? */
34821308Sache  register int i;
34921308Sache
35021308Sache  for (i = 0; i < NUM_TC_STRINGS; i++)
351119614Sache#  ifdef __LCC__
352119614Sache    *(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp);
353119614Sache#  else
35421308Sache    *(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
355119614Sache#  endif
35658314Sache#endif
35721308Sache  tcap_initialized = 1;
35821308Sache}
35921308Sache
36021308Sacheint
36121308Sache_rl_init_terminal_io (terminal_name)
36275409Sache     const char *terminal_name;
36321308Sache{
36475409Sache  const char *term;
36575409Sache  char *buffer;
36658314Sache  int tty, tgetent_ret;
36721308Sache
36875409Sache  term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
36975409Sache  _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL;
37058314Sache  tty = rl_instream ? fileno (rl_instream) : 0;
37175409Sache  _rl_screenwidth = _rl_screenheight = 0;
37221308Sache
37358314Sache  if (term == 0)
37458314Sache    term = "dumb";
37521308Sache
37658314Sache  /* I've separated this out for later work on not calling tgetent at all
37758314Sache     if the calling application has supplied a custom redisplay function,
37858314Sache     (and possibly if the application has supplied a custom input function). */
37958314Sache  if (CUSTOM_REDISPLAY_FUNC())
38058314Sache    {
38158314Sache      tgetent_ret = -1;
38258314Sache    }
38358314Sache  else
38458314Sache    {
38558314Sache      if (term_string_buffer == 0)
386119614Sache	term_string_buffer = (char *)xmalloc(2032);
38721308Sache
38858314Sache      if (term_buffer == 0)
389119614Sache	term_buffer = (char *)xmalloc(4080);
39021308Sache
39158314Sache      buffer = term_string_buffer;
39221308Sache
39358314Sache      tgetent_ret = tgetent (term_buffer, term);
39458314Sache    }
39521308Sache
39658314Sache  if (tgetent_ret <= 0)
39721308Sache    {
39858314Sache      FREE (term_string_buffer);
39958314Sache      FREE (term_buffer);
40058314Sache      buffer = term_buffer = term_string_buffer = (char *)NULL;
40158314Sache
40258314Sache      _rl_term_autowrap = 0;	/* used by _rl_get_screen_size */
40358314Sache
40458314Sache#if defined (__EMX__)
40575409Sache      _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
40675409Sache      _rl_screenwidth--;
40758314Sache#else /* !__EMX__ */
40858314Sache      _rl_get_screen_size (tty, 0);
40958314Sache#endif /* !__EMX__ */
41058314Sache
41158314Sache      /* Defaults. */
41275409Sache      if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
41358314Sache        {
41475409Sache	  _rl_screenwidth = 79;
41575409Sache	  _rl_screenheight = 24;
41658314Sache        }
41758314Sache
41858314Sache      /* Everything below here is used by the redisplay code (tputs). */
41975409Sache      _rl_screenchars = _rl_screenwidth * _rl_screenheight;
42075409Sache      _rl_term_cr = "\r";
42175409Sache      _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
42275409Sache      _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
42375409Sache      _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
424119614Sache      _rl_term_kh = _rl_term_kH = _rl_term_kI = (char *)NULL;
425119614Sache      _rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL;
42675409Sache      _rl_term_mm = _rl_term_mo = (char *)NULL;
427119614Sache      _rl_term_ve = _rl_term_vs = (char *)NULL;
42821308Sache#if defined (HACK_TERMCAP_MOTION)
42921308Sache      term_forward_char = (char *)NULL;
43021308Sache#endif
43175409Sache      _rl_terminal_can_insert = term_has_meta = 0;
43258314Sache
43358314Sache      /* Reasonable defaults for tgoto().  Readline currently only uses
43475409Sache         tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we
43558314Sache         change that later... */
43658314Sache      PC = '\0';
43775409Sache      BC = _rl_term_backspace = "\b";
43875409Sache      UP = _rl_term_up;
43958314Sache
44021308Sache      return 0;
44121308Sache    }
44221308Sache
44321308Sache  get_term_capabilities (&buffer);
44421308Sache
44521308Sache  /* Set up the variables that the termcap library expects the application
44621308Sache     to provide. */
44775409Sache  PC = _rl_term_pc ? *_rl_term_pc : 0;
44875409Sache  BC = _rl_term_backspace;
44975409Sache  UP = _rl_term_up;
45021308Sache
45175409Sache  if (!_rl_term_cr)
45275409Sache    _rl_term_cr = "\r";
45321308Sache
45421308Sache  _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
45521308Sache
45621308Sache  _rl_get_screen_size (tty, 0);
45721308Sache
45821308Sache  /* "An application program can assume that the terminal can do
45921308Sache      character insertion if *any one of* the capabilities `IC',
46021308Sache      `im', `ic' or `ip' is provided."  But we can't do anything if
46121308Sache      only `ip' is provided, so... */
46275409Sache  _rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic);
46321308Sache
46421308Sache  /* Check to see if this terminal has a meta key and clear the capability
46521308Sache     variables if there is none. */
46621308Sache  term_has_meta = (tgetflag ("km") || tgetflag ("MT"));
46721308Sache  if (!term_has_meta)
46875409Sache    _rl_term_mm = _rl_term_mo = (char *)NULL;
46921308Sache
47021308Sache  /* Attempt to find and bind the arrow keys.  Do not override already
47121308Sache     bound keys in an overzealous attempt, however. */
47221308Sache
473119614Sache  bind_termcap_arrow_keys (emacs_standard_keymap);
47421308Sache
475119614Sache#if defined (VI_MODE)
476119614Sache  bind_termcap_arrow_keys (vi_movement_keymap);
477119614Sache  bind_termcap_arrow_keys (vi_insertion_keymap);
478119614Sache#endif /* VI_MODE */
47921308Sache
480119614Sache  return 0;
481119614Sache}
482119614Sache
483119614Sache/* Bind the arrow key sequences from the termcap description in MAP. */
484119614Sachestatic void
485119614Sachebind_termcap_arrow_keys (map)
486119614Sache     Keymap map;
487119614Sache{
488119614Sache  Keymap xkeymap;
489119614Sache
490119614Sache  xkeymap = _rl_keymap;
491119614Sache  _rl_keymap = map;
492119614Sache
49375409Sache  _rl_bind_if_unbound (_rl_term_ku, rl_get_previous_history);
49475409Sache  _rl_bind_if_unbound (_rl_term_kd, rl_get_next_history);
49575409Sache  _rl_bind_if_unbound (_rl_term_kr, rl_forward);
49675409Sache  _rl_bind_if_unbound (_rl_term_kl, rl_backward);
49721308Sache
49875409Sache  _rl_bind_if_unbound (_rl_term_kh, rl_beg_of_line);	/* Home */
499119614Sache  _rl_bind_if_unbound (_rl_term_at7, rl_end_of_line);	/* End */
50021308Sache
50121308Sache  _rl_keymap = xkeymap;
50221308Sache}
50321308Sache
50421308Sachechar *
50521308Sacherl_get_termcap (cap)
50675409Sache     const char *cap;
50721308Sache{
50821308Sache  register int i;
50921308Sache
51021308Sache  if (tcap_initialized == 0)
51121308Sache    return ((char *)NULL);
51221308Sache  for (i = 0; i < NUM_TC_STRINGS; i++)
51321308Sache    {
51421308Sache      if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
51521308Sache        return *(tc_strings[i].tc_value);
51621308Sache    }
51721308Sache  return ((char *)NULL);
51821308Sache}
51921308Sache
52026497Sache/* Re-initialize the terminal considering that the TERM/TERMCAP variable
52126497Sache   has changed. */
52226497Sacheint
52326497Sacherl_reset_terminal (terminal_name)
52475409Sache     const char *terminal_name;
52526497Sache{
52626497Sache  _rl_init_terminal_io (terminal_name);
52726497Sache  return 0;
52826497Sache}
52926497Sache
53021308Sache/* A function for the use of tputs () */
53135486Sache#ifdef _MINIX
53235486Sachevoid
53335486Sache_rl_output_character_function (c)
53435486Sache     int c;
53535486Sache{
53635486Sache  putc (c, _rl_out_stream);
53735486Sache}
53835486Sache#else /* !_MINIX */
53921308Sacheint
54021308Sache_rl_output_character_function (c)
54121308Sache     int c;
54221308Sache{
54321308Sache  return putc (c, _rl_out_stream);
54421308Sache}
54535486Sache#endif /* !_MINIX */
54658314Sache
54721308Sache/* Write COUNT characters from STRING to the output stream. */
54821308Sachevoid
54921308Sache_rl_output_some_chars (string, count)
55075409Sache     const char *string;
55121308Sache     int count;
55221308Sache{
55321308Sache  fwrite (string, 1, count, _rl_out_stream);
55421308Sache}
55521308Sache
55621308Sache/* Move the cursor back. */
55721308Sacheint
55821308Sache_rl_backspace (count)
55921308Sache     int count;
56021308Sache{
56121308Sache  register int i;
56221308Sache
56375409Sache  if (_rl_term_backspace)
56421308Sache    for (i = 0; i < count; i++)
56575409Sache      tputs (_rl_term_backspace, 1, _rl_output_character_function);
56621308Sache  else
56721308Sache    for (i = 0; i < count; i++)
56821308Sache      putc ('\b', _rl_out_stream);
56921308Sache  return 0;
57021308Sache}
57121308Sache
57221308Sache/* Move to the start of the next line. */
57321308Sacheint
57475409Sacherl_crlf ()
57521308Sache{
57621308Sache#if defined (NEW_TTY_DRIVER)
57775409Sache  if (_rl_term_cr)
57875409Sache    tputs (_rl_term_cr, 1, _rl_output_character_function);
57921308Sache#endif /* NEW_TTY_DRIVER */
58021308Sache  putc ('\n', _rl_out_stream);
58121308Sache  return 0;
58221308Sache}
58321308Sache
58421308Sache/* Ring the terminal bell. */
58521308Sacheint
58675409Sacherl_ding ()
58721308Sache{
58821308Sache  if (readline_echoing_p)
58921308Sache    {
59021308Sache      switch (_rl_bell_preference)
59121308Sache        {
59221308Sache	case NO_BELL:
59321308Sache	default:
59421308Sache	  break;
59521308Sache	case VISIBLE_BELL:
59675409Sache	  if (_rl_visible_bell)
59721308Sache	    {
59875409Sache	      tputs (_rl_visible_bell, 1, _rl_output_character_function);
59921308Sache	      break;
60021308Sache	    }
60121308Sache	  /* FALLTHROUGH */
60221308Sache	case AUDIBLE_BELL:
60321308Sache	  fprintf (stderr, "\007");
60421308Sache	  fflush (stderr);
60521308Sache	  break;
60621308Sache        }
60721308Sache      return (0);
60821308Sache    }
60921308Sache  return (-1);
61021308Sache}
61121308Sache
61221308Sache/* **************************************************************** */
61321308Sache/*								    */
61421308Sache/*	 	Controlling the Meta Key and Keypad		    */
61521308Sache/*								    */
61621308Sache/* **************************************************************** */
61721308Sache
61826497Sachevoid
61921308Sache_rl_enable_meta_key ()
62021308Sache{
62158314Sache#if !defined (__DJGPP__)
62275409Sache  if (term_has_meta && _rl_term_mm)
62375409Sache    tputs (_rl_term_mm, 1, _rl_output_character_function);
62458314Sache#endif
62521308Sache}
62621308Sache
62721308Sachevoid
62821308Sache_rl_control_keypad (on)
62921308Sache     int on;
63021308Sache{
63158314Sache#if !defined (__DJGPP__)
63275409Sache  if (on && _rl_term_ks)
63375409Sache    tputs (_rl_term_ks, 1, _rl_output_character_function);
63475409Sache  else if (!on && _rl_term_ke)
63575409Sache    tputs (_rl_term_ke, 1, _rl_output_character_function);
63658314Sache#endif
63721308Sache}
638119614Sache
639119614Sache/* **************************************************************** */
640119614Sache/*								    */
641119614Sache/*	 		Controlling the Cursor			    */
642119614Sache/*								    */
643119614Sache/* **************************************************************** */
644119614Sache
645119614Sache/* Set the cursor appropriately depending on IM, which is one of the
646119614Sache   insert modes (insert or overwrite).  Insert mode gets the normal
647119614Sache   cursor.  Overwrite mode gets a very visible cursor.  Only does
648119614Sache   anything if we have both capabilities. */
649119614Sachevoid
650119614Sache_rl_set_cursor (im, force)
651119614Sache     int im, force;
652119614Sache{
653119614Sache  if (_rl_term_ve && _rl_term_vs)
654119614Sache    {
655119614Sache      if (force || im != rl_insert_mode)
656119614Sache	{
657119614Sache	  if (im == RL_IM_OVERWRITE)
658119614Sache	    tputs (_rl_term_vs, 1, _rl_output_character_function);
659119614Sache	  else
660119614Sache	    tputs (_rl_term_ve, 1, _rl_output_character_function);
661119614Sache	}
662119614Sache    }
663119614Sache}
664