1 /* terminal.c -- controlling the terminal with termcap. */
2 
3 /* Copyright (C) 1996-2006 Free Software Foundation, Inc.
4 
5    This file is part of the GNU Readline Library, a library for
6    reading lines of text with interactive input and history editing.
7 
8    The GNU Readline Library is free software; you can redistribute it
9    and/or modify it under the terms of the GNU General Public License
10    as published by the Free Software Foundation; either version 2, or
11    (at your option) any later version.
12 
13    The GNU Readline Library is distributed in the hope that it will be
14    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    The GNU General Public License is often shipped with GNU software, and
19    is generally kept in a file called COPYING or LICENSE.  If you do not
20    have a copy of the license, write to the Free Software Foundation,
21    51 Franklin Street, Fifth Floor, Boston, MA  02110-1335  USA. */
22 #define READLINE_LIBRARY
23 
24 #if defined (HAVE_CONFIG_H)
25 #  include "config_readline.h"
26 #endif
27 
28 #include <sys/types.h>
29 #include "posixstat.h"
30 #include <fcntl.h>
31 #if defined (HAVE_SYS_FILE_H)
32 #  include <sys/file.h>
33 #endif /* HAVE_SYS_FILE_H */
34 
35 #if defined (HAVE_UNISTD_H)
36 #  include <unistd.h>
37 #endif /* HAVE_UNISTD_H */
38 
39 #if defined (HAVE_STDLIB_H)
40 #  include <stdlib.h>
41 #else
42 #  include "ansi_stdlib.h"
43 #endif /* HAVE_STDLIB_H */
44 
45 #if defined (HAVE_LOCALE_H)
46 #  include <locale.h>
47 #endif
48 
49 #include <stdio.h>
50 
51 /* System-specific feature definitions and include files. */
52 #include "rldefs.h"
53 
54 #if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ)
55 #  include <sys/ioctl.h>
56 #endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */
57 
58 #include "rltty.h"
59 #include "tcap.h"
60 
61 /* Some standard library routines. */
62 #include "readline.h"
63 #include "history.h"
64 
65 #include "rlprivate.h"
66 #include "rlshell.h"
67 #include "xmalloc.h"
68 
69 #if defined (__MINGW32__)
70 #  include <windows.h>
71 #  include <wincon.h>
72 
73 static void _win_get_screensize PARAMS((int *, int *));
74 #endif
75 
76 #if defined (__EMX__)
77 static void _emx_get_screensize PARAMS((int *, int *));
78 #endif
79 
80 #define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
81 #define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
82 
83 /*  If the calling application sets this to a non-zero value, readline will
84     use the $LINES and $COLUMNS environment variables to set its idea of the
85     window size before interrogating the kernel. */
86 int rl_prefer_env_winsize = 0;
87 
88 /* **************************************************************** */
89 /*								    */
90 /*			Terminal and Termcap			    */
91 /*								    */
92 /* **************************************************************** */
93 
94 static char *term_buffer = (char *)NULL;
95 static char *term_string_buffer = (char *)NULL;
96 
97 static int tcap_initialized;
98 
99 #if !defined (__linux__)
100 #  if defined (__EMX__) || defined (NEED_EXTERN_PC)
101 extern
102 #  endif /* __EMX__ || NEED_EXTERN_PC */
103 char PC, *BC, *UP;
104 #endif /* __linux__ */
105 
106 /* Some strings to control terminal actions.  These are output by tputs (). */
107 const char *_rl_term_clreol;
108 const char *_rl_term_clrpag;
109 const char *_rl_term_cr;
110 const char *_rl_term_backspace;
111 char _rl_term_backspace_default[2] = { '\b', 0 };
112 const char *_rl_term_goto;
113 const char *_rl_term_pc;
114 
115 /* Non-zero if we determine that the terminal can do character insertion. */
116 int _rl_terminal_can_insert = 0;
117 
118 /* How to insert characters. */
119 const char *_rl_term_im;
120 const char *_rl_term_ei;
121 const char *_rl_term_ic;
122 const char *_rl_term_ip;
123 const char *_rl_term_IC;
124 
125 /* How to delete characters. */
126 const char *_rl_term_dc;
127 const char *_rl_term_DC;
128 
129 const char *_rl_term_forward_char;
130 
131 /* How to go up a line. */
132 const char *_rl_term_up;
133 char _rl_term_up_default[2] = { 0, 0 };
134 
135 /* A visible bell; char if the terminal can be made to flash the screen. */
136 static const char *_rl_visible_bell;
137 
138 /* Non-zero means the terminal can auto-wrap lines. */
139 int _rl_term_autowrap = -1;
140 
141 /* Non-zero means that this terminal has a meta key. */
142 static int term_has_meta;
143 
144 /* The sequences to write to turn on and off the meta key, if this
145    terminal has one. */
146 static const char *_rl_term_mm;
147 static const char *_rl_term_mo;
148 
149 /* The key sequences output by the arrow keys, if this terminal has any. */
150 static const char *_rl_term_ku;
151 static const char *_rl_term_kd;
152 static const char *_rl_term_kr;
153 static const char *_rl_term_kl;
154 
155 /* How to initialize and reset the arrow keys, if this terminal has any. */
156 static const char *_rl_term_ks;
157 static const char *_rl_term_ke;
158 
159 /* The key sequences sent by the Home and End keys, if any. */
160 static const char *_rl_term_kh;
161 static const char *_rl_term_kH;
162 static const char *_rl_term_at7;	/* @7 */
163 
164 /* Delete key */
165 static const char *_rl_term_kD;
166 
167 /* Insert key */
168 static const char *_rl_term_kI;
169 
170 /* Cursor control */
171 static const char *_rl_term_vs;	/* very visible */
172 static const char *_rl_term_ve;	/* normal */
173 
174 static void bind_termcap_arrow_keys PARAMS((Keymap));
175 
176 /* Variables that hold the screen dimensions, used by the display code. */
177 int _rl_screenwidth, _rl_screenheight, _rl_screenchars;
178 
179 /* Non-zero means the user wants to enable the keypad. */
180 int _rl_enable_keypad;
181 
182 /* Non-zero means the user wants to enable a meta key. */
183 int _rl_enable_meta = 1;
184 
185 #if defined (__EMX__)
186 static void
_emx_get_screensize(swp,shp)187 _emx_get_screensize (swp, shp)
188      int *swp, *shp;
189 {
190   int sz[2];
191 
192   _scrsize (sz);
193 
194   if (swp)
195     *swp = sz[0];
196   if (shp)
197     *shp = sz[1];
198 }
199 #endif
200 
201 #if defined (__MINGW32__)
202 static void
_win_get_screensize(swp,shp)203 _win_get_screensize (swp, shp)
204      int *swp, *shp;
205 {
206   HANDLE hConOut;
207   CONSOLE_SCREEN_BUFFER_INFO scr;
208 
209   hConOut = GetStdHandle (STD_OUTPUT_HANDLE);
210   if (hConOut != INVALID_HANDLE_VALUE)
211     {
212       if (GetConsoleScreenBufferInfo (hConOut, &scr))
213 	{
214 	  *swp = scr.dwSize.X;
215 	  *shp = scr.srWindow.Bottom - scr.srWindow.Top + 1;
216 	}
217     }
218 }
219 #endif
220 
221 /* Get readline's idea of the screen size.  TTY is a file descriptor open
222    to the terminal.  If IGNORE_ENV is true, we do not pay attention to the
223    values of $LINES and $COLUMNS.  The tests for TERM_STRING_BUFFER being
224    non-null serve to check whether or not we have initialized termcap. */
225 void
_rl_get_screen_size(tty,ignore_env)226 _rl_get_screen_size (tty, ignore_env)
227      int tty, ignore_env;
228 {
229   char *ss;
230 #if defined (TIOCGWINSZ)
231   struct winsize window_size;
232 #endif /* TIOCGWINSZ */
233   int wr, wc;
234 
235   wr = wc = -1;
236 #if defined (TIOCGWINSZ)
237   if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
238     {
239       wc = (int) window_size.ws_col;
240       wr = (int) window_size.ws_row;
241     }
242 #endif /* TIOCGWINSZ */
243 
244 #if defined (__EMX__)
245   _emx_get_screensize (&wc, &wr);
246 #elif defined (__MINGW32__)
247   _win_get_screensize (&wc, &wr);
248 #endif
249 
250   if (ignore_env || rl_prefer_env_winsize == 0)
251     {
252       _rl_screenwidth = wc;
253       _rl_screenheight = wr;
254     }
255   else
256     _rl_screenwidth = _rl_screenheight = -1;
257 
258   /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
259      is unset.  If we prefer the environment, check it first before
260      assigning the value returned by the kernel. */
261   if (_rl_screenwidth <= 0)
262     {
263       if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS")))
264 	_rl_screenwidth = atoi (ss);
265 
266       if (_rl_screenwidth <= 0)
267         _rl_screenwidth = wc;
268 
269 #if !defined (__DJGPP__)
270       if (_rl_screenwidth <= 0 && term_string_buffer)
271 	_rl_screenwidth = tgetnum ((char *)"co");
272 #endif
273     }
274 
275   /* Environment variable LINES overrides setting of "li" if IGNORE_ENV
276      is unset. */
277   if (_rl_screenheight <= 0)
278     {
279       if (ignore_env == 0 && (ss = sh_get_env_value ("LINES")))
280 	_rl_screenheight = atoi (ss);
281 
282       if (_rl_screenheight <= 0)
283         _rl_screenheight = wr;
284 
285 #if !defined (__DJGPP__)
286       if (_rl_screenheight <= 0 && term_string_buffer)
287 	_rl_screenheight = tgetnum ((char *)"li");
288 #endif
289     }
290 
291   /* If all else fails, default to 80x24 terminal. */
292   if (_rl_screenwidth <= 1)
293     _rl_screenwidth = 80;
294 
295   if (_rl_screenheight <= 0)
296     _rl_screenheight = 24;
297 
298   /* If we're being compiled as part of bash, set the environment
299      variables $LINES and $COLUMNS to new values.  Otherwise, just
300      do a pair of putenv () or setenv () calls. */
301   sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth);
302 
303   if (_rl_term_autowrap == 0)
304     _rl_screenwidth--;
305 
306   _rl_screenchars = _rl_screenwidth * _rl_screenheight;
307 }
308 
309 void
_rl_set_screen_size(rows,cols)310 _rl_set_screen_size (rows, cols)
311      int rows, cols;
312 {
313   if (_rl_term_autowrap == -1)
314     _rl_init_terminal_io (rl_terminal_name);
315 
316   if (rows > 0)
317     _rl_screenheight = rows;
318   if (cols > 0)
319     {
320       _rl_screenwidth = cols;
321       if (_rl_term_autowrap == 0)
322 	_rl_screenwidth--;
323     }
324 
325   if (rows > 0 || cols > 0)
326     _rl_screenchars = _rl_screenwidth * _rl_screenheight;
327 }
328 
329 void
rl_set_screen_size(rows,cols)330 rl_set_screen_size (rows, cols)
331      int rows, cols;
332 {
333   _rl_set_screen_size (rows, cols);
334 }
335 
336 void
rl_get_screen_size(rows,cols)337 rl_get_screen_size (rows, cols)
338      int *rows, *cols;
339 {
340   if (rows)
341     *rows = _rl_screenheight;
342   if (cols)
343     *cols = _rl_screenwidth;
344 }
345 
346 void
rl_reset_screen_size()347 rl_reset_screen_size ()
348 {
349   _rl_get_screen_size (fileno (rl_instream), 0);
350 }
351 
352 void
rl_resize_terminal()353 rl_resize_terminal ()
354 {
355   if (readline_echoing_p)
356     {
357       _rl_get_screen_size (fileno (rl_instream), 1);
358       if (CUSTOM_REDISPLAY_FUNC ())
359 	rl_forced_update_display ();
360       else
361 	_rl_redisplay_after_sigwinch ();
362     }
363 }
364 
365 struct _tc_string {
366      const char *tc_var;
367      const char **tc_value;
368 };
369 
370 /* This should be kept sorted, just in case we decide to change the
371    search algorithm to something smarter. */
372 static struct _tc_string tc_strings[] =
373 {
374   { "@7", &_rl_term_at7 },
375   { "DC", &_rl_term_DC },
376   { "IC", &_rl_term_IC },
377   { "ce", &_rl_term_clreol },
378   { "cl", &_rl_term_clrpag },
379   { "cr", &_rl_term_cr },
380   { "dc", &_rl_term_dc },
381   { "ei", &_rl_term_ei },
382   { "ic", &_rl_term_ic },
383   { "im", &_rl_term_im },
384   { "kD", &_rl_term_kD },	/* delete */
385   { "kH", &_rl_term_kH },	/* home down ?? */
386   { "kI", &_rl_term_kI },	/* insert */
387   { "kd", &_rl_term_kd },
388   { "ke", &_rl_term_ke },	/* end keypad mode */
389   { "kh", &_rl_term_kh },	/* home */
390   { "kl", &_rl_term_kl },
391   { "kr", &_rl_term_kr },
392   { "ks", &_rl_term_ks },	/* start keypad mode */
393   { "ku", &_rl_term_ku },
394   { "le", &_rl_term_backspace },
395   { "mm", &_rl_term_mm },
396   { "mo", &_rl_term_mo },
397   { "nd", &_rl_term_forward_char },
398   { "pc", &_rl_term_pc },
399   { "up", &_rl_term_up },
400   { "vb", &_rl_visible_bell },
401   { "vs", &_rl_term_vs },
402   { "ve", &_rl_term_ve },
403 };
404 
405 #define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
406 
407 /* Read the desired terminal capability strings into BP.  The capabilities
408    are described in the TC_STRINGS table. */
409 static void
get_term_capabilities(bp)410 get_term_capabilities (bp)
411      char **bp;
412 {
413 #if !defined (__DJGPP__)	/* XXX - doesn't DJGPP have a termcap library? */
414   register unsigned int i;
415 
416   for (i = 0; i < NUM_TC_STRINGS; i++)
417     *(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp);
418 #endif
419   tcap_initialized = 1;
420 }
421 
422 int
_rl_init_terminal_io(terminal_name)423 _rl_init_terminal_io (terminal_name)
424      const char *terminal_name;
425 {
426   const char *term;
427   char *buffer;
428   int tty, tgetent_ret;
429 
430   term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
431   _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL;
432   tty = rl_instream ? fileno (rl_instream) : 0;
433 
434   if (term == 0)
435     term = "dumb";
436 
437   /* I've separated this out for later work on not calling tgetent at all
438      if the calling application has supplied a custom redisplay function,
439      (and possibly if the application has supplied a custom input function). */
440   if (CUSTOM_REDISPLAY_FUNC())
441     {
442       tgetent_ret = -1;
443     }
444   else
445     {
446       if (term_string_buffer == 0)
447 	term_string_buffer = (char *)xmalloc(2032);
448 
449       if (term_buffer == 0)
450 	term_buffer = (char *)xmalloc(4080);
451 
452       buffer = term_string_buffer;
453 
454       tgetent_ret = tgetent (term_buffer, term);
455     }
456 
457   if (tgetent_ret <= 0)
458     {
459       FREE (term_string_buffer);
460       FREE (term_buffer);
461       buffer = term_buffer = term_string_buffer = (char *)NULL;
462 
463       _rl_term_autowrap = 0;	/* used by _rl_get_screen_size */
464 
465       /* Allow calling application to set default height and width, using
466 	 rl_set_screen_size */
467       if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
468 	{
469 #if defined (__EMX__)
470 	  _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
471 	  _rl_screenwidth--;
472 #else /* !__EMX__ */
473 	  _rl_get_screen_size (tty, 0);
474 #endif /* !__EMX__ */
475 	}
476 
477       /* Defaults. */
478       if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
479         {
480 	  _rl_screenwidth = 79;
481 	  _rl_screenheight = 24;
482         }
483 
484       /* Everything below here is used by the redisplay code (tputs). */
485       _rl_screenchars = _rl_screenwidth * _rl_screenheight;
486       _rl_term_cr = "\r";
487       _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
488       _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
489       _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
490       _rl_term_kh = _rl_term_kH = _rl_term_kI = _rl_term_kD = (char *)NULL;
491       _rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL;
492       _rl_term_mm = _rl_term_mo = (char *)NULL;
493       _rl_term_ve = _rl_term_vs = (char *)NULL;
494       _rl_term_forward_char = (char *)NULL;
495       _rl_terminal_can_insert = term_has_meta = 0;
496 
497       /* Reasonable defaults for tgoto().  Readline currently only uses
498          tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we
499          change that later... */
500       PC = '\0';
501       _rl_term_backspace = _rl_term_backspace_default;
502       BC = (char*)_rl_term_backspace;
503       UP = (char*)_rl_term_up;
504 
505       return 0;
506     }
507 
508   get_term_capabilities (&buffer);
509 
510   /* Set up the variables that the termcap library expects the application
511      to provide. */
512   PC = _rl_term_pc ? *_rl_term_pc : 0;
513   BC = (char*)_rl_term_backspace;
514   UP = (char*)_rl_term_up;
515 
516   if (!_rl_term_cr)
517     _rl_term_cr = "\r";
518 
519   _rl_term_autowrap = tgetflag ((char *)"am") && tgetflag ((char *)"xn");
520 
521   /* Allow calling application to set default height and width, using
522      rl_set_screen_size */
523   if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
524     _rl_get_screen_size (tty, 0);
525 
526   /* "An application program can assume that the terminal can do
527       character insertion if *any one of* the capabilities `IC',
528       `im', `ic' or `ip' is provided."  But we can't do anything if
529       only `ip' is provided, so... */
530   _rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic);
531 
532   /* Check to see if this terminal has a meta key and clear the capability
533      variables if there is none. */
534   term_has_meta = (tgetflag ((char *)"km") || tgetflag ((char *)"MT"));
535   if (!term_has_meta)
536     _rl_term_mm = _rl_term_mo = (char *)NULL;
537 
538   /* Attempt to find and bind the arrow keys.  Do not override already
539      bound keys in an overzealous attempt, however. */
540 
541   bind_termcap_arrow_keys (emacs_standard_keymap);
542 
543 #if defined (VI_MODE)
544   bind_termcap_arrow_keys (vi_movement_keymap);
545   bind_termcap_arrow_keys (vi_insertion_keymap);
546 #endif /* VI_MODE */
547 
548   return 0;
549 }
550 
551 /* Bind the arrow key sequences from the termcap description in MAP. */
552 static void
bind_termcap_arrow_keys(map)553 bind_termcap_arrow_keys (map)
554      Keymap map;
555 {
556   Keymap xkeymap;
557 
558   xkeymap = _rl_keymap;
559   _rl_keymap = map;
560 
561   rl_bind_keyseq_if_unbound (_rl_term_ku, rl_get_previous_history);
562   rl_bind_keyseq_if_unbound (_rl_term_kd, rl_get_next_history);
563   rl_bind_keyseq_if_unbound (_rl_term_kr, rl_forward_char);
564   rl_bind_keyseq_if_unbound (_rl_term_kl, rl_backward_char);
565 
566   rl_bind_keyseq_if_unbound (_rl_term_kh, rl_beg_of_line);	/* Home */
567   rl_bind_keyseq_if_unbound (_rl_term_at7, rl_end_of_line);	/* End */
568 
569   rl_bind_keyseq_if_unbound (_rl_term_kD, rl_delete);
570 
571   _rl_keymap = xkeymap;
572 }
573 
574 const char *
rl_get_termcap(cap)575 rl_get_termcap (cap)
576      const char *cap;
577 {
578   register unsigned int i;
579 
580   if (tcap_initialized == 0)
581     return ((char *)NULL);
582   for (i = 0; i < NUM_TC_STRINGS; i++)
583     {
584       if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
585         return *(tc_strings[i].tc_value);
586     }
587   return ((char *)NULL);
588 }
589 
590 /* Re-initialize the terminal considering that the TERM/TERMCAP variable
591    has changed. */
592 int
rl_reset_terminal(terminal_name)593 rl_reset_terminal (terminal_name)
594      const char *terminal_name;
595 {
596   _rl_screenwidth = _rl_screenheight = 0;
597   _rl_init_terminal_io (terminal_name);
598   return 0;
599 }
600 
601 /* A function for the use of tputs () */
602 #ifdef _MINIX
603 void
_rl_output_character_function(c)604 _rl_output_character_function (c)
605      int c;
606 {
607   putc (c, _rl_out_stream);
608 }
609 #else /* !_MINIX */
610 int
_rl_output_character_function(c)611 _rl_output_character_function (c)
612      int c;
613 {
614   return putc (c, _rl_out_stream);
615 }
616 #endif /* !_MINIX */
617 
618 /* Write COUNT characters from STRING to the output stream. */
619 void
_rl_output_some_chars(string,count)620 _rl_output_some_chars (string, count)
621      const char *string;
622      int count;
623 {
624   if (fwrite (string, 1, count, _rl_out_stream) != (size_t)count)
625     fprintf(stderr, "Write failed\n");
626 }
627 
628 /* Move the cursor back. */
629 int
_rl_backspace(count)630 _rl_backspace (count)
631      int count;
632 {
633   register int i;
634 
635   if (_rl_term_backspace)
636     for (i = 0; i < count; i++)
637       tputs (_rl_term_backspace, 1, _rl_output_character_function);
638   else
639     for (i = 0; i < count; i++)
640       putc ('\b', _rl_out_stream);
641   return 0;
642 }
643 
644 /* Move to the start of the next line. */
645 int
rl_crlf()646 rl_crlf ()
647 {
648 #if defined (NEW_TTY_DRIVER)
649   if (_rl_term_cr)
650     tputs (_rl_term_cr, 1, _rl_output_character_function);
651 #endif /* NEW_TTY_DRIVER */
652   putc ('\n', _rl_out_stream);
653   return 0;
654 }
655 
656 /* Ring the terminal bell. */
657 int
rl_ding()658 rl_ding ()
659 {
660   if (readline_echoing_p)
661     {
662       switch (_rl_bell_preference)
663         {
664 	case NO_BELL:
665 	default:
666 	  break;
667 	case VISIBLE_BELL:
668 	  if (_rl_visible_bell)
669 	    {
670 	      tputs (_rl_visible_bell, 1, _rl_output_character_function);
671 	      break;
672 	    }
673 	  /* FALLTHROUGH */
674 	case AUDIBLE_BELL:
675 	  fprintf (stderr, "\007");
676 	  fflush (stderr);
677 	  break;
678         }
679       return (0);
680     }
681   return (-1);
682 }
683 
684 /* **************************************************************** */
685 /*								    */
686 /*	 	Controlling the Meta Key and Keypad		    */
687 /*								    */
688 /* **************************************************************** */
689 
690 void
_rl_enable_meta_key()691 _rl_enable_meta_key ()
692 {
693 #if !defined (__DJGPP__)
694   if (term_has_meta && _rl_term_mm)
695     tputs (_rl_term_mm, 1, _rl_output_character_function);
696 #endif
697 }
698 
699 void
_rl_control_keypad(on)700 _rl_control_keypad (on)
701      int on;
702 {
703 #if !defined (__DJGPP__)
704   if (on && _rl_term_ks)
705     tputs (_rl_term_ks, 1, _rl_output_character_function);
706   else if (!on && _rl_term_ke)
707     tputs (_rl_term_ke, 1, _rl_output_character_function);
708 #endif
709 }
710 
711 /* **************************************************************** */
712 /*								    */
713 /*	 		Controlling the Cursor			    */
714 /*								    */
715 /* **************************************************************** */
716 
717 /* Set the cursor appropriately depending on IM, which is one of the
718    insert modes (insert or overwrite).  Insert mode gets the normal
719    cursor.  Overwrite mode gets a very visible cursor.  Only does
720    anything if we have both capabilities. */
721 void
_rl_set_cursor(im,force)722 _rl_set_cursor (im, force)
723      int im, force;
724 {
725   if (_rl_term_ve && _rl_term_vs)
726     {
727       if (force || im != rl_insert_mode)
728 	{
729 	  if (im == RL_IM_OVERWRITE)
730 	    tputs (_rl_term_vs, 1, _rl_output_character_function);
731 	  else
732 	    tputs (_rl_term_ve, 1, _rl_output_character_function);
733 	}
734     }
735 }
736