OSDN Git Service

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