1 /* $NetBSD: terminal.c,v 1.1.1.5 2008/09/02 07:50:09 christos Exp $ */
3 /* terminal.c -- how to handle the physical terminal for Info.
4 Id: terminal.c,v 1.3 2004/04/11 17:56:46 karl Exp
6 Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1996, 1997, 1998,
7 1999, 2001, 2002, 2004 Free Software Foundation, Inc.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 Originally written by Brian Fox (bfox@ai.mit.edu). */
29 #include <sys/types.h>
32 /* The Unix termcap interface code. */
33 #ifdef HAVE_NCURSES_TERMCAP_H
34 #include <ncurses/termcap.h>
39 /* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC.
40 Unfortunately, PC is a global variable used by the termcap library. */
43 /* Termcap requires these variables, whether we access them or not. */
45 char PC
; /* Pad character */
46 short ospeed
; /* Terminal output baud rate */
47 extern int tgetnum (), tgetflag (), tgetent ();
48 extern char *tgetstr (), *tgoto ();
50 #endif /* not HAVE_TERMCAP_H */
51 #endif /* not HAVE_NCURSES_TERMCAP_H */
53 /* Function "hooks". If you make one of these point to a function, that
54 function is called when appropriate instead of its namesake. Your
55 function is called with exactly the same arguments that were passed
56 to the namesake function. */
57 VFunction
*terminal_begin_inverse_hook
= (VFunction
*)NULL
;
58 VFunction
*terminal_end_inverse_hook
= (VFunction
*)NULL
;
59 VFunction
*terminal_prep_terminal_hook
= (VFunction
*)NULL
;
60 VFunction
*terminal_unprep_terminal_hook
= (VFunction
*)NULL
;
61 VFunction
*terminal_up_line_hook
= (VFunction
*)NULL
;
62 VFunction
*terminal_down_line_hook
= (VFunction
*)NULL
;
63 VFunction
*terminal_clear_screen_hook
= (VFunction
*)NULL
;
64 VFunction
*terminal_clear_to_eol_hook
= (VFunction
*)NULL
;
65 VFunction
*terminal_get_screen_size_hook
= (VFunction
*)NULL
;
66 VFunction
*terminal_goto_xy_hook
= (VFunction
*)NULL
;
67 VFunction
*terminal_initialize_terminal_hook
= (VFunction
*)NULL
;
68 VFunction
*terminal_new_terminal_hook
= (VFunction
*)NULL
;
69 VFunction
*terminal_put_text_hook
= (VFunction
*)NULL
;
70 VFunction
*terminal_ring_bell_hook
= (VFunction
*)NULL
;
71 VFunction
*terminal_write_chars_hook
= (VFunction
*)NULL
;
72 VFunction
*terminal_scroll_terminal_hook
= (VFunction
*)NULL
;
74 /* **************************************************************** */
76 /* Terminal and Termcap */
78 /* **************************************************************** */
80 /* A buffer which holds onto the current terminal description, and a pointer
81 used to float within it. And the name of the terminal. */
82 static char *term_buffer
= NULL
;
83 static char *term_string_buffer
= NULL
;
84 static char *term_name
;
86 /* Some strings to control terminal actions. These are output by tputs (). */
87 static char *term_goto
, *term_clreol
, *term_cr
, *term_clrpag
;
88 static char *term_begin_use
, *term_end_use
;
89 static char *term_AL
, *term_DL
, *term_al
, *term_dl
;
91 static char *term_keypad_on
, *term_keypad_off
;
93 /* How to go up a line. */
96 /* How to go down a line. */
99 /* An audible bell, if the terminal can be made to make noise. */
100 static char *audible_bell
;
102 /* A visible bell, if the terminal can be made to flash the screen. */
103 static char *visible_bell
;
105 /* The string to write to turn on the meta key, if this term has one. */
106 static char *term_mm
;
108 /* The string to turn on inverse mode, if this term has one. */
109 static char *term_invbeg
;
111 /* The string to turn off inverse mode, if this term has one. */
112 static char *term_invend
;
114 /* Although I can't find any documentation that says this is supposed to
115 return its argument, all the code I've looked at (termutils, less)
118 output_character_function (int c
)
124 /* Macro to send STRING to the terminal. */
125 #define send_to_terminal(string) \
128 tputs (string, 1, output_character_function); \
131 /* Tell the terminal that we will be doing cursor addressable motion. */
133 terminal_begin_using_terminal (void)
135 RETSIGTYPE (*sigsave
) (int signum
);
138 send_to_terminal (term_keypad_on
);
140 if (!term_begin_use
|| !*term_begin_use
)
144 sigsave
= signal (SIGWINCH
, SIG_IGN
);
147 send_to_terminal (term_begin_use
);
149 if (STREQ (term_name
, "sun-cmd"))
150 /* Without this fflush and sleep, running info in a shelltool or
151 cmdtool (TERM=sun-cmd) with scrollbars loses -- the scrollbars are
152 not restored properly.
153 From: strube@physik3.gwdg.de (Hans Werner Strube). */
157 signal (SIGWINCH
, sigsave
);
161 /* Tell the terminal that we will not be doing any more cursor
162 addressable motion. */
164 terminal_end_using_terminal (void)
166 RETSIGTYPE (*sigsave
) (int signum
);
169 send_to_terminal (term_keypad_off
);
171 if (!term_end_use
|| !*term_end_use
)
175 sigsave
= signal (SIGWINCH
, SIG_IGN
);
178 send_to_terminal (term_end_use
);
180 if (STREQ (term_name
, "sun-cmd"))
181 /* See comments at other sleep. */
185 signal (SIGWINCH
, sigsave
);
189 /* **************************************************************** */
191 /* Necessary Terminal Functions */
193 /* **************************************************************** */
195 /* The functions and variables on this page implement the user visible
196 portion of the terminal interface. */
198 /* The width and height of the terminal. */
199 int screenwidth
, screenheight
;
201 /* Non-zero means this terminal can't really do anything. */
202 int terminal_is_dumb_p
= 0;
204 /* Non-zero means that this terminal has a meta key. */
205 int terminal_has_meta_p
= 0;
207 /* Non-zero means that this terminal can produce a visible bell. */
208 int terminal_has_visible_bell_p
= 0;
210 /* Non-zero means to use that visible bell if at all possible. */
211 int terminal_use_visible_bell_p
= 0;
213 /* Non-zero means that the terminal can do scrolling. */
214 int terminal_can_scroll
= 0;
216 /* The key sequences output by the arrow keys, if this terminal has any. */
217 char *term_ku
= NULL
;
218 char *term_kd
= NULL
;
219 char *term_kr
= NULL
;
220 char *term_kl
= NULL
;
221 char *term_kP
= NULL
; /* page-up */
222 char *term_kN
= NULL
; /* page-down */
223 char *term_kh
= NULL
; /* home */
224 char *term_ke
= NULL
; /* end */
225 char *term_kD
= NULL
; /* delete */
226 char *term_ki
= NULL
; /* ins */
227 char *term_kx
= NULL
; /* del */
229 /* Move the cursor to the terminal location of X and Y. */
231 terminal_goto_xy (int x
, int y
)
233 if (terminal_goto_xy_hook
)
234 (*terminal_goto_xy_hook
) (x
, y
);
238 tputs (tgoto (term_goto
, x
, y
), 1, output_character_function
);
242 /* Print STRING to the terminal at the current position. */
244 terminal_put_text (char *string
)
246 if (terminal_put_text_hook
)
247 (*terminal_put_text_hook
) (string
);
250 printf ("%s", string
);
254 /* Print NCHARS from STRING to the terminal at the current position. */
256 terminal_write_chars (char *string
, int nchars
)
258 if (terminal_write_chars_hook
)
259 (*terminal_write_chars_hook
) (string
, nchars
);
263 fwrite (string
, 1, nchars
, stdout
);
267 /* Clear from the current position of the cursor to the end of the line. */
269 terminal_clear_to_eol (void)
271 if (terminal_clear_to_eol_hook
)
272 (*terminal_clear_to_eol_hook
) ();
275 send_to_terminal (term_clreol
);
279 /* Clear the entire terminal screen. */
281 terminal_clear_screen (void)
283 if (terminal_clear_screen_hook
)
284 (*terminal_clear_screen_hook
) ();
287 send_to_terminal (term_clrpag
);
291 /* Move the cursor up one line. */
293 terminal_up_line (void)
295 if (terminal_up_line_hook
)
296 (*terminal_up_line_hook
) ();
299 send_to_terminal (term_up
);
303 /* Move the cursor down one line. */
305 terminal_down_line (void)
307 if (terminal_down_line_hook
)
308 (*terminal_down_line_hook
) ();
311 send_to_terminal (term_dn
);
315 /* Turn on reverse video if possible. */
317 terminal_begin_inverse (void)
319 if (terminal_begin_inverse_hook
)
320 (*terminal_begin_inverse_hook
) ();
323 send_to_terminal (term_invbeg
);
327 /* Turn off reverse video if possible. */
329 terminal_end_inverse (void)
331 if (terminal_end_inverse_hook
)
332 (*terminal_end_inverse_hook
) ();
335 send_to_terminal (term_invend
);
339 /* Ring the terminal bell. The bell is run visibly if it both has one and
340 terminal_use_visible_bell_p is non-zero. */
342 terminal_ring_bell (void)
344 if (terminal_ring_bell_hook
)
345 (*terminal_ring_bell_hook
) ();
348 if (terminal_has_visible_bell_p
&& terminal_use_visible_bell_p
)
349 send_to_terminal (visible_bell
);
351 send_to_terminal (audible_bell
);
355 /* At the line START, delete COUNT lines from the terminal display. */
357 terminal_delete_lines (int start
, int count
)
361 /* Normalize arguments. */
365 lines
= screenheight
- start
;
366 terminal_goto_xy (0, start
);
368 tputs (tgoto (term_DL
, 0, count
), lines
, output_character_function
);
372 tputs (term_dl
, lines
, output_character_function
);
378 /* At the line START, insert COUNT lines in the terminal display. */
380 terminal_insert_lines (int start
, int count
)
384 /* Normalize arguments. */
388 lines
= screenheight
- start
;
389 terminal_goto_xy (0, start
);
392 tputs (tgoto (term_AL
, 0, count
), lines
, output_character_function
);
396 tputs (term_al
, lines
, output_character_function
);
402 /* Scroll an area of the terminal, starting with the region from START
403 to END, AMOUNT lines. If AMOUNT is negative, the lines are scrolled
404 towards the top of the screen, else they are scrolled towards the
405 bottom of the screen. */
407 terminal_scroll_terminal (int start
, int end
, int amount
)
409 if (!terminal_can_scroll
)
412 /* Any scrolling at all? */
416 if (terminal_scroll_terminal_hook
)
417 (*terminal_scroll_terminal_hook
) (start
, end
, amount
);
420 /* If we are scrolling down, delete AMOUNT lines at END. Then insert
421 AMOUNT lines at START. */
424 terminal_delete_lines (end
, amount
);
425 terminal_insert_lines (start
, amount
);
428 /* If we are scrolling up, delete AMOUNT lines before START. This
429 actually does the upwards scroll. Then, insert AMOUNT lines
430 after the already scrolled region (i.e., END - AMOUNT). */
433 int abs_amount
= -amount
;
434 terminal_delete_lines (start
- abs_amount
, abs_amount
);
435 terminal_insert_lines (end
- abs_amount
, abs_amount
);
440 /* Re-initialize the terminal considering that the TERM/TERMCAP variable
443 terminal_new_terminal (char *terminal_name
)
445 if (terminal_new_terminal_hook
)
446 (*terminal_new_terminal_hook
) (terminal_name
);
449 terminal_initialize_terminal (terminal_name
);
453 /* Set the global variables SCREENWIDTH and SCREENHEIGHT. */
455 terminal_get_screen_size (void)
457 if (terminal_get_screen_size_hook
)
458 (*terminal_get_screen_size_hook
) ();
461 screenwidth
= screenheight
= 0;
463 #if defined (TIOCGWINSZ)
465 struct winsize window_size
;
467 if (ioctl (fileno (stdout
), TIOCGWINSZ
, &window_size
) == 0)
469 screenwidth
= (int) window_size
.ws_col
;
470 screenheight
= (int) window_size
.ws_row
;
473 #endif /* TIOCGWINSZ */
475 /* Environment variable COLUMNS overrides setting of "co". */
476 if (screenwidth
<= 0)
478 char *sw
= getenv ("COLUMNS");
481 screenwidth
= atoi (sw
);
483 if (screenwidth
<= 0)
484 screenwidth
= tgetnum ("co");
487 /* Environment variable LINES overrides setting of "li". */
488 if (screenheight
<= 0)
490 char *sh
= getenv ("LINES");
493 screenheight
= atoi (sh
);
495 if (screenheight
<= 0)
496 screenheight
= tgetnum ("li");
499 /* If all else fails, default to 80x24 terminal. */
500 if (screenwidth
<= 0)
503 if (screenheight
<= 0)
508 /* Initialize the terminal which is known as TERMINAL_NAME. If this
509 terminal doesn't have cursor addressability, `terminal_is_dumb_p'
510 becomes nonzero. The variables SCREENHEIGHT and SCREENWIDTH are set
511 to the dimensions that this terminal actually has. The variable
512 TERMINAL_HAS_META_P becomes nonzero if this terminal supports a Meta
513 key. Finally, the terminal screen is cleared. */
515 terminal_initialize_terminal (char *terminal_name
)
519 terminal_is_dumb_p
= 0;
521 if (terminal_initialize_terminal_hook
)
523 (*terminal_initialize_terminal_hook
) (terminal_name
);
527 term_name
= terminal_name
? terminal_name
: getenv ("TERM");
531 if (!term_string_buffer
)
532 term_string_buffer
= xmalloc (2048);
535 term_buffer
= xmalloc (2048);
537 buffer
= term_string_buffer
;
539 term_clrpag
= term_cr
= term_clreol
= NULL
;
541 /* HP-UX 11.x returns 0 for OK --jeff.hull@state.co.us. */
542 if (tgetent (term_buffer
, term_name
) < 0)
544 terminal_is_dumb_p
= 1;
548 term_up
= term_dn
= audible_bell
= visible_bell
= NULL
;
549 term_ku
= term_kd
= term_kl
= term_kr
= NULL
;
550 term_kP
= term_kN
= NULL
;
551 term_kh
= term_ke
= NULL
;
556 BC
= tgetstr ("pc", &buffer
);
559 #if defined (HAVE_TERMIOS_H)
562 if (tcgetattr (fileno(stdout
), &ti
) != -1)
563 ospeed
= cfgetospeed (&ti
);
568 # if defined (TIOCGETP)
572 if (ioctl (fileno (stdout
), TIOCGETP
, &sg
) != -1)
573 ospeed
= sg
.sg_ospeed
;
579 # endif /* !TIOCGETP */
582 term_cr
= tgetstr ("cr", &buffer
);
583 term_clreol
= tgetstr ("ce", &buffer
);
584 term_clrpag
= tgetstr ("cl", &buffer
);
585 term_goto
= tgetstr ("cm", &buffer
);
587 /* Find out about this terminal's scrolling capability. */
588 term_AL
= tgetstr ("AL", &buffer
);
589 term_DL
= tgetstr ("DL", &buffer
);
590 term_al
= tgetstr ("al", &buffer
);
591 term_dl
= tgetstr ("dl", &buffer
);
593 terminal_can_scroll
= ((term_AL
|| term_al
) && (term_DL
|| term_dl
));
595 term_invbeg
= tgetstr ("mr", &buffer
);
597 term_invend
= tgetstr ("me", &buffer
);
604 terminal_get_screen_size ();
606 term_up
= tgetstr ("up", &buffer
);
607 term_dn
= tgetstr ("dn", &buffer
);
608 visible_bell
= tgetstr ("vb", &buffer
);
609 terminal_has_visible_bell_p
= (visible_bell
!= NULL
);
610 audible_bell
= tgetstr ("bl", &buffer
);
612 audible_bell
= "\007";
613 term_begin_use
= tgetstr ("ti", &buffer
);
614 term_end_use
= tgetstr ("te", &buffer
);
616 term_keypad_on
= tgetstr ("ks", &buffer
);
617 term_keypad_off
= tgetstr ("ke", &buffer
);
619 /* Check to see if this terminal has a meta key. */
620 terminal_has_meta_p
= (tgetflag ("km") || tgetflag ("MT"));
621 if (terminal_has_meta_p
)
623 term_mm
= tgetstr ("mm", &buffer
);
630 /* Attempt to find the arrow keys. */
631 term_ku
= tgetstr ("ku", &buffer
);
632 term_kd
= tgetstr ("kd", &buffer
);
633 term_kr
= tgetstr ("kr", &buffer
);
634 term_kl
= tgetstr ("kl", &buffer
);
636 term_kP
= tgetstr ("kP", &buffer
);
637 term_kN
= tgetstr ("kN", &buffer
);
640 term_kh
= tgetstr ("kh", &buffer
);
641 term_ke
= tgetstr ("@7", &buffer
);
642 term_ki
= tgetstr ("kI", &buffer
);
643 term_kx
= tgetstr ("kD", &buffer
);
644 #endif /* defined(INFOKEY) */
646 /* Home and end keys. */
647 term_kh
= tgetstr ("kh", &buffer
);
648 term_ke
= tgetstr ("@7", &buffer
);
650 term_kD
= tgetstr ("kD", &buffer
);
652 /* If this terminal is not cursor addressable, then it is really dumb. */
654 terminal_is_dumb_p
= 1;
657 /* How to read characters from the terminal. */
659 #if defined (HAVE_TERMIOS_H)
660 struct termios original_termios
, ttybuff
;
662 # if defined (HAVE_TERMIO_H)
663 /* A buffer containing the terminal mode flags upon entry to info. */
664 struct termio original_termio
, ttybuff
;
665 # else /* !HAVE_TERMIO_H */
666 /* Buffers containing the terminal mode flags upon entry to info. */
667 int original_tty_flags
= 0;
669 struct sgttyb ttybuff
;
671 # if defined(TIOCGETC) && defined(M_XENIX)
672 /* SCO 3.2v5.0.2 defines but does not support TIOCGETC. Gak. Maybe
673 better fix would be to use Posix termios in preference. --gildea,
678 # if defined (TIOCGETC)
679 /* A buffer containing the terminal interrupt characters upon entry
681 struct tchars original_tchars
;
684 # if defined (TIOCGLTC)
685 /* A buffer containing the local terminal mode characters upon entry
687 struct ltchars original_ltchars
;
689 # endif /* !HAVE_TERMIO_H */
690 #endif /* !HAVE_TERMIOS_H */
692 /* Prepare to start using the terminal to read characters singly. */
694 terminal_prep_terminal (void)
698 if (terminal_prep_terminal_hook
)
700 (*terminal_prep_terminal_hook
) ();
704 terminal_begin_using_terminal ();
706 tty
= fileno (stdin
);
708 #if defined (HAVE_TERMIOS_H)
709 tcgetattr (tty
, &original_termios
);
710 tcgetattr (tty
, &ttybuff
);
712 # if defined (HAVE_TERMIO_H)
713 ioctl (tty
, TCGETA
, &original_termio
);
714 ioctl (tty
, TCGETA
, &ttybuff
);
718 #if defined (HAVE_TERMIOS_H) || defined (HAVE_TERMIO_H)
719 ttybuff
.c_iflag
&= (~ISTRIP
& ~INLCR
& ~IGNCR
& ~ICRNL
& ~IXON
);
720 /* These output flags are not part of POSIX, so only use them if they
723 ttybuff
.c_oflag
&= ~ONLCR
;
726 ttybuff
.c_oflag
&= ~OCRNL
;
728 ttybuff
.c_lflag
&= (~ICANON
& ~ECHO
);
730 ttybuff
.c_cc
[VMIN
] = 1;
731 ttybuff
.c_cc
[VTIME
] = 0;
733 if (ttybuff
.c_cc
[VINTR
] == '\177')
734 ttybuff
.c_cc
[VINTR
] = -1;
736 if (ttybuff
.c_cc
[VQUIT
] == '\177')
737 ttybuff
.c_cc
[VQUIT
] = -1;
740 if (ttybuff
.c_cc
[VLNEXT
] == '\026')
741 ttybuff
.c_cc
[VLNEXT
] = -1;
743 #endif /* TERMIOS or TERMIO */
745 /* cf. emacs/src/sysdep.c for being sure output is on. */
746 #if defined (HAVE_TERMIOS_H)
747 /* linux kernel 2.2.x needs a TCOFF followed by a TCOON to turn output
748 back on if the user presses ^S at the very beginning; just a TCOON
749 doesn't work. --Kevin Ryde <user42@zip.com.au>, 16jun2000. */
750 tcsetattr (tty
, TCSANOW
, &ttybuff
);
752 tcflow (tty
, TCOOFF
);
756 # if defined (HAVE_TERMIO_H)
757 ioctl (tty
, TCSETA
, &ttybuff
);
759 ioctl (tty
, TCXONC
, 1);
764 #if !defined (HAVE_TERMIOS_H) && !defined (HAVE_TERMIO_H)
765 ioctl (tty
, TIOCGETP
, &ttybuff
);
767 if (!original_tty_flags
)
768 original_tty_flags
= ttybuff
.sg_flags
;
770 /* Make this terminal pass 8 bits around while we are using it. */
772 ttybuff
.sg_flags
|= PASS8
;
775 # if defined (TIOCLGET) && defined (LPASS8)
778 ioctl (tty
, TIOCLGET
, &flags
);
779 original_lmode
= flags
;
781 ioctl (tty
, TIOCLSET
, &flags
);
783 # endif /* TIOCLGET && LPASS8 */
785 # if defined (TIOCGETC)
789 ioctl (tty
, TIOCGETC
, &original_tchars
);
790 temp
= original_tchars
;
793 temp
.t_startc
= temp
.t_stopc
= -1;
795 /* Often set to C-d. */
798 /* If the a quit or interrupt character conflicts with one of our
799 commands, then make it go away. */
800 if (temp
.t_intrc
== '\177')
803 if (temp
.t_quitc
== '\177')
806 ioctl (tty
, TIOCSETC
, &temp
);
808 # endif /* TIOCGETC */
810 # if defined (TIOCGLTC)
814 ioctl (tty
, TIOCGLTC
, &original_ltchars
);
815 temp
= original_ltchars
;
817 /* Make the interrupt keys go away. Just enough to make people happy. */
818 temp
.t_lnextc
= -1; /* C-v. */
819 temp
.t_dsuspc
= -1; /* C-y. */
820 temp
.t_flushc
= -1; /* C-o. */
821 ioctl (tty
, TIOCSLTC
, &temp
);
823 # endif /* TIOCGLTC */
825 ttybuff
.sg_flags
&= ~ECHO
;
826 ttybuff
.sg_flags
|= CBREAK
;
827 ioctl (tty
, TIOCSETN
, &ttybuff
);
828 #endif /* !HAVE_TERMIOS_H && !HAVE_TERMIO_H */
831 /* Restore the tty settings back to what they were before we started using
834 terminal_unprep_terminal (void)
838 if (terminal_unprep_terminal_hook
)
840 (*terminal_unprep_terminal_hook
) ();
844 tty
= fileno (stdin
);
846 #if defined (HAVE_TERMIOS_H)
847 tcsetattr (tty
, TCSANOW
, &original_termios
);
849 # if defined (HAVE_TERMIO_H)
850 ioctl (tty
, TCSETA
, &original_termio
);
851 # else /* !HAVE_TERMIO_H */
852 ioctl (tty
, TIOCGETP
, &ttybuff
);
853 ttybuff
.sg_flags
= original_tty_flags
;
854 ioctl (tty
, TIOCSETN
, &ttybuff
);
856 # if defined (TIOCGETC)
857 ioctl (tty
, TIOCSETC
, &original_tchars
);
858 # endif /* TIOCGETC */
860 # if defined (TIOCGLTC)
861 ioctl (tty
, TIOCSLTC
, &original_ltchars
);
862 # endif /* TIOCGLTC */
864 # if defined (TIOCLGET) && defined (LPASS8)
865 ioctl (tty
, TIOCLSET
, &original_lmode
);
866 # endif /* TIOCLGET && LPASS8 */
868 # endif /* !HAVE_TERMIO_H */
869 #endif /* !HAVE_TERMIOS_H */
870 terminal_end_using_terminal ();