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