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 static struct display
*get_tty_display (Lisp_Object display
);
90 void delete_initial_display
P_ ((struct display
*));
91 void create_tty_output
P_ ((struct frame
*));
92 void delete_tty_output
P_ ((struct frame
*));
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 /* Display space properties */
116 extern Lisp_Object Qspace
, QCalign_to
, QCwidth
;
118 /* Function to use to ring the bell. */
120 Lisp_Object Vring_bell_function
;
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 displays currently in use. */
129 struct display
*display_list
;
131 /* The initial display device, created by initial_term_init. */
132 struct display
*initial_display
;
134 /* Chain of all tty device parameters. */
135 struct tty_display_info
*tty_list
;
137 /* Nonzero means no need to redraw the entire frame on resuming a
138 suspended Emacs. This is useful on terminals with multiple
139 pages, where one page is used for Emacs and another for all
141 int no_redraw_on_reenter
;
144 /* Meaning of bits in no_color_video. Each bit set means that the
145 corresponding attribute cannot be combined with colors. */
149 NC_STANDOUT
= 1 << 0,
150 NC_UNDERLINE
= 1 << 1,
157 NC_ALT_CHARSET
= 1 << 8
162 /* The largest frame width in any call to calculate_costs. */
166 /* The largest frame height in any call to calculate_costs. */
170 /* Non-zero if we have dropped our controlling tty and therefore
171 should not open a frame on stdout. */
172 static int no_controlling_tty
;
174 /* The first unallocated display id. */
175 static int next_display_id
;
177 /* Provided for lisp packages. */
179 static int system_uses_terminfo
;
183 extern char *tgetstr ();
187 /* We aren't X windows, but we aren't termcap either. This makes me
188 uncertain as to what value to use for frame.output_method. For
189 this file, we'll define FRAME_TERMCAP_P to be zero so that our
190 output hooks get called instead of the termcap functions. Probably
191 the best long-term solution is to define an output_windows_nt... */
193 #undef FRAME_TERMCAP_P
194 #define FRAME_TERMCAP_P(_f_) 0
195 #endif /* WINDOWSNT */
198 ring_bell (struct frame
*f
)
200 if (!NILP (Vring_bell_function
))
202 Lisp_Object function
;
204 /* Temporarily set the global variable to nil
205 so that if we get an error, it stays nil
206 and we don't call it over and over.
208 We don't specbind it, because that would carefully
209 restore the bad value if there's an error
210 and make the loop of errors happen anyway. */
212 function
= Vring_bell_function
;
213 Vring_bell_function
= Qnil
;
217 Vring_bell_function
= function
;
219 else if (FRAME_DISPLAY (f
)->ring_bell_hook
)
220 (*FRAME_DISPLAY (f
)->ring_bell_hook
) (f
);
223 /* Ring the bell on a tty. */
226 tty_ring_bell (struct frame
*f
)
228 struct tty_display_info
*tty
= FRAME_TTY (f
);
232 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
233 ? tty
->TS_visible_bell
235 fflush (tty
->output
);
239 /* Set up termcap modes for Emacs. */
242 tty_set_terminal_modes (struct display
*display
)
244 struct tty_display_info
*tty
= display
->display_info
.tty
;
248 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
249 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
250 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
255 /* Reset termcap modes before exiting Emacs. */
258 tty_reset_terminal_modes (struct display
*display
)
260 struct tty_display_info
*tty
= display
->display_info
.tty
;
264 turn_off_highlight (tty
);
265 turn_off_insert (tty
);
266 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
267 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
268 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
269 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
270 /* Output raw CR so kernel can track the cursor hpos. */
277 update_begin (struct frame
*f
)
279 if (FRAME_DISPLAY (f
)->update_begin_hook
)
280 (*FRAME_DISPLAY (f
)->update_begin_hook
) (f
);
284 update_end (struct frame
*f
)
286 if (FRAME_DISPLAY (f
)->update_end_hook
)
287 (*FRAME_DISPLAY (f
)->update_end_hook
) (f
);
290 /* Flag the end of a display update on a termcap display. */
293 tty_update_end (struct frame
*f
)
295 struct tty_display_info
*tty
= FRAME_TTY (f
);
297 if (!XWINDOW (selected_window
)->cursor_off_p
)
298 tty_show_cursor (tty
);
299 turn_off_insert (tty
);
300 background_highlight (tty
);
303 /* Specify how many text lines, from the top of the window,
304 should be affected by insert-lines and delete-lines operations.
305 This, and those operations, are used only within an update
306 that is bounded by calls to update_begin and update_end. */
309 set_terminal_window (struct frame
*f
, int size
)
311 if (FRAME_DISPLAY (f
)->set_terminal_window_hook
)
312 (*FRAME_DISPLAY (f
)->set_terminal_window_hook
) (f
, size
);
315 /* The implementation of set_terminal_window for termcap frames. */
318 tty_set_terminal_window (struct frame
*f
, int size
)
320 struct tty_display_info
*tty
= FRAME_TTY (f
);
322 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
323 if (FRAME_SCROLL_REGION_OK (f
))
324 set_scroll_region (f
, 0, tty
->specified_window
);
328 set_scroll_region (struct frame
*f
, int start
, int stop
)
331 struct tty_display_info
*tty
= FRAME_TTY (f
);
333 if (tty
->TS_set_scroll_region
)
334 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
335 else if (tty
->TS_set_scroll_region_1
)
336 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
337 FRAME_LINES (f
), start
,
338 FRAME_LINES (f
) - stop
,
341 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
350 turn_on_insert (struct tty_display_info
*tty
)
352 if (!tty
->insert_mode
)
353 OUTPUT (tty
, tty
->TS_insert_mode
);
354 tty
->insert_mode
= 1;
358 turn_off_insert (struct tty_display_info
*tty
)
360 if (tty
->insert_mode
)
361 OUTPUT (tty
, tty
->TS_end_insert_mode
);
362 tty
->insert_mode
= 0;
365 /* Handle highlighting. */
368 turn_off_highlight (struct tty_display_info
*tty
)
370 if (tty
->standout_mode
)
371 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
372 tty
->standout_mode
= 0;
376 turn_on_highlight (struct tty_display_info
*tty
)
378 if (!tty
->standout_mode
)
379 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
380 tty
->standout_mode
= 1;
384 toggle_highlight (struct tty_display_info
*tty
)
386 if (tty
->standout_mode
)
387 turn_off_highlight (tty
);
389 turn_on_highlight (tty
);
393 /* Make cursor invisible. */
396 tty_hide_cursor (struct tty_display_info
*tty
)
398 if (tty
->cursor_hidden
== 0)
400 tty
->cursor_hidden
= 1;
401 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
406 /* Ensure that cursor is visible. */
409 tty_show_cursor (struct tty_display_info
*tty
)
411 if (tty
->cursor_hidden
)
413 tty
->cursor_hidden
= 0;
414 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
415 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
420 /* Set standout mode to the state it should be in for
421 empty space inside windows. What this is,
422 depends on the user option inverse-video. */
425 background_highlight (struct tty_display_info
*tty
)
428 turn_on_highlight (tty
);
430 turn_off_highlight (tty
);
433 /* Set standout mode to the mode specified for the text to be output. */
436 highlight_if_desired (struct tty_display_info
*tty
)
439 turn_on_highlight (tty
);
441 turn_off_highlight (tty
);
445 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
446 frame-relative coordinates. */
449 cursor_to (struct frame
*f
, int vpos
, int hpos
)
451 if (FRAME_DISPLAY (f
)->cursor_to_hook
)
452 (*FRAME_DISPLAY (f
)->cursor_to_hook
) (f
, vpos
, hpos
);
456 tty_cursor_to (struct frame
*f
, int vpos
, int hpos
)
458 struct tty_display_info
*tty
= FRAME_TTY (f
);
460 /* Detect the case where we are called from reset_sys_modes
461 and the costs have never been calculated. Do nothing. */
462 if (! tty
->costs_set
)
465 if (curY (tty
) == vpos
466 && curX (tty
) == hpos
)
468 if (!tty
->TF_standout_motion
)
469 background_highlight (tty
);
470 if (!tty
->TF_insmode_motion
)
471 turn_off_insert (tty
);
472 cmgoto (tty
, vpos
, hpos
);
475 /* Similar but don't take any account of the wasted characters. */
478 raw_cursor_to (struct frame
*f
, int row
, int col
)
480 if (FRAME_DISPLAY (f
)->raw_cursor_to_hook
)
481 (*FRAME_DISPLAY (f
)->raw_cursor_to_hook
) (f
, row
, col
);
485 tty_raw_cursor_to (struct frame
*f
, int row
, int col
)
487 struct tty_display_info
*tty
= FRAME_TTY (f
);
489 if (curY (tty
) == row
490 && curX (tty
) == col
)
492 if (!tty
->TF_standout_motion
)
493 background_highlight (tty
);
494 if (!tty
->TF_insmode_motion
)
495 turn_off_insert (tty
);
496 cmgoto (tty
, row
, col
);
499 /* Erase operations */
501 /* Clear from cursor to end of frame. */
503 clear_to_end (struct frame
*f
)
505 if (FRAME_DISPLAY (f
)->clear_to_end_hook
)
506 (*FRAME_DISPLAY (f
)->clear_to_end_hook
) (f
);
509 /* Clear from cursor to end of frame on a termcap device. */
512 tty_clear_to_end (struct frame
*f
)
515 struct tty_display_info
*tty
= FRAME_TTY (f
);
517 if (tty
->TS_clr_to_bottom
)
519 background_highlight (tty
);
520 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
524 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
527 clear_end_of_line (f
, FRAME_COLS (f
));
532 /* Clear entire frame */
535 clear_frame (struct frame
*f
)
537 if (FRAME_DISPLAY (f
)->clear_frame_hook
)
538 (*FRAME_DISPLAY (f
)->clear_frame_hook
) (f
);
541 /* Clear an entire termcap frame. */
544 tty_clear_frame (struct frame
*f
)
546 struct tty_display_info
*tty
= FRAME_TTY (f
);
548 if (tty
->TS_clr_frame
)
550 background_highlight (tty
);
551 OUTPUT (tty
, tty
->TS_clr_frame
);
561 /* Clear from cursor to end of line.
562 Assume that the line is already clear starting at column first_unused_hpos.
564 Note that the cursor may be moved, on terminals lacking a `ce' string. */
567 clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
569 if (FRAME_DISPLAY (f
)->clear_end_of_line_hook
)
570 (*FRAME_DISPLAY (f
)->clear_end_of_line_hook
) (f
, first_unused_hpos
);
573 /* An implementation of clear_end_of_line for termcap frames.
575 Note that the cursor may be moved, on terminals lacking a `ce' string. */
578 tty_clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
581 struct tty_display_info
*tty
= FRAME_TTY (f
);
583 /* Detect the case where we are called from reset_sys_modes
584 and the costs have never been calculated. Do nothing. */
585 if (! tty
->costs_set
)
588 if (curX (tty
) >= first_unused_hpos
)
590 background_highlight (tty
);
591 if (tty
->TS_clr_line
)
593 OUTPUT1 (tty
, tty
->TS_clr_line
);
596 { /* have to do it the hard way */
597 turn_off_insert (tty
);
599 /* Do not write in last row last col with Auto-wrap on. */
601 && curY (tty
) == FrameRows (tty
) - 1
602 && first_unused_hpos
== FrameCols (tty
))
605 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
608 fputc (' ', tty
->termscript
);
609 fputc (' ', tty
->output
);
611 cmplus (tty
, first_unused_hpos
- curX (tty
));
615 /* Buffer to store the source and result of code conversion for terminal. */
616 static unsigned char *encode_terminal_buf
;
617 /* Allocated size of the above buffer. */
618 static int encode_terminal_bufsize
;
620 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
621 Set CODING->produced to the byte-length of the resulting byte
622 sequence, and return a pointer to that byte sequence. */
625 encode_terminal_code (src
, src_len
, coding
)
628 struct coding_system
*coding
;
630 struct glyph
*src_start
= src
, *src_end
= src
+ src_len
;
633 int nchars
, nbytes
, required
;
634 register int tlen
= GLYPH_TABLE_LENGTH
;
635 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
637 /* Allocate sufficient size of buffer to store all characters in
638 multibyte-form. But, it may be enlarged on demand if
639 Vglyph_table contains a string. */
640 required
= MAX_MULTIBYTE_LENGTH
* src_len
;
641 if (encode_terminal_bufsize
< required
)
643 if (encode_terminal_bufsize
== 0)
644 encode_terminal_buf
= xmalloc (required
);
646 encode_terminal_buf
= xrealloc (encode_terminal_buf
, required
);
647 encode_terminal_bufsize
= required
;
650 buf
= encode_terminal_buf
;
652 while (src
< src_end
)
654 /* We must skip glyphs to be padded for a wide character. */
655 if (! CHAR_GLYPH_PADDING_P (*src
))
657 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
659 if (g
< 0 || g
>= tlen
)
661 /* This glyph doesn't has an entry in Vglyph_table. */
662 if (CHAR_VALID_P (src
->u
.ch
, 0))
663 buf
+= CHAR_STRING (src
->u
.ch
, buf
);
670 /* This glyph has an entry in Vglyph_table,
671 so process any alias before testing for simpleness. */
672 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
674 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
676 int c
= FAST_GLYPH_CHAR (g
);
678 if (CHAR_VALID_P (c
, 0))
679 buf
+= CHAR_STRING (c
, buf
);
686 /* We have a string in Vglyph_table. */
690 if (! STRING_MULTIBYTE (string
))
691 string
= string_to_multibyte (string
);
692 nbytes
= buf
- encode_terminal_buf
;
693 if (nbytes
+ SBYTES (string
) < encode_terminal_bufsize
)
695 encode_terminal_bufsize
= nbytes
+ SBYTES (string
);
696 encode_terminal_buf
= xrealloc (encode_terminal_buf
,
697 encode_terminal_bufsize
);
698 buf
= encode_terminal_buf
+ nbytes
;
700 bcopy (SDATA (string
), buf
, SBYTES (string
));
701 buf
+= SBYTES (string
);
702 nchars
+= SCHARS (string
);
709 nbytes
= buf
- encode_terminal_buf
;
710 coding
->src_multibyte
= 1;
711 coding
->dst_multibyte
= 0;
712 if (SYMBOLP (coding
->pre_write_conversion
)
713 && ! NILP (Ffboundp (coding
->pre_write_conversion
)))
715 run_pre_write_conversin_on_c_str (&encode_terminal_buf
,
716 &encode_terminal_bufsize
,
717 nchars
, nbytes
, coding
);
718 nchars
= coding
->produced_char
;
719 nbytes
= coding
->produced
;
721 required
= nbytes
+ encoding_buffer_size (coding
, nbytes
);
722 if (encode_terminal_bufsize
< required
)
724 encode_terminal_bufsize
= required
;
725 encode_terminal_buf
= xrealloc (encode_terminal_buf
, required
);
728 encode_coding (coding
, encode_terminal_buf
, encode_terminal_buf
+ nbytes
,
729 nbytes
, encode_terminal_bufsize
- nbytes
);
730 return encode_terminal_buf
+ nbytes
;
734 /* Output LEN glyphs starting at STRING at the nominal cursor position.
735 Advance the nominal cursor over the text. */
738 write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
740 if (FRAME_DISPLAY (f
)->write_glyphs_hook
)
741 (*FRAME_DISPLAY (f
)->write_glyphs_hook
) (f
, string
, len
);
744 /* An implementation of write_glyphs for termcap frames. */
747 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
749 unsigned char *conversion_buffer
;
750 struct coding_system
*coding
;
752 struct tty_display_info
*tty
= FRAME_TTY (f
);
754 turn_off_insert (tty
);
755 tty_hide_cursor (tty
);
757 /* Don't dare write in last column of bottom line, if Auto-Wrap,
758 since that would scroll the whole frame on some terminals. */
761 && curY (tty
) + 1 == FRAME_LINES (f
)
762 && (curX (tty
) + len
) == FRAME_COLS (f
))
769 /* If terminal_coding does any conversion, use it, otherwise use
770 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
771 because it always return 1 if the member src_multibyte is 1. */
772 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
773 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
774 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
776 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
780 /* Identify a run of glyphs with the same face. */
781 int face_id
= string
->face_id
;
784 for (n
= 1; n
< len
; ++n
)
785 if (string
[n
].face_id
!= face_id
)
788 /* Turn appearance modes of the face of the run on. */
789 highlight_if_desired (tty
);
790 turn_on_face (f
, face_id
);
793 /* This is the last run. */
794 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
795 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
796 if (coding
->produced
> 0)
798 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
799 if (ferror (tty
->output
))
800 clearerr (tty
->output
);
802 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
807 /* Turn appearance modes off. */
808 turn_off_face (f
, face_id
);
809 turn_off_highlight (tty
);
815 /* Insert LEN glyphs from START at the nominal cursor position.
817 If start is zero, insert blanks instead of a string at start */
820 insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
825 if (FRAME_DISPLAY (f
)->insert_glyphs_hook
)
826 (*FRAME_DISPLAY (f
)->insert_glyphs_hook
) (f
, start
, len
);
829 /* An implementation of insert_glyphs for termcap frames. */
832 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
835 struct glyph
*glyph
= NULL
;
836 unsigned char *conversion_buffer
;
837 unsigned char space
[1];
838 struct coding_system
*coding
;
840 struct tty_display_info
*tty
= FRAME_TTY (f
);
842 if (tty
->TS_ins_multi_chars
)
844 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
848 write_glyphs (f
, start
, len
);
852 turn_on_insert (tty
);
856 space
[0] = SPACEGLYPH
;
858 /* If terminal_coding does any conversion, use it, otherwise use
859 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
860 because it always return 1 if the member src_multibyte is 1. */
861 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
862 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
863 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
865 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
869 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
872 conversion_buffer
= space
;
873 coding
->produced
= 1;
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 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
893 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
896 if (coding
->produced
> 0)
898 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
899 if (ferror (tty
->output
))
900 clearerr (tty
->output
);
902 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
905 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
908 turn_off_face (f
, glyph
->face_id
);
909 turn_off_highlight (tty
);
916 /* Delete N glyphs at the nominal cursor position. */
919 delete_glyphs (struct frame
*f
, int n
)
921 if (FRAME_DISPLAY (f
)->delete_glyphs_hook
)
922 (*FRAME_DISPLAY (f
)->delete_glyphs_hook
) (f
, n
);
925 /* An implementation of delete_glyphs for termcap frames. */
928 tty_delete_glyphs (struct frame
*f
, int n
)
933 struct tty_display_info
*tty
= FRAME_TTY (f
);
935 if (tty
->delete_in_insert_mode
)
937 turn_on_insert (tty
);
941 turn_off_insert (tty
);
942 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
945 if (tty
->TS_del_multi_chars
)
947 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
952 for (i
= 0; i
< n
; i
++)
953 OUTPUT1 (tty
, tty
->TS_del_char
);
954 if (!tty
->delete_in_insert_mode
)
955 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
958 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
961 ins_del_lines (struct frame
*f
, int vpos
, int n
)
963 if (FRAME_DISPLAY (f
)->ins_del_lines_hook
)
964 (*FRAME_DISPLAY (f
)->ins_del_lines_hook
) (f
, vpos
, n
);
967 /* An implementation of ins_del_lines for termcap frames. */
970 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
972 struct tty_display_info
*tty
= FRAME_TTY (f
);
973 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
974 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
975 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
977 register int i
= n
> 0 ? n
: -n
;
980 /* If the lines below the insertion are being pushed
981 into the end of the window, this is the same as clearing;
982 and we know the lines are already clear, since the matching
983 deletion has already been done. So can ignore this. */
984 /* If the lines below the deletion are blank lines coming
985 out of the end of the window, don't bother,
986 as there will be a matching inslines later that will flush them. */
987 if (FRAME_SCROLL_REGION_OK (f
)
988 && vpos
+ i
>= tty
->specified_window
)
990 if (!FRAME_MEMORY_BELOW_FRAME (f
)
991 && vpos
+ i
>= FRAME_LINES (f
))
996 raw_cursor_to (f
, vpos
, 0);
997 background_highlight (tty
);
998 buf
= tparam (multi
, 0, 0, i
);
1004 raw_cursor_to (f
, vpos
, 0);
1005 background_highlight (tty
);
1007 OUTPUT (tty
, single
);
1008 if (tty
->TF_teleray
)
1013 set_scroll_region (f
, vpos
, tty
->specified_window
);
1015 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
1017 raw_cursor_to (f
, vpos
, 0);
1018 background_highlight (tty
);
1020 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1021 set_scroll_region (f
, 0, tty
->specified_window
);
1024 if (!FRAME_SCROLL_REGION_OK (f
)
1025 && FRAME_MEMORY_BELOW_FRAME (f
)
1028 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
1033 /* Compute cost of sending "str", in characters,
1034 not counting any line-dependent padding. */
1037 string_cost (char *str
)
1041 tputs (str
, 0, evalcost
);
1045 /* Compute cost of sending "str", in characters,
1046 counting any line-dependent padding at one line. */
1049 string_cost_one_line (char *str
)
1053 tputs (str
, 1, evalcost
);
1057 /* Compute per line amount of line-dependent padding,
1058 in tenths of characters. */
1061 per_line_cost (char *str
)
1065 tputs (str
, 0, evalcost
);
1068 tputs (str
, 10, evalcost
);
1073 /* char_ins_del_cost[n] is cost of inserting N characters.
1074 char_ins_del_cost[-n] is cost of deleting N characters.
1075 The length of this vector is based on max_frame_cols. */
1077 int *char_ins_del_vector
;
1079 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1084 calculate_ins_del_char_costs (struct frame
*f
)
1086 struct tty_display_info
*tty
= FRAME_TTY (f
);
1087 int ins_startup_cost
, del_startup_cost
;
1088 int ins_cost_per_char
, del_cost_per_char
;
1092 if (tty
->TS_ins_multi_chars
)
1094 ins_cost_per_char
= 0;
1095 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1097 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1098 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1100 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1101 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1102 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1103 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1107 ins_startup_cost
= 9999;
1108 ins_cost_per_char
= 0;
1111 if (tty
->TS_del_multi_chars
)
1113 del_cost_per_char
= 0;
1114 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1116 else if (tty
->TS_del_char
)
1118 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1119 + string_cost (tty
->TS_end_delete_mode
));
1120 if (tty
->delete_in_insert_mode
)
1121 del_startup_cost
/= 2;
1122 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1126 del_startup_cost
= 9999;
1127 del_cost_per_char
= 0;
1130 /* Delete costs are at negative offsets */
1131 p
= &char_ins_del_cost (f
)[0];
1132 for (i
= FRAME_COLS (f
); --i
>= 0;)
1133 *--p
= (del_startup_cost
+= del_cost_per_char
);
1135 /* Doing nothing is free */
1136 p
= &char_ins_del_cost (f
)[0];
1139 /* Insert costs are at positive offsets */
1140 for (i
= FRAME_COLS (f
); --i
>= 0;)
1141 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1145 calculate_costs (struct frame
*frame
)
1147 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1149 if (FRAME_TERMCAP_P (frame
))
1151 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1152 register char *f
= (tty
->TS_set_scroll_region
1153 ? tty
->TS_set_scroll_region
1154 : tty
->TS_set_scroll_region_1
);
1156 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1160 /* These variables are only used for terminal stuff. They are
1161 allocated once for the terminal frame of X-windows emacs, but not
1164 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1165 X turns off char_ins_del_ok. */
1167 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1168 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1170 if (char_ins_del_vector
!= 0)
1172 = (int *) xrealloc (char_ins_del_vector
,
1174 + 2 * max_frame_cols
* sizeof (int)));
1177 = (int *) xmalloc (sizeof (int)
1178 + 2 * max_frame_cols
* sizeof (int));
1180 bzero (char_ins_del_vector
, (sizeof (int)
1181 + 2 * max_frame_cols
* sizeof (int)));
1184 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1185 do_line_insertion_deletion_costs (frame
,
1186 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1187 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1190 do_line_insertion_deletion_costs (frame
,
1191 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1192 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1195 calculate_ins_del_char_costs (frame
);
1197 /* Don't use TS_repeat if its padding is worse than sending the chars */
1198 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1199 tty
->RPov
= string_cost (tty
->TS_repeat
);
1201 tty
->RPov
= FRAME_COLS (frame
) * 2;
1203 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1211 /* Termcap capability names that correspond directly to X keysyms.
1212 Some of these (marked "terminfo") aren't supplied by old-style
1213 (Berkeley) termcap entries. They're listed in X keysym order;
1214 except we put the keypad keys first, so that if they clash with
1215 other keys (as on the IBM PC keyboard) they get overridden.
1218 static struct fkey_table keys
[] =
1220 {"kh", "home"}, /* termcap */
1221 {"kl", "left"}, /* termcap */
1222 {"ku", "up"}, /* termcap */
1223 {"kr", "right"}, /* termcap */
1224 {"kd", "down"}, /* termcap */
1225 {"%8", "prior"}, /* terminfo */
1226 {"%5", "next"}, /* terminfo */
1227 {"@7", "end"}, /* terminfo */
1228 {"@1", "begin"}, /* terminfo */
1229 {"*6", "select"}, /* terminfo */
1230 {"%9", "print"}, /* terminfo */
1231 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1233 * "insert" --- see below
1235 {"&8", "undo"}, /* terminfo */
1236 {"%0", "redo"}, /* terminfo */
1237 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1238 {"@0", "find"}, /* terminfo */
1239 {"@2", "cancel"}, /* terminfo */
1240 {"%1", "help"}, /* terminfo */
1242 * "break" goes here, but can't be reliably intercepted with termcap
1244 {"&4", "reset"}, /* terminfo --- actually `restart' */
1246 * "system" and "user" --- no termcaps
1248 {"kE", "clearline"}, /* terminfo */
1249 {"kA", "insertline"}, /* terminfo */
1250 {"kL", "deleteline"}, /* terminfo */
1251 {"kI", "insertchar"}, /* terminfo */
1252 {"kD", "deletechar"}, /* terminfo */
1253 {"kB", "backtab"}, /* terminfo */
1255 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1257 {"@8", "kp-enter"}, /* terminfo */
1259 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1260 * "kp-multiply", "kp-add", "kp-separator",
1261 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1262 * --- no termcaps for any of these.
1264 {"K4", "kp-1"}, /* terminfo */
1266 * "kp-2" --- no termcap
1268 {"K5", "kp-3"}, /* terminfo */
1270 * "kp-4" --- no termcap
1272 {"K2", "kp-5"}, /* terminfo */
1274 * "kp-6" --- no termcap
1276 {"K1", "kp-7"}, /* terminfo */
1278 * "kp-8" --- no termcap
1280 {"K3", "kp-9"}, /* terminfo */
1282 * "kp-equal" --- no termcap
1295 static char **term_get_fkeys_arg
;
1296 static Lisp_Object
term_get_fkeys_1 ();
1298 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1299 This function scans the termcap function key sequence entries, and
1300 adds entries to Vfunction_key_map for each function key it finds. */
1303 term_get_fkeys (address
)
1306 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1307 errors during the call. The only errors should be from Fdefine_key
1308 when given a key sequence containing an invalid prefix key. If the
1309 termcap defines function keys which use a prefix that is already bound
1310 to a command by the default bindings, we should silently ignore that
1311 function key specification, rather than giving the user an error and
1312 refusing to run at all on such a terminal. */
1314 extern Lisp_Object
Fidentity ();
1315 term_get_fkeys_arg
= address
;
1316 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1324 char **address
= term_get_fkeys_arg
;
1326 /* This can happen if CANNOT_DUMP or with strange options. */
1328 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1330 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1332 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1334 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1335 Fmake_vector (make_number (1),
1336 intern (keys
[i
].name
)));
1339 /* The uses of the "k0" capability are inconsistent; sometimes it
1340 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1341 We will attempt to politely accommodate both systems by testing for
1342 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1345 char *k_semi
= tgetstr ("k;", address
);
1346 char *k0
= tgetstr ("k0", address
);
1347 char *k0_name
= "f10";
1352 /* Define f0 first, so that f10 takes precedence in case the
1353 key sequences happens to be the same. */
1354 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1355 Fmake_vector (make_number (1), intern ("f0")));
1356 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1357 Fmake_vector (make_number (1), intern ("f10")));
1360 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1361 Fmake_vector (make_number (1), intern (k0_name
)));
1364 /* Set up cookies for numbered function keys above f10. */
1366 char fcap
[3], fkey
[4];
1368 fcap
[0] = 'F'; fcap
[2] = '\0';
1369 for (i
= 11; i
< 64; i
++)
1372 fcap
[1] = '1' + i
- 11;
1374 fcap
[1] = 'A' + i
- 20;
1376 fcap
[1] = 'a' + i
- 46;
1379 char *sequence
= tgetstr (fcap
, address
);
1382 sprintf (fkey
, "f%d", i
);
1383 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1384 Fmake_vector (make_number (1),
1392 * Various mappings to try and get a better fit.
1395 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1396 if (!tgetstr (cap1, address)) \
1398 char *sequence = tgetstr (cap2, address); \
1400 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1401 Fmake_vector (make_number (1), \
1405 /* if there's no key_next keycap, map key_npage to `next' keysym */
1406 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1407 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1408 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1409 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1410 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1411 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1412 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1414 /* IBM has their own non-standard dialect of terminfo.
1415 If the standard name isn't found, try the IBM name. */
1416 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1417 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1418 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1419 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1420 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1421 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1422 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1423 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1424 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1425 #undef CONDITIONAL_REASSIGN
1432 /***********************************************************************
1433 Character Display Information
1434 ***********************************************************************/
1436 static void append_glyph
P_ ((struct it
*));
1437 static void produce_stretch_glyph
P_ ((struct it
*));
1440 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1441 terminal frames if IT->glyph_row != NULL. IT->c is the character
1442 for which to produce glyphs; IT->face_id contains the character's
1443 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1450 struct glyph
*glyph
, *end
;
1453 xassert (it
->glyph_row
);
1454 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1455 + it
->glyph_row
->used
[it
->area
]);
1456 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1459 i
< it
->pixel_width
&& glyph
< end
;
1462 glyph
->type
= CHAR_GLYPH
;
1463 glyph
->pixel_width
= 1;
1464 glyph
->u
.ch
= it
->c
;
1465 glyph
->face_id
= it
->face_id
;
1466 glyph
->padding_p
= i
> 0;
1467 glyph
->charpos
= CHARPOS (it
->position
);
1468 glyph
->object
= it
->object
;
1470 ++it
->glyph_row
->used
[it
->area
];
1476 /* Produce glyphs for the display element described by IT. *IT
1477 specifies what we want to produce a glyph for (character, image, ...),
1478 and where in the glyph matrix we currently are (glyph row and hpos).
1479 produce_glyphs fills in output fields of *IT with information such as the
1480 pixel width and height of a character, and maybe output actual glyphs at
1481 the same time if IT->glyph_row is non-null. See the explanation of
1482 struct display_iterator in dispextern.h for an overview.
1484 produce_glyphs also stores the result of glyph width, ascent
1485 etc. computations in *IT.
1487 IT->glyph_row may be null, in which case produce_glyphs does not
1488 actually fill in the glyphs. This is used in the move_* functions
1489 in xdisp.c for text width and height computations.
1491 Callers usually don't call produce_glyphs directly;
1492 instead they use the macro PRODUCE_GLYPHS. */
1498 /* If a hook is installed, let it do the work. */
1499 xassert (it
->what
== IT_CHARACTER
1500 || it
->what
== IT_COMPOSITION
1501 || it
->what
== IT_STRETCH
);
1503 if (it
->what
== IT_STRETCH
)
1505 produce_stretch_glyph (it
);
1509 /* Nothing but characters are supported on terminal frames. For a
1510 composition sequence, it->c is the first character of the
1512 xassert (it
->what
== IT_CHARACTER
1513 || it
->what
== IT_COMPOSITION
);
1515 if (it
->c
>= 040 && it
->c
< 0177)
1517 it
->pixel_width
= it
->nglyphs
= 1;
1521 else if (it
->c
== '\n')
1522 it
->pixel_width
= it
->nglyphs
= 0;
1523 else if (it
->c
== '\t')
1525 int absolute_x
= (it
->current_x
1526 + it
->continuation_lines_width
);
1528 = (((1 + absolute_x
+ it
->tab_width
- 1)
1533 /* If part of the TAB has been displayed on the previous line
1534 which is continued now, continuation_lines_width will have
1535 been incremented already by the part that fitted on the
1536 continued line. So, we will get the right number of spaces
1538 nspaces
= next_tab_x
- absolute_x
;
1545 it
->pixel_width
= it
->len
= 1;
1553 it
->pixel_width
= nspaces
;
1554 it
->nglyphs
= nspaces
;
1556 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1558 /* Coming here means that it->c is from display table, thus we
1559 must send the code as is to the terminal. Although there's
1560 no way to know how many columns it occupies on a screen, it
1561 is a good assumption that a single byte code has 1-column
1563 it
->pixel_width
= it
->nglyphs
= 1;
1569 /* A multi-byte character. The display width is fixed for all
1570 characters of the set. Some of the glyphs may have to be
1571 ignored because they are already displayed in a continued
1573 int charset
= CHAR_CHARSET (it
->c
);
1575 it
->pixel_width
= CHARSET_WIDTH (charset
);
1576 it
->nglyphs
= it
->pixel_width
;
1583 /* Advance current_x by the pixel width as a convenience for
1585 if (it
->area
== TEXT_AREA
)
1586 it
->current_x
+= it
->pixel_width
;
1587 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1588 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1592 /* Produce a stretch glyph for iterator IT. IT->object is the value
1593 of the glyph property displayed. The value must be a list
1594 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1597 1. `:width WIDTH' specifies that the space should be WIDTH *
1598 canonical char width wide. WIDTH may be an integer or floating
1601 2. `:align-to HPOS' specifies that the space should be wide enough
1602 to reach HPOS, a value in canonical character units. */
1605 produce_stretch_glyph (it
)
1608 /* (space :width WIDTH ...) */
1609 Lisp_Object prop
, plist
;
1610 int width
= 0, align_to
= -1;
1611 int zero_width_ok_p
= 0;
1614 /* List should start with `space'. */
1615 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1616 plist
= XCDR (it
->object
);
1618 /* Compute the width of the stretch. */
1619 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1620 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1622 /* Absolute width `:width WIDTH' specified and valid. */
1623 zero_width_ok_p
= 1;
1624 width
= (int)(tem
+ 0.5);
1626 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1627 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1629 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1630 align_to
= (align_to
< 0
1632 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1633 else if (align_to
< 0)
1634 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1635 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1636 zero_width_ok_p
= 1;
1639 /* Nothing specified -> width defaults to canonical char width. */
1640 width
= FRAME_COLUMN_WIDTH (it
->f
);
1642 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1645 if (width
> 0 && it
->glyph_row
)
1647 Lisp_Object o_object
= it
->object
;
1648 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1652 if (!STRINGP (object
))
1653 object
= it
->w
->buffer
;
1654 it
->object
= object
;
1656 it
->pixel_width
= it
->len
= 1;
1659 it
->object
= o_object
;
1662 it
->pixel_width
= width
;
1663 it
->nglyphs
= width
;
1667 /* Get information about special display element WHAT in an
1668 environment described by IT. WHAT is one of IT_TRUNCATION or
1669 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1670 non-null glyph_row member. This function ensures that fields like
1671 face_id, c, len of IT are left untouched. */
1674 produce_special_glyphs (it
, what
)
1676 enum display_element_type what
;
1682 temp_it
.what
= IT_CHARACTER
;
1684 temp_it
.object
= make_number (0);
1685 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1687 if (what
== IT_CONTINUATION
)
1689 /* Continuation glyph. */
1691 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1692 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1694 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it
->dp
)));
1695 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1700 produce_glyphs (&temp_it
);
1701 it
->pixel_width
= temp_it
.pixel_width
;
1702 it
->nglyphs
= temp_it
.pixel_width
;
1704 else if (what
== IT_TRUNCATION
)
1706 /* Truncation glyph. */
1708 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1709 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1711 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it
->dp
)));
1712 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1717 produce_glyphs (&temp_it
);
1718 it
->pixel_width
= temp_it
.pixel_width
;
1719 it
->nglyphs
= temp_it
.pixel_width
;
1727 /***********************************************************************
1729 ***********************************************************************/
1731 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1732 one of the enumerators from enum no_color_bit, or a bit set built
1733 from them. Some display attributes may not be used together with
1734 color; the termcap capability `NC' specifies which ones. */
1736 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1737 (tty->TN_max_colors > 0 \
1738 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1741 /* Turn appearances of face FACE_ID on tty frame F on. */
1744 turn_on_face (f
, face_id
)
1748 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1749 long fg
= face
->foreground
;
1750 long bg
= face
->background
;
1751 struct tty_display_info
*tty
= FRAME_TTY (f
);
1753 /* Do this first because TS_end_standout_mode may be the same
1754 as TS_exit_attribute_mode, which turns all appearances off. */
1755 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1757 if (tty
->TN_max_colors
> 0)
1759 if (fg
>= 0 && bg
>= 0)
1761 /* If the terminal supports colors, we can set them
1762 below without using reverse video. The face's fg
1763 and bg colors are set as they should appear on
1764 the screen, i.e. they take the inverse-video'ness
1765 of the face already into account. */
1767 else if (inverse_video
)
1769 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1770 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1771 toggle_highlight (tty
);
1775 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1776 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1777 toggle_highlight (tty
);
1782 /* If we can't display colors, use reverse video
1783 if the face specifies that. */
1786 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1787 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1788 toggle_highlight (tty
);
1792 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1793 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1794 toggle_highlight (tty
);
1799 if (face
->tty_bold_p
)
1801 if (MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1802 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1804 else if (face
->tty_dim_p
)
1805 if (MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1806 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1808 /* Alternate charset and blinking not yet used. */
1809 if (face
->tty_alt_charset_p
1810 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1811 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1813 if (face
->tty_blinking_p
1814 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1815 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1817 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1818 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1820 if (tty
->TN_max_colors
> 0)
1824 if (fg
>= 0 && tty
->TS_set_foreground
)
1826 p
= tparam (tty
->TS_set_foreground
, NULL
, 0, (int) fg
);
1831 if (bg
>= 0 && tty
->TS_set_background
)
1833 p
= tparam (tty
->TS_set_background
, NULL
, 0, (int) bg
);
1841 /* Turn off appearances of face FACE_ID on tty frame F. */
1844 turn_off_face (f
, face_id
)
1848 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1849 struct tty_display_info
*tty
= FRAME_TTY (f
);
1851 xassert (face
!= NULL
);
1853 if (tty
->TS_exit_attribute_mode
)
1855 /* Capability "me" will turn off appearance modes double-bright,
1856 half-bright, reverse-video, standout, underline. It may or
1857 may not turn off alt-char-mode. */
1858 if (face
->tty_bold_p
1860 || face
->tty_reverse_p
1861 || face
->tty_alt_charset_p
1862 || face
->tty_blinking_p
1863 || face
->tty_underline_p
)
1865 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
1866 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
1867 tty
->standout_mode
= 0;
1870 if (face
->tty_alt_charset_p
)
1871 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1875 /* If we don't have "me" we can only have those appearances
1876 that have exit sequences defined. */
1877 if (face
->tty_alt_charset_p
)
1878 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1880 if (face
->tty_underline_p
)
1881 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
1884 /* Switch back to default colors. */
1885 if (tty
->TN_max_colors
> 0
1886 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
1887 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
1888 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
1889 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
1890 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
1894 /* Return non-zero if the terminal on frame F supports all of the
1895 capabilities in CAPS simultaneously, with foreground and background
1896 colors FG and BG. */
1899 tty_capable_p (tty
, caps
, fg
, bg
)
1900 struct tty_display_info
*tty
;
1902 unsigned long fg
, bg
;
1904 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
1905 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
1908 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
1909 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
1910 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
1911 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
1912 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
1913 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
1919 /* Return non-zero if the terminal is capable to display colors. */
1921 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
1923 doc
: /* Return non-nil if the tty device that DISPLAY uses can display colors. */)
1925 Lisp_Object display
;
1927 struct display
*d
= get_tty_display (display
);
1931 return d
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
1934 /* Return the number of supported colors. */
1935 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
1936 Stty_display_color_cells
, 0, 1, 0,
1937 doc
: /* Return the number of colors supported by the tty device that DISPLAY uses. */)
1939 Lisp_Object display
;
1941 struct display
*d
= get_tty_display (display
);
1943 return make_number (0);
1945 return make_number (d
->display_info
.tty
->TN_max_colors
);
1950 /* Save or restore the default color-related capabilities of this
1953 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
1956 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
1957 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
1961 if (default_orig_pair
)
1962 xfree (default_orig_pair
);
1963 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
1965 if (default_set_foreground
)
1966 xfree (default_set_foreground
);
1967 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
1970 if (default_set_background
)
1971 xfree (default_set_background
);
1972 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
1975 default_max_colors
= tty
->TN_max_colors
;
1976 default_max_pairs
= tty
->TN_max_pairs
;
1977 default_no_color_video
= tty
->TN_no_color_video
;
1981 tty
->TS_orig_pair
= default_orig_pair
;
1982 tty
->TS_set_foreground
= default_set_foreground
;
1983 tty
->TS_set_background
= default_set_background
;
1984 tty
->TN_max_colors
= default_max_colors
;
1985 tty
->TN_max_pairs
= default_max_pairs
;
1986 tty
->TN_no_color_video
= default_no_color_video
;
1990 /* Setup one of the standard tty color schemes according to MODE.
1991 MODE's value is generally the number of colors which we want to
1992 support; zero means set up for the default capabilities, the ones
1993 we saw at term_init time; -1 means turn off color support. */
1995 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
1997 /* Canonicalize all negative values of MODE. */
2003 case -1: /* no colors at all */
2004 tty
->TN_max_colors
= 0;
2005 tty
->TN_max_pairs
= 0;
2006 tty
->TN_no_color_video
= 0;
2007 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2009 case 0: /* default colors, if any */
2011 tty_default_color_capabilities (tty
, 0);
2013 case 8: /* 8 standard ANSI colors */
2014 tty
->TS_orig_pair
= "\033[0m";
2016 tty
->TS_set_foreground
= "\033[3%p1%dm";
2017 tty
->TS_set_background
= "\033[4%p1%dm";
2019 tty
->TS_set_foreground
= "\033[3%dm";
2020 tty
->TS_set_background
= "\033[4%dm";
2022 tty
->TN_max_colors
= 8;
2023 tty
->TN_max_pairs
= 64;
2024 tty
->TN_no_color_video
= 0;
2030 set_tty_color_mode (f
, val
)
2034 Lisp_Object color_mode_spec
, current_mode_spec
;
2035 Lisp_Object color_mode
, current_mode
;
2037 extern Lisp_Object Qtty_color_mode
;
2038 Lisp_Object tty_color_mode_alist
;
2040 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2047 if (NILP (tty_color_mode_alist
))
2048 color_mode_spec
= Qnil
;
2050 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2052 if (CONSP (color_mode_spec
))
2053 color_mode
= XCDR (color_mode_spec
);
2058 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2060 if (CONSP (current_mode_spec
))
2061 current_mode
= XCDR (current_mode_spec
);
2063 current_mode
= Qnil
;
2064 if (INTEGERP (color_mode
))
2065 mode
= XINT (color_mode
);
2067 mode
= 0; /* meaning default */
2068 if (INTEGERP (current_mode
))
2069 old_mode
= XINT (current_mode
);
2073 if (mode
!= old_mode
)
2075 tty_setup_colors (FRAME_TTY (f
), mode
);
2076 /* This recomputes all the faces given the new color
2078 call0 (intern ("tty-set-up-initial-frame-faces"));
2083 #endif /* !WINDOWSNT */
2087 /* Return the display object specified by DISPLAY. DISPLAY may be a
2088 display id, a frame, or nil for the display device of the current
2092 get_display (Lisp_Object display
)
2095 display
= selected_frame
;
2097 if (! INTEGERP (display
) && ! FRAMEP (display
))
2100 if (INTEGERP (display
))
2104 for (d
= display_list
; d
; d
= d
->next_display
)
2106 if (d
->id
== XINT (display
))
2111 else if (FRAMEP (display
))
2113 return FRAME_DISPLAY (XFRAME (display
));
2118 /* Return the tty display object specified by DISPLAY. */
2120 static struct display
*
2121 get_tty_display (Lisp_Object display
)
2123 struct display
*d
= get_display (display
);
2125 if (d
&& d
->type
== output_initial
)
2128 if (d
&& d
->type
!= output_termcap
)
2130 #if 0 /* XXX We need a predicate as the first argument; find one. */
2131 wrong_type_argument ("Not a termcap display", display
);
2132 #else /* Until we fix the wrong_type_argument call above, simply throw
2134 error ("DISPLAY is not a termcap display");
2141 /* Return the active termcap display that uses the tty device with the
2142 given name. If NAME is NULL, return the display corresponding to
2143 our controlling terminal.
2145 This function ignores suspended displays.
2147 Returns NULL if the named terminal device is not opened. */
2150 get_named_tty_display (name
)
2155 for (d
= display_list
; d
; d
= d
->next_display
) {
2156 if (d
->type
== output_termcap
2157 && ((d
->display_info
.tty
->name
== 0 && name
== 0)
2158 || (name
&& d
->display_info
.tty
->name
2159 && !strcmp (d
->display_info
.tty
->name
, name
)))
2160 && DISPLAY_ACTIVE_P (d
))
2169 DEFUN ("display-name", Fdisplay_name
, Sdisplay_name
, 0, 1, 0,
2170 doc
: /* Return the name of the device that DISPLAY uses.
2171 It is not guaranteed that the returned value is unique among opened displays.
2173 DISPLAY can be a display, a frame, or nil (meaning the selected
2174 frame's display). */)
2176 Lisp_Object display
;
2178 struct display
*d
= get_display (display
);
2181 wrong_type_argument (Qdisplay_live_p
, display
);
2184 return build_string (d
->name
);
2189 DEFUN ("display-tty-type", Fdisplay_tty_type
, Sdisplay_tty_type
, 0, 1, 0,
2190 doc
: /* Return the type of the TTY device that DISPLAY uses. */)
2192 Lisp_Object display
;
2194 struct display
*d
= get_display (display
);
2197 wrong_type_argument (Qdisplay_live_p
, display
);
2198 if (d
->type
!= output_termcap
)
2199 error ("Display %d is not a termcap display", d
->id
);
2201 if (d
->display_info
.tty
->type
)
2202 return build_string (d
->display_info
.tty
->type
);
2207 DEFUN ("display-controlling-tty-p", Fdisplay_controlling_tty_p
, Sdisplay_controlling_tty_p
, 0, 1, 0,
2208 doc
: /* Return non-nil if DISPLAY is on the controlling tty of the Emacs process. */)
2210 Lisp_Object display
;
2212 struct display
*d
= get_display (display
);
2215 wrong_type_argument (Qdisplay_live_p
, display
);
2217 if (d
->type
!= output_termcap
|| d
->display_info
.tty
->name
)
2224 /***********************************************************************
2226 ***********************************************************************/
2228 /* Create the bootstrap display device for the initial frame.
2229 Returns a display of type output_initial. */
2232 init_initial_display (void)
2234 if (initialized
|| display_list
|| tty_list
)
2237 initial_display
= create_display ();
2238 initial_display
->type
= output_initial
;
2239 initial_display
->name
= xstrdup ("initial_display");
2241 initial_display
->delete_display_hook
= &delete_initial_display
;
2242 /* All other hooks are NULL. */
2244 return initial_display
;
2247 /* Deletes the bootstrap display device.
2248 Called through delete_display_hook. */
2251 delete_initial_display (struct display
*display
)
2253 if (display
!= initial_display
)
2256 delete_display (display
);
2257 initial_display
= NULL
;
2260 /* Drop the controlling terminal if fd is the same device. */
2262 dissociate_if_controlling_tty (int fd
)
2265 EMACS_GET_TTY_PGRP (fd
, &pgid
); /* If tcgetpgrp succeeds, fd is the ctty. */
2268 #if defined (USG) && !defined (BSD_PGRPS)
2270 no_controlling_tty
= 1;
2272 #ifdef TIOCNOTTY /* Try BSD ioctls. */
2273 sigblock (sigmask (SIGTTOU
));
2274 fd
= emacs_open ("/dev/tty", O_RDWR
, 0);
2275 if (fd
!= -1 && ioctl (fd
, TIOCNOTTY
, 0) != -1)
2277 no_controlling_tty
= 1;
2281 sigunblock (sigmask (SIGTTOU
));
2283 /* Unknown system. */
2285 #endif /* ! TIOCNOTTY */
2290 /* Create a termcap display on the tty device with the given name and
2293 If NAME is NULL, then use the controlling tty, i.e., stdin/stdout.
2294 Otherwise NAME should be a path to the tty device file,
2297 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
2299 If MUST_SUCCEED is true, then all errors are fatal. */
2302 term_init (char *name
, char *terminal_type
, int must_succeed
)
2305 char **address
= &area
;
2306 char *buffer
= NULL
;
2307 int buffer_size
= 4096;
2310 struct tty_display_info
*tty
;
2311 struct display
*display
;
2313 static void maybe_fatal();
2316 maybe_fatal (must_succeed
, 0, 0,
2317 "Unknown terminal type",
2318 "Unknown terminal type");
2320 /* If we already have an active display on the given device, use that.
2321 If all displays are suspended, create a new one instead. */
2322 /* XXX Perhaps this should be made explicit by having term_init
2323 always create a new display and separating display and frame
2324 creation on Lisp level. */
2325 display
= get_named_tty_display (name
);
2329 display
= create_display ();
2330 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
2331 bzero (tty
, sizeof (struct tty_display_info
));
2332 tty
->next
= tty_list
;
2335 display
->type
= output_termcap
;
2336 display
->display_info
.tty
= tty
;
2337 tty
->display
= display
;
2339 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
2342 display
->rif
= 0; /* ttys don't support window-based redisplay. */
2344 display
->cursor_to_hook
= &tty_cursor_to
;
2345 display
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
2347 display
->clear_to_end_hook
= &tty_clear_to_end
;
2348 display
->clear_frame_hook
= &tty_clear_frame
;
2349 display
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
2351 display
->ins_del_lines_hook
= &tty_ins_del_lines
;
2353 display
->insert_glyphs_hook
= &tty_insert_glyphs
;
2354 display
->write_glyphs_hook
= &tty_write_glyphs
;
2355 display
->delete_glyphs_hook
= &tty_delete_glyphs
;
2357 display
->ring_bell_hook
= &tty_ring_bell
;
2359 display
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
2360 display
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
2361 display
->update_begin_hook
= 0; /* Not needed. */
2362 display
->update_end_hook
= &tty_update_end
;
2363 display
->set_terminal_window_hook
= &tty_set_terminal_window
;
2365 display
->mouse_position_hook
= 0; /* Not needed. */
2366 display
->frame_rehighlight_hook
= 0; /* Not needed. */
2367 display
->frame_raise_lower_hook
= 0; /* Not needed. */
2369 display
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
2370 display
->condemn_scroll_bars_hook
= 0; /* Not needed. */
2371 display
->redeem_scroll_bar_hook
= 0; /* Not needed. */
2372 display
->judge_scroll_bars_hook
= 0; /* Not needed. */
2374 display
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
2375 display
->frame_up_to_date_hook
= 0; /* Not needed. */
2377 display
->delete_frame_hook
= &delete_tty_output
;
2378 display
->delete_display_hook
= &delete_tty
;
2385 #ifdef O_IGNORE_CTTY
2386 /* Open the terminal device. Don't recognize it as our
2387 controlling terminal, and don't make it the controlling tty
2388 if we don't have one at the moment. */
2389 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
2391 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
2392 defined on Hurd. On other systems, we need to dissociate
2393 ourselves from the controlling tty when we want to open a
2394 frame on the same terminal. */
2396 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
2398 #endif /* O_IGNORE_CTTY */
2402 delete_tty (display
);
2403 error ("Could not open file: %s", name
);
2408 error ("Not a tty device: %s", name
);
2411 dissociate_if_controlling_tty (fd
);
2413 file
= fdopen (fd
, "w+");
2414 tty
->name
= xstrdup (name
);
2415 display
->name
= xstrdup (name
);
2421 if (no_controlling_tty
)
2423 /* Opening a frame on stdout is unsafe if we have
2424 disconnected our controlling terminal. */
2425 error ("There is no controlling terminal any more");
2428 display
->name
= xstrdup (ttyname (0));
2430 tty
->output
= stdout
;
2433 tty
->type
= xstrdup (terminal_type
);
2435 add_keyboard_wait_descriptor (fileno (tty
->input
));
2437 encode_terminal_bufsize
= 0;
2440 initialize_w32_display ();
2444 area
= (char *) xmalloc (2044);
2446 FrameRows (tty
) = FRAME_LINES (f
); /* XXX */
2447 FrameCols (tty
) = FRAME_COLS (f
); /* XXX */
2448 tty
->specified_window
= FRAME_LINES (f
); /* XXX */
2450 tty
->display
->delete_in_insert_mode
= 1;
2453 display
->scroll_region_ok
= 0;
2455 /* Seems to insert lines when it's not supposed to, messing
2456 up the display. In doing a trace, it didn't seem to be
2457 called much, so I don't think we're losing anything by
2459 display
->line_ins_del_ok
= 0;
2460 display
->char_ins_del_ok
= 1;
2464 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0; /* XXX */
2465 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
; /* XXX */
2466 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2469 #else /* not WINDOWSNT */
2473 buffer
= (char *) xmalloc (buffer_size
);
2475 /* On some systems, tgetent tries to access the controlling
2477 sigblock (sigmask (SIGTTOU
));
2478 status
= tgetent (buffer
, terminal_type
);
2479 sigunblock (sigmask (SIGTTOU
));
2484 maybe_fatal (must_succeed
, buffer
, display
,
2485 "Cannot open terminfo database file",
2486 "Cannot open terminfo database file");
2488 maybe_fatal (must_succeed
, buffer
, display
,
2489 "Cannot open termcap database file",
2490 "Cannot open termcap database file");
2496 maybe_fatal (must_succeed
, buffer
, display
,
2497 "Terminal type %s is not defined",
2498 "Terminal type %s is not defined.\n\
2499 If that is not the actual type of terminal you have,\n\
2500 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2501 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2502 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2505 maybe_fatal (must_succeed
, buffer
, display
,
2506 "Terminal type %s is not defined",
2507 "Terminal type %s is not defined.\n\
2508 If that is not the actual type of terminal you have,\n\
2509 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2510 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2511 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2517 if (strlen (buffer
) >= buffer_size
)
2519 buffer_size
= strlen (buffer
);
2521 area
= (char *) xmalloc (buffer_size
);
2523 tty
->TS_ins_line
= tgetstr ("al", address
);
2524 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
2525 tty
->TS_bell
= tgetstr ("bl", address
);
2526 BackTab (tty
) = tgetstr ("bt", address
);
2527 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
2528 tty
->TS_clr_line
= tgetstr ("ce", address
);
2529 tty
->TS_clr_frame
= tgetstr ("cl", address
);
2530 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
2531 AbsPosition (tty
) = tgetstr ("cm", address
);
2532 CR (tty
) = tgetstr ("cr", address
);
2533 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
2534 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
2535 RowPosition (tty
) = tgetstr ("cv", address
);
2536 tty
->TS_del_char
= tgetstr ("dc", address
);
2537 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
2538 tty
->TS_del_line
= tgetstr ("dl", address
);
2539 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
2540 tty
->TS_delete_mode
= tgetstr ("dm", address
);
2541 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
2542 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
2543 Home (tty
) = tgetstr ("ho", address
);
2544 tty
->TS_ins_char
= tgetstr ("ic", address
);
2545 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
2546 tty
->TS_insert_mode
= tgetstr ("im", address
);
2547 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
2548 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
2549 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
2550 LastLine (tty
) = tgetstr ("ll", address
);
2551 Right (tty
) = tgetstr ("nd", address
);
2552 Down (tty
) = tgetstr ("do", address
);
2554 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
2556 /* VMS puts a carriage return before each linefeed,
2557 so it is not safe to use linefeeds. */
2558 if (Down (tty
) && Down (tty
)[0] == '\n' && Down (tty
)[1] == '\0')
2561 if (tgetflag ("bs"))
2562 Left (tty
) = "\b"; /* can't possibly be longer! */
2563 else /* (Actually, "bs" is obsolete...) */
2564 Left (tty
) = tgetstr ("le", address
);
2566 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
2567 tty
->TS_pad_char
= tgetstr ("pc", address
);
2568 tty
->TS_repeat
= tgetstr ("rp", address
);
2569 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
2570 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
2571 tty
->TS_standout_mode
= tgetstr ("so", address
);
2572 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
2573 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
2574 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
2575 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
2576 Up (tty
) = tgetstr ("up", address
);
2577 tty
->TS_visible_bell
= tgetstr ("vb", address
);
2578 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
2579 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
2580 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
2581 tty
->TS_set_window
= tgetstr ("wi", address
);
2583 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
2584 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
2585 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
2586 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
2587 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
2588 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
2589 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2590 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2591 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
2593 MultiUp (tty
) = tgetstr ("UP", address
);
2594 MultiDown (tty
) = tgetstr ("DO", address
);
2595 MultiLeft (tty
) = tgetstr ("LE", address
);
2596 MultiRight (tty
) = tgetstr ("RI", address
);
2598 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2599 color because we can't switch back to the default foreground and
2601 tty
->TS_orig_pair
= tgetstr ("op", address
);
2602 if (tty
->TS_orig_pair
)
2604 tty
->TS_set_foreground
= tgetstr ("AF", address
);
2605 tty
->TS_set_background
= tgetstr ("AB", address
);
2606 if (!tty
->TS_set_foreground
)
2609 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
2610 tty
->TS_set_background
= tgetstr ("Sb", address
);
2613 tty
->TN_max_colors
= tgetnum ("Co");
2614 tty
->TN_max_pairs
= tgetnum ("pa");
2616 tty
->TN_no_color_video
= tgetnum ("NC");
2617 if (tty
->TN_no_color_video
== -1)
2618 tty
->TN_no_color_video
= 0;
2621 tty_default_color_capabilities (tty
, 1);
2623 MagicWrap (tty
) = tgetflag ("xn");
2624 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2625 the former flag imply the latter. */
2626 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
2627 display
->memory_below_frame
= tgetflag ("db");
2628 tty
->TF_hazeltine
= tgetflag ("hz");
2629 display
->must_write_spaces
= tgetflag ("in");
2630 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
2631 tty
->TF_insmode_motion
= tgetflag ("mi");
2632 tty
->TF_standout_motion
= tgetflag ("ms");
2633 tty
->TF_underscore
= tgetflag ("ul");
2634 tty
->TF_teleray
= tgetflag ("xt");
2636 term_get_fkeys (address
);
2638 /* Get frame size from system, or else from termcap. */
2641 get_tty_size (fileno (tty
->input
), &width
, &height
);
2642 FrameCols (tty
) = width
;
2643 FrameRows (tty
) = height
;
2646 if (FrameCols (tty
) <= 0)
2647 FrameCols (tty
) = tgetnum ("co");
2648 if (FrameRows (tty
) <= 0)
2649 FrameRows (tty
) = tgetnum ("li");
2651 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
2652 maybe_fatal (must_succeed
, NULL
, display
,
2653 "Screen size %dx%d is too small"
2654 "Screen size %dx%d is too small",
2655 FrameCols (tty
), FrameRows (tty
));
2657 #if 0 /* This is not used anywhere. */
2658 tty
->display
->min_padding_speed
= tgetnum ("pb");
2661 TabWidth (tty
) = tgetnum ("tw");
2664 /* These capabilities commonly use ^J.
2665 I don't know why, but sending them on VMS does not work;
2666 it causes following spaces to be lost, sometimes.
2667 For now, the simplest fix is to avoid using these capabilities ever. */
2668 if (Down (tty
) && Down (tty
)[0] == '\n')
2673 tty
->TS_bell
= "\07";
2675 if (!tty
->TS_fwd_scroll
)
2676 tty
->TS_fwd_scroll
= Down (tty
);
2678 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
2680 if (TabWidth (tty
) < 0)
2683 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2684 and newer termcap doc does not seem to say there is a default.
2685 if (!tty->Wcm->cm_tab)
2686 tty->Wcm->cm_tab = "\t";
2689 /* We don't support standout modes that use `magic cookies', so
2690 turn off any that do. */
2691 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
2693 tty
->TS_standout_mode
= 0;
2694 tty
->TS_end_standout_mode
= 0;
2696 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
2698 tty
->TS_enter_underline_mode
= 0;
2699 tty
->TS_exit_underline_mode
= 0;
2702 /* If there's no standout mode, try to use underlining instead. */
2703 if (tty
->TS_standout_mode
== 0)
2705 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
2706 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
2709 /* If no `se' string, try using a `me' string instead.
2710 If that fails, we can't use standout mode at all. */
2711 if (tty
->TS_end_standout_mode
== 0)
2713 char *s
= tgetstr ("me", address
);
2715 tty
->TS_end_standout_mode
= s
;
2717 tty
->TS_standout_mode
= 0;
2720 if (tty
->TF_teleray
)
2722 tty
->Wcm
->cm_tab
= 0;
2723 /* We can't support standout mode, because it uses magic cookies. */
2724 tty
->TS_standout_mode
= 0;
2725 /* But that means we cannot rely on ^M to go to column zero! */
2727 /* LF can't be trusted either -- can alter hpos */
2728 /* if move at column 0 thru a line with TS_standout_mode */
2732 /* Special handling for certain terminal types known to need it */
2734 if (!strcmp (terminal_type
, "supdup"))
2736 display
->memory_below_frame
= 1;
2737 tty
->Wcm
->cm_losewrap
= 1;
2739 if (!strncmp (terminal_type
, "c10", 3)
2740 || !strcmp (terminal_type
, "perq"))
2742 /* Supply a makeshift :wi string.
2743 This string is not valid in general since it works only
2744 for windows starting at the upper left corner;
2745 but that is all Emacs uses.
2747 This string works only if the frame is using
2748 the top of the video memory, because addressing is memory-relative.
2749 So first check the :ti string to see if that is true.
2751 It would be simpler if the :wi string could go in the termcap
2752 entry, but it can't because it is not fully valid.
2753 If it were in the termcap entry, it would confuse other programs. */
2754 if (!tty
->TS_set_window
)
2756 p
= tty
->TS_termcap_modes
;
2757 while (*p
&& strcmp (p
, "\033v "))
2760 tty
->TS_set_window
= "\033v%C %C %C %C ";
2762 /* Termcap entry often fails to have :in: flag */
2763 display
->must_write_spaces
= 1;
2764 /* :ti string typically fails to have \E^G! in it */
2765 /* This limits scope of insert-char to one line. */
2766 strcpy (area
, tty
->TS_termcap_modes
);
2767 strcat (area
, "\033\007!");
2768 tty
->TS_termcap_modes
= area
;
2769 area
+= strlen (area
) + 1;
2770 p
= AbsPosition (tty
);
2771 /* Change all %+ parameters to %C, to handle
2772 values above 96 correctly for the C100. */
2775 if (p
[0] == '%' && p
[1] == '+')
2781 tty
->specified_window
= FrameRows (tty
);
2783 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
2785 maybe_fatal (must_succeed
, NULL
, display
,
2786 "Terminal type \"%s\" is not powerful enough to run Emacs",
2788 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2789 It lacks the ability to position the cursor.\n\
2790 If that is not the actual type of terminal you have, use either the\n\
2791 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2792 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2795 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2796 It lacks the ability to position the cursor.\n\
2797 If that is not the actual type of terminal you have,\n\
2798 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2799 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2800 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2801 # else /* TERMCAP */
2802 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2803 It lacks the ability to position the cursor.\n\
2804 If that is not the actual type of terminal you have,\n\
2805 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2806 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2807 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2808 # endif /* TERMINFO */
2813 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
2814 maybe_fatal (must_succeed
, NULL
, display
,
2815 "Could not determine the frame size",
2816 "Could not determine the frame size");
2818 tty
->delete_in_insert_mode
2819 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
2820 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
2822 tty
->se_is_so
= (tty
->TS_standout_mode
2823 && tty
->TS_end_standout_mode
2824 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
2826 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
2828 display
->scroll_region_ok
2830 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
2832 display
->line_ins_del_ok
2833 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
2834 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
2835 || (display
->scroll_region_ok
2836 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
2838 display
->char_ins_del_ok
2839 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
2840 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
2841 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
2843 display
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
2845 init_baud_rate (fileno (tty
->input
));
2848 /* The HFT system on AIX doesn't optimize for scrolling, so it's
2849 really ugly at times. */
2850 display
->line_ins_del_ok
= 0;
2851 display
->char_ins_del_ok
= 0;
2855 tty
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
2856 init_kboard (tty
->kboard
);
2857 tty
->kboard
->next_kboard
= all_kboards
;
2858 all_kboards
= tty
->kboard
;
2859 /* Don't let the initial kboard remain current longer than necessary.
2860 That would cause problems if a file loaded on startup tries to
2861 prompt in the mini-buffer. */
2862 if (current_kboard
== initial_kboard
)
2863 current_kboard
= tty
->kboard
;
2864 tty
->kboard
->reference_count
++;
2867 /* Don't do this. I think termcap may still need the buffer. */
2868 /* xfree (buffer); */
2870 /* Init system terminal modes (RAW or CBREAK, etc.). */
2871 init_sys_modes (tty
);
2874 #endif /* not WINDOWSNT */
2877 /* Auxiliary error-handling function for term_init.
2878 Free BUFFER and delete DISPLAY, then call error or fatal
2879 with str1 or str2, respectively, according to MUST_SUCCEED. */
2882 maybe_fatal (must_succeed
, buffer
, display
, str1
, str2
, arg1
, arg2
)
2885 struct display
*display
;
2886 char *str1
, *str2
, *arg1
, *arg2
;
2892 delete_tty (display
);
2895 fatal (str2
, arg1
, arg2
);
2897 error (str1
, arg1
, arg2
);
2904 fatal (str
, arg1
, arg2
)
2905 char *str
, *arg1
, *arg2
;
2907 fprintf (stderr
, "emacs: ");
2908 fprintf (stderr
, str
, arg1
, arg2
);
2909 fprintf (stderr
, "\n");
2916 static int deleting_tty
= 0;
2919 /* Delete the given terminal device, closing all frames on it. */
2922 delete_tty (struct display
*display
)
2924 struct tty_display_info
*tty
;
2925 Lisp_Object tail
, frame
;
2930 /* We get a recursive call when we delete the last frame on this
2934 if (display
->type
!= output_termcap
)
2937 tty
= display
->display_info
.tty
;
2940 FOR_EACH_FRAME (tail
, frame
)
2942 struct frame
*f
= XFRAME (frame
);
2943 if (FRAME_LIVE_P (f
) && (!FRAME_TERMCAP_P (f
) || FRAME_TTY (f
) != tty
))
2950 error ("Attempt to delete the sole display with live frames");
2952 if (tty
== tty_list
)
2953 tty_list
= tty
->next
;
2956 struct tty_display_info
*p
;
2957 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
2961 /* This should not happen. */
2964 p
->next
= tty
->next
;
2970 FOR_EACH_FRAME (tail
, frame
)
2972 struct frame
*f
= XFRAME (frame
);
2973 if (FRAME_TERMCAP_P (f
) && FRAME_LIVE_P (f
) && FRAME_TTY (f
) == tty
)
2975 Fdelete_frame (frame
, Qt
);
2979 /* reset_sys_modes needs a valid display, so this call needs to be
2980 before delete_display. */
2981 reset_sys_modes (tty
);
2983 delete_display (display
);
2985 tty_name
= tty
->name
;
2991 delete_keyboard_wait_descriptor (fileno (tty
->input
));
2992 if (tty
->input
!= stdin
)
2993 fclose (tty
->input
);
2995 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
2996 fclose (tty
->output
);
2997 if (tty
->termscript
)
2998 fclose (tty
->termscript
);
3001 xfree (tty
->old_tty
);
3007 if (tty
->kboard
&& --tty
->kboard
->reference_count
> 0)
3010 delete_kboard (tty
->kboard
);
3013 bzero (tty
, sizeof (struct tty_display_info
));
3020 /* Initialize the tty-dependent part of frame F. The frame must
3021 already have its display initialized. */
3024 create_tty_output (struct frame
*f
)
3026 struct tty_output
*t
;
3028 if (! FRAME_TERMCAP_P (f
))
3031 t
= xmalloc (sizeof (struct tty_output
));
3032 bzero (t
, sizeof (struct tty_output
));
3034 t
->display_info
= FRAME_DISPLAY (f
)->display_info
.tty
;
3036 f
->output_data
.tty
= t
;
3039 /* Delete the tty-dependent part of frame F. */
3042 delete_tty_output (struct frame
*f
)
3044 if (! FRAME_TERMCAP_P (f
))
3047 xfree (f
->output_data
.tty
);
3053 /* Mark the pointers in the tty_display_info objects.
3054 Called by the Fgarbage_collector. */
3059 struct tty_display_info
*tty
;
3061 for (tty
= tty_list
; tty
; tty
= tty
->next
)
3064 mark_object (tty
->top_frame
);
3070 /* Create a new display object and add it to the display list. */
3073 create_display (void)
3075 struct display
*display
= (struct display
*) xmalloc (sizeof (struct display
));
3077 bzero (display
, sizeof (struct display
));
3078 display
->next_display
= display_list
;
3079 display_list
= display
;
3081 display
->id
= next_display_id
++;
3083 display
->keyboard_coding
=
3084 (struct coding_system
*) xmalloc (sizeof (struct coding_system
));
3085 display
->terminal_coding
=
3086 (struct coding_system
*) xmalloc (sizeof (struct coding_system
));
3088 setup_coding_system (Qnil
, display
->keyboard_coding
);
3089 setup_coding_system (Qnil
, display
->terminal_coding
);
3094 /* Remove a display from the display list and free its memory. */
3097 delete_display (struct display
*display
)
3099 struct display
**dp
;
3100 Lisp_Object tail
, frame
;
3102 /* Check for and close live frames that are still on this
3104 FOR_EACH_FRAME (tail
, frame
)
3106 struct frame
*f
= XFRAME (frame
);
3107 if (FRAME_LIVE_P (f
) && f
->display
== display
)
3109 Fdelete_frame (frame
, Qt
);
3113 for (dp
= &display_list
; *dp
!= display
; dp
= &(*dp
)->next_display
)
3116 *dp
= display
->next_display
;
3118 if (display
->keyboard_coding
)
3119 xfree (display
->keyboard_coding
);
3120 if (display
->terminal_coding
)
3121 xfree (display
->terminal_coding
);
3123 xfree (display
->name
);
3125 bzero (display
, sizeof (struct display
));
3129 DEFUN ("delete-display", Fdelete_display
, Sdelete_display
, 0, 2, 0,
3130 doc
: /* Delete DISPLAY by deleting all frames on it and closing the device.
3131 DISPLAY may be a display id, a frame, or nil for the display
3132 device of the current frame.
3134 Normally, you may not delete a display if all other displays are suspended,
3135 but if the second argument FORCE is non-nil, you may do so. */)
3137 Lisp_Object display
, force
;
3139 struct display
*d
, *p
;
3141 d
= get_display (display
);
3147 while (p
&& (p
== d
|| !DISPLAY_ACTIVE_P (p
)))
3148 p
= p
->next_display
;
3150 if (NILP (force
) && !p
)
3151 error ("Attempt to delete the sole active display");
3153 if (d
->delete_display_hook
)
3154 (*d
->delete_display_hook
) (d
);
3161 DEFUN ("display-live-p", Fdisplay_live_p
, Sdisplay_live_p
, 1, 1, 0,
3162 doc
: /* Return non-nil if OBJECT is a display which has not been deleted.
3163 Value is nil if OBJECT is not a live display.
3164 If object is a live display, the return value indicates what sort of
3165 output device it uses. See the documentation of `framep' for possible
3168 Displays are represented by their integer identifiers. */)
3174 if (!INTEGERP (object
))
3177 d
= get_display (object
);
3184 case output_initial
: /* The initial frame is like a termcap frame. */
3185 case output_termcap
:
3187 case output_x_window
:
3191 case output_msdos_raw
:
3200 DEFUN ("display-list", Fdisplay_list
, Sdisplay_list
, 0, 0, 0,
3201 doc
: /* Return a list of all displays.
3202 Displays are represented by their integer identifiers. */)
3205 Lisp_Object displays
= Qnil
;
3208 for (d
= display_list
; d
; d
= d
->next_display
)
3209 displays
= Fcons (make_number (d
->id
), displays
);
3217 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
3218 doc
: /* Suspend the terminal device TTY.
3219 The terminal is restored to its default state, and Emacs ceases all
3220 access to the terminal device. Frames that use the device are not
3221 deleted, but input is not read from them and if they change, their
3222 display is not updated.
3224 TTY may be a display id, a frame, or nil for the display device of the
3225 currently selected frame.
3227 This function runs `suspend-tty-functions' after suspending the
3228 device. The functions are run with one arg, the id of the suspended
3231 `suspend-tty' does nothing if it is called on an already suspended
3234 A suspended terminal device may be resumed by calling `resume-tty' on
3239 struct display
*d
= get_tty_display (tty
);
3243 error ("Unknown tty device");
3245 f
= d
->display_info
.tty
->input
;
3249 reset_sys_modes (d
->display_info
.tty
);
3251 delete_keyboard_wait_descriptor (fileno (f
));
3254 if (f
!= d
->display_info
.tty
->output
)
3255 fclose (d
->display_info
.tty
->output
);
3257 d
->display_info
.tty
->input
= 0;
3258 d
->display_info
.tty
->output
= 0;
3260 if (FRAMEP (d
->display_info
.tty
->top_frame
))
3261 FRAME_SET_VISIBLE (XFRAME (d
->display_info
.tty
->top_frame
), 0);
3263 /* Run `suspend-tty-functions'. */
3264 if (!NILP (Vrun_hooks
))
3266 Lisp_Object args
[2];
3267 args
[0] = intern ("suspend-tty-functions");
3268 args
[1] = make_number (d
->id
);
3269 Frun_hook_with_args (2, args
);
3277 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
3278 doc
: /* Resume the previously suspended terminal device TTY.
3279 The terminal is opened and reinitialized. Frames that are on the
3280 suspended display are revived.
3282 It is an error to resume a display while another display is active on
3285 This function runs `resume-tty-functions' after resuming the device.
3286 The functions are run with one arg, the id of the resumed display
3289 `resume-tty' does nothing if it is called on a device that is not
3292 TTY may be a display id, a frame, or nil for the display device of the
3293 currently selected frame. */)
3297 struct display
*d
= get_tty_display (tty
);
3301 error ("Unknown tty device");
3303 if (!d
->display_info
.tty
->input
)
3305 if (get_named_tty_display (d
->display_info
.tty
->name
))
3306 error ("Cannot resume display while another display is active on the same device");
3308 fd
= emacs_open (d
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
3310 /* XXX What if open fails? */
3312 dissociate_if_controlling_tty (fd
);
3314 d
->display_info
.tty
->output
= fdopen (fd
, "w+");
3315 d
->display_info
.tty
->input
= d
->display_info
.tty
->output
;
3317 add_keyboard_wait_descriptor (fd
);
3319 if (FRAMEP (d
->display_info
.tty
->top_frame
))
3320 FRAME_SET_VISIBLE (XFRAME (d
->display_info
.tty
->top_frame
), 1);
3322 init_sys_modes (d
->display_info
.tty
);
3324 /* Run `suspend-tty-functions'. */
3325 if (!NILP (Vrun_hooks
))
3327 Lisp_Object args
[2];
3328 args
[0] = intern ("resume-tty-functions");
3329 args
[1] = make_number (d
->id
);
3330 Frun_hook_with_args (2, args
);
3341 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
3342 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3343 This variable can be used by terminal emulator packages. */);
3345 system_uses_terminfo
= 1;
3347 system_uses_terminfo
= 0;
3350 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
3351 doc
: /* Non-nil means call this function to ring the bell.
3352 The function should accept no arguments. */);
3353 Vring_bell_function
= Qnil
;
3355 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions
,
3356 doc
: /* Functions to be run after suspending a tty.
3357 The functions are run with one argument, the name of the tty to be suspended.
3358 See `suspend-tty'. */);
3359 Vsuspend_tty_functions
= Qnil
;
3362 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions
,
3363 doc
: /* Functions to be run after resuming a tty.
3364 The functions are run with one argument, the name of the tty that was revived.
3365 See `resume-tty'. */);
3366 Vresume_tty_functions
= Qnil
;
3368 defsubr (&Stty_display_color_p
);
3369 defsubr (&Stty_display_color_cells
);
3370 defsubr (&Sdisplay_name
);
3371 defsubr (&Sdisplay_tty_type
);
3372 defsubr (&Sdisplay_controlling_tty_p
);
3373 defsubr (&Sdelete_display
);
3374 defsubr (&Sdisplay_live_p
);
3375 defsubr (&Sdisplay_list
);
3376 defsubr (&Ssuspend_tty
);
3377 defsubr (&Sresume_tty
);
3379 Fprovide (intern ("multi-tty"), Qnil
);
3385 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
3386 (do not change this comment) */