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