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
= XFRAME (selected_frame
);
181 if (!NILP (Vring_bell_function
))
183 Lisp_Object function
;
185 /* Temporarily set the global variable to nil
186 so that if we get an error, it stays nil
187 and we don't call it over and over.
189 We don't specbind it, because that would carefully
190 restore the bad value if there's an error
191 and make the loop of errors happen anyway. */
193 function
= Vring_bell_function
;
194 Vring_bell_function
= Qnil
;
198 Vring_bell_function
= function
;
200 else if (FRAME_DISPLAY (f
)->ring_bell_hook
)
201 (*FRAME_DISPLAY (f
)->ring_bell_hook
) ();
207 struct frame
*f
= XFRAME (selected_frame
);
208 struct tty_display_info
*tty
= FRAME_TTY (f
);
210 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
211 ? tty
->TS_visible_bell
215 void tty_set_terminal_modes (struct display
*display
)
217 struct tty_display_info
*tty
= display
->display_info
.tty
;
219 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
220 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
221 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
225 void tty_reset_terminal_modes (struct display
*display
)
227 struct tty_display_info
*tty
= display
->display_info
.tty
;
229 turn_off_highlight (tty
);
230 turn_off_insert (tty
);
231 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
232 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
233 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
234 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
235 /* Output raw CR so kernel can track the cursor hpos. */
245 if (FRAME_DISPLAY (f
)->update_begin_hook
)
246 (*FRAME_DISPLAY (f
)->update_begin_hook
) (f
);
253 if (FRAME_DISPLAY (f
)->update_end_hook
)
254 (*FRAME_DISPLAY (f
)->update_end_hook
) (f
);
255 updating_frame
= NULL
;
259 tty_update_end (struct frame
*f
)
261 struct tty_display_info
*tty
= FRAME_TTY (f
);
263 if (!XWINDOW (selected_window
)->cursor_off_p
)
264 tty_show_cursor (tty
);
265 turn_off_insert (tty
);
266 background_highlight (tty
);
270 set_terminal_window (size
)
273 struct frame
*f
= (updating_frame
275 : XFRAME (selected_frame
));
277 if (FRAME_DISPLAY (f
)->set_terminal_window_hook
)
278 (*FRAME_DISPLAY (f
)->set_terminal_window_hook
) (size
);
282 tty_set_terminal_window (int size
)
284 struct frame
*f
= (updating_frame
286 : XFRAME (selected_frame
));
288 struct tty_display_info
*tty
= FRAME_TTY (f
);
290 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
291 if (FRAME_SCROLL_REGION_OK (f
))
292 set_scroll_region (0, tty
->specified_window
);
296 set_scroll_region (start
, stop
)
300 struct frame
*f
= (updating_frame
302 : XFRAME (selected_frame
));
304 struct tty_display_info
*tty
= FRAME_TTY (f
);
306 if (tty
->TS_set_scroll_region
)
307 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
308 else if (tty
->TS_set_scroll_region_1
)
309 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
310 FRAME_LINES (f
), start
,
311 FRAME_LINES (f
) - stop
,
314 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
323 turn_on_insert (struct tty_display_info
*tty
)
325 if (!tty
->insert_mode
)
326 OUTPUT (tty
, tty
->TS_insert_mode
);
327 tty
->insert_mode
= 1;
331 turn_off_insert (struct tty_display_info
*tty
)
333 if (tty
->insert_mode
)
334 OUTPUT (tty
, tty
->TS_end_insert_mode
);
335 tty
->insert_mode
= 0;
338 /* Handle highlighting. */
341 turn_off_highlight (struct tty_display_info
*tty
)
343 if (tty
->standout_mode
)
344 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
345 tty
->standout_mode
= 0;
349 turn_on_highlight (struct tty_display_info
*tty
)
351 if (!tty
->standout_mode
)
352 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
353 tty
->standout_mode
= 1;
357 toggle_highlight (struct tty_display_info
*tty
)
359 if (tty
->standout_mode
)
360 turn_off_highlight (tty
);
362 turn_on_highlight (tty
);
366 /* Make cursor invisible. */
369 tty_hide_cursor (struct tty_display_info
*tty
)
371 if (tty
->cursor_hidden
== 0)
373 tty
->cursor_hidden
= 1;
374 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
379 /* Ensure that cursor is visible. */
382 tty_show_cursor (struct tty_display_info
*tty
)
384 if (tty
->cursor_hidden
)
386 tty
->cursor_hidden
= 0;
387 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
388 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
393 /* Set standout mode to the state it should be in for
394 empty space inside windows. What this is,
395 depends on the user option inverse-video. */
398 background_highlight (struct tty_display_info
*tty
)
401 turn_on_highlight (tty
);
403 turn_off_highlight (tty
);
406 /* Set standout mode to the mode specified for the text to be output. */
409 highlight_if_desired (struct tty_display_info
*tty
)
412 turn_on_highlight (tty
);
414 turn_off_highlight (tty
);
418 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
419 frame-relative coordinates. */
422 cursor_to (vpos
, hpos
)
425 struct frame
*f
= (updating_frame
427 : XFRAME (selected_frame
));
429 if (FRAME_DISPLAY (f
)->cursor_to_hook
)
430 (*FRAME_DISPLAY (f
)->cursor_to_hook
) (vpos
, hpos
);
434 tty_cursor_to (int vpos
, int hpos
)
436 struct frame
*f
= (updating_frame
438 : XFRAME (selected_frame
));
440 struct tty_display_info
*tty
= FRAME_TTY (f
);
442 /* Detect the case where we are called from reset_sys_modes
443 and the costs have never been calculated. Do nothing. */
444 if (! tty
->costs_set
)
447 if (curY (tty
) == vpos
448 && curX (tty
) == hpos
)
450 if (!tty
->TF_standout_motion
)
451 background_highlight (tty
);
452 if (!tty
->TF_insmode_motion
)
453 turn_off_insert (tty
);
454 cmgoto (tty
, vpos
, hpos
);
457 /* Similar but don't take any account of the wasted characters. */
460 raw_cursor_to (row
, col
)
463 struct frame
*f
= (updating_frame
465 : XFRAME (selected_frame
));
467 if (FRAME_DISPLAY (f
)->raw_cursor_to_hook
)
468 (*FRAME_DISPLAY (f
)->raw_cursor_to_hook
) (row
, col
);
472 tty_raw_cursor_to (int row
, int col
)
474 struct frame
*f
= (updating_frame
476 : XFRAME (selected_frame
));
478 struct tty_display_info
*tty
= FRAME_TTY (f
);
480 if (curY (tty
) == row
481 && curX (tty
) == col
)
483 if (!tty
->TF_standout_motion
)
484 background_highlight (tty
);
485 if (!tty
->TF_insmode_motion
)
486 turn_off_insert (tty
);
487 cmgoto (tty
, row
, col
);
490 /* Erase operations */
492 /* clear from cursor to end of frame */
496 struct frame
*f
= (updating_frame
498 : XFRAME (selected_frame
));
500 if (FRAME_DISPLAY (f
)->clear_to_end_hook
)
501 (*FRAME_DISPLAY (f
)->clear_to_end_hook
) ();
505 tty_clear_to_end (void)
508 struct frame
*f
= (updating_frame
510 : XFRAME (selected_frame
));
511 struct tty_display_info
*tty
= FRAME_TTY (f
);
513 if (tty
->TS_clr_to_bottom
)
515 background_highlight (tty
);
516 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
520 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
523 clear_end_of_line (FRAME_COLS (f
));
528 /* Clear entire frame */
533 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
535 if (FRAME_DISPLAY (f
)->clear_frame_hook
)
536 (*FRAME_DISPLAY (f
)->clear_frame_hook
) ();
542 struct frame
*f
= (updating_frame
544 : XFRAME (selected_frame
));
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 (first_unused_hpos
)
568 int first_unused_hpos
;
570 struct frame
*f
= (updating_frame
572 : XFRAME (selected_frame
));
574 if (FRAME_DISPLAY (f
)->clear_end_of_line_hook
)
575 (*FRAME_DISPLAY (f
)->clear_end_of_line_hook
) (first_unused_hpos
);
579 tty_clear_end_of_line (int first_unused_hpos
)
582 struct frame
*f
= (updating_frame
584 : XFRAME (selected_frame
));
585 struct tty_display_info
*tty
= FRAME_TTY (f
);
587 /* Detect the case where we are called from reset_sys_modes
588 and the costs have never been calculated. Do nothing. */
589 if (! tty
->costs_set
)
592 if (curX (tty
) >= first_unused_hpos
)
594 background_highlight (tty
);
595 if (tty
->TS_clr_line
)
597 OUTPUT1 (tty
, tty
->TS_clr_line
);
600 { /* have to do it the hard way */
601 turn_off_insert (tty
);
603 /* Do not write in last row last col with Auto-wrap on. */
605 && curY (tty
) == FrameRows (tty
) - 1
606 && first_unused_hpos
== FrameCols (tty
))
609 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
611 if (TTY_TERMSCRIPT (tty
))
612 fputc (' ', TTY_TERMSCRIPT (tty
));
613 fputc (' ', TTY_OUTPUT (tty
));
615 cmplus (tty
, first_unused_hpos
- curX (tty
));
619 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
620 store them at DST. Do not write more than DST_LEN bytes. That may
621 require stopping before all SRC_LEN input glyphs have been
624 We store the number of glyphs actually converted in *CONSUMED. The
625 return value is the number of bytes store in DST. */
628 encode_terminal_code (src
, dst
, src_len
, dst_len
, consumed
)
632 int dst_len
, *consumed
;
634 struct glyph
*src_start
= src
, *src_end
= src
+ src_len
;
635 unsigned char *dst_start
= dst
, *dst_end
= dst
+ dst_len
;
637 unsigned char workbuf
[MAX_MULTIBYTE_LENGTH
];
638 const unsigned char *buf
;
640 register int tlen
= GLYPH_TABLE_LENGTH
;
641 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
643 struct coding_system
*coding
;
645 /* If terminal_coding does any conversion, use it, otherwise use
646 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
647 because it always return 1 if the member src_multibyte is 1. */
648 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
650 : &safe_terminal_coding
);
652 while (src
< src_end
)
654 /* We must skip glyphs to be padded for a wide character. */
655 if (! CHAR_GLYPH_PADDING_P (*src
))
657 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
659 if (g
< 0 || g
>= tlen
)
661 /* This glyph doesn't has an entry in Vglyph_table. */
662 if (! CHAR_VALID_P (src
->u
.ch
, 0))
666 coding
->src_multibyte
= 0;
670 len
= CHAR_STRING (src
->u
.ch
, workbuf
);
672 coding
->src_multibyte
= 1;
677 /* This glyph has an entry in Vglyph_table,
678 so process any alias before testing for simpleness. */
679 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
681 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
683 /* We set the multi-byte form of a character in G
684 (that should be an ASCII character) at
686 workbuf
[0] = FAST_GLYPH_CHAR (g
);
689 coding
->src_multibyte
= 0;
693 /* We have a string in Vglyph_table. */
694 len
= GLYPH_LENGTH (tbase
, g
);
695 buf
= GLYPH_STRING (tbase
, g
);
696 coding
->src_multibyte
= STRING_MULTIBYTE (tbase
[g
]);
700 result
= encode_coding (coding
, buf
, dst
, len
, dst_end
- dst
);
701 len
-= coding
->consumed
;
702 dst
+= coding
->produced
;
703 if (result
== CODING_FINISH_INSUFFICIENT_DST
704 || (result
== CODING_FINISH_INSUFFICIENT_SRC
705 && len
> dst_end
- dst
))
706 /* The remaining output buffer is too short. We must
707 break the loop here without increasing SRC so that the
708 next call of this function starts from the same glyph. */
713 /* This is the case that a code of the range 0200..0237
714 exists in buf. We must just write out such a code. */
715 buf
+= coding
->consumed
;
723 *consumed
= src
- src_start
;
724 return (dst
- dst_start
);
729 write_glyphs (string
, len
)
730 register struct glyph
*string
;
733 struct frame
*f
= (updating_frame
735 : XFRAME (selected_frame
));
737 if (FRAME_DISPLAY (f
)->write_glyphs_hook
)
738 (*FRAME_DISPLAY (f
)->write_glyphs_hook
) (string
, len
);
742 tty_write_glyphs (struct glyph
*string
, int len
)
744 int produced
, consumed
;
745 unsigned char conversion_buffer
[1024];
746 int conversion_buffer_size
= sizeof conversion_buffer
;
748 struct frame
*f
= (updating_frame
750 : XFRAME (selected_frame
));
752 struct tty_display_info
*tty
= FRAME_TTY (f
);
754 turn_off_insert (tty
);
755 tty_hide_cursor (tty
);
757 /* Don't dare write in last column of bottom line, if Auto-Wrap,
758 since that would scroll the whole frame on some terminals. */
761 && curY (tty
) + 1 == FRAME_LINES (f
)
762 && (curX (tty
) + len
) == FRAME_COLS (f
))
769 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
771 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
775 /* Identify a run of glyphs with the same face. */
776 int face_id
= string
->face_id
;
779 for (n
= 1; n
< len
; ++n
)
780 if (string
[n
].face_id
!= face_id
)
783 /* Turn appearance modes of the face of the run on. */
784 highlight_if_desired (tty
);
785 turn_on_face (f
, face_id
);
789 /* We use a fixed size (1024 bytes) of conversion buffer.
790 Usually it is sufficient, but if not, we just repeat the
792 produced
= encode_terminal_code (string
, conversion_buffer
,
793 n
, conversion_buffer_size
,
797 fwrite (conversion_buffer
, 1, produced
,
799 if (ferror (TTY_OUTPUT (tty
)))
800 clearerr (TTY_OUTPUT (tty
));
801 if (TTY_TERMSCRIPT (tty
))
802 fwrite (conversion_buffer
, 1, produced
,
803 TTY_TERMSCRIPT (tty
));
810 /* Turn appearance modes off. */
811 turn_off_face (f
, face_id
);
812 turn_off_highlight (tty
);
815 /* We may have to output some codes to terminate the writing. */
816 if (CODING_REQUIRE_FLUSHING (&terminal_coding
))
818 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
819 encode_coding (&terminal_coding
, "", conversion_buffer
,
820 0, conversion_buffer_size
);
821 if (terminal_coding
.produced
> 0)
823 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
825 if (ferror (TTY_OUTPUT (tty
)))
826 clearerr (TTY_OUTPUT (tty
));
827 if (TTY_TERMSCRIPT (tty
))
828 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
829 TTY_TERMSCRIPT (tty
));
836 /* If start is zero, insert blanks instead of a string at start */
839 insert_glyphs (start
, len
)
840 register struct glyph
*start
;
843 struct frame
*f
= (updating_frame
845 : XFRAME (selected_frame
));
850 if (FRAME_DISPLAY (f
)->insert_glyphs_hook
)
851 (*FRAME_DISPLAY (f
)->insert_glyphs_hook
) (start
, len
);
855 tty_insert_glyphs (struct glyph
*start
, int len
)
858 struct glyph
*glyph
= NULL
;
859 struct frame
*f
= (updating_frame
861 : XFRAME (selected_frame
));
863 struct tty_display_info
*tty
= FRAME_TTY (f
);
865 if (tty
->TS_ins_multi_chars
)
867 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
871 write_glyphs (start
, len
);
875 turn_on_insert (tty
);
877 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
878 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
881 int produced
, consumed
;
882 unsigned char conversion_buffer
[1024];
883 int conversion_buffer_size
= sizeof conversion_buffer
;
885 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
888 conversion_buffer
[0] = SPACEGLYPH
;
893 highlight_if_desired (tty
);
894 turn_on_face (f
, start
->face_id
);
897 /* We must open sufficient space for a character which
898 occupies more than one column. */
899 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
901 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
906 /* This is the last glyph. */
907 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
909 /* The size of conversion buffer (1024 bytes) is surely
910 sufficient for just one glyph. */
911 produced
= encode_terminal_code (glyph
, conversion_buffer
, 1,
912 conversion_buffer_size
, &consumed
);
917 fwrite (conversion_buffer
, 1, produced
,
919 if (ferror (TTY_OUTPUT (tty
)))
920 clearerr (TTY_OUTPUT (tty
));
921 if (TTY_TERMSCRIPT (tty
))
922 fwrite (conversion_buffer
, 1, produced
,
923 TTY_TERMSCRIPT (tty
));
926 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
929 turn_off_face (f
, glyph
->face_id
);
930 turn_off_highlight (tty
);
941 struct frame
*f
= (updating_frame
943 : XFRAME (selected_frame
));
945 if (FRAME_DISPLAY (f
)->delete_glyphs_hook
)
946 (*FRAME_DISPLAY (f
)->delete_glyphs_hook
) (n
);
950 tty_delete_glyphs (int n
)
954 struct frame
*f
= (updating_frame
956 : XFRAME (selected_frame
));
958 struct tty_display_info
*tty
= FRAME_TTY (f
);
960 if (tty
->delete_in_insert_mode
)
962 turn_on_insert (tty
);
966 turn_off_insert (tty
);
967 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
970 if (tty
->TS_del_multi_chars
)
972 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
977 for (i
= 0; i
< n
; i
++)
978 OUTPUT1 (tty
, tty
->TS_del_char
);
979 if (!tty
->delete_in_insert_mode
)
980 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
983 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
986 ins_del_lines (vpos
, n
)
989 struct frame
*f
= (updating_frame
991 : XFRAME (selected_frame
));
993 if (FRAME_DISPLAY (f
)->ins_del_lines_hook
)
994 (*FRAME_DISPLAY (f
)->ins_del_lines_hook
) (vpos
, n
);
998 tty_ins_del_lines (int vpos
, int n
)
1000 struct frame
*f
= (updating_frame
1002 : XFRAME (selected_frame
));
1004 struct tty_display_info
*tty
= FRAME_TTY (f
);
1005 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
1006 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
1007 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
1009 register int i
= n
> 0 ? n
: -n
;
1012 /* If the lines below the insertion are being pushed
1013 into the end of the window, this is the same as clearing;
1014 and we know the lines are already clear, since the matching
1015 deletion has already been done. So can ignore this. */
1016 /* If the lines below the deletion are blank lines coming
1017 out of the end of the window, don't bother,
1018 as there will be a matching inslines later that will flush them. */
1019 if (FRAME_SCROLL_REGION_OK (f
)
1020 && vpos
+ i
>= tty
->specified_window
)
1022 if (!FRAME_MEMORY_BELOW_FRAME (f
)
1023 && vpos
+ i
>= FRAME_LINES (f
))
1028 raw_cursor_to (vpos
, 0);
1029 background_highlight (tty
);
1030 buf
= tparam (multi
, 0, 0, i
);
1036 raw_cursor_to (vpos
, 0);
1037 background_highlight (tty
);
1039 OUTPUT (tty
, single
);
1040 if (tty
->TF_teleray
)
1045 set_scroll_region (vpos
, tty
->specified_window
);
1047 raw_cursor_to (tty
->specified_window
- 1, 0);
1049 raw_cursor_to (vpos
, 0);
1050 background_highlight (tty
);
1052 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1053 set_scroll_region (0, tty
->specified_window
);
1056 if (!FRAME_SCROLL_REGION_OK (f
)
1057 && FRAME_MEMORY_BELOW_FRAME (f
)
1060 cursor_to (FRAME_LINES (f
) + n
, 0);
1065 /* Compute cost of sending "str", in characters,
1066 not counting any line-dependent padding. */
1074 tputs (str
, 0, evalcost
);
1078 /* Compute cost of sending "str", in characters,
1079 counting any line-dependent padding at one line. */
1082 string_cost_one_line (str
)
1087 tputs (str
, 1, evalcost
);
1091 /* Compute per line amount of line-dependent padding,
1092 in tenths of characters. */
1100 tputs (str
, 0, evalcost
);
1103 tputs (str
, 10, evalcost
);
1108 /* char_ins_del_cost[n] is cost of inserting N characters.
1109 char_ins_del_cost[-n] is cost of deleting N characters.
1110 The length of this vector is based on max_frame_cols. */
1112 int *char_ins_del_vector
;
1114 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1119 calculate_ins_del_char_costs (f
)
1122 struct tty_display_info
*tty
= FRAME_TTY (f
);
1123 int ins_startup_cost
, del_startup_cost
;
1124 int ins_cost_per_char
, del_cost_per_char
;
1128 if (tty
->TS_ins_multi_chars
)
1130 ins_cost_per_char
= 0;
1131 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1133 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1134 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1136 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1137 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1138 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1139 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1143 ins_startup_cost
= 9999;
1144 ins_cost_per_char
= 0;
1147 if (tty
->TS_del_multi_chars
)
1149 del_cost_per_char
= 0;
1150 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1152 else if (tty
->TS_del_char
)
1154 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1155 + string_cost (tty
->TS_end_delete_mode
));
1156 if (tty
->delete_in_insert_mode
)
1157 del_startup_cost
/= 2;
1158 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1162 del_startup_cost
= 9999;
1163 del_cost_per_char
= 0;
1166 /* Delete costs are at negative offsets */
1167 p
= &char_ins_del_cost (f
)[0];
1168 for (i
= FRAME_COLS (f
); --i
>= 0;)
1169 *--p
= (del_startup_cost
+= del_cost_per_char
);
1171 /* Doing nothing is free */
1172 p
= &char_ins_del_cost (f
)[0];
1175 /* Insert costs are at positive offsets */
1176 for (i
= FRAME_COLS (f
); --i
>= 0;)
1177 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1181 calculate_costs (frame
)
1184 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1186 if (FRAME_TERMCAP_P (frame
))
1188 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1189 register char *f
= (tty
->TS_set_scroll_region
1190 ? tty
->TS_set_scroll_region
1191 : tty
->TS_set_scroll_region_1
);
1193 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1197 /* These variables are only used for terminal stuff. They are
1198 allocated once for the terminal frame of X-windows emacs, but not
1201 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1202 X turns off char_ins_del_ok. */
1204 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1205 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1207 if (char_ins_del_vector
!= 0)
1209 = (int *) xrealloc (char_ins_del_vector
,
1211 + 2 * max_frame_cols
* sizeof (int)));
1214 = (int *) xmalloc (sizeof (int)
1215 + 2 * max_frame_cols
* sizeof (int));
1217 bzero (char_ins_del_vector
, (sizeof (int)
1218 + 2 * max_frame_cols
* sizeof (int)));
1221 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1222 do_line_insertion_deletion_costs (frame
,
1223 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1224 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1227 do_line_insertion_deletion_costs (frame
,
1228 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1229 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1232 calculate_ins_del_char_costs (frame
);
1234 /* Don't use TS_repeat if its padding is worse than sending the chars */
1235 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1236 tty
->RPov
= string_cost (tty
->TS_repeat
);
1238 tty
->RPov
= FRAME_COLS (frame
) * 2;
1240 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1248 /* Termcap capability names that correspond directly to X keysyms.
1249 Some of these (marked "terminfo") aren't supplied by old-style
1250 (Berkeley) termcap entries. They're listed in X keysym order;
1251 except we put the keypad keys first, so that if they clash with
1252 other keys (as on the IBM PC keyboard) they get overridden.
1255 static struct fkey_table keys
[] =
1257 {"kh", "home"}, /* termcap */
1258 {"kl", "left"}, /* termcap */
1259 {"ku", "up"}, /* termcap */
1260 {"kr", "right"}, /* termcap */
1261 {"kd", "down"}, /* termcap */
1262 {"%8", "prior"}, /* terminfo */
1263 {"%5", "next"}, /* terminfo */
1264 {"@7", "end"}, /* terminfo */
1265 {"@1", "begin"}, /* terminfo */
1266 {"*6", "select"}, /* terminfo */
1267 {"%9", "print"}, /* terminfo */
1268 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1270 * "insert" --- see below
1272 {"&8", "undo"}, /* terminfo */
1273 {"%0", "redo"}, /* terminfo */
1274 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1275 {"@0", "find"}, /* terminfo */
1276 {"@2", "cancel"}, /* terminfo */
1277 {"%1", "help"}, /* terminfo */
1279 * "break" goes here, but can't be reliably intercepted with termcap
1281 {"&4", "reset"}, /* terminfo --- actually `restart' */
1283 * "system" and "user" --- no termcaps
1285 {"kE", "clearline"}, /* terminfo */
1286 {"kA", "insertline"}, /* terminfo */
1287 {"kL", "deleteline"}, /* terminfo */
1288 {"kI", "insertchar"}, /* terminfo */
1289 {"kD", "deletechar"}, /* terminfo */
1290 {"kB", "backtab"}, /* terminfo */
1292 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1294 {"@8", "kp-enter"}, /* terminfo */
1296 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1297 * "kp-multiply", "kp-add", "kp-separator",
1298 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1299 * --- no termcaps for any of these.
1301 {"K4", "kp-1"}, /* terminfo */
1303 * "kp-2" --- no termcap
1305 {"K5", "kp-3"}, /* terminfo */
1307 * "kp-4" --- no termcap
1309 {"K2", "kp-5"}, /* terminfo */
1311 * "kp-6" --- no termcap
1313 {"K1", "kp-7"}, /* terminfo */
1315 * "kp-8" --- no termcap
1317 {"K3", "kp-9"}, /* terminfo */
1319 * "kp-equal" --- no termcap
1332 static char **term_get_fkeys_arg
;
1333 static Lisp_Object
term_get_fkeys_1 ();
1335 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1336 This function scans the termcap function key sequence entries, and
1337 adds entries to Vfunction_key_map for each function key it finds. */
1340 term_get_fkeys (address
)
1343 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1344 errors during the call. The only errors should be from Fdefine_key
1345 when given a key sequence containing an invalid prefix key. If the
1346 termcap defines function keys which use a prefix that is already bound
1347 to a command by the default bindings, we should silently ignore that
1348 function key specification, rather than giving the user an error and
1349 refusing to run at all on such a terminal. */
1351 extern Lisp_Object
Fidentity ();
1352 term_get_fkeys_arg
= address
;
1353 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1361 char **address
= term_get_fkeys_arg
;
1363 /* This can happen if CANNOT_DUMP or with strange options. */
1365 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1367 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1369 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1371 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1372 Fmake_vector (make_number (1),
1373 intern (keys
[i
].name
)));
1376 /* The uses of the "k0" capability are inconsistent; sometimes it
1377 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1378 We will attempt to politely accommodate both systems by testing for
1379 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1382 char *k_semi
= tgetstr ("k;", address
);
1383 char *k0
= tgetstr ("k0", address
);
1384 char *k0_name
= "f10";
1389 /* Define f0 first, so that f10 takes precedence in case the
1390 key sequences happens to be the same. */
1391 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1392 Fmake_vector (make_number (1), intern ("f0")));
1393 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1394 Fmake_vector (make_number (1), intern ("f10")));
1397 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1398 Fmake_vector (make_number (1), intern (k0_name
)));
1401 /* Set up cookies for numbered function keys above f10. */
1403 char fcap
[3], fkey
[4];
1405 fcap
[0] = 'F'; fcap
[2] = '\0';
1406 for (i
= 11; i
< 64; i
++)
1409 fcap
[1] = '1' + i
- 11;
1411 fcap
[1] = 'A' + i
- 20;
1413 fcap
[1] = 'a' + i
- 46;
1416 char *sequence
= tgetstr (fcap
, address
);
1419 sprintf (fkey
, "f%d", i
);
1420 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1421 Fmake_vector (make_number (1),
1429 * Various mappings to try and get a better fit.
1432 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1433 if (!tgetstr (cap1, address)) \
1435 char *sequence = tgetstr (cap2, address); \
1437 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1438 Fmake_vector (make_number (1), \
1442 /* if there's no key_next keycap, map key_npage to `next' keysym */
1443 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1444 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1445 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1446 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1447 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1448 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1449 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1451 /* IBM has their own non-standard dialect of terminfo.
1452 If the standard name isn't found, try the IBM name. */
1453 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1454 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1455 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1456 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1457 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1458 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1459 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1460 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1461 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1462 #undef CONDITIONAL_REASSIGN
1469 /***********************************************************************
1470 Character Display Information
1471 ***********************************************************************/
1473 static void append_glyph
P_ ((struct it
*));
1476 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1477 terminal frames if IT->glyph_row != NULL. IT->c is the character
1478 for which to produce glyphs; IT->face_id contains the character's
1479 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1486 struct glyph
*glyph
, *end
;
1489 xassert (it
->glyph_row
);
1490 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1491 + it
->glyph_row
->used
[it
->area
]);
1492 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1495 i
< it
->pixel_width
&& glyph
< end
;
1498 glyph
->type
= CHAR_GLYPH
;
1499 glyph
->pixel_width
= 1;
1500 glyph
->u
.ch
= it
->c
;
1501 glyph
->face_id
= it
->face_id
;
1502 glyph
->padding_p
= i
> 0;
1503 glyph
->charpos
= CHARPOS (it
->position
);
1504 glyph
->object
= it
->object
;
1506 ++it
->glyph_row
->used
[it
->area
];
1512 /* Produce glyphs for the display element described by IT. *IT
1513 specifies what we want to produce a glyph for (character, image, ...),
1514 and where in the glyph matrix we currently are (glyph row and hpos).
1515 produce_glyphs fills in output fields of *IT with information such as the
1516 pixel width and height of a character, and maybe output actual glyphs at
1517 the same time if IT->glyph_row is non-null. See the explanation of
1518 struct display_iterator in dispextern.h for an overview.
1520 produce_glyphs also stores the result of glyph width, ascent
1521 etc. computations in *IT.
1523 IT->glyph_row may be null, in which case produce_glyphs does not
1524 actually fill in the glyphs. This is used in the move_* functions
1525 in xdisp.c for text width and height computations.
1527 Callers usually don't call produce_glyphs directly;
1528 instead they use the macro PRODUCE_GLYPHS. */
1534 /* If a hook is installed, let it do the work. */
1535 xassert (it
->what
== IT_CHARACTER
1536 || it
->what
== IT_COMPOSITION
1537 || it
->what
== IT_IMAGE
1538 || it
->what
== IT_STRETCH
);
1540 /* Nothing but characters are supported on terminal frames. For a
1541 composition sequence, it->c is the first character of the
1543 xassert (it
->what
== IT_CHARACTER
1544 || it
->what
== IT_COMPOSITION
);
1546 if (it
->c
>= 040 && it
->c
< 0177)
1548 it
->pixel_width
= it
->nglyphs
= 1;
1552 else if (it
->c
== '\n')
1553 it
->pixel_width
= it
->nglyphs
= 0;
1554 else if (it
->c
== '\t')
1556 int absolute_x
= (it
->current_x
1557 + it
->continuation_lines_width
);
1559 = (((1 + absolute_x
+ it
->tab_width
- 1)
1564 /* If part of the TAB has been displayed on the previous line
1565 which is continued now, continuation_lines_width will have
1566 been incremented already by the part that fitted on the
1567 continued line. So, we will get the right number of spaces
1569 nspaces
= next_tab_x
- absolute_x
;
1576 it
->pixel_width
= it
->len
= 1;
1584 it
->pixel_width
= nspaces
;
1585 it
->nglyphs
= nspaces
;
1587 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1589 /* Coming here means that it->c is from display table, thus we
1590 must send the code as is to the terminal. Although there's
1591 no way to know how many columns it occupies on a screen, it
1592 is a good assumption that a single byte code has 1-column
1594 it
->pixel_width
= it
->nglyphs
= 1;
1600 /* A multi-byte character. The display width is fixed for all
1601 characters of the set. Some of the glyphs may have to be
1602 ignored because they are already displayed in a continued
1604 int charset
= CHAR_CHARSET (it
->c
);
1606 it
->pixel_width
= CHARSET_WIDTH (charset
);
1607 it
->nglyphs
= it
->pixel_width
;
1613 /* Advance current_x by the pixel width as a convenience for
1615 if (it
->area
== TEXT_AREA
)
1616 it
->current_x
+= it
->pixel_width
;
1617 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1618 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1622 /* Get information about special display element WHAT in an
1623 environment described by IT. WHAT is one of IT_TRUNCATION or
1624 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1625 non-null glyph_row member. This function ensures that fields like
1626 face_id, c, len of IT are left untouched. */
1629 produce_special_glyphs (it
, what
)
1631 enum display_element_type what
;
1637 temp_it
.what
= IT_CHARACTER
;
1639 temp_it
.object
= make_number (0);
1640 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1642 if (what
== IT_CONTINUATION
)
1644 /* Continuation glyph. */
1646 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1647 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1649 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it
->dp
)));
1650 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1655 produce_glyphs (&temp_it
);
1656 it
->pixel_width
= temp_it
.pixel_width
;
1657 it
->nglyphs
= temp_it
.pixel_width
;
1659 else if (what
== IT_TRUNCATION
)
1661 /* Truncation glyph. */
1663 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1664 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1666 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it
->dp
)));
1667 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1672 produce_glyphs (&temp_it
);
1673 it
->pixel_width
= temp_it
.pixel_width
;
1674 it
->nglyphs
= temp_it
.pixel_width
;
1682 /***********************************************************************
1684 ***********************************************************************/
1686 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1687 one of the enumerators from enum no_color_bit, or a bit set built
1688 from them. Some display attributes may not be used together with
1689 color; the termcap capability `NC' specifies which ones. */
1691 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1692 (tty->TN_max_colors > 0 \
1693 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1696 /* Turn appearances of face FACE_ID on tty frame F on. */
1699 turn_on_face (f
, face_id
)
1703 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1704 long fg
= face
->foreground
;
1705 long bg
= face
->background
;
1706 struct tty_display_info
*tty
= FRAME_TTY (f
);
1708 /* Do this first because TS_end_standout_mode may be the same
1709 as TS_exit_attribute_mode, which turns all appearances off. */
1710 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1712 if (tty
->TN_max_colors
> 0)
1714 if (fg
>= 0 && bg
>= 0)
1716 /* If the terminal supports colors, we can set them
1717 below without using reverse video. The face's fg
1718 and bg colors are set as they should appear on
1719 the screen, i.e. they take the inverse-video'ness
1720 of the face already into account. */
1722 else if (inverse_video
)
1724 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1725 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1726 toggle_highlight (tty
);
1730 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1731 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1732 toggle_highlight (tty
);
1737 /* If we can't display colors, use reverse video
1738 if the face specifies that. */
1741 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1742 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1743 toggle_highlight (tty
);
1747 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1748 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1749 toggle_highlight (tty
);
1754 if (face
->tty_bold_p
)
1756 if (MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1757 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1759 else if (face
->tty_dim_p
)
1760 if (MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1761 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1763 /* Alternate charset and blinking not yet used. */
1764 if (face
->tty_alt_charset_p
1765 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1766 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1768 if (face
->tty_blinking_p
1769 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1770 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1772 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1773 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1775 if (tty
->TN_max_colors
> 0)
1779 if (fg
>= 0 && tty
->TS_set_foreground
)
1781 p
= tparam (tty
->TS_set_foreground
, NULL
, 0, (int) fg
);
1786 if (bg
>= 0 && tty
->TS_set_background
)
1788 p
= tparam (tty
->TS_set_background
, NULL
, 0, (int) bg
);
1796 /* Turn off appearances of face FACE_ID on tty frame F. */
1799 turn_off_face (f
, face_id
)
1803 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1804 struct tty_display_info
*tty
= FRAME_TTY (f
);
1806 xassert (face
!= NULL
);
1808 if (tty
->TS_exit_attribute_mode
)
1810 /* Capability "me" will turn off appearance modes double-bright,
1811 half-bright, reverse-video, standout, underline. It may or
1812 may not turn off alt-char-mode. */
1813 if (face
->tty_bold_p
1815 || face
->tty_reverse_p
1816 || face
->tty_alt_charset_p
1817 || face
->tty_blinking_p
1818 || face
->tty_underline_p
)
1820 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
1821 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
1822 tty
->standout_mode
= 0;
1825 if (face
->tty_alt_charset_p
)
1826 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1830 /* If we don't have "me" we can only have those appearances
1831 that have exit sequences defined. */
1832 if (face
->tty_alt_charset_p
)
1833 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1835 if (face
->tty_underline_p
)
1836 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
1839 /* Switch back to default colors. */
1840 if (tty
->TN_max_colors
> 0
1841 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
1842 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
1843 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
1844 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
1845 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
1849 /* Return non-zero if the terminal on frame F supports all of the
1850 capabilities in CAPS simultaneously, with foreground and background
1851 colors FG and BG. */
1854 tty_capable_p (tty
, caps
, fg
, bg
)
1855 struct tty_display_info
*tty
;
1857 unsigned long fg
, bg
;
1859 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
1860 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
1863 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
1864 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
1865 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
1866 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
1867 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
1868 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
1874 /* Return the tty display object specified by DISPLAY.
1875 DISPLAY may be a frame or a string. */
1877 static struct display
*
1878 get_tty_display (Lisp_Object display
)
1882 if (! FRAMEP (display
) && ! STRINGP (display
))
1885 /* The initial frame does not support colors. */
1886 if (FRAMEP (display
) && FRAME_INITIAL_P (XFRAME (display
)))
1889 if (FRAMEP (display
))
1891 if (! FRAME_TERMCAP_P (XFRAME (display
)))
1892 #if 0 /* XXX We need a predicate as the first argument; find one. */
1893 wrong_type_argument ("Not a termcap frame", display
);
1894 #else /* Until we fix the wrong_type_argument call above, simply throw
1896 error ("DISPLAY is not a termcap frame");
1899 d
= FRAME_DISPLAY (XFRAME (display
));
1901 else if (STRINGP (display
))
1903 char *name
= (char *) alloca (SBYTES (display
) + 1);
1904 strncpy (name
, SDATA (display
), SBYTES (display
));
1905 name
[SBYTES (display
)] = 0;
1907 d
= get_named_tty_display (name
);
1910 error ("There is no tty display on %s", name
);
1917 /* Return non-zero if the terminal is capable to display colors. */
1919 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
1921 doc
: /* Return non-nil if TTY can display colors on DISPLAY. */)
1923 Lisp_Object display
;
1925 struct display
*d
= get_tty_display (display
);
1929 return d
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
1932 /* Return the number of supported colors. */
1933 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
1934 Stty_display_color_cells
, 0, 1, 0,
1935 doc
: /* Return the number of colors supported by TTY on DISPLAY. */)
1937 Lisp_Object display
;
1939 struct display
*d
= get_tty_display (display
);
1943 return make_number (d
->display_info
.tty
->TN_max_colors
);
1948 /* Save or restore the default color-related capabilities of this
1951 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
1954 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
1955 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
1959 if (default_orig_pair
)
1960 xfree (default_orig_pair
);
1961 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
1963 if (default_set_foreground
)
1964 xfree (default_set_foreground
);
1965 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
1968 if (default_set_background
)
1969 xfree (default_set_background
);
1970 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
1973 default_max_colors
= tty
->TN_max_colors
;
1974 default_max_pairs
= tty
->TN_max_pairs
;
1975 default_no_color_video
= tty
->TN_no_color_video
;
1979 tty
->TS_orig_pair
= default_orig_pair
;
1980 tty
->TS_set_foreground
= default_set_foreground
;
1981 tty
->TS_set_background
= default_set_background
;
1982 tty
->TN_max_colors
= default_max_colors
;
1983 tty
->TN_max_pairs
= default_max_pairs
;
1984 tty
->TN_no_color_video
= default_no_color_video
;
1988 /* Setup one of the standard tty color schemes according to MODE.
1989 MODE's value is generally the number of colors which we want to
1990 support; zero means set up for the default capabilities, the ones
1991 we saw at term_init time; -1 means turn off color support. */
1993 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
1995 /* Canonicalize all negative values of MODE. */
2001 case -1: /* no colors at all */
2002 tty
->TN_max_colors
= 0;
2003 tty
->TN_max_pairs
= 0;
2004 tty
->TN_no_color_video
= 0;
2005 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2007 case 0: /* default colors, if any */
2009 tty_default_color_capabilities (tty
, 0);
2011 case 8: /* 8 standard ANSI colors */
2012 tty
->TS_orig_pair
= "\033[0m";
2014 tty
->TS_set_foreground
= "\033[3%p1%dm";
2015 tty
->TS_set_background
= "\033[4%p1%dm";
2017 tty
->TS_set_foreground
= "\033[3%dm";
2018 tty
->TS_set_background
= "\033[4%dm";
2020 tty
->TN_max_colors
= 8;
2021 tty
->TN_max_pairs
= 64;
2022 tty
->TN_no_color_video
= 0;
2028 set_tty_color_mode (f
, val
)
2032 Lisp_Object color_mode_spec
, current_mode_spec
;
2033 Lisp_Object color_mode
, current_mode
;
2035 extern Lisp_Object Qtty_color_mode
;
2036 Lisp_Object tty_color_mode_alist
;
2038 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2045 if (NILP (tty_color_mode_alist
))
2046 color_mode_spec
= Qnil
;
2048 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2050 if (CONSP (color_mode_spec
))
2051 color_mode
= XCDR (color_mode_spec
);
2056 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2058 if (CONSP (current_mode_spec
))
2059 current_mode
= XCDR (current_mode_spec
);
2061 current_mode
= Qnil
;
2062 if (INTEGERP (color_mode
))
2063 mode
= XINT (color_mode
);
2065 mode
= 0; /* meaning default */
2066 if (INTEGERP (current_mode
))
2067 old_mode
= XINT (current_mode
);
2071 if (mode
!= old_mode
)
2073 tty_setup_colors (FRAME_TTY (f
), mode
);
2074 /* This recomputes all the faces given the new color
2076 call0 (intern ("tty-set-up-initial-frame-faces"));
2081 #endif /* !WINDOWSNT */
2086 get_named_tty_display (name
)
2091 for (d
= display_list
; d
; d
= d
->next_display
) {
2092 if (d
->type
== output_termcap
2093 && ((d
->display_info
.tty
->name
== 0 && name
== 0)
2094 || (name
&& d
->display_info
.tty
->name
2095 && !strcmp (d
->display_info
.tty
->name
, name
))))
2104 DEFUN ("frame-tty-name", Fframe_tty_name
, Sframe_tty_name
, 0, 1, 0,
2105 doc
: /* Return the name of the TTY device that FRAME is displayed on. */)
2113 f
= XFRAME (selected_frame
);
2117 CHECK_LIVE_FRAME (frame
);
2121 if (f
->output_method
!= output_termcap
)
2122 wrong_type_argument (Qframe_tty_name
, frame
);
2124 if (FRAME_TTY (f
)->name
)
2125 return build_string (FRAME_TTY (f
)->name
);
2130 DEFUN ("frame-tty-type", Fframe_tty_type
, Sframe_tty_type
, 0, 1, 0,
2131 doc
: /* Return the type of the TTY device that FRAME is displayed on. */)
2139 f
= XFRAME (selected_frame
);
2143 CHECK_LIVE_FRAME (frame
);
2147 if (f
->output_method
!= output_termcap
)
2148 wrong_type_argument (Qframe_tty_type
, frame
);
2150 if (FRAME_TTY (f
)->type
)
2151 return build_string (FRAME_TTY (f
)->type
);
2157 /***********************************************************************
2159 ***********************************************************************/
2161 /* Create the bootstrap display device for the initial frame.
2163 Returns a display of type output_initial. */
2165 init_initial_display (void)
2167 struct tty_display_info
*tty
;
2169 if (initialized
|| display_list
|| tty_list
)
2172 initial_display
= create_display ();
2173 initial_display
->type
= output_initial
;
2175 initial_display
->delete_display_hook
= &delete_initial_display
;
2176 /* All other hooks are NULL. */
2178 return initial_display
;
2181 /* Deletes the bootstrap display device.
2182 Called through delete_display_hook. */
2184 delete_initial_display (struct display
*display
)
2186 if (display
!= initial_display
)
2189 delete_display (display
);
2190 initial_display
= NULL
;
2193 /* Create a termcap display on the tty device with the given name and
2196 If NAME is NULL, then use the controlling tty, i.e., stdin/stdout.
2197 Otherwise NAME should be a path to the tty device file,
2200 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
2202 If MUST_SUCCEED is true, then all errors are fatal. */
2204 term_init (char *name
, char *terminal_type
, int must_succeed
)
2207 char **address
= &area
;
2208 char *buffer
= NULL
;
2209 int buffer_size
= 4096;
2212 struct tty_display_info
*tty
;
2213 struct display
*display
;
2215 static void maybe_fatal();
2218 maybe_fatal (must_succeed
, 0, 0,
2219 "Unknown terminal type",
2220 "Unknown terminal type");
2222 display
= get_named_tty_display (name
);
2224 return display
; /* We have already opened a display there. */
2226 display
= create_display ();
2227 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
2228 bzero (tty
, sizeof (struct tty_display_info
));
2229 tty
->next
= tty_list
;
2232 display
->type
= output_termcap
;
2233 display
->display_info
.tty
= tty
;
2234 tty
->display
= display
;
2236 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
2239 display
->rif
= 0; /* ttys don't support window-based redisplay. */
2241 display
->cursor_to_hook
= &tty_cursor_to
;
2242 display
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
2244 display
->clear_to_end_hook
= &tty_clear_to_end
;
2245 display
->clear_frame_hook
= &tty_clear_frame
;
2246 display
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
2248 display
->ins_del_lines_hook
= &tty_ins_del_lines
;
2250 display
->insert_glyphs_hook
= &tty_insert_glyphs
;
2251 display
->write_glyphs_hook
= &tty_write_glyphs
;
2252 display
->delete_glyphs_hook
= &tty_delete_glyphs
;
2254 display
->ring_bell_hook
= &tty_ring_bell
;
2256 display
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
2257 display
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
2258 display
->update_begin_hook
= 0; /* Not needed. */
2259 display
->update_end_hook
= &tty_update_end
;
2260 display
->set_terminal_window_hook
= &tty_set_terminal_window
;
2262 display
->mouse_position_hook
= 0; /* Not needed. */
2263 display
->frame_rehighlight_hook
= 0; /* Not needed. */
2264 display
->frame_raise_lower_hook
= 0; /* Not needed. */
2266 display
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
2267 display
->condemn_scroll_bars_hook
= 0; /* Not needed. */
2268 display
->redeem_scroll_bar_hook
= 0; /* Not needed. */
2269 display
->judge_scroll_bars_hook
= 0; /* Not needed. */
2271 display
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
2272 display
->frame_up_to_date_hook
= 0; /* Not needed. */
2274 display
->delete_frame_hook
= &delete_tty_output
;
2275 display
->delete_display_hook
= &delete_tty
;
2281 fd
= emacs_open (name
, O_RDWR
, 0);
2284 delete_tty (display
);
2285 error ("Could not open file: %s", name
);
2287 file
= fdopen (fd
, "w+");
2288 tty
->name
= xstrdup (name
);
2296 tty
->output
= stdout
;
2299 tty
->type
= xstrdup (terminal_type
);
2301 add_keyboard_wait_descriptor (fileno (tty
->input
));
2304 initialize_w32_display ();
2308 area
= (char *) xmalloc (2044);
2310 FrameRows (tty
) = FRAME_LINES (f
); /* XXX */
2311 FrameCols (tty
) = FRAME_COLS (f
); /* XXX */
2312 tty
->specified_window
= FRAME_LINES (f
); /* XXX */
2314 tty
->display
->delete_in_insert_mode
= 1;
2317 display
->scroll_region_ok
= 0;
2319 /* Seems to insert lines when it's not supposed to, messing
2320 up the display. In doing a trace, it didn't seem to be
2321 called much, so I don't think we're losing anything by
2323 display
->line_ins_del_ok
= 0;
2324 display
->char_ins_del_ok
= 1;
2328 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0; /* XXX */
2329 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
; /* XXX */
2330 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2333 #else /* not WINDOWSNT */
2337 buffer
= (char *) xmalloc (buffer_size
);
2338 status
= tgetent (buffer
, terminal_type
);
2342 maybe_fatal (must_succeed
, buffer
, display
,
2343 "Cannot open terminfo database file",
2344 "Cannot open terminfo database file");
2346 maybe_fatal (must_succeed
, buffer
, display
,
2347 "Cannot open termcap database file",
2348 "Cannot open termcap database file");
2354 maybe_fatal (must_succeed
, buffer
, display
,
2355 "Terminal type %s is not defined",
2356 "Terminal type %s is not defined.\n\
2357 If that is not the actual type of terminal you have,\n\
2358 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2359 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2360 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2363 maybe_fatal (must_succeed
, buffer
, display
,
2364 "Terminal type %s is not defined",
2365 "Terminal type %s is not defined.\n\
2366 If that is not the actual type of terminal you have,\n\
2367 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2368 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2369 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2375 if (strlen (buffer
) >= buffer_size
)
2377 buffer_size
= strlen (buffer
);
2379 area
= (char *) xmalloc (buffer_size
);
2381 tty
->TS_ins_line
= tgetstr ("al", address
);
2382 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
2383 tty
->TS_bell
= tgetstr ("bl", address
);
2384 BackTab (tty
) = tgetstr ("bt", address
);
2385 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
2386 tty
->TS_clr_line
= tgetstr ("ce", address
);
2387 tty
->TS_clr_frame
= tgetstr ("cl", address
);
2388 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
2389 AbsPosition (tty
) = tgetstr ("cm", address
);
2390 CR (tty
) = tgetstr ("cr", address
);
2391 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
2392 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
2393 RowPosition (tty
) = tgetstr ("cv", address
);
2394 tty
->TS_del_char
= tgetstr ("dc", address
);
2395 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
2396 tty
->TS_del_line
= tgetstr ("dl", address
);
2397 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
2398 tty
->TS_delete_mode
= tgetstr ("dm", address
);
2399 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
2400 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
2401 Home (tty
) = tgetstr ("ho", address
);
2402 tty
->TS_ins_char
= tgetstr ("ic", address
);
2403 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
2404 tty
->TS_insert_mode
= tgetstr ("im", address
);
2405 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
2406 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
2407 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
2408 LastLine (tty
) = tgetstr ("ll", address
);
2409 Right (tty
) = tgetstr ("nd", address
);
2410 Down (tty
) = tgetstr ("do", address
);
2412 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
2414 /* VMS puts a carriage return before each linefeed,
2415 so it is not safe to use linefeeds. */
2416 if (Down (tty
) && Down (tty
)[0] == '\n' && Down (tty
)[1] == '\0')
2419 if (tgetflag ("bs"))
2420 Left (tty
) = "\b"; /* can't possibly be longer! */
2421 else /* (Actually, "bs" is obsolete...) */
2422 Left (tty
) = tgetstr ("le", address
);
2424 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
2425 tty
->TS_pad_char
= tgetstr ("pc", address
);
2426 tty
->TS_repeat
= tgetstr ("rp", address
);
2427 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
2428 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
2429 tty
->TS_standout_mode
= tgetstr ("so", address
);
2430 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
2431 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
2432 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
2433 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
2434 Up (tty
) = tgetstr ("up", address
);
2435 tty
->TS_visible_bell
= tgetstr ("vb", address
);
2436 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
2437 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
2438 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
2439 tty
->TS_set_window
= tgetstr ("wi", address
);
2441 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
2442 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
2443 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
2444 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
2445 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
2446 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
2447 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2448 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2449 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
2451 MultiUp (tty
) = tgetstr ("UP", address
);
2452 MultiDown (tty
) = tgetstr ("DO", address
);
2453 MultiLeft (tty
) = tgetstr ("LE", address
);
2454 MultiRight (tty
) = tgetstr ("RI", address
);
2456 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2457 color because we can't switch back to the default foreground and
2459 tty
->TS_orig_pair
= tgetstr ("op", address
);
2460 if (tty
->TS_orig_pair
)
2462 tty
->TS_set_foreground
= tgetstr ("AF", address
);
2463 tty
->TS_set_background
= tgetstr ("AB", address
);
2464 if (!tty
->TS_set_foreground
)
2467 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
2468 tty
->TS_set_background
= tgetstr ("Sb", address
);
2471 tty
->TN_max_colors
= tgetnum ("Co");
2472 tty
->TN_max_pairs
= tgetnum ("pa");
2474 tty
->TN_no_color_video
= tgetnum ("NC");
2475 if (tty
->TN_no_color_video
== -1)
2476 tty
->TN_no_color_video
= 0;
2479 tty_default_color_capabilities (tty
, 1);
2481 MagicWrap (tty
) = tgetflag ("xn");
2482 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2483 the former flag imply the latter. */
2484 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
2485 display
->memory_below_frame
= tgetflag ("db");
2486 tty
->TF_hazeltine
= tgetflag ("hz");
2487 display
->must_write_spaces
= tgetflag ("in");
2488 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
2489 tty
->TF_insmode_motion
= tgetflag ("mi");
2490 tty
->TF_standout_motion
= tgetflag ("ms");
2491 tty
->TF_underscore
= tgetflag ("ul");
2492 tty
->TF_teleray
= tgetflag ("xt");
2494 term_get_fkeys (address
);
2496 /* Get frame size from system, or else from termcap. */
2499 get_tty_size (fileno (TTY_INPUT (tty
)), &width
, &height
);
2500 FrameCols (tty
) = width
;
2501 FrameRows (tty
) = height
;
2504 if (FrameCols (tty
) <= 0)
2505 FrameCols (tty
) = tgetnum ("co");
2506 if (FrameRows (tty
) <= 0)
2507 FrameRows (tty
) = tgetnum ("li");
2509 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
2510 maybe_fatal (must_succeed
, NULL
, display
,
2511 "Screen size %dx%d is too small"
2512 "Screen size %dx%d is too small",
2513 FrameCols (tty
), FrameRows (tty
));
2515 #if 0 /* This is not used anywhere. */
2516 tty
->display
->min_padding_speed
= tgetnum ("pb");
2519 TabWidth (tty
) = tgetnum ("tw");
2522 /* These capabilities commonly use ^J.
2523 I don't know why, but sending them on VMS does not work;
2524 it causes following spaces to be lost, sometimes.
2525 For now, the simplest fix is to avoid using these capabilities ever. */
2526 if (Down (tty
) && Down (tty
)[0] == '\n')
2531 tty
->TS_bell
= "\07";
2533 if (!tty
->TS_fwd_scroll
)
2534 tty
->TS_fwd_scroll
= Down (tty
);
2536 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
2538 if (TabWidth (tty
) < 0)
2541 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2542 and newer termcap doc does not seem to say there is a default.
2543 if (!tty->Wcm->cm_tab)
2544 tty->Wcm->cm_tab = "\t";
2547 /* We don't support standout modes that use `magic cookies', so
2548 turn off any that do. */
2549 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
2551 tty
->TS_standout_mode
= 0;
2552 tty
->TS_end_standout_mode
= 0;
2554 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
2556 tty
->TS_enter_underline_mode
= 0;
2557 tty
->TS_exit_underline_mode
= 0;
2560 /* If there's no standout mode, try to use underlining instead. */
2561 if (tty
->TS_standout_mode
== 0)
2563 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
2564 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
2567 /* If no `se' string, try using a `me' string instead.
2568 If that fails, we can't use standout mode at all. */
2569 if (tty
->TS_end_standout_mode
== 0)
2571 char *s
= tgetstr ("me", address
);
2573 tty
->TS_end_standout_mode
= s
;
2575 tty
->TS_standout_mode
= 0;
2578 if (tty
->TF_teleray
)
2580 tty
->Wcm
->cm_tab
= 0;
2581 /* We can't support standout mode, because it uses magic cookies. */
2582 tty
->TS_standout_mode
= 0;
2583 /* But that means we cannot rely on ^M to go to column zero! */
2585 /* LF can't be trusted either -- can alter hpos */
2586 /* if move at column 0 thru a line with TS_standout_mode */
2590 /* Special handling for certain terminal types known to need it */
2592 if (!strcmp (terminal_type
, "supdup"))
2594 display
->memory_below_frame
= 1;
2595 tty
->Wcm
->cm_losewrap
= 1;
2597 if (!strncmp (terminal_type
, "c10", 3)
2598 || !strcmp (terminal_type
, "perq"))
2600 /* Supply a makeshift :wi string.
2601 This string is not valid in general since it works only
2602 for windows starting at the upper left corner;
2603 but that is all Emacs uses.
2605 This string works only if the frame is using
2606 the top of the video memory, because addressing is memory-relative.
2607 So first check the :ti string to see if that is true.
2609 It would be simpler if the :wi string could go in the termcap
2610 entry, but it can't because it is not fully valid.
2611 If it were in the termcap entry, it would confuse other programs. */
2612 if (!tty
->TS_set_window
)
2614 p
= tty
->TS_termcap_modes
;
2615 while (*p
&& strcmp (p
, "\033v "))
2618 tty
->TS_set_window
= "\033v%C %C %C %C ";
2620 /* Termcap entry often fails to have :in: flag */
2621 display
->must_write_spaces
= 1;
2622 /* :ti string typically fails to have \E^G! in it */
2623 /* This limits scope of insert-char to one line. */
2624 strcpy (area
, tty
->TS_termcap_modes
);
2625 strcat (area
, "\033\007!");
2626 tty
->TS_termcap_modes
= area
;
2627 area
+= strlen (area
) + 1;
2628 p
= AbsPosition (tty
);
2629 /* Change all %+ parameters to %C, to handle
2630 values above 96 correctly for the C100. */
2633 if (p
[0] == '%' && p
[1] == '+')
2639 tty
->specified_window
= FrameRows (tty
);
2641 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
2643 maybe_fatal (must_succeed
, NULL
, display
,
2644 "Terminal type \"%s\" is not powerful enough to run Emacs",
2646 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2647 It lacks the ability to position the cursor.\n\
2648 If that is not the actual type of terminal you have, use either the\n\
2649 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2650 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2653 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2654 It lacks the ability to position the cursor.\n\
2655 If that is not the actual type of terminal you have,\n\
2656 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2657 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2658 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2659 # else /* TERMCAP */
2660 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2661 It lacks the ability to position the cursor.\n\
2662 If that is not the actual type of terminal you have,\n\
2663 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2664 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2665 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2666 # endif /* TERMINFO */
2671 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
2672 maybe_fatal (must_succeed
, NULL
, display
,
2673 "Could not determine the frame size",
2674 "Could not determine the frame size");
2676 tty
->delete_in_insert_mode
2677 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
2678 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
2680 tty
->se_is_so
= (tty
->TS_standout_mode
2681 && tty
->TS_end_standout_mode
2682 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
2684 UseTabs (tty
) = tabs_safe_p (fileno (TTY_INPUT (tty
))) && TabWidth (tty
) == 8;
2686 display
->scroll_region_ok
2688 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
2690 display
->line_ins_del_ok
2691 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
2692 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
2693 || (display
->scroll_region_ok
2694 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
2696 display
->char_ins_del_ok
2697 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
2698 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
2699 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
2701 display
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
2703 init_baud_rate (fileno (TTY_INPUT (tty
)));
2706 /* The HFT system on AIX doesn't optimize for scrolling, so it's
2707 really ugly at times. */
2708 display
->line_ins_del_ok
= 0;
2709 display
->char_ins_del_ok
= 0;
2713 tty
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
2714 init_kboard (tty
->kboard
);
2715 tty
->kboard
->next_kboard
= all_kboards
;
2716 all_kboards
= tty
->kboard
;
2717 /* Don't let the initial kboard remain current longer than necessary.
2718 That would cause problems if a file loaded on startup tries to
2719 prompt in the mini-buffer. */
2720 if (current_kboard
== initial_kboard
)
2721 current_kboard
= tty
->kboard
;
2722 tty
->kboard
->reference_count
++;
2725 /* Don't do this. I think termcap may still need the buffer. */
2726 /* xfree (buffer); */
2728 /* Init system terminal modes (RAW or CBREAK, etc.). */
2729 init_sys_modes (tty
);
2732 #endif /* not WINDOWSNT */
2735 /* Auxiliary error-handling function for term_init.
2736 Free BUFFER and delete DISPLAY, then call error or fatal
2737 with str1 or str2, respectively, according to MUST_SUCCEED.
2740 maybe_fatal (must_succeed
, buffer
, display
, str1
, str2
, arg1
, arg2
)
2743 struct display
*display
;
2744 char *str1
, *str2
, *arg1
, *arg2
;
2750 delete_tty (display
);
2753 fatal (str2
, arg1
, arg2
);
2755 error (str1
, arg1
, arg2
);
2762 fatal (str
, arg1
, arg2
)
2763 char *str
, *arg1
, *arg2
;
2765 fprintf (stderr
, "emacs: ");
2766 fprintf (stderr
, str
, arg1
, arg2
);
2767 fprintf (stderr
, "\n");
2774 DEFUN ("delete-tty", Fdelete_tty
, Sdelete_tty
, 0, 1, 0,
2775 doc
: /* Delete all frames on the terminal named TTY, and close the device.
2776 If omitted, TTY defaults to the controlling terminal.
2778 This function runs `delete-tty-after-functions' after closing the
2779 tty. The functions are run with one arg, the frame to be deleted. */)
2788 if (SBYTES (tty
) > 0)
2790 name
= (char *) alloca (SBYTES (tty
) + 1);
2791 strncpy (name
, SDATA (tty
), SBYTES (tty
));
2792 name
[SBYTES (tty
)] = 0;
2795 d
= get_named_tty_display (name
);
2798 error ("No such terminal device: %s", name
);
2803 static int deleting_tty
= 0;
2806 delete_tty (struct display
*display
)
2808 struct tty_display_info
*tty
;
2809 Lisp_Object tail
, frame
;
2813 /* We get a recursive call when we delete the last frame on this
2819 if (display
->type
!= output_termcap
)
2822 tty
= display
->display_info
.tty
;
2824 if (tty
== tty_list
)
2825 tty_list
= tty
->next
;
2828 struct tty_display_info
*p
;
2829 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
2833 /* This should not happen. */
2836 p
->next
= tty
->next
;
2840 FOR_EACH_FRAME (tail
, frame
)
2842 struct frame
*f
= XFRAME (frame
);
2843 if (FRAME_TERMCAP_P (f
) && FRAME_LIVE_P (f
) && FRAME_TTY (f
) == tty
)
2845 Fdelete_frame (frame
, Qt
);
2846 f
->output_data
.tty
= 0;
2850 /* reset_sys_modes needs a valid display, so this call needs to be
2851 before delete_display. */
2852 reset_sys_modes (tty
);
2854 delete_display (display
);
2856 tty_name
= tty
->name
;
2862 delete_keyboard_wait_descriptor (fileno (tty
->input
));
2863 if (tty
->input
!= stdin
)
2864 fclose (tty
->input
);
2866 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
2867 fclose (tty
->output
);
2868 if (tty
->termscript
)
2869 fclose (tty
->termscript
);
2872 xfree (tty
->old_tty
);
2878 if (tty
->kboard
&& --tty
->kboard
->reference_count
> 0)
2881 delete_kboard (tty
->kboard
);
2884 bzero (tty
, sizeof (struct tty_display_info
));
2888 /* Run `delete-tty-after-functions'. */
2889 if (!NILP (Vrun_hooks
))
2891 Lisp_Object args
[2];
2892 args
[0] = intern ("delete-tty-after-functions");
2895 args
[1] = build_string (tty_name
);
2900 Frun_hook_with_args (2, args
);
2906 /* Initialize the tty-dependent part of frame F. The frame must
2907 already have its display initialized. */
2909 create_tty_output (struct frame
*f
)
2911 struct tty_output
*t
;
2913 if (! FRAME_TERMCAP_P (f
))
2916 t
= xmalloc (sizeof (struct tty_output
));
2917 bzero (t
, sizeof (struct tty_output
));
2919 t
->display_info
= FRAME_DISPLAY (f
)->display_info
.tty
;
2921 f
->output_data
.tty
= t
;
2924 /* Delete the tty-dependent part of frame F. */
2926 delete_tty_output (struct frame
*f
)
2928 if (! FRAME_TERMCAP_P (f
))
2931 xfree (f
->output_data
.tty
);
2937 /* Mark the pointers in the tty_display_info objects.
2938 Called by the Fgarbage_collector. */
2942 struct tty_display_info
*tty
;
2944 for (tty
= tty_list
; tty
; tty
= tty
->next
)
2947 mark_object (tty
->top_frame
);
2953 /* Create a new display object and add it to the display list. */
2955 create_display (void)
2957 struct display
*dev
= (struct display
*) xmalloc (sizeof (struct display
));
2959 bzero (dev
, sizeof (struct display
));
2960 dev
->next_display
= display_list
;
2966 /* Remove a display from the display list and free its memory. */
2968 delete_display (struct display
*dev
)
2970 struct display
**dp
;
2971 for (dp
= &display_list
; *dp
!= dev
; dp
= &(*dp
)->next_display
)
2974 *dp
= dev
->next_display
;
2976 bzero (dev
, sizeof (struct display
));
2985 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
2986 doc
: /* Non-nil means the system uses terminfo rather than termcap.
2987 This variable can be used by terminal emulator packages. */);
2989 system_uses_terminfo
= 1;
2991 system_uses_terminfo
= 0;
2994 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
2995 doc
: /* Non-nil means call this function to ring the bell.
2996 The function should accept no arguments. */);
2997 Vring_bell_function
= Qnil
;
2999 DEFVAR_LISP ("delete-tty-after-functions", &Vdelete_tty_after_functions
,
3000 doc
: /* Functions to be run after deleting a tty.
3001 The functions are run with one argument, the name of the tty to be deleted.
3002 See `delete-tty'. */);
3003 Vdelete_tty_after_functions
= Qnil
;
3005 Qframe_tty_name
= intern ("frame-tty-name");
3006 staticpro (&Qframe_tty_name
);
3008 Qframe_tty_type
= intern ("frame-tty-type");
3009 staticpro (&Qframe_tty_type
);
3011 defsubr (&Stty_display_color_p
);
3012 defsubr (&Stty_display_color_cells
);
3013 defsubr (&Sframe_tty_name
);
3014 defsubr (&Sframe_tty_type
);
3015 defsubr (&Sdelete_tty
);
3017 Fprovide (intern ("multi-tty"), Qnil
);
3023 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
3024 (do not change this comment) */