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>. */
39 #include "termhooks.h"
40 #include "dispextern.h"
44 /* For now, don't try to include termcap.h. On some systems,
45 configure finds a non-standard termcap.h that the main build
48 #if defined HAVE_TERMCAP_H && 0
51 extern void tputs
P_ ((const char *, int, int (*)(int)));
52 extern int tgetent
P_ ((char *, const char *));
53 extern int tgetflag
P_ ((char *id
));
54 extern int tgetnum
P_ ((char *id
));
69 static void turn_on_face
P_ ((struct frame
*, int face_id
));
70 static void turn_off_face
P_ ((struct frame
*, int face_id
));
71 static void tty_show_cursor
P_ ((struct tty_display_info
*));
72 static void tty_hide_cursor
P_ ((struct tty_display_info
*));
74 void delete_initial_display
P_ ((struct display
*));
75 void delete_tty
P_ ((struct display
*));
76 void create_tty_output
P_ ((struct frame
*));
77 void delete_tty_output
P_ ((struct frame
*));
79 #define OUTPUT(tty, a) \
80 emacs_tputs ((tty), a, \
81 (int) (FRAME_LINES (XFRAME (selected_frame)) \
85 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
86 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
88 #define OUTPUT_IF(tty, a) \
91 emacs_tputs ((tty), a, \
92 (int) (FRAME_LINES (XFRAME (selected_frame)) \
97 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
99 /* Function to use to ring the bell. */
101 Lisp_Object Vring_bell_function
;
103 /* Functions to call after a tty was deleted. */
104 Lisp_Object Vdelete_tty_after_functions
;
106 /* Chain of all displays currently in use. */
107 struct display
*display_list
;
109 /* The initial display device, created by initial_term_init. */
110 struct display
*initial_display
;
112 /* Chain of all tty device parameters. */
113 struct tty_display_info
*tty_list
;
115 /* Nonzero means no need to redraw the entire frame on resuming a
116 suspended Emacs. This is useful on terminals with multiple
117 pages, where one page is used for Emacs and another for all
119 int no_redraw_on_reenter
;
121 Lisp_Object Qframe_tty_name
, Qframe_tty_type
;
125 /* Meaning of bits in no_color_video. Each bit set means that the
126 corresponding attribute cannot be combined with colors. */
130 NC_STANDOUT
= 1 << 0,
131 NC_UNDERLINE
= 1 << 1,
138 NC_ALT_CHARSET
= 1 << 8
143 /* The largest frame width in any call to calculate_costs. */
147 /* The largest frame height in any call to calculate_costs. */
151 /* Frame currently being redisplayed; 0 if not currently redisplaying.
152 (Direct output does not count). */
154 FRAME_PTR updating_frame
;
156 /* Provided for lisp packages. */
158 static int system_uses_terminfo
;
162 extern char *tgetstr ();
166 /* We aren't X windows, but we aren't termcap either. This makes me
167 uncertain as to what value to use for frame.output_method. For
168 this file, we'll define FRAME_TERMCAP_P to be zero so that our
169 output hooks get called instead of the termcap functions. Probably
170 the best long-term solution is to define an output_windows_nt... */
172 #undef FRAME_TERMCAP_P
173 #define FRAME_TERMCAP_P(_f_) 0
174 #endif /* WINDOWSNT */
179 struct frame
*f
= (updating_frame
181 : XFRAME (selected_frame
));
183 if (!NILP (Vring_bell_function
))
185 Lisp_Object function
;
187 /* Temporarily set the global variable to nil
188 so that if we get an error, it stays nil
189 and we don't call it over and over.
191 We don't specbind it, because that would carefully
192 restore the bad value if there's an error
193 and make the loop of errors happen anyway. */
195 function
= Vring_bell_function
;
196 Vring_bell_function
= Qnil
;
200 Vring_bell_function
= function
;
202 else if (FRAME_DISPLAY (f
)->ring_bell_hook
)
203 (*FRAME_DISPLAY (f
)->ring_bell_hook
) ();
209 struct frame
*f
= (updating_frame
211 : XFRAME (selected_frame
));
213 struct tty_display_info
*tty
= FRAME_TTY (f
);
215 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
216 ? tty
->TS_visible_bell
220 void tty_set_terminal_modes (struct display
*display
)
222 struct tty_display_info
*tty
= display
->display_info
.tty
;
224 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
225 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
226 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
230 void tty_reset_terminal_modes (struct display
*display
)
232 struct tty_display_info
*tty
= display
->display_info
.tty
;
234 turn_off_highlight (tty
);
235 turn_off_insert (tty
);
236 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
237 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
238 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
239 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
240 /* Output raw CR so kernel can track the cursor hpos. */
250 if (FRAME_DISPLAY (f
)->update_begin_hook
)
251 (*FRAME_DISPLAY (f
)->update_begin_hook
) (f
);
258 if (FRAME_DISPLAY (f
)->update_end_hook
)
259 (*FRAME_DISPLAY (f
)->update_end_hook
) (f
);
260 updating_frame
= NULL
;
264 tty_update_end (struct frame
*f
)
266 struct tty_display_info
*tty
= FRAME_TTY (f
);
268 if (!XWINDOW (selected_window
)->cursor_off_p
)
269 tty_show_cursor (tty
);
270 turn_off_insert (tty
);
271 background_highlight (tty
);
275 set_terminal_window (size
)
278 struct frame
*f
= (updating_frame
280 : XFRAME (selected_frame
));
282 if (FRAME_DISPLAY (f
)->set_terminal_window_hook
)
283 (*FRAME_DISPLAY (f
)->set_terminal_window_hook
) (size
);
287 tty_set_terminal_window (int size
)
289 struct frame
*f
= (updating_frame
291 : XFRAME (selected_frame
));
293 struct tty_display_info
*tty
= FRAME_TTY (f
);
295 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
296 if (FRAME_SCROLL_REGION_OK (f
))
297 set_scroll_region (0, tty
->specified_window
);
301 set_scroll_region (start
, stop
)
305 struct frame
*f
= (updating_frame
307 : XFRAME (selected_frame
));
309 struct tty_display_info
*tty
= FRAME_TTY (f
);
311 if (tty
->TS_set_scroll_region
)
312 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
313 else if (tty
->TS_set_scroll_region_1
)
314 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
315 FRAME_LINES (f
), start
,
316 FRAME_LINES (f
) - stop
,
319 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
328 turn_on_insert (struct tty_display_info
*tty
)
330 if (!tty
->insert_mode
)
331 OUTPUT (tty
, tty
->TS_insert_mode
);
332 tty
->insert_mode
= 1;
336 turn_off_insert (struct tty_display_info
*tty
)
338 if (tty
->insert_mode
)
339 OUTPUT (tty
, tty
->TS_end_insert_mode
);
340 tty
->insert_mode
= 0;
343 /* Handle highlighting. */
346 turn_off_highlight (struct tty_display_info
*tty
)
348 if (tty
->standout_mode
)
349 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
350 tty
->standout_mode
= 0;
354 turn_on_highlight (struct tty_display_info
*tty
)
356 if (!tty
->standout_mode
)
357 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
358 tty
->standout_mode
= 1;
362 toggle_highlight (struct tty_display_info
*tty
)
364 if (tty
->standout_mode
)
365 turn_off_highlight (tty
);
367 turn_on_highlight (tty
);
371 /* Make cursor invisible. */
374 tty_hide_cursor (struct tty_display_info
*tty
)
376 if (tty
->cursor_hidden
== 0)
378 tty
->cursor_hidden
= 1;
379 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
384 /* Ensure that cursor is visible. */
387 tty_show_cursor (struct tty_display_info
*tty
)
389 if (tty
->cursor_hidden
)
391 tty
->cursor_hidden
= 0;
392 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
393 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
398 /* Set standout mode to the state it should be in for
399 empty space inside windows. What this is,
400 depends on the user option inverse-video. */
403 background_highlight (struct tty_display_info
*tty
)
406 turn_on_highlight (tty
);
408 turn_off_highlight (tty
);
411 /* Set standout mode to the mode specified for the text to be output. */
414 highlight_if_desired (struct tty_display_info
*tty
)
417 turn_on_highlight (tty
);
419 turn_off_highlight (tty
);
423 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
424 frame-relative coordinates. */
427 cursor_to (vpos
, hpos
)
430 struct frame
*f
= (updating_frame
432 : XFRAME (selected_frame
));
434 if (FRAME_DISPLAY (f
)->cursor_to_hook
)
435 (*FRAME_DISPLAY (f
)->cursor_to_hook
) (vpos
, hpos
);
439 tty_cursor_to (int vpos
, int hpos
)
441 struct frame
*f
= (updating_frame
443 : XFRAME (selected_frame
));
445 struct tty_display_info
*tty
= FRAME_TTY (f
);
447 /* Detect the case where we are called from reset_sys_modes
448 and the costs have never been calculated. Do nothing. */
449 if (! tty
->costs_set
)
452 if (curY (tty
) == vpos
453 && curX (tty
) == hpos
)
455 if (!tty
->TF_standout_motion
)
456 background_highlight (tty
);
457 if (!tty
->TF_insmode_motion
)
458 turn_off_insert (tty
);
459 cmgoto (tty
, vpos
, hpos
);
462 /* Similar but don't take any account of the wasted characters. */
465 raw_cursor_to (row
, col
)
468 struct frame
*f
= (updating_frame
470 : XFRAME (selected_frame
));
472 if (FRAME_DISPLAY (f
)->raw_cursor_to_hook
)
473 (*FRAME_DISPLAY (f
)->raw_cursor_to_hook
) (row
, col
);
477 tty_raw_cursor_to (int row
, int col
)
479 struct frame
*f
= (updating_frame
481 : XFRAME (selected_frame
));
483 struct tty_display_info
*tty
= FRAME_TTY (f
);
485 if (curY (tty
) == row
486 && curX (tty
) == col
)
488 if (!tty
->TF_standout_motion
)
489 background_highlight (tty
);
490 if (!tty
->TF_insmode_motion
)
491 turn_off_insert (tty
);
492 cmgoto (tty
, row
, col
);
495 /* Erase operations */
497 /* clear from cursor to end of frame */
501 struct frame
*f
= (updating_frame
503 : XFRAME (selected_frame
));
505 if (FRAME_DISPLAY (f
)->clear_to_end_hook
)
506 (*FRAME_DISPLAY (f
)->clear_to_end_hook
) ();
510 tty_clear_to_end (void)
513 struct frame
*f
= (updating_frame
515 : XFRAME (selected_frame
));
516 struct tty_display_info
*tty
= FRAME_TTY (f
);
518 if (tty
->TS_clr_to_bottom
)
520 background_highlight (tty
);
521 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
525 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
528 clear_end_of_line (FRAME_COLS (f
));
533 /* Clear entire frame */
538 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
540 if (FRAME_DISPLAY (f
)->clear_frame_hook
)
541 (*FRAME_DISPLAY (f
)->clear_frame_hook
) ();
547 struct frame
*f
= (updating_frame
549 : XFRAME (selected_frame
));
551 struct tty_display_info
*tty
= FRAME_TTY (f
);
553 if (tty
->TS_clr_frame
)
555 background_highlight (tty
);
556 OUTPUT (tty
, tty
->TS_clr_frame
);
566 /* Clear from cursor to end of line.
567 Assume that the line is already clear starting at column first_unused_hpos.
569 Note that the cursor may be moved, on terminals lacking a `ce' string. */
572 clear_end_of_line (first_unused_hpos
)
573 int first_unused_hpos
;
575 struct frame
*f
= (updating_frame
577 : XFRAME (selected_frame
));
579 if (FRAME_DISPLAY (f
)->clear_end_of_line_hook
)
580 (*FRAME_DISPLAY (f
)->clear_end_of_line_hook
) (first_unused_hpos
);
584 tty_clear_end_of_line (int first_unused_hpos
)
587 struct frame
*f
= (updating_frame
589 : XFRAME (selected_frame
));
590 struct tty_display_info
*tty
= FRAME_TTY (f
);
592 /* Detect the case where we are called from reset_sys_modes
593 and the costs have never been calculated. Do nothing. */
594 if (! tty
->costs_set
)
597 if (curX (tty
) >= first_unused_hpos
)
599 background_highlight (tty
);
600 if (tty
->TS_clr_line
)
602 OUTPUT1 (tty
, tty
->TS_clr_line
);
605 { /* have to do it the hard way */
606 turn_off_insert (tty
);
608 /* Do not write in last row last col with Auto-wrap on. */
610 && curY (tty
) == FrameRows (tty
) - 1
611 && first_unused_hpos
== FrameCols (tty
))
614 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
616 if (TTY_TERMSCRIPT (tty
))
617 fputc (' ', TTY_TERMSCRIPT (tty
));
618 fputc (' ', TTY_OUTPUT (tty
));
620 cmplus (tty
, first_unused_hpos
- curX (tty
));
624 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
625 store them at DST. Do not write more than DST_LEN bytes. That may
626 require stopping before all SRC_LEN input glyphs have been
629 We store the number of glyphs actually converted in *CONSUMED. The
630 return value is the number of bytes store in DST. */
633 encode_terminal_code (src
, dst
, src_len
, dst_len
, consumed
)
637 int dst_len
, *consumed
;
639 struct glyph
*src_start
= src
, *src_end
= src
+ src_len
;
640 unsigned char *dst_start
= dst
, *dst_end
= dst
+ dst_len
;
642 unsigned char workbuf
[MAX_MULTIBYTE_LENGTH
];
643 const unsigned char *buf
;
645 register int tlen
= GLYPH_TABLE_LENGTH
;
646 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
648 struct coding_system
*coding
;
650 /* If terminal_coding does any conversion, use it, otherwise use
651 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
652 because it always return 1 if the member src_multibyte is 1. */
653 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
655 : &safe_terminal_coding
);
657 while (src
< src_end
)
659 /* We must skip glyphs to be padded for a wide character. */
660 if (! CHAR_GLYPH_PADDING_P (*src
))
662 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
664 if (g
< 0 || g
>= tlen
)
666 /* This glyph doesn't has an entry in Vglyph_table. */
667 if (! CHAR_VALID_P (src
->u
.ch
, 0))
671 coding
->src_multibyte
= 0;
675 len
= CHAR_STRING (src
->u
.ch
, workbuf
);
677 coding
->src_multibyte
= 1;
682 /* This glyph has an entry in Vglyph_table,
683 so process any alias before testing for simpleness. */
684 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
686 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
688 /* We set the multi-byte form of a character in G
689 (that should be an ASCII character) at
691 workbuf
[0] = FAST_GLYPH_CHAR (g
);
694 coding
->src_multibyte
= 0;
698 /* We have a string in Vglyph_table. */
699 len
= GLYPH_LENGTH (tbase
, g
);
700 buf
= GLYPH_STRING (tbase
, g
);
701 coding
->src_multibyte
= STRING_MULTIBYTE (tbase
[g
]);
705 result
= encode_coding (coding
, buf
, dst
, len
, dst_end
- dst
);
706 len
-= coding
->consumed
;
707 dst
+= coding
->produced
;
708 if (result
== CODING_FINISH_INSUFFICIENT_DST
709 || (result
== CODING_FINISH_INSUFFICIENT_SRC
710 && len
> dst_end
- dst
))
711 /* The remaining output buffer is too short. We must
712 break the loop here without increasing SRC so that the
713 next call of this function starts from the same glyph. */
718 /* This is the case that a code of the range 0200..0237
719 exists in buf. We must just write out such a code. */
720 buf
+= coding
->consumed
;
728 *consumed
= src
- src_start
;
729 return (dst
- dst_start
);
734 write_glyphs (string
, len
)
735 register struct glyph
*string
;
738 struct frame
*f
= (updating_frame
740 : XFRAME (selected_frame
));
742 if (FRAME_DISPLAY (f
)->write_glyphs_hook
)
743 (*FRAME_DISPLAY (f
)->write_glyphs_hook
) (string
, len
);
747 tty_write_glyphs (struct glyph
*string
, int len
)
749 int produced
, consumed
;
750 unsigned char conversion_buffer
[1024];
751 int conversion_buffer_size
= sizeof conversion_buffer
;
753 struct frame
*f
= (updating_frame
755 : XFRAME (selected_frame
));
757 struct tty_display_info
*tty
= FRAME_TTY (f
);
759 turn_off_insert (tty
);
760 tty_hide_cursor (tty
);
762 /* Don't dare write in last column of bottom line, if Auto-Wrap,
763 since that would scroll the whole frame on some terminals. */
766 && curY (tty
) + 1 == FRAME_LINES (f
)
767 && (curX (tty
) + len
) == FRAME_COLS (f
))
774 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
776 terminal_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
);
794 /* We use a fixed size (1024 bytes) of conversion buffer.
795 Usually it is sufficient, but if not, we just repeat the
797 produced
= encode_terminal_code (string
, conversion_buffer
,
798 n
, conversion_buffer_size
,
802 fwrite (conversion_buffer
, 1, produced
,
804 if (ferror (TTY_OUTPUT (tty
)))
805 clearerr (TTY_OUTPUT (tty
));
806 if (TTY_TERMSCRIPT (tty
))
807 fwrite (conversion_buffer
, 1, produced
,
808 TTY_TERMSCRIPT (tty
));
815 /* Turn appearance modes off. */
816 turn_off_face (f
, face_id
);
817 turn_off_highlight (tty
);
820 /* We may have to output some codes to terminate the writing. */
821 if (CODING_REQUIRE_FLUSHING (&terminal_coding
))
823 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
824 encode_coding (&terminal_coding
, "", conversion_buffer
,
825 0, conversion_buffer_size
);
826 if (terminal_coding
.produced
> 0)
828 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
830 if (ferror (TTY_OUTPUT (tty
)))
831 clearerr (TTY_OUTPUT (tty
));
832 if (TTY_TERMSCRIPT (tty
))
833 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
834 TTY_TERMSCRIPT (tty
));
841 /* If start is zero, insert blanks instead of a string at start */
844 insert_glyphs (start
, len
)
845 register struct glyph
*start
;
848 struct frame
*f
= (updating_frame
850 : XFRAME (selected_frame
));
855 if (FRAME_DISPLAY (f
)->insert_glyphs_hook
)
856 (*FRAME_DISPLAY (f
)->insert_glyphs_hook
) (start
, len
);
860 tty_insert_glyphs (struct glyph
*start
, int len
)
863 struct glyph
*glyph
= NULL
;
864 struct frame
*f
= (updating_frame
866 : XFRAME (selected_frame
));
868 struct tty_display_info
*tty
= FRAME_TTY (f
);
870 if (tty
->TS_ins_multi_chars
)
872 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
876 write_glyphs (start
, len
);
880 turn_on_insert (tty
);
882 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
883 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
886 int produced
, consumed
;
887 unsigned char conversion_buffer
[1024];
888 int conversion_buffer_size
= sizeof conversion_buffer
;
890 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
893 conversion_buffer
[0] = SPACEGLYPH
;
898 highlight_if_desired (tty
);
899 turn_on_face (f
, start
->face_id
);
902 /* We must open sufficient space for a character which
903 occupies more than one column. */
904 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
906 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
911 /* This is the last glyph. */
912 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
914 /* The size of conversion buffer (1024 bytes) is surely
915 sufficient for just one glyph. */
916 produced
= encode_terminal_code (glyph
, conversion_buffer
, 1,
917 conversion_buffer_size
, &consumed
);
922 fwrite (conversion_buffer
, 1, produced
,
924 if (ferror (TTY_OUTPUT (tty
)))
925 clearerr (TTY_OUTPUT (tty
));
926 if (TTY_TERMSCRIPT (tty
))
927 fwrite (conversion_buffer
, 1, produced
,
928 TTY_TERMSCRIPT (tty
));
931 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
934 turn_off_face (f
, glyph
->face_id
);
935 turn_off_highlight (tty
);
946 struct frame
*f
= (updating_frame
948 : XFRAME (selected_frame
));
950 if (FRAME_DISPLAY (f
)->delete_glyphs_hook
)
951 (*FRAME_DISPLAY (f
)->delete_glyphs_hook
) (n
);
955 tty_delete_glyphs (int n
)
959 struct frame
*f
= (updating_frame
961 : XFRAME (selected_frame
));
963 struct tty_display_info
*tty
= FRAME_TTY (f
);
965 if (tty
->delete_in_insert_mode
)
967 turn_on_insert (tty
);
971 turn_off_insert (tty
);
972 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
975 if (tty
->TS_del_multi_chars
)
977 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
982 for (i
= 0; i
< n
; i
++)
983 OUTPUT1 (tty
, tty
->TS_del_char
);
984 if (!tty
->delete_in_insert_mode
)
985 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
988 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
991 ins_del_lines (vpos
, n
)
994 struct frame
*f
= (updating_frame
996 : XFRAME (selected_frame
));
998 if (FRAME_DISPLAY (f
)->ins_del_lines_hook
)
999 (*FRAME_DISPLAY (f
)->ins_del_lines_hook
) (vpos
, n
);
1003 tty_ins_del_lines (int vpos
, int n
)
1005 struct frame
*f
= (updating_frame
1007 : XFRAME (selected_frame
));
1009 struct tty_display_info
*tty
= FRAME_TTY (f
);
1010 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
1011 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
1012 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
1014 register int i
= n
> 0 ? n
: -n
;
1017 /* If the lines below the insertion are being pushed
1018 into the end of the window, this is the same as clearing;
1019 and we know the lines are already clear, since the matching
1020 deletion has already been done. So can ignore this. */
1021 /* If the lines below the deletion are blank lines coming
1022 out of the end of the window, don't bother,
1023 as there will be a matching inslines later that will flush them. */
1024 if (FRAME_SCROLL_REGION_OK (f
)
1025 && vpos
+ i
>= tty
->specified_window
)
1027 if (!FRAME_MEMORY_BELOW_FRAME (f
)
1028 && vpos
+ i
>= FRAME_LINES (f
))
1033 raw_cursor_to (vpos
, 0);
1034 background_highlight (tty
);
1035 buf
= tparam (multi
, 0, 0, i
);
1041 raw_cursor_to (vpos
, 0);
1042 background_highlight (tty
);
1044 OUTPUT (tty
, single
);
1045 if (tty
->TF_teleray
)
1050 set_scroll_region (vpos
, tty
->specified_window
);
1052 raw_cursor_to (tty
->specified_window
- 1, 0);
1054 raw_cursor_to (vpos
, 0);
1055 background_highlight (tty
);
1057 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1058 set_scroll_region (0, tty
->specified_window
);
1061 if (!FRAME_SCROLL_REGION_OK (f
)
1062 && FRAME_MEMORY_BELOW_FRAME (f
)
1065 cursor_to (FRAME_LINES (f
) + n
, 0);
1070 /* Compute cost of sending "str", in characters,
1071 not counting any line-dependent padding. */
1079 tputs (str
, 0, evalcost
);
1083 /* Compute cost of sending "str", in characters,
1084 counting any line-dependent padding at one line. */
1087 string_cost_one_line (str
)
1092 tputs (str
, 1, evalcost
);
1096 /* Compute per line amount of line-dependent padding,
1097 in tenths of characters. */
1105 tputs (str
, 0, evalcost
);
1108 tputs (str
, 10, evalcost
);
1113 /* char_ins_del_cost[n] is cost of inserting N characters.
1114 char_ins_del_cost[-n] is cost of deleting N characters.
1115 The length of this vector is based on max_frame_cols. */
1117 int *char_ins_del_vector
;
1119 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1124 calculate_ins_del_char_costs (f
)
1127 struct tty_display_info
*tty
= FRAME_TTY (f
);
1128 int ins_startup_cost
, del_startup_cost
;
1129 int ins_cost_per_char
, del_cost_per_char
;
1133 if (tty
->TS_ins_multi_chars
)
1135 ins_cost_per_char
= 0;
1136 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1138 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1139 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1141 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1142 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1143 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1144 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1148 ins_startup_cost
= 9999;
1149 ins_cost_per_char
= 0;
1152 if (tty
->TS_del_multi_chars
)
1154 del_cost_per_char
= 0;
1155 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1157 else if (tty
->TS_del_char
)
1159 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1160 + string_cost (tty
->TS_end_delete_mode
));
1161 if (tty
->delete_in_insert_mode
)
1162 del_startup_cost
/= 2;
1163 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1167 del_startup_cost
= 9999;
1168 del_cost_per_char
= 0;
1171 /* Delete costs are at negative offsets */
1172 p
= &char_ins_del_cost (f
)[0];
1173 for (i
= FRAME_COLS (f
); --i
>= 0;)
1174 *--p
= (del_startup_cost
+= del_cost_per_char
);
1176 /* Doing nothing is free */
1177 p
= &char_ins_del_cost (f
)[0];
1180 /* Insert costs are at positive offsets */
1181 for (i
= FRAME_COLS (f
); --i
>= 0;)
1182 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1186 calculate_costs (frame
)
1189 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1191 if (FRAME_TERMCAP_P (frame
))
1193 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1194 register char *f
= (tty
->TS_set_scroll_region
1195 ? tty
->TS_set_scroll_region
1196 : tty
->TS_set_scroll_region_1
);
1198 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1202 /* These variables are only used for terminal stuff. They are
1203 allocated once for the terminal frame of X-windows emacs, but not
1206 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1207 X turns off char_ins_del_ok. */
1209 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1210 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1212 if (char_ins_del_vector
!= 0)
1214 = (int *) xrealloc (char_ins_del_vector
,
1216 + 2 * max_frame_cols
* sizeof (int)));
1219 = (int *) xmalloc (sizeof (int)
1220 + 2 * max_frame_cols
* sizeof (int));
1222 bzero (char_ins_del_vector
, (sizeof (int)
1223 + 2 * max_frame_cols
* sizeof (int)));
1226 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1227 do_line_insertion_deletion_costs (frame
,
1228 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1229 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1232 do_line_insertion_deletion_costs (frame
,
1233 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1234 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1237 calculate_ins_del_char_costs (frame
);
1239 /* Don't use TS_repeat if its padding is worse than sending the chars */
1240 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1241 tty
->RPov
= string_cost (tty
->TS_repeat
);
1243 tty
->RPov
= FRAME_COLS (frame
) * 2;
1245 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1253 /* Termcap capability names that correspond directly to X keysyms.
1254 Some of these (marked "terminfo") aren't supplied by old-style
1255 (Berkeley) termcap entries. They're listed in X keysym order;
1256 except we put the keypad keys first, so that if they clash with
1257 other keys (as on the IBM PC keyboard) they get overridden.
1260 static struct fkey_table keys
[] =
1262 {"kh", "home"}, /* termcap */
1263 {"kl", "left"}, /* termcap */
1264 {"ku", "up"}, /* termcap */
1265 {"kr", "right"}, /* termcap */
1266 {"kd", "down"}, /* termcap */
1267 {"%8", "prior"}, /* terminfo */
1268 {"%5", "next"}, /* terminfo */
1269 {"@7", "end"}, /* terminfo */
1270 {"@1", "begin"}, /* terminfo */
1271 {"*6", "select"}, /* terminfo */
1272 {"%9", "print"}, /* terminfo */
1273 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1275 * "insert" --- see below
1277 {"&8", "undo"}, /* terminfo */
1278 {"%0", "redo"}, /* terminfo */
1279 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1280 {"@0", "find"}, /* terminfo */
1281 {"@2", "cancel"}, /* terminfo */
1282 {"%1", "help"}, /* terminfo */
1284 * "break" goes here, but can't be reliably intercepted with termcap
1286 {"&4", "reset"}, /* terminfo --- actually `restart' */
1288 * "system" and "user" --- no termcaps
1290 {"kE", "clearline"}, /* terminfo */
1291 {"kA", "insertline"}, /* terminfo */
1292 {"kL", "deleteline"}, /* terminfo */
1293 {"kI", "insertchar"}, /* terminfo */
1294 {"kD", "deletechar"}, /* terminfo */
1295 {"kB", "backtab"}, /* terminfo */
1297 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1299 {"@8", "kp-enter"}, /* terminfo */
1301 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1302 * "kp-multiply", "kp-add", "kp-separator",
1303 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1304 * --- no termcaps for any of these.
1306 {"K4", "kp-1"}, /* terminfo */
1308 * "kp-2" --- no termcap
1310 {"K5", "kp-3"}, /* terminfo */
1312 * "kp-4" --- no termcap
1314 {"K2", "kp-5"}, /* terminfo */
1316 * "kp-6" --- no termcap
1318 {"K1", "kp-7"}, /* terminfo */
1320 * "kp-8" --- no termcap
1322 {"K3", "kp-9"}, /* terminfo */
1324 * "kp-equal" --- no termcap
1337 static char **term_get_fkeys_arg
;
1338 static Lisp_Object
term_get_fkeys_1 ();
1340 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1341 This function scans the termcap function key sequence entries, and
1342 adds entries to Vfunction_key_map for each function key it finds. */
1345 term_get_fkeys (address
)
1348 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1349 errors during the call. The only errors should be from Fdefine_key
1350 when given a key sequence containing an invalid prefix key. If the
1351 termcap defines function keys which use a prefix that is already bound
1352 to a command by the default bindings, we should silently ignore that
1353 function key specification, rather than giving the user an error and
1354 refusing to run at all on such a terminal. */
1356 extern Lisp_Object
Fidentity ();
1357 term_get_fkeys_arg
= address
;
1358 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1366 char **address
= term_get_fkeys_arg
;
1368 /* This can happen if CANNOT_DUMP or with strange options. */
1370 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1372 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1374 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1376 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1377 Fmake_vector (make_number (1),
1378 intern (keys
[i
].name
)));
1381 /* The uses of the "k0" capability are inconsistent; sometimes it
1382 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1383 We will attempt to politely accommodate both systems by testing for
1384 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1387 char *k_semi
= tgetstr ("k;", address
);
1388 char *k0
= tgetstr ("k0", address
);
1389 char *k0_name
= "f10";
1394 /* Define f0 first, so that f10 takes precedence in case the
1395 key sequences happens to be the same. */
1396 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1397 Fmake_vector (make_number (1), intern ("f0")));
1398 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1399 Fmake_vector (make_number (1), intern ("f10")));
1402 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1403 Fmake_vector (make_number (1), intern (k0_name
)));
1406 /* Set up cookies for numbered function keys above f10. */
1408 char fcap
[3], fkey
[4];
1410 fcap
[0] = 'F'; fcap
[2] = '\0';
1411 for (i
= 11; i
< 64; i
++)
1414 fcap
[1] = '1' + i
- 11;
1416 fcap
[1] = 'A' + i
- 20;
1418 fcap
[1] = 'a' + i
- 46;
1421 char *sequence
= tgetstr (fcap
, address
);
1424 sprintf (fkey
, "f%d", i
);
1425 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1426 Fmake_vector (make_number (1),
1434 * Various mappings to try and get a better fit.
1437 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1438 if (!tgetstr (cap1, address)) \
1440 char *sequence = tgetstr (cap2, address); \
1442 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1443 Fmake_vector (make_number (1), \
1447 /* if there's no key_next keycap, map key_npage to `next' keysym */
1448 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1449 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1450 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1451 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1452 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1453 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1454 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1456 /* IBM has their own non-standard dialect of terminfo.
1457 If the standard name isn't found, try the IBM name. */
1458 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1459 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1460 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1461 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1462 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1463 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1464 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1465 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1466 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1467 #undef CONDITIONAL_REASSIGN
1474 /***********************************************************************
1475 Character Display Information
1476 ***********************************************************************/
1478 static void append_glyph
P_ ((struct it
*));
1481 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1482 terminal frames if IT->glyph_row != NULL. IT->c is the character
1483 for which to produce glyphs; IT->face_id contains the character's
1484 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1491 struct glyph
*glyph
, *end
;
1494 xassert (it
->glyph_row
);
1495 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1496 + it
->glyph_row
->used
[it
->area
]);
1497 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1500 i
< it
->pixel_width
&& glyph
< end
;
1503 glyph
->type
= CHAR_GLYPH
;
1504 glyph
->pixel_width
= 1;
1505 glyph
->u
.ch
= it
->c
;
1506 glyph
->face_id
= it
->face_id
;
1507 glyph
->padding_p
= i
> 0;
1508 glyph
->charpos
= CHARPOS (it
->position
);
1509 glyph
->object
= it
->object
;
1511 ++it
->glyph_row
->used
[it
->area
];
1517 /* Produce glyphs for the display element described by IT. *IT
1518 specifies what we want to produce a glyph for (character, image, ...),
1519 and where in the glyph matrix we currently are (glyph row and hpos).
1520 produce_glyphs fills in output fields of *IT with information such as the
1521 pixel width and height of a character, and maybe output actual glyphs at
1522 the same time if IT->glyph_row is non-null. See the explanation of
1523 struct display_iterator in dispextern.h for an overview.
1525 produce_glyphs also stores the result of glyph width, ascent
1526 etc. computations in *IT.
1528 IT->glyph_row may be null, in which case produce_glyphs does not
1529 actually fill in the glyphs. This is used in the move_* functions
1530 in xdisp.c for text width and height computations.
1532 Callers usually don't call produce_glyphs directly;
1533 instead they use the macro PRODUCE_GLYPHS. */
1539 /* If a hook is installed, let it do the work. */
1540 xassert (it
->what
== IT_CHARACTER
1541 || it
->what
== IT_COMPOSITION
1542 || it
->what
== IT_IMAGE
1543 || it
->what
== IT_STRETCH
);
1545 /* Nothing but characters are supported on terminal frames. For a
1546 composition sequence, it->c is the first character of the
1548 xassert (it
->what
== IT_CHARACTER
1549 || it
->what
== IT_COMPOSITION
);
1551 if (it
->c
>= 040 && it
->c
< 0177)
1553 it
->pixel_width
= it
->nglyphs
= 1;
1557 else if (it
->c
== '\n')
1558 it
->pixel_width
= it
->nglyphs
= 0;
1559 else if (it
->c
== '\t')
1561 int absolute_x
= (it
->current_x
1562 + it
->continuation_lines_width
);
1564 = (((1 + absolute_x
+ it
->tab_width
- 1)
1569 /* If part of the TAB has been displayed on the previous line
1570 which is continued now, continuation_lines_width will have
1571 been incremented already by the part that fitted on the
1572 continued line. So, we will get the right number of spaces
1574 nspaces
= next_tab_x
- absolute_x
;
1581 it
->pixel_width
= it
->len
= 1;
1589 it
->pixel_width
= nspaces
;
1590 it
->nglyphs
= nspaces
;
1592 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1594 /* Coming here means that it->c is from display table, thus we
1595 must send the code as is to the terminal. Although there's
1596 no way to know how many columns it occupies on a screen, it
1597 is a good assumption that a single byte code has 1-column
1599 it
->pixel_width
= it
->nglyphs
= 1;
1605 /* A multi-byte character. The display width is fixed for all
1606 characters of the set. Some of the glyphs may have to be
1607 ignored because they are already displayed in a continued
1609 int charset
= CHAR_CHARSET (it
->c
);
1611 it
->pixel_width
= CHARSET_WIDTH (charset
);
1612 it
->nglyphs
= it
->pixel_width
;
1618 /* Advance current_x by the pixel width as a convenience for
1620 if (it
->area
== TEXT_AREA
)
1621 it
->current_x
+= it
->pixel_width
;
1622 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1623 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1627 /* Get information about special display element WHAT in an
1628 environment described by IT. WHAT is one of IT_TRUNCATION or
1629 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1630 non-null glyph_row member. This function ensures that fields like
1631 face_id, c, len of IT are left untouched. */
1634 produce_special_glyphs (it
, what
)
1636 enum display_element_type what
;
1642 temp_it
.what
= IT_CHARACTER
;
1644 temp_it
.object
= make_number (0);
1645 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1647 if (what
== IT_CONTINUATION
)
1649 /* Continuation glyph. */
1651 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1652 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1654 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it
->dp
)));
1655 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1660 produce_glyphs (&temp_it
);
1661 it
->pixel_width
= temp_it
.pixel_width
;
1662 it
->nglyphs
= temp_it
.pixel_width
;
1664 else if (what
== IT_TRUNCATION
)
1666 /* Truncation glyph. */
1668 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1669 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1671 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it
->dp
)));
1672 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1677 produce_glyphs (&temp_it
);
1678 it
->pixel_width
= temp_it
.pixel_width
;
1679 it
->nglyphs
= temp_it
.pixel_width
;
1687 /***********************************************************************
1689 ***********************************************************************/
1691 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1692 one of the enumerators from enum no_color_bit, or a bit set built
1693 from them. Some display attributes may not be used together with
1694 color; the termcap capability `NC' specifies which ones. */
1696 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1697 (tty->TN_max_colors > 0 \
1698 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1701 /* Turn appearances of face FACE_ID on tty frame F on. */
1704 turn_on_face (f
, face_id
)
1708 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1709 long fg
= face
->foreground
;
1710 long bg
= face
->background
;
1711 struct tty_display_info
*tty
= FRAME_TTY (f
);
1713 /* Do this first because TS_end_standout_mode may be the same
1714 as TS_exit_attribute_mode, which turns all appearances off. */
1715 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1717 if (tty
->TN_max_colors
> 0)
1719 if (fg
>= 0 && bg
>= 0)
1721 /* If the terminal supports colors, we can set them
1722 below without using reverse video. The face's fg
1723 and bg colors are set as they should appear on
1724 the screen, i.e. they take the inverse-video'ness
1725 of the face already into account. */
1727 else if (inverse_video
)
1729 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1730 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1731 toggle_highlight (tty
);
1735 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1736 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1737 toggle_highlight (tty
);
1742 /* If we can't display colors, use reverse video
1743 if the face specifies that. */
1746 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1747 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1748 toggle_highlight (tty
);
1752 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1753 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1754 toggle_highlight (tty
);
1759 if (face
->tty_bold_p
)
1761 if (MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1762 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1764 else if (face
->tty_dim_p
)
1765 if (MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1766 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1768 /* Alternate charset and blinking not yet used. */
1769 if (face
->tty_alt_charset_p
1770 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1771 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1773 if (face
->tty_blinking_p
1774 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1775 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1777 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1778 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1780 if (tty
->TN_max_colors
> 0)
1784 if (fg
>= 0 && tty
->TS_set_foreground
)
1786 p
= tparam (tty
->TS_set_foreground
, NULL
, 0, (int) fg
);
1791 if (bg
>= 0 && tty
->TS_set_background
)
1793 p
= tparam (tty
->TS_set_background
, NULL
, 0, (int) bg
);
1801 /* Turn off appearances of face FACE_ID on tty frame F. */
1804 turn_off_face (f
, face_id
)
1808 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1809 struct tty_display_info
*tty
= FRAME_TTY (f
);
1811 xassert (face
!= NULL
);
1813 if (tty
->TS_exit_attribute_mode
)
1815 /* Capability "me" will turn off appearance modes double-bright,
1816 half-bright, reverse-video, standout, underline. It may or
1817 may not turn off alt-char-mode. */
1818 if (face
->tty_bold_p
1820 || face
->tty_reverse_p
1821 || face
->tty_alt_charset_p
1822 || face
->tty_blinking_p
1823 || face
->tty_underline_p
)
1825 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
1826 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
1827 tty
->standout_mode
= 0;
1830 if (face
->tty_alt_charset_p
)
1831 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1835 /* If we don't have "me" we can only have those appearances
1836 that have exit sequences defined. */
1837 if (face
->tty_alt_charset_p
)
1838 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1840 if (face
->tty_underline_p
)
1841 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
1844 /* Switch back to default colors. */
1845 if (tty
->TN_max_colors
> 0
1846 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
1847 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
1848 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
1849 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
1850 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
1854 /* Return non-zero if the terminal on frame F supports all of the
1855 capabilities in CAPS simultaneously, with foreground and background
1856 colors FG and BG. */
1859 tty_capable_p (tty
, caps
, fg
, bg
)
1860 struct tty_display_info
*tty
;
1862 unsigned long fg
, bg
;
1864 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
1865 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
1868 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
1869 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
1870 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
1871 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
1872 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
1873 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
1879 /* Return the tty display object specified by DISPLAY.
1880 DISPLAY may be a frame or a string. */
1882 static struct display
*
1883 get_tty_display (Lisp_Object display
)
1887 if (! FRAMEP (display
) && ! STRINGP (display
))
1890 /* The initial frame does not support colors. */
1891 if (FRAMEP (display
) && FRAME_INITIAL_P (XFRAME (display
)))
1894 if (FRAMEP (display
))
1896 if (! FRAME_TERMCAP_P (XFRAME (display
)))
1897 #if 0 /* XXX We need a predicate as the first argument; find one. */
1898 wrong_type_argument ("Not a termcap frame", display
);
1899 #else /* Until we fix the wrong_type_argument call above, simply throw
1901 error ("DISPLAY is not a termcap frame");
1904 d
= FRAME_DISPLAY (XFRAME (display
));
1906 else if (STRINGP (display
))
1908 char *name
= (char *) alloca (SBYTES (display
) + 1);
1909 strncpy (name
, SDATA (display
), SBYTES (display
));
1910 name
[SBYTES (display
)] = 0;
1912 d
= get_named_tty_display (name
);
1915 error ("There is no tty display on %s", name
);
1922 /* Return non-zero if the terminal is capable to display colors. */
1924 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
1926 doc
: /* Return non-nil if TTY can display colors on DISPLAY. */)
1928 Lisp_Object display
;
1930 struct display
*d
= get_tty_display (display
);
1934 return d
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
1937 /* Return the number of supported colors. */
1938 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
1939 Stty_display_color_cells
, 0, 1, 0,
1940 doc
: /* Return the number of colors supported by TTY on DISPLAY. */)
1942 Lisp_Object display
;
1944 struct display
*d
= get_tty_display (display
);
1948 return make_number (d
->display_info
.tty
->TN_max_colors
);
1953 /* Save or restore the default color-related capabilities of this
1956 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
1959 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
1960 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
1964 if (default_orig_pair
)
1965 xfree (default_orig_pair
);
1966 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
1968 if (default_set_foreground
)
1969 xfree (default_set_foreground
);
1970 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
1973 if (default_set_background
)
1974 xfree (default_set_background
);
1975 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
1978 default_max_colors
= tty
->TN_max_colors
;
1979 default_max_pairs
= tty
->TN_max_pairs
;
1980 default_no_color_video
= tty
->TN_no_color_video
;
1984 tty
->TS_orig_pair
= default_orig_pair
;
1985 tty
->TS_set_foreground
= default_set_foreground
;
1986 tty
->TS_set_background
= default_set_background
;
1987 tty
->TN_max_colors
= default_max_colors
;
1988 tty
->TN_max_pairs
= default_max_pairs
;
1989 tty
->TN_no_color_video
= default_no_color_video
;
1993 /* Setup one of the standard tty color schemes according to MODE.
1994 MODE's value is generally the number of colors which we want to
1995 support; zero means set up for the default capabilities, the ones
1996 we saw at term_init time; -1 means turn off color support. */
1998 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2000 /* Canonicalize all negative values of MODE. */
2006 case -1: /* no colors at all */
2007 tty
->TN_max_colors
= 0;
2008 tty
->TN_max_pairs
= 0;
2009 tty
->TN_no_color_video
= 0;
2010 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2012 case 0: /* default colors, if any */
2014 tty_default_color_capabilities (tty
, 0);
2016 case 8: /* 8 standard ANSI colors */
2017 tty
->TS_orig_pair
= "\033[0m";
2019 tty
->TS_set_foreground
= "\033[3%p1%dm";
2020 tty
->TS_set_background
= "\033[4%p1%dm";
2022 tty
->TS_set_foreground
= "\033[3%dm";
2023 tty
->TS_set_background
= "\033[4%dm";
2025 tty
->TN_max_colors
= 8;
2026 tty
->TN_max_pairs
= 64;
2027 tty
->TN_no_color_video
= 0;
2033 set_tty_color_mode (f
, val
)
2037 Lisp_Object color_mode_spec
, current_mode_spec
;
2038 Lisp_Object color_mode
, current_mode
;
2040 extern Lisp_Object Qtty_color_mode
;
2041 Lisp_Object tty_color_mode_alist
;
2043 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2050 if (NILP (tty_color_mode_alist
))
2051 color_mode_spec
= Qnil
;
2053 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2055 if (CONSP (color_mode_spec
))
2056 color_mode
= XCDR (color_mode_spec
);
2061 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2063 if (CONSP (current_mode_spec
))
2064 current_mode
= XCDR (current_mode_spec
);
2066 current_mode
= Qnil
;
2067 if (INTEGERP (color_mode
))
2068 mode
= XINT (color_mode
);
2070 mode
= 0; /* meaning default */
2071 if (INTEGERP (current_mode
))
2072 old_mode
= XINT (current_mode
);
2076 if (mode
!= old_mode
)
2078 tty_setup_colors (FRAME_TTY (f
), mode
);
2079 /* This recomputes all the faces given the new color
2081 call0 (intern ("tty-set-up-initial-frame-faces"));
2086 #endif /* !WINDOWSNT */
2091 get_named_tty_display (name
)
2096 for (d
= display_list
; d
; d
= d
->next_display
) {
2097 if (d
->type
== output_termcap
2098 && ((d
->display_info
.tty
->name
== 0 && name
== 0)
2099 || (name
&& d
->display_info
.tty
->name
2100 && !strcmp (d
->display_info
.tty
->name
, name
))))
2109 DEFUN ("frame-tty-name", Fframe_tty_name
, Sframe_tty_name
, 0, 1, 0,
2110 doc
: /* Return the name of the TTY device that FRAME is displayed on. */)
2118 f
= XFRAME (selected_frame
);
2122 CHECK_LIVE_FRAME (frame
);
2126 if (f
->output_method
!= output_termcap
)
2127 wrong_type_argument (Qframe_tty_name
, frame
);
2129 if (FRAME_TTY (f
)->name
)
2130 return build_string (FRAME_TTY (f
)->name
);
2135 DEFUN ("frame-tty-type", Fframe_tty_type
, Sframe_tty_type
, 0, 1, 0,
2136 doc
: /* Return the type of the TTY device that FRAME is displayed on. */)
2144 f
= XFRAME (selected_frame
);
2148 CHECK_LIVE_FRAME (frame
);
2152 if (f
->output_method
!= output_termcap
)
2153 wrong_type_argument (Qframe_tty_type
, frame
);
2155 if (FRAME_TTY (f
)->type
)
2156 return build_string (FRAME_TTY (f
)->type
);
2162 /***********************************************************************
2164 ***********************************************************************/
2166 /* Create the bootstrap display device for the initial frame.
2168 Returns a display of type output_initial. */
2170 init_initial_display (void)
2172 struct tty_display_info
*tty
;
2174 if (initialized
|| display_list
|| tty_list
)
2177 initial_display
= create_display ();
2178 initial_display
->type
= output_initial
;
2180 initial_display
->delete_display_hook
= &delete_initial_display
;
2181 /* All other hooks are NULL. */
2183 return initial_display
;
2186 /* Deletes the bootstrap display device.
2187 Called through delete_display_hook. */
2189 delete_initial_display (struct display
*display
)
2191 if (display
!= initial_display
)
2194 delete_display (display
);
2195 initial_display
= NULL
;
2198 /* Create a termcap display on the tty device with the given name and
2201 If NAME is NULL, then use the controlling tty, i.e., stdin/stdout.
2202 Otherwise NAME should be a path to the tty device file,
2205 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
2207 If MUST_SUCCEED is true, then all errors are fatal. */
2209 term_init (char *name
, char *terminal_type
, int must_succeed
)
2212 char **address
= &area
;
2213 char *buffer
= NULL
;
2214 int buffer_size
= 4096;
2217 struct tty_display_info
*tty
;
2218 struct display
*display
;
2220 static void maybe_fatal();
2223 maybe_fatal (must_succeed
, 0, 0,
2224 "Unknown terminal type",
2225 "Unknown terminal type");
2227 display
= get_named_tty_display (name
);
2229 return display
; /* We have already opened a display there. */
2231 display
= create_display ();
2232 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
2233 bzero (tty
, sizeof (struct tty_display_info
));
2234 tty
->next
= tty_list
;
2237 display
->type
= output_termcap
;
2238 display
->display_info
.tty
= tty
;
2239 tty
->display
= display
;
2241 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
2244 display
->rif
= 0; /* ttys don't support window-based redisplay. */
2246 display
->cursor_to_hook
= &tty_cursor_to
;
2247 display
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
2249 display
->clear_to_end_hook
= &tty_clear_to_end
;
2250 display
->clear_frame_hook
= &tty_clear_frame
;
2251 display
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
2253 display
->ins_del_lines_hook
= &tty_ins_del_lines
;
2255 display
->insert_glyphs_hook
= &tty_insert_glyphs
;
2256 display
->write_glyphs_hook
= &tty_write_glyphs
;
2257 display
->delete_glyphs_hook
= &tty_delete_glyphs
;
2259 display
->ring_bell_hook
= &tty_ring_bell
;
2261 display
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
2262 display
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
2263 display
->update_begin_hook
= 0; /* Not needed. */
2264 display
->update_end_hook
= &tty_update_end
;
2265 display
->set_terminal_window_hook
= &tty_set_terminal_window
;
2267 display
->mouse_position_hook
= 0; /* Not needed. */
2268 display
->frame_rehighlight_hook
= 0; /* Not needed. */
2269 display
->frame_raise_lower_hook
= 0; /* Not needed. */
2271 display
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
2272 display
->condemn_scroll_bars_hook
= 0; /* Not needed. */
2273 display
->redeem_scroll_bar_hook
= 0; /* Not needed. */
2274 display
->judge_scroll_bars_hook
= 0; /* Not needed. */
2276 display
->read_socket_hook
= 0; /* Not needed. */
2277 display
->frame_up_to_date_hook
= 0; /* Not needed. */
2279 display
->delete_frame_hook
= &delete_tty_output
;
2280 display
->delete_display_hook
= &delete_tty
;
2286 fd
= emacs_open (name
, O_RDWR
, 0);
2289 delete_tty (display
);
2290 error ("Could not open file: %s", name
);
2292 file
= fdopen (fd
, "w+");
2293 tty
->name
= xstrdup (name
);
2301 tty
->output
= stdout
;
2304 tty
->type
= xstrdup (terminal_type
);
2306 add_keyboard_wait_descriptor (fileno (tty
->input
));
2309 initialize_w32_display ();
2313 area
= (char *) xmalloc (2044);
2315 FrameRows (tty
) = FRAME_LINES (f
); /* XXX */
2316 FrameCols (tty
) = FRAME_COLS (f
); /* XXX */
2317 tty
->specified_window
= FRAME_LINES (f
); /* XXX */
2319 tty
->display
->delete_in_insert_mode
= 1;
2322 display
->scroll_region_ok
= 0;
2324 /* Seems to insert lines when it's not supposed to, messing
2325 up the display. In doing a trace, it didn't seem to be
2326 called much, so I don't think we're losing anything by
2328 display
->line_ins_del_ok
= 0;
2329 display
->char_ins_del_ok
= 1;
2333 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0; /* XXX */
2334 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
; /* XXX */
2335 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2338 #else /* not WINDOWSNT */
2342 buffer
= (char *) xmalloc (buffer_size
);
2343 status
= tgetent (buffer
, terminal_type
);
2347 maybe_fatal (must_succeed
, buffer
, display
,
2348 "Cannot open terminfo database file",
2349 "Cannot open terminfo database file");
2351 maybe_fatal (must_succeed
, buffer
, display
,
2352 "Cannot open termcap database file",
2353 "Cannot open termcap database file");
2359 maybe_fatal (must_succeed
, buffer
, display
,
2360 "Terminal type %s is not defined",
2361 "Terminal type %s is not defined.\n\
2362 If that is not the actual type of terminal you have,\n\
2363 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2364 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2365 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2368 maybe_fatal (must_succeed
, buffer
, display
,
2369 "Terminal type %s is not defined",
2370 "Terminal type %s is not defined.\n\
2371 If that is not the actual type of terminal you have,\n\
2372 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2373 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2374 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2380 if (strlen (buffer
) >= buffer_size
)
2382 buffer_size
= strlen (buffer
);
2384 area
= (char *) xmalloc (buffer_size
);
2386 tty
->TS_ins_line
= tgetstr ("al", address
);
2387 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
2388 tty
->TS_bell
= tgetstr ("bl", address
);
2389 BackTab (tty
) = tgetstr ("bt", address
);
2390 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
2391 tty
->TS_clr_line
= tgetstr ("ce", address
);
2392 tty
->TS_clr_frame
= tgetstr ("cl", address
);
2393 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
2394 AbsPosition (tty
) = tgetstr ("cm", address
);
2395 CR (tty
) = tgetstr ("cr", address
);
2396 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
2397 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
2398 RowPosition (tty
) = tgetstr ("cv", address
);
2399 tty
->TS_del_char
= tgetstr ("dc", address
);
2400 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
2401 tty
->TS_del_line
= tgetstr ("dl", address
);
2402 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
2403 tty
->TS_delete_mode
= tgetstr ("dm", address
);
2404 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
2405 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
2406 Home (tty
) = tgetstr ("ho", address
);
2407 tty
->TS_ins_char
= tgetstr ("ic", address
);
2408 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
2409 tty
->TS_insert_mode
= tgetstr ("im", address
);
2410 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
2411 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
2412 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
2413 LastLine (tty
) = tgetstr ("ll", address
);
2414 Right (tty
) = tgetstr ("nd", address
);
2415 Down (tty
) = tgetstr ("do", address
);
2417 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
2419 /* VMS puts a carriage return before each linefeed,
2420 so it is not safe to use linefeeds. */
2421 if (Down (tty
) && Down (tty
)[0] == '\n' && Down (tty
)[1] == '\0')
2424 if (tgetflag ("bs"))
2425 Left (tty
) = "\b"; /* can't possibly be longer! */
2426 else /* (Actually, "bs" is obsolete...) */
2427 Left (tty
) = tgetstr ("le", address
);
2429 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
2430 tty
->TS_pad_char
= tgetstr ("pc", address
);
2431 tty
->TS_repeat
= tgetstr ("rp", address
);
2432 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
2433 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
2434 tty
->TS_standout_mode
= tgetstr ("so", address
);
2435 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
2436 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
2437 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
2438 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
2439 Up (tty
) = tgetstr ("up", address
);
2440 tty
->TS_visible_bell
= tgetstr ("vb", address
);
2441 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
2442 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
2443 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
2444 tty
->TS_set_window
= tgetstr ("wi", address
);
2446 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
2447 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
2448 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
2449 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
2450 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
2451 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
2452 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2453 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2454 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
2456 MultiUp (tty
) = tgetstr ("UP", address
);
2457 MultiDown (tty
) = tgetstr ("DO", address
);
2458 MultiLeft (tty
) = tgetstr ("LE", address
);
2459 MultiRight (tty
) = tgetstr ("RI", address
);
2461 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2462 color because we can't switch back to the default foreground and
2464 tty
->TS_orig_pair
= tgetstr ("op", address
);
2465 if (tty
->TS_orig_pair
)
2467 tty
->TS_set_foreground
= tgetstr ("AF", address
);
2468 tty
->TS_set_background
= tgetstr ("AB", address
);
2469 if (!tty
->TS_set_foreground
)
2472 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
2473 tty
->TS_set_background
= tgetstr ("Sb", address
);
2476 tty
->TN_max_colors
= tgetnum ("Co");
2477 tty
->TN_max_pairs
= tgetnum ("pa");
2479 tty
->TN_no_color_video
= tgetnum ("NC");
2480 if (tty
->TN_no_color_video
== -1)
2481 tty
->TN_no_color_video
= 0;
2484 tty_default_color_capabilities (tty
, 1);
2486 MagicWrap (tty
) = tgetflag ("xn");
2487 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2488 the former flag imply the latter. */
2489 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
2490 display
->memory_below_frame
= tgetflag ("db");
2491 tty
->TF_hazeltine
= tgetflag ("hz");
2492 display
->must_write_spaces
= tgetflag ("in");
2493 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
2494 tty
->TF_insmode_motion
= tgetflag ("mi");
2495 tty
->TF_standout_motion
= tgetflag ("ms");
2496 tty
->TF_underscore
= tgetflag ("ul");
2497 tty
->TF_teleray
= tgetflag ("xt");
2499 term_get_fkeys (address
);
2501 /* Get frame size from system, or else from termcap. */
2504 get_tty_size (fileno (TTY_INPUT (tty
)), &width
, &height
);
2505 FrameCols (tty
) = width
;
2506 FrameRows (tty
) = height
;
2509 if (FrameCols (tty
) <= 0)
2510 FrameCols (tty
) = tgetnum ("co");
2511 if (FrameRows (tty
) <= 0)
2512 FrameRows (tty
) = tgetnum ("li");
2514 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
2515 maybe_fatal (must_succeed
, NULL
, display
,
2516 "Screen size %dx%d is too small"
2517 "Screen size %dx%d is too small",
2518 FrameCols (tty
), FrameRows (tty
));
2520 #if 0 /* This is not used anywhere. */
2521 tty
->display
->min_padding_speed
= tgetnum ("pb");
2524 TabWidth (tty
) = tgetnum ("tw");
2527 /* These capabilities commonly use ^J.
2528 I don't know why, but sending them on VMS does not work;
2529 it causes following spaces to be lost, sometimes.
2530 For now, the simplest fix is to avoid using these capabilities ever. */
2531 if (Down (tty
) && Down (tty
)[0] == '\n')
2536 tty
->TS_bell
= "\07";
2538 if (!tty
->TS_fwd_scroll
)
2539 tty
->TS_fwd_scroll
= Down (tty
);
2541 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
2543 if (TabWidth (tty
) < 0)
2546 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2547 and newer termcap doc does not seem to say there is a default.
2548 if (!tty->Wcm->cm_tab)
2549 tty->Wcm->cm_tab = "\t";
2552 /* We don't support standout modes that use `magic cookies', so
2553 turn off any that do. */
2554 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
2556 tty
->TS_standout_mode
= 0;
2557 tty
->TS_end_standout_mode
= 0;
2559 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
2561 tty
->TS_enter_underline_mode
= 0;
2562 tty
->TS_exit_underline_mode
= 0;
2565 /* If there's no standout mode, try to use underlining instead. */
2566 if (tty
->TS_standout_mode
== 0)
2568 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
2569 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
2572 /* If no `se' string, try using a `me' string instead.
2573 If that fails, we can't use standout mode at all. */
2574 if (tty
->TS_end_standout_mode
== 0)
2576 char *s
= tgetstr ("me", address
);
2578 tty
->TS_end_standout_mode
= s
;
2580 tty
->TS_standout_mode
= 0;
2583 if (tty
->TF_teleray
)
2585 tty
->Wcm
->cm_tab
= 0;
2586 /* We can't support standout mode, because it uses magic cookies. */
2587 tty
->TS_standout_mode
= 0;
2588 /* But that means we cannot rely on ^M to go to column zero! */
2590 /* LF can't be trusted either -- can alter hpos */
2591 /* if move at column 0 thru a line with TS_standout_mode */
2595 /* Special handling for certain terminal types known to need it */
2597 if (!strcmp (terminal_type
, "supdup"))
2599 display
->memory_below_frame
= 1;
2600 tty
->Wcm
->cm_losewrap
= 1;
2602 if (!strncmp (terminal_type
, "c10", 3)
2603 || !strcmp (terminal_type
, "perq"))
2605 /* Supply a makeshift :wi string.
2606 This string is not valid in general since it works only
2607 for windows starting at the upper left corner;
2608 but that is all Emacs uses.
2610 This string works only if the frame is using
2611 the top of the video memory, because addressing is memory-relative.
2612 So first check the :ti string to see if that is true.
2614 It would be simpler if the :wi string could go in the termcap
2615 entry, but it can't because it is not fully valid.
2616 If it were in the termcap entry, it would confuse other programs. */
2617 if (!tty
->TS_set_window
)
2619 p
= tty
->TS_termcap_modes
;
2620 while (*p
&& strcmp (p
, "\033v "))
2623 tty
->TS_set_window
= "\033v%C %C %C %C ";
2625 /* Termcap entry often fails to have :in: flag */
2626 display
->must_write_spaces
= 1;
2627 /* :ti string typically fails to have \E^G! in it */
2628 /* This limits scope of insert-char to one line. */
2629 strcpy (area
, tty
->TS_termcap_modes
);
2630 strcat (area
, "\033\007!");
2631 tty
->TS_termcap_modes
= area
;
2632 area
+= strlen (area
) + 1;
2633 p
= AbsPosition (tty
);
2634 /* Change all %+ parameters to %C, to handle
2635 values above 96 correctly for the C100. */
2638 if (p
[0] == '%' && p
[1] == '+')
2644 tty
->specified_window
= FrameRows (tty
);
2646 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
2648 maybe_fatal (must_succeed
, NULL
, display
,
2649 "Terminal type \"%s\" is not powerful enough to run Emacs",
2651 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2652 It lacks the ability to position the cursor.\n\
2653 If that is not the actual type of terminal you have, use either the\n\
2654 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2655 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2658 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2659 It lacks the ability to position the cursor.\n\
2660 If that is not the actual type of terminal you have,\n\
2661 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2662 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2663 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2664 # else /* TERMCAP */
2665 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2666 It lacks the ability to position the cursor.\n\
2667 If that is not the actual type of terminal you have,\n\
2668 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2669 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2670 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2671 # endif /* TERMINFO */
2676 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
2677 maybe_fatal (must_succeed
, NULL
, display
,
2678 "Could not determine the frame size",
2679 "Could not determine the frame size");
2681 tty
->delete_in_insert_mode
2682 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
2683 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
2685 tty
->se_is_so
= (tty
->TS_standout_mode
2686 && tty
->TS_end_standout_mode
2687 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
2689 UseTabs (tty
) = tabs_safe_p (fileno (TTY_INPUT (tty
))) && TabWidth (tty
) == 8;
2691 display
->scroll_region_ok
2693 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
2695 display
->line_ins_del_ok
2696 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
2697 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
2698 || (display
->scroll_region_ok
2699 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
2701 display
->char_ins_del_ok
2702 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
2703 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
2704 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
2706 display
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
2708 init_baud_rate (fileno (TTY_INPUT (tty
)));
2710 /* XXX This condition sounds bogus. */
2711 if (display
->read_socket_hook
) /* Baudrate is somewhat
2712 meaningless in this case */
2716 /* The HFT system on AIX doesn't optimize for scrolling, so it's
2717 really ugly at times. */
2718 display
->line_ins_del_ok
= 0;
2719 display
->char_ins_del_ok
= 0;
2723 tty
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
2724 init_kboard (tty
->kboard
);
2725 tty
->kboard
->next_kboard
= all_kboards
;
2726 all_kboards
= tty
->kboard
;
2727 /* Don't let the initial kboard remain current longer than necessary.
2728 That would cause problems if a file loaded on startup tries to
2729 prompt in the mini-buffer. */
2730 if (current_kboard
== initial_kboard
)
2731 current_kboard
= tty
->kboard
;
2732 tty
->kboard
->reference_count
++;
2735 /* Don't do this. I think termcap may still need the buffer. */
2736 /* xfree (buffer); */
2738 /* Init system terminal modes (RAW or CBREAK, etc.). */
2739 init_sys_modes (tty
);
2742 #endif /* not WINDOWSNT */
2745 /* Auxiliary error-handling function for term_init.
2746 Free BUFFER and delete DISPLAY, then call error or fatal
2747 with str1 or str2, respectively, according to MUST_SUCCEED.
2750 maybe_fatal (must_succeed
, buffer
, display
, str1
, str2
, arg1
, arg2
)
2753 struct display
*display
;
2754 char *str1
, *str2
, *arg1
, *arg2
;
2760 delete_tty (display
);
2763 fatal (str2
, arg1
, arg2
);
2765 error (str1
, arg1
, arg2
);
2772 fatal (str
, arg1
, arg2
)
2773 char *str
, *arg1
, *arg2
;
2775 fprintf (stderr
, "emacs: ");
2776 fprintf (stderr
, str
, arg1
, arg2
);
2777 fprintf (stderr
, "\n");
2784 DEFUN ("delete-tty", Fdelete_tty
, Sdelete_tty
, 0, 1, 0,
2785 doc
: /* Delete all frames on the terminal named TTY, and close the device.
2786 If omitted, TTY defaults to the controlling terminal.
2788 This function runs `delete-tty-after-functions' after closing the
2789 tty. The functions are run with one arg, the frame to be deleted. */)
2798 if (SBYTES (tty
) > 0)
2800 name
= (char *) alloca (SBYTES (tty
) + 1);
2801 strncpy (name
, SDATA (tty
), SBYTES (tty
));
2802 name
[SBYTES (tty
)] = 0;
2805 d
= get_named_tty_display (name
);
2808 error ("No such terminal device: %s", name
);
2813 static int deleting_tty
= 0;
2816 delete_tty (struct display
*display
)
2818 struct tty_display_info
*tty
;
2819 Lisp_Object tail
, frame
;
2823 /* We get a recursive call when we delete the last frame on this
2829 if (display
->type
!= output_termcap
)
2832 tty
= display
->display_info
.tty
;
2834 if (tty
== tty_list
)
2835 tty_list
= tty
->next
;
2838 struct tty_display_info
*p
;
2839 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
2843 /* This should not happen. */
2846 p
->next
= tty
->next
;
2850 FOR_EACH_FRAME (tail
, frame
)
2852 struct frame
*f
= XFRAME (frame
);
2853 if (FRAME_TERMCAP_P (f
) && FRAME_LIVE_P (f
) && FRAME_TTY (f
) == tty
)
2855 Fdelete_frame (frame
, Qt
);
2856 f
->output_data
.tty
= 0;
2860 /* reset_sys_modes needs a valid display, so this call needs to be
2861 before delete_display. */
2862 reset_sys_modes (tty
);
2864 delete_display (display
);
2866 tty_name
= tty
->name
;
2872 delete_keyboard_wait_descriptor (fileno (tty
->input
));
2873 if (tty
->input
!= stdin
)
2874 fclose (tty
->input
);
2876 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
2877 fclose (tty
->output
);
2878 if (tty
->termscript
)
2879 fclose (tty
->termscript
);
2882 xfree (tty
->old_tty
);
2888 if (tty
->kboard
&& --tty
->kboard
->reference_count
> 0)
2891 delete_kboard (tty
->kboard
);
2894 bzero (tty
, sizeof (struct tty_display_info
));
2898 /* Run `delete-tty-after-functions'. */
2899 if (!NILP (Vrun_hooks
))
2901 Lisp_Object args
[2];
2902 args
[0] = intern ("delete-tty-after-functions");
2905 args
[1] = build_string (tty_name
);
2910 Frun_hook_with_args (2, args
);
2916 /* Initialize the tty-dependent part of frame F. The frame must
2917 already have its display initialized. */
2919 create_tty_output (struct frame
*f
)
2921 if (! FRAME_TERMCAP_P (f
))
2924 struct tty_output
*t
= xmalloc (sizeof (struct tty_output
));
2925 bzero (t
, sizeof (struct tty_output
));
2927 t
->display_info
= FRAME_DISPLAY (f
)->display_info
.tty
;
2929 f
->output_data
.tty
= t
;
2932 /* Delete the tty-dependent part of frame F. */
2934 delete_tty_output (struct frame
*f
)
2936 if (! FRAME_TERMCAP_P (f
))
2939 xfree (f
->output_data
.tty
);
2945 /* Mark the pointers in the tty_display_info objects.
2946 Called by the Fgarbage_collector. */
2950 struct tty_display_info
*tty
;
2952 for (tty
= tty_list
; tty
; tty
= tty
->next
)
2955 mark_object (tty
->top_frame
);
2961 /* Create a new display object and add it to the display list. */
2963 create_display (void)
2965 struct display
*dev
= (struct display
*) xmalloc (sizeof (struct display
));
2967 bzero (dev
, sizeof (struct display
));
2968 dev
->next_display
= display_list
;
2974 /* Remove a display from the display list and free its memory. */
2976 delete_display (struct display
*dev
)
2978 struct display
**dp
;
2979 for (dp
= &display_list
; *dp
!= dev
; dp
= &(*dp
)->next_display
)
2982 *dp
= dev
->next_display
;
2984 bzero (dev
, sizeof (struct display
));
2993 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
2994 doc
: /* Non-nil means the system uses terminfo rather than termcap.
2995 This variable can be used by terminal emulator packages. */);
2997 system_uses_terminfo
= 1;
2999 system_uses_terminfo
= 0;
3002 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
3003 doc
: /* Non-nil means call this function to ring the bell.
3004 The function should accept no arguments. */);
3005 Vring_bell_function
= Qnil
;
3007 DEFVAR_LISP ("delete-tty-after-functions", &Vdelete_tty_after_functions
,
3008 doc
: /* Functions to be run after deleting a tty.
3009 The functions are run with one argument, the name of the tty to be deleted.
3010 See `delete-tty'. */);
3011 Vdelete_tty_after_functions
= Qnil
;
3013 Qframe_tty_name
= intern ("frame-tty-name");
3014 staticpro (&Qframe_tty_name
);
3016 Qframe_tty_type
= intern ("frame-tty-type");
3017 staticpro (&Qframe_tty_type
);
3019 defsubr (&Stty_display_color_p
);
3020 defsubr (&Stty_display_color_cells
);
3021 defsubr (&Sframe_tty_name
);
3022 defsubr (&Sframe_tty_type
);
3023 defsubr (&Sdelete_tty
);
3025 Fprovide (intern ("multi-tty"), Qnil
);
3031 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
3032 (do not change this comment) */