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