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>. */
37 #include "termhooks.h"
38 #include "dispextern.h"
42 /* For now, don't try to include termcap.h. On some systems,
43 configure finds a non-standard termcap.h that the main build
46 #if defined HAVE_TERMCAP_H && 0
49 extern void tputs
P_ ((const char *, int, int (*)(int)));
50 extern int tgetent
P_ ((char *, const char *));
51 extern int tgetflag
P_ ((char *id
));
52 extern int tgetnum
P_ ((char *id
));
63 static void turn_on_face
P_ ((struct frame
*, int face_id
));
64 static void turn_off_face
P_ ((struct frame
*, int face_id
));
65 static void tty_show_cursor
P_ ((void));
66 static void tty_hide_cursor
P_ ((void));
69 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) - curY), cmputc)
70 #define OUTPUT1(a) tputs (a, 1, cmputc)
71 #define OUTPUTL(a, lines) tputs (a, lines, cmputc)
73 #define OUTPUT_IF(a) \
76 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) \
80 #define OUTPUT1_IF(a) do { if (a) tputs (a, 1, cmputc); } while (0)
82 /* Function to use to ring the bell. */
84 Lisp_Object Vring_bell_function
;
86 /* Terminal characteristics that higher levels want to look at.
87 These are all extern'd in termchar.h */
89 int must_write_spaces
; /* Nonzero means spaces in the text
90 must actually be output; can't just skip
91 over some columns to leave them blank. */
92 int min_padding_speed
; /* Speed below which no padding necessary */
94 int line_ins_del_ok
; /* Terminal can insert and delete lines */
95 int char_ins_del_ok
; /* Terminal can insert and delete chars */
96 int scroll_region_ok
; /* Terminal supports setting the
98 int scroll_region_cost
; /* Cost of setting a scroll window,
99 measured in characters */
100 int memory_below_frame
; /* Terminal remembers lines
101 scrolled off bottom */
102 int fast_clear_end_of_line
; /* Terminal has a `ce' string */
104 /* Nonzero means no need to redraw the entire frame on resuming
105 a suspended Emacs. This is useful on terminals with multiple pages,
106 where one page is used for Emacs and another for all else. */
108 int no_redraw_on_reenter
;
110 /* Hook functions that you can set to snap out the functions in this file.
111 These are all extern'd in termhooks.h */
113 void (*cursor_to_hook
) P_ ((int, int));
114 void (*raw_cursor_to_hook
) P_ ((int, int));
115 void (*clear_to_end_hook
) P_ ((void));
116 void (*clear_frame_hook
) P_ ((void));
117 void (*clear_end_of_line_hook
) P_ ((int));
119 void (*ins_del_lines_hook
) P_ ((int, int));
121 void (*delete_glyphs_hook
) P_ ((int));
123 void (*ring_bell_hook
) P_ ((void));
125 void (*reset_terminal_modes_hook
) P_ ((void));
126 void (*set_terminal_modes_hook
) P_ ((void));
127 void (*update_begin_hook
) P_ ((struct frame
*));
128 void (*update_end_hook
) P_ ((struct frame
*));
129 void (*set_terminal_window_hook
) P_ ((int));
130 void (*insert_glyphs_hook
) P_ ((struct glyph
*, int));
131 void (*write_glyphs_hook
) P_ ((struct glyph
*, int));
132 void (*delete_glyphs_hook
) P_ ((int));
134 int (*read_socket_hook
) P_ ((int, struct input_event
*, int, int));
136 void (*frame_up_to_date_hook
) P_ ((struct frame
*));
138 /* Return the current position of the mouse.
140 Set *f to the frame the mouse is in, or zero if the mouse is in no
141 Emacs frame. If it is set to zero, all the other arguments are
144 If the motion started in a scroll bar, set *bar_window to the
145 scroll bar's window, *part to the part the mouse is currently over,
146 *x to the position of the mouse along the scroll bar, and *y to the
147 overall length of the scroll bar.
149 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
150 row of the character cell the mouse is over.
152 Set *time to the time the mouse was at the returned position.
154 This should clear mouse_moved until the next motion
157 void (*mouse_position_hook
) P_ ((FRAME_PTR
*f
, int insist
,
158 Lisp_Object
*bar_window
,
159 enum scroll_bar_part
*part
,
162 unsigned long *time
));
164 /* When reading from a minibuffer in a different frame, Emacs wants
165 to shift the highlight from the selected frame to the mini-buffer's
166 frame; under X, this means it lies about where the focus is.
167 This hook tells the window system code to re-decide where to put
170 void (*frame_rehighlight_hook
) P_ ((FRAME_PTR f
));
172 /* If we're displaying frames using a window system that can stack
173 frames on top of each other, this hook allows you to bring a frame
174 to the front, or bury it behind all the other windows. If this
175 hook is zero, that means the device we're displaying on doesn't
176 support overlapping frames, so there's no need to raise or lower
179 If RAISE is non-zero, F is brought to the front, before all other
180 windows. If RAISE is zero, F is sent to the back, behind all other
183 void (*frame_raise_lower_hook
) P_ ((FRAME_PTR f
, int raise
));
185 /* Set the vertical scroll bar for WINDOW to have its upper left corner
186 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
187 indicate that we are displaying PORTION characters out of a total
188 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
189 have a scroll bar, create one for it. */
191 void (*set_vertical_scroll_bar_hook
)
192 P_ ((struct window
*window
,
193 int portion
, int whole
, int position
));
196 /* The following three hooks are used when we're doing a thorough
197 redisplay of the frame. We don't explicitly know which scroll bars
198 are going to be deleted, because keeping track of when windows go
199 away is a real pain - can you say set-window-configuration?
200 Instead, we just assert at the beginning of redisplay that *all*
201 scroll bars are to be removed, and then save scroll bars from the
202 fiery pit when we actually redisplay their window. */
204 /* Arrange for all scroll bars on FRAME to be removed at the next call
205 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
206 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
208 This should be applied to each frame each time its window tree is
209 redisplayed, even if it is not displaying scroll bars at the moment;
210 if the HAS_SCROLL_BARS flag has just been turned off, only calling
211 this and the judge_scroll_bars_hook will get rid of them.
213 If non-zero, this hook should be safe to apply to any frame,
214 whether or not it can support scroll bars, and whether or not it is
215 currently displaying them. */
217 void (*condemn_scroll_bars_hook
) P_ ((FRAME_PTR frame
));
219 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
220 Note that it's okay to redeem a scroll bar that is not condemned. */
222 void (*redeem_scroll_bar_hook
) P_ ((struct window
*window
));
224 /* Remove all scroll bars on FRAME that haven't been saved since the
225 last call to `*condemn_scroll_bars_hook'.
227 This should be applied to each frame after each time its window
228 tree is redisplayed, even if it is not displaying scroll bars at the
229 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
230 calling this and condemn_scroll_bars_hook will get rid of them.
232 If non-zero, this hook should be safe to apply to any frame,
233 whether or not it can support scroll bars, and whether or not it is
234 currently displaying them. */
236 void (*judge_scroll_bars_hook
) P_ ((FRAME_PTR FRAME
));
238 /* Strings, numbers and flags taken from the termcap entry. */
240 char *TS_ins_line
; /* "al" */
241 char *TS_ins_multi_lines
; /* "AL" (one parameter, # lines to insert) */
242 char *TS_bell
; /* "bl" */
243 char *TS_clr_to_bottom
; /* "cd" */
244 char *TS_clr_line
; /* "ce", clear to end of line */
245 char *TS_clr_frame
; /* "cl" */
246 char *TS_set_scroll_region
; /* "cs" (2 params, first line and last line) */
247 char *TS_set_scroll_region_1
; /* "cS" (4 params: total lines,
248 lines above scroll region, lines below it,
249 total lines again) */
250 char *TS_del_char
; /* "dc" */
251 char *TS_del_multi_chars
; /* "DC" (one parameter, # chars to delete) */
252 char *TS_del_line
; /* "dl" */
253 char *TS_del_multi_lines
; /* "DL" (one parameter, # lines to delete) */
254 char *TS_delete_mode
; /* "dm", enter character-delete mode */
255 char *TS_end_delete_mode
; /* "ed", leave character-delete mode */
256 char *TS_end_insert_mode
; /* "ei", leave character-insert mode */
257 char *TS_ins_char
; /* "ic" */
258 char *TS_ins_multi_chars
; /* "IC" (one parameter, # chars to insert) */
259 char *TS_insert_mode
; /* "im", enter character-insert mode */
260 char *TS_pad_inserted_char
; /* "ip". Just padding, no commands. */
261 char *TS_end_keypad_mode
; /* "ke" */
262 char *TS_keypad_mode
; /* "ks" */
263 char *TS_pad_char
; /* "pc", char to use as padding */
264 char *TS_repeat
; /* "rp" (2 params, # times to repeat
265 and character to be repeated) */
266 char *TS_end_standout_mode
; /* "se" */
267 char *TS_fwd_scroll
; /* "sf" */
268 char *TS_standout_mode
; /* "so" */
269 char *TS_rev_scroll
; /* "sr" */
270 char *TS_end_termcap_modes
; /* "te" */
271 char *TS_termcap_modes
; /* "ti" */
272 char *TS_visible_bell
; /* "vb" */
273 char *TS_cursor_normal
; /* "ve" */
274 char *TS_cursor_visible
; /* "vs" */
275 char *TS_cursor_invisible
; /* "vi" */
276 char *TS_set_window
; /* "wi" (4 params, start and end of window,
277 each as vpos and hpos) */
279 /* Value of the "NC" (no_color_video) capability, or 0 if not
282 static int TN_no_color_video
;
284 /* Meaning of bits in no_color_video. Each bit set means that the
285 corresponding attribute cannot be combined with colors. */
289 NC_STANDOUT
= 1 << 0,
290 NC_UNDERLINE
= 1 << 1,
297 NC_ALT_CHARSET
= 1 << 8
300 /* "md" -- turn on bold (extra bright mode). */
302 char *TS_enter_bold_mode
;
304 /* "mh" -- turn on half-bright mode. */
306 char *TS_enter_dim_mode
;
308 /* "mb" -- enter blinking mode. */
310 char *TS_enter_blink_mode
;
312 /* "mr" -- enter reverse video mode. */
314 char *TS_enter_reverse_mode
;
316 /* "us"/"ue" -- start/end underlining. */
318 char *TS_exit_underline_mode
, *TS_enter_underline_mode
;
320 /* "as"/"ae" -- start/end alternate character set. Not really
323 char *TS_enter_alt_charset_mode
, *TS_exit_alt_charset_mode
;
325 /* "me" -- switch appearances off. */
327 char *TS_exit_attribute_mode
;
329 /* "Co" -- number of colors. */
333 /* "pa" -- max. number of color pairs on screen. Not handled yet.
334 Could be a problem if not equal to TN_max_colors * TN_max_colors. */
338 /* "op" -- SVr4 set default pair to its original value. */
342 /* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
343 1 param, the color index. */
345 char *TS_set_foreground
, *TS_set_background
;
347 int TF_hazeltine
; /* termcap hz flag. */
348 int TF_insmode_motion
; /* termcap mi flag: can move while in insert mode. */
349 int TF_standout_motion
; /* termcap mi flag: can move while in standout mode. */
350 int TF_underscore
; /* termcap ul flag: _ underlines if over-struck on
351 non-blank position. Must clear before writing _. */
352 int TF_teleray
; /* termcap xt flag: many weird consequences.
355 static int RPov
; /* # chars to start a TS_repeat */
357 static int delete_in_insert_mode
; /* delete mode == insert mode */
359 static int se_is_so
; /* 1 if same string both enters and leaves
364 /* The largest frame width in any call to calculate_costs. */
368 /* The largest frame height in any call to calculate_costs. */
372 static int costs_set
; /* Nonzero if costs have been calculated. */
374 int insert_mode
; /* Nonzero when in insert mode. */
375 int standout_mode
; /* Nonzero when in standout mode. */
377 /* Size of window specified by higher levels.
378 This is the number of lines, from the top of frame downwards,
379 which can participate in insert-line/delete-line operations.
381 Effectively it excludes the bottom frame_lines - specified_window_size
382 lines from those operations. */
384 int specified_window
;
386 /* Frame currently being redisplayed; 0 if not currently redisplaying.
387 (Direct output does not count). */
389 FRAME_PTR updating_frame
;
391 /* Provided for lisp packages. */
393 static int system_uses_terminfo
;
395 /* Flag used in tty_show/hide_cursor. */
397 static int tty_cursor_hidden
;
401 extern char *tgetstr ();
405 /* We aren't X windows, but we aren't termcap either. This makes me
406 uncertain as to what value to use for frame.output_method. For
407 this file, we'll define FRAME_TERMCAP_P to be zero so that our
408 output hooks get called instead of the termcap functions. Probably
409 the best long-term solution is to define an output_windows_nt... */
411 #undef FRAME_TERMCAP_P
412 #define FRAME_TERMCAP_P(_f_) 0
413 #endif /* WINDOWSNT */
418 if (!NILP (Vring_bell_function
))
420 Lisp_Object function
;
422 /* Temporarily set the global variable to nil
423 so that if we get an error, it stays nil
424 and we don't call it over and over.
426 We don't specbind it, because that would carefully
427 restore the bad value if there's an error
428 and make the loop of errors happen anyway. */
430 function
= Vring_bell_function
;
431 Vring_bell_function
= Qnil
;
435 Vring_bell_function
= function
;
437 else if (!FRAME_TERMCAP_P (XFRAME (selected_frame
)))
438 (*ring_bell_hook
) ();
440 OUTPUT (TS_visible_bell
&& visible_bell
? TS_visible_bell
: TS_bell
);
444 set_terminal_modes ()
446 if (FRAME_TERMCAP_P (XFRAME (selected_frame
)))
448 OUTPUT_IF (TS_termcap_modes
);
449 OUTPUT_IF (TS_cursor_visible
);
450 OUTPUT_IF (TS_keypad_mode
);
454 (*set_terminal_modes_hook
) ();
458 reset_terminal_modes ()
460 if (FRAME_TERMCAP_P (XFRAME (selected_frame
)))
462 turn_off_highlight ();
464 OUTPUT_IF (TS_end_keypad_mode
);
465 OUTPUT_IF (TS_cursor_normal
);
466 OUTPUT_IF (TS_end_termcap_modes
);
467 OUTPUT_IF (TS_orig_pair
);
468 /* Output raw CR so kernel can track the cursor hpos. */
471 else if (reset_terminal_modes_hook
)
472 (*reset_terminal_modes_hook
) ();
480 if (!FRAME_TERMCAP_P (f
))
481 update_begin_hook (f
);
488 if (FRAME_TERMCAP_P (f
))
490 if (!XWINDOW (selected_window
)->cursor_off_p
)
493 background_highlight ();
498 updating_frame
= NULL
;
502 set_terminal_window (size
)
505 if (FRAME_TERMCAP_P (updating_frame
))
507 specified_window
= size
? size
: FRAME_LINES (updating_frame
);
508 if (scroll_region_ok
)
509 set_scroll_region (0, specified_window
);
512 set_terminal_window_hook (size
);
516 set_scroll_region (start
, stop
)
520 struct frame
*sf
= XFRAME (selected_frame
);
522 if (TS_set_scroll_region
)
523 buf
= tparam (TS_set_scroll_region
, 0, 0, start
, stop
- 1);
524 else if (TS_set_scroll_region_1
)
525 buf
= tparam (TS_set_scroll_region_1
, 0, 0,
526 FRAME_LINES (sf
), start
,
527 FRAME_LINES (sf
) - stop
,
530 buf
= tparam (TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (sf
));
542 OUTPUT (TS_insert_mode
);
550 OUTPUT (TS_end_insert_mode
);
554 /* Handle highlighting. */
557 turn_off_highlight ()
560 OUTPUT_IF (TS_end_standout_mode
);
568 OUTPUT_IF (TS_standout_mode
);
576 turn_off_highlight ();
578 turn_on_highlight ();
582 /* Make cursor invisible. */
587 if (tty_cursor_hidden
== 0)
589 tty_cursor_hidden
= 1;
590 OUTPUT_IF (TS_cursor_invisible
);
595 /* Ensure that cursor is visible. */
600 if (tty_cursor_hidden
)
602 tty_cursor_hidden
= 0;
603 OUTPUT_IF (TS_cursor_normal
);
604 OUTPUT_IF (TS_cursor_visible
);
609 /* Set standout mode to the state it should be in for
610 empty space inside windows. What this is,
611 depends on the user option inverse-video. */
614 background_highlight ()
617 turn_on_highlight ();
619 turn_off_highlight ();
622 /* Set standout mode to the mode specified for the text to be output. */
625 highlight_if_desired ()
628 turn_on_highlight ();
630 turn_off_highlight ();
634 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
635 frame-relative coordinates. */
638 cursor_to (vpos
, hpos
)
641 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
643 if (! FRAME_TERMCAP_P (f
) && cursor_to_hook
)
645 (*cursor_to_hook
) (vpos
, hpos
);
649 /* Detect the case where we are called from reset_sys_modes
650 and the costs have never been calculated. Do nothing. */
654 if (curY
== vpos
&& curX
== hpos
)
656 if (!TF_standout_motion
)
657 background_highlight ();
658 if (!TF_insmode_motion
)
663 /* Similar but don't take any account of the wasted characters. */
666 raw_cursor_to (row
, col
)
669 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
670 if (! FRAME_TERMCAP_P (f
))
672 (*raw_cursor_to_hook
) (row
, col
);
675 if (curY
== row
&& curX
== col
)
677 if (!TF_standout_motion
)
678 background_highlight ();
679 if (!TF_insmode_motion
)
684 /* Erase operations */
686 /* clear from cursor to end of frame */
692 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
694 (*clear_to_end_hook
) ();
697 if (TS_clr_to_bottom
)
699 background_highlight ();
700 OUTPUT (TS_clr_to_bottom
);
704 for (i
= curY
; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
707 clear_end_of_line (FRAME_COLS (XFRAME (selected_frame
)));
712 /* Clear entire frame */
717 struct frame
*sf
= XFRAME (selected_frame
);
720 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: sf
)))
722 (*clear_frame_hook
) ();
727 background_highlight ();
728 OUTPUT (TS_clr_frame
);
738 /* Clear from cursor to end of line.
739 Assume that the line is already clear starting at column first_unused_hpos.
741 Note that the cursor may be moved, on terminals lacking a `ce' string. */
744 clear_end_of_line (first_unused_hpos
)
745 int first_unused_hpos
;
749 if (clear_end_of_line_hook
750 && ! FRAME_TERMCAP_P ((updating_frame
752 : XFRAME (selected_frame
))))
754 (*clear_end_of_line_hook
) (first_unused_hpos
);
758 /* Detect the case where we are called from reset_sys_modes
759 and the costs have never been calculated. Do nothing. */
763 if (curX
>= first_unused_hpos
)
765 background_highlight ();
768 OUTPUT1 (TS_clr_line
);
771 { /* have to do it the hard way */
772 struct frame
*sf
= XFRAME (selected_frame
);
775 /* Do not write in last row last col with Auto-wrap on. */
776 if (AutoWrap
&& curY
== FRAME_LINES (sf
) - 1
777 && first_unused_hpos
== FRAME_COLS (sf
))
780 for (i
= curX
; i
< first_unused_hpos
; i
++)
783 fputc (' ', termscript
);
786 cmplus (first_unused_hpos
- curX
);
790 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
791 store them at DST. Do not write more than DST_LEN bytes. That may
792 require stopping before all SRC_LEN input glyphs have been
795 We store the number of glyphs actually converted in *CONSUMED. The
796 return value is the number of bytes store in DST. */
799 encode_terminal_code (src
, dst
, src_len
, dst_len
, consumed
)
803 int dst_len
, *consumed
;
805 struct glyph
*src_start
= src
, *src_end
= src
+ src_len
;
806 unsigned char *dst_start
= dst
, *dst_end
= dst
+ dst_len
;
808 unsigned char workbuf
[MAX_MULTIBYTE_LENGTH
];
809 const unsigned char *buf
;
811 register int tlen
= GLYPH_TABLE_LENGTH
;
812 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
814 struct coding_system
*coding
;
816 /* If terminal_coding does any conversion, use it, otherwise use
817 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
818 because it always return 1 if the member src_multibyte is 1. */
819 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
821 : &safe_terminal_coding
);
823 while (src
< src_end
)
825 /* We must skip glyphs to be padded for a wide character. */
826 if (! CHAR_GLYPH_PADDING_P (*src
))
828 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
830 if (g
< 0 || g
>= tlen
)
832 /* This glyph doesn't has an entry in Vglyph_table. */
833 if (! CHAR_VALID_P (src
->u
.ch
, 0))
837 coding
->src_multibyte
= 0;
841 len
= CHAR_STRING (src
->u
.ch
, workbuf
);
843 coding
->src_multibyte
= 1;
848 /* This glyph has an entry in Vglyph_table,
849 so process any alias before testing for simpleness. */
850 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
852 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
854 /* We set the multi-byte form of a character in G
855 (that should be an ASCII character) at
857 workbuf
[0] = FAST_GLYPH_CHAR (g
);
860 coding
->src_multibyte
= 0;
864 /* We have a string in Vglyph_table. */
865 len
= GLYPH_LENGTH (tbase
, g
);
866 buf
= GLYPH_STRING (tbase
, g
);
867 coding
->src_multibyte
= STRING_MULTIBYTE (tbase
[g
]);
871 result
= encode_coding (coding
, buf
, dst
, len
, dst_end
- dst
);
872 len
-= coding
->consumed
;
873 dst
+= coding
->produced
;
874 if (result
== CODING_FINISH_INSUFFICIENT_DST
875 || (result
== CODING_FINISH_INSUFFICIENT_SRC
876 && len
> dst_end
- dst
))
877 /* The remaining output buffer is too short. We must
878 break the loop here without increasing SRC so that the
879 next call of this function starts from the same glyph. */
884 /* This is the case that a code of the range 0200..0237
885 exists in buf. We must just write out such a code. */
886 buf
+= coding
->consumed
;
894 *consumed
= src
- src_start
;
895 return (dst
- dst_start
);
900 write_glyphs (string
, len
)
901 register struct glyph
*string
;
904 int produced
, consumed
;
905 struct frame
*sf
= XFRAME (selected_frame
);
906 struct frame
*f
= updating_frame
? updating_frame
: sf
;
907 unsigned char conversion_buffer
[1024];
908 int conversion_buffer_size
= sizeof conversion_buffer
;
910 if (write_glyphs_hook
911 && ! FRAME_TERMCAP_P (f
))
913 (*write_glyphs_hook
) (string
, len
);
920 /* Don't dare write in last column of bottom line, if Auto-Wrap,
921 since that would scroll the whole frame on some terminals. */
924 && curY
+ 1 == FRAME_LINES (sf
)
925 && (curX
+ len
) == FRAME_COLS (sf
))
932 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
934 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
938 /* Identify a run of glyphs with the same face. */
939 int face_id
= string
->face_id
;
942 for (n
= 1; n
< len
; ++n
)
943 if (string
[n
].face_id
!= face_id
)
946 /* Turn appearance modes of the face of the run on. */
947 highlight_if_desired ();
948 turn_on_face (f
, face_id
);
952 /* We use a fixed size (1024 bytes) of conversion buffer.
953 Usually it is sufficient, but if not, we just repeat the
955 produced
= encode_terminal_code (string
, conversion_buffer
,
956 n
, conversion_buffer_size
,
960 fwrite (conversion_buffer
, 1, produced
, stdout
);
964 fwrite (conversion_buffer
, 1, produced
, termscript
);
971 /* Turn appearance modes off. */
972 turn_off_face (f
, face_id
);
973 turn_off_highlight ();
976 /* We may have to output some codes to terminate the writing. */
977 if (CODING_REQUIRE_FLUSHING (&terminal_coding
))
979 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
980 encode_coding (&terminal_coding
, "", conversion_buffer
,
981 0, conversion_buffer_size
);
982 if (terminal_coding
.produced
> 0)
984 fwrite (conversion_buffer
, 1, terminal_coding
.produced
, stdout
);
988 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
996 /* If start is zero, insert blanks instead of a string at start */
999 insert_glyphs (start
, len
)
1000 register struct glyph
*start
;
1004 struct glyph
*glyph
= NULL
;
1005 struct frame
*f
, *sf
;
1010 if (insert_glyphs_hook
)
1012 (*insert_glyphs_hook
) (start
, len
);
1016 sf
= XFRAME (selected_frame
);
1017 f
= updating_frame
? updating_frame
: sf
;
1019 if (TS_ins_multi_chars
)
1021 buf
= tparam (TS_ins_multi_chars
, 0, 0, len
);
1025 write_glyphs (start
, len
);
1031 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
1032 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
1035 int produced
, consumed
;
1036 unsigned char conversion_buffer
[1024];
1037 int conversion_buffer_size
= sizeof conversion_buffer
;
1039 OUTPUT1_IF (TS_ins_char
);
1042 conversion_buffer
[0] = SPACEGLYPH
;
1047 highlight_if_desired ();
1048 turn_on_face (f
, start
->face_id
);
1051 /* We must open sufficient space for a character which
1052 occupies more than one column. */
1053 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
1055 OUTPUT1_IF (TS_ins_char
);
1060 /* This is the last glyph. */
1061 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
1063 /* The size of conversion buffer (1024 bytes) is surely
1064 sufficient for just one glyph. */
1065 produced
= encode_terminal_code (glyph
, conversion_buffer
, 1,
1066 conversion_buffer_size
, &consumed
);
1071 fwrite (conversion_buffer
, 1, produced
, stdout
);
1072 if (ferror (stdout
))
1075 fwrite (conversion_buffer
, 1, produced
, termscript
);
1078 OUTPUT1_IF (TS_pad_inserted_char
);
1081 turn_off_face (f
, glyph
->face_id
);
1082 turn_off_highlight ();
1096 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1098 (*delete_glyphs_hook
) (n
);
1102 if (delete_in_insert_mode
)
1109 OUTPUT_IF (TS_delete_mode
);
1112 if (TS_del_multi_chars
)
1114 buf
= tparam (TS_del_multi_chars
, 0, 0, n
);
1119 for (i
= 0; i
< n
; i
++)
1120 OUTPUT1 (TS_del_char
);
1121 if (!delete_in_insert_mode
)
1122 OUTPUT_IF (TS_end_delete_mode
);
1125 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1128 ins_del_lines (vpos
, n
)
1131 char *multi
= n
> 0 ? TS_ins_multi_lines
: TS_del_multi_lines
;
1132 char *single
= n
> 0 ? TS_ins_line
: TS_del_line
;
1133 char *scroll
= n
> 0 ? TS_rev_scroll
: TS_fwd_scroll
;
1136 register int i
= n
> 0 ? n
: -n
;
1139 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1141 (*ins_del_lines_hook
) (vpos
, n
);
1145 sf
= XFRAME (selected_frame
);
1147 /* If the lines below the insertion are being pushed
1148 into the end of the window, this is the same as clearing;
1149 and we know the lines are already clear, since the matching
1150 deletion has already been done. So can ignore this. */
1151 /* If the lines below the deletion are blank lines coming
1152 out of the end of the window, don't bother,
1153 as there will be a matching inslines later that will flush them. */
1154 if (scroll_region_ok
&& vpos
+ i
>= specified_window
)
1156 if (!memory_below_frame
&& vpos
+ i
>= FRAME_LINES (sf
))
1161 raw_cursor_to (vpos
, 0);
1162 background_highlight ();
1163 buf
= tparam (multi
, 0, 0, i
);
1169 raw_cursor_to (vpos
, 0);
1170 background_highlight ();
1178 set_scroll_region (vpos
, specified_window
);
1180 raw_cursor_to (specified_window
- 1, 0);
1182 raw_cursor_to (vpos
, 0);
1183 background_highlight ();
1185 OUTPUTL (scroll
, specified_window
- vpos
);
1186 set_scroll_region (0, specified_window
);
1189 if (!scroll_region_ok
&& memory_below_frame
&& n
< 0)
1191 cursor_to (FRAME_LINES (sf
) + n
, 0);
1196 /* Compute cost of sending "str", in characters,
1197 not counting any line-dependent padding. */
1205 tputs (str
, 0, evalcost
);
1209 /* Compute cost of sending "str", in characters,
1210 counting any line-dependent padding at one line. */
1213 string_cost_one_line (str
)
1218 tputs (str
, 1, evalcost
);
1222 /* Compute per line amount of line-dependent padding,
1223 in tenths of characters. */
1231 tputs (str
, 0, evalcost
);
1234 tputs (str
, 10, evalcost
);
1239 /* char_ins_del_cost[n] is cost of inserting N characters.
1240 char_ins_del_cost[-n] is cost of deleting N characters.
1241 The length of this vector is based on max_frame_cols. */
1243 int *char_ins_del_vector
;
1245 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1250 calculate_ins_del_char_costs (frame
)
1253 int ins_startup_cost
, del_startup_cost
;
1254 int ins_cost_per_char
, del_cost_per_char
;
1258 if (TS_ins_multi_chars
)
1260 ins_cost_per_char
= 0;
1261 ins_startup_cost
= string_cost_one_line (TS_ins_multi_chars
);
1263 else if (TS_ins_char
|| TS_pad_inserted_char
1264 || (TS_insert_mode
&& TS_end_insert_mode
))
1266 ins_startup_cost
= (30 * (string_cost (TS_insert_mode
)
1267 + string_cost (TS_end_insert_mode
))) / 100;
1268 ins_cost_per_char
= (string_cost_one_line (TS_ins_char
)
1269 + string_cost_one_line (TS_pad_inserted_char
));
1273 ins_startup_cost
= 9999;
1274 ins_cost_per_char
= 0;
1277 if (TS_del_multi_chars
)
1279 del_cost_per_char
= 0;
1280 del_startup_cost
= string_cost_one_line (TS_del_multi_chars
);
1282 else if (TS_del_char
)
1284 del_startup_cost
= (string_cost (TS_delete_mode
)
1285 + string_cost (TS_end_delete_mode
));
1286 if (delete_in_insert_mode
)
1287 del_startup_cost
/= 2;
1288 del_cost_per_char
= string_cost_one_line (TS_del_char
);
1292 del_startup_cost
= 9999;
1293 del_cost_per_char
= 0;
1296 /* Delete costs are at negative offsets */
1297 p
= &char_ins_del_cost (frame
)[0];
1298 for (i
= FRAME_COLS (frame
); --i
>= 0;)
1299 *--p
= (del_startup_cost
+= del_cost_per_char
);
1301 /* Doing nothing is free */
1302 p
= &char_ins_del_cost (frame
)[0];
1305 /* Insert costs are at positive offsets */
1306 for (i
= FRAME_COLS (frame
); --i
>= 0;)
1307 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1311 calculate_costs (frame
)
1314 register char *f
= (TS_set_scroll_region
1315 ? TS_set_scroll_region
1316 : TS_set_scroll_region_1
);
1318 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1320 scroll_region_cost
= string_cost (f
);
1322 /* These variables are only used for terminal stuff. They are allocated
1323 once for the terminal frame of X-windows emacs, but not used afterwards.
1325 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1326 X turns off char_ins_del_ok. */
1328 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1329 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1333 if (char_ins_del_vector
!= 0)
1335 = (int *) xrealloc (char_ins_del_vector
,
1337 + 2 * max_frame_cols
* sizeof (int)));
1340 = (int *) xmalloc (sizeof (int)
1341 + 2 * max_frame_cols
* sizeof (int));
1343 bzero (char_ins_del_vector
, (sizeof (int)
1344 + 2 * max_frame_cols
* sizeof (int)));
1346 if (f
&& (!TS_ins_line
&& !TS_del_line
))
1347 do_line_insertion_deletion_costs (frame
,
1348 TS_rev_scroll
, TS_ins_multi_lines
,
1349 TS_fwd_scroll
, TS_del_multi_lines
,
1352 do_line_insertion_deletion_costs (frame
,
1353 TS_ins_line
, TS_ins_multi_lines
,
1354 TS_del_line
, TS_del_multi_lines
,
1357 calculate_ins_del_char_costs (frame
);
1359 /* Don't use TS_repeat if its padding is worse than sending the chars */
1360 if (TS_repeat
&& per_line_cost (TS_repeat
) * baud_rate
< 9000)
1361 RPov
= string_cost (TS_repeat
);
1363 RPov
= FRAME_COLS (frame
) * 2;
1365 cmcostinit (); /* set up cursor motion costs */
1372 /* Termcap capability names that correspond directly to X keysyms.
1373 Some of these (marked "terminfo") aren't supplied by old-style
1374 (Berkeley) termcap entries. They're listed in X keysym order;
1375 except we put the keypad keys first, so that if they clash with
1376 other keys (as on the IBM PC keyboard) they get overridden.
1379 static struct fkey_table keys
[] =
1381 {"kh", "home"}, /* termcap */
1382 {"kl", "left"}, /* termcap */
1383 {"ku", "up"}, /* termcap */
1384 {"kr", "right"}, /* termcap */
1385 {"kd", "down"}, /* termcap */
1386 {"%8", "prior"}, /* terminfo */
1387 {"%5", "next"}, /* terminfo */
1388 {"@7", "end"}, /* terminfo */
1389 {"@1", "begin"}, /* terminfo */
1390 {"*6", "select"}, /* terminfo */
1391 {"%9", "print"}, /* terminfo */
1392 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1394 * "insert" --- see below
1396 {"&8", "undo"}, /* terminfo */
1397 {"%0", "redo"}, /* terminfo */
1398 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1399 {"@0", "find"}, /* terminfo */
1400 {"@2", "cancel"}, /* terminfo */
1401 {"%1", "help"}, /* terminfo */
1403 * "break" goes here, but can't be reliably intercepted with termcap
1405 {"&4", "reset"}, /* terminfo --- actually `restart' */
1407 * "system" and "user" --- no termcaps
1409 {"kE", "clearline"}, /* terminfo */
1410 {"kA", "insertline"}, /* terminfo */
1411 {"kL", "deleteline"}, /* terminfo */
1412 {"kI", "insertchar"}, /* terminfo */
1413 {"kD", "deletechar"}, /* terminfo */
1414 {"kB", "backtab"}, /* terminfo */
1416 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1418 {"@8", "kp-enter"}, /* terminfo */
1420 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1421 * "kp-multiply", "kp-add", "kp-separator",
1422 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1423 * --- no termcaps for any of these.
1425 {"K4", "kp-1"}, /* terminfo */
1427 * "kp-2" --- no termcap
1429 {"K5", "kp-3"}, /* terminfo */
1431 * "kp-4" --- no termcap
1433 {"K2", "kp-5"}, /* terminfo */
1435 * "kp-6" --- no termcap
1437 {"K1", "kp-7"}, /* terminfo */
1439 * "kp-8" --- no termcap
1441 {"K3", "kp-9"}, /* terminfo */
1443 * "kp-equal" --- no termcap
1456 static char **term_get_fkeys_arg
;
1457 static Lisp_Object
term_get_fkeys_1 ();
1459 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1460 This function scans the termcap function key sequence entries, and
1461 adds entries to Vfunction_key_map for each function key it finds. */
1464 term_get_fkeys (address
)
1467 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1468 errors during the call. The only errors should be from Fdefine_key
1469 when given a key sequence containing an invalid prefix key. If the
1470 termcap defines function keys which use a prefix that is already bound
1471 to a command by the default bindings, we should silently ignore that
1472 function key specification, rather than giving the user an error and
1473 refusing to run at all on such a terminal. */
1475 extern Lisp_Object
Fidentity ();
1476 term_get_fkeys_arg
= address
;
1477 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1485 char **address
= term_get_fkeys_arg
;
1487 /* This can happen if CANNOT_DUMP or with strange options. */
1489 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1491 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1493 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1495 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1496 Fmake_vector (make_number (1),
1497 intern (keys
[i
].name
)));
1500 /* The uses of the "k0" capability are inconsistent; sometimes it
1501 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1502 We will attempt to politely accommodate both systems by testing for
1503 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1506 char *k_semi
= tgetstr ("k;", address
);
1507 char *k0
= tgetstr ("k0", address
);
1508 char *k0_name
= "f10";
1513 /* Define f0 first, so that f10 takes precedence in case the
1514 key sequences happens to be the same. */
1515 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1516 Fmake_vector (make_number (1), intern ("f0")));
1517 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1518 Fmake_vector (make_number (1), intern ("f10")));
1521 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1522 Fmake_vector (make_number (1), intern (k0_name
)));
1525 /* Set up cookies for numbered function keys above f10. */
1527 char fcap
[3], fkey
[4];
1529 fcap
[0] = 'F'; fcap
[2] = '\0';
1530 for (i
= 11; i
< 64; i
++)
1533 fcap
[1] = '1' + i
- 11;
1535 fcap
[1] = 'A' + i
- 20;
1537 fcap
[1] = 'a' + i
- 46;
1540 char *sequence
= tgetstr (fcap
, address
);
1543 sprintf (fkey
, "f%d", i
);
1544 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1545 Fmake_vector (make_number (1),
1553 * Various mappings to try and get a better fit.
1556 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1557 if (!tgetstr (cap1, address)) \
1559 char *sequence = tgetstr (cap2, address); \
1561 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1562 Fmake_vector (make_number (1), \
1566 /* if there's no key_next keycap, map key_npage to `next' keysym */
1567 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1568 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1569 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1570 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1571 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1572 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1573 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1575 /* IBM has their own non-standard dialect of terminfo.
1576 If the standard name isn't found, try the IBM name. */
1577 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1578 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1579 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1580 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1581 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1582 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1583 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1584 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1585 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1586 #undef CONDITIONAL_REASSIGN
1593 /***********************************************************************
1594 Character Display Information
1595 ***********************************************************************/
1597 static void append_glyph
P_ ((struct it
*));
1600 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1601 terminal frames if IT->glyph_row != NULL. IT->c is the character
1602 for which to produce glyphs; IT->face_id contains the character's
1603 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1610 struct glyph
*glyph
, *end
;
1613 xassert (it
->glyph_row
);
1614 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1615 + it
->glyph_row
->used
[it
->area
]);
1616 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1619 i
< it
->pixel_width
&& glyph
< end
;
1622 glyph
->type
= CHAR_GLYPH
;
1623 glyph
->pixel_width
= 1;
1624 glyph
->u
.ch
= it
->c
;
1625 glyph
->face_id
= it
->face_id
;
1626 glyph
->padding_p
= i
> 0;
1627 glyph
->charpos
= CHARPOS (it
->position
);
1628 glyph
->object
= it
->object
;
1630 ++it
->glyph_row
->used
[it
->area
];
1636 /* Produce glyphs for the display element described by IT. *IT
1637 specifies what we want to produce a glyph for (character, image, ...),
1638 and where in the glyph matrix we currently are (glyph row and hpos).
1639 produce_glyphs fills in output fields of *IT with information such as the
1640 pixel width and height of a character, and maybe output actual glyphs at
1641 the same time if IT->glyph_row is non-null. See the explanation of
1642 struct display_iterator in dispextern.h for an overview.
1644 produce_glyphs also stores the result of glyph width, ascent
1645 etc. computations in *IT.
1647 IT->glyph_row may be null, in which case produce_glyphs does not
1648 actually fill in the glyphs. This is used in the move_* functions
1649 in xdisp.c for text width and height computations.
1651 Callers usually don't call produce_glyphs directly;
1652 instead they use the macro PRODUCE_GLYPHS. */
1658 /* If a hook is installed, let it do the work. */
1659 xassert (it
->what
== IT_CHARACTER
1660 || it
->what
== IT_COMPOSITION
1661 || it
->what
== IT_IMAGE
1662 || it
->what
== IT_STRETCH
);
1664 /* Nothing but characters are supported on terminal frames. For a
1665 composition sequence, it->c is the first character of the
1667 xassert (it
->what
== IT_CHARACTER
1668 || it
->what
== IT_COMPOSITION
);
1670 if (it
->c
>= 040 && it
->c
< 0177)
1672 it
->pixel_width
= it
->nglyphs
= 1;
1676 else if (it
->c
== '\n')
1677 it
->pixel_width
= it
->nglyphs
= 0;
1678 else if (it
->c
== '\t')
1680 int absolute_x
= (it
->current_x
1681 + it
->continuation_lines_width
);
1683 = (((1 + absolute_x
+ it
->tab_width
- 1)
1688 /* If part of the TAB has been displayed on the previous line
1689 which is continued now, continuation_lines_width will have
1690 been incremented already by the part that fitted on the
1691 continued line. So, we will get the right number of spaces
1693 nspaces
= next_tab_x
- absolute_x
;
1700 it
->pixel_width
= it
->len
= 1;
1708 it
->pixel_width
= nspaces
;
1709 it
->nglyphs
= nspaces
;
1711 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1713 /* Coming here means that it->c is from display table, thus we
1714 must send the code as is to the terminal. Although there's
1715 no way to know how many columns it occupies on a screen, it
1716 is a good assumption that a single byte code has 1-column
1718 it
->pixel_width
= it
->nglyphs
= 1;
1724 /* A multi-byte character. The display width is fixed for all
1725 characters of the set. Some of the glyphs may have to be
1726 ignored because they are already displayed in a continued
1728 int charset
= CHAR_CHARSET (it
->c
);
1730 it
->pixel_width
= CHARSET_WIDTH (charset
);
1731 it
->nglyphs
= it
->pixel_width
;
1737 /* Advance current_x by the pixel width as a convenience for
1739 if (it
->area
== TEXT_AREA
)
1740 it
->current_x
+= it
->pixel_width
;
1741 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1742 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1746 /* Get information about special display element WHAT in an
1747 environment described by IT. WHAT is one of IT_TRUNCATION or
1748 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1749 non-null glyph_row member. This function ensures that fields like
1750 face_id, c, len of IT are left untouched. */
1753 produce_special_glyphs (it
, what
)
1755 enum display_element_type what
;
1761 temp_it
.what
= IT_CHARACTER
;
1763 temp_it
.object
= make_number (0);
1764 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1766 if (what
== IT_CONTINUATION
)
1768 /* Continuation glyph. */
1770 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1771 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1773 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it
->dp
)));
1774 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1779 produce_glyphs (&temp_it
);
1780 it
->pixel_width
= temp_it
.pixel_width
;
1781 it
->nglyphs
= temp_it
.pixel_width
;
1783 else if (what
== IT_TRUNCATION
)
1785 /* Truncation glyph. */
1787 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1788 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1790 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it
->dp
)));
1791 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1796 produce_glyphs (&temp_it
);
1797 it
->pixel_width
= temp_it
.pixel_width
;
1798 it
->nglyphs
= temp_it
.pixel_width
;
1806 /***********************************************************************
1808 ***********************************************************************/
1810 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1811 one of the enumerators from enum no_color_bit, or a bit set built
1812 from them. Some display attributes may not be used together with
1813 color; the termcap capability `NC' specifies which ones. */
1815 #define MAY_USE_WITH_COLORS_P(ATTR) \
1816 (TN_max_colors > 0 \
1817 ? (TN_no_color_video & (ATTR)) == 0 \
1820 /* Turn appearances of face FACE_ID on tty frame F on. */
1823 turn_on_face (f
, face_id
)
1827 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1828 long fg
= face
->foreground
;
1829 long bg
= face
->background
;
1831 /* Do this first because TS_end_standout_mode may be the same
1832 as TS_exit_attribute_mode, which turns all appearances off. */
1833 if (MAY_USE_WITH_COLORS_P (NC_REVERSE
))
1835 if (TN_max_colors
> 0)
1837 if (fg
>= 0 && bg
>= 0)
1839 /* If the terminal supports colors, we can set them
1840 below without using reverse video. The face's fg
1841 and bg colors are set as they should appear on
1842 the screen, i.e. they take the inverse-video'ness
1843 of the face already into account. */
1845 else if (inverse_video
)
1847 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1848 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1849 toggle_highlight ();
1853 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1854 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1855 toggle_highlight ();
1860 /* If we can't display colors, use reverse video
1861 if the face specifies that. */
1864 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1865 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1866 toggle_highlight ();
1870 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1871 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1872 toggle_highlight ();
1877 if (face
->tty_bold_p
)
1879 if (MAY_USE_WITH_COLORS_P (NC_BOLD
))
1880 OUTPUT1_IF (TS_enter_bold_mode
);
1882 else if (face
->tty_dim_p
)
1883 if (MAY_USE_WITH_COLORS_P (NC_DIM
))
1884 OUTPUT1_IF (TS_enter_dim_mode
);
1886 /* Alternate charset and blinking not yet used. */
1887 if (face
->tty_alt_charset_p
1888 && MAY_USE_WITH_COLORS_P (NC_ALT_CHARSET
))
1889 OUTPUT1_IF (TS_enter_alt_charset_mode
);
1891 if (face
->tty_blinking_p
1892 && MAY_USE_WITH_COLORS_P (NC_BLINK
))
1893 OUTPUT1_IF (TS_enter_blink_mode
);
1895 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (NC_UNDERLINE
))
1896 OUTPUT1_IF (TS_enter_underline_mode
);
1898 if (TN_max_colors
> 0)
1902 if (fg
>= 0 && TS_set_foreground
)
1904 p
= tparam (TS_set_foreground
, NULL
, 0, (int) fg
);
1909 if (bg
>= 0 && TS_set_background
)
1911 p
= tparam (TS_set_background
, NULL
, 0, (int) bg
);
1919 /* Turn off appearances of face FACE_ID on tty frame F. */
1922 turn_off_face (f
, face_id
)
1926 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1928 xassert (face
!= NULL
);
1930 if (TS_exit_attribute_mode
)
1932 /* Capability "me" will turn off appearance modes double-bright,
1933 half-bright, reverse-video, standout, underline. It may or
1934 may not turn off alt-char-mode. */
1935 if (face
->tty_bold_p
1937 || face
->tty_reverse_p
1938 || face
->tty_alt_charset_p
1939 || face
->tty_blinking_p
1940 || face
->tty_underline_p
)
1942 OUTPUT1_IF (TS_exit_attribute_mode
);
1943 if (strcmp (TS_exit_attribute_mode
, TS_end_standout_mode
) == 0)
1947 if (face
->tty_alt_charset_p
)
1948 OUTPUT_IF (TS_exit_alt_charset_mode
);
1952 /* If we don't have "me" we can only have those appearances
1953 that have exit sequences defined. */
1954 if (face
->tty_alt_charset_p
)
1955 OUTPUT_IF (TS_exit_alt_charset_mode
);
1957 if (face
->tty_underline_p
)
1958 OUTPUT_IF (TS_exit_underline_mode
);
1961 /* Switch back to default colors. */
1962 if (TN_max_colors
> 0
1963 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
1964 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
1965 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
1966 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
1967 OUTPUT1_IF (TS_orig_pair
);
1971 /* Return non-zero if the terminal on frame F supports all of the
1972 capabilities in CAPS simultaneously, with foreground and background
1973 colors FG and BG. */
1976 tty_capable_p (f
, caps
, fg
, bg
)
1979 unsigned long fg
, bg
;
1981 #define TTY_CAPABLE_P_TRY(cap, TS, NC_bit) \
1982 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(NC_bit))) \
1985 TTY_CAPABLE_P_TRY (TTY_CAP_INVERSE
, TS_standout_mode
, NC_REVERSE
);
1986 TTY_CAPABLE_P_TRY (TTY_CAP_UNDERLINE
, TS_enter_underline_mode
, NC_UNDERLINE
);
1987 TTY_CAPABLE_P_TRY (TTY_CAP_BOLD
, TS_enter_bold_mode
, NC_BOLD
);
1988 TTY_CAPABLE_P_TRY (TTY_CAP_DIM
, TS_enter_dim_mode
, NC_DIM
);
1989 TTY_CAPABLE_P_TRY (TTY_CAP_BLINK
, TS_enter_blink_mode
, NC_BLINK
);
1990 TTY_CAPABLE_P_TRY (TTY_CAP_ALT_CHARSET
, TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
1997 /* Return non-zero if the terminal is capable to display colors. */
1999 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2001 doc
: /* Return non-nil if TTY can display colors on DISPLAY. */)
2003 Lisp_Object display
;
2005 return TN_max_colors
> 0 ? Qt
: Qnil
;
2008 /* Return the number of supported colors. */
2009 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2010 Stty_display_color_cells
, 0, 1, 0,
2011 doc
: /* Return the number of colors supported by TTY on DISPLAY. */)
2013 Lisp_Object display
;
2015 return make_number (TN_max_colors
);
2020 /* Save or restore the default color-related capabilities of this
2023 tty_default_color_capabilities (save
)
2027 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
2028 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
2032 if (default_orig_pair
)
2033 xfree (default_orig_pair
);
2034 default_orig_pair
= TS_orig_pair
? xstrdup (TS_orig_pair
) : NULL
;
2036 if (default_set_foreground
)
2037 xfree (default_set_foreground
);
2038 default_set_foreground
= TS_set_foreground
? xstrdup (TS_set_foreground
)
2041 if (default_set_background
)
2042 xfree (default_set_background
);
2043 default_set_background
= TS_set_background
? xstrdup (TS_set_background
)
2046 default_max_colors
= TN_max_colors
;
2047 default_max_pairs
= TN_max_pairs
;
2048 default_no_color_video
= TN_no_color_video
;
2052 TS_orig_pair
= default_orig_pair
;
2053 TS_set_foreground
= default_set_foreground
;
2054 TS_set_background
= default_set_background
;
2055 TN_max_colors
= default_max_colors
;
2056 TN_max_pairs
= default_max_pairs
;
2057 TN_no_color_video
= default_no_color_video
;
2061 /* Setup one of the standard tty color schemes according to MODE.
2062 MODE's value is generally the number of colors which we want to
2063 support; zero means set up for the default capabilities, the ones
2064 we saw at term_init time; -1 means turn off color support. */
2066 tty_setup_colors (mode
)
2071 case -1: /* no colors at all */
2074 TN_no_color_video
= 0;
2075 TS_set_foreground
= TS_set_background
= TS_orig_pair
= NULL
;
2077 case 0: /* default colors, if any */
2079 tty_default_color_capabilities (0);
2081 case 8: /* 8 standard ANSI colors */
2082 TS_orig_pair
= "\033[0m";
2084 TS_set_foreground
= "\033[3%p1%dm";
2085 TS_set_background
= "\033[4%p1%dm";
2087 TS_set_foreground
= "\033[3%dm";
2088 TS_set_background
= "\033[4%dm";
2092 TN_no_color_video
= 0;
2098 set_tty_color_mode (f
, val
)
2102 Lisp_Object color_mode_spec
, current_mode_spec
;
2103 Lisp_Object color_mode
, current_mode
;
2105 extern Lisp_Object Qtty_color_mode
;
2106 Lisp_Object tty_color_mode_alist
;
2108 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2115 if (NILP (tty_color_mode_alist
))
2116 color_mode_spec
= Qnil
;
2118 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2119 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2121 if (CONSP (color_mode_spec
))
2122 color_mode
= XCDR (color_mode_spec
);
2126 if (CONSP (current_mode_spec
))
2127 current_mode
= XCDR (current_mode_spec
);
2129 current_mode
= Qnil
;
2130 if (NATNUMP (color_mode
))
2131 mode
= XINT (color_mode
);
2133 mode
= 0; /* meaning default */
2134 if (NATNUMP (current_mode
))
2135 old_mode
= XINT (current_mode
);
2139 if (mode
!= old_mode
)
2141 tty_setup_colors (mode
);
2142 /* This recomputes all the faces given the new color
2144 call0 (intern ("tty-set-up-initial-frame-faces"));
2149 #endif /* !WINDOWSNT */
2152 /***********************************************************************
2154 ***********************************************************************/
2157 term_init (terminal_type
)
2158 char *terminal_type
;
2161 char **address
= &area
;
2165 struct frame
*sf
= XFRAME (selected_frame
);
2168 initialize_w32_display ();
2172 area
= (char *) xmalloc (2044);
2177 FrameRows
= FRAME_LINES (sf
);
2178 FrameCols
= FRAME_COLS (sf
);
2179 specified_window
= FRAME_LINES (sf
);
2181 delete_in_insert_mode
= 1;
2184 scroll_region_ok
= 0;
2186 /* Seems to insert lines when it's not supposed to, messing
2187 up the display. In doing a trace, it didn't seem to be
2188 called much, so I don't think we're losing anything by
2191 line_ins_del_ok
= 0;
2192 char_ins_del_ok
= 1;
2196 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
2197 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
2198 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2201 #else /* not WINDOWSNT */
2205 status
= tgetent (buffer
, terminal_type
);
2209 fatal ("Cannot open terminfo database file");
2211 fatal ("Cannot open termcap database file");
2217 fatal ("Terminal type %s is not defined.\n\
2218 If that is not the actual type of terminal you have,\n\
2219 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2220 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2221 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2224 fatal ("Terminal type %s is not defined.\n\
2225 If that is not the actual type of terminal you have,\n\
2226 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2227 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2228 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2233 area
= (char *) xmalloc (2044);
2235 area
= (char *) xmalloc (strlen (buffer
));
2236 #endif /* not TERMINFO */
2240 TS_ins_line
= tgetstr ("al", address
);
2241 TS_ins_multi_lines
= tgetstr ("AL", address
);
2242 TS_bell
= tgetstr ("bl", address
);
2243 BackTab
= tgetstr ("bt", address
);
2244 TS_clr_to_bottom
= tgetstr ("cd", address
);
2245 TS_clr_line
= tgetstr ("ce", address
);
2246 TS_clr_frame
= tgetstr ("cl", address
);
2247 ColPosition
= NULL
; /* tgetstr ("ch", address); */
2248 AbsPosition
= tgetstr ("cm", address
);
2249 CR
= tgetstr ("cr", address
);
2250 TS_set_scroll_region
= tgetstr ("cs", address
);
2251 TS_set_scroll_region_1
= tgetstr ("cS", address
);
2252 RowPosition
= tgetstr ("cv", address
);
2253 TS_del_char
= tgetstr ("dc", address
);
2254 TS_del_multi_chars
= tgetstr ("DC", address
);
2255 TS_del_line
= tgetstr ("dl", address
);
2256 TS_del_multi_lines
= tgetstr ("DL", address
);
2257 TS_delete_mode
= tgetstr ("dm", address
);
2258 TS_end_delete_mode
= tgetstr ("ed", address
);
2259 TS_end_insert_mode
= tgetstr ("ei", address
);
2260 Home
= tgetstr ("ho", address
);
2261 TS_ins_char
= tgetstr ("ic", address
);
2262 TS_ins_multi_chars
= tgetstr ("IC", address
);
2263 TS_insert_mode
= tgetstr ("im", address
);
2264 TS_pad_inserted_char
= tgetstr ("ip", address
);
2265 TS_end_keypad_mode
= tgetstr ("ke", address
);
2266 TS_keypad_mode
= tgetstr ("ks", address
);
2267 LastLine
= tgetstr ("ll", address
);
2268 Right
= tgetstr ("nd", address
);
2269 Down
= tgetstr ("do", address
);
2271 Down
= tgetstr ("nl", address
); /* Obsolete name for "do" */
2273 /* VMS puts a carriage return before each linefeed,
2274 so it is not safe to use linefeeds. */
2275 if (Down
&& Down
[0] == '\n' && Down
[1] == '\0')
2278 if (tgetflag ("bs"))
2279 Left
= "\b"; /* can't possibly be longer! */
2280 else /* (Actually, "bs" is obsolete...) */
2281 Left
= tgetstr ("le", address
);
2283 Left
= tgetstr ("bc", address
); /* Obsolete name for "le" */
2284 TS_pad_char
= tgetstr ("pc", address
);
2285 TS_repeat
= tgetstr ("rp", address
);
2286 TS_end_standout_mode
= tgetstr ("se", address
);
2287 TS_fwd_scroll
= tgetstr ("sf", address
);
2288 TS_standout_mode
= tgetstr ("so", address
);
2289 TS_rev_scroll
= tgetstr ("sr", address
);
2290 Wcm
.cm_tab
= tgetstr ("ta", address
);
2291 TS_end_termcap_modes
= tgetstr ("te", address
);
2292 TS_termcap_modes
= tgetstr ("ti", address
);
2293 Up
= tgetstr ("up", address
);
2294 TS_visible_bell
= tgetstr ("vb", address
);
2295 TS_cursor_normal
= tgetstr ("ve", address
);
2296 TS_cursor_visible
= tgetstr ("vs", address
);
2297 TS_cursor_invisible
= tgetstr ("vi", address
);
2298 TS_set_window
= tgetstr ("wi", address
);
2300 TS_enter_underline_mode
= tgetstr ("us", address
);
2301 TS_exit_underline_mode
= tgetstr ("ue", address
);
2302 TS_enter_bold_mode
= tgetstr ("md", address
);
2303 TS_enter_dim_mode
= tgetstr ("mh", address
);
2304 TS_enter_blink_mode
= tgetstr ("mb", address
);
2305 TS_enter_reverse_mode
= tgetstr ("mr", address
);
2306 TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2307 TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2308 TS_exit_attribute_mode
= tgetstr ("me", address
);
2310 MultiUp
= tgetstr ("UP", address
);
2311 MultiDown
= tgetstr ("DO", address
);
2312 MultiLeft
= tgetstr ("LE", address
);
2313 MultiRight
= tgetstr ("RI", address
);
2315 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2316 color because we can't switch back to the default foreground and
2318 TS_orig_pair
= tgetstr ("op", address
);
2321 TS_set_foreground
= tgetstr ("AF", address
);
2322 TS_set_background
= tgetstr ("AB", address
);
2323 if (!TS_set_foreground
)
2326 TS_set_foreground
= tgetstr ("Sf", address
);
2327 TS_set_background
= tgetstr ("Sb", address
);
2330 TN_max_colors
= tgetnum ("Co");
2331 TN_max_pairs
= tgetnum ("pa");
2333 TN_no_color_video
= tgetnum ("NC");
2334 if (TN_no_color_video
== -1)
2335 TN_no_color_video
= 0;
2338 tty_default_color_capabilities (1);
2340 MagicWrap
= tgetflag ("xn");
2341 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2342 the former flag imply the latter. */
2343 AutoWrap
= MagicWrap
|| tgetflag ("am");
2344 memory_below_frame
= tgetflag ("db");
2345 TF_hazeltine
= tgetflag ("hz");
2346 must_write_spaces
= tgetflag ("in");
2347 meta_key
= tgetflag ("km") || tgetflag ("MT");
2348 TF_insmode_motion
= tgetflag ("mi");
2349 TF_standout_motion
= tgetflag ("ms");
2350 TF_underscore
= tgetflag ("ul");
2351 TF_teleray
= tgetflag ("xt");
2353 term_get_fkeys (address
);
2355 /* Get frame size from system, or else from termcap. */
2358 get_frame_size (&width
, &height
);
2359 FRAME_COLS (sf
) = width
;
2360 FRAME_LINES (sf
) = height
;
2363 if (FRAME_COLS (sf
) <= 0)
2364 SET_FRAME_COLS (sf
, tgetnum ("co"));
2366 /* Keep width and external_width consistent */
2367 SET_FRAME_COLS (sf
, FRAME_COLS (sf
));
2368 if (FRAME_LINES (sf
) <= 0)
2369 FRAME_LINES (sf
) = tgetnum ("li");
2371 if (FRAME_LINES (sf
) < 3 || FRAME_COLS (sf
) < 3)
2372 fatal ("Screen size %dx%d is too small",
2373 FRAME_LINES (sf
), FRAME_COLS (sf
));
2375 min_padding_speed
= tgetnum ("pb");
2376 TabWidth
= tgetnum ("tw");
2379 /* These capabilities commonly use ^J.
2380 I don't know why, but sending them on VMS does not work;
2381 it causes following spaces to be lost, sometimes.
2382 For now, the simplest fix is to avoid using these capabilities ever. */
2383 if (Down
&& Down
[0] == '\n')
2391 TS_fwd_scroll
= Down
;
2393 PC
= TS_pad_char
? *TS_pad_char
: 0;
2398 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2399 and newer termcap doc does not seem to say there is a default.
2404 /* We don't support standout modes that use `magic cookies', so
2405 turn off any that do. */
2406 if (TS_standout_mode
&& tgetnum ("sg") >= 0)
2408 TS_standout_mode
= 0;
2409 TS_end_standout_mode
= 0;
2411 if (TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
2413 TS_enter_underline_mode
= 0;
2414 TS_exit_underline_mode
= 0;
2417 /* If there's no standout mode, try to use underlining instead. */
2418 if (TS_standout_mode
== 0)
2420 TS_standout_mode
= TS_enter_underline_mode
;
2421 TS_end_standout_mode
= TS_exit_underline_mode
;
2424 /* If no `se' string, try using a `me' string instead.
2425 If that fails, we can't use standout mode at all. */
2426 if (TS_end_standout_mode
== 0)
2428 char *s
= tgetstr ("me", address
);
2430 TS_end_standout_mode
= s
;
2432 TS_standout_mode
= 0;
2438 /* We can't support standout mode, because it uses magic cookies. */
2439 TS_standout_mode
= 0;
2440 /* But that means we cannot rely on ^M to go to column zero! */
2442 /* LF can't be trusted either -- can alter hpos */
2443 /* if move at column 0 thru a line with TS_standout_mode */
2447 /* Special handling for certain terminal types known to need it */
2449 if (!strcmp (terminal_type
, "supdup"))
2451 memory_below_frame
= 1;
2452 Wcm
.cm_losewrap
= 1;
2454 if (!strncmp (terminal_type
, "c10", 3)
2455 || !strcmp (terminal_type
, "perq"))
2457 /* Supply a makeshift :wi string.
2458 This string is not valid in general since it works only
2459 for windows starting at the upper left corner;
2460 but that is all Emacs uses.
2462 This string works only if the frame is using
2463 the top of the video memory, because addressing is memory-relative.
2464 So first check the :ti string to see if that is true.
2466 It would be simpler if the :wi string could go in the termcap
2467 entry, but it can't because it is not fully valid.
2468 If it were in the termcap entry, it would confuse other programs. */
2471 p
= TS_termcap_modes
;
2472 while (*p
&& strcmp (p
, "\033v "))
2475 TS_set_window
= "\033v%C %C %C %C ";
2477 /* Termcap entry often fails to have :in: flag */
2478 must_write_spaces
= 1;
2479 /* :ti string typically fails to have \E^G! in it */
2480 /* This limits scope of insert-char to one line. */
2481 strcpy (area
, TS_termcap_modes
);
2482 strcat (area
, "\033\007!");
2483 TS_termcap_modes
= area
;
2484 area
+= strlen (area
) + 1;
2486 /* Change all %+ parameters to %C, to handle
2487 values above 96 correctly for the C100. */
2490 if (p
[0] == '%' && p
[1] == '+')
2496 FrameRows
= FRAME_LINES (sf
);
2497 FrameCols
= FRAME_COLS (sf
);
2498 specified_window
= FRAME_LINES (sf
);
2500 if (Wcm_init () == -1) /* can't do cursor motion */
2502 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2503 It lacks the ability to position the cursor.\n\
2504 If that is not the actual type of terminal you have, use either the\n\
2505 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2506 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2510 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2511 It lacks the ability to position the cursor.\n\
2512 If that is not the actual type of terminal you have,\n\
2513 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2514 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2515 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2517 # else /* TERMCAP */
2518 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2519 It lacks the ability to position the cursor.\n\
2520 If that is not the actual type of terminal you have,\n\
2521 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2522 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2523 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2525 # endif /* TERMINFO */
2527 if (FRAME_LINES (sf
) <= 0
2528 || FRAME_COLS (sf
) <= 0)
2529 fatal ("The frame size has not been specified");
2531 delete_in_insert_mode
2532 = TS_delete_mode
&& TS_insert_mode
2533 && !strcmp (TS_delete_mode
, TS_insert_mode
);
2535 se_is_so
= (TS_standout_mode
2536 && TS_end_standout_mode
2537 && !strcmp (TS_standout_mode
, TS_end_standout_mode
));
2539 UseTabs
= tabs_safe_p () && TabWidth
== 8;
2543 && (TS_set_window
|| TS_set_scroll_region
|| TS_set_scroll_region_1
));
2545 line_ins_del_ok
= (((TS_ins_line
|| TS_ins_multi_lines
)
2546 && (TS_del_line
|| TS_del_multi_lines
))
2547 || (scroll_region_ok
&& TS_fwd_scroll
&& TS_rev_scroll
));
2549 char_ins_del_ok
= ((TS_ins_char
|| TS_insert_mode
2550 || TS_pad_inserted_char
|| TS_ins_multi_chars
)
2551 && (TS_del_char
|| TS_del_multi_chars
));
2553 fast_clear_end_of_line
= TS_clr_line
!= 0;
2556 if (read_socket_hook
) /* Baudrate is somewhat */
2557 /* meaningless in this case */
2560 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
2561 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
2562 #endif /* WINDOWSNT */
2567 fatal (str
, arg1
, arg2
)
2568 char *str
, *arg1
, *arg2
;
2570 fprintf (stderr
, "emacs: ");
2571 fprintf (stderr
, str
, arg1
, arg2
);
2572 fprintf (stderr
, "\n");
2580 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
2581 doc
: /* Non-nil means the system uses terminfo rather than termcap.
2582 This variable can be used by terminal emulator packages. */);
2584 system_uses_terminfo
= 1;
2586 system_uses_terminfo
= 0;
2589 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
2590 doc
: /* Non-nil means call this function to ring the bell.
2591 The function should accept no arguments. */);
2592 Vring_bell_function
= Qnil
;
2594 defsubr (&Stty_display_color_p
);
2595 defsubr (&Stty_display_color_cells
);