1 /* terminal.c -- How to handle the physical terminal for Info. 2 $Id: terminal.c,v 1.5 2000/02/09 02:18:40 espie Exp $ 3 4 Copyright (C) 1988, 89, 90, 91, 92, 93, 96, 97, 98, 99 5 Free Software Foundation, Inc. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2, or (at your option) 10 any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 21 Written by Brian Fox (bfox@ai.mit.edu). */ 22 23 #include "info.h" 24 #include "terminal.h" 25 #include "termdep.h" 26 27 #include <sys/types.h> 28 #include <signal.h> 29 #include <sys/ioctl.h> /* TIOCGWINSZ on LynxOS, at least */ 30 31 /* The Unix termcap interface code. */ 32 #ifdef HAVE_NCURSES_TERMCAP_H 33 #include <ncurses/termcap.h> 34 #else 35 #ifdef HAVE_TERMCAP_H 36 #include <termcap.h> 37 #else 38 /* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC. 39 Unfortunately, PC is a global variable used by the termcap library. */ 40 #undef PC 41 42 /* Termcap requires these variables, whether we access them or not. */ 43 char *BC, *UP; 44 char PC; /* Pad character */ 45 short ospeed; /* Terminal output baud rate */ 46 extern int tgetnum (), tgetflag (), tgetent (); 47 extern char *tgetstr (), *tgoto (); 48 extern void tputs (); 49 #endif /* not HAVE_TERMCAP_H */ 50 #endif /* not HAVE_NCURSES_TERMCAP_H */ 51 52 /* Function "hooks". If you make one of these point to a function, that 53 function is called when appropriate instead of its namesake. Your 54 function is called with exactly the same arguments that were passed 55 to the namesake function. */ 56 VFunction *terminal_begin_inverse_hook = (VFunction *)NULL; 57 VFunction *terminal_end_inverse_hook = (VFunction *)NULL; 58 VFunction *terminal_prep_terminal_hook = (VFunction *)NULL; 59 VFunction *terminal_unprep_terminal_hook = (VFunction *)NULL; 60 VFunction *terminal_up_line_hook = (VFunction *)NULL; 61 VFunction *terminal_down_line_hook = (VFunction *)NULL; 62 VFunction *terminal_clear_screen_hook = (VFunction *)NULL; 63 VFunction *terminal_clear_to_eol_hook = (VFunction *)NULL; 64 VFunction *terminal_get_screen_size_hook = (VFunction *)NULL; 65 VFunction *terminal_goto_xy_hook = (VFunction *)NULL; 66 VFunction *terminal_initialize_terminal_hook = (VFunction *)NULL; 67 VFunction *terminal_new_terminal_hook = (VFunction *)NULL; 68 VFunction *terminal_put_text_hook = (VFunction *)NULL; 69 VFunction *terminal_ring_bell_hook = (VFunction *)NULL; 70 VFunction *terminal_write_chars_hook = (VFunction *)NULL; 71 VFunction *terminal_scroll_terminal_hook = (VFunction *)NULL; 72 73 /* **************************************************************** */ 74 /* */ 75 /* Terminal and Termcap */ 76 /* */ 77 /* **************************************************************** */ 78 79 /* A buffer which holds onto the current terminal description, and a pointer 80 used to float within it. And the name of the terminal. */ 81 static char *term_buffer = NULL; 82 static char *term_string_buffer = NULL; 83 static char *term_name; 84 85 /* Some strings to control terminal actions. These are output by tputs (). */ 86 static char *term_goto, *term_clreol, *term_cr, *term_clrpag; 87 static char *term_begin_use, *term_end_use; 88 static char *term_AL, *term_DL, *term_al, *term_dl; 89 90 static char *term_keypad_on, *term_keypad_off; 91 92 /* How to go up a line. */ 93 static char *term_up; 94 95 /* How to go down a line. */ 96 static char *term_dn; 97 98 /* An audible bell, if the terminal can be made to make noise. */ 99 static char *audible_bell; 100 101 /* A visible bell, if the terminal can be made to flash the screen. */ 102 static char *visible_bell; 103 104 /* The string to write to turn on the meta key, if this term has one. */ 105 static char *term_mm; 106 107 /* The string to write to turn off the meta key, if this term has one. */ 108 static char *term_mo; 109 110 /* The string to turn on inverse mode, if this term has one. */ 111 static char *term_invbeg; 112 113 /* The string to turn off inverse mode, if this term has one. */ 114 static char *term_invend; 115 116 /* Although I can't find any documentation that says this is supposed to 117 return its argument, all the code I've looked at (termutils, less) 118 does so, so fine. */ 119 static int 120 output_character_function (c) 121 int c; 122 { 123 putc (c, stdout); 124 return c; 125 } 126 127 /* Macro to send STRING to the terminal. */ 128 #define send_to_terminal(string) \ 129 do { \ 130 if (string) \ 131 tputs (string, 1, output_character_function); \ 132 } while (0) 133 134 /* Tell the terminal that we will be doing cursor addressable motion. */ 135 static void 136 terminal_begin_using_terminal () 137 { 138 RETSIGTYPE (*sigsave) (); 139 140 if (term_keypad_on) 141 send_to_terminal (term_keypad_on); 142 143 if (!term_begin_use || !*term_begin_use) 144 return; 145 146 #ifdef SIGWINCH 147 sigsave = signal (SIGWINCH, SIG_IGN); 148 #endif 149 150 send_to_terminal (term_begin_use); 151 fflush (stdout); 152 if (STREQ (term_name, "sun-cmd")) 153 /* Without this fflush and sleep, running info in a shelltool or 154 cmdtool (TERM=sun-cmd) with scrollbars loses -- the scrollbars are 155 not restored properly. 156 From: strube@physik3.gwdg.de (Hans Werner Strube). */ 157 sleep (1); 158 159 #ifdef SIGWINCH 160 signal (SIGWINCH, sigsave); 161 #endif 162 } 163 164 /* Tell the terminal that we will not be doing any more cursor 165 addressable motion. */ 166 static void 167 terminal_end_using_terminal () 168 { 169 RETSIGTYPE (*sigsave) (); 170 171 if (term_keypad_off) 172 send_to_terminal (term_keypad_off); 173 174 if (!term_end_use || !*term_end_use) 175 return; 176 177 #ifdef SIGWINCH 178 sigsave = signal (SIGWINCH, SIG_IGN); 179 #endif 180 181 send_to_terminal (term_end_use); 182 fflush (stdout); 183 if (STREQ (term_name, "sun-cmd")) 184 /* See comments at other sleep. */ 185 sleep (1); 186 187 #ifdef SIGWINCH 188 signal (SIGWINCH, sigsave); 189 #endif 190 } 191 192 /* **************************************************************** */ 193 /* */ 194 /* Necessary Terminal Functions */ 195 /* */ 196 /* **************************************************************** */ 197 198 /* The functions and variables on this page implement the user visible 199 portion of the terminal interface. */ 200 201 /* The width and height of the terminal. */ 202 int screenwidth, screenheight; 203 204 /* Non-zero means this terminal can't really do anything. */ 205 int terminal_is_dumb_p = 0; 206 207 /* Non-zero means that this terminal has a meta key. */ 208 int terminal_has_meta_p = 0; 209 210 /* Non-zero means that this terminal can produce a visible bell. */ 211 int terminal_has_visible_bell_p = 0; 212 213 /* Non-zero means to use that visible bell if at all possible. */ 214 int terminal_use_visible_bell_p = 0; 215 216 /* Non-zero means that the terminal can do scrolling. */ 217 int terminal_can_scroll = 0; 218 219 /* The key sequences output by the arrow keys, if this terminal has any. */ 220 char *term_ku = (char *)NULL; 221 char *term_kd = (char *)NULL; 222 char *term_kr = (char *)NULL; 223 char *term_kl = (char *)NULL; 224 char *term_kP = (char *)NULL; /* page-up */ 225 char *term_kN = (char *)NULL; /* page-down */ 226 227 /* Move the cursor to the terminal location of X and Y. */ 228 void 229 terminal_goto_xy (x, y) 230 int x, y; 231 { 232 if (terminal_goto_xy_hook) 233 (*terminal_goto_xy_hook) (x, y); 234 else 235 { 236 if (term_goto) 237 tputs (tgoto (term_goto, x, y), 1, output_character_function); 238 } 239 } 240 241 /* Print STRING to the terminal at the current position. */ 242 void 243 terminal_put_text (string) 244 char *string; 245 { 246 if (terminal_put_text_hook) 247 (*terminal_put_text_hook) (string); 248 else 249 { 250 printf ("%s", string); 251 } 252 } 253 254 /* Print NCHARS from STRING to the terminal at the current position. */ 255 void 256 terminal_write_chars (string, nchars) 257 char *string; 258 int nchars; 259 { 260 if (terminal_write_chars_hook) 261 (*terminal_write_chars_hook) (string, nchars); 262 else 263 { 264 if (nchars) 265 fwrite (string, 1, nchars, stdout); 266 } 267 } 268 269 /* Clear from the current position of the cursor to the end of the line. */ 270 void 271 terminal_clear_to_eol () 272 { 273 if (terminal_clear_to_eol_hook) 274 (*terminal_clear_to_eol_hook) (); 275 else 276 { 277 send_to_terminal (term_clreol); 278 } 279 } 280 281 /* Clear the entire terminal screen. */ 282 void 283 terminal_clear_screen () 284 { 285 if (terminal_clear_screen_hook) 286 (*terminal_clear_screen_hook) (); 287 else 288 { 289 send_to_terminal (term_clrpag); 290 } 291 } 292 293 /* Move the cursor up one line. */ 294 void 295 terminal_up_line () 296 { 297 if (terminal_up_line_hook) 298 (*terminal_up_line_hook) (); 299 else 300 { 301 send_to_terminal (term_up); 302 } 303 } 304 305 /* Move the cursor down one line. */ 306 void 307 terminal_down_line () 308 { 309 if (terminal_down_line_hook) 310 (*terminal_down_line_hook) (); 311 else 312 { 313 send_to_terminal (term_dn); 314 } 315 } 316 317 /* Turn on reverse video if possible. */ 318 void 319 terminal_begin_inverse () 320 { 321 if (terminal_begin_inverse_hook) 322 (*terminal_begin_inverse_hook) (); 323 else 324 { 325 send_to_terminal (term_invbeg); 326 } 327 } 328 329 /* Turn off reverse video if possible. */ 330 void 331 terminal_end_inverse () 332 { 333 if (terminal_end_inverse_hook) 334 (*terminal_end_inverse_hook) (); 335 else 336 { 337 send_to_terminal (term_invend); 338 } 339 } 340 341 /* Ring the terminal bell. The bell is run visibly if it both has one and 342 terminal_use_visible_bell_p is non-zero. */ 343 void 344 terminal_ring_bell () 345 { 346 if (terminal_ring_bell_hook) 347 (*terminal_ring_bell_hook) (); 348 else 349 { 350 if (terminal_has_visible_bell_p && terminal_use_visible_bell_p) 351 send_to_terminal (visible_bell); 352 else 353 send_to_terminal (audible_bell); 354 } 355 } 356 357 /* At the line START, delete COUNT lines from the terminal display. */ 358 static void 359 terminal_delete_lines (start, count) 360 int start, count; 361 { 362 int lines; 363 364 /* Normalize arguments. */ 365 if (start < 0) 366 start = 0; 367 368 lines = screenheight - start; 369 terminal_goto_xy (0, start); 370 if (term_DL) 371 tputs (tgoto (term_DL, 0, count), lines, output_character_function); 372 else 373 { 374 while (count--) 375 tputs (term_dl, lines, output_character_function); 376 } 377 378 fflush (stdout); 379 } 380 381 /* At the line START, insert COUNT lines in the terminal display. */ 382 static void 383 terminal_insert_lines (start, count) 384 int start, count; 385 { 386 int lines; 387 388 /* Normalize arguments. */ 389 if (start < 0) 390 start = 0; 391 392 lines = screenheight - start; 393 terminal_goto_xy (0, start); 394 395 if (term_AL) 396 tputs (tgoto (term_AL, 0, count), lines, output_character_function); 397 else 398 { 399 while (count--) 400 tputs (term_al, lines, output_character_function); 401 } 402 403 fflush (stdout); 404 } 405 406 /* Scroll an area of the terminal, starting with the region from START 407 to END, AMOUNT lines. If AMOUNT is negative, the lines are scrolled 408 towards the top of the screen, else they are scrolled towards the 409 bottom of the screen. */ 410 void 411 terminal_scroll_terminal (start, end, amount) 412 int start, end, amount; 413 { 414 if (!terminal_can_scroll) 415 return; 416 417 /* Any scrolling at all? */ 418 if (amount == 0) 419 return; 420 421 if (terminal_scroll_terminal_hook) 422 (*terminal_scroll_terminal_hook) (start, end, amount); 423 else 424 { 425 /* If we are scrolling down, delete AMOUNT lines at END. Then insert 426 AMOUNT lines at START. */ 427 if (amount > 0) 428 { 429 terminal_delete_lines (end, amount); 430 terminal_insert_lines (start, amount); 431 } 432 433 /* If we are scrolling up, delete AMOUNT lines before START. This 434 actually does the upwards scroll. Then, insert AMOUNT lines 435 after the already scrolled region (i.e., END - AMOUNT). */ 436 if (amount < 0) 437 { 438 int abs_amount = -amount; 439 terminal_delete_lines (start - abs_amount, abs_amount); 440 terminal_insert_lines (end - abs_amount, abs_amount); 441 } 442 } 443 } 444 445 /* Re-initialize the terminal considering that the TERM/TERMCAP variable 446 has changed. */ 447 void 448 terminal_new_terminal (terminal_name) 449 char *terminal_name; 450 { 451 if (terminal_new_terminal_hook) 452 (*terminal_new_terminal_hook) (terminal_name); 453 else 454 { 455 terminal_initialize_terminal (terminal_name); 456 } 457 } 458 459 /* Set the global variables SCREENWIDTH and SCREENHEIGHT. */ 460 void 461 terminal_get_screen_size () 462 { 463 if (terminal_get_screen_size_hook) 464 (*terminal_get_screen_size_hook) (); 465 else 466 { 467 screenwidth = screenheight = 0; 468 469 #if defined (TIOCGWINSZ) 470 { 471 struct winsize window_size; 472 473 if (ioctl (fileno (stdout), TIOCGWINSZ, &window_size) == 0) 474 { 475 screenwidth = (int) window_size.ws_col; 476 screenheight = (int) window_size.ws_row; 477 } 478 } 479 #endif /* TIOCGWINSZ */ 480 481 /* Environment variable COLUMNS overrides setting of "co". */ 482 if (screenwidth <= 0) 483 { 484 char *sw = getenv ("COLUMNS"); 485 486 if (sw) 487 screenwidth = atoi (sw); 488 489 if (screenwidth <= 0) 490 screenwidth = tgetnum ("co"); 491 } 492 493 /* Environment variable LINES overrides setting of "li". */ 494 if (screenheight <= 0) 495 { 496 char *sh = getenv ("LINES"); 497 498 if (sh) 499 screenheight = atoi (sh); 500 501 if (screenheight <= 0) 502 screenheight = tgetnum ("li"); 503 } 504 505 /* If all else fails, default to 80x24 terminal. */ 506 if (screenwidth <= 0) 507 screenwidth = 80; 508 509 if (screenheight <= 0) 510 screenheight = 24; 511 } 512 } 513 514 /* Initialize the terminal which is known as TERMINAL_NAME. If this 515 terminal doesn't have cursor addressability, `terminal_is_dumb_p' 516 becomes nonzero. The variables SCREENHEIGHT and SCREENWIDTH are set 517 to the dimensions that this terminal actually has. The variable 518 TERMINAL_HAS_META_P becomes nonzero if this terminal supports a Meta 519 key. Finally, the terminal screen is cleared. */ 520 void 521 terminal_initialize_terminal (terminal_name) 522 char *terminal_name; 523 { 524 char *buffer; 525 526 terminal_is_dumb_p = 0; 527 528 if (terminal_initialize_terminal_hook) 529 { 530 (*terminal_initialize_terminal_hook) (terminal_name); 531 return; 532 } 533 534 term_name = terminal_name ? terminal_name : getenv ("TERM"); 535 if (!term_name) 536 term_name = "dumb"; 537 538 if (!term_string_buffer) 539 term_string_buffer = xmalloc (2048); 540 541 if (!term_buffer) 542 term_buffer = xmalloc (2048); 543 544 buffer = term_string_buffer; 545 546 term_clrpag = term_cr = term_clreol = NULL; 547 548 /* HP-UX 11.x returns 0 for OK --jeff.hull@state.co.us. */ 549 if (tgetent (term_buffer, term_name) < 0) 550 { 551 terminal_is_dumb_p = 1; 552 screenwidth = 80; 553 screenheight = 24; 554 term_cr = "\r"; 555 term_up = term_dn = audible_bell = visible_bell = NULL; 556 term_ku = term_kd = term_kl = term_kr = NULL; 557 term_kP = term_kN = NULL; 558 return; 559 } 560 561 BC = tgetstr ("pc", &buffer); 562 PC = BC ? *BC : 0; 563 564 #if defined (HAVE_TERMIOS_H) 565 { 566 struct termios ti; 567 if (tcgetattr (fileno(stdout), &ti) != -1) 568 ospeed = cfgetospeed (&ti); 569 else 570 ospeed = B9600; 571 } 572 #else 573 # if defined (TIOCGETP) 574 { 575 struct sgttyb sg; 576 577 if (ioctl (fileno (stdout), TIOCGETP, &sg) != -1) 578 ospeed = sg.sg_ospeed; 579 else 580 ospeed = B9600; 581 } 582 # else 583 ospeed = B9600; 584 # endif /* !TIOCGETP */ 585 #endif 586 587 term_cr = tgetstr ("cr", &buffer); 588 term_clreol = tgetstr ("ce", &buffer); 589 term_clrpag = tgetstr ("cl", &buffer); 590 term_goto = tgetstr ("cm", &buffer); 591 592 /* Find out about this terminal's scrolling capability. */ 593 term_AL = tgetstr ("AL", &buffer); 594 term_DL = tgetstr ("DL", &buffer); 595 term_al = tgetstr ("al", &buffer); 596 term_dl = tgetstr ("dl", &buffer); 597 598 terminal_can_scroll = ((term_AL || term_al) && (term_DL || term_dl)); 599 600 term_invbeg = tgetstr ("mr", &buffer); 601 if (term_invbeg) 602 term_invend = tgetstr ("me", &buffer); 603 else 604 term_invend = (char *)NULL; 605 606 if (!term_cr) 607 term_cr = "\r"; 608 609 terminal_get_screen_size (); 610 611 term_up = tgetstr ("up", &buffer); 612 term_dn = tgetstr ("dn", &buffer); 613 visible_bell = tgetstr ("vb", &buffer); 614 terminal_has_visible_bell_p = (visible_bell != (char *)NULL); 615 audible_bell = tgetstr ("bl", &buffer); 616 if (!audible_bell) 617 audible_bell = "\007"; 618 term_begin_use = tgetstr ("ti", &buffer); 619 term_end_use = tgetstr ("te", &buffer); 620 621 term_keypad_on = tgetstr ("ks", &buffer); 622 term_keypad_off = tgetstr ("ke", &buffer); 623 624 /* Check to see if this terminal has a meta key. */ 625 terminal_has_meta_p = (tgetflag ("km") || tgetflag ("MT")); 626 if (terminal_has_meta_p) 627 { 628 term_mm = tgetstr ("mm", &buffer); 629 term_mo = tgetstr ("mo", &buffer); 630 } 631 else 632 { 633 term_mm = (char *)NULL; 634 term_mo = (char *)NULL; 635 } 636 637 /* Attempt to find the arrow keys. */ 638 term_ku = tgetstr ("ku", &buffer); 639 term_kd = tgetstr ("kd", &buffer); 640 term_kr = tgetstr ("kr", &buffer); 641 term_kl = tgetstr ("kl", &buffer); 642 643 term_kP = tgetstr ("kP", &buffer); 644 term_kN = tgetstr ("kN", &buffer); 645 646 /* If this terminal is not cursor addressable, then it is really dumb. */ 647 if (!term_goto) 648 terminal_is_dumb_p = 1; 649 } 650 651 /* How to read characters from the terminal. */ 652 653 #if defined (HAVE_TERMIOS_H) 654 struct termios original_termios, ttybuff; 655 #else 656 # if defined (HAVE_TERMIO_H) 657 /* A buffer containing the terminal mode flags upon entry to info. */ 658 struct termio original_termio, ttybuff; 659 # else /* !HAVE_TERMIO_H */ 660 /* Buffers containing the terminal mode flags upon entry to info. */ 661 int original_tty_flags = 0; 662 int original_lmode; 663 struct sgttyb ttybuff; 664 665 # if defined(TIOCGETC) && defined(M_XENIX) 666 /* SCO 3.2v5.0.2 defines but does not support TIOCGETC. Gak. Maybe 667 better fix would be to use Posix termios in preference. --gildea, 668 1jul99. */ 669 # undef TIOCGETC 670 # endif 671 672 # if defined (TIOCGETC) 673 /* A buffer containing the terminal interrupt characters upon entry 674 to Info. */ 675 struct tchars original_tchars; 676 # endif 677 678 # if defined (TIOCGLTC) 679 /* A buffer containing the local terminal mode characters upon entry 680 to Info. */ 681 struct ltchars original_ltchars; 682 # endif 683 # endif /* !HAVE_TERMIO_H */ 684 #endif /* !HAVE_TERMIOS_H */ 685 686 /* Prepare to start using the terminal to read characters singly. */ 687 void 688 terminal_prep_terminal () 689 { 690 int tty; 691 692 if (terminal_prep_terminal_hook) 693 { 694 (*terminal_prep_terminal_hook) (); 695 return; 696 } 697 698 terminal_begin_using_terminal (); 699 700 tty = fileno (stdin); 701 702 #if defined (HAVE_TERMIOS_H) 703 tcgetattr (tty, &original_termios); 704 tcgetattr (tty, &ttybuff); 705 #else 706 # if defined (HAVE_TERMIO_H) 707 ioctl (tty, TCGETA, &original_termio); 708 ioctl (tty, TCGETA, &ttybuff); 709 # endif 710 #endif 711 712 #if defined (HAVE_TERMIOS_H) || defined (HAVE_TERMIO_H) 713 ttybuff.c_iflag &= (~ISTRIP & ~INLCR & ~IGNCR & ~ICRNL & ~IXON); 714 /* These output flags are not part of POSIX, so only use them if they 715 are defined. */ 716 #ifdef ONLCR 717 ttybuff.c_oflag &= ~ONLCR ; 718 #endif 719 #ifdef OCRNL 720 ttybuff.c_oflag &= ~OCRNL; 721 #endif 722 ttybuff.c_lflag &= (~ICANON & ~ECHO); 723 724 ttybuff.c_cc[VMIN] = 1; 725 ttybuff.c_cc[VTIME] = 0; 726 727 if (ttybuff.c_cc[VINTR] == '\177') 728 ttybuff.c_cc[VINTR] = -1; 729 730 if (ttybuff.c_cc[VQUIT] == '\177') 731 ttybuff.c_cc[VQUIT] = -1; 732 733 #ifdef VLNEXT 734 if (ttybuff.c_cc[VLNEXT] == '\026') 735 ttybuff.c_cc[VLNEXT] = -1; 736 #endif /* VLNEXT */ 737 #endif /* TERMIOS or TERMIO */ 738 739 #if defined (HAVE_TERMIOS_H) 740 tcsetattr (tty, TCSANOW, &ttybuff); 741 #else 742 # if defined (HAVE_TERMIO_H) 743 ioctl (tty, TCSETA, &ttybuff); 744 # endif 745 #endif 746 747 #if !defined (HAVE_TERMIOS_H) && !defined (HAVE_TERMIO_H) 748 ioctl (tty, TIOCGETP, &ttybuff); 749 750 if (!original_tty_flags) 751 original_tty_flags = ttybuff.sg_flags; 752 753 /* Make this terminal pass 8 bits around while we are using it. */ 754 # if defined (PASS8) 755 ttybuff.sg_flags |= PASS8; 756 # endif /* PASS8 */ 757 758 # if defined (TIOCLGET) && defined (LPASS8) 759 { 760 int flags; 761 ioctl (tty, TIOCLGET, &flags); 762 original_lmode = flags; 763 flags |= LPASS8; 764 ioctl (tty, TIOCLSET, &flags); 765 } 766 # endif /* TIOCLGET && LPASS8 */ 767 768 # if defined (TIOCGETC) 769 { 770 struct tchars temp; 771 772 ioctl (tty, TIOCGETC, &original_tchars); 773 temp = original_tchars; 774 775 /* C-s and C-q. */ 776 temp.t_startc = temp.t_stopc = -1; 777 778 /* Often set to C-d. */ 779 temp.t_eofc = -1; 780 781 /* If the a quit or interrupt character conflicts with one of our 782 commands, then make it go away. */ 783 if (temp.t_intrc == '\177') 784 temp.t_intrc = -1; 785 786 if (temp.t_quitc == '\177') 787 temp.t_quitc = -1; 788 789 ioctl (tty, TIOCSETC, &temp); 790 } 791 # endif /* TIOCGETC */ 792 793 # if defined (TIOCGLTC) 794 { 795 struct ltchars temp; 796 797 ioctl (tty, TIOCGLTC, &original_ltchars); 798 temp = original_ltchars; 799 800 /* Make the interrupt keys go away. Just enough to make people happy. */ 801 temp.t_lnextc = -1; /* C-v. */ 802 temp.t_dsuspc = -1; /* C-y. */ 803 temp.t_flushc = -1; /* C-o. */ 804 ioctl (tty, TIOCSLTC, &temp); 805 } 806 # endif /* TIOCGLTC */ 807 808 ttybuff.sg_flags &= ~ECHO; 809 ttybuff.sg_flags |= CBREAK; 810 ioctl (tty, TIOCSETN, &ttybuff); 811 #endif /* !HAVE_TERMIOS_H && !HAVE_TERMIO_H */ 812 } 813 814 /* Restore the tty settings back to what they were before we started using 815 this terminal. */ 816 void 817 terminal_unprep_terminal () 818 { 819 int tty; 820 821 if (terminal_unprep_terminal_hook) 822 { 823 (*terminal_unprep_terminal_hook) (); 824 return; 825 } 826 827 tty = fileno (stdin); 828 829 #if defined (HAVE_TERMIOS_H) 830 tcsetattr (tty, TCSANOW, &original_termios); 831 #else 832 # if defined (HAVE_TERMIO_H) 833 ioctl (tty, TCSETA, &original_termio); 834 # else /* !HAVE_TERMIO_H */ 835 ioctl (tty, TIOCGETP, &ttybuff); 836 ttybuff.sg_flags = original_tty_flags; 837 ioctl (tty, TIOCSETN, &ttybuff); 838 839 # if defined (TIOCGETC) 840 ioctl (tty, TIOCSETC, &original_tchars); 841 # endif /* TIOCGETC */ 842 843 # if defined (TIOCGLTC) 844 ioctl (tty, TIOCSLTC, &original_ltchars); 845 # endif /* TIOCGLTC */ 846 847 # if defined (TIOCLGET) && defined (LPASS8) 848 ioctl (tty, TIOCLSET, &original_lmode); 849 # endif /* TIOCLGET && LPASS8 */ 850 851 # endif /* !HAVE_TERMIO_H */ 852 #endif /* !HAVE_TERMIOS_H */ 853 terminal_end_using_terminal (); 854 } 855 856 #ifdef __MSDOS__ 857 # include "pcterm.c" 858 #endif 859