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 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
616 store them at DST. Do not write more than DST_LEN bytes. That may
617 require stopping before all SRC_LEN input glyphs have been
620 We store the number of glyphs actually converted in *CONSUMED. The
621 return value is the number of bytes store in DST. */
624 encode_terminal_code (struct coding_system
*coding
,
631 struct glyph
*src_start
= src
, *src_end
= src
+ src_len
;
632 unsigned char *dst_start
= dst
, *dst_end
= dst
+ dst_len
;
634 unsigned char workbuf
[MAX_MULTIBYTE_LENGTH
];
635 const unsigned char *buf
;
637 register int tlen
= GLYPH_TABLE_LENGTH
;
638 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
641 /* If the specified coding does any conversion, use it, otherwise use
642 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
643 because it always returns 1 if the member src_multibyte is 1. */
644 coding
= (coding
->common_flags
& CODING_REQUIRE_ENCODING_MASK
646 : &safe_terminal_coding
);
648 while (src
< src_end
)
650 /* We must skip glyphs to be padded for a wide character. */
651 if (! CHAR_GLYPH_PADDING_P (*src
))
653 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
655 if (g
< 0 || g
>= tlen
)
657 /* This glyph doesn't has an entry in Vglyph_table. */
658 if (! CHAR_VALID_P (src
->u
.ch
, 0))
662 coding
->src_multibyte
= 0;
666 len
= CHAR_STRING (src
->u
.ch
, workbuf
);
668 coding
->src_multibyte
= 1;
673 /* This glyph has an entry in Vglyph_table,
674 so process any alias before testing for simpleness. */
675 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
677 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
679 /* We set the multi-byte form of a character in G
680 (that should be an ASCII character) at
682 workbuf
[0] = FAST_GLYPH_CHAR (g
);
685 coding
->src_multibyte
= 0;
689 /* We have a string in Vglyph_table. */
690 len
= GLYPH_LENGTH (tbase
, g
);
691 buf
= GLYPH_STRING (tbase
, g
);
692 coding
->src_multibyte
= STRING_MULTIBYTE (tbase
[g
]);
696 result
= encode_coding (coding
, buf
, dst
, len
, dst_end
- dst
);
697 len
-= coding
->consumed
;
698 dst
+= coding
->produced
;
699 if (result
== CODING_FINISH_INSUFFICIENT_DST
700 || (result
== CODING_FINISH_INSUFFICIENT_SRC
701 && len
> dst_end
- dst
))
702 /* The remaining output buffer is too short. We must
703 break the loop here without increasing SRC so that the
704 next call of this function starts from the same glyph. */
709 /* This is the case that a code of the range 0200..0237
710 exists in buf. We must just write out such a code. */
711 buf
+= coding
->consumed
;
719 *consumed
= src
- src_start
;
720 return (dst
- dst_start
);
724 /* Output LEN glyphs starting at STRING at the nominal cursor position.
725 Advance the nominal cursor over the text. */
728 write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
730 if (FRAME_DISPLAY (f
)->write_glyphs_hook
)
731 (*FRAME_DISPLAY (f
)->write_glyphs_hook
) (f
, string
, len
);
734 /* An implementation of write_glyphs for termcap frames. */
737 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
739 int produced
, consumed
;
740 unsigned char conversion_buffer
[1024];
741 int conversion_buffer_size
= sizeof conversion_buffer
;
743 struct tty_display_info
*tty
= FRAME_TTY (f
);
745 turn_off_insert (tty
);
746 tty_hide_cursor (tty
);
748 /* Don't dare write in last column of bottom line, if Auto-Wrap,
749 since that would scroll the whole frame on some terminals. */
752 && curY (tty
) + 1 == FRAME_LINES (f
)
753 && (curX (tty
) + len
) == FRAME_COLS (f
))
760 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
762 FRAME_TERMINAL_CODING (f
)->mode
&= ~CODING_MODE_LAST_BLOCK
;
766 /* Identify a run of glyphs with the same face. */
767 int face_id
= string
->face_id
;
770 for (n
= 1; n
< len
; ++n
)
771 if (string
[n
].face_id
!= face_id
)
774 /* Turn appearance modes of the face of the run on. */
775 highlight_if_desired (tty
);
776 turn_on_face (f
, face_id
);
780 /* We use a fixed size (1024 bytes) of conversion buffer.
781 Usually it is sufficient, but if not, we just repeat the
783 produced
= encode_terminal_code (FRAME_TERMINAL_CODING (f
),
784 string
, conversion_buffer
,
785 n
, conversion_buffer_size
,
789 fwrite (conversion_buffer
, 1, produced
,
791 if (ferror (tty
->output
))
792 clearerr (tty
->output
);
794 fwrite (conversion_buffer
, 1, produced
,
802 /* Turn appearance modes off. */
803 turn_off_face (f
, face_id
);
804 turn_off_highlight (tty
);
807 /* We may have to output some codes to terminate the writing. */
808 if (CODING_REQUIRE_FLUSHING (FRAME_TERMINAL_CODING (f
)))
810 FRAME_TERMINAL_CODING (f
)->mode
|= CODING_MODE_LAST_BLOCK
;
811 encode_coding (FRAME_TERMINAL_CODING (f
), "",
812 conversion_buffer
, 0, conversion_buffer_size
);
813 if (FRAME_TERMINAL_CODING (f
)->produced
> 0)
815 fwrite (conversion_buffer
, 1,
816 FRAME_TERMINAL_CODING (f
)->produced
,
818 if (ferror (tty
->output
))
819 clearerr (tty
->output
);
821 fwrite (conversion_buffer
, 1,
822 FRAME_TERMINAL_CODING (f
)->produced
,
830 /* Insert LEN glyphs from START at the nominal cursor position.
832 If start is zero, insert blanks instead of a string at start */
835 insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
840 if (FRAME_DISPLAY (f
)->insert_glyphs_hook
)
841 (*FRAME_DISPLAY (f
)->insert_glyphs_hook
) (f
, start
, len
);
844 /* An implementation of insert_glyphs for termcap frames. */
847 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
850 struct glyph
*glyph
= NULL
;
852 struct tty_display_info
*tty
= FRAME_TTY (f
);
854 if (tty
->TS_ins_multi_chars
)
856 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
860 write_glyphs (f
, start
, len
);
864 turn_on_insert (tty
);
866 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
867 FRAME_TERMINAL_CODING (f
)->mode
&= ~CODING_MODE_LAST_BLOCK
;
870 int produced
, consumed
;
871 unsigned char conversion_buffer
[1024];
872 int conversion_buffer_size
= sizeof conversion_buffer
;
874 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
877 conversion_buffer
[0] = SPACEGLYPH
;
882 highlight_if_desired (tty
);
883 turn_on_face (f
, start
->face_id
);
886 /* We must open sufficient space for a character which
887 occupies more than one column. */
888 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
890 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
895 /* This is the last glyph. */
896 FRAME_TERMINAL_CODING (f
)->mode
|= CODING_MODE_LAST_BLOCK
;
898 /* The size of conversion buffer (1024 bytes) is surely
899 sufficient for just one glyph. */
900 produced
= encode_terminal_code (FRAME_TERMINAL_CODING (f
),
901 glyph
, conversion_buffer
, 1,
902 conversion_buffer_size
, &consumed
);
907 fwrite (conversion_buffer
, 1, produced
,
909 if (ferror (tty
->output
))
910 clearerr (tty
->output
);
912 fwrite (conversion_buffer
, 1, produced
,
916 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
919 turn_off_face (f
, glyph
->face_id
);
920 turn_off_highlight (tty
);
927 /* Delete N glyphs at the nominal cursor position. */
930 delete_glyphs (struct frame
*f
, int n
)
932 if (FRAME_DISPLAY (f
)->delete_glyphs_hook
)
933 (*FRAME_DISPLAY (f
)->delete_glyphs_hook
) (f
, n
);
936 /* An implementation of delete_glyphs for termcap frames. */
939 tty_delete_glyphs (struct frame
*f
, int n
)
944 struct tty_display_info
*tty
= FRAME_TTY (f
);
946 if (tty
->delete_in_insert_mode
)
948 turn_on_insert (tty
);
952 turn_off_insert (tty
);
953 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
956 if (tty
->TS_del_multi_chars
)
958 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
963 for (i
= 0; i
< n
; i
++)
964 OUTPUT1 (tty
, tty
->TS_del_char
);
965 if (!tty
->delete_in_insert_mode
)
966 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
969 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
972 ins_del_lines (struct frame
*f
, int vpos
, int n
)
974 if (FRAME_DISPLAY (f
)->ins_del_lines_hook
)
975 (*FRAME_DISPLAY (f
)->ins_del_lines_hook
) (f
, vpos
, n
);
978 /* An implementation of ins_del_lines for termcap frames. */
981 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
983 struct tty_display_info
*tty
= FRAME_TTY (f
);
984 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
985 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
986 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
988 register int i
= n
> 0 ? n
: -n
;
991 /* If the lines below the insertion are being pushed
992 into the end of the window, this is the same as clearing;
993 and we know the lines are already clear, since the matching
994 deletion has already been done. So can ignore this. */
995 /* If the lines below the deletion are blank lines coming
996 out of the end of the window, don't bother,
997 as there will be a matching inslines later that will flush them. */
998 if (FRAME_SCROLL_REGION_OK (f
)
999 && vpos
+ i
>= tty
->specified_window
)
1001 if (!FRAME_MEMORY_BELOW_FRAME (f
)
1002 && vpos
+ i
>= FRAME_LINES (f
))
1007 raw_cursor_to (f
, vpos
, 0);
1008 background_highlight (tty
);
1009 buf
= tparam (multi
, 0, 0, i
);
1015 raw_cursor_to (f
, vpos
, 0);
1016 background_highlight (tty
);
1018 OUTPUT (tty
, single
);
1019 if (tty
->TF_teleray
)
1024 set_scroll_region (f
, vpos
, tty
->specified_window
);
1026 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
1028 raw_cursor_to (f
, vpos
, 0);
1029 background_highlight (tty
);
1031 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1032 set_scroll_region (f
, 0, tty
->specified_window
);
1035 if (!FRAME_SCROLL_REGION_OK (f
)
1036 && FRAME_MEMORY_BELOW_FRAME (f
)
1039 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
1044 /* Compute cost of sending "str", in characters,
1045 not counting any line-dependent padding. */
1048 string_cost (char *str
)
1052 tputs (str
, 0, evalcost
);
1056 /* Compute cost of sending "str", in characters,
1057 counting any line-dependent padding at one line. */
1060 string_cost_one_line (char *str
)
1064 tputs (str
, 1, evalcost
);
1068 /* Compute per line amount of line-dependent padding,
1069 in tenths of characters. */
1072 per_line_cost (char *str
)
1076 tputs (str
, 0, evalcost
);
1079 tputs (str
, 10, evalcost
);
1084 /* char_ins_del_cost[n] is cost of inserting N characters.
1085 char_ins_del_cost[-n] is cost of deleting N characters.
1086 The length of this vector is based on max_frame_cols. */
1088 int *char_ins_del_vector
;
1090 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1095 calculate_ins_del_char_costs (struct frame
*f
)
1097 struct tty_display_info
*tty
= FRAME_TTY (f
);
1098 int ins_startup_cost
, del_startup_cost
;
1099 int ins_cost_per_char
, del_cost_per_char
;
1103 if (tty
->TS_ins_multi_chars
)
1105 ins_cost_per_char
= 0;
1106 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1108 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1109 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1111 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1112 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1113 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1114 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1118 ins_startup_cost
= 9999;
1119 ins_cost_per_char
= 0;
1122 if (tty
->TS_del_multi_chars
)
1124 del_cost_per_char
= 0;
1125 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1127 else if (tty
->TS_del_char
)
1129 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1130 + string_cost (tty
->TS_end_delete_mode
));
1131 if (tty
->delete_in_insert_mode
)
1132 del_startup_cost
/= 2;
1133 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1137 del_startup_cost
= 9999;
1138 del_cost_per_char
= 0;
1141 /* Delete costs are at negative offsets */
1142 p
= &char_ins_del_cost (f
)[0];
1143 for (i
= FRAME_COLS (f
); --i
>= 0;)
1144 *--p
= (del_startup_cost
+= del_cost_per_char
);
1146 /* Doing nothing is free */
1147 p
= &char_ins_del_cost (f
)[0];
1150 /* Insert costs are at positive offsets */
1151 for (i
= FRAME_COLS (f
); --i
>= 0;)
1152 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1156 calculate_costs (struct frame
*frame
)
1158 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1160 if (FRAME_TERMCAP_P (frame
))
1162 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1163 register char *f
= (tty
->TS_set_scroll_region
1164 ? tty
->TS_set_scroll_region
1165 : tty
->TS_set_scroll_region_1
);
1167 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1171 /* These variables are only used for terminal stuff. They are
1172 allocated once for the terminal frame of X-windows emacs, but not
1175 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1176 X turns off char_ins_del_ok. */
1178 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1179 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1181 if (char_ins_del_vector
!= 0)
1183 = (int *) xrealloc (char_ins_del_vector
,
1185 + 2 * max_frame_cols
* sizeof (int)));
1188 = (int *) xmalloc (sizeof (int)
1189 + 2 * max_frame_cols
* sizeof (int));
1191 bzero (char_ins_del_vector
, (sizeof (int)
1192 + 2 * max_frame_cols
* sizeof (int)));
1195 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1196 do_line_insertion_deletion_costs (frame
,
1197 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1198 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1201 do_line_insertion_deletion_costs (frame
,
1202 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1203 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1206 calculate_ins_del_char_costs (frame
);
1208 /* Don't use TS_repeat if its padding is worse than sending the chars */
1209 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1210 tty
->RPov
= string_cost (tty
->TS_repeat
);
1212 tty
->RPov
= FRAME_COLS (frame
) * 2;
1214 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1222 /* Termcap capability names that correspond directly to X keysyms.
1223 Some of these (marked "terminfo") aren't supplied by old-style
1224 (Berkeley) termcap entries. They're listed in X keysym order;
1225 except we put the keypad keys first, so that if they clash with
1226 other keys (as on the IBM PC keyboard) they get overridden.
1229 static struct fkey_table keys
[] =
1231 {"kh", "home"}, /* termcap */
1232 {"kl", "left"}, /* termcap */
1233 {"ku", "up"}, /* termcap */
1234 {"kr", "right"}, /* termcap */
1235 {"kd", "down"}, /* termcap */
1236 {"%8", "prior"}, /* terminfo */
1237 {"%5", "next"}, /* terminfo */
1238 {"@7", "end"}, /* terminfo */
1239 {"@1", "begin"}, /* terminfo */
1240 {"*6", "select"}, /* terminfo */
1241 {"%9", "print"}, /* terminfo */
1242 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1244 * "insert" --- see below
1246 {"&8", "undo"}, /* terminfo */
1247 {"%0", "redo"}, /* terminfo */
1248 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1249 {"@0", "find"}, /* terminfo */
1250 {"@2", "cancel"}, /* terminfo */
1251 {"%1", "help"}, /* terminfo */
1253 * "break" goes here, but can't be reliably intercepted with termcap
1255 {"&4", "reset"}, /* terminfo --- actually `restart' */
1257 * "system" and "user" --- no termcaps
1259 {"kE", "clearline"}, /* terminfo */
1260 {"kA", "insertline"}, /* terminfo */
1261 {"kL", "deleteline"}, /* terminfo */
1262 {"kI", "insertchar"}, /* terminfo */
1263 {"kD", "deletechar"}, /* terminfo */
1264 {"kB", "backtab"}, /* terminfo */
1266 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1268 {"@8", "kp-enter"}, /* terminfo */
1270 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1271 * "kp-multiply", "kp-add", "kp-separator",
1272 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1273 * --- no termcaps for any of these.
1275 {"K4", "kp-1"}, /* terminfo */
1277 * "kp-2" --- no termcap
1279 {"K5", "kp-3"}, /* terminfo */
1281 * "kp-4" --- no termcap
1283 {"K2", "kp-5"}, /* terminfo */
1285 * "kp-6" --- no termcap
1287 {"K1", "kp-7"}, /* terminfo */
1289 * "kp-8" --- no termcap
1291 {"K3", "kp-9"}, /* terminfo */
1293 * "kp-equal" --- no termcap
1306 static char **term_get_fkeys_arg
;
1307 static Lisp_Object
term_get_fkeys_1 ();
1309 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1310 This function scans the termcap function key sequence entries, and
1311 adds entries to Vfunction_key_map for each function key it finds. */
1314 term_get_fkeys (address
)
1317 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1318 errors during the call. The only errors should be from Fdefine_key
1319 when given a key sequence containing an invalid prefix key. If the
1320 termcap defines function keys which use a prefix that is already bound
1321 to a command by the default bindings, we should silently ignore that
1322 function key specification, rather than giving the user an error and
1323 refusing to run at all on such a terminal. */
1325 extern Lisp_Object
Fidentity ();
1326 term_get_fkeys_arg
= address
;
1327 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1335 char **address
= term_get_fkeys_arg
;
1337 /* This can happen if CANNOT_DUMP or with strange options. */
1339 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1341 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1343 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1345 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1346 Fmake_vector (make_number (1),
1347 intern (keys
[i
].name
)));
1350 /* The uses of the "k0" capability are inconsistent; sometimes it
1351 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1352 We will attempt to politely accommodate both systems by testing for
1353 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1356 char *k_semi
= tgetstr ("k;", address
);
1357 char *k0
= tgetstr ("k0", address
);
1358 char *k0_name
= "f10";
1363 /* Define f0 first, so that f10 takes precedence in case the
1364 key sequences happens to be the same. */
1365 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1366 Fmake_vector (make_number (1), intern ("f0")));
1367 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1368 Fmake_vector (make_number (1), intern ("f10")));
1371 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1372 Fmake_vector (make_number (1), intern (k0_name
)));
1375 /* Set up cookies for numbered function keys above f10. */
1377 char fcap
[3], fkey
[4];
1379 fcap
[0] = 'F'; fcap
[2] = '\0';
1380 for (i
= 11; i
< 64; i
++)
1383 fcap
[1] = '1' + i
- 11;
1385 fcap
[1] = 'A' + i
- 20;
1387 fcap
[1] = 'a' + i
- 46;
1390 char *sequence
= tgetstr (fcap
, address
);
1393 sprintf (fkey
, "f%d", i
);
1394 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1395 Fmake_vector (make_number (1),
1403 * Various mappings to try and get a better fit.
1406 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1407 if (!tgetstr (cap1, address)) \
1409 char *sequence = tgetstr (cap2, address); \
1411 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1412 Fmake_vector (make_number (1), \
1416 /* if there's no key_next keycap, map key_npage to `next' keysym */
1417 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1418 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1419 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1420 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1421 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1422 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1423 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1425 /* IBM has their own non-standard dialect of terminfo.
1426 If the standard name isn't found, try the IBM name. */
1427 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1428 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1429 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1430 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1431 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1432 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1433 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1434 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1435 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1436 #undef CONDITIONAL_REASSIGN
1443 /***********************************************************************
1444 Character Display Information
1445 ***********************************************************************/
1447 static void append_glyph
P_ ((struct it
*));
1448 static void produce_stretch_glyph
P_ ((struct it
*));
1451 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1452 terminal frames if IT->glyph_row != NULL. IT->c is the character
1453 for which to produce glyphs; IT->face_id contains the character's
1454 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1461 struct glyph
*glyph
, *end
;
1464 xassert (it
->glyph_row
);
1465 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1466 + it
->glyph_row
->used
[it
->area
]);
1467 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1470 i
< it
->pixel_width
&& glyph
< end
;
1473 glyph
->type
= CHAR_GLYPH
;
1474 glyph
->pixel_width
= 1;
1475 glyph
->u
.ch
= it
->c
;
1476 glyph
->face_id
= it
->face_id
;
1477 glyph
->padding_p
= i
> 0;
1478 glyph
->charpos
= CHARPOS (it
->position
);
1479 glyph
->object
= it
->object
;
1481 ++it
->glyph_row
->used
[it
->area
];
1487 /* Produce glyphs for the display element described by IT. *IT
1488 specifies what we want to produce a glyph for (character, image, ...),
1489 and where in the glyph matrix we currently are (glyph row and hpos).
1490 produce_glyphs fills in output fields of *IT with information such as the
1491 pixel width and height of a character, and maybe output actual glyphs at
1492 the same time if IT->glyph_row is non-null. See the explanation of
1493 struct display_iterator in dispextern.h for an overview.
1495 produce_glyphs also stores the result of glyph width, ascent
1496 etc. computations in *IT.
1498 IT->glyph_row may be null, in which case produce_glyphs does not
1499 actually fill in the glyphs. This is used in the move_* functions
1500 in xdisp.c for text width and height computations.
1502 Callers usually don't call produce_glyphs directly;
1503 instead they use the macro PRODUCE_GLYPHS. */
1509 /* If a hook is installed, let it do the work. */
1510 xassert (it
->what
== IT_CHARACTER
1511 || it
->what
== IT_COMPOSITION
1512 || it
->what
== IT_STRETCH
);
1514 if (it
->what
== IT_STRETCH
)
1516 produce_stretch_glyph (it
);
1520 /* Nothing but characters are supported on terminal frames. For a
1521 composition sequence, it->c is the first character of the
1523 xassert (it
->what
== IT_CHARACTER
1524 || it
->what
== IT_COMPOSITION
);
1526 if (it
->c
>= 040 && it
->c
< 0177)
1528 it
->pixel_width
= it
->nglyphs
= 1;
1532 else if (it
->c
== '\n')
1533 it
->pixel_width
= it
->nglyphs
= 0;
1534 else if (it
->c
== '\t')
1536 int absolute_x
= (it
->current_x
1537 + it
->continuation_lines_width
);
1539 = (((1 + absolute_x
+ it
->tab_width
- 1)
1544 /* If part of the TAB has been displayed on the previous line
1545 which is continued now, continuation_lines_width will have
1546 been incremented already by the part that fitted on the
1547 continued line. So, we will get the right number of spaces
1549 nspaces
= next_tab_x
- absolute_x
;
1556 it
->pixel_width
= it
->len
= 1;
1564 it
->pixel_width
= nspaces
;
1565 it
->nglyphs
= nspaces
;
1567 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1569 /* Coming here means that it->c is from display table, thus we
1570 must send the code as is to the terminal. Although there's
1571 no way to know how many columns it occupies on a screen, it
1572 is a good assumption that a single byte code has 1-column
1574 it
->pixel_width
= it
->nglyphs
= 1;
1580 /* A multi-byte character. The display width is fixed for all
1581 characters of the set. Some of the glyphs may have to be
1582 ignored because they are already displayed in a continued
1584 int charset
= CHAR_CHARSET (it
->c
);
1586 it
->pixel_width
= CHARSET_WIDTH (charset
);
1587 it
->nglyphs
= it
->pixel_width
;
1594 /* Advance current_x by the pixel width as a convenience for
1596 if (it
->area
== TEXT_AREA
)
1597 it
->current_x
+= it
->pixel_width
;
1598 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1599 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1603 /* Produce a stretch glyph for iterator IT. IT->object is the value
1604 of the glyph property displayed. The value must be a list
1605 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1608 1. `:width WIDTH' specifies that the space should be WIDTH *
1609 canonical char width wide. WIDTH may be an integer or floating
1612 2. `:align-to HPOS' specifies that the space should be wide enough
1613 to reach HPOS, a value in canonical character units. */
1616 produce_stretch_glyph (it
)
1619 /* (space :width WIDTH ...) */
1620 Lisp_Object prop
, plist
;
1621 int width
= 0, align_to
= -1;
1622 int zero_width_ok_p
= 0;
1625 /* List should start with `space'. */
1626 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1627 plist
= XCDR (it
->object
);
1629 /* Compute the width of the stretch. */
1630 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1631 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1633 /* Absolute width `:width WIDTH' specified and valid. */
1634 zero_width_ok_p
= 1;
1635 width
= (int)(tem
+ 0.5);
1637 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1638 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1640 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1641 align_to
= (align_to
< 0
1643 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1644 else if (align_to
< 0)
1645 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1646 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1647 zero_width_ok_p
= 1;
1650 /* Nothing specified -> width defaults to canonical char width. */
1651 width
= FRAME_COLUMN_WIDTH (it
->f
);
1653 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1656 if (width
> 0 && it
->glyph_row
)
1658 Lisp_Object o_object
= it
->object
;
1659 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1663 if (!STRINGP (object
))
1664 object
= it
->w
->buffer
;
1665 it
->object
= object
;
1667 it
->pixel_width
= it
->len
= 1;
1670 it
->object
= o_object
;
1673 it
->pixel_width
= width
;
1674 it
->nglyphs
= width
;
1678 /* Get information about special display element WHAT in an
1679 environment described by IT. WHAT is one of IT_TRUNCATION or
1680 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1681 non-null glyph_row member. This function ensures that fields like
1682 face_id, c, len of IT are left untouched. */
1685 produce_special_glyphs (it
, what
)
1687 enum display_element_type what
;
1693 temp_it
.what
= IT_CHARACTER
;
1695 temp_it
.object
= make_number (0);
1696 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1698 if (what
== IT_CONTINUATION
)
1700 /* Continuation glyph. */
1702 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1703 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1705 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it
->dp
)));
1706 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1711 produce_glyphs (&temp_it
);
1712 it
->pixel_width
= temp_it
.pixel_width
;
1713 it
->nglyphs
= temp_it
.pixel_width
;
1715 else if (what
== IT_TRUNCATION
)
1717 /* Truncation glyph. */
1719 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1720 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1722 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it
->dp
)));
1723 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1728 produce_glyphs (&temp_it
);
1729 it
->pixel_width
= temp_it
.pixel_width
;
1730 it
->nglyphs
= temp_it
.pixel_width
;
1738 /***********************************************************************
1740 ***********************************************************************/
1742 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1743 one of the enumerators from enum no_color_bit, or a bit set built
1744 from them. Some display attributes may not be used together with
1745 color; the termcap capability `NC' specifies which ones. */
1747 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1748 (tty->TN_max_colors > 0 \
1749 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1752 /* Turn appearances of face FACE_ID on tty frame F on. */
1755 turn_on_face (f
, face_id
)
1759 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1760 long fg
= face
->foreground
;
1761 long bg
= face
->background
;
1762 struct tty_display_info
*tty
= FRAME_TTY (f
);
1764 /* Do this first because TS_end_standout_mode may be the same
1765 as TS_exit_attribute_mode, which turns all appearances off. */
1766 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1768 if (tty
->TN_max_colors
> 0)
1770 if (fg
>= 0 && bg
>= 0)
1772 /* If the terminal supports colors, we can set them
1773 below without using reverse video. The face's fg
1774 and bg colors are set as they should appear on
1775 the screen, i.e. they take the inverse-video'ness
1776 of the face already into account. */
1778 else if (inverse_video
)
1780 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1781 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1782 toggle_highlight (tty
);
1786 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1787 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1788 toggle_highlight (tty
);
1793 /* If we can't display colors, use reverse video
1794 if the face specifies that. */
1797 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1798 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1799 toggle_highlight (tty
);
1803 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1804 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1805 toggle_highlight (tty
);
1810 if (face
->tty_bold_p
)
1812 if (MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1813 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1815 else if (face
->tty_dim_p
)
1816 if (MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1817 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1819 /* Alternate charset and blinking not yet used. */
1820 if (face
->tty_alt_charset_p
1821 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1822 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1824 if (face
->tty_blinking_p
1825 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1826 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1828 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1829 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1831 if (tty
->TN_max_colors
> 0)
1835 if (fg
>= 0 && tty
->TS_set_foreground
)
1837 p
= tparam (tty
->TS_set_foreground
, NULL
, 0, (int) fg
);
1842 if (bg
>= 0 && tty
->TS_set_background
)
1844 p
= tparam (tty
->TS_set_background
, NULL
, 0, (int) bg
);
1852 /* Turn off appearances of face FACE_ID on tty frame F. */
1855 turn_off_face (f
, face_id
)
1859 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1860 struct tty_display_info
*tty
= FRAME_TTY (f
);
1862 xassert (face
!= NULL
);
1864 if (tty
->TS_exit_attribute_mode
)
1866 /* Capability "me" will turn off appearance modes double-bright,
1867 half-bright, reverse-video, standout, underline. It may or
1868 may not turn off alt-char-mode. */
1869 if (face
->tty_bold_p
1871 || face
->tty_reverse_p
1872 || face
->tty_alt_charset_p
1873 || face
->tty_blinking_p
1874 || face
->tty_underline_p
)
1876 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
1877 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
1878 tty
->standout_mode
= 0;
1881 if (face
->tty_alt_charset_p
)
1882 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1886 /* If we don't have "me" we can only have those appearances
1887 that have exit sequences defined. */
1888 if (face
->tty_alt_charset_p
)
1889 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1891 if (face
->tty_underline_p
)
1892 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
1895 /* Switch back to default colors. */
1896 if (tty
->TN_max_colors
> 0
1897 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
1898 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
1899 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
1900 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
1901 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
1905 /* Return non-zero if the terminal on frame F supports all of the
1906 capabilities in CAPS simultaneously, with foreground and background
1907 colors FG and BG. */
1910 tty_capable_p (tty
, caps
, fg
, bg
)
1911 struct tty_display_info
*tty
;
1913 unsigned long fg
, bg
;
1915 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
1916 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
1919 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
1920 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
1921 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
1922 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
1923 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
1924 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
1930 /* Return non-zero if the terminal is capable to display colors. */
1932 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
1934 doc
: /* Return non-nil if the tty device that DISPLAY uses can display colors. */)
1936 Lisp_Object display
;
1938 struct display
*d
= get_tty_display (display
);
1942 return d
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
1945 /* Return the number of supported colors. */
1946 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
1947 Stty_display_color_cells
, 0, 1, 0,
1948 doc
: /* Return the number of colors supported by the tty device that DISPLAY uses. */)
1950 Lisp_Object display
;
1952 struct display
*d
= get_tty_display (display
);
1954 return make_number (0);
1956 return make_number (d
->display_info
.tty
->TN_max_colors
);
1961 /* Save or restore the default color-related capabilities of this
1964 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
1967 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
1968 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
1972 if (default_orig_pair
)
1973 xfree (default_orig_pair
);
1974 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
1976 if (default_set_foreground
)
1977 xfree (default_set_foreground
);
1978 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
1981 if (default_set_background
)
1982 xfree (default_set_background
);
1983 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
1986 default_max_colors
= tty
->TN_max_colors
;
1987 default_max_pairs
= tty
->TN_max_pairs
;
1988 default_no_color_video
= tty
->TN_no_color_video
;
1992 tty
->TS_orig_pair
= default_orig_pair
;
1993 tty
->TS_set_foreground
= default_set_foreground
;
1994 tty
->TS_set_background
= default_set_background
;
1995 tty
->TN_max_colors
= default_max_colors
;
1996 tty
->TN_max_pairs
= default_max_pairs
;
1997 tty
->TN_no_color_video
= default_no_color_video
;
2001 /* Setup one of the standard tty color schemes according to MODE.
2002 MODE's value is generally the number of colors which we want to
2003 support; zero means set up for the default capabilities, the ones
2004 we saw at term_init time; -1 means turn off color support. */
2006 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2008 /* Canonicalize all negative values of MODE. */
2014 case -1: /* no colors at all */
2015 tty
->TN_max_colors
= 0;
2016 tty
->TN_max_pairs
= 0;
2017 tty
->TN_no_color_video
= 0;
2018 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2020 case 0: /* default colors, if any */
2022 tty_default_color_capabilities (tty
, 0);
2024 case 8: /* 8 standard ANSI colors */
2025 tty
->TS_orig_pair
= "\033[0m";
2027 tty
->TS_set_foreground
= "\033[3%p1%dm";
2028 tty
->TS_set_background
= "\033[4%p1%dm";
2030 tty
->TS_set_foreground
= "\033[3%dm";
2031 tty
->TS_set_background
= "\033[4%dm";
2033 tty
->TN_max_colors
= 8;
2034 tty
->TN_max_pairs
= 64;
2035 tty
->TN_no_color_video
= 0;
2041 set_tty_color_mode (f
, val
)
2045 Lisp_Object color_mode_spec
, current_mode_spec
;
2046 Lisp_Object color_mode
, current_mode
;
2048 extern Lisp_Object Qtty_color_mode
;
2049 Lisp_Object tty_color_mode_alist
;
2051 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2058 if (NILP (tty_color_mode_alist
))
2059 color_mode_spec
= Qnil
;
2061 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2063 if (CONSP (color_mode_spec
))
2064 color_mode
= XCDR (color_mode_spec
);
2069 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2071 if (CONSP (current_mode_spec
))
2072 current_mode
= XCDR (current_mode_spec
);
2074 current_mode
= Qnil
;
2075 if (INTEGERP (color_mode
))
2076 mode
= XINT (color_mode
);
2078 mode
= 0; /* meaning default */
2079 if (INTEGERP (current_mode
))
2080 old_mode
= XINT (current_mode
);
2084 if (mode
!= old_mode
)
2086 tty_setup_colors (FRAME_TTY (f
), mode
);
2087 /* This recomputes all the faces given the new color
2089 call0 (intern ("tty-set-up-initial-frame-faces"));
2094 #endif /* !WINDOWSNT */
2098 /* Return the display object specified by DISPLAY. DISPLAY may be a
2099 display id, a frame, or nil for the display device of the current
2103 get_display (Lisp_Object display
)
2106 display
= selected_frame
;
2108 if (! INTEGERP (display
) && ! FRAMEP (display
))
2111 if (INTEGERP (display
))
2115 for (d
= display_list
; d
; d
= d
->next_display
)
2117 if (d
->id
== XINT (display
))
2122 else if (FRAMEP (display
))
2124 return FRAME_DISPLAY (XFRAME (display
));
2129 /* Return the tty display object specified by DISPLAY. */
2131 static struct display
*
2132 get_tty_display (Lisp_Object display
)
2134 struct display
*d
= get_display (display
);
2136 if (d
&& d
->type
== output_initial
)
2139 if (d
&& d
->type
!= output_termcap
)
2141 #if 0 /* XXX We need a predicate as the first argument; find one. */
2142 wrong_type_argument ("Not a termcap display", display
);
2143 #else /* Until we fix the wrong_type_argument call above, simply throw
2145 error ("DISPLAY is not a termcap display");
2152 /* Return the active termcap display that uses the tty device with the
2153 given name. If NAME is NULL, return the display corresponding to
2154 our controlling terminal.
2156 This function ignores suspended displays.
2158 Returns NULL if the named terminal device is not opened. */
2161 get_named_tty_display (name
)
2166 for (d
= display_list
; d
; d
= d
->next_display
) {
2167 if (d
->type
== output_termcap
2168 && ((d
->display_info
.tty
->name
== 0 && name
== 0)
2169 || (name
&& d
->display_info
.tty
->name
2170 && !strcmp (d
->display_info
.tty
->name
, name
)))
2171 && DISPLAY_ACTIVE_P (d
))
2180 DEFUN ("display-name", Fdisplay_name
, Sdisplay_name
, 0, 1, 0,
2181 doc
: /* Return the name of the device that DISPLAY uses.
2182 It is not guaranteed that the returned value is unique among opened displays.
2184 DISPLAY can be a display, a frame, or nil (meaning the selected
2185 frame's display). */)
2187 Lisp_Object display
;
2189 struct display
*d
= get_display (display
);
2192 wrong_type_argument (Qdisplay_live_p
, display
);
2195 return build_string (d
->name
);
2200 DEFUN ("display-tty-type", Fdisplay_tty_type
, Sdisplay_tty_type
, 0, 1, 0,
2201 doc
: /* Return the type of the TTY device that DISPLAY uses. */)
2203 Lisp_Object display
;
2205 struct display
*d
= get_display (display
);
2208 wrong_type_argument (Qdisplay_live_p
, display
);
2209 if (d
->type
!= output_termcap
)
2210 error ("Display %d is not a termcap display", d
->id
);
2212 if (d
->display_info
.tty
->type
)
2213 return build_string (d
->display_info
.tty
->type
);
2218 DEFUN ("display-controlling-tty-p", Fdisplay_controlling_tty_p
, Sdisplay_controlling_tty_p
, 0, 1, 0,
2219 doc
: /* Return non-nil if DISPLAY is on the controlling tty of the Emacs process. */)
2221 Lisp_Object display
;
2223 struct display
*d
= get_display (display
);
2226 wrong_type_argument (Qdisplay_live_p
, display
);
2228 if (d
->type
!= output_termcap
|| d
->display_info
.tty
->name
)
2235 /***********************************************************************
2237 ***********************************************************************/
2239 /* Create the bootstrap display device for the initial frame.
2240 Returns a display of type output_initial. */
2243 init_initial_display (void)
2245 if (initialized
|| display_list
|| tty_list
)
2248 initial_display
= create_display ();
2249 initial_display
->type
= output_initial
;
2250 initial_display
->name
= xstrdup ("initial_display");
2252 initial_display
->delete_display_hook
= &delete_initial_display
;
2253 /* All other hooks are NULL. */
2255 return initial_display
;
2258 /* Deletes the bootstrap display device.
2259 Called through delete_display_hook. */
2262 delete_initial_display (struct display
*display
)
2264 if (display
!= initial_display
)
2267 delete_display (display
);
2268 initial_display
= NULL
;
2271 /* Drop the controlling terminal if fd is the same device. */
2273 dissociate_if_controlling_tty (int fd
)
2276 EMACS_GET_TTY_PGRP (fd
, &pgid
); /* If tcgetpgrp succeeds, fd is the ctty. */
2279 #if defined (USG) && !defined (BSD_PGRPS)
2281 no_controlling_tty
= 1;
2283 #ifdef TIOCNOTTY /* Try BSD ioctls. */
2284 sigblock (sigmask (SIGTTOU
));
2285 fd
= emacs_open ("/dev/tty", O_RDWR
, 0);
2286 if (fd
!= -1 && ioctl (fd
, TIOCNOTTY
, 0) != -1)
2288 no_controlling_tty
= 1;
2292 sigunblock (sigmask (SIGTTOU
));
2294 /* Unknown system. */
2296 #endif /* ! TIOCNOTTY */
2301 /* Create a termcap display on the tty device with the given name and
2304 If NAME is NULL, then use the controlling tty, i.e., stdin/stdout.
2305 Otherwise NAME should be a path to the tty device file,
2308 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
2310 If MUST_SUCCEED is true, then all errors are fatal. */
2313 term_init (char *name
, char *terminal_type
, int must_succeed
)
2316 char **address
= &area
;
2317 char *buffer
= NULL
;
2318 int buffer_size
= 4096;
2321 struct tty_display_info
*tty
;
2322 struct display
*display
;
2324 static void maybe_fatal();
2327 maybe_fatal (must_succeed
, 0, 0,
2328 "Unknown terminal type",
2329 "Unknown terminal type");
2331 /* If we already have an active display on the given device, use that.
2332 If all displays are suspended, create a new one instead. */
2333 /* XXX Perhaps this should be made explicit by having term_init
2334 always create a new display and separating display and frame
2335 creation on Lisp level. */
2336 display
= get_named_tty_display (name
);
2340 display
= create_display ();
2341 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
2342 bzero (tty
, sizeof (struct tty_display_info
));
2343 tty
->next
= tty_list
;
2346 display
->type
= output_termcap
;
2347 display
->display_info
.tty
= tty
;
2348 tty
->display
= display
;
2350 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
2353 display
->rif
= 0; /* ttys don't support window-based redisplay. */
2355 display
->cursor_to_hook
= &tty_cursor_to
;
2356 display
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
2358 display
->clear_to_end_hook
= &tty_clear_to_end
;
2359 display
->clear_frame_hook
= &tty_clear_frame
;
2360 display
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
2362 display
->ins_del_lines_hook
= &tty_ins_del_lines
;
2364 display
->insert_glyphs_hook
= &tty_insert_glyphs
;
2365 display
->write_glyphs_hook
= &tty_write_glyphs
;
2366 display
->delete_glyphs_hook
= &tty_delete_glyphs
;
2368 display
->ring_bell_hook
= &tty_ring_bell
;
2370 display
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
2371 display
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
2372 display
->update_begin_hook
= 0; /* Not needed. */
2373 display
->update_end_hook
= &tty_update_end
;
2374 display
->set_terminal_window_hook
= &tty_set_terminal_window
;
2376 display
->mouse_position_hook
= 0; /* Not needed. */
2377 display
->frame_rehighlight_hook
= 0; /* Not needed. */
2378 display
->frame_raise_lower_hook
= 0; /* Not needed. */
2380 display
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
2381 display
->condemn_scroll_bars_hook
= 0; /* Not needed. */
2382 display
->redeem_scroll_bar_hook
= 0; /* Not needed. */
2383 display
->judge_scroll_bars_hook
= 0; /* Not needed. */
2385 display
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
2386 display
->frame_up_to_date_hook
= 0; /* Not needed. */
2388 display
->delete_frame_hook
= &delete_tty_output
;
2389 display
->delete_display_hook
= &delete_tty
;
2396 #ifdef O_IGNORE_CTTY
2397 /* Open the terminal device. Don't recognize it as our
2398 controlling terminal, and don't make it the controlling tty
2399 if we don't have one at the moment. */
2400 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
2402 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
2403 defined on Hurd. On other systems, we need to dissociate
2404 ourselves from the controlling tty when we want to open a
2405 frame on the same terminal. */
2407 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
2409 #endif /* O_IGNORE_CTTY */
2413 delete_tty (display
);
2414 error ("Could not open file: %s", name
);
2419 error ("Not a tty device: %s", name
);
2422 dissociate_if_controlling_tty (fd
);
2424 file
= fdopen (fd
, "w+");
2425 tty
->name
= xstrdup (name
);
2426 display
->name
= xstrdup (name
);
2432 if (no_controlling_tty
)
2434 /* Opening a frame on stdout is unsafe if we have
2435 disconnected our controlling terminal. */
2436 error ("There is no controlling terminal any more");
2439 display
->name
= xstrdup (ttyname (0));
2441 tty
->output
= stdout
;
2444 tty
->type
= xstrdup (terminal_type
);
2446 add_keyboard_wait_descriptor (fileno (tty
->input
));
2449 initialize_w32_display ();
2453 area
= (char *) xmalloc (2044);
2455 FrameRows (tty
) = FRAME_LINES (f
); /* XXX */
2456 FrameCols (tty
) = FRAME_COLS (f
); /* XXX */
2457 tty
->specified_window
= FRAME_LINES (f
); /* XXX */
2459 tty
->display
->delete_in_insert_mode
= 1;
2462 display
->scroll_region_ok
= 0;
2464 /* Seems to insert lines when it's not supposed to, messing
2465 up the display. In doing a trace, it didn't seem to be
2466 called much, so I don't think we're losing anything by
2468 display
->line_ins_del_ok
= 0;
2469 display
->char_ins_del_ok
= 1;
2473 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0; /* XXX */
2474 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
; /* XXX */
2475 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2478 #else /* not WINDOWSNT */
2482 buffer
= (char *) xmalloc (buffer_size
);
2484 /* On some systems, tgetent tries to access the controlling
2486 sigblock (sigmask (SIGTTOU
));
2487 status
= tgetent (buffer
, terminal_type
);
2488 sigunblock (sigmask (SIGTTOU
));
2493 maybe_fatal (must_succeed
, buffer
, display
,
2494 "Cannot open terminfo database file",
2495 "Cannot open terminfo database file");
2497 maybe_fatal (must_succeed
, buffer
, display
,
2498 "Cannot open termcap database file",
2499 "Cannot open termcap database file");
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 TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2514 maybe_fatal (must_succeed
, buffer
, display
,
2515 "Terminal type %s is not defined",
2516 "Terminal type %s is not defined.\n\
2517 If that is not the actual type of terminal you have,\n\
2518 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2519 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2520 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2526 if (strlen (buffer
) >= buffer_size
)
2528 buffer_size
= strlen (buffer
);
2530 area
= (char *) xmalloc (buffer_size
);
2532 tty
->TS_ins_line
= tgetstr ("al", address
);
2533 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
2534 tty
->TS_bell
= tgetstr ("bl", address
);
2535 BackTab (tty
) = tgetstr ("bt", address
);
2536 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
2537 tty
->TS_clr_line
= tgetstr ("ce", address
);
2538 tty
->TS_clr_frame
= tgetstr ("cl", address
);
2539 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
2540 AbsPosition (tty
) = tgetstr ("cm", address
);
2541 CR (tty
) = tgetstr ("cr", address
);
2542 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
2543 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
2544 RowPosition (tty
) = tgetstr ("cv", address
);
2545 tty
->TS_del_char
= tgetstr ("dc", address
);
2546 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
2547 tty
->TS_del_line
= tgetstr ("dl", address
);
2548 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
2549 tty
->TS_delete_mode
= tgetstr ("dm", address
);
2550 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
2551 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
2552 Home (tty
) = tgetstr ("ho", address
);
2553 tty
->TS_ins_char
= tgetstr ("ic", address
);
2554 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
2555 tty
->TS_insert_mode
= tgetstr ("im", address
);
2556 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
2557 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
2558 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
2559 LastLine (tty
) = tgetstr ("ll", address
);
2560 Right (tty
) = tgetstr ("nd", address
);
2561 Down (tty
) = tgetstr ("do", address
);
2563 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
2565 /* VMS puts a carriage return before each linefeed,
2566 so it is not safe to use linefeeds. */
2567 if (Down (tty
) && Down (tty
)[0] == '\n' && Down (tty
)[1] == '\0')
2570 if (tgetflag ("bs"))
2571 Left (tty
) = "\b"; /* can't possibly be longer! */
2572 else /* (Actually, "bs" is obsolete...) */
2573 Left (tty
) = tgetstr ("le", address
);
2575 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
2576 tty
->TS_pad_char
= tgetstr ("pc", address
);
2577 tty
->TS_repeat
= tgetstr ("rp", address
);
2578 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
2579 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
2580 tty
->TS_standout_mode
= tgetstr ("so", address
);
2581 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
2582 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
2583 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
2584 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
2585 Up (tty
) = tgetstr ("up", address
);
2586 tty
->TS_visible_bell
= tgetstr ("vb", address
);
2587 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
2588 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
2589 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
2590 tty
->TS_set_window
= tgetstr ("wi", address
);
2592 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
2593 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
2594 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
2595 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
2596 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
2597 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
2598 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2599 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2600 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
2602 MultiUp (tty
) = tgetstr ("UP", address
);
2603 MultiDown (tty
) = tgetstr ("DO", address
);
2604 MultiLeft (tty
) = tgetstr ("LE", address
);
2605 MultiRight (tty
) = tgetstr ("RI", address
);
2607 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2608 color because we can't switch back to the default foreground and
2610 tty
->TS_orig_pair
= tgetstr ("op", address
);
2611 if (tty
->TS_orig_pair
)
2613 tty
->TS_set_foreground
= tgetstr ("AF", address
);
2614 tty
->TS_set_background
= tgetstr ("AB", address
);
2615 if (!tty
->TS_set_foreground
)
2618 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
2619 tty
->TS_set_background
= tgetstr ("Sb", address
);
2622 tty
->TN_max_colors
= tgetnum ("Co");
2623 tty
->TN_max_pairs
= tgetnum ("pa");
2625 tty
->TN_no_color_video
= tgetnum ("NC");
2626 if (tty
->TN_no_color_video
== -1)
2627 tty
->TN_no_color_video
= 0;
2630 tty_default_color_capabilities (tty
, 1);
2632 MagicWrap (tty
) = tgetflag ("xn");
2633 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2634 the former flag imply the latter. */
2635 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
2636 display
->memory_below_frame
= tgetflag ("db");
2637 tty
->TF_hazeltine
= tgetflag ("hz");
2638 display
->must_write_spaces
= tgetflag ("in");
2639 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
2640 tty
->TF_insmode_motion
= tgetflag ("mi");
2641 tty
->TF_standout_motion
= tgetflag ("ms");
2642 tty
->TF_underscore
= tgetflag ("ul");
2643 tty
->TF_teleray
= tgetflag ("xt");
2645 term_get_fkeys (address
);
2647 /* Get frame size from system, or else from termcap. */
2650 get_tty_size (fileno (tty
->input
), &width
, &height
);
2651 FrameCols (tty
) = width
;
2652 FrameRows (tty
) = height
;
2655 if (FrameCols (tty
) <= 0)
2656 FrameCols (tty
) = tgetnum ("co");
2657 if (FrameRows (tty
) <= 0)
2658 FrameRows (tty
) = tgetnum ("li");
2660 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
2661 maybe_fatal (must_succeed
, NULL
, display
,
2662 "Screen size %dx%d is too small"
2663 "Screen size %dx%d is too small",
2664 FrameCols (tty
), FrameRows (tty
));
2666 #if 0 /* This is not used anywhere. */
2667 tty
->display
->min_padding_speed
= tgetnum ("pb");
2670 TabWidth (tty
) = tgetnum ("tw");
2673 /* These capabilities commonly use ^J.
2674 I don't know why, but sending them on VMS does not work;
2675 it causes following spaces to be lost, sometimes.
2676 For now, the simplest fix is to avoid using these capabilities ever. */
2677 if (Down (tty
) && Down (tty
)[0] == '\n')
2682 tty
->TS_bell
= "\07";
2684 if (!tty
->TS_fwd_scroll
)
2685 tty
->TS_fwd_scroll
= Down (tty
);
2687 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
2689 if (TabWidth (tty
) < 0)
2692 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2693 and newer termcap doc does not seem to say there is a default.
2694 if (!tty->Wcm->cm_tab)
2695 tty->Wcm->cm_tab = "\t";
2698 /* We don't support standout modes that use `magic cookies', so
2699 turn off any that do. */
2700 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
2702 tty
->TS_standout_mode
= 0;
2703 tty
->TS_end_standout_mode
= 0;
2705 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
2707 tty
->TS_enter_underline_mode
= 0;
2708 tty
->TS_exit_underline_mode
= 0;
2711 /* If there's no standout mode, try to use underlining instead. */
2712 if (tty
->TS_standout_mode
== 0)
2714 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
2715 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
2718 /* If no `se' string, try using a `me' string instead.
2719 If that fails, we can't use standout mode at all. */
2720 if (tty
->TS_end_standout_mode
== 0)
2722 char *s
= tgetstr ("me", address
);
2724 tty
->TS_end_standout_mode
= s
;
2726 tty
->TS_standout_mode
= 0;
2729 if (tty
->TF_teleray
)
2731 tty
->Wcm
->cm_tab
= 0;
2732 /* We can't support standout mode, because it uses magic cookies. */
2733 tty
->TS_standout_mode
= 0;
2734 /* But that means we cannot rely on ^M to go to column zero! */
2736 /* LF can't be trusted either -- can alter hpos */
2737 /* if move at column 0 thru a line with TS_standout_mode */
2741 /* Special handling for certain terminal types known to need it */
2743 if (!strcmp (terminal_type
, "supdup"))
2745 display
->memory_below_frame
= 1;
2746 tty
->Wcm
->cm_losewrap
= 1;
2748 if (!strncmp (terminal_type
, "c10", 3)
2749 || !strcmp (terminal_type
, "perq"))
2751 /* Supply a makeshift :wi string.
2752 This string is not valid in general since it works only
2753 for windows starting at the upper left corner;
2754 but that is all Emacs uses.
2756 This string works only if the frame is using
2757 the top of the video memory, because addressing is memory-relative.
2758 So first check the :ti string to see if that is true.
2760 It would be simpler if the :wi string could go in the termcap
2761 entry, but it can't because it is not fully valid.
2762 If it were in the termcap entry, it would confuse other programs. */
2763 if (!tty
->TS_set_window
)
2765 p
= tty
->TS_termcap_modes
;
2766 while (*p
&& strcmp (p
, "\033v "))
2769 tty
->TS_set_window
= "\033v%C %C %C %C ";
2771 /* Termcap entry often fails to have :in: flag */
2772 display
->must_write_spaces
= 1;
2773 /* :ti string typically fails to have \E^G! in it */
2774 /* This limits scope of insert-char to one line. */
2775 strcpy (area
, tty
->TS_termcap_modes
);
2776 strcat (area
, "\033\007!");
2777 tty
->TS_termcap_modes
= area
;
2778 area
+= strlen (area
) + 1;
2779 p
= AbsPosition (tty
);
2780 /* Change all %+ parameters to %C, to handle
2781 values above 96 correctly for the C100. */
2784 if (p
[0] == '%' && p
[1] == '+')
2790 tty
->specified_window
= FrameRows (tty
);
2792 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
2794 maybe_fatal (must_succeed
, NULL
, display
,
2795 "Terminal type \"%s\" is not powerful enough to run Emacs",
2797 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2798 It lacks the ability to position the cursor.\n\
2799 If that is not the actual type of terminal you have, use either the\n\
2800 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2801 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2804 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2805 It lacks the ability to position the cursor.\n\
2806 If that is not the actual type of terminal you have,\n\
2807 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2808 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2809 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2810 # else /* TERMCAP */
2811 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2812 It lacks the ability to position the cursor.\n\
2813 If that is not the actual type of terminal you have,\n\
2814 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2815 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2816 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2817 # endif /* TERMINFO */
2822 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
2823 maybe_fatal (must_succeed
, NULL
, display
,
2824 "Could not determine the frame size",
2825 "Could not determine the frame size");
2827 tty
->delete_in_insert_mode
2828 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
2829 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
2831 tty
->se_is_so
= (tty
->TS_standout_mode
2832 && tty
->TS_end_standout_mode
2833 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
2835 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
2837 display
->scroll_region_ok
2839 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
2841 display
->line_ins_del_ok
2842 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
2843 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
2844 || (display
->scroll_region_ok
2845 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
2847 display
->char_ins_del_ok
2848 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
2849 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
2850 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
2852 display
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
2854 init_baud_rate (fileno (tty
->input
));
2857 /* The HFT system on AIX doesn't optimize for scrolling, so it's
2858 really ugly at times. */
2859 display
->line_ins_del_ok
= 0;
2860 display
->char_ins_del_ok
= 0;
2864 tty
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
2865 init_kboard (tty
->kboard
);
2866 tty
->kboard
->next_kboard
= all_kboards
;
2867 all_kboards
= tty
->kboard
;
2868 /* Don't let the initial kboard remain current longer than necessary.
2869 That would cause problems if a file loaded on startup tries to
2870 prompt in the mini-buffer. */
2871 if (current_kboard
== initial_kboard
)
2872 current_kboard
= tty
->kboard
;
2873 tty
->kboard
->reference_count
++;
2876 /* Don't do this. I think termcap may still need the buffer. */
2877 /* xfree (buffer); */
2879 /* Init system terminal modes (RAW or CBREAK, etc.). */
2880 init_sys_modes (tty
);
2883 #endif /* not WINDOWSNT */
2886 /* Auxiliary error-handling function for term_init.
2887 Free BUFFER and delete DISPLAY, then call error or fatal
2888 with str1 or str2, respectively, according to MUST_SUCCEED. */
2891 maybe_fatal (must_succeed
, buffer
, display
, str1
, str2
, arg1
, arg2
)
2894 struct display
*display
;
2895 char *str1
, *str2
, *arg1
, *arg2
;
2901 delete_tty (display
);
2904 fatal (str2
, arg1
, arg2
);
2906 error (str1
, arg1
, arg2
);
2913 fatal (str
, arg1
, arg2
)
2914 char *str
, *arg1
, *arg2
;
2916 fprintf (stderr
, "emacs: ");
2917 fprintf (stderr
, str
, arg1
, arg2
);
2918 fprintf (stderr
, "\n");
2925 static int deleting_tty
= 0;
2928 /* Delete the given terminal device, closing all frames on it. */
2931 delete_tty (struct display
*display
)
2933 struct tty_display_info
*tty
;
2934 Lisp_Object tail
, frame
;
2939 /* We get a recursive call when we delete the last frame on this
2943 if (display
->type
!= output_termcap
)
2946 tty
= display
->display_info
.tty
;
2949 FOR_EACH_FRAME (tail
, frame
)
2951 struct frame
*f
= XFRAME (frame
);
2952 if (FRAME_LIVE_P (f
) && (!FRAME_TERMCAP_P (f
) || FRAME_TTY (f
) != tty
))
2959 error ("Attempt to delete the sole display with live frames");
2961 if (tty
== tty_list
)
2962 tty_list
= tty
->next
;
2965 struct tty_display_info
*p
;
2966 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
2970 /* This should not happen. */
2973 p
->next
= tty
->next
;
2979 FOR_EACH_FRAME (tail
, frame
)
2981 struct frame
*f
= XFRAME (frame
);
2982 if (FRAME_TERMCAP_P (f
) && FRAME_LIVE_P (f
) && FRAME_TTY (f
) == tty
)
2984 Fdelete_frame (frame
, Qt
);
2988 /* reset_sys_modes needs a valid display, so this call needs to be
2989 before delete_display. */
2990 reset_sys_modes (tty
);
2992 delete_display (display
);
2994 tty_name
= tty
->name
;
3000 delete_keyboard_wait_descriptor (fileno (tty
->input
));
3001 if (tty
->input
!= stdin
)
3002 fclose (tty
->input
);
3004 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
3005 fclose (tty
->output
);
3006 if (tty
->termscript
)
3007 fclose (tty
->termscript
);
3010 xfree (tty
->old_tty
);
3016 if (tty
->kboard
&& --tty
->kboard
->reference_count
> 0)
3019 delete_kboard (tty
->kboard
);
3022 bzero (tty
, sizeof (struct tty_display_info
));
3029 /* Initialize the tty-dependent part of frame F. The frame must
3030 already have its display initialized. */
3033 create_tty_output (struct frame
*f
)
3035 struct tty_output
*t
;
3037 if (! FRAME_TERMCAP_P (f
))
3040 t
= xmalloc (sizeof (struct tty_output
));
3041 bzero (t
, sizeof (struct tty_output
));
3043 t
->display_info
= FRAME_DISPLAY (f
)->display_info
.tty
;
3045 f
->output_data
.tty
= t
;
3048 /* Delete the tty-dependent part of frame F. */
3051 delete_tty_output (struct frame
*f
)
3053 if (! FRAME_TERMCAP_P (f
))
3056 xfree (f
->output_data
.tty
);
3062 /* Mark the pointers in the tty_display_info objects.
3063 Called by the Fgarbage_collector. */
3068 struct tty_display_info
*tty
;
3070 for (tty
= tty_list
; tty
; tty
= tty
->next
)
3073 mark_object (tty
->top_frame
);
3079 /* Create a new display object and add it to the display list. */
3082 create_display (void)
3084 struct display
*display
= (struct display
*) xmalloc (sizeof (struct display
));
3086 bzero (display
, sizeof (struct display
));
3087 display
->next_display
= display_list
;
3088 display_list
= display
;
3090 display
->id
= next_display_id
++;
3092 display
->keyboard_coding
=
3093 (struct coding_system
*) xmalloc (sizeof (struct coding_system
));
3094 display
->terminal_coding
=
3095 (struct coding_system
*) xmalloc (sizeof (struct coding_system
));
3097 setup_coding_system (Qnil
, display
->keyboard_coding
);
3098 setup_coding_system (Qnil
, display
->terminal_coding
);
3103 /* Remove a display from the display list and free its memory. */
3106 delete_display (struct display
*display
)
3108 struct display
**dp
;
3109 Lisp_Object tail
, frame
;
3111 /* Check for and close live frames that are still on this
3113 FOR_EACH_FRAME (tail
, frame
)
3115 struct frame
*f
= XFRAME (frame
);
3116 if (FRAME_LIVE_P (f
) && f
->display
== display
)
3118 Fdelete_frame (frame
, Qt
);
3122 for (dp
= &display_list
; *dp
!= display
; dp
= &(*dp
)->next_display
)
3125 *dp
= display
->next_display
;
3127 if (display
->keyboard_coding
)
3128 xfree (display
->keyboard_coding
);
3129 if (display
->terminal_coding
)
3130 xfree (display
->terminal_coding
);
3132 xfree (display
->name
);
3134 bzero (display
, sizeof (struct display
));
3138 DEFUN ("delete-display", Fdelete_display
, Sdelete_display
, 0, 2, 0,
3139 doc
: /* Delete DISPLAY by deleting all frames on it and closing the device.
3140 DISPLAY may be a display id, a frame, or nil for the display
3141 device of the current frame.
3143 Normally, you may not delete a display if all other displays are suspended,
3144 but if the second argument FORCE is non-nil, you may do so. */)
3146 Lisp_Object display
, force
;
3148 struct display
*d
, *p
;
3150 d
= get_display (display
);
3156 while (p
&& (p
== d
|| !DISPLAY_ACTIVE_P (p
)))
3157 p
= p
->next_display
;
3159 if (NILP (force
) && !p
)
3160 error ("Attempt to delete the sole active display");
3162 if (d
->delete_display_hook
)
3163 (*d
->delete_display_hook
) (d
);
3170 DEFUN ("display-live-p", Fdisplay_live_p
, Sdisplay_live_p
, 1, 1, 0,
3171 doc
: /* Return non-nil if OBJECT is a display which has not been deleted.
3172 Value is nil if OBJECT is not a live display.
3173 If object is a live display, the return value indicates what sort of
3174 output device it uses. See the documentation of `framep' for possible
3177 Displays are represented by their integer identifiers. */)
3183 if (!INTEGERP (object
))
3186 d
= get_display (object
);
3193 case output_initial
: /* The initial frame is like a termcap frame. */
3194 case output_termcap
:
3196 case output_x_window
:
3200 case output_msdos_raw
:
3209 DEFUN ("display-list", Fdisplay_list
, Sdisplay_list
, 0, 0, 0,
3210 doc
: /* Return a list of all displays.
3211 Displays are represented by their integer identifiers. */)
3214 Lisp_Object displays
= Qnil
;
3217 for (d
= display_list
; d
; d
= d
->next_display
)
3218 displays
= Fcons (make_number (d
->id
), displays
);
3226 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
3227 doc
: /* Suspend the terminal device TTY.
3228 The terminal is restored to its default state, and Emacs ceases all
3229 access to the terminal device. Frames that use the device are not
3230 deleted, but input is not read from them and if they change, their
3231 display is not updated.
3233 TTY may be a display id, a frame, or nil for the display device of the
3234 currently selected frame.
3236 This function runs `suspend-tty-functions' after suspending the
3237 device. The functions are run with one arg, the id of the suspended
3240 `suspend-tty' does nothing if it is called on an already suspended
3243 A suspended terminal device may be resumed by calling `resume-tty' on
3248 struct display
*d
= get_tty_display (tty
);
3252 error ("Unknown tty device");
3254 f
= d
->display_info
.tty
->input
;
3258 reset_sys_modes (d
->display_info
.tty
);
3260 delete_keyboard_wait_descriptor (fileno (f
));
3263 if (f
!= d
->display_info
.tty
->output
)
3264 fclose (d
->display_info
.tty
->output
);
3266 d
->display_info
.tty
->input
= 0;
3267 d
->display_info
.tty
->output
= 0;
3269 if (FRAMEP (d
->display_info
.tty
->top_frame
))
3270 FRAME_SET_VISIBLE (XFRAME (d
->display_info
.tty
->top_frame
), 0);
3272 /* Run `suspend-tty-functions'. */
3273 if (!NILP (Vrun_hooks
))
3275 Lisp_Object args
[2];
3276 args
[0] = intern ("suspend-tty-functions");
3277 args
[1] = make_number (d
->id
);
3278 Frun_hook_with_args (2, args
);
3286 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
3287 doc
: /* Resume the previously suspended terminal device TTY.
3288 The terminal is opened and reinitialized. Frames that are on the
3289 suspended display are revived.
3291 It is an error to resume a display while another display is active on
3294 This function runs `resume-tty-functions' after resuming the device.
3295 The functions are run with one arg, the id of the resumed display
3298 `resume-tty' does nothing if it is called on a device that is not
3301 TTY may be a display id, a frame, or nil for the display device of the
3302 currently selected frame. */)
3306 struct display
*d
= get_tty_display (tty
);
3310 error ("Unknown tty device");
3312 if (!d
->display_info
.tty
->input
)
3314 if (get_named_tty_display (d
->display_info
.tty
->name
))
3315 error ("Cannot resume display while another display is active on the same device");
3317 fd
= emacs_open (d
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
3319 /* XXX What if open fails? */
3321 dissociate_if_controlling_tty (fd
);
3323 d
->display_info
.tty
->output
= fdopen (fd
, "w+");
3324 d
->display_info
.tty
->input
= d
->display_info
.tty
->output
;
3326 add_keyboard_wait_descriptor (fd
);
3328 if (FRAMEP (d
->display_info
.tty
->top_frame
))
3329 FRAME_SET_VISIBLE (XFRAME (d
->display_info
.tty
->top_frame
), 1);
3331 init_sys_modes (d
->display_info
.tty
);
3333 /* Run `suspend-tty-functions'. */
3334 if (!NILP (Vrun_hooks
))
3336 Lisp_Object args
[2];
3337 args
[0] = intern ("resume-tty-functions");
3338 args
[1] = make_number (d
->id
);
3339 Frun_hook_with_args (2, args
);
3350 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
3351 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3352 This variable can be used by terminal emulator packages. */);
3354 system_uses_terminfo
= 1;
3356 system_uses_terminfo
= 0;
3359 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
3360 doc
: /* Non-nil means call this function to ring the bell.
3361 The function should accept no arguments. */);
3362 Vring_bell_function
= Qnil
;
3364 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions
,
3365 doc
: /* Functions to be run after suspending a tty.
3366 The functions are run with one argument, the name of the tty to be suspended.
3367 See `suspend-tty'. */);
3368 Vsuspend_tty_functions
= Qnil
;
3371 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions
,
3372 doc
: /* Functions to be run after resuming a tty.
3373 The functions are run with one argument, the name of the tty that was revived.
3374 See `resume-tty'. */);
3375 Vresume_tty_functions
= Qnil
;
3377 defsubr (&Stty_display_color_p
);
3378 defsubr (&Stty_display_color_cells
);
3379 defsubr (&Sdisplay_name
);
3380 defsubr (&Sdisplay_tty_type
);
3381 defsubr (&Sdisplay_controlling_tty_p
);
3382 defsubr (&Sdelete_display
);
3383 defsubr (&Sdisplay_live_p
);
3384 defsubr (&Sdisplay_list
);
3385 defsubr (&Ssuspend_tty
);
3386 defsubr (&Sresume_tty
);
3388 Fprovide (intern ("multi-tty"), Qnil
);
3394 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
3395 (do not change this comment) */