terminal.c revision 58314
158314Sache/* $FreeBSD: head/contrib/libreadline/terminal.c 58314 2000-03-19 22:00:57Z 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/* Non-zero means this terminal can't really do anything. */
8121308Sachestatic int dumb_term;
8221308Sache
8321308Sache#if !defined (__linux__)
8426497Sache#  if defined (__EMX__) || defined (NEED_EXTERN_PC)
8526497Sacheextern
8626497Sache#  endif /* __EMX__ || NEED_EXTERN_PC */
8726497Sachechar PC, *BC, *UP;
8821308Sache#endif /* __linux__ */
8921308Sache
9021308Sache/* Some strings to control terminal actions.  These are output by tputs (). */
9121308Sachechar *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace;
9221308Sachechar *term_pc;
9321308Sache
9421308Sache/* Non-zero if we determine that the terminal can do character insertion. */
9521308Sacheint terminal_can_insert = 0;
9621308Sache
9721308Sache/* How to insert characters. */
9821308Sachechar *term_im, *term_ei, *term_ic, *term_ip, *term_IC;
9921308Sache
10021308Sache/* How to delete characters. */
10121308Sachechar *term_dc, *term_DC;
10221308Sache
10321308Sache#if defined (HACK_TERMCAP_MOTION)
10421308Sachechar *term_forward_char;
10521308Sache#endif  /* HACK_TERMCAP_MOTION */
10621308Sache
10721308Sache/* How to go up a line. */
10821308Sachechar *term_up;
10921308Sache
11021308Sache/* A visible bell, if the terminal can be made to flash the screen. */
11121308Sachestatic char *visible_bell;
11221308Sache
11321308Sache/* Non-zero means the terminal can auto-wrap lines. */
11421308Sacheint _rl_term_autowrap;
11521308Sache
11621308Sache/* Non-zero means that this terminal has a meta key. */
11721308Sachestatic int term_has_meta;
11821308Sache
11921308Sache/* The sequences to write to turn on and off the meta key, if this
12021308Sache   terminal    has one. */
12121308Sachestatic char *term_mm, *term_mo;
12221308Sache
12321308Sache/* The key sequences output by the arrow keys, if this terminal has any. */
12421308Sachestatic char *term_ku, *term_kd, *term_kr, *term_kl;
12521308Sache
12621308Sache/* How to initialize and reset the arrow keys, if this terminal has any. */
12721308Sachestatic char *term_ks, *term_ke;
12821308Sache
12921308Sache/* The key sequences sent by the Home and End keys, if any. */
13021308Sachestatic char *term_kh, *term_kH;
13121308Sache
13221308Sache/* Variables that hold the screen dimensions, used by the display code. */
13321308Sacheint screenwidth, screenheight, screenchars;
13421308Sache
13521308Sache/* Non-zero means the user wants to enable the keypad. */
13621308Sacheint _rl_enable_keypad;
13721308Sache
13821308Sache/* Non-zero means the user wants to enable a meta key. */
13921308Sacheint _rl_enable_meta = 1;
14021308Sache
14158314Sache#if defined (__EMX__)
14258314Sachestatic void
14358314Sache_emx_get_screensize (swp, shp)
14458314Sache     int *swp, *shp;
14558314Sache{
14658314Sache  int sz[2];
14758314Sache
14858314Sache  _scrsize (sz);
14958314Sache
15058314Sache  if (swp)
15158314Sache    *swp = sz[0];
15258314Sache  if (shp)
15358314Sache    *shp = sz[1];
15458314Sache}
15558314Sache#endif
15658314Sache
15721308Sache/* Get readline's idea of the screen size.  TTY is a file descriptor open
15821308Sache   to the terminal.  If IGNORE_ENV is true, we do not pay attention to the
15921308Sache   values of $LINES and $COLUMNS.  The tests for TERM_STRING_BUFFER being
16021308Sache   non-null serve to check whether or not we have initialized termcap. */
16121308Sachevoid
16221308Sache_rl_get_screen_size (tty, ignore_env)
16321308Sache     int tty, ignore_env;
16421308Sache{
16521308Sache  char *ss;
16621308Sache#if defined (TIOCGWINSZ)
16721308Sache  struct winsize window_size;
16821308Sache#endif /* TIOCGWINSZ */
16921308Sache
17021308Sache#if defined (TIOCGWINSZ)
17121308Sache  if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
17221308Sache    {
17321308Sache      screenwidth = (int) window_size.ws_col;
17421308Sache      screenheight = (int) window_size.ws_row;
17521308Sache    }
17621308Sache#endif /* TIOCGWINSZ */
17721308Sache
17826497Sache#if defined (__EMX__)
17958314Sache  _emx_get_screensize (&screenwidth, &screenheight);
18026497Sache#endif
18126497Sache
18221308Sache  /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
18321308Sache     is unset. */
18421308Sache  if (screenwidth <= 0)
18521308Sache    {
18626497Sache      if (ignore_env == 0 && (ss = get_env_value ("COLUMNS")))
18721308Sache	screenwidth = atoi (ss);
18821308Sache
18958314Sache#if !defined (__DJGPP__)
19021308Sache      if (screenwidth <= 0 && term_string_buffer)
19121308Sache	screenwidth = tgetnum ("co");
19258314Sache#endif
19321308Sache    }
19421308Sache
19521308Sache  /* Environment variable LINES overrides setting of "li" if IGNORE_ENV
19621308Sache     is unset. */
19721308Sache  if (screenheight <= 0)
19821308Sache    {
19926497Sache      if (ignore_env == 0 && (ss = get_env_value ("LINES")))
20021308Sache	screenheight = atoi (ss);
20121308Sache
20258314Sache#if !defined (__DJGPP__)
20321308Sache      if (screenheight <= 0 && term_string_buffer)
20421308Sache	screenheight = tgetnum ("li");
20558314Sache#endif
20621308Sache    }
20721308Sache
20821308Sache  /* If all else fails, default to 80x24 terminal. */
20921308Sache  if (screenwidth <= 1)
21021308Sache    screenwidth = 80;
21121308Sache
21221308Sache  if (screenheight <= 0)
21321308Sache    screenheight = 24;
21421308Sache
21521308Sache  /* If we're being compiled as part of bash, set the environment
21621308Sache     variables $LINES and $COLUMNS to new values.  Otherwise, just
21721308Sache     do a pair of putenv () or setenv () calls. */
21821308Sache  set_lines_and_columns (screenheight, screenwidth);
21921308Sache
22058314Sache  if (_rl_term_autowrap == 0)
22121308Sache    screenwidth--;
22221308Sache
22321308Sache  screenchars = screenwidth * screenheight;
22421308Sache}
22521308Sache
22621308Sachevoid
22721308Sache_rl_set_screen_size (rows, cols)
22821308Sache     int rows, cols;
22921308Sache{
23021308Sache  screenheight = rows;
23121308Sache  screenwidth = cols;
23221308Sache
23321308Sache  if (_rl_term_autowrap == 0)
23421308Sache    screenwidth--;
23521308Sache
23621308Sache  screenchars = screenwidth * screenheight;
23721308Sache}
23821308Sache
23947558Sachevoid
24047558Sacherl_resize_terminal ()
24147558Sache{
24247558Sache  if (readline_echoing_p)
24347558Sache    {
24447558Sache      _rl_get_screen_size (fileno (rl_instream), 1);
24547558Sache      _rl_redisplay_after_sigwinch ();
24647558Sache    }
24747558Sache}
24847558Sache
24921308Sachestruct _tc_string {
25021308Sache     char *tc_var;
25121308Sache     char **tc_value;
25221308Sache};
25321308Sache
25421308Sache/* This should be kept sorted, just in case we decide to change the
25521308Sache   search algorithm to something smarter. */
25621308Sachestatic struct _tc_string tc_strings[] =
25721308Sache{
25858314Sache  { "DC", &term_DC },
25958314Sache  { "IC", &term_IC },
26058314Sache  { "ce", &term_clreol },
26158314Sache  { "cl", &term_clrpag },
26258314Sache  { "cr", &term_cr },
26358314Sache  { "dc", &term_dc },
26458314Sache  { "ei", &term_ei },
26558314Sache  { "ic", &term_ic },
26658314Sache  { "im", &term_im },
26758314Sache  { "kd", &term_kd },
26858314Sache  { "kh", &term_kh },	/* home */
26958314Sache  { "@7", &term_kH },	/* end */
27058314Sache  { "kl", &term_kl },
27158314Sache  { "kr", &term_kr },
27258314Sache  { "ku", &term_ku },
27358314Sache  { "ks", &term_ks },
27458314Sache  { "ke", &term_ke },
27558314Sache  { "le", &term_backspace },
27658314Sache  { "mm", &term_mm },
27758314Sache  { "mo", &term_mo },
27821308Sache#if defined (HACK_TERMCAP_MOTION)
27958314Sache  { "nd", &term_forward_char },
28021308Sache#endif
28158314Sache  { "pc", &term_pc },
28258314Sache  { "up", &term_up },
28358314Sache  { "vb", &visible_bell },
28421308Sache};
28521308Sache
28621308Sache#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
28721308Sache
28821308Sache/* Read the desired terminal capability strings into BP.  The capabilities
28921308Sache   are described in the TC_STRINGS table. */
29021308Sachestatic void
29121308Sacheget_term_capabilities (bp)
29221308Sache     char **bp;
29321308Sache{
29458314Sache#if !defined (__DJGPP__)	/* XXX - doesn't DJGPP have a termcap library? */
29521308Sache  register int i;
29621308Sache
29721308Sache  for (i = 0; i < NUM_TC_STRINGS; i++)
29821308Sache    *(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
29958314Sache#endif
30021308Sache  tcap_initialized = 1;
30121308Sache}
30221308Sache
30358314Sache#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
30458314Sache#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
30558314Sache
30621308Sacheint
30721308Sache_rl_init_terminal_io (terminal_name)
30821308Sache     char *terminal_name;
30921308Sache{
31021308Sache  char *term, *buffer;
31158314Sache  int tty, tgetent_ret;
31221308Sache  Keymap xkeymap;
31321308Sache
31426497Sache  term = terminal_name ? terminal_name : get_env_value ("TERM");
31558314Sache  term_clrpag = term_cr = term_clreol = (char *)NULL;
31658314Sache  tty = rl_instream ? fileno (rl_instream) : 0;
31758314Sache  screenwidth = screenheight = 0;
31821308Sache
31958314Sache  if (term == 0)
32058314Sache    term = "dumb";
32121308Sache
32258314Sache  /* I've separated this out for later work on not calling tgetent at all
32358314Sache     if the calling application has supplied a custom redisplay function,
32458314Sache     (and possibly if the application has supplied a custom input function). */
32558314Sache  if (CUSTOM_REDISPLAY_FUNC())
32658314Sache    {
32758314Sache      tgetent_ret = -1;
32858314Sache    }
32958314Sache  else
33058314Sache    {
33158314Sache      if (term_string_buffer == 0)
33258314Sache	term_string_buffer = xmalloc(2032);
33321308Sache
33458314Sache      if (term_buffer == 0)
33558314Sache	term_buffer = xmalloc(4080);
33621308Sache
33758314Sache      buffer = term_string_buffer;
33821308Sache
33958314Sache      tgetent_ret = tgetent (term_buffer, term);
34058314Sache    }
34121308Sache
34258314Sache  if (tgetent_ret <= 0)
34321308Sache    {
34458314Sache      FREE (term_string_buffer);
34558314Sache      FREE (term_buffer);
34658314Sache      buffer = term_buffer = term_string_buffer = (char *)NULL;
34758314Sache
34821308Sache      dumb_term = 1;
34958314Sache      _rl_term_autowrap = 0;	/* used by _rl_get_screen_size */
35058314Sache
35158314Sache#if defined (__EMX__)
35258314Sache      _emx_get_screensize (&screenwidth, &screenheight);
35358314Sache      screenwidth--;
35458314Sache#else /* !__EMX__ */
35558314Sache      _rl_get_screen_size (tty, 0);
35658314Sache#endif /* !__EMX__ */
35758314Sache
35858314Sache      /* Defaults. */
35958314Sache      if (screenwidth <= 0 || screenheight <= 0)
36058314Sache        {
36158314Sache	  screenwidth = 79;
36258314Sache	  screenheight = 24;
36358314Sache        }
36458314Sache
36558314Sache      /* Everything below here is used by the redisplay code (tputs). */
36658314Sache      screenchars = screenwidth * screenheight;
36721308Sache      term_cr = "\r";
36821308Sache      term_im = term_ei = term_ic = term_IC = (char *)NULL;
36921308Sache      term_up = term_dc = term_DC = visible_bell = (char *)NULL;
37021308Sache      term_ku = term_kd = term_kl = term_kr = (char *)NULL;
37158314Sache      term_mm = term_mo = (char *)NULL;
37221308Sache#if defined (HACK_TERMCAP_MOTION)
37321308Sache      term_forward_char = (char *)NULL;
37421308Sache#endif
37558314Sache      terminal_can_insert = term_has_meta = 0;
37658314Sache
37758314Sache      /* Reasonable defaults for tgoto().  Readline currently only uses
37858314Sache         tgoto if term_IC or term_DC is defined, but just in case we
37958314Sache         change that later... */
38058314Sache      PC = '\0';
38158314Sache      BC = term_backspace = "\b";
38258314Sache      UP = term_up;
38358314Sache
38421308Sache      return 0;
38521308Sache    }
38621308Sache
38721308Sache  get_term_capabilities (&buffer);
38821308Sache
38921308Sache  /* Set up the variables that the termcap library expects the application
39021308Sache     to provide. */
39121308Sache  PC = term_pc ? *term_pc : 0;
39221308Sache  BC = term_backspace;
39321308Sache  UP = term_up;
39421308Sache
39521308Sache  if (!term_cr)
39621308Sache    term_cr = "\r";
39721308Sache
39821308Sache  _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
39921308Sache
40021308Sache  _rl_get_screen_size (tty, 0);
40121308Sache
40221308Sache  /* "An application program can assume that the terminal can do
40321308Sache      character insertion if *any one of* the capabilities `IC',
40421308Sache      `im', `ic' or `ip' is provided."  But we can't do anything if
40521308Sache      only `ip' is provided, so... */
40621308Sache  terminal_can_insert = (term_IC || term_im || term_ic);
40721308Sache
40821308Sache  /* Check to see if this terminal has a meta key and clear the capability
40921308Sache     variables if there is none. */
41021308Sache  term_has_meta = (tgetflag ("km") || tgetflag ("MT"));
41121308Sache  if (!term_has_meta)
41221308Sache    term_mm = term_mo = (char *)NULL;
41321308Sache
41421308Sache  /* Attempt to find and bind the arrow keys.  Do not override already
41521308Sache     bound keys in an overzealous attempt, however. */
41621308Sache  xkeymap = _rl_keymap;
41721308Sache
41821308Sache  _rl_keymap = emacs_standard_keymap;
41921308Sache  _rl_bind_if_unbound (term_ku, rl_get_previous_history);
42021308Sache  _rl_bind_if_unbound (term_kd, rl_get_next_history);
42121308Sache  _rl_bind_if_unbound (term_kr, rl_forward);
42221308Sache  _rl_bind_if_unbound (term_kl, rl_backward);
42321308Sache
42421308Sache  _rl_bind_if_unbound (term_kh, rl_beg_of_line);	/* Home */
42521308Sache  _rl_bind_if_unbound (term_kH, rl_end_of_line);	/* End */
42621308Sache
42721308Sache#if defined (VI_MODE)
42821308Sache  _rl_keymap = vi_movement_keymap;
42921308Sache  _rl_bind_if_unbound (term_ku, rl_get_previous_history);
43021308Sache  _rl_bind_if_unbound (term_kd, rl_get_next_history);
43121308Sache  _rl_bind_if_unbound (term_kr, rl_forward);
43221308Sache  _rl_bind_if_unbound (term_kl, rl_backward);
43321308Sache
43421308Sache  _rl_bind_if_unbound (term_kh, rl_beg_of_line);	/* Home */
43521308Sache  _rl_bind_if_unbound (term_kH, rl_end_of_line);	/* End */
43621308Sache#endif /* VI_MODE */
43721308Sache
43821308Sache  _rl_keymap = xkeymap;
43921308Sache
44021308Sache  return 0;
44121308Sache}
44221308Sache
44321308Sachechar *
44421308Sacherl_get_termcap (cap)
44521308Sache     char *cap;
44621308Sache{
44721308Sache  register int i;
44821308Sache
44921308Sache  if (tcap_initialized == 0)
45021308Sache    return ((char *)NULL);
45121308Sache  for (i = 0; i < NUM_TC_STRINGS; i++)
45221308Sache    {
45321308Sache      if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
45421308Sache        return *(tc_strings[i].tc_value);
45521308Sache    }
45621308Sache  return ((char *)NULL);
45721308Sache}
45821308Sache
45926497Sache/* Re-initialize the terminal considering that the TERM/TERMCAP variable
46026497Sache   has changed. */
46126497Sacheint
46226497Sacherl_reset_terminal (terminal_name)
46326497Sache     char *terminal_name;
46426497Sache{
46526497Sache  _rl_init_terminal_io (terminal_name);
46626497Sache  return 0;
46726497Sache}
46826497Sache
46921308Sache/* A function for the use of tputs () */
47035486Sache#ifdef _MINIX
47135486Sachevoid
47235486Sache_rl_output_character_function (c)
47335486Sache     int c;
47435486Sache{
47535486Sache  putc (c, _rl_out_stream);
47635486Sache}
47735486Sache#else /* !_MINIX */
47821308Sacheint
47921308Sache_rl_output_character_function (c)
48021308Sache     int c;
48121308Sache{
48221308Sache  return putc (c, _rl_out_stream);
48321308Sache}
48435486Sache#endif /* !_MINIX */
48558314Sache
48621308Sache/* Write COUNT characters from STRING to the output stream. */
48721308Sachevoid
48821308Sache_rl_output_some_chars (string, count)
48921308Sache     char *string;
49021308Sache     int count;
49121308Sache{
49221308Sache  fwrite (string, 1, count, _rl_out_stream);
49321308Sache}
49421308Sache
49521308Sache/* Move the cursor back. */
49621308Sacheint
49721308Sache_rl_backspace (count)
49821308Sache     int count;
49921308Sache{
50021308Sache  register int i;
50121308Sache
50221308Sache  if (term_backspace)
50321308Sache    for (i = 0; i < count; i++)
50421308Sache      tputs (term_backspace, 1, _rl_output_character_function);
50521308Sache  else
50621308Sache    for (i = 0; i < count; i++)
50721308Sache      putc ('\b', _rl_out_stream);
50821308Sache  return 0;
50921308Sache}
51021308Sache
51121308Sache/* Move to the start of the next line. */
51221308Sacheint
51321308Sachecrlf ()
51421308Sache{
51521308Sache#if defined (NEW_TTY_DRIVER)
51621308Sache  if (term_cr)
51721308Sache    tputs (term_cr, 1, _rl_output_character_function);
51821308Sache#endif /* NEW_TTY_DRIVER */
51921308Sache  putc ('\n', _rl_out_stream);
52021308Sache  return 0;
52121308Sache}
52221308Sache
52321308Sache/* Ring the terminal bell. */
52421308Sacheint
52521308Sacheding ()
52621308Sache{
52721308Sache  if (readline_echoing_p)
52821308Sache    {
52921308Sache      switch (_rl_bell_preference)
53021308Sache        {
53121308Sache	case NO_BELL:
53221308Sache	default:
53321308Sache	  break;
53421308Sache	case VISIBLE_BELL:
53521308Sache	  if (visible_bell)
53621308Sache	    {
53721308Sache	      tputs (visible_bell, 1, _rl_output_character_function);
53821308Sache	      break;
53921308Sache	    }
54021308Sache	  /* FALLTHROUGH */
54121308Sache	case AUDIBLE_BELL:
54221308Sache	  fprintf (stderr, "\007");
54321308Sache	  fflush (stderr);
54421308Sache	  break;
54521308Sache        }
54621308Sache      return (0);
54721308Sache    }
54821308Sache  return (-1);
54921308Sache}
55021308Sache
55121308Sache/* **************************************************************** */
55221308Sache/*								    */
55321308Sache/*	 	Controlling the Meta Key and Keypad		    */
55421308Sache/*								    */
55521308Sache/* **************************************************************** */
55621308Sache
55726497Sachevoid
55821308Sache_rl_enable_meta_key ()
55921308Sache{
56058314Sache#if !defined (__DJGPP__)
56121308Sache  if (term_has_meta && term_mm)
56235486Sache    tputs (term_mm, 1, _rl_output_character_function);
56358314Sache#endif
56421308Sache}
56521308Sache
56621308Sachevoid
56721308Sache_rl_control_keypad (on)
56821308Sache     int on;
56921308Sache{
57058314Sache#if !defined (__DJGPP__)
57121308Sache  if (on && term_ks)
57235486Sache    tputs (term_ks, 1, _rl_output_character_function);
57321308Sache  else if (!on && term_ke)
57435486Sache    tputs (term_ke, 1, _rl_output_character_function);
57558314Sache#endif
57621308Sache}
577