source: trunk/texinfo/info/terminal.c@ 2618

Last change on this file since 2618 was 2617, checked in by bird, 19 years ago

GNU Texinfo 4.8

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