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