xref: /dragonfly/contrib/gdb-7/readline/terminal.c (revision 5868d2b9)
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 }
791