1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 86, 87, 93, 94, 95, 98, 2000, 2001, 2002
3 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., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
31 #include <unistd.h> /* For isatty. */
34 #include <termios.h> /* For TIOCNOTTY. */
47 #include "termhooks.h"
48 #include "dispextern.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 turn_on_face
P_ ((struct frame
*, int face_id
));
84 static void turn_off_face
P_ ((struct frame
*, int face_id
));
85 static void tty_show_cursor
P_ ((struct tty_display_info
*));
86 static void tty_hide_cursor
P_ ((struct tty_display_info
*));
88 void delete_initial_display
P_ ((struct display
*));
89 void create_tty_output
P_ ((struct frame
*));
90 void delete_tty_output
P_ ((struct frame
*));
92 #define OUTPUT(tty, a) \
93 emacs_tputs ((tty), a, \
94 (int) (FRAME_LINES (XFRAME (selected_frame)) \
98 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
99 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
101 #define OUTPUT_IF(tty, a) \
104 emacs_tputs ((tty), a, \
105 (int) (FRAME_LINES (XFRAME (selected_frame)) \
110 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
112 /* Display space properties */
114 extern Lisp_Object Qspace
, QCalign_to
, QCwidth
;
116 /* Function to use to ring the bell. */
118 Lisp_Object Vring_bell_function
;
120 /* Functions to call after deleting a tty. */
121 Lisp_Object Vdelete_tty_after_functions
;
123 /* Functions to call after suspending a tty. */
124 Lisp_Object Vsuspend_tty_functions
;
126 /* Functions to call after resuming a tty. */
127 Lisp_Object Vresume_tty_functions
;
129 /* Chain of all displays currently in use. */
130 struct display
*display_list
;
132 /* The initial display device, created by initial_term_init. */
133 struct display
*initial_display
;
135 /* Chain of all tty device parameters. */
136 struct tty_display_info
*tty_list
;
138 /* Nonzero means no need to redraw the entire frame on resuming a
139 suspended Emacs. This is useful on terminals with multiple
140 pages, where one page is used for Emacs and another for all
142 int no_redraw_on_reenter
;
144 Lisp_Object Qframe_tty_name
, Qframe_tty_type
;
148 /* Meaning of bits in no_color_video. Each bit set means that the
149 corresponding attribute cannot be combined with colors. */
153 NC_STANDOUT
= 1 << 0,
154 NC_UNDERLINE
= 1 << 1,
161 NC_ALT_CHARSET
= 1 << 8
166 /* The largest frame width in any call to calculate_costs. */
170 /* The largest frame height in any call to calculate_costs. */
174 /* Non-zero if we have dropped our controlling tty and therefore
175 should not open a frame on stdout. */
176 static int no_controlling_tty
;
178 /* Provided for lisp packages. */
180 static int system_uses_terminfo
;
184 extern char *tgetstr ();
188 /* We aren't X windows, but we aren't termcap either. This makes me
189 uncertain as to what value to use for frame.output_method. For
190 this file, we'll define FRAME_TERMCAP_P to be zero so that our
191 output hooks get called instead of the termcap functions. Probably
192 the best long-term solution is to define an output_windows_nt... */
194 #undef FRAME_TERMCAP_P
195 #define FRAME_TERMCAP_P(_f_) 0
196 #endif /* WINDOWSNT */
199 ring_bell (struct frame
*f
)
201 if (!NILP (Vring_bell_function
))
203 Lisp_Object function
;
205 /* Temporarily set the global variable to nil
206 so that if we get an error, it stays nil
207 and we don't call it over and over.
209 We don't specbind it, because that would carefully
210 restore the bad value if there's an error
211 and make the loop of errors happen anyway. */
213 function
= Vring_bell_function
;
214 Vring_bell_function
= Qnil
;
218 Vring_bell_function
= function
;
220 else if (FRAME_DISPLAY (f
)->ring_bell_hook
)
221 (*FRAME_DISPLAY (f
)->ring_bell_hook
) (f
);
224 /* Ring the bell on a tty. */
227 tty_ring_bell (struct frame
*f
)
229 struct tty_display_info
*tty
= FRAME_TTY (f
);
231 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
232 ? tty
->TS_visible_bell
234 fflush (tty
->output
);
237 /* Set up termcap modes for Emacs. */
240 tty_set_terminal_modes (struct display
*display
)
242 struct tty_display_info
*tty
= display
->display_info
.tty
;
246 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
247 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
248 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
253 /* Reset termcap modes before exiting Emacs. */
256 tty_reset_terminal_modes (struct display
*display
)
258 struct tty_display_info
*tty
= display
->display_info
.tty
;
262 turn_off_highlight (tty
);
263 turn_off_insert (tty
);
264 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
265 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
266 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
267 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
268 /* Output raw CR so kernel can track the cursor hpos. */
275 update_begin (struct frame
*f
)
277 if (FRAME_DISPLAY (f
)->update_begin_hook
)
278 (*FRAME_DISPLAY (f
)->update_begin_hook
) (f
);
282 update_end (struct frame
*f
)
284 if (FRAME_DISPLAY (f
)->update_end_hook
)
285 (*FRAME_DISPLAY (f
)->update_end_hook
) (f
);
288 /* Flag the end of a display update on a termcap display. */
291 tty_update_end (struct frame
*f
)
293 struct tty_display_info
*tty
= FRAME_TTY (f
);
295 if (!XWINDOW (selected_window
)->cursor_off_p
)
296 tty_show_cursor (tty
);
297 turn_off_insert (tty
);
298 background_highlight (tty
);
301 /* Specify how many text lines, from the top of the window,
302 should be affected by insert-lines and delete-lines operations.
303 This, and those operations, are used only within an update
304 that is bounded by calls to update_begin and update_end. */
307 set_terminal_window (struct frame
*f
, int size
)
309 if (FRAME_DISPLAY (f
)->set_terminal_window_hook
)
310 (*FRAME_DISPLAY (f
)->set_terminal_window_hook
) (f
, size
);
313 /* The implementation of set_terminal_window for termcap frames. */
316 tty_set_terminal_window (struct frame
*f
, int size
)
318 struct tty_display_info
*tty
= FRAME_TTY (f
);
320 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
321 if (FRAME_SCROLL_REGION_OK (f
))
322 set_scroll_region (f
, 0, tty
->specified_window
);
326 set_scroll_region (struct frame
*f
, int start
, int stop
)
329 struct tty_display_info
*tty
= FRAME_TTY (f
);
331 if (tty
->TS_set_scroll_region
)
332 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
333 else if (tty
->TS_set_scroll_region_1
)
334 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
335 FRAME_LINES (f
), start
,
336 FRAME_LINES (f
) - stop
,
339 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
348 turn_on_insert (struct tty_display_info
*tty
)
350 if (!tty
->insert_mode
)
351 OUTPUT (tty
, tty
->TS_insert_mode
);
352 tty
->insert_mode
= 1;
356 turn_off_insert (struct tty_display_info
*tty
)
358 if (tty
->insert_mode
)
359 OUTPUT (tty
, tty
->TS_end_insert_mode
);
360 tty
->insert_mode
= 0;
363 /* Handle highlighting. */
366 turn_off_highlight (struct tty_display_info
*tty
)
368 if (tty
->standout_mode
)
369 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
370 tty
->standout_mode
= 0;
374 turn_on_highlight (struct tty_display_info
*tty
)
376 if (!tty
->standout_mode
)
377 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
378 tty
->standout_mode
= 1;
382 toggle_highlight (struct tty_display_info
*tty
)
384 if (tty
->standout_mode
)
385 turn_off_highlight (tty
);
387 turn_on_highlight (tty
);
391 /* Make cursor invisible. */
394 tty_hide_cursor (struct tty_display_info
*tty
)
396 if (tty
->cursor_hidden
== 0)
398 tty
->cursor_hidden
= 1;
399 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
404 /* Ensure that cursor is visible. */
407 tty_show_cursor (struct tty_display_info
*tty
)
409 if (tty
->cursor_hidden
)
411 tty
->cursor_hidden
= 0;
412 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
413 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
418 /* Set standout mode to the state it should be in for
419 empty space inside windows. What this is,
420 depends on the user option inverse-video. */
423 background_highlight (struct tty_display_info
*tty
)
426 turn_on_highlight (tty
);
428 turn_off_highlight (tty
);
431 /* Set standout mode to the mode specified for the text to be output. */
434 highlight_if_desired (struct tty_display_info
*tty
)
437 turn_on_highlight (tty
);
439 turn_off_highlight (tty
);
443 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
444 frame-relative coordinates. */
447 cursor_to (struct frame
*f
, int vpos
, int hpos
)
449 if (FRAME_DISPLAY (f
)->cursor_to_hook
)
450 (*FRAME_DISPLAY (f
)->cursor_to_hook
) (f
, vpos
, hpos
);
454 tty_cursor_to (struct frame
*f
, int vpos
, int hpos
)
456 struct tty_display_info
*tty
= FRAME_TTY (f
);
458 /* Detect the case where we are called from reset_sys_modes
459 and the costs have never been calculated. Do nothing. */
460 if (! tty
->costs_set
)
463 if (curY (tty
) == vpos
464 && curX (tty
) == hpos
)
466 if (!tty
->TF_standout_motion
)
467 background_highlight (tty
);
468 if (!tty
->TF_insmode_motion
)
469 turn_off_insert (tty
);
470 cmgoto (tty
, vpos
, hpos
);
473 /* Similar but don't take any account of the wasted characters. */
476 raw_cursor_to (struct frame
*f
, int row
, int col
)
478 if (FRAME_DISPLAY (f
)->raw_cursor_to_hook
)
479 (*FRAME_DISPLAY (f
)->raw_cursor_to_hook
) (f
, row
, col
);
483 tty_raw_cursor_to (struct frame
*f
, int row
, int col
)
485 struct tty_display_info
*tty
= FRAME_TTY (f
);
487 if (curY (tty
) == row
488 && curX (tty
) == col
)
490 if (!tty
->TF_standout_motion
)
491 background_highlight (tty
);
492 if (!tty
->TF_insmode_motion
)
493 turn_off_insert (tty
);
494 cmgoto (tty
, row
, col
);
497 /* Erase operations */
499 /* Clear from cursor to end of frame. */
501 clear_to_end (struct frame
*f
)
503 if (FRAME_DISPLAY (f
)->clear_to_end_hook
)
504 (*FRAME_DISPLAY (f
)->clear_to_end_hook
) (f
);
507 /* Clear from cursor to end of frame on a termcap device. */
510 tty_clear_to_end (struct frame
*f
)
513 struct tty_display_info
*tty
= FRAME_TTY (f
);
515 if (tty
->TS_clr_to_bottom
)
517 background_highlight (tty
);
518 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
522 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
525 clear_end_of_line (f
, FRAME_COLS (f
));
530 /* Clear entire frame */
533 clear_frame (struct frame
*f
)
535 if (FRAME_DISPLAY (f
)->clear_frame_hook
)
536 (*FRAME_DISPLAY (f
)->clear_frame_hook
) (f
);
539 /* Clear an entire termcap frame. */
542 tty_clear_frame (struct frame
*f
)
544 struct tty_display_info
*tty
= FRAME_TTY (f
);
546 if (tty
->TS_clr_frame
)
548 background_highlight (tty
);
549 OUTPUT (tty
, tty
->TS_clr_frame
);
559 /* Clear from cursor to end of line.
560 Assume that the line is already clear starting at column first_unused_hpos.
562 Note that the cursor may be moved, on terminals lacking a `ce' string. */
565 clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
567 if (FRAME_DISPLAY (f
)->clear_end_of_line_hook
)
568 (*FRAME_DISPLAY (f
)->clear_end_of_line_hook
) (f
, first_unused_hpos
);
571 /* An implementation of clear_end_of_line for termcap frames.
573 Note that the cursor may be moved, on terminals lacking a `ce' string. */
576 tty_clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
579 struct tty_display_info
*tty
= FRAME_TTY (f
);
581 /* Detect the case where we are called from reset_sys_modes
582 and the costs have never been calculated. Do nothing. */
583 if (! tty
->costs_set
)
586 if (curX (tty
) >= first_unused_hpos
)
588 background_highlight (tty
);
589 if (tty
->TS_clr_line
)
591 OUTPUT1 (tty
, tty
->TS_clr_line
);
594 { /* have to do it the hard way */
595 turn_off_insert (tty
);
597 /* Do not write in last row last col with Auto-wrap on. */
599 && curY (tty
) == FrameRows (tty
) - 1
600 && first_unused_hpos
== FrameCols (tty
))
603 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
606 fputc (' ', tty
->termscript
);
607 fputc (' ', tty
->output
);
609 cmplus (tty
, first_unused_hpos
- curX (tty
));
613 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
614 store them at DST. Do not write more than DST_LEN bytes. That may
615 require stopping before all SRC_LEN input glyphs have been
618 We store the number of glyphs actually converted in *CONSUMED. The
619 return value is the number of bytes store in DST. */
622 encode_terminal_code (src
, dst
, src_len
, dst_len
, consumed
)
626 int dst_len
, *consumed
;
628 struct glyph
*src_start
= src
, *src_end
= src
+ src_len
;
629 unsigned char *dst_start
= dst
, *dst_end
= dst
+ dst_len
;
631 unsigned char workbuf
[MAX_MULTIBYTE_LENGTH
];
632 const unsigned char *buf
;
634 register int tlen
= GLYPH_TABLE_LENGTH
;
635 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
637 struct coding_system
*coding
;
639 /* If terminal_coding does any conversion, use it, otherwise use
640 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
641 because it always return 1 if the member src_multibyte is 1. */
642 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
644 : &safe_terminal_coding
);
646 while (src
< src_end
)
648 /* We must skip glyphs to be padded for a wide character. */
649 if (! CHAR_GLYPH_PADDING_P (*src
))
651 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
653 if (g
< 0 || g
>= tlen
)
655 /* This glyph doesn't has an entry in Vglyph_table. */
656 if (! CHAR_VALID_P (src
->u
.ch
, 0))
660 coding
->src_multibyte
= 0;
664 len
= CHAR_STRING (src
->u
.ch
, workbuf
);
666 coding
->src_multibyte
= 1;
671 /* This glyph has an entry in Vglyph_table,
672 so process any alias before testing for simpleness. */
673 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
675 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
677 /* We set the multi-byte form of a character in G
678 (that should be an ASCII character) at
680 workbuf
[0] = FAST_GLYPH_CHAR (g
);
683 coding
->src_multibyte
= 0;
687 /* We have a string in Vglyph_table. */
688 len
= GLYPH_LENGTH (tbase
, g
);
689 buf
= GLYPH_STRING (tbase
, g
);
690 coding
->src_multibyte
= STRING_MULTIBYTE (tbase
[g
]);
694 result
= encode_coding (coding
, buf
, dst
, len
, dst_end
- dst
);
695 len
-= coding
->consumed
;
696 dst
+= coding
->produced
;
697 if (result
== CODING_FINISH_INSUFFICIENT_DST
698 || (result
== CODING_FINISH_INSUFFICIENT_SRC
699 && len
> dst_end
- dst
))
700 /* The remaining output buffer is too short. We must
701 break the loop here without increasing SRC so that the
702 next call of this function starts from the same glyph. */
707 /* This is the case that a code of the range 0200..0237
708 exists in buf. We must just write out such a code. */
709 buf
+= coding
->consumed
;
717 *consumed
= src
- src_start
;
718 return (dst
- dst_start
);
722 /* Output LEN glyphs starting at STRING at the nominal cursor position.
723 Advance the nominal cursor over the text. */
726 write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
728 if (FRAME_DISPLAY (f
)->write_glyphs_hook
)
729 (*FRAME_DISPLAY (f
)->write_glyphs_hook
) (f
, string
, len
);
732 /* An implementation of write_glyphs for termcap frames. */
735 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
737 int produced
, consumed
;
738 unsigned char conversion_buffer
[1024];
739 int conversion_buffer_size
= sizeof conversion_buffer
;
741 struct tty_display_info
*tty
= FRAME_TTY (f
);
743 turn_off_insert (tty
);
744 tty_hide_cursor (tty
);
746 /* Don't dare write in last column of bottom line, if Auto-Wrap,
747 since that would scroll the whole frame on some terminals. */
750 && curY (tty
) + 1 == FRAME_LINES (f
)
751 && (curX (tty
) + len
) == FRAME_COLS (f
))
758 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
760 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
764 /* Identify a run of glyphs with the same face. */
765 int face_id
= string
->face_id
;
768 for (n
= 1; n
< len
; ++n
)
769 if (string
[n
].face_id
!= face_id
)
772 /* Turn appearance modes of the face of the run on. */
773 highlight_if_desired (tty
);
774 turn_on_face (f
, face_id
);
778 /* We use a fixed size (1024 bytes) of conversion buffer.
779 Usually it is sufficient, but if not, we just repeat the
781 produced
= encode_terminal_code (string
, conversion_buffer
,
782 n
, conversion_buffer_size
,
786 fwrite (conversion_buffer
, 1, produced
,
788 if (ferror (tty
->output
))
789 clearerr (tty
->output
);
791 fwrite (conversion_buffer
, 1, produced
,
799 /* Turn appearance modes off. */
800 turn_off_face (f
, face_id
);
801 turn_off_highlight (tty
);
804 /* We may have to output some codes to terminate the writing. */
805 if (CODING_REQUIRE_FLUSHING (&terminal_coding
))
807 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
808 encode_coding (&terminal_coding
, "", conversion_buffer
,
809 0, conversion_buffer_size
);
810 if (terminal_coding
.produced
> 0)
812 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
814 if (ferror (tty
->output
))
815 clearerr (tty
->output
);
817 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
825 /* Insert LEN glyphs from START at the nominal cursor position.
827 If start is zero, insert blanks instead of a string at start */
830 insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
835 if (FRAME_DISPLAY (f
)->insert_glyphs_hook
)
836 (*FRAME_DISPLAY (f
)->insert_glyphs_hook
) (f
, start
, len
);
839 /* An implementation of insert_glyphs for termcap frames. */
842 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
845 struct glyph
*glyph
= NULL
;
847 struct tty_display_info
*tty
= FRAME_TTY (f
);
849 if (tty
->TS_ins_multi_chars
)
851 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
855 write_glyphs (f
, start
, len
);
859 turn_on_insert (tty
);
861 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
862 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
865 int produced
, consumed
;
866 unsigned char conversion_buffer
[1024];
867 int conversion_buffer_size
= sizeof conversion_buffer
;
869 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
872 conversion_buffer
[0] = SPACEGLYPH
;
877 highlight_if_desired (tty
);
878 turn_on_face (f
, start
->face_id
);
881 /* We must open sufficient space for a character which
882 occupies more than one column. */
883 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
885 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
890 /* This is the last glyph. */
891 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
893 /* The size of conversion buffer (1024 bytes) is surely
894 sufficient for just one glyph. */
895 produced
= encode_terminal_code (glyph
, conversion_buffer
, 1,
896 conversion_buffer_size
, &consumed
);
901 fwrite (conversion_buffer
, 1, produced
,
903 if (ferror (tty
->output
))
904 clearerr (tty
->output
);
906 fwrite (conversion_buffer
, 1, produced
,
910 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
913 turn_off_face (f
, glyph
->face_id
);
914 turn_off_highlight (tty
);
921 /* Delete N glyphs at the nominal cursor position. */
924 delete_glyphs (struct frame
*f
, int n
)
926 if (FRAME_DISPLAY (f
)->delete_glyphs_hook
)
927 (*FRAME_DISPLAY (f
)->delete_glyphs_hook
) (f
, n
);
930 /* An implementation of delete_glyphs for termcap frames. */
933 tty_delete_glyphs (struct frame
*f
, int n
)
938 struct tty_display_info
*tty
= FRAME_TTY (f
);
940 if (tty
->delete_in_insert_mode
)
942 turn_on_insert (tty
);
946 turn_off_insert (tty
);
947 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
950 if (tty
->TS_del_multi_chars
)
952 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
957 for (i
= 0; i
< n
; i
++)
958 OUTPUT1 (tty
, tty
->TS_del_char
);
959 if (!tty
->delete_in_insert_mode
)
960 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
963 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
966 ins_del_lines (struct frame
*f
, int vpos
, int n
)
968 if (FRAME_DISPLAY (f
)->ins_del_lines_hook
)
969 (*FRAME_DISPLAY (f
)->ins_del_lines_hook
) (f
, vpos
, n
);
972 /* An implementation of ins_del_lines for termcap frames. */
975 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
977 struct tty_display_info
*tty
= FRAME_TTY (f
);
978 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
979 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
980 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
982 register int i
= n
> 0 ? n
: -n
;
985 /* If the lines below the insertion are being pushed
986 into the end of the window, this is the same as clearing;
987 and we know the lines are already clear, since the matching
988 deletion has already been done. So can ignore this. */
989 /* If the lines below the deletion are blank lines coming
990 out of the end of the window, don't bother,
991 as there will be a matching inslines later that will flush them. */
992 if (FRAME_SCROLL_REGION_OK (f
)
993 && vpos
+ i
>= tty
->specified_window
)
995 if (!FRAME_MEMORY_BELOW_FRAME (f
)
996 && vpos
+ i
>= FRAME_LINES (f
))
1001 raw_cursor_to (f
, vpos
, 0);
1002 background_highlight (tty
);
1003 buf
= tparam (multi
, 0, 0, i
);
1009 raw_cursor_to (f
, vpos
, 0);
1010 background_highlight (tty
);
1012 OUTPUT (tty
, single
);
1013 if (tty
->TF_teleray
)
1018 set_scroll_region (f
, vpos
, tty
->specified_window
);
1020 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
1022 raw_cursor_to (f
, vpos
, 0);
1023 background_highlight (tty
);
1025 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1026 set_scroll_region (f
, 0, tty
->specified_window
);
1029 if (!FRAME_SCROLL_REGION_OK (f
)
1030 && FRAME_MEMORY_BELOW_FRAME (f
)
1033 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
1038 /* Compute cost of sending "str", in characters,
1039 not counting any line-dependent padding. */
1042 string_cost (char *str
)
1046 tputs (str
, 0, evalcost
);
1050 /* Compute cost of sending "str", in characters,
1051 counting any line-dependent padding at one line. */
1054 string_cost_one_line (char *str
)
1058 tputs (str
, 1, evalcost
);
1062 /* Compute per line amount of line-dependent padding,
1063 in tenths of characters. */
1066 per_line_cost (char *str
)
1070 tputs (str
, 0, evalcost
);
1073 tputs (str
, 10, evalcost
);
1078 /* char_ins_del_cost[n] is cost of inserting N characters.
1079 char_ins_del_cost[-n] is cost of deleting N characters.
1080 The length of this vector is based on max_frame_cols. */
1082 int *char_ins_del_vector
;
1084 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1089 calculate_ins_del_char_costs (struct frame
*f
)
1091 struct tty_display_info
*tty
= FRAME_TTY (f
);
1092 int ins_startup_cost
, del_startup_cost
;
1093 int ins_cost_per_char
, del_cost_per_char
;
1097 if (tty
->TS_ins_multi_chars
)
1099 ins_cost_per_char
= 0;
1100 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1102 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1103 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1105 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1106 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1107 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1108 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1112 ins_startup_cost
= 9999;
1113 ins_cost_per_char
= 0;
1116 if (tty
->TS_del_multi_chars
)
1118 del_cost_per_char
= 0;
1119 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1121 else if (tty
->TS_del_char
)
1123 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1124 + string_cost (tty
->TS_end_delete_mode
));
1125 if (tty
->delete_in_insert_mode
)
1126 del_startup_cost
/= 2;
1127 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1131 del_startup_cost
= 9999;
1132 del_cost_per_char
= 0;
1135 /* Delete costs are at negative offsets */
1136 p
= &char_ins_del_cost (f
)[0];
1137 for (i
= FRAME_COLS (f
); --i
>= 0;)
1138 *--p
= (del_startup_cost
+= del_cost_per_char
);
1140 /* Doing nothing is free */
1141 p
= &char_ins_del_cost (f
)[0];
1144 /* Insert costs are at positive offsets */
1145 for (i
= FRAME_COLS (f
); --i
>= 0;)
1146 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1150 calculate_costs (struct frame
*frame
)
1152 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1154 if (FRAME_TERMCAP_P (frame
))
1156 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1157 register char *f
= (tty
->TS_set_scroll_region
1158 ? tty
->TS_set_scroll_region
1159 : tty
->TS_set_scroll_region_1
);
1161 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1165 /* These variables are only used for terminal stuff. They are
1166 allocated once for the terminal frame of X-windows emacs, but not
1169 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1170 X turns off char_ins_del_ok. */
1172 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1173 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1175 if (char_ins_del_vector
!= 0)
1177 = (int *) xrealloc (char_ins_del_vector
,
1179 + 2 * max_frame_cols
* sizeof (int)));
1182 = (int *) xmalloc (sizeof (int)
1183 + 2 * max_frame_cols
* sizeof (int));
1185 bzero (char_ins_del_vector
, (sizeof (int)
1186 + 2 * max_frame_cols
* sizeof (int)));
1189 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1190 do_line_insertion_deletion_costs (frame
,
1191 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1192 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1195 do_line_insertion_deletion_costs (frame
,
1196 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1197 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1200 calculate_ins_del_char_costs (frame
);
1202 /* Don't use TS_repeat if its padding is worse than sending the chars */
1203 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1204 tty
->RPov
= string_cost (tty
->TS_repeat
);
1206 tty
->RPov
= FRAME_COLS (frame
) * 2;
1208 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1216 /* Termcap capability names that correspond directly to X keysyms.
1217 Some of these (marked "terminfo") aren't supplied by old-style
1218 (Berkeley) termcap entries. They're listed in X keysym order;
1219 except we put the keypad keys first, so that if they clash with
1220 other keys (as on the IBM PC keyboard) they get overridden.
1223 static struct fkey_table keys
[] =
1225 {"kh", "home"}, /* termcap */
1226 {"kl", "left"}, /* termcap */
1227 {"ku", "up"}, /* termcap */
1228 {"kr", "right"}, /* termcap */
1229 {"kd", "down"}, /* termcap */
1230 {"%8", "prior"}, /* terminfo */
1231 {"%5", "next"}, /* terminfo */
1232 {"@7", "end"}, /* terminfo */
1233 {"@1", "begin"}, /* terminfo */
1234 {"*6", "select"}, /* terminfo */
1235 {"%9", "print"}, /* terminfo */
1236 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1238 * "insert" --- see below
1240 {"&8", "undo"}, /* terminfo */
1241 {"%0", "redo"}, /* terminfo */
1242 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1243 {"@0", "find"}, /* terminfo */
1244 {"@2", "cancel"}, /* terminfo */
1245 {"%1", "help"}, /* terminfo */
1247 * "break" goes here, but can't be reliably intercepted with termcap
1249 {"&4", "reset"}, /* terminfo --- actually `restart' */
1251 * "system" and "user" --- no termcaps
1253 {"kE", "clearline"}, /* terminfo */
1254 {"kA", "insertline"}, /* terminfo */
1255 {"kL", "deleteline"}, /* terminfo */
1256 {"kI", "insertchar"}, /* terminfo */
1257 {"kD", "deletechar"}, /* terminfo */
1258 {"kB", "backtab"}, /* terminfo */
1260 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1262 {"@8", "kp-enter"}, /* terminfo */
1264 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1265 * "kp-multiply", "kp-add", "kp-separator",
1266 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1267 * --- no termcaps for any of these.
1269 {"K4", "kp-1"}, /* terminfo */
1271 * "kp-2" --- no termcap
1273 {"K5", "kp-3"}, /* terminfo */
1275 * "kp-4" --- no termcap
1277 {"K2", "kp-5"}, /* terminfo */
1279 * "kp-6" --- no termcap
1281 {"K1", "kp-7"}, /* terminfo */
1283 * "kp-8" --- no termcap
1285 {"K3", "kp-9"}, /* terminfo */
1287 * "kp-equal" --- no termcap
1300 static char **term_get_fkeys_arg
;
1301 static Lisp_Object
term_get_fkeys_1 ();
1303 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1304 This function scans the termcap function key sequence entries, and
1305 adds entries to Vfunction_key_map for each function key it finds. */
1308 term_get_fkeys (address
)
1311 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1312 errors during the call. The only errors should be from Fdefine_key
1313 when given a key sequence containing an invalid prefix key. If the
1314 termcap defines function keys which use a prefix that is already bound
1315 to a command by the default bindings, we should silently ignore that
1316 function key specification, rather than giving the user an error and
1317 refusing to run at all on such a terminal. */
1319 extern Lisp_Object
Fidentity ();
1320 term_get_fkeys_arg
= address
;
1321 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1329 char **address
= term_get_fkeys_arg
;
1331 /* This can happen if CANNOT_DUMP or with strange options. */
1333 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1335 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1337 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1339 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1340 Fmake_vector (make_number (1),
1341 intern (keys
[i
].name
)));
1344 /* The uses of the "k0" capability are inconsistent; sometimes it
1345 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1346 We will attempt to politely accommodate both systems by testing for
1347 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1350 char *k_semi
= tgetstr ("k;", address
);
1351 char *k0
= tgetstr ("k0", address
);
1352 char *k0_name
= "f10";
1357 /* Define f0 first, so that f10 takes precedence in case the
1358 key sequences happens to be the same. */
1359 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1360 Fmake_vector (make_number (1), intern ("f0")));
1361 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1362 Fmake_vector (make_number (1), intern ("f10")));
1365 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1366 Fmake_vector (make_number (1), intern (k0_name
)));
1369 /* Set up cookies for numbered function keys above f10. */
1371 char fcap
[3], fkey
[4];
1373 fcap
[0] = 'F'; fcap
[2] = '\0';
1374 for (i
= 11; i
< 64; i
++)
1377 fcap
[1] = '1' + i
- 11;
1379 fcap
[1] = 'A' + i
- 20;
1381 fcap
[1] = 'a' + i
- 46;
1384 char *sequence
= tgetstr (fcap
, address
);
1387 sprintf (fkey
, "f%d", i
);
1388 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1389 Fmake_vector (make_number (1),
1397 * Various mappings to try and get a better fit.
1400 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1401 if (!tgetstr (cap1, address)) \
1403 char *sequence = tgetstr (cap2, address); \
1405 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1406 Fmake_vector (make_number (1), \
1410 /* if there's no key_next keycap, map key_npage to `next' keysym */
1411 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1412 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1413 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1414 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1415 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1416 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1417 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1419 /* IBM has their own non-standard dialect of terminfo.
1420 If the standard name isn't found, try the IBM name. */
1421 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1422 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1423 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1424 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1425 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1426 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1427 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1428 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1429 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1430 #undef CONDITIONAL_REASSIGN
1437 /***********************************************************************
1438 Character Display Information
1439 ***********************************************************************/
1441 static void append_glyph
P_ ((struct it
*));
1442 static void produce_stretch_glyph
P_ ((struct it
*));
1445 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1446 terminal frames if IT->glyph_row != NULL. IT->c is the character
1447 for which to produce glyphs; IT->face_id contains the character's
1448 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1455 struct glyph
*glyph
, *end
;
1458 xassert (it
->glyph_row
);
1459 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1460 + it
->glyph_row
->used
[it
->area
]);
1461 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1464 i
< it
->pixel_width
&& glyph
< end
;
1467 glyph
->type
= CHAR_GLYPH
;
1468 glyph
->pixel_width
= 1;
1469 glyph
->u
.ch
= it
->c
;
1470 glyph
->face_id
= it
->face_id
;
1471 glyph
->padding_p
= i
> 0;
1472 glyph
->charpos
= CHARPOS (it
->position
);
1473 glyph
->object
= it
->object
;
1475 ++it
->glyph_row
->used
[it
->area
];
1481 /* Produce glyphs for the display element described by IT. *IT
1482 specifies what we want to produce a glyph for (character, image, ...),
1483 and where in the glyph matrix we currently are (glyph row and hpos).
1484 produce_glyphs fills in output fields of *IT with information such as the
1485 pixel width and height of a character, and maybe output actual glyphs at
1486 the same time if IT->glyph_row is non-null. See the explanation of
1487 struct display_iterator in dispextern.h for an overview.
1489 produce_glyphs also stores the result of glyph width, ascent
1490 etc. computations in *IT.
1492 IT->glyph_row may be null, in which case produce_glyphs does not
1493 actually fill in the glyphs. This is used in the move_* functions
1494 in xdisp.c for text width and height computations.
1496 Callers usually don't call produce_glyphs directly;
1497 instead they use the macro PRODUCE_GLYPHS. */
1503 /* If a hook is installed, let it do the work. */
1504 xassert (it
->what
== IT_CHARACTER
1505 || it
->what
== IT_COMPOSITION
1506 || it
->what
== IT_STRETCH
);
1508 if (it
->what
== IT_STRETCH
)
1510 produce_stretch_glyph (it
);
1514 /* Nothing but characters are supported on terminal frames. For a
1515 composition sequence, it->c is the first character of the
1517 xassert (it
->what
== IT_CHARACTER
1518 || it
->what
== IT_COMPOSITION
);
1520 if (it
->c
>= 040 && it
->c
< 0177)
1522 it
->pixel_width
= it
->nglyphs
= 1;
1526 else if (it
->c
== '\n')
1527 it
->pixel_width
= it
->nglyphs
= 0;
1528 else if (it
->c
== '\t')
1530 int absolute_x
= (it
->current_x
1531 + it
->continuation_lines_width
);
1533 = (((1 + absolute_x
+ it
->tab_width
- 1)
1538 /* If part of the TAB has been displayed on the previous line
1539 which is continued now, continuation_lines_width will have
1540 been incremented already by the part that fitted on the
1541 continued line. So, we will get the right number of spaces
1543 nspaces
= next_tab_x
- absolute_x
;
1550 it
->pixel_width
= it
->len
= 1;
1558 it
->pixel_width
= nspaces
;
1559 it
->nglyphs
= nspaces
;
1561 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1563 /* Coming here means that it->c is from display table, thus we
1564 must send the code as is to the terminal. Although there's
1565 no way to know how many columns it occupies on a screen, it
1566 is a good assumption that a single byte code has 1-column
1568 it
->pixel_width
= it
->nglyphs
= 1;
1574 /* A multi-byte character. The display width is fixed for all
1575 characters of the set. Some of the glyphs may have to be
1576 ignored because they are already displayed in a continued
1578 int charset
= CHAR_CHARSET (it
->c
);
1580 it
->pixel_width
= CHARSET_WIDTH (charset
);
1581 it
->nglyphs
= it
->pixel_width
;
1588 /* Advance current_x by the pixel width as a convenience for
1590 if (it
->area
== TEXT_AREA
)
1591 it
->current_x
+= it
->pixel_width
;
1592 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1593 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1597 /* Produce a stretch glyph for iterator IT. IT->object is the value
1598 of the glyph property displayed. The value must be a list
1599 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1602 1. `:width WIDTH' specifies that the space should be WIDTH *
1603 canonical char width wide. WIDTH may be an integer or floating
1606 2. `:align-to HPOS' specifies that the space should be wide enough
1607 to reach HPOS, a value in canonical character units. */
1610 produce_stretch_glyph (it
)
1613 /* (space :width WIDTH ...) */
1614 Lisp_Object prop
, plist
;
1615 int width
= 0, align_to
= -1;
1616 int zero_width_ok_p
= 0;
1619 /* List should start with `space'. */
1620 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1621 plist
= XCDR (it
->object
);
1623 /* Compute the width of the stretch. */
1624 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1625 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1627 /* Absolute width `:width WIDTH' specified and valid. */
1628 zero_width_ok_p
= 1;
1629 width
= (int)(tem
+ 0.5);
1631 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1632 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1634 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1635 align_to
= (align_to
< 0
1637 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1638 else if (align_to
< 0)
1639 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1640 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1641 zero_width_ok_p
= 1;
1644 /* Nothing specified -> width defaults to canonical char width. */
1645 width
= FRAME_COLUMN_WIDTH (it
->f
);
1647 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1650 if (width
> 0 && it
->glyph_row
)
1652 Lisp_Object o_object
= it
->object
;
1653 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1657 if (!STRINGP (object
))
1658 object
= it
->w
->buffer
;
1659 it
->object
= object
;
1661 it
->pixel_width
= it
->len
= 1;
1664 it
->object
= o_object
;
1667 it
->pixel_width
= width
;
1668 it
->nglyphs
= width
;
1672 /* Get information about special display element WHAT in an
1673 environment described by IT. WHAT is one of IT_TRUNCATION or
1674 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1675 non-null glyph_row member. This function ensures that fields like
1676 face_id, c, len of IT are left untouched. */
1679 produce_special_glyphs (it
, what
)
1681 enum display_element_type what
;
1687 temp_it
.what
= IT_CHARACTER
;
1689 temp_it
.object
= make_number (0);
1690 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1692 if (what
== IT_CONTINUATION
)
1694 /* Continuation glyph. */
1696 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1697 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1699 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it
->dp
)));
1700 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1705 produce_glyphs (&temp_it
);
1706 it
->pixel_width
= temp_it
.pixel_width
;
1707 it
->nglyphs
= temp_it
.pixel_width
;
1709 else if (what
== IT_TRUNCATION
)
1711 /* Truncation glyph. */
1713 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1714 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1716 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it
->dp
)));
1717 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1722 produce_glyphs (&temp_it
);
1723 it
->pixel_width
= temp_it
.pixel_width
;
1724 it
->nglyphs
= temp_it
.pixel_width
;
1732 /***********************************************************************
1734 ***********************************************************************/
1736 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1737 one of the enumerators from enum no_color_bit, or a bit set built
1738 from them. Some display attributes may not be used together with
1739 color; the termcap capability `NC' specifies which ones. */
1741 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1742 (tty->TN_max_colors > 0 \
1743 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1746 /* Turn appearances of face FACE_ID on tty frame F on. */
1749 turn_on_face (f
, face_id
)
1753 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1754 long fg
= face
->foreground
;
1755 long bg
= face
->background
;
1756 struct tty_display_info
*tty
= FRAME_TTY (f
);
1758 /* Do this first because TS_end_standout_mode may be the same
1759 as TS_exit_attribute_mode, which turns all appearances off. */
1760 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1762 if (tty
->TN_max_colors
> 0)
1764 if (fg
>= 0 && bg
>= 0)
1766 /* If the terminal supports colors, we can set them
1767 below without using reverse video. The face's fg
1768 and bg colors are set as they should appear on
1769 the screen, i.e. they take the inverse-video'ness
1770 of the face already into account. */
1772 else if (inverse_video
)
1774 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1775 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1776 toggle_highlight (tty
);
1780 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1781 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1782 toggle_highlight (tty
);
1787 /* If we can't display colors, use reverse video
1788 if the face specifies that. */
1791 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1792 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1793 toggle_highlight (tty
);
1797 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1798 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1799 toggle_highlight (tty
);
1804 if (face
->tty_bold_p
)
1806 if (MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1807 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1809 else if (face
->tty_dim_p
)
1810 if (MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1811 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1813 /* Alternate charset and blinking not yet used. */
1814 if (face
->tty_alt_charset_p
1815 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1816 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1818 if (face
->tty_blinking_p
1819 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1820 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1822 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1823 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1825 if (tty
->TN_max_colors
> 0)
1829 if (fg
>= 0 && tty
->TS_set_foreground
)
1831 p
= tparam (tty
->TS_set_foreground
, NULL
, 0, (int) fg
);
1836 if (bg
>= 0 && tty
->TS_set_background
)
1838 p
= tparam (tty
->TS_set_background
, NULL
, 0, (int) bg
);
1846 /* Turn off appearances of face FACE_ID on tty frame F. */
1849 turn_off_face (f
, face_id
)
1853 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1854 struct tty_display_info
*tty
= FRAME_TTY (f
);
1856 xassert (face
!= NULL
);
1858 if (tty
->TS_exit_attribute_mode
)
1860 /* Capability "me" will turn off appearance modes double-bright,
1861 half-bright, reverse-video, standout, underline. It may or
1862 may not turn off alt-char-mode. */
1863 if (face
->tty_bold_p
1865 || face
->tty_reverse_p
1866 || face
->tty_alt_charset_p
1867 || face
->tty_blinking_p
1868 || face
->tty_underline_p
)
1870 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
1871 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
1872 tty
->standout_mode
= 0;
1875 if (face
->tty_alt_charset_p
)
1876 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1880 /* If we don't have "me" we can only have those appearances
1881 that have exit sequences defined. */
1882 if (face
->tty_alt_charset_p
)
1883 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1885 if (face
->tty_underline_p
)
1886 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
1889 /* Switch back to default colors. */
1890 if (tty
->TN_max_colors
> 0
1891 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
1892 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
1893 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
1894 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
1895 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
1899 /* Return non-zero if the terminal on frame F supports all of the
1900 capabilities in CAPS simultaneously, with foreground and background
1901 colors FG and BG. */
1904 tty_capable_p (tty
, caps
, fg
, bg
)
1905 struct tty_display_info
*tty
;
1907 unsigned long fg
, bg
;
1909 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
1910 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
1913 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
1914 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
1915 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
1916 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
1917 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
1918 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
1924 /* Return the tty display object specified by DISPLAY. DISPLAY may be
1925 a frame, a string, or nil for the display device of the current
1928 static struct display
*
1929 get_tty_display (Lisp_Object display
)
1934 display
= selected_frame
;
1936 if (! FRAMEP (display
) && ! STRINGP (display
))
1939 /* The initial frame does not support colors. */
1940 if (FRAMEP (display
) && FRAME_INITIAL_P (XFRAME (display
)))
1943 if (FRAMEP (display
))
1945 if (! FRAME_TERMCAP_P (XFRAME (display
)))
1946 #if 0 /* XXX We need a predicate as the first argument; find one. */
1947 wrong_type_argument ("Not a termcap frame", display
);
1948 #else /* Until we fix the wrong_type_argument call above, simply throw
1950 error ("DISPLAY is not a termcap frame");
1953 d
= FRAME_DISPLAY (XFRAME (display
));
1955 else if (STRINGP (display
))
1957 char *name
= (char *) alloca (SBYTES (display
) + 1);
1958 strncpy (name
, SDATA (display
), SBYTES (display
));
1959 name
[SBYTES (display
)] = 0;
1961 d
= get_named_tty_display (name
);
1964 error ("There is no tty display on %s", name
);
1971 /* Return non-zero if the terminal is capable to display colors. */
1973 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
1975 doc
: /* Return non-nil if TTY can display colors on DISPLAY. */)
1977 Lisp_Object display
;
1979 struct display
*d
= get_tty_display (display
);
1983 return d
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
1986 /* Return the number of supported colors. */
1987 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
1988 Stty_display_color_cells
, 0, 1, 0,
1989 doc
: /* Return the number of colors supported by TTY on DISPLAY. */)
1991 Lisp_Object display
;
1993 struct display
*d
= get_tty_display (display
);
1997 return make_number (d
->display_info
.tty
->TN_max_colors
);
2002 /* Save or restore the default color-related capabilities of this
2005 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
2008 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
2009 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
2013 if (default_orig_pair
)
2014 xfree (default_orig_pair
);
2015 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
2017 if (default_set_foreground
)
2018 xfree (default_set_foreground
);
2019 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
2022 if (default_set_background
)
2023 xfree (default_set_background
);
2024 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
2027 default_max_colors
= tty
->TN_max_colors
;
2028 default_max_pairs
= tty
->TN_max_pairs
;
2029 default_no_color_video
= tty
->TN_no_color_video
;
2033 tty
->TS_orig_pair
= default_orig_pair
;
2034 tty
->TS_set_foreground
= default_set_foreground
;
2035 tty
->TS_set_background
= default_set_background
;
2036 tty
->TN_max_colors
= default_max_colors
;
2037 tty
->TN_max_pairs
= default_max_pairs
;
2038 tty
->TN_no_color_video
= default_no_color_video
;
2042 /* Setup one of the standard tty color schemes according to MODE.
2043 MODE's value is generally the number of colors which we want to
2044 support; zero means set up for the default capabilities, the ones
2045 we saw at term_init time; -1 means turn off color support. */
2047 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2049 /* Canonicalize all negative values of MODE. */
2055 case -1: /* no colors at all */
2056 tty
->TN_max_colors
= 0;
2057 tty
->TN_max_pairs
= 0;
2058 tty
->TN_no_color_video
= 0;
2059 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2061 case 0: /* default colors, if any */
2063 tty_default_color_capabilities (tty
, 0);
2065 case 8: /* 8 standard ANSI colors */
2066 tty
->TS_orig_pair
= "\033[0m";
2068 tty
->TS_set_foreground
= "\033[3%p1%dm";
2069 tty
->TS_set_background
= "\033[4%p1%dm";
2071 tty
->TS_set_foreground
= "\033[3%dm";
2072 tty
->TS_set_background
= "\033[4%dm";
2074 tty
->TN_max_colors
= 8;
2075 tty
->TN_max_pairs
= 64;
2076 tty
->TN_no_color_video
= 0;
2082 set_tty_color_mode (f
, val
)
2086 Lisp_Object color_mode_spec
, current_mode_spec
;
2087 Lisp_Object color_mode
, current_mode
;
2089 extern Lisp_Object Qtty_color_mode
;
2090 Lisp_Object tty_color_mode_alist
;
2092 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2099 if (NILP (tty_color_mode_alist
))
2100 color_mode_spec
= Qnil
;
2102 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2104 if (CONSP (color_mode_spec
))
2105 color_mode
= XCDR (color_mode_spec
);
2110 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2112 if (CONSP (current_mode_spec
))
2113 current_mode
= XCDR (current_mode_spec
);
2115 current_mode
= Qnil
;
2116 if (INTEGERP (color_mode
))
2117 mode
= XINT (color_mode
);
2119 mode
= 0; /* meaning default */
2120 if (INTEGERP (current_mode
))
2121 old_mode
= XINT (current_mode
);
2125 if (mode
!= old_mode
)
2127 tty_setup_colors (FRAME_TTY (f
), mode
);
2128 /* This recomputes all the faces given the new color
2130 call0 (intern ("tty-set-up-initial-frame-faces"));
2135 #endif /* !WINDOWSNT */
2139 /* Return the termcap display with the given name. If NAME is null,
2140 return the display corresponding to our controlling terminal.
2142 Returns NULL if the named terminal device is not opened. */
2145 get_named_tty_display (name
)
2150 for (d
= display_list
; d
; d
= d
->next_display
) {
2151 if (d
->type
== output_termcap
2152 && ((d
->display_info
.tty
->name
== 0 && name
== 0)
2153 || (name
&& d
->display_info
.tty
->name
2154 && !strcmp (d
->display_info
.tty
->name
, name
))))
2163 DEFUN ("frame-tty-name", Fframe_tty_name
, Sframe_tty_name
, 0, 1, 0,
2164 doc
: /* Return the name of the TTY device that FRAME is displayed on. */)
2172 f
= XFRAME (selected_frame
);
2176 CHECK_LIVE_FRAME (frame
);
2180 if (f
->output_method
!= output_termcap
)
2181 wrong_type_argument (Qframe_tty_name
, frame
);
2183 if (FRAME_TTY (f
)->name
)
2184 return build_string (FRAME_TTY (f
)->name
);
2189 DEFUN ("frame-tty-type", Fframe_tty_type
, Sframe_tty_type
, 0, 1, 0,
2190 doc
: /* Return the type of the TTY device that FRAME is displayed on. */)
2198 f
= XFRAME (selected_frame
);
2202 CHECK_LIVE_FRAME (frame
);
2206 if (f
->output_method
!= output_termcap
)
2207 wrong_type_argument (Qframe_tty_type
, frame
);
2209 if (FRAME_TTY (f
)->type
)
2210 return build_string (FRAME_TTY (f
)->type
);
2216 /***********************************************************************
2218 ***********************************************************************/
2220 /* Create the bootstrap display device for the initial frame.
2221 Returns a display of type output_initial. */
2224 init_initial_display (void)
2226 if (initialized
|| display_list
|| tty_list
)
2229 initial_display
= create_display ();
2230 initial_display
->type
= output_initial
;
2232 initial_display
->delete_display_hook
= &delete_initial_display
;
2233 /* All other hooks are NULL. */
2235 return initial_display
;
2238 /* Deletes the bootstrap display device.
2239 Called through delete_display_hook. */
2242 delete_initial_display (struct display
*display
)
2244 if (display
!= initial_display
)
2247 delete_display (display
);
2248 initial_display
= NULL
;
2251 /* Drop the controlling terminal if fd is the same device. */
2253 dissociate_if_controlling_tty (int fd
)
2255 #if defined (USG) && !defined (BSD_PGRPS)
2257 EMACS_GET_TTY_PGRP (fd
, &pgid
);
2261 no_controlling_tty
= 1;
2264 #ifdef TIOCNOTTY /* Try BSD ioctls. */
2265 sigblock (sigmask (SIGTTOU
));
2266 if (ioctl (fd
, TIOCNOTTY
, 0) != -1)
2268 no_controlling_tty
= 1;
2270 sigunblock (sigmask (SIGTTOU
));
2272 /* Unknown system. */
2274 #endif /* ! TIOCNOTTY */
2278 /* Create a termcap display on the tty device with the given name and
2281 If NAME is NULL, then use the controlling tty, i.e., stdin/stdout.
2282 Otherwise NAME should be a path to the tty device file,
2285 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
2287 If MUST_SUCCEED is true, then all errors are fatal. */
2290 term_init (char *name
, char *terminal_type
, int must_succeed
)
2293 char **address
= &area
;
2294 char *buffer
= NULL
;
2295 int buffer_size
= 4096;
2298 struct tty_display_info
*tty
;
2299 struct display
*display
;
2301 static void maybe_fatal();
2304 maybe_fatal (must_succeed
, 0, 0,
2305 "Unknown terminal type",
2306 "Unknown terminal type");
2308 display
= get_named_tty_display (name
);
2311 /* XXX We would be able to support multiple emacsclients from
2312 the same terminal if display devices were Lisp objects.
2313 (Lisp code must know the difference between two separate
2314 displays on the same terminal device.) -- lorentey */
2315 if (! display
->display_info
.tty
->input
)
2316 error ("%s already has a suspended frame on it, can't open it twice", name
);
2320 display
= create_display ();
2321 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
2322 bzero (tty
, sizeof (struct tty_display_info
));
2323 tty
->next
= tty_list
;
2326 display
->type
= output_termcap
;
2327 display
->display_info
.tty
= tty
;
2328 tty
->display
= display
;
2330 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
2333 display
->rif
= 0; /* ttys don't support window-based redisplay. */
2335 display
->cursor_to_hook
= &tty_cursor_to
;
2336 display
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
2338 display
->clear_to_end_hook
= &tty_clear_to_end
;
2339 display
->clear_frame_hook
= &tty_clear_frame
;
2340 display
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
2342 display
->ins_del_lines_hook
= &tty_ins_del_lines
;
2344 display
->insert_glyphs_hook
= &tty_insert_glyphs
;
2345 display
->write_glyphs_hook
= &tty_write_glyphs
;
2346 display
->delete_glyphs_hook
= &tty_delete_glyphs
;
2348 display
->ring_bell_hook
= &tty_ring_bell
;
2350 display
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
2351 display
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
2352 display
->update_begin_hook
= 0; /* Not needed. */
2353 display
->update_end_hook
= &tty_update_end
;
2354 display
->set_terminal_window_hook
= &tty_set_terminal_window
;
2356 display
->mouse_position_hook
= 0; /* Not needed. */
2357 display
->frame_rehighlight_hook
= 0; /* Not needed. */
2358 display
->frame_raise_lower_hook
= 0; /* Not needed. */
2360 display
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
2361 display
->condemn_scroll_bars_hook
= 0; /* Not needed. */
2362 display
->redeem_scroll_bar_hook
= 0; /* Not needed. */
2363 display
->judge_scroll_bars_hook
= 0; /* Not needed. */
2365 display
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
2366 display
->frame_up_to_date_hook
= 0; /* Not needed. */
2368 display
->delete_frame_hook
= &delete_tty_output
;
2369 display
->delete_display_hook
= &delete_tty
;
2376 #ifdef O_IGNORE_CTTY
2377 /* Open the terminal device. Don't recognize it as our
2378 controlling terminal, and don't make it the controlling tty
2379 if we don't have one at the moment. */
2380 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
2382 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
2383 defined on Hurd. On other systems, we need to dissociate
2384 ourselves from the controlling tty when we want to open a
2385 frame on the same terminal. */
2387 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
2389 #endif /* O_IGNORE_CTTY */
2393 delete_tty (display
);
2394 error ("Could not open file: %s", name
);
2399 error ("Not a tty device: %s", name
);
2402 dissociate_if_controlling_tty (fd
);
2404 file
= fdopen (fd
, "w+");
2405 tty
->name
= xstrdup (name
);
2411 if (no_controlling_tty
)
2413 /* Opening a frame on stdout is unsafe if we have
2414 disconnected our controlling terminal. */
2415 error ("There is no controlling terminal any more");
2419 tty
->output
= stdout
;
2422 tty
->type
= xstrdup (terminal_type
);
2424 add_keyboard_wait_descriptor (fileno (tty
->input
));
2427 initialize_w32_display ();
2431 area
= (char *) xmalloc (2044);
2433 FrameRows (tty
) = FRAME_LINES (f
); /* XXX */
2434 FrameCols (tty
) = FRAME_COLS (f
); /* XXX */
2435 tty
->specified_window
= FRAME_LINES (f
); /* XXX */
2437 tty
->display
->delete_in_insert_mode
= 1;
2440 display
->scroll_region_ok
= 0;
2442 /* Seems to insert lines when it's not supposed to, messing
2443 up the display. In doing a trace, it didn't seem to be
2444 called much, so I don't think we're losing anything by
2446 display
->line_ins_del_ok
= 0;
2447 display
->char_ins_del_ok
= 1;
2451 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0; /* XXX */
2452 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
; /* XXX */
2453 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2456 #else /* not WINDOWSNT */
2460 buffer
= (char *) xmalloc (buffer_size
);
2462 /* On some systems, tgetent tries to access the controlling
2464 sigblock (sigmask (SIGTTOU
));
2465 status
= tgetent (buffer
, terminal_type
);
2466 sigunblock (sigmask (SIGTTOU
));
2471 maybe_fatal (must_succeed
, buffer
, display
,
2472 "Cannot open terminfo database file",
2473 "Cannot open terminfo database file");
2475 maybe_fatal (must_succeed
, buffer
, display
,
2476 "Cannot open termcap database file",
2477 "Cannot open termcap database file");
2483 maybe_fatal (must_succeed
, buffer
, display
,
2484 "Terminal type %s is not defined",
2485 "Terminal type %s is not defined.\n\
2486 If that is not the actual type of terminal you have,\n\
2487 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2488 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2489 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2492 maybe_fatal (must_succeed
, buffer
, display
,
2493 "Terminal type %s is not defined",
2494 "Terminal type %s is not defined.\n\
2495 If that is not the actual type of terminal you have,\n\
2496 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2497 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2498 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2504 if (strlen (buffer
) >= buffer_size
)
2506 buffer_size
= strlen (buffer
);
2508 area
= (char *) xmalloc (buffer_size
);
2510 tty
->TS_ins_line
= tgetstr ("al", address
);
2511 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
2512 tty
->TS_bell
= tgetstr ("bl", address
);
2513 BackTab (tty
) = tgetstr ("bt", address
);
2514 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
2515 tty
->TS_clr_line
= tgetstr ("ce", address
);
2516 tty
->TS_clr_frame
= tgetstr ("cl", address
);
2517 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
2518 AbsPosition (tty
) = tgetstr ("cm", address
);
2519 CR (tty
) = tgetstr ("cr", address
);
2520 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
2521 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
2522 RowPosition (tty
) = tgetstr ("cv", address
);
2523 tty
->TS_del_char
= tgetstr ("dc", address
);
2524 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
2525 tty
->TS_del_line
= tgetstr ("dl", address
);
2526 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
2527 tty
->TS_delete_mode
= tgetstr ("dm", address
);
2528 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
2529 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
2530 Home (tty
) = tgetstr ("ho", address
);
2531 tty
->TS_ins_char
= tgetstr ("ic", address
);
2532 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
2533 tty
->TS_insert_mode
= tgetstr ("im", address
);
2534 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
2535 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
2536 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
2537 LastLine (tty
) = tgetstr ("ll", address
);
2538 Right (tty
) = tgetstr ("nd", address
);
2539 Down (tty
) = tgetstr ("do", address
);
2541 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
2543 /* VMS puts a carriage return before each linefeed,
2544 so it is not safe to use linefeeds. */
2545 if (Down (tty
) && Down (tty
)[0] == '\n' && Down (tty
)[1] == '\0')
2548 if (tgetflag ("bs"))
2549 Left (tty
) = "\b"; /* can't possibly be longer! */
2550 else /* (Actually, "bs" is obsolete...) */
2551 Left (tty
) = tgetstr ("le", address
);
2553 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
2554 tty
->TS_pad_char
= tgetstr ("pc", address
);
2555 tty
->TS_repeat
= tgetstr ("rp", address
);
2556 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
2557 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
2558 tty
->TS_standout_mode
= tgetstr ("so", address
);
2559 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
2560 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
2561 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
2562 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
2563 Up (tty
) = tgetstr ("up", address
);
2564 tty
->TS_visible_bell
= tgetstr ("vb", address
);
2565 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
2566 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
2567 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
2568 tty
->TS_set_window
= tgetstr ("wi", address
);
2570 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
2571 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
2572 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
2573 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
2574 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
2575 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
2576 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2577 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2578 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
2580 MultiUp (tty
) = tgetstr ("UP", address
);
2581 MultiDown (tty
) = tgetstr ("DO", address
);
2582 MultiLeft (tty
) = tgetstr ("LE", address
);
2583 MultiRight (tty
) = tgetstr ("RI", address
);
2585 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2586 color because we can't switch back to the default foreground and
2588 tty
->TS_orig_pair
= tgetstr ("op", address
);
2589 if (tty
->TS_orig_pair
)
2591 tty
->TS_set_foreground
= tgetstr ("AF", address
);
2592 tty
->TS_set_background
= tgetstr ("AB", address
);
2593 if (!tty
->TS_set_foreground
)
2596 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
2597 tty
->TS_set_background
= tgetstr ("Sb", address
);
2600 tty
->TN_max_colors
= tgetnum ("Co");
2601 tty
->TN_max_pairs
= tgetnum ("pa");
2603 tty
->TN_no_color_video
= tgetnum ("NC");
2604 if (tty
->TN_no_color_video
== -1)
2605 tty
->TN_no_color_video
= 0;
2608 tty_default_color_capabilities (tty
, 1);
2610 MagicWrap (tty
) = tgetflag ("xn");
2611 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2612 the former flag imply the latter. */
2613 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
2614 display
->memory_below_frame
= tgetflag ("db");
2615 tty
->TF_hazeltine
= tgetflag ("hz");
2616 display
->must_write_spaces
= tgetflag ("in");
2617 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
2618 tty
->TF_insmode_motion
= tgetflag ("mi");
2619 tty
->TF_standout_motion
= tgetflag ("ms");
2620 tty
->TF_underscore
= tgetflag ("ul");
2621 tty
->TF_teleray
= tgetflag ("xt");
2623 term_get_fkeys (address
);
2625 /* Get frame size from system, or else from termcap. */
2628 get_tty_size (fileno (tty
->input
), &width
, &height
);
2629 FrameCols (tty
) = width
;
2630 FrameRows (tty
) = height
;
2633 if (FrameCols (tty
) <= 0)
2634 FrameCols (tty
) = tgetnum ("co");
2635 if (FrameRows (tty
) <= 0)
2636 FrameRows (tty
) = tgetnum ("li");
2638 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
2639 maybe_fatal (must_succeed
, NULL
, display
,
2640 "Screen size %dx%d is too small"
2641 "Screen size %dx%d is too small",
2642 FrameCols (tty
), FrameRows (tty
));
2644 #if 0 /* This is not used anywhere. */
2645 tty
->display
->min_padding_speed
= tgetnum ("pb");
2648 TabWidth (tty
) = tgetnum ("tw");
2651 /* These capabilities commonly use ^J.
2652 I don't know why, but sending them on VMS does not work;
2653 it causes following spaces to be lost, sometimes.
2654 For now, the simplest fix is to avoid using these capabilities ever. */
2655 if (Down (tty
) && Down (tty
)[0] == '\n')
2660 tty
->TS_bell
= "\07";
2662 if (!tty
->TS_fwd_scroll
)
2663 tty
->TS_fwd_scroll
= Down (tty
);
2665 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
2667 if (TabWidth (tty
) < 0)
2670 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2671 and newer termcap doc does not seem to say there is a default.
2672 if (!tty->Wcm->cm_tab)
2673 tty->Wcm->cm_tab = "\t";
2676 /* We don't support standout modes that use `magic cookies', so
2677 turn off any that do. */
2678 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
2680 tty
->TS_standout_mode
= 0;
2681 tty
->TS_end_standout_mode
= 0;
2683 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
2685 tty
->TS_enter_underline_mode
= 0;
2686 tty
->TS_exit_underline_mode
= 0;
2689 /* If there's no standout mode, try to use underlining instead. */
2690 if (tty
->TS_standout_mode
== 0)
2692 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
2693 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
2696 /* If no `se' string, try using a `me' string instead.
2697 If that fails, we can't use standout mode at all. */
2698 if (tty
->TS_end_standout_mode
== 0)
2700 char *s
= tgetstr ("me", address
);
2702 tty
->TS_end_standout_mode
= s
;
2704 tty
->TS_standout_mode
= 0;
2707 if (tty
->TF_teleray
)
2709 tty
->Wcm
->cm_tab
= 0;
2710 /* We can't support standout mode, because it uses magic cookies. */
2711 tty
->TS_standout_mode
= 0;
2712 /* But that means we cannot rely on ^M to go to column zero! */
2714 /* LF can't be trusted either -- can alter hpos */
2715 /* if move at column 0 thru a line with TS_standout_mode */
2719 /* Special handling for certain terminal types known to need it */
2721 if (!strcmp (terminal_type
, "supdup"))
2723 display
->memory_below_frame
= 1;
2724 tty
->Wcm
->cm_losewrap
= 1;
2726 if (!strncmp (terminal_type
, "c10", 3)
2727 || !strcmp (terminal_type
, "perq"))
2729 /* Supply a makeshift :wi string.
2730 This string is not valid in general since it works only
2731 for windows starting at the upper left corner;
2732 but that is all Emacs uses.
2734 This string works only if the frame is using
2735 the top of the video memory, because addressing is memory-relative.
2736 So first check the :ti string to see if that is true.
2738 It would be simpler if the :wi string could go in the termcap
2739 entry, but it can't because it is not fully valid.
2740 If it were in the termcap entry, it would confuse other programs. */
2741 if (!tty
->TS_set_window
)
2743 p
= tty
->TS_termcap_modes
;
2744 while (*p
&& strcmp (p
, "\033v "))
2747 tty
->TS_set_window
= "\033v%C %C %C %C ";
2749 /* Termcap entry often fails to have :in: flag */
2750 display
->must_write_spaces
= 1;
2751 /* :ti string typically fails to have \E^G! in it */
2752 /* This limits scope of insert-char to one line. */
2753 strcpy (area
, tty
->TS_termcap_modes
);
2754 strcat (area
, "\033\007!");
2755 tty
->TS_termcap_modes
= area
;
2756 area
+= strlen (area
) + 1;
2757 p
= AbsPosition (tty
);
2758 /* Change all %+ parameters to %C, to handle
2759 values above 96 correctly for the C100. */
2762 if (p
[0] == '%' && p
[1] == '+')
2768 tty
->specified_window
= FrameRows (tty
);
2770 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
2772 maybe_fatal (must_succeed
, NULL
, display
,
2773 "Terminal type \"%s\" is not powerful enough to run Emacs",
2775 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2776 It lacks the ability to position the cursor.\n\
2777 If that is not the actual type of terminal you have, use either the\n\
2778 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2779 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2782 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2783 It lacks the ability to position the cursor.\n\
2784 If that is not the actual type of terminal you have,\n\
2785 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2786 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2787 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2788 # else /* TERMCAP */
2789 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2790 It lacks the ability to position the cursor.\n\
2791 If that is not the actual type of terminal you have,\n\
2792 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2793 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2794 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2795 # endif /* TERMINFO */
2800 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
2801 maybe_fatal (must_succeed
, NULL
, display
,
2802 "Could not determine the frame size",
2803 "Could not determine the frame size");
2805 tty
->delete_in_insert_mode
2806 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
2807 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
2809 tty
->se_is_so
= (tty
->TS_standout_mode
2810 && tty
->TS_end_standout_mode
2811 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
2813 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
2815 display
->scroll_region_ok
2817 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
2819 display
->line_ins_del_ok
2820 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
2821 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
2822 || (display
->scroll_region_ok
2823 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
2825 display
->char_ins_del_ok
2826 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
2827 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
2828 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
2830 display
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
2832 init_baud_rate (fileno (tty
->input
));
2835 /* The HFT system on AIX doesn't optimize for scrolling, so it's
2836 really ugly at times. */
2837 display
->line_ins_del_ok
= 0;
2838 display
->char_ins_del_ok
= 0;
2842 tty
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
2843 init_kboard (tty
->kboard
);
2844 tty
->kboard
->next_kboard
= all_kboards
;
2845 all_kboards
= tty
->kboard
;
2846 /* Don't let the initial kboard remain current longer than necessary.
2847 That would cause problems if a file loaded on startup tries to
2848 prompt in the mini-buffer. */
2849 if (current_kboard
== initial_kboard
)
2850 current_kboard
= tty
->kboard
;
2851 tty
->kboard
->reference_count
++;
2854 /* Don't do this. I think termcap may still need the buffer. */
2855 /* xfree (buffer); */
2857 /* Init system terminal modes (RAW or CBREAK, etc.). */
2858 init_sys_modes (tty
);
2861 #endif /* not WINDOWSNT */
2864 /* Auxiliary error-handling function for term_init.
2865 Free BUFFER and delete DISPLAY, then call error or fatal
2866 with str1 or str2, respectively, according to MUST_SUCCEED. */
2869 maybe_fatal (must_succeed
, buffer
, display
, str1
, str2
, arg1
, arg2
)
2872 struct display
*display
;
2873 char *str1
, *str2
, *arg1
, *arg2
;
2879 delete_tty (display
);
2882 fatal (str2
, arg1
, arg2
);
2884 error (str1
, arg1
, arg2
);
2891 fatal (str
, arg1
, arg2
)
2892 char *str
, *arg1
, *arg2
;
2894 fprintf (stderr
, "emacs: ");
2895 fprintf (stderr
, str
, arg1
, arg2
);
2896 fprintf (stderr
, "\n");
2903 DEFUN ("delete-tty", Fdelete_tty
, Sdelete_tty
, 0, 1, 0,
2904 doc
: /* Delete all frames on the terminal named TTY, and close the device.
2905 If omitted, TTY defaults to the controlling terminal.
2907 This function runs `delete-tty-after-functions' after closing the
2908 tty. The functions are run with one arg, the frame to be deleted. */)
2917 if (SBYTES (tty
) > 0)
2919 name
= (char *) alloca (SBYTES (tty
) + 1);
2920 strncpy (name
, SDATA (tty
), SBYTES (tty
));
2921 name
[SBYTES (tty
)] = 0;
2924 d
= get_named_tty_display (name
);
2927 error ("No such terminal device: %s", name
);
2934 static int deleting_tty
= 0;
2937 /* Delete the given terminal device, closing all frames on it. */
2940 delete_tty (struct display
*display
)
2942 struct tty_display_info
*tty
;
2943 Lisp_Object tail
, frame
;
2948 /* We get a recursive call when we delete the last frame on this
2952 if (display
->type
!= output_termcap
)
2955 tty
= display
->display_info
.tty
;
2958 FOR_EACH_FRAME (tail
, frame
)
2960 struct frame
*f
= XFRAME (frame
);
2961 if (FRAME_LIVE_P (f
) && (!FRAME_TERMCAP_P (f
) || FRAME_TTY (f
) != tty
))
2968 error ("Attempt to delete the sole display with live frames");
2970 if (tty
== tty_list
)
2971 tty_list
= tty
->next
;
2974 struct tty_display_info
*p
;
2975 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
2979 /* This should not happen. */
2982 p
->next
= tty
->next
;
2988 FOR_EACH_FRAME (tail
, frame
)
2990 struct frame
*f
= XFRAME (frame
);
2991 if (FRAME_TERMCAP_P (f
) && FRAME_LIVE_P (f
) && FRAME_TTY (f
) == tty
)
2993 Fdelete_frame (frame
, Qt
);
2997 /* reset_sys_modes needs a valid display, so this call needs to be
2998 before delete_display. */
2999 reset_sys_modes (tty
);
3001 delete_display (display
);
3003 tty_name
= tty
->name
;
3009 delete_keyboard_wait_descriptor (fileno (tty
->input
));
3010 if (tty
->input
!= stdin
)
3011 fclose (tty
->input
);
3013 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
3014 fclose (tty
->output
);
3015 if (tty
->termscript
)
3016 fclose (tty
->termscript
);
3019 xfree (tty
->old_tty
);
3025 if (tty
->kboard
&& --tty
->kboard
->reference_count
> 0)
3028 delete_kboard (tty
->kboard
);
3031 bzero (tty
, sizeof (struct tty_display_info
));
3035 /* Run `delete-tty-after-functions'. */
3036 if (!NILP (Vrun_hooks
))
3038 Lisp_Object args
[2];
3039 args
[0] = intern ("delete-tty-after-functions");
3042 args
[1] = build_string (tty_name
);
3047 Frun_hook_with_args (2, args
);
3053 /* Initialize the tty-dependent part of frame F. The frame must
3054 already have its display initialized. */
3057 create_tty_output (struct frame
*f
)
3059 struct tty_output
*t
;
3061 if (! FRAME_TERMCAP_P (f
))
3064 t
= xmalloc (sizeof (struct tty_output
));
3065 bzero (t
, sizeof (struct tty_output
));
3067 t
->display_info
= FRAME_DISPLAY (f
)->display_info
.tty
;
3069 f
->output_data
.tty
= t
;
3072 /* Delete the tty-dependent part of frame F. */
3075 delete_tty_output (struct frame
*f
)
3077 if (! FRAME_TERMCAP_P (f
))
3080 xfree (f
->output_data
.tty
);
3086 /* Mark the pointers in the tty_display_info objects.
3087 Called by the Fgarbage_collector. */
3092 struct tty_display_info
*tty
;
3094 for (tty
= tty_list
; tty
; tty
= tty
->next
)
3097 mark_object (tty
->top_frame
);
3103 /* Create a new display object and add it to the display list. */
3106 create_display (void)
3108 struct display
*dev
= (struct display
*) xmalloc (sizeof (struct display
));
3110 bzero (dev
, sizeof (struct display
));
3111 dev
->next_display
= display_list
;
3117 /* Remove a display from the display list and free its memory. */
3120 delete_display (struct display
*dev
)
3122 struct display
**dp
;
3123 Lisp_Object tail
, frame
;
3125 /* Check for and close live frames that are still on this
3127 FOR_EACH_FRAME (tail
, frame
)
3129 struct frame
*f
= XFRAME (frame
);
3130 if (FRAME_LIVE_P (f
) && f
->display
== dev
)
3132 Fdelete_frame (frame
, Qt
);
3136 for (dp
= &display_list
; *dp
!= dev
; dp
= &(*dp
)->next_display
)
3139 *dp
= dev
->next_display
;
3141 bzero (dev
, sizeof (struct display
));
3147 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
3148 doc
: /* Suspend the terminal device TTY.
3149 The terminal is restored to its default state, and Emacs closes all
3150 access to the terminal device. Frames that use the device are not
3151 deleted, but input is not read from them and if they change, their
3152 display is not updated.
3154 TTY may a string (a device name), a frame, or nil for the display
3155 device of the currently selected frame.
3157 This function runs `suspend-tty-functions' after suspending the
3158 device. The functions are run with one arg, the name of the terminal
3161 `suspend-tty' does nothing if it is called on an already suspended
3164 A suspended terminal device may be resumed by calling `resume-tty' on
3169 struct display
*d
= get_tty_display (tty
);
3173 error ("Unknown tty device");
3175 f
= d
->display_info
.tty
->input
;
3179 reset_sys_modes (d
->display_info
.tty
);
3181 delete_keyboard_wait_descriptor (fileno (f
));
3184 if (f
!= d
->display_info
.tty
->output
)
3185 fclose (d
->display_info
.tty
->output
);
3187 d
->display_info
.tty
->input
= 0;
3188 d
->display_info
.tty
->output
= 0;
3190 if (FRAMEP (d
->display_info
.tty
->top_frame
))
3191 FRAME_SET_VISIBLE (XFRAME (d
->display_info
.tty
->top_frame
), 0);
3193 /* Run `suspend-tty-functions'. */
3194 if (!NILP (Vrun_hooks
))
3196 Lisp_Object args
[2];
3197 args
[0] = intern ("suspend-tty-functions");
3198 if (d
->display_info
.tty
->name
)
3200 args
[1] = build_string (d
->display_info
.tty
->name
);
3204 Frun_hook_with_args (2, args
);
3212 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
3213 doc
: /* Resume the previously suspended terminal device TTY.
3214 The terminal is opened and reinitialized. Frames that used the
3215 suspended device are revived.
3217 This function runs `resume-tty-functions' after resuming the device.
3218 The functions are run with one arg, the name of the terminal device.
3220 `resume-tty' does nothing if it is called on a device that is not
3223 TTY may a string (a device name), a frame, or nil for the display
3224 device of the currently selected frame. */)
3228 struct display
*d
= get_tty_display (tty
);
3232 error ("Unknown tty device");
3234 if (!d
->display_info
.tty
->input
)
3236 fd
= emacs_open (d
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
3238 /* XXX What if open fails? */
3240 dissociate_if_controlling_tty (fd
);
3242 d
->display_info
.tty
->output
= fdopen (fd
, "w+");
3243 d
->display_info
.tty
->input
= d
->display_info
.tty
->output
;
3245 add_keyboard_wait_descriptor (fd
);
3247 if (FRAMEP (d
->display_info
.tty
->top_frame
))
3248 FRAME_SET_VISIBLE (XFRAME (d
->display_info
.tty
->top_frame
), 1);
3250 init_sys_modes (d
->display_info
.tty
);
3252 /* Run `suspend-tty-functions'. */
3253 if (!NILP (Vrun_hooks
))
3255 Lisp_Object args
[2];
3256 args
[0] = intern ("resume-tty-functions");
3257 if (d
->display_info
.tty
->name
)
3259 args
[1] = build_string (d
->display_info
.tty
->name
);
3263 Frun_hook_with_args (2, args
);
3274 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
3275 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3276 This variable can be used by terminal emulator packages. */);
3278 system_uses_terminfo
= 1;
3280 system_uses_terminfo
= 0;
3283 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
3284 doc
: /* Non-nil means call this function to ring the bell.
3285 The function should accept no arguments. */);
3286 Vring_bell_function
= Qnil
;
3288 DEFVAR_LISP ("delete-tty-after-functions", &Vdelete_tty_after_functions
,
3289 doc
: /* Functions to be run after deleting a tty.
3290 The functions are run with one argument, the name of the tty to be deleted.
3291 See `delete-tty'. */);
3292 Vdelete_tty_after_functions
= Qnil
;
3295 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions
,
3296 doc
: /* Functions to be run after suspending a tty.
3297 The functions are run with one argument, the name of the tty to be suspended.
3298 See `suspend-tty'. */);
3299 Vsuspend_tty_functions
= Qnil
;
3302 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions
,
3303 doc
: /* Functions to be run after resuming a tty.
3304 The functions are run with one argument, the name of the tty that was revived.
3305 See `resume-tty'. */);
3306 Vresume_tty_functions
= Qnil
;
3308 Qframe_tty_name
= intern ("frame-tty-name");
3309 staticpro (&Qframe_tty_name
);
3311 Qframe_tty_type
= intern ("frame-tty-type");
3312 staticpro (&Qframe_tty_type
);
3314 defsubr (&Stty_display_color_p
);
3315 defsubr (&Stty_display_color_cells
);
3316 defsubr (&Sframe_tty_name
);
3317 defsubr (&Sframe_tty_type
);
3318 defsubr (&Sdelete_tty
);
3319 defsubr (&Ssuspend_tty
);
3320 defsubr (&Sresume_tty
);
3322 Fprovide (intern ("multi-tty"), Qnil
);
3328 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
3329 (do not change this comment) */