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