1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs 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)
12 GNU Emacs 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.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
30 #include <unistd.h> /* For isatty. */
33 #include <termios.h> /* For TIOCNOTTY. */
46 #include "termhooks.h"
47 #include "dispextern.h"
50 #include "blockinput.h"
51 #include "syssignal.h"
54 /* For now, don't try to include termcap.h. On some systems,
55 configure finds a non-standard termcap.h that the main build
58 #if defined HAVE_TERMCAP_H && 0
61 extern void tputs
P_ ((const char *, int, int (*)(int)));
62 extern int tgetent
P_ ((char *, const char *));
63 extern int tgetflag
P_ ((char *id
));
64 extern int tgetnum
P_ ((char *id
));
83 static void tty_set_scroll_region
P_ ((struct frame
*f
, int start
, int stop
));
84 static void turn_on_face
P_ ((struct frame
*, int face_id
));
85 static void turn_off_face
P_ ((struct frame
*, int face_id
));
86 static void tty_show_cursor
P_ ((struct tty_display_info
*));
87 static void tty_hide_cursor
P_ ((struct tty_display_info
*));
88 static void tty_background_highlight
P_ ((struct tty_display_info
*tty
));
89 static void clear_tty_hooks
P_ ((struct terminal
*terminal
));
90 static void set_tty_hooks
P_ ((struct terminal
*terminal
));
91 static void dissociate_if_controlling_tty
P_ ((int fd
));
92 static void delete_tty
P_ ((struct terminal
*));
94 #define OUTPUT(tty, a) \
95 emacs_tputs ((tty), a, \
96 (int) (FRAME_LINES (XFRAME (selected_frame)) \
100 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
101 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
103 #define OUTPUT_IF(tty, a) \
106 emacs_tputs ((tty), a, \
107 (int) (FRAME_LINES (XFRAME (selected_frame)) \
112 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
114 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */
116 static int visible_cursor
;
118 /* Display space properties */
120 extern Lisp_Object Qspace
, QCalign_to
, QCwidth
;
122 /* Functions to call after suspending a tty. */
123 Lisp_Object Vsuspend_tty_functions
;
125 /* Functions to call after resuming a tty. */
126 Lisp_Object Vresume_tty_functions
;
128 /* Chain of all tty device parameters. */
129 struct tty_display_info
*tty_list
;
131 /* Nonzero means no need to redraw the entire frame on resuming a
132 suspended Emacs. This is useful on terminals with multiple
133 pages, where one page is used for Emacs and another for all
135 int no_redraw_on_reenter
;
137 /* Meaning of bits in no_color_video. Each bit set means that the
138 corresponding attribute cannot be combined with colors. */
142 NC_STANDOUT
= 1 << 0,
143 NC_UNDERLINE
= 1 << 1,
150 NC_ALT_CHARSET
= 1 << 8
155 /* The largest frame width in any call to calculate_costs. */
159 /* The largest frame height in any call to calculate_costs. */
163 /* Non-zero if we have dropped our controlling tty and therefore
164 should not open a frame on stdout. */
165 static int no_controlling_tty
;
167 /* Provided for lisp packages. */
169 static int system_uses_terminfo
;
173 extern char *tgetstr ();
177 /* We aren't X windows, but we aren't termcap either. This makes me
178 uncertain as to what value to use for frame.output_method. For
179 this file, we'll define FRAME_TERMCAP_P to be zero so that our
180 output hooks get called instead of the termcap functions. Probably
181 the best long-term solution is to define an output_windows_nt... */
183 #undef FRAME_TERMCAP_P
184 #define FRAME_TERMCAP_P(_f_) 0
185 #endif /* WINDOWSNT */
188 /* Ring the bell on a tty. */
191 tty_ring_bell (struct frame
*f
)
193 struct tty_display_info
*tty
= FRAME_TTY (f
);
197 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
198 ? tty
->TS_visible_bell
200 fflush (tty
->output
);
204 /* Set up termcap modes for Emacs. */
207 tty_set_terminal_modes (struct terminal
*terminal
)
209 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
213 if (tty
->TS_termcap_modes
)
214 OUTPUT (tty
, tty
->TS_termcap_modes
);
217 /* Output enough newlines to scroll all the old screen contents
218 off the screen, so it won't be overwritten and lost. */
221 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
225 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
226 OUTPUT_IF (tty
, visible_cursor
? tty
->TS_cursor_visible
: tty
->TS_cursor_normal
);
227 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
229 fflush (tty
->output
);
233 /* Reset termcap modes before exiting Emacs. */
236 tty_reset_terminal_modes (struct terminal
*terminal
)
238 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
242 tty_turn_off_highlight (tty
);
243 tty_turn_off_insert (tty
);
244 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
245 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
246 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
247 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
248 /* Output raw CR so kernel can track the cursor hpos. */
251 fflush (tty
->output
);
255 /* Flag the end of a display update on a termcap terminal. */
258 tty_update_end (struct frame
*f
)
260 struct tty_display_info
*tty
= FRAME_TTY (f
);
262 if (!XWINDOW (selected_window
)->cursor_off_p
)
263 tty_show_cursor (tty
);
264 tty_turn_off_insert (tty
);
265 tty_background_highlight (tty
);
268 /* The implementation of set_terminal_window for termcap frames. */
271 tty_set_terminal_window (struct frame
*f
, int size
)
273 struct tty_display_info
*tty
= FRAME_TTY (f
);
275 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
276 if (FRAME_SCROLL_REGION_OK (f
))
277 tty_set_scroll_region (f
, 0, tty
->specified_window
);
281 tty_set_scroll_region (struct frame
*f
, int start
, int stop
)
284 struct tty_display_info
*tty
= FRAME_TTY (f
);
286 if (tty
->TS_set_scroll_region
)
287 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
288 else if (tty
->TS_set_scroll_region_1
)
289 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
290 FRAME_LINES (f
), start
,
291 FRAME_LINES (f
) - stop
,
294 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
303 tty_turn_on_insert (struct tty_display_info
*tty
)
305 if (!tty
->insert_mode
)
306 OUTPUT (tty
, tty
->TS_insert_mode
);
307 tty
->insert_mode
= 1;
311 tty_turn_off_insert (struct tty_display_info
*tty
)
313 if (tty
->insert_mode
)
314 OUTPUT (tty
, tty
->TS_end_insert_mode
);
315 tty
->insert_mode
= 0;
318 /* Handle highlighting. */
321 tty_turn_off_highlight (struct tty_display_info
*tty
)
323 if (tty
->standout_mode
)
324 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
325 tty
->standout_mode
= 0;
329 tty_turn_on_highlight (struct tty_display_info
*tty
)
331 if (!tty
->standout_mode
)
332 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
333 tty
->standout_mode
= 1;
337 tty_toggle_highlight (struct tty_display_info
*tty
)
339 if (tty
->standout_mode
)
340 tty_turn_off_highlight (tty
);
342 tty_turn_on_highlight (tty
);
346 /* Make cursor invisible. */
349 tty_hide_cursor (struct tty_display_info
*tty
)
351 if (tty
->cursor_hidden
== 0)
353 tty
->cursor_hidden
= 1;
354 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
359 /* Ensure that cursor is visible. */
362 tty_show_cursor (struct tty_display_info
*tty
)
364 if (tty
->cursor_hidden
)
366 tty
->cursor_hidden
= 0;
367 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
369 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
374 /* Set standout mode to the state it should be in for
375 empty space inside windows. What this is,
376 depends on the user option inverse-video. */
379 tty_background_highlight (struct tty_display_info
*tty
)
382 tty_turn_on_highlight (tty
);
384 tty_turn_off_highlight (tty
);
387 /* Set standout mode to the mode specified for the text to be output. */
390 tty_highlight_if_desired (struct tty_display_info
*tty
)
393 tty_turn_on_highlight (tty
);
395 tty_turn_off_highlight (tty
);
399 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
400 frame-relative coordinates. */
403 tty_cursor_to (struct frame
*f
, int vpos
, int hpos
)
405 struct tty_display_info
*tty
= FRAME_TTY (f
);
407 /* Detect the case where we are called from reset_sys_modes
408 and the costs have never been calculated. Do nothing. */
409 if (! tty
->costs_set
)
412 if (curY (tty
) == vpos
413 && curX (tty
) == hpos
)
415 if (!tty
->TF_standout_motion
)
416 tty_background_highlight (tty
);
417 if (!tty
->TF_insmode_motion
)
418 tty_turn_off_insert (tty
);
419 cmgoto (tty
, vpos
, hpos
);
422 /* Similar but don't take any account of the wasted characters. */
425 tty_raw_cursor_to (struct frame
*f
, int row
, int col
)
427 struct tty_display_info
*tty
= FRAME_TTY (f
);
429 if (curY (tty
) == row
430 && curX (tty
) == col
)
432 if (!tty
->TF_standout_motion
)
433 tty_background_highlight (tty
);
434 if (!tty
->TF_insmode_motion
)
435 tty_turn_off_insert (tty
);
436 cmgoto (tty
, row
, col
);
439 /* Erase operations */
441 /* Clear from cursor to end of frame on a termcap device. */
444 tty_clear_to_end (struct frame
*f
)
447 struct tty_display_info
*tty
= FRAME_TTY (f
);
449 if (tty
->TS_clr_to_bottom
)
451 tty_background_highlight (tty
);
452 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
456 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
459 clear_end_of_line (f
, FRAME_COLS (f
));
464 /* Clear an entire termcap frame. */
467 tty_clear_frame (struct frame
*f
)
469 struct tty_display_info
*tty
= FRAME_TTY (f
);
471 if (tty
->TS_clr_frame
)
473 tty_background_highlight (tty
);
474 OUTPUT (tty
, tty
->TS_clr_frame
);
484 /* An implementation of clear_end_of_line for termcap frames.
486 Note that the cursor may be moved, on terminals lacking a `ce' string. */
489 tty_clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
492 struct tty_display_info
*tty
= FRAME_TTY (f
);
494 /* Detect the case where we are called from reset_sys_modes
495 and the costs have never been calculated. Do nothing. */
496 if (! tty
->costs_set
)
499 if (curX (tty
) >= first_unused_hpos
)
501 tty_background_highlight (tty
);
502 if (tty
->TS_clr_line
)
504 OUTPUT1 (tty
, tty
->TS_clr_line
);
507 { /* have to do it the hard way */
508 tty_turn_off_insert (tty
);
510 /* Do not write in last row last col with Auto-wrap on. */
512 && curY (tty
) == FrameRows (tty
) - 1
513 && first_unused_hpos
== FrameCols (tty
))
516 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
519 fputc (' ', tty
->termscript
);
520 fputc (' ', tty
->output
);
522 cmplus (tty
, first_unused_hpos
- curX (tty
));
526 /* Buffer to store the source and result of code conversion for terminal. */
527 static unsigned char *encode_terminal_buf
;
528 /* Allocated size of the above buffer. */
529 static int encode_terminal_bufsize
;
531 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
532 Set CODING->produced to the byte-length of the resulting byte
533 sequence, and return a pointer to that byte sequence. */
536 encode_terminal_code (src
, src_len
, coding
)
539 struct coding_system
*coding
;
541 struct glyph
*src_end
= src
+ src_len
;
544 int nchars
, nbytes
, required
;
545 register int tlen
= GLYPH_TABLE_LENGTH
;
546 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
548 /* Allocate sufficient size of buffer to store all characters in
549 multibyte-form. But, it may be enlarged on demand if
550 Vglyph_table contains a string. */
551 required
= MAX_MULTIBYTE_LENGTH
* src_len
;
552 if (encode_terminal_bufsize
< required
)
554 if (encode_terminal_bufsize
== 0)
555 encode_terminal_buf
= xmalloc (required
);
557 encode_terminal_buf
= xrealloc (encode_terminal_buf
, required
);
558 encode_terminal_bufsize
= required
;
561 buf
= encode_terminal_buf
;
563 while (src
< src_end
)
565 /* We must skip glyphs to be padded for a wide character. */
566 if (! CHAR_GLYPH_PADDING_P (*src
))
568 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
570 if (g
< 0 || g
>= tlen
)
572 /* This glyph doesn't has an entry in Vglyph_table. */
573 if (CHAR_VALID_P (src
->u
.ch
, 0))
574 buf
+= CHAR_STRING (src
->u
.ch
, buf
);
581 /* This glyph has an entry in Vglyph_table,
582 so process any alias before testing for simpleness. */
583 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
585 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
587 int c
= FAST_GLYPH_CHAR (g
);
589 if (CHAR_VALID_P (c
, 0))
590 buf
+= CHAR_STRING (c
, buf
);
597 /* We have a string in Vglyph_table. */
601 if (! STRING_MULTIBYTE (string
))
602 string
= string_to_multibyte (string
);
603 nbytes
= buf
- encode_terminal_buf
;
604 if (encode_terminal_bufsize
< nbytes
+ SBYTES (string
))
606 encode_terminal_bufsize
= nbytes
+ SBYTES (string
);
607 encode_terminal_buf
= xrealloc (encode_terminal_buf
,
608 encode_terminal_bufsize
);
609 buf
= encode_terminal_buf
+ nbytes
;
611 bcopy (SDATA (string
), buf
, SBYTES (string
));
612 buf
+= SBYTES (string
);
613 nchars
+= SCHARS (string
);
620 nbytes
= buf
- encode_terminal_buf
;
621 coding
->src_multibyte
= 1;
622 coding
->dst_multibyte
= 0;
623 if (SYMBOLP (coding
->pre_write_conversion
)
624 && ! NILP (Ffboundp (coding
->pre_write_conversion
)))
626 run_pre_write_conversin_on_c_str (&encode_terminal_buf
,
627 &encode_terminal_bufsize
,
628 nchars
, nbytes
, coding
);
629 nchars
= coding
->produced_char
;
630 nbytes
= coding
->produced
;
632 required
= nbytes
+ encoding_buffer_size (coding
, nbytes
);
633 if (encode_terminal_bufsize
< required
)
635 encode_terminal_bufsize
= required
;
636 encode_terminal_buf
= xrealloc (encode_terminal_buf
, required
);
639 encode_coding (coding
, encode_terminal_buf
, encode_terminal_buf
+ nbytes
,
640 nbytes
, encode_terminal_bufsize
- nbytes
);
641 return encode_terminal_buf
+ nbytes
;
645 /* An implementation of write_glyphs for termcap frames. */
648 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
650 unsigned char *conversion_buffer
;
651 struct coding_system
*coding
;
653 struct tty_display_info
*tty
= FRAME_TTY (f
);
655 tty_turn_off_insert (tty
);
656 tty_hide_cursor (tty
);
658 /* Don't dare write in last column of bottom line, if Auto-Wrap,
659 since that would scroll the whole frame on some terminals. */
662 && curY (tty
) + 1 == FRAME_LINES (f
)
663 && (curX (tty
) + len
) == FRAME_COLS (f
))
670 /* If terminal_coding does any conversion, use it, otherwise use
671 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
672 because it always return 1 if the member src_multibyte is 1. */
673 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
674 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
675 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
677 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
681 /* Identify a run of glyphs with the same face. */
682 int face_id
= string
->face_id
;
685 for (n
= 1; n
< len
; ++n
)
686 if (string
[n
].face_id
!= face_id
)
689 /* Turn appearance modes of the face of the run on. */
690 tty_highlight_if_desired (tty
);
691 turn_on_face (f
, face_id
);
694 /* This is the last run. */
695 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
696 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
697 if (coding
->produced
> 0)
700 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
701 if (ferror (tty
->output
))
702 clearerr (tty
->output
);
704 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
710 /* Turn appearance modes off. */
711 turn_off_face (f
, face_id
);
712 tty_turn_off_highlight (tty
);
718 /* An implementation of insert_glyphs for termcap frames. */
721 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
724 struct glyph
*glyph
= NULL
;
725 unsigned char *conversion_buffer
;
726 unsigned char space
[1];
727 struct coding_system
*coding
;
729 struct tty_display_info
*tty
= FRAME_TTY (f
);
731 if (tty
->TS_ins_multi_chars
)
733 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
737 write_glyphs (f
, start
, len
);
741 tty_turn_on_insert (tty
);
745 space
[0] = SPACEGLYPH
;
747 /* If terminal_coding does any conversion, use it, otherwise use
748 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
749 because it always return 1 if the member src_multibyte is 1. */
750 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
751 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
752 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
754 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
758 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
761 conversion_buffer
= space
;
762 coding
->produced
= 1;
766 tty_highlight_if_desired (tty
);
767 turn_on_face (f
, start
->face_id
);
770 /* We must open sufficient space for a character which
771 occupies more than one column. */
772 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
774 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
779 /* This is the last glyph. */
780 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
782 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
785 if (coding
->produced
> 0)
788 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
789 if (ferror (tty
->output
))
790 clearerr (tty
->output
);
792 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
796 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
799 turn_off_face (f
, glyph
->face_id
);
800 tty_turn_off_highlight (tty
);
807 /* An implementation of delete_glyphs for termcap frames. */
810 tty_delete_glyphs (struct frame
*f
, int n
)
815 struct tty_display_info
*tty
= FRAME_TTY (f
);
817 if (tty
->delete_in_insert_mode
)
819 tty_turn_on_insert (tty
);
823 tty_turn_off_insert (tty
);
824 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
827 if (tty
->TS_del_multi_chars
)
829 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
834 for (i
= 0; i
< n
; i
++)
835 OUTPUT1 (tty
, tty
->TS_del_char
);
836 if (!tty
->delete_in_insert_mode
)
837 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
840 /* An implementation of ins_del_lines for termcap frames. */
843 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
845 struct tty_display_info
*tty
= FRAME_TTY (f
);
846 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
847 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
848 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
850 register int i
= n
> 0 ? n
: -n
;
853 /* If the lines below the insertion are being pushed
854 into the end of the window, this is the same as clearing;
855 and we know the lines are already clear, since the matching
856 deletion has already been done. So can ignore this. */
857 /* If the lines below the deletion are blank lines coming
858 out of the end of the window, don't bother,
859 as there will be a matching inslines later that will flush them. */
860 if (FRAME_SCROLL_REGION_OK (f
)
861 && vpos
+ i
>= tty
->specified_window
)
863 if (!FRAME_MEMORY_BELOW_FRAME (f
)
864 && vpos
+ i
>= FRAME_LINES (f
))
869 raw_cursor_to (f
, vpos
, 0);
870 tty_background_highlight (tty
);
871 buf
= tparam (multi
, 0, 0, i
);
877 raw_cursor_to (f
, vpos
, 0);
878 tty_background_highlight (tty
);
880 OUTPUT (tty
, single
);
886 tty_set_scroll_region (f
, vpos
, tty
->specified_window
);
888 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
890 raw_cursor_to (f
, vpos
, 0);
891 tty_background_highlight (tty
);
893 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
894 tty_set_scroll_region (f
, 0, tty
->specified_window
);
897 if (!FRAME_SCROLL_REGION_OK (f
)
898 && FRAME_MEMORY_BELOW_FRAME (f
)
901 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
906 /* Compute cost of sending "str", in characters,
907 not counting any line-dependent padding. */
910 string_cost (char *str
)
914 tputs (str
, 0, evalcost
);
918 /* Compute cost of sending "str", in characters,
919 counting any line-dependent padding at one line. */
922 string_cost_one_line (char *str
)
926 tputs (str
, 1, evalcost
);
930 /* Compute per line amount of line-dependent padding,
931 in tenths of characters. */
934 per_line_cost (char *str
)
938 tputs (str
, 0, evalcost
);
941 tputs (str
, 10, evalcost
);
946 /* char_ins_del_cost[n] is cost of inserting N characters.
947 char_ins_del_cost[-n] is cost of deleting N characters.
948 The length of this vector is based on max_frame_cols. */
950 int *char_ins_del_vector
;
952 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
957 calculate_ins_del_char_costs (struct frame
*f
)
959 struct tty_display_info
*tty
= FRAME_TTY (f
);
960 int ins_startup_cost
, del_startup_cost
;
961 int ins_cost_per_char
, del_cost_per_char
;
965 if (tty
->TS_ins_multi_chars
)
967 ins_cost_per_char
= 0;
968 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
970 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
971 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
973 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
974 + string_cost (tty
->TS_end_insert_mode
))) / 100;
975 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
976 + string_cost_one_line (tty
->TS_pad_inserted_char
));
980 ins_startup_cost
= 9999;
981 ins_cost_per_char
= 0;
984 if (tty
->TS_del_multi_chars
)
986 del_cost_per_char
= 0;
987 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
989 else if (tty
->TS_del_char
)
991 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
992 + string_cost (tty
->TS_end_delete_mode
));
993 if (tty
->delete_in_insert_mode
)
994 del_startup_cost
/= 2;
995 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
999 del_startup_cost
= 9999;
1000 del_cost_per_char
= 0;
1003 /* Delete costs are at negative offsets */
1004 p
= &char_ins_del_cost (f
)[0];
1005 for (i
= FRAME_COLS (f
); --i
>= 0;)
1006 *--p
= (del_startup_cost
+= del_cost_per_char
);
1008 /* Doing nothing is free */
1009 p
= &char_ins_del_cost (f
)[0];
1012 /* Insert costs are at positive offsets */
1013 for (i
= FRAME_COLS (f
); --i
>= 0;)
1014 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1018 calculate_costs (struct frame
*frame
)
1020 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1022 if (FRAME_TERMCAP_P (frame
))
1024 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1025 register char *f
= (tty
->TS_set_scroll_region
1026 ? tty
->TS_set_scroll_region
1027 : tty
->TS_set_scroll_region_1
);
1029 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1033 /* These variables are only used for terminal stuff. They are
1034 allocated once for the terminal frame of X-windows emacs, but not
1037 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1038 X turns off char_ins_del_ok. */
1040 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1041 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1043 if (char_ins_del_vector
!= 0)
1045 = (int *) xrealloc (char_ins_del_vector
,
1047 + 2 * max_frame_cols
* sizeof (int)));
1050 = (int *) xmalloc (sizeof (int)
1051 + 2 * max_frame_cols
* sizeof (int));
1053 bzero (char_ins_del_vector
, (sizeof (int)
1054 + 2 * max_frame_cols
* sizeof (int)));
1057 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1058 do_line_insertion_deletion_costs (frame
,
1059 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1060 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1063 do_line_insertion_deletion_costs (frame
,
1064 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1065 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1068 calculate_ins_del_char_costs (frame
);
1070 /* Don't use TS_repeat if its padding is worse than sending the chars */
1071 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1072 tty
->RPov
= string_cost (tty
->TS_repeat
);
1074 tty
->RPov
= FRAME_COLS (frame
) * 2;
1076 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1084 /* Termcap capability names that correspond directly to X keysyms.
1085 Some of these (marked "terminfo") aren't supplied by old-style
1086 (Berkeley) termcap entries. They're listed in X keysym order;
1087 except we put the keypad keys first, so that if they clash with
1088 other keys (as on the IBM PC keyboard) they get overridden.
1091 static struct fkey_table keys
[] =
1093 {"kh", "home"}, /* termcap */
1094 {"kl", "left"}, /* termcap */
1095 {"ku", "up"}, /* termcap */
1096 {"kr", "right"}, /* termcap */
1097 {"kd", "down"}, /* termcap */
1098 {"%8", "prior"}, /* terminfo */
1099 {"%5", "next"}, /* terminfo */
1100 {"@7", "end"}, /* terminfo */
1101 {"@1", "begin"}, /* terminfo */
1102 {"*6", "select"}, /* terminfo */
1103 {"%9", "print"}, /* terminfo */
1104 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1106 * "insert" --- see below
1108 {"&8", "undo"}, /* terminfo */
1109 {"%0", "redo"}, /* terminfo */
1110 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1111 {"@0", "find"}, /* terminfo */
1112 {"@2", "cancel"}, /* terminfo */
1113 {"%1", "help"}, /* terminfo */
1115 * "break" goes here, but can't be reliably intercepted with termcap
1117 {"&4", "reset"}, /* terminfo --- actually `restart' */
1119 * "system" and "user" --- no termcaps
1121 {"kE", "clearline"}, /* terminfo */
1122 {"kA", "insertline"}, /* terminfo */
1123 {"kL", "deleteline"}, /* terminfo */
1124 {"kI", "insertchar"}, /* terminfo */
1125 {"kD", "deletechar"}, /* terminfo */
1126 {"kB", "backtab"}, /* terminfo */
1128 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1130 {"@8", "kp-enter"}, /* terminfo */
1132 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1133 * "kp-multiply", "kp-add", "kp-separator",
1134 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1135 * --- no termcaps for any of these.
1137 {"K4", "kp-1"}, /* terminfo */
1139 * "kp-2" --- no termcap
1141 {"K5", "kp-3"}, /* terminfo */
1143 * "kp-4" --- no termcap
1145 {"K2", "kp-5"}, /* terminfo */
1147 * "kp-6" --- no termcap
1149 {"K1", "kp-7"}, /* terminfo */
1151 * "kp-8" --- no termcap
1153 {"K3", "kp-9"}, /* terminfo */
1155 * "kp-equal" --- no termcap
1167 {"&0", "S-cancel"}, /*shifted cancel key*/
1168 {"&9", "S-begin"}, /*shifted begin key*/
1169 {"*0", "S-find"}, /*shifted find key*/
1170 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1171 {"*4", "S-delete"}, /*shifted delete-character key*/
1172 {"*7", "S-end"}, /*shifted end key*/
1173 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1174 {"#1", "S-help"}, /*shifted help key*/
1175 {"#2", "S-home"}, /*shifted home key*/
1176 {"#3", "S-insert"}, /*shifted insert-character key*/
1177 {"#4", "S-left"}, /*shifted left-arrow key*/
1178 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1179 {"%c", "S-next"}, /*shifted next key*/
1180 {"%e", "S-prior"}, /*shifted previous key*/
1181 {"%f", "S-print"}, /*shifted print key*/
1182 {"%g", "S-redo"}, /*shifted redo key*/
1183 {"%i", "S-right"}, /*shifted right-arrow key*/
1184 {"!3", "S-undo"} /*shifted undo key*/
1187 static char **term_get_fkeys_address
;
1188 static KBOARD
*term_get_fkeys_kboard
;
1189 static Lisp_Object
term_get_fkeys_1 ();
1191 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1192 This function scans the termcap function key sequence entries, and
1193 adds entries to Vfunction_key_map for each function key it finds. */
1196 term_get_fkeys (address
, kboard
)
1200 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1201 errors during the call. The only errors should be from Fdefine_key
1202 when given a key sequence containing an invalid prefix key. If the
1203 termcap defines function keys which use a prefix that is already bound
1204 to a command by the default bindings, we should silently ignore that
1205 function key specification, rather than giving the user an error and
1206 refusing to run at all on such a terminal. */
1208 extern Lisp_Object
Fidentity ();
1209 term_get_fkeys_address
= address
;
1210 term_get_fkeys_kboard
= kboard
;
1211 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1219 char **address
= term_get_fkeys_address
;
1220 KBOARD
*kboard
= term_get_fkeys_kboard
;
1222 /* This can happen if CANNOT_DUMP or with strange options. */
1224 kboard
->Vlocal_function_key_map
= Fmake_sparse_keymap (Qnil
);
1226 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1228 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1230 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (sequence
),
1231 Fmake_vector (make_number (1),
1232 intern (keys
[i
].name
)));
1235 /* The uses of the "k0" capability are inconsistent; sometimes it
1236 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1237 We will attempt to politely accommodate both systems by testing for
1238 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1241 char *k_semi
= tgetstr ("k;", address
);
1242 char *k0
= tgetstr ("k0", address
);
1243 char *k0_name
= "f10";
1248 /* Define f0 first, so that f10 takes precedence in case the
1249 key sequences happens to be the same. */
1250 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (k0
),
1251 Fmake_vector (make_number (1), intern ("f0")));
1252 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (k_semi
),
1253 Fmake_vector (make_number (1), intern ("f10")));
1256 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (k0
),
1257 Fmake_vector (make_number (1), intern (k0_name
)));
1260 /* Set up cookies for numbered function keys above f10. */
1262 char fcap
[3], fkey
[4];
1264 fcap
[0] = 'F'; fcap
[2] = '\0';
1265 for (i
= 11; i
< 64; i
++)
1268 fcap
[1] = '1' + i
- 11;
1270 fcap
[1] = 'A' + i
- 20;
1272 fcap
[1] = 'a' + i
- 46;
1275 char *sequence
= tgetstr (fcap
, address
);
1278 sprintf (fkey
, "f%d", i
);
1279 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (sequence
),
1280 Fmake_vector (make_number (1),
1288 * Various mappings to try and get a better fit.
1291 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1292 if (!tgetstr (cap1, address)) \
1294 char *sequence = tgetstr (cap2, address); \
1296 Fdefine_key (kboard->Vlocal_function_key_map, build_string (sequence), \
1297 Fmake_vector (make_number (1), \
1301 /* if there's no key_next keycap, map key_npage to `next' keysym */
1302 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1303 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1304 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1305 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1306 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1307 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1308 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1310 /* IBM has their own non-standard dialect of terminfo.
1311 If the standard name isn't found, try the IBM name. */
1312 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1313 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1314 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1315 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1316 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1317 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1318 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1319 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1320 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1321 #undef CONDITIONAL_REASSIGN
1328 /***********************************************************************
1329 Character Display Information
1330 ***********************************************************************/
1332 /* Avoid name clash with functions defined in xterm.c */
1334 #define append_glyph append_glyph_term
1335 #define produce_stretch_glyph produce_stretch_glyph_term
1338 static void append_glyph
P_ ((struct it
*));
1339 static void produce_stretch_glyph
P_ ((struct it
*));
1342 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1343 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1344 the character for which to produce glyphs; IT->face_id contains the
1345 character's face. Padding glyphs are appended if IT->c has a
1346 IT->pixel_width > 1. */
1352 struct glyph
*glyph
, *end
;
1355 xassert (it
->glyph_row
);
1356 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1357 + it
->glyph_row
->used
[it
->area
]);
1358 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1361 i
< it
->pixel_width
&& glyph
< end
;
1364 glyph
->type
= CHAR_GLYPH
;
1365 glyph
->pixel_width
= 1;
1366 glyph
->u
.ch
= it
->char_to_display
;
1367 glyph
->face_id
= it
->face_id
;
1368 glyph
->padding_p
= i
> 0;
1369 glyph
->charpos
= CHARPOS (it
->position
);
1370 glyph
->object
= it
->object
;
1372 ++it
->glyph_row
->used
[it
->area
];
1378 /* Produce glyphs for the display element described by IT. *IT
1379 specifies what we want to produce a glyph for (character, image, ...),
1380 and where in the glyph matrix we currently are (glyph row and hpos).
1381 produce_glyphs fills in output fields of *IT with information such as the
1382 pixel width and height of a character, and maybe output actual glyphs at
1383 the same time if IT->glyph_row is non-null. See the explanation of
1384 struct display_iterator in dispextern.h for an overview.
1386 produce_glyphs also stores the result of glyph width, ascent
1387 etc. computations in *IT.
1389 IT->glyph_row may be null, in which case produce_glyphs does not
1390 actually fill in the glyphs. This is used in the move_* functions
1391 in xdisp.c for text width and height computations.
1393 Callers usually don't call produce_glyphs directly;
1394 instead they use the macro PRODUCE_GLYPHS. */
1400 /* If a hook is installed, let it do the work. */
1401 xassert (it
->what
== IT_CHARACTER
1402 || it
->what
== IT_COMPOSITION
1403 || it
->what
== IT_STRETCH
);
1405 if (it
->what
== IT_STRETCH
)
1407 produce_stretch_glyph (it
);
1411 /* Nothing but characters are supported on terminal frames. For a
1412 composition sequence, it->c is the first character of the
1414 xassert (it
->what
== IT_CHARACTER
1415 || it
->what
== IT_COMPOSITION
);
1417 /* Maybe translate single-byte characters to multibyte. */
1418 it
->char_to_display
= it
->c
;
1420 if (it
->c
>= 040 && it
->c
< 0177)
1422 it
->pixel_width
= it
->nglyphs
= 1;
1426 else if (it
->c
== '\n')
1427 it
->pixel_width
= it
->nglyphs
= 0;
1428 else if (it
->c
== '\t')
1430 int absolute_x
= (it
->current_x
1431 + it
->continuation_lines_width
);
1433 = (((1 + absolute_x
+ it
->tab_width
- 1)
1438 /* If part of the TAB has been displayed on the previous line
1439 which is continued now, continuation_lines_width will have
1440 been incremented already by the part that fitted on the
1441 continued line. So, we will get the right number of spaces
1443 nspaces
= next_tab_x
- absolute_x
;
1449 it
->char_to_display
= ' ';
1450 it
->pixel_width
= it
->len
= 1;
1456 it
->pixel_width
= nspaces
;
1457 it
->nglyphs
= nspaces
;
1459 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1461 if (unibyte_display_via_language_environment
1463 || !NILP (Vnonascii_translation_table
)))
1467 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1468 charset
= CHAR_CHARSET (it
->char_to_display
);
1469 it
->pixel_width
= CHARSET_WIDTH (charset
);
1470 it
->nglyphs
= it
->pixel_width
;
1476 /* Coming here means that it->c is from display table, thus we
1477 must send the code as is to the terminal. Although there's
1478 no way to know how many columns it occupies on a screen, it
1479 is a good assumption that a single byte code has 1-column
1481 it
->pixel_width
= it
->nglyphs
= 1;
1488 /* A multi-byte character. The display width is fixed for all
1489 characters of the set. Some of the glyphs may have to be
1490 ignored because they are already displayed in a continued
1492 int charset
= CHAR_CHARSET (it
->c
);
1494 it
->pixel_width
= CHARSET_WIDTH (charset
);
1495 it
->nglyphs
= it
->pixel_width
;
1502 /* Advance current_x by the pixel width as a convenience for
1504 if (it
->area
== TEXT_AREA
)
1505 it
->current_x
+= it
->pixel_width
;
1506 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1507 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1511 /* Produce a stretch glyph for iterator IT. IT->object is the value
1512 of the glyph property displayed. The value must be a list
1513 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1516 1. `:width WIDTH' specifies that the space should be WIDTH *
1517 canonical char width wide. WIDTH may be an integer or floating
1520 2. `:align-to HPOS' specifies that the space should be wide enough
1521 to reach HPOS, a value in canonical character units. */
1524 produce_stretch_glyph (it
)
1527 /* (space :width WIDTH ...) */
1528 Lisp_Object prop
, plist
;
1529 int width
= 0, align_to
= -1;
1530 int zero_width_ok_p
= 0;
1533 /* List should start with `space'. */
1534 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1535 plist
= XCDR (it
->object
);
1537 /* Compute the width of the stretch. */
1538 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1539 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1541 /* Absolute width `:width WIDTH' specified and valid. */
1542 zero_width_ok_p
= 1;
1543 width
= (int)(tem
+ 0.5);
1545 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1546 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1548 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1549 align_to
= (align_to
< 0
1551 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1552 else if (align_to
< 0)
1553 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1554 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1555 zero_width_ok_p
= 1;
1558 /* Nothing specified -> width defaults to canonical char width. */
1559 width
= FRAME_COLUMN_WIDTH (it
->f
);
1561 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1564 if (width
> 0 && it
->glyph_row
)
1566 Lisp_Object o_object
= it
->object
;
1567 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1570 if (!STRINGP (object
))
1571 object
= it
->w
->buffer
;
1572 it
->object
= object
;
1573 it
->char_to_display
= ' ';
1574 it
->pixel_width
= it
->len
= 1;
1577 it
->object
= o_object
;
1579 it
->pixel_width
= width
;
1580 it
->nglyphs
= width
;
1584 /* Get information about special display element WHAT in an
1585 environment described by IT. WHAT is one of IT_TRUNCATION or
1586 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1587 non-null glyph_row member. This function ensures that fields like
1588 face_id, c, len of IT are left untouched. */
1591 produce_special_glyphs (it
, what
)
1593 enum display_element_type what
;
1600 temp_it
.what
= IT_CHARACTER
;
1602 temp_it
.object
= make_number (0);
1603 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1605 if (what
== IT_CONTINUATION
)
1607 /* Continuation glyph. */
1609 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1610 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1612 glyph
= XINT (DISP_CONTINUE_GLYPH (it
->dp
));
1613 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
1618 else if (what
== IT_TRUNCATION
)
1620 /* Truncation glyph. */
1622 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1623 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1625 glyph
= XINT (DISP_TRUNC_GLYPH (it
->dp
));
1626 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
1634 temp_it
.c
= FAST_GLYPH_CHAR (glyph
);
1635 temp_it
.face_id
= FAST_GLYPH_FACE (glyph
);
1636 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1638 produce_glyphs (&temp_it
);
1639 it
->pixel_width
= temp_it
.pixel_width
;
1640 it
->nglyphs
= temp_it
.pixel_width
;
1645 /***********************************************************************
1647 ***********************************************************************/
1649 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1650 one of the enumerators from enum no_color_bit, or a bit set built
1651 from them. Some display attributes may not be used together with
1652 color; the termcap capability `NC' specifies which ones. */
1654 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1655 (tty->TN_max_colors > 0 \
1656 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1659 /* Turn appearances of face FACE_ID on tty frame F on.
1660 FACE_ID is a realized face ID number, in the face cache. */
1663 turn_on_face (f
, face_id
)
1667 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1668 long fg
= face
->foreground
;
1669 long bg
= face
->background
;
1670 struct tty_display_info
*tty
= FRAME_TTY (f
);
1672 /* Do this first because TS_end_standout_mode may be the same
1673 as TS_exit_attribute_mode, which turns all appearances off. */
1674 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1676 if (tty
->TN_max_colors
> 0)
1678 if (fg
>= 0 && bg
>= 0)
1680 /* If the terminal supports colors, we can set them
1681 below without using reverse video. The face's fg
1682 and bg colors are set as they should appear on
1683 the screen, i.e. they take the inverse-video'ness
1684 of the face already into account. */
1686 else if (inverse_video
)
1688 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1689 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1690 tty_toggle_highlight (tty
);
1694 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1695 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1696 tty_toggle_highlight (tty
);
1701 /* If we can't display colors, use reverse video
1702 if the face specifies that. */
1705 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1706 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1707 tty_toggle_highlight (tty
);
1711 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1712 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1713 tty_toggle_highlight (tty
);
1718 if (face
->tty_bold_p
)
1720 if (MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1721 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1723 else if (face
->tty_dim_p
)
1724 if (MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1725 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1727 /* Alternate charset and blinking not yet used. */
1728 if (face
->tty_alt_charset_p
1729 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1730 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1732 if (face
->tty_blinking_p
1733 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1734 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1736 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1737 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1739 if (tty
->TN_max_colors
> 0)
1743 ts
= tty
->standout_mode
? tty
->TS_set_background
: tty
->TS_set_foreground
;
1746 p
= tparam (ts
, NULL
, 0, (int) fg
);
1751 ts
= tty
->standout_mode
? tty
->TS_set_foreground
: tty
->TS_set_background
;
1754 p
= tparam (ts
, NULL
, 0, (int) bg
);
1762 /* Turn off appearances of face FACE_ID on tty frame F. */
1765 turn_off_face (f
, face_id
)
1769 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1770 struct tty_display_info
*tty
= FRAME_TTY (f
);
1772 xassert (face
!= NULL
);
1774 if (tty
->TS_exit_attribute_mode
)
1776 /* Capability "me" will turn off appearance modes double-bright,
1777 half-bright, reverse-video, standout, underline. It may or
1778 may not turn off alt-char-mode. */
1779 if (face
->tty_bold_p
1781 || face
->tty_reverse_p
1782 || face
->tty_alt_charset_p
1783 || face
->tty_blinking_p
1784 || face
->tty_underline_p
)
1786 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
1787 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
1788 tty
->standout_mode
= 0;
1791 if (face
->tty_alt_charset_p
)
1792 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1796 /* If we don't have "me" we can only have those appearances
1797 that have exit sequences defined. */
1798 if (face
->tty_alt_charset_p
)
1799 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1801 if (face
->tty_underline_p
)
1802 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
1805 /* Switch back to default colors. */
1806 if (tty
->TN_max_colors
> 0
1807 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
1808 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
1809 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
1810 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
1811 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
1815 /* Return non-zero if the terminal on frame F supports all of the
1816 capabilities in CAPS simultaneously, with foreground and background
1817 colors FG and BG. */
1820 tty_capable_p (tty
, caps
, fg
, bg
)
1821 struct tty_display_info
*tty
;
1823 unsigned long fg
, bg
;
1825 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
1826 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
1829 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
1830 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
1831 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
1832 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
1833 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
1834 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
1840 /* Return non-zero if the terminal is capable to display colors. */
1842 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
1844 doc
: /* Return non-nil if the tty device TERMINAL can display colors.
1846 TERMINAL can be a terminal id, a frame or nil (meaning the selected
1847 frame's terminal). This function always returns nil if TERMINAL
1848 is not on a tty device. */)
1850 Lisp_Object terminal
;
1852 struct terminal
*t
= get_tty_terminal (terminal
, 0);
1856 return t
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
1859 /* Return the number of supported colors. */
1860 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
1861 Stty_display_color_cells
, 0, 1, 0,
1862 doc
: /* Return the number of colors supported by the tty device TERMINAL.
1864 TERMINAL can be a terminal id, a frame or nil (meaning the selected
1865 frame's terminal). This function always returns 0 if TERMINAL
1866 is not on a tty device. */)
1868 Lisp_Object terminal
;
1870 struct terminal
*t
= get_tty_terminal (terminal
, 0);
1872 return make_number (0);
1874 return make_number (t
->display_info
.tty
->TN_max_colors
);
1879 /* Save or restore the default color-related capabilities of this
1882 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
1885 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
1886 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
1890 if (default_orig_pair
)
1891 xfree (default_orig_pair
);
1892 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
1894 if (default_set_foreground
)
1895 xfree (default_set_foreground
);
1896 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
1899 if (default_set_background
)
1900 xfree (default_set_background
);
1901 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
1904 default_max_colors
= tty
->TN_max_colors
;
1905 default_max_pairs
= tty
->TN_max_pairs
;
1906 default_no_color_video
= tty
->TN_no_color_video
;
1910 tty
->TS_orig_pair
= default_orig_pair
;
1911 tty
->TS_set_foreground
= default_set_foreground
;
1912 tty
->TS_set_background
= default_set_background
;
1913 tty
->TN_max_colors
= default_max_colors
;
1914 tty
->TN_max_pairs
= default_max_pairs
;
1915 tty
->TN_no_color_video
= default_no_color_video
;
1919 /* Setup one of the standard tty color schemes according to MODE.
1920 MODE's value is generally the number of colors which we want to
1921 support; zero means set up for the default capabilities, the ones
1922 we saw at init_tty time; -1 means turn off color support. */
1924 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
1926 /* Canonicalize all negative values of MODE. */
1932 case -1: /* no colors at all */
1933 tty
->TN_max_colors
= 0;
1934 tty
->TN_max_pairs
= 0;
1935 tty
->TN_no_color_video
= 0;
1936 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
1938 case 0: /* default colors, if any */
1940 tty_default_color_capabilities (tty
, 0);
1942 case 8: /* 8 standard ANSI colors */
1943 tty
->TS_orig_pair
= "\033[0m";
1945 tty
->TS_set_foreground
= "\033[3%p1%dm";
1946 tty
->TS_set_background
= "\033[4%p1%dm";
1948 tty
->TS_set_foreground
= "\033[3%dm";
1949 tty
->TS_set_background
= "\033[4%dm";
1951 tty
->TN_max_colors
= 8;
1952 tty
->TN_max_pairs
= 64;
1953 tty
->TN_no_color_video
= 0;
1959 set_tty_color_mode (f
, val
)
1963 Lisp_Object color_mode_spec
, current_mode_spec
;
1964 Lisp_Object color_mode
, current_mode
;
1966 extern Lisp_Object Qtty_color_mode
;
1967 Lisp_Object tty_color_mode_alist
;
1969 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
1976 if (NILP (tty_color_mode_alist
))
1977 color_mode_spec
= Qnil
;
1979 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
1981 if (CONSP (color_mode_spec
))
1982 color_mode
= XCDR (color_mode_spec
);
1987 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
1989 if (CONSP (current_mode_spec
))
1990 current_mode
= XCDR (current_mode_spec
);
1992 current_mode
= Qnil
;
1993 if (INTEGERP (color_mode
))
1994 mode
= XINT (color_mode
);
1996 mode
= 0; /* meaning default */
1997 if (INTEGERP (current_mode
))
1998 old_mode
= XINT (current_mode
);
2002 if (mode
!= old_mode
)
2004 tty_setup_colors (FRAME_TTY (f
), mode
);
2005 /* This recomputes all the faces given the new color
2007 call0 (intern ("tty-set-up-initial-frame-faces"));
2012 #endif /* !WINDOWSNT */
2016 /* Return the tty display object specified by TERMINAL. */
2019 get_tty_terminal (Lisp_Object terminal
, int throw)
2021 struct terminal
*t
= get_terminal (terminal
, throw);
2023 if (t
&& t
->type
== output_initial
)
2026 if (t
&& t
->type
!= output_termcap
)
2029 error ("Device %d is not a termcap terminal device", t
->id
);
2037 /* Return an active termcap device that uses the tty device with the
2040 This function ignores suspended devices.
2042 Returns NULL if the named terminal device is not opened. */
2045 get_named_tty (name
)
2053 for (t
= terminal_list
; t
; t
= t
->next_terminal
)
2055 if (t
->type
== output_termcap
2056 && !strcmp (t
->display_info
.tty
->name
, name
)
2057 && TERMINAL_ACTIVE_P (t
))
2065 DEFUN ("tty-type", Ftty_type
, Stty_type
, 0, 1, 0,
2066 doc
: /* Return the type of the tty device that TERMINAL uses.
2067 Returns nil if TERMINAL is not on a tty device.
2069 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2070 frame's terminal). */)
2072 Lisp_Object terminal
;
2074 struct terminal
*t
= get_terminal (terminal
, 1);
2076 if (t
->type
!= output_termcap
)
2079 if (t
->display_info
.tty
->type
)
2080 return build_string (t
->display_info
.tty
->type
);
2085 DEFUN ("controlling-tty-p", Fcontrolling_tty_p
, Scontrolling_tty_p
, 0, 1, 0,
2086 doc
: /* Return non-nil if TERMINAL is on the controlling tty of the Emacs process.
2088 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2089 frame's terminal). This function always returns nil if TERMINAL
2090 is not on a tty device. */)
2092 Lisp_Object terminal
;
2094 struct terminal
*t
= get_terminal (terminal
, 1);
2096 if (t
->type
!= output_termcap
|| strcmp (t
->display_info
.tty
->name
, "/dev/tty"))
2102 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 1, 0,
2103 doc
: /* Declare that the tty used by TERMINAL does not handle underlining.
2104 This is used to override the terminfo data, for certain terminals that
2105 do not really do underlining, but say that they do. This function has
2106 no effect if used on a non-tty terminal.
2108 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2109 frame's terminal). This function always returns nil if TERMINAL
2110 is not on a tty device. */)
2112 Lisp_Object terminal
;
2114 struct terminal
*t
= get_terminal (terminal
, 1);
2116 if (t
->type
== output_termcap
)
2117 t
->display_info
.tty
->TS_enter_underline_mode
= 0;
2123 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
2124 doc
: /* Suspend the terminal device TTY.
2126 The device is restored to its default state, and Emacs ceases all
2127 access to the tty device. Frames that use the device are not deleted,
2128 but input is not read from them and if they change, their display is
2131 TTY may be a terminal id, a frame, or nil for the terminal device of
2132 the currently selected frame.
2134 This function runs `suspend-tty-functions' after suspending the
2135 device. The functions are run with one arg, the id of the suspended
2138 `suspend-tty' does nothing if it is called on a device that is already
2141 A suspended tty may be resumed by calling `resume-tty' on it. */)
2145 struct terminal
*t
= get_tty_terminal (tty
, 1);
2149 error ("Unknown tty device");
2151 f
= t
->display_info
.tty
->input
;
2155 reset_sys_modes (t
->display_info
.tty
);
2157 delete_keyboard_wait_descriptor (fileno (f
));
2160 if (f
!= t
->display_info
.tty
->output
)
2161 fclose (t
->display_info
.tty
->output
);
2163 t
->display_info
.tty
->input
= 0;
2164 t
->display_info
.tty
->output
= 0;
2166 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2167 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 0);
2169 /* Run `suspend-tty-functions'. */
2170 if (!NILP (Vrun_hooks
))
2172 Lisp_Object args
[2];
2173 args
[0] = intern ("suspend-tty-functions");
2174 args
[1] = make_number (t
->id
);
2175 Frun_hook_with_args (2, args
);
2179 /* Clear display hooks to prevent further output. */
2180 clear_tty_hooks (t
);
2185 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
2186 doc
: /* Resume the previously suspended terminal device TTY.
2187 The terminal is opened and reinitialized. Frames that are on the
2188 suspended terminal are revived.
2190 It is an error to resume a terminal while another terminal is active
2193 This function runs `resume-tty-functions' after resuming the terminal.
2194 The functions are run with one arg, the id of the resumed terminal
2197 `resume-tty' does nothing if it is called on a device that is not
2200 TTY may be a terminal id, a frame, or nil for the terminal device of
2201 the currently selected frame. */)
2205 struct terminal
*t
= get_tty_terminal (tty
, 1);
2209 error ("Unknown tty device");
2211 if (!t
->display_info
.tty
->input
)
2213 if (get_named_tty (t
->display_info
.tty
->name
))
2214 error ("Cannot resume display while another display is active on the same device");
2216 fd
= emacs_open (t
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
2219 error ("Can not reopen tty device %s: %s", t
->display_info
.tty
->name
, strerror (errno
));
2221 if (strcmp (t
->display_info
.tty
->name
, "/dev/tty"))
2222 dissociate_if_controlling_tty (fd
);
2224 t
->display_info
.tty
->output
= fdopen (fd
, "w+");
2225 t
->display_info
.tty
->input
= t
->display_info
.tty
->output
;
2227 add_keyboard_wait_descriptor (fd
);
2229 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2230 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 1);
2232 init_sys_modes (t
->display_info
.tty
);
2234 /* Run `suspend-tty-functions'. */
2235 if (!NILP (Vrun_hooks
))
2237 Lisp_Object args
[2];
2238 args
[0] = intern ("resume-tty-functions");
2239 args
[1] = make_number (t
->id
);
2240 Frun_hook_with_args (2, args
);
2250 /***********************************************************************
2252 ***********************************************************************/
2254 /* Initialize the tty-dependent part of frame F. The frame must
2255 already have its device initialized. */
2258 create_tty_output (struct frame
*f
)
2260 struct tty_output
*t
;
2262 if (! FRAME_TERMCAP_P (f
))
2265 t
= xmalloc (sizeof (struct tty_output
));
2266 bzero (t
, sizeof (struct tty_output
));
2268 t
->display_info
= FRAME_TERMINAL (f
)->display_info
.tty
;
2270 f
->output_data
.tty
= t
;
2273 /* Delete the tty-dependent part of frame F. */
2276 delete_tty_output (struct frame
*f
)
2278 if (! FRAME_TERMCAP_P (f
))
2281 xfree (f
->output_data
.tty
);
2287 clear_tty_hooks (struct terminal
*terminal
)
2290 terminal
->cursor_to_hook
= 0;
2291 terminal
->raw_cursor_to_hook
= 0;
2292 terminal
->clear_to_end_hook
= 0;
2293 terminal
->clear_frame_hook
= 0;
2294 terminal
->clear_end_of_line_hook
= 0;
2295 terminal
->ins_del_lines_hook
= 0;
2296 terminal
->insert_glyphs_hook
= 0;
2297 terminal
->write_glyphs_hook
= 0;
2298 terminal
->delete_glyphs_hook
= 0;
2299 terminal
->ring_bell_hook
= 0;
2300 terminal
->reset_terminal_modes_hook
= 0;
2301 terminal
->set_terminal_modes_hook
= 0;
2302 terminal
->update_begin_hook
= 0;
2303 terminal
->update_end_hook
= 0;
2304 terminal
->set_terminal_window_hook
= 0;
2305 terminal
->mouse_position_hook
= 0;
2306 terminal
->frame_rehighlight_hook
= 0;
2307 terminal
->frame_raise_lower_hook
= 0;
2308 terminal
->fullscreen_hook
= 0;
2309 terminal
->set_vertical_scroll_bar_hook
= 0;
2310 terminal
->condemn_scroll_bars_hook
= 0;
2311 terminal
->redeem_scroll_bar_hook
= 0;
2312 terminal
->judge_scroll_bars_hook
= 0;
2313 terminal
->read_socket_hook
= 0;
2314 terminal
->frame_up_to_date_hook
= 0;
2316 /* Leave these two set, or suspended frames are not deleted
2318 terminal
->delete_frame_hook
= &delete_tty_output
;
2319 terminal
->delete_terminal_hook
= &delete_tty
;
2323 set_tty_hooks (struct terminal
*terminal
)
2325 terminal
->rif
= 0; /* ttys don't support window-based redisplay. */
2327 terminal
->cursor_to_hook
= &tty_cursor_to
;
2328 terminal
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
2330 terminal
->clear_to_end_hook
= &tty_clear_to_end
;
2331 terminal
->clear_frame_hook
= &tty_clear_frame
;
2332 terminal
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
2334 terminal
->ins_del_lines_hook
= &tty_ins_del_lines
;
2336 terminal
->insert_glyphs_hook
= &tty_insert_glyphs
;
2337 terminal
->write_glyphs_hook
= &tty_write_glyphs
;
2338 terminal
->delete_glyphs_hook
= &tty_delete_glyphs
;
2340 terminal
->ring_bell_hook
= &tty_ring_bell
;
2342 terminal
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
2343 terminal
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
2344 terminal
->update_begin_hook
= 0; /* Not needed. */
2345 terminal
->update_end_hook
= &tty_update_end
;
2346 terminal
->set_terminal_window_hook
= &tty_set_terminal_window
;
2348 terminal
->mouse_position_hook
= 0; /* Not needed. */
2349 terminal
->frame_rehighlight_hook
= 0; /* Not needed. */
2350 terminal
->frame_raise_lower_hook
= 0; /* Not needed. */
2352 terminal
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
2353 terminal
->condemn_scroll_bars_hook
= 0; /* Not needed. */
2354 terminal
->redeem_scroll_bar_hook
= 0; /* Not needed. */
2355 terminal
->judge_scroll_bars_hook
= 0; /* Not needed. */
2357 terminal
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
2358 terminal
->frame_up_to_date_hook
= 0; /* Not needed. */
2360 terminal
->delete_frame_hook
= &delete_tty_output
;
2361 terminal
->delete_terminal_hook
= &delete_tty
;
2364 /* Drop the controlling terminal if fd is the same device. */
2366 dissociate_if_controlling_tty (int fd
)
2370 EMACS_GET_TTY_PGRP (fd
, &pgid
); /* If tcgetpgrp succeeds, fd is the ctty. */
2373 #if defined (USG) && !defined (BSD_PGRPS)
2375 no_controlling_tty
= 1;
2377 #ifdef TIOCNOTTY /* Try BSD ioctls. */
2378 sigblock (sigmask (SIGTTOU
));
2379 fd
= emacs_open ("/dev/tty", O_RDWR
, 0);
2380 if (fd
!= -1 && ioctl (fd
, TIOCNOTTY
, 0) != -1)
2382 no_controlling_tty
= 1;
2386 sigunblock (sigmask (SIGTTOU
));
2388 /* Unknown system. */
2390 #endif /* ! TIOCNOTTY */
2396 static void maybe_fatal();
2398 /* Create a termcap display on the tty device with the given name and
2401 If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
2402 Otherwise NAME should be a path to the tty device file,
2405 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
2407 If MUST_SUCCEED is true, then all errors are fatal. */
2410 init_tty (char *name
, char *terminal_type
, int must_succeed
)
2413 char **address
= &area
;
2414 char *buffer
= NULL
;
2415 int buffer_size
= 4096;
2416 register char *p
= NULL
;
2418 struct tty_display_info
*tty
= NULL
;
2419 struct terminal
*terminal
= NULL
;
2420 int ctty
= 0; /* 1 if asked to open controlling tty. */
2423 maybe_fatal (must_succeed
, 0, 0,
2424 "Unknown terminal type",
2425 "Unknown terminal type");
2430 if (!strcmp (name
, "/dev/tty"))
2433 /* If we already have a terminal on the given device, use that. If
2434 all such terminals are suspended, create a new one instead. */
2435 /* XXX Perhaps this should be made explicit by having init_tty
2436 always create a new terminal and separating terminal and frame
2437 creation on Lisp level. */
2438 terminal
= get_named_tty (name
);
2443 terminal
= create_terminal ();
2444 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
2445 bzero (tty
, sizeof (struct tty_display_info
));
2446 tty
->next
= tty_list
;
2449 terminal
->type
= output_termcap
;
2450 terminal
->display_info
.tty
= tty
;
2451 tty
->terminal
= terminal
;
2453 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
2457 set_tty_hooks (terminal
);
2463 #ifdef O_IGNORE_CTTY
2465 /* Open the terminal device. Don't recognize it as our
2466 controlling terminal, and don't make it the controlling tty
2467 if we don't have one at the moment. */
2468 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
2471 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
2472 defined on Hurd. On other systems, we need to explicitly
2473 dissociate ourselves from the controlling tty when we want to
2474 open a frame on the same terminal. */
2475 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
2476 #endif /* O_IGNORE_CTTY */
2479 maybe_fatal (must_succeed
, buffer
, terminal
,
2480 "Could not open file: %s",
2481 "Could not open file: %s",
2486 maybe_fatal (must_succeed
, buffer
, terminal
,
2487 "Not a tty device: %s",
2488 "Not a tty device: %s",
2492 #ifndef O_IGNORE_CTTY
2494 dissociate_if_controlling_tty (fd
);
2497 file
= fdopen (fd
, "w+");
2498 tty
->name
= xstrdup (name
);
2499 terminal
->name
= xstrdup (name
);
2504 tty
->type
= xstrdup (terminal_type
);
2506 add_keyboard_wait_descriptor (fileno (tty
->input
));
2510 encode_terminal_bufsize
= 0;
2513 initialize_w32_display ();
2515 /* XXX Can this be non-null? */
2518 tty
->name
= xstrdup (name
);
2519 terminal
->name
= xstrdup (name
);
2521 tty
->type
= xstrdup (terminal_type
);
2523 /* XXX not sure if this line is correct. If it is not set then we
2524 crash in update_display_1. */
2525 tty
->output
= stdout
;
2529 area
= (char *) xmalloc (2044); /* XXX this seems unused. */
2532 struct frame
*f
= XFRAME (selected_frame
);
2534 FrameRows (tty
) = FRAME_LINES (f
); /* XXX */
2535 FrameCols (tty
) = FRAME_COLS (f
); /* XXX */
2536 tty
->specified_window
= FRAME_LINES (f
); /* XXX */
2538 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0; /* XXX */
2539 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
; /* XXX */
2541 tty
->delete_in_insert_mode
= 1;
2544 terminal
->scroll_region_ok
= 0;
2546 /* Seems to insert lines when it's not supposed to, messing up the
2547 display. In doing a trace, it didn't seem to be called much, so I
2548 don't think we're losing anything by turning it off. */
2549 terminal
->line_ins_del_ok
= 0;
2550 terminal
->char_ins_del_ok
= 1;
2554 tty
->TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2557 #else /* not WINDOWSNT */
2561 buffer
= (char *) xmalloc (buffer_size
);
2563 /* On some systems, tgetent tries to access the controlling
2565 sigblock (sigmask (SIGTTOU
));
2566 status
= tgetent (buffer
, terminal_type
);
2567 sigunblock (sigmask (SIGTTOU
));
2572 maybe_fatal (must_succeed
, buffer
, terminal
,
2573 "Cannot open terminfo database file",
2574 "Cannot open terminfo database file");
2576 maybe_fatal (must_succeed
, buffer
, terminal
,
2577 "Cannot open termcap database file",
2578 "Cannot open termcap database file");
2584 maybe_fatal (must_succeed
, buffer
, terminal
,
2585 "Terminal type %s is not defined",
2586 "Terminal type %s is not defined.\n\
2587 If that is not the actual type of terminal you have,\n\
2588 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2589 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2590 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2593 maybe_fatal (must_succeed
, buffer
, terminal
,
2594 "Terminal type %s is not defined",
2595 "Terminal type %s is not defined.\n\
2596 If that is not the actual type of terminal you have,\n\
2597 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2598 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2599 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2605 if (strlen (buffer
) >= buffer_size
)
2607 buffer_size
= strlen (buffer
);
2609 area
= (char *) xmalloc (buffer_size
);
2611 tty
->TS_ins_line
= tgetstr ("al", address
);
2612 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
2613 tty
->TS_bell
= tgetstr ("bl", address
);
2614 BackTab (tty
) = tgetstr ("bt", address
);
2615 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
2616 tty
->TS_clr_line
= tgetstr ("ce", address
);
2617 tty
->TS_clr_frame
= tgetstr ("cl", address
);
2618 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
2619 AbsPosition (tty
) = tgetstr ("cm", address
);
2620 CR (tty
) = tgetstr ("cr", address
);
2621 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
2622 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
2623 RowPosition (tty
) = tgetstr ("cv", address
);
2624 tty
->TS_del_char
= tgetstr ("dc", address
);
2625 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
2626 tty
->TS_del_line
= tgetstr ("dl", address
);
2627 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
2628 tty
->TS_delete_mode
= tgetstr ("dm", address
);
2629 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
2630 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
2631 Home (tty
) = tgetstr ("ho", address
);
2632 tty
->TS_ins_char
= tgetstr ("ic", address
);
2633 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
2634 tty
->TS_insert_mode
= tgetstr ("im", address
);
2635 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
2636 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
2637 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
2638 LastLine (tty
) = tgetstr ("ll", address
);
2639 Right (tty
) = tgetstr ("nd", address
);
2640 Down (tty
) = tgetstr ("do", address
);
2642 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
2644 /* VMS puts a carriage return before each linefeed,
2645 so it is not safe to use linefeeds. */
2646 if (Down (tty
) && Down (tty
)[0] == '\n' && Down (tty
)[1] == '\0')
2649 if (tgetflag ("bs"))
2650 Left (tty
) = "\b"; /* can't possibly be longer! */
2651 else /* (Actually, "bs" is obsolete...) */
2652 Left (tty
) = tgetstr ("le", address
);
2654 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
2655 tty
->TS_pad_char
= tgetstr ("pc", address
);
2656 tty
->TS_repeat
= tgetstr ("rp", address
);
2657 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
2658 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
2659 tty
->TS_standout_mode
= tgetstr ("so", address
);
2660 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
2661 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
2662 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
2663 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
2664 Up (tty
) = tgetstr ("up", address
);
2665 tty
->TS_visible_bell
= tgetstr ("vb", address
);
2666 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
2667 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
2668 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
2669 tty
->TS_set_window
= tgetstr ("wi", address
);
2671 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
2672 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
2673 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
2674 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
2675 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
2676 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
2677 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2678 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2679 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
2681 MultiUp (tty
) = tgetstr ("UP", address
);
2682 MultiDown (tty
) = tgetstr ("DO", address
);
2683 MultiLeft (tty
) = tgetstr ("LE", address
);
2684 MultiRight (tty
) = tgetstr ("RI", address
);
2686 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2687 color because we can't switch back to the default foreground and
2689 tty
->TS_orig_pair
= tgetstr ("op", address
);
2690 if (tty
->TS_orig_pair
)
2692 tty
->TS_set_foreground
= tgetstr ("AF", address
);
2693 tty
->TS_set_background
= tgetstr ("AB", address
);
2694 if (!tty
->TS_set_foreground
)
2697 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
2698 tty
->TS_set_background
= tgetstr ("Sb", address
);
2701 tty
->TN_max_colors
= tgetnum ("Co");
2702 tty
->TN_max_pairs
= tgetnum ("pa");
2704 tty
->TN_no_color_video
= tgetnum ("NC");
2705 if (tty
->TN_no_color_video
== -1)
2706 tty
->TN_no_color_video
= 0;
2709 tty_default_color_capabilities (tty
, 1);
2711 MagicWrap (tty
) = tgetflag ("xn");
2712 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2713 the former flag imply the latter. */
2714 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
2715 terminal
->memory_below_frame
= tgetflag ("db");
2716 tty
->TF_hazeltine
= tgetflag ("hz");
2717 terminal
->must_write_spaces
= tgetflag ("in");
2718 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
2719 tty
->TF_insmode_motion
= tgetflag ("mi");
2720 tty
->TF_standout_motion
= tgetflag ("ms");
2721 tty
->TF_underscore
= tgetflag ("ul");
2722 tty
->TF_teleray
= tgetflag ("xt");
2725 terminal
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
2726 init_kboard (terminal
->kboard
);
2727 terminal
->kboard
->next_kboard
= all_kboards
;
2728 all_kboards
= terminal
->kboard
;
2729 terminal
->kboard
->reference_count
++;
2730 /* Don't let the initial kboard remain current longer than necessary.
2731 That would cause problems if a file loaded on startup tries to
2732 prompt in the mini-buffer. */
2733 if (current_kboard
== initial_kboard
)
2734 current_kboard
= terminal
->kboard
;
2737 term_get_fkeys (address
, terminal
->kboard
);
2739 /* Get frame size from system, or else from termcap. */
2742 get_tty_size (fileno (tty
->input
), &width
, &height
);
2743 FrameCols (tty
) = width
;
2744 FrameRows (tty
) = height
;
2747 if (FrameCols (tty
) <= 0)
2748 FrameCols (tty
) = tgetnum ("co");
2749 if (FrameRows (tty
) <= 0)
2750 FrameRows (tty
) = tgetnum ("li");
2752 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
2753 maybe_fatal (must_succeed
, NULL
, terminal
,
2754 "Screen size %dx%d is too small"
2755 "Screen size %dx%d is too small",
2756 FrameCols (tty
), FrameRows (tty
));
2758 #if 0 /* This is not used anywhere. */
2759 tty
->terminal
->min_padding_speed
= tgetnum ("pb");
2762 TabWidth (tty
) = tgetnum ("tw");
2765 /* These capabilities commonly use ^J.
2766 I don't know why, but sending them on VMS does not work;
2767 it causes following spaces to be lost, sometimes.
2768 For now, the simplest fix is to avoid using these capabilities ever. */
2769 if (Down (tty
) && Down (tty
)[0] == '\n')
2774 tty
->TS_bell
= "\07";
2776 if (!tty
->TS_fwd_scroll
)
2777 tty
->TS_fwd_scroll
= Down (tty
);
2779 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
2781 if (TabWidth (tty
) < 0)
2784 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2785 and newer termcap doc does not seem to say there is a default.
2786 if (!tty->Wcm->cm_tab)
2787 tty->Wcm->cm_tab = "\t";
2790 /* We don't support standout modes that use `magic cookies', so
2791 turn off any that do. */
2792 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
2794 tty
->TS_standout_mode
= 0;
2795 tty
->TS_end_standout_mode
= 0;
2797 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
2799 tty
->TS_enter_underline_mode
= 0;
2800 tty
->TS_exit_underline_mode
= 0;
2803 /* If there's no standout mode, try to use underlining instead. */
2804 if (tty
->TS_standout_mode
== 0)
2806 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
2807 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
2810 /* If no `se' string, try using a `me' string instead.
2811 If that fails, we can't use standout mode at all. */
2812 if (tty
->TS_end_standout_mode
== 0)
2814 char *s
= tgetstr ("me", address
);
2816 tty
->TS_end_standout_mode
= s
;
2818 tty
->TS_standout_mode
= 0;
2821 if (tty
->TF_teleray
)
2823 tty
->Wcm
->cm_tab
= 0;
2824 /* We can't support standout mode, because it uses magic cookies. */
2825 tty
->TS_standout_mode
= 0;
2826 /* But that means we cannot rely on ^M to go to column zero! */
2828 /* LF can't be trusted either -- can alter hpos */
2829 /* if move at column 0 thru a line with TS_standout_mode */
2833 /* Special handling for certain terminal types known to need it */
2835 if (!strcmp (terminal_type
, "supdup"))
2837 terminal
->memory_below_frame
= 1;
2838 tty
->Wcm
->cm_losewrap
= 1;
2840 if (!strncmp (terminal_type
, "c10", 3)
2841 || !strcmp (terminal_type
, "perq"))
2843 /* Supply a makeshift :wi string.
2844 This string is not valid in general since it works only
2845 for windows starting at the upper left corner;
2846 but that is all Emacs uses.
2848 This string works only if the frame is using
2849 the top of the video memory, because addressing is memory-relative.
2850 So first check the :ti string to see if that is true.
2852 It would be simpler if the :wi string could go in the termcap
2853 entry, but it can't because it is not fully valid.
2854 If it were in the termcap entry, it would confuse other programs. */
2855 if (!tty
->TS_set_window
)
2857 p
= tty
->TS_termcap_modes
;
2858 while (*p
&& strcmp (p
, "\033v "))
2861 tty
->TS_set_window
= "\033v%C %C %C %C ";
2863 /* Termcap entry often fails to have :in: flag */
2864 terminal
->must_write_spaces
= 1;
2865 /* :ti string typically fails to have \E^G! in it */
2866 /* This limits scope of insert-char to one line. */
2867 strcpy (area
, tty
->TS_termcap_modes
);
2868 strcat (area
, "\033\007!");
2869 tty
->TS_termcap_modes
= area
;
2870 area
+= strlen (area
) + 1;
2871 p
= AbsPosition (tty
);
2872 /* Change all %+ parameters to %C, to handle
2873 values above 96 correctly for the C100. */
2876 if (p
[0] == '%' && p
[1] == '+')
2882 tty
->specified_window
= FrameRows (tty
);
2884 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
2886 maybe_fatal (must_succeed
, NULL
, terminal
,
2887 "Terminal type \"%s\" is not powerful enough to run Emacs",
2889 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2890 It lacks the ability to position the cursor.\n\
2891 If that is not the actual type of terminal you have, use either the\n\
2892 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2893 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2896 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2897 It lacks the ability to position the cursor.\n\
2898 If that is not the actual type of terminal you have,\n\
2899 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2900 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2901 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2902 # else /* TERMCAP */
2903 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2904 It lacks the ability to position the cursor.\n\
2905 If that is not the actual type of terminal you have,\n\
2906 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2907 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2908 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2909 # endif /* TERMINFO */
2914 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
2915 maybe_fatal (must_succeed
, NULL
, terminal
,
2916 "Could not determine the frame size",
2917 "Could not determine the frame size");
2919 tty
->delete_in_insert_mode
2920 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
2921 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
2923 tty
->se_is_so
= (tty
->TS_standout_mode
2924 && tty
->TS_end_standout_mode
2925 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
2927 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
2929 terminal
->scroll_region_ok
2931 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
2933 terminal
->line_ins_del_ok
2934 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
2935 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
2936 || (terminal
->scroll_region_ok
2937 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
2939 terminal
->char_ins_del_ok
2940 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
2941 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
2942 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
2944 terminal
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
2946 init_baud_rate (fileno (tty
->input
));
2949 /* The HFT system on AIX doesn't optimize for scrolling, so it's
2950 really ugly at times. */
2951 terminal
->line_ins_del_ok
= 0;
2952 terminal
->char_ins_del_ok
= 0;
2955 /* Don't do this. I think termcap may still need the buffer. */
2956 /* xfree (buffer); */
2958 /* Init system terminal modes (RAW or CBREAK, etc.). */
2959 init_sys_modes (tty
);
2962 #endif /* not WINDOWSNT */
2965 /* Auxiliary error-handling function for init_tty.
2966 Free BUFFER and delete TERMINAL, then call error or fatal
2967 with str1 or str2, respectively, according to MUST_SUCCEED. */
2970 maybe_fatal (must_succeed
, buffer
, terminal
, str1
, str2
, arg1
, arg2
)
2973 struct terminal
*terminal
;
2974 char *str1
, *str2
, *arg1
, *arg2
;
2980 delete_tty (terminal
);
2983 fatal (str2
, arg1
, arg2
);
2985 error (str1
, arg1
, arg2
);
2992 fatal (str
, arg1
, arg2
)
2993 char *str
, *arg1
, *arg2
;
2995 fprintf (stderr
, "emacs: ");
2996 fprintf (stderr
, str
, arg1
, arg2
);
2997 fprintf (stderr
, "\n");
3004 /* Delete the given tty terminal, closing all frames on it. */
3007 delete_tty (struct terminal
*terminal
)
3009 struct tty_display_info
*tty
;
3010 Lisp_Object tail
, frame
;
3013 /* Protect against recursive calls. Fdelete_frame in
3014 delete_terminal calls us back when it deletes our last frame. */
3015 if (terminal
->deleted
)
3018 if (terminal
->type
!= output_termcap
)
3021 tty
= terminal
->display_info
.tty
;
3024 FOR_EACH_FRAME (tail
, frame
)
3026 struct frame
*f
= XFRAME (frame
);
3027 if (FRAME_LIVE_P (f
) && (!FRAME_TERMCAP_P (f
) || FRAME_TTY (f
) != tty
))
3034 error ("Attempt to delete the sole terminal device with live frames");
3036 if (tty
== tty_list
)
3037 tty_list
= tty
->next
;
3040 struct tty_display_info
*p
;
3041 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
3045 /* This should not happen. */
3048 p
->next
= tty
->next
;
3052 /* reset_sys_modes needs a valid device, so this call needs to be
3053 before delete_terminal. */
3054 reset_sys_modes (tty
);
3056 delete_terminal (terminal
);
3066 delete_keyboard_wait_descriptor (fileno (tty
->input
));
3067 if (tty
->input
!= stdin
)
3068 fclose (tty
->input
);
3070 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
3071 fclose (tty
->output
);
3072 if (tty
->termscript
)
3073 fclose (tty
->termscript
);
3076 xfree (tty
->old_tty
);
3081 bzero (tty
, sizeof (struct tty_display_info
));
3087 /* Mark the pointers in the tty_display_info objects.
3088 Called by the Fgarbage_collector. */
3093 struct tty_display_info
*tty
;
3095 for (tty
= tty_list
; tty
; tty
= tty
->next
)
3098 mark_object (tty
->top_frame
);
3107 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
3108 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3109 This variable can be used by terminal emulator packages. */);
3111 system_uses_terminfo
= 1;
3113 system_uses_terminfo
= 0;
3116 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions
,
3117 doc
: /* Functions to be run after suspending a tty.
3118 The functions are run with one argument, the terminal id to be suspended.
3119 See `suspend-tty'. */);
3120 Vsuspend_tty_functions
= Qnil
;
3123 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions
,
3124 doc
: /* Functions to be run after resuming a tty.
3125 The functions are run with one argument, the terminal id that was revived.
3126 See `resume-tty'. */);
3127 Vresume_tty_functions
= Qnil
;
3129 DEFVAR_BOOL ("visible-cursor", &visible_cursor
,
3130 doc
: /* Non-nil means to make the cursor very visible.
3131 This only has an effect when running in a text terminal.
3132 What means \"very visible\" is up to your terminal. It may make the cursor
3133 bigger, or it may make it blink, or it may do nothing at all. */);
3136 defsubr (&Stty_display_color_p
);
3137 defsubr (&Stty_display_color_cells
);
3138 defsubr (&Stty_no_underline
);
3139 defsubr (&Stty_type
);
3140 defsubr (&Scontrolling_tty_p
);
3141 defsubr (&Ssuspend_tty
);
3142 defsubr (&Sresume_tty
);
3147 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
3148 (do not change this comment) */