1 /* terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 86, 87, 93, 94, 95, 98
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@acm.org>. */
36 #include "termhooks.h"
38 #include "dispextern.h"
44 extern void tputs
P_ ((const char *, int, int (*)(int)));
45 extern int tgetent
P_ ((char *, const char *));
46 extern int tgetflag
P_ ((char *id
));
47 extern int tgetnum
P_ ((char *id
));
55 static void turn_on_face
P_ ((struct frame
*, int face_id
));
56 static void turn_off_face
P_ ((struct frame
*, int face_id
));
57 static void tty_show_cursor
P_ ((void));
58 static void tty_hide_cursor
P_ ((void));
60 #define max(a, b) ((a) > (b) ? (a) : (b))
61 #define min(a, b) ((a) < (b) ? (a) : (b))
64 tputs (a, (int) (FRAME_HEIGHT (XFRAME (selected_frame)) - curY), cmputc)
65 #define OUTPUT1(a) tputs (a, 1, cmputc)
66 #define OUTPUTL(a, lines) tputs (a, lines, cmputc)
68 #define OUTPUT_IF(a) \
71 tputs (a, (int) (FRAME_HEIGHT (XFRAME (selected_frame)) \
75 #define OUTPUT1_IF(a) do { if (a) tputs (a, 1, cmputc); } while (0)
77 /* Function to use to ring the bell. */
79 Lisp_Object Vring_bell_function
;
81 /* Terminal characteristics that higher levels want to look at.
82 These are all extern'd in termchar.h */
84 int must_write_spaces
; /* Nonzero means spaces in the text
85 must actually be output; can't just skip
86 over some columns to leave them blank. */
87 int min_padding_speed
; /* Speed below which no padding necessary */
89 int line_ins_del_ok
; /* Terminal can insert and delete lines */
90 int char_ins_del_ok
; /* Terminal can insert and delete chars */
91 int scroll_region_ok
; /* Terminal supports setting the
93 int scroll_region_cost
; /* Cost of setting a scroll window,
94 measured in characters */
95 int memory_below_frame
; /* Terminal remembers lines
96 scrolled off bottom */
97 int fast_clear_end_of_line
; /* Terminal has a `ce' string */
99 /* Nonzero means no need to redraw the entire frame on resuming
100 a suspended Emacs. This is useful on terminals with multiple pages,
101 where one page is used for Emacs and another for all else. */
103 int no_redraw_on_reenter
;
105 /* Hook functions that you can set to snap out the functions in this file.
106 These are all extern'd in termhooks.h */
108 void (*cursor_to_hook
) P_ ((int, int));
109 void (*raw_cursor_to_hook
) P_ ((int, int));
110 void (*clear_to_end_hook
) P_ ((void));
111 void (*clear_frame_hook
) P_ ((void));
112 void (*clear_end_of_line_hook
) P_ ((int));
114 void (*ins_del_lines_hook
) P_ ((int, int));
116 void (*change_line_highlight_hook
) P_ ((int, int, int, int));
117 void (*reassert_line_highlight_hook
) P_ ((int, int));
119 void (*delete_glyphs_hook
) P_ ((int));
121 void (*ring_bell_hook
) P_ ((void));
123 void (*reset_terminal_modes_hook
) P_ ((void));
124 void (*set_terminal_modes_hook
) P_ ((void));
125 void (*update_begin_hook
) P_ ((struct frame
*));
126 void (*update_end_hook
) P_ ((struct frame
*));
127 void (*set_terminal_window_hook
) P_ ((int));
128 void (*insert_glyphs_hook
) P_ ((struct glyph
*, int));
129 void (*write_glyphs_hook
) P_ ((struct glyph
*, int));
130 void (*delete_glyphs_hook
) P_ ((int));
132 int (*read_socket_hook
) P_ ((int, struct input_event
*, int, int));
134 void (*frame_up_to_date_hook
) P_ ((struct frame
*));
136 /* Return the current position of the mouse.
138 Set *f to the frame the mouse is in, or zero if the mouse is in no
139 Emacs frame. If it is set to zero, all the other arguments are
142 If the motion started in a scroll bar, set *bar_window to the
143 scroll bar's window, *part to the part the mouse is currently over,
144 *x to the position of the mouse along the scroll bar, and *y to the
145 overall length of the scroll bar.
147 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
148 row of the character cell the mouse is over.
150 Set *time to the time the mouse was at the returned position.
152 This should clear mouse_moved until the next motion
154 void (*mouse_position_hook
) P_ ((FRAME_PTR
*f
, int insist
,
155 Lisp_Object
*bar_window
,
156 enum scroll_bar_part
*part
,
159 unsigned long *time
));
161 /* When reading from a minibuffer in a different frame, Emacs wants
162 to shift the highlight from the selected frame to the mini-buffer's
163 frame; under X, this means it lies about where the focus is.
164 This hook tells the window system code to re-decide where to put
166 void (*frame_rehighlight_hook
) P_ ((FRAME_PTR f
));
168 /* If we're displaying frames using a window system that can stack
169 frames on top of each other, this hook allows you to bring a frame
170 to the front, or bury it behind all the other windows. If this
171 hook is zero, that means the device we're displaying on doesn't
172 support overlapping frames, so there's no need to raise or lower
175 If RAISE is non-zero, F is brought to the front, before all other
176 windows. If RAISE is zero, F is sent to the back, behind all other
178 void (*frame_raise_lower_hook
) P_ ((FRAME_PTR f
, int raise
));
180 /* Set the vertical scroll bar for WINDOW to have its upper left corner
181 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
182 indicate that we are displaying PORTION characters out of a total
183 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
184 have a scroll bar, create one for it. */
186 void (*set_vertical_scroll_bar_hook
)
187 P_ ((struct window
*window
,
188 int portion
, int whole
, int position
));
191 /* The following three hooks are used when we're doing a thorough
192 redisplay of the frame. We don't explicitly know which scroll bars
193 are going to be deleted, because keeping track of when windows go
194 away is a real pain - can you say set-window-configuration?
195 Instead, we just assert at the beginning of redisplay that *all*
196 scroll bars are to be removed, and then save scroll bars from the
197 fiery pit when we actually redisplay their window. */
199 /* Arrange for all scroll bars on FRAME to be removed at the next call
200 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
201 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
203 This should be applied to each frame each time its window tree is
204 redisplayed, even if it is not displaying scroll bars at the moment;
205 if the HAS_SCROLL_BARS flag has just been turned off, only calling
206 this and the judge_scroll_bars_hook will get rid of them.
208 If non-zero, this hook should be safe to apply to any frame,
209 whether or not it can support scroll bars, and whether or not it is
210 currently displaying them. */
211 void (*condemn_scroll_bars_hook
) P_ ((FRAME_PTR frame
));
213 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
214 Note that it's okay to redeem a scroll bar that is not condemned. */
215 void (*redeem_scroll_bar_hook
) P_ ((struct window
*window
));
217 /* Remove all scroll bars on FRAME that haven't been saved since the
218 last call to `*condemn_scroll_bars_hook'.
220 This should be applied to each frame after each time its window
221 tree is redisplayed, even if it is not displaying scroll bars at the
222 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
223 calling this and condemn_scroll_bars_hook will get rid of them.
225 If non-zero, this hook should be safe to apply to any frame,
226 whether or not it can support scroll bars, and whether or not it is
227 currently displaying them. */
228 void (*judge_scroll_bars_hook
) P_ ((FRAME_PTR FRAME
));
230 /* Hook to call in estimate_mode_line_height, if any. */
232 int (* estimate_mode_line_height_hook
) P_ ((struct frame
*f
, enum face_id
));
235 /* Strings, numbers and flags taken from the termcap entry. */
237 char *TS_ins_line
; /* "al" */
238 char *TS_ins_multi_lines
; /* "AL" (one parameter, # lines to insert) */
239 char *TS_bell
; /* "bl" */
240 char *TS_clr_to_bottom
; /* "cd" */
241 char *TS_clr_line
; /* "ce", clear to end of line */
242 char *TS_clr_frame
; /* "cl" */
243 char *TS_set_scroll_region
; /* "cs" (2 params, first line and last line) */
244 char *TS_set_scroll_region_1
; /* "cS" (4 params: total lines,
245 lines above scroll region, lines below it,
246 total lines again) */
247 char *TS_del_char
; /* "dc" */
248 char *TS_del_multi_chars
; /* "DC" (one parameter, # chars to delete) */
249 char *TS_del_line
; /* "dl" */
250 char *TS_del_multi_lines
; /* "DL" (one parameter, # lines to delete) */
251 char *TS_delete_mode
; /* "dm", enter character-delete mode */
252 char *TS_end_delete_mode
; /* "ed", leave character-delete mode */
253 char *TS_end_insert_mode
; /* "ei", leave character-insert mode */
254 char *TS_ins_char
; /* "ic" */
255 char *TS_ins_multi_chars
; /* "IC" (one parameter, # chars to insert) */
256 char *TS_insert_mode
; /* "im", enter character-insert mode */
257 char *TS_pad_inserted_char
; /* "ip". Just padding, no commands. */
258 char *TS_end_keypad_mode
; /* "ke" */
259 char *TS_keypad_mode
; /* "ks" */
260 char *TS_pad_char
; /* "pc", char to use as padding */
261 char *TS_repeat
; /* "rp" (2 params, # times to repeat
262 and character to be repeated) */
263 char *TS_end_standout_mode
; /* "se" */
264 char *TS_fwd_scroll
; /* "sf" */
265 char *TS_standout_mode
; /* "so" */
266 char *TS_rev_scroll
; /* "sr" */
267 char *TS_end_termcap_modes
; /* "te" */
268 char *TS_termcap_modes
; /* "ti" */
269 char *TS_visible_bell
; /* "vb" */
270 char *TS_cursor_normal
; /* "ve" */
271 char *TS_cursor_visible
; /* "vs" */
272 char *TS_cursor_invisible
; /* "vi" */
273 char *TS_set_window
; /* "wi" (4 params, start and end of window,
274 each as vpos and hpos) */
276 /* Value of the "NC" (no_color_video) capability, or 0 if not
279 static int TN_no_color_video
;
281 /* Meaning of bits in no_color_video. Each bit set means that the
282 corresponding attribute cannot be combined with colors. */
286 NC_STANDOUT
= 1 << 0,
287 NC_UNDERLINE
= 1 << 1,
294 NC_ALT_CHARSET
= 1 << 8
297 /* "md" -- turn on bold (extra bright mode). */
299 char *TS_enter_bold_mode
;
301 /* "mh" -- turn on half-bright mode. */
303 char *TS_enter_dim_mode
;
305 /* "mb" -- enter blinking mode. */
307 char *TS_enter_blink_mode
;
309 /* "mr" -- enter reverse video mode. */
311 char *TS_enter_reverse_mode
;
313 /* "us"/"ue" -- start/end underlining. */
315 char *TS_exit_underline_mode
, *TS_enter_underline_mode
;
317 /* "ug" -- number of blanks left by underline. */
319 int TN_magic_cookie_glitch_ul
;
321 /* "as"/"ae" -- start/end alternate character set. Not really
324 char *TS_enter_alt_charset_mode
, *TS_exit_alt_charset_mode
;
326 /* "me" -- switch appearances off. */
328 char *TS_exit_attribute_mode
;
330 /* "Co" -- number of colors. */
334 /* "pa" -- max. number of color pairs on screen. Not handled yet.
335 Could be a problem if not equal to TN_max_colors * TN_max_colors. */
339 /* "op" -- SVr4 set default pair to its original value. */
343 /* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
344 1 param, the color index. */
346 char *TS_set_foreground
, *TS_set_background
;
348 int TF_hazeltine
; /* termcap hz flag. */
349 int TF_insmode_motion
; /* termcap mi flag: can move while in insert mode. */
350 int TF_standout_motion
; /* termcap mi flag: can move while in standout mode. */
351 int TF_underscore
; /* termcap ul flag: _ underlines if over-struck on
352 non-blank position. Must clear before writing _. */
353 int TF_teleray
; /* termcap xt flag: many weird consequences.
356 int TF_xs
; /* Nonzero for "xs". If set together with
357 TN_standout_width == 0, it means don't bother
358 to write any end-standout cookies. */
360 int TN_standout_width
; /* termcap sg number: width occupied by standout
363 static int RPov
; /* # chars to start a TS_repeat */
365 static int delete_in_insert_mode
; /* delete mode == insert mode */
367 static int se_is_so
; /* 1 if same string both enters and leaves
372 /* The largest frame width in any call to calculate_costs. */
376 /* The largest frame height in any call to calculate_costs. */
378 int max_frame_height
;
380 /* Number of chars of space used for standout marker at beginning of line,
381 or'd with 0100. Zero if no standout marker at all.
382 The length of these vectors is max_frame_height.
384 Used IFF TN_standout_width >= 0. */
386 static char *chars_wasted
;
387 static char *copybuf
;
389 /* nonzero means supposed to write text in standout mode. */
391 int standout_requested
;
393 int insert_mode
; /* Nonzero when in insert mode. */
394 int standout_mode
; /* Nonzero when in standout mode. */
396 /* Size of window specified by higher levels.
397 This is the number of lines, from the top of frame downwards,
398 which can participate in insert-line/delete-line operations.
400 Effectively it excludes the bottom frame_height - specified_window_size
401 lines from those operations. */
403 int specified_window
;
405 /* Frame currently being redisplayed; 0 if not currently redisplaying.
406 (Direct output does not count). */
408 FRAME_PTR updating_frame
;
410 /* Provided for lisp packages. */
412 static int system_uses_terminfo
;
416 extern char *tgetstr ();
421 /* We aren't X windows, but we aren't termcap either. This makes me
422 uncertain as to what value to use for frame.output_method. For
423 this file, we'll define FRAME_TERMCAP_P to be zero so that our
424 output hooks get called instead of the termcap functions. Probably
425 the best long-term solution is to define an output_windows_nt... */
427 #undef FRAME_TERMCAP_P
428 #define FRAME_TERMCAP_P(_f_) 0
429 #endif /* WINDOWSNT */
434 if (! NILP (Vring_bell_function
))
436 Lisp_Object function
;
438 /* Temporarily set the global variable to nil
439 so that if we get an error, it stays nil
440 and we don't call it over and over.
442 We don't specbind it, because that would carefully
443 restore the bad value if there's an error
444 and make the loop of errors happen anyway. */
445 function
= Vring_bell_function
;
446 Vring_bell_function
= Qnil
;
450 Vring_bell_function
= function
;
454 if (! FRAME_TERMCAP_P (XFRAME (selected_frame
)))
456 (*ring_bell_hook
) ();
459 OUTPUT (TS_visible_bell
&& visible_bell
? TS_visible_bell
: TS_bell
);
463 set_terminal_modes ()
465 if (! FRAME_TERMCAP_P (XFRAME (selected_frame
)))
467 (*set_terminal_modes_hook
) ();
470 OUTPUT_IF (TS_termcap_modes
);
471 OUTPUT_IF (TS_cursor_visible
);
472 OUTPUT_IF (TS_keypad_mode
);
477 reset_terminal_modes ()
479 if (! FRAME_TERMCAP_P (XFRAME (selected_frame
)))
481 if (reset_terminal_modes_hook
)
482 (*reset_terminal_modes_hook
) ();
485 if (TN_standout_width
< 0)
486 turn_off_highlight ();
488 OUTPUT_IF (TS_end_keypad_mode
);
489 OUTPUT_IF (TS_cursor_normal
);
490 OUTPUT_IF (TS_end_termcap_modes
);
491 OUTPUT_IF (TS_orig_pair
);
492 /* Output raw CR so kernel can track the cursor hpos. */
493 /* But on magic-cookie terminals this can erase an end-standout marker and
494 cause the rest of the frame to be in standout, so move down first. */
495 if (TN_standout_width
>= 0)
505 if (! FRAME_TERMCAP_P (updating_frame
))
506 (*update_begin_hook
) (f
);
515 if (! FRAME_TERMCAP_P (updating_frame
))
517 (*update_end_hook
) (f
);
522 if (!XWINDOW (selected_window
)->cursor_off_p
)
526 background_highlight ();
527 standout_requested
= 0;
532 set_terminal_window (size
)
535 if (! FRAME_TERMCAP_P (updating_frame
))
537 (*set_terminal_window_hook
) (size
);
540 specified_window
= size
? size
: FRAME_HEIGHT (XFRAME (selected_frame
));
541 if (!scroll_region_ok
)
543 set_scroll_region (0, specified_window
);
547 set_scroll_region (start
, stop
)
551 struct frame
*sf
= XFRAME (selected_frame
);
553 if (TS_set_scroll_region
)
555 buf
= tparam (TS_set_scroll_region
, 0, 0, start
, stop
- 1);
557 else if (TS_set_scroll_region_1
)
559 buf
= tparam (TS_set_scroll_region_1
, 0, 0,
560 FRAME_HEIGHT (sf
), start
,
561 FRAME_HEIGHT (sf
) - stop
,
566 buf
= tparam (TS_set_window
, 0, 0, start
, 0, stop
, FRAME_WIDTH (sf
));
577 OUTPUT (TS_insert_mode
);
585 OUTPUT (TS_end_insert_mode
);
589 /* Handle highlighting when TN_standout_width (termcap sg) is not specified.
590 In these terminals, output is affected by the value of standout
591 mode when the output is written.
593 These functions are called on all terminals, but do nothing
594 on terminals whose standout mode does not work that way. */
597 turn_off_highlight ()
599 if (TN_standout_width
< 0)
602 OUTPUT_IF (TS_end_standout_mode
);
610 if (TN_standout_width
< 0)
613 OUTPUT_IF (TS_standout_mode
);
619 /* Make cursor invisible. */
624 OUTPUT_IF (TS_cursor_invisible
);
628 /* Ensure that cursor is visible. */
633 OUTPUT_IF (TS_cursor_normal
);
634 OUTPUT_IF (TS_cursor_visible
);
638 /* Set standout mode to the state it should be in for
639 empty space inside windows. What this is,
640 depends on the user option inverse-video. */
643 background_highlight ()
645 if (TN_standout_width
>= 0)
648 turn_on_highlight ();
650 turn_off_highlight ();
653 /* Set standout mode to the mode specified for the text to be output. */
656 highlight_if_desired ()
658 if (TN_standout_width
>= 0)
660 if (!inverse_video
== !standout_requested
)
661 turn_off_highlight ();
663 turn_on_highlight ();
666 /* Handle standout mode for terminals in which TN_standout_width >= 0.
667 On these terminals, standout is controlled by markers that
668 live inside the terminal's memory. TN_standout_width is the width
669 that the marker occupies in memory. Standout runs from the marker
670 to the end of the line on some terminals, or to the next
671 turn-off-standout marker (TS_end_standout_mode) string
672 on other terminals. */
674 /* Write a standout marker or end-standout marker at the front of the line
675 at vertical position vpos. */
678 write_standout_marker (flag
, vpos
)
681 if (flag
|| (TS_end_standout_mode
&& !TF_teleray
&& !se_is_so
682 && !(TF_xs
&& TN_standout_width
== 0)))
685 cmplus (TN_standout_width
);
686 OUTPUT (flag
? TS_standout_mode
: TS_end_standout_mode
);
687 chars_wasted
[curY
] = TN_standout_width
| 0100;
691 /* External interface to control of standout mode.
692 Call this when about to modify line at position VPOS
693 and not change whether it is highlighted. */
696 reassert_line_highlight (highlight
, vpos
)
700 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
701 if (! FRAME_TERMCAP_P (f
))
703 (*reassert_line_highlight_hook
) (highlight
, vpos
);
706 if (TN_standout_width
< 0)
707 /* Handle terminals where standout takes affect at output time */
708 standout_requested
= highlight
;
709 else if (chars_wasted
&& chars_wasted
[vpos
] == 0)
710 /* For terminals with standout markers, write one on this line
711 if there isn't one already. */
712 write_standout_marker (highlight
, vpos
);
715 /* Call this when about to modify line at position VPOS
716 and change whether it is highlighted. */
719 change_line_highlight (new_highlight
, vpos
, y
, first_unused_hpos
)
720 int new_highlight
, vpos
, y
, first_unused_hpos
;
722 standout_requested
= new_highlight
;
723 if (! FRAME_TERMCAP_P (updating_frame
))
725 (*change_line_highlight_hook
) (new_highlight
, vpos
, y
, first_unused_hpos
);
731 if (TN_standout_width
< 0)
732 background_highlight ();
733 /* If line starts with a marker, delete the marker */
734 else if (TS_clr_line
&& chars_wasted
[curY
])
737 /* On Teleray, make sure to erase the SO marker. */
740 cmgoto (curY
- 1, FRAME_WIDTH (XFRAME (selected_frame
)) - 4);
742 curY
++; /* ESC S moves to next line where the TS_standout_mode was */
746 cmgoto (curY
, 0); /* reposition to kill standout marker */
748 clear_end_of_line_raw (first_unused_hpos
);
749 reassert_line_highlight (new_highlight
, curY
);
753 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
754 frame-relative coordinates. */
757 cursor_to (vpos
, hpos
)
760 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
762 if (! FRAME_TERMCAP_P (f
) && cursor_to_hook
)
764 (*cursor_to_hook
) (vpos
, hpos
);
768 /* Detect the case where we are called from reset_sys_modes
769 and the costs have never been calculated. Do nothing. */
770 if (chars_wasted
== 0)
773 hpos
+= chars_wasted
[vpos
] & 077;
774 if (curY
== vpos
&& curX
== hpos
)
776 if (!TF_standout_motion
)
777 background_highlight ();
778 if (!TF_insmode_motion
)
783 /* Similar but don't take any account of the wasted characters. */
786 raw_cursor_to (row
, col
)
789 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
790 if (! FRAME_TERMCAP_P (f
))
792 (*raw_cursor_to_hook
) (row
, col
);
795 if (curY
== row
&& curX
== col
)
797 if (!TF_standout_motion
)
798 background_highlight ();
799 if (!TF_insmode_motion
)
804 /* Erase operations */
806 /* clear from cursor to end of frame */
812 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
814 (*clear_to_end_hook
) ();
817 if (TS_clr_to_bottom
)
819 background_highlight ();
820 OUTPUT (TS_clr_to_bottom
);
821 bzero (chars_wasted
+ curY
,
822 FRAME_HEIGHT (XFRAME (selected_frame
)) - curY
);
826 for (i
= curY
; i
< FRAME_HEIGHT (XFRAME (selected_frame
)); i
++)
829 clear_end_of_line_raw (FRAME_WIDTH (XFRAME (selected_frame
)));
834 /* Clear entire frame */
839 struct frame
*sf
= XFRAME (selected_frame
);
842 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: sf
)))
844 (*clear_frame_hook
) ();
849 background_highlight ();
850 OUTPUT (TS_clr_frame
);
851 bzero (chars_wasted
, FRAME_HEIGHT (sf
));
861 /* Clear to end of line, but do not clear any standout marker.
862 Assumes that the cursor is positioned at a character of real text,
863 which implies it cannot be before a standout marker
864 unless the marker has zero width.
866 Note that the cursor may be moved. */
869 clear_end_of_line (first_unused_hpos
)
870 int first_unused_hpos
;
872 if (FRAME_TERMCAP_P (XFRAME (selected_frame
))
874 && TN_standout_width
== 0 && curX
== 0 && chars_wasted
[curY
] != 0)
875 write_glyphs (&space_glyph
, 1);
876 clear_end_of_line_raw (first_unused_hpos
);
879 /* Clear from cursor to end of line.
880 Assume that the line is already clear starting at column first_unused_hpos.
881 If the cursor is at a standout marker, erase the marker.
883 Note that the cursor may be moved, on terminals lacking a `ce' string. */
886 clear_end_of_line_raw (first_unused_hpos
)
887 int first_unused_hpos
;
891 if (clear_end_of_line_hook
892 && ! FRAME_TERMCAP_P ((updating_frame
894 : XFRAME (selected_frame
))))
896 (*clear_end_of_line_hook
) (first_unused_hpos
);
900 /* Detect the case where we are called from reset_sys_modes
901 and the costs have never been calculated. Do nothing. */
902 if (chars_wasted
== 0)
905 first_unused_hpos
+= chars_wasted
[curY
] & 077;
906 if (curX
>= first_unused_hpos
)
908 /* Notice if we are erasing a magic cookie */
910 chars_wasted
[curY
] = 0;
911 background_highlight ();
914 OUTPUT1 (TS_clr_line
);
917 { /* have to do it the hard way */
918 struct frame
*sf
= XFRAME (selected_frame
);
921 /* Do not write in last row last col with Auto-wrap on. */
922 if (AutoWrap
&& curY
== FRAME_HEIGHT (sf
) - 1
923 && first_unused_hpos
== FRAME_WIDTH (sf
))
926 for (i
= curX
; i
< first_unused_hpos
; i
++)
929 fputc (' ', termscript
);
932 cmplus (first_unused_hpos
- curX
);
936 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
937 store them at DST. Do not write more than DST_LEN bytes. That may
938 require stopping before all SRC_LEN input glyphs have been
941 We store the number of glyphs actually converted in *CONSUMED. The
942 return value is the number of bytes store in DST. */
945 encode_terminal_code (src
, dst
, src_len
, dst_len
, consumed
)
949 int dst_len
, *consumed
;
951 struct glyph
*src_start
= src
, *src_end
= src
+ src_len
;
952 unsigned char *dst_start
= dst
, *dst_end
= dst
+ dst_len
;
955 unsigned char workbuf
[MAX_MULTIBYTE_LENGTH
], *buf
;
957 register int tlen
= GLYPH_TABLE_LENGTH
;
958 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
960 struct coding_system
*coding
;
962 /* If terminal_coding does any conversion, use it, otherwise use
963 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
964 because it always return 1 if the member src_multibyte is 1. */
965 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
967 : &safe_terminal_coding
);
969 while (src
< src_end
)
971 /* We must skip glyphs to be padded for a wide character. */
972 if (! CHAR_GLYPH_PADDING_P (*src
))
974 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
976 if (g
< 0 || g
>= tlen
)
978 /* This glyph doesn't has an entry in Vglyph_table. */
979 if (! CHAR_VALID_P (src
->u
.ch
, 0))
983 coding
->src_multibyte
= 0;
987 len
= CHAR_STRING (src
->u
.ch
, workbuf
);
989 coding
->src_multibyte
= 1;
994 /* This glyph has an entry in Vglyph_table,
995 so process any alias before testing for simpleness. */
996 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
998 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
1000 /* We set the multi-byte form of a character in G
1001 (that should be an ASCII character) at
1003 workbuf
[0] = FAST_GLYPH_CHAR (g
);
1006 coding
->src_multibyte
= 0;
1010 /* We have a string in Vglyph_table. */
1011 len
= GLYPH_LENGTH (tbase
, g
);
1012 buf
= GLYPH_STRING (tbase
, g
);
1013 coding
->src_multibyte
= STRING_MULTIBYTE (tbase
[g
]);
1017 result
= encode_coding (coding
, buf
, dst
, len
, dst_end
- dst
);
1018 len
-= coding
->consumed
;
1019 dst
+= coding
->produced
;
1020 if (result
== CODING_FINISH_INSUFFICIENT_DST
1021 || (result
== CODING_FINISH_INSUFFICIENT_SRC
1022 && len
> dst_end
- dst
))
1023 /* The remaining output buffer is too short. We must
1024 break the loop here without increasing SRC so that the
1025 next call of this function starts from the same glyph. */
1030 /* This is the case that a code of the range 0200..0237
1031 exists in buf. We must just write out such a code. */
1032 buf
+= coding
->consumed
;
1040 *consumed
= src
- src_start
;
1041 return (dst
- dst_start
);
1046 write_glyphs (string
, len
)
1047 register struct glyph
*string
;
1050 int produced
, consumed
;
1051 struct frame
*sf
= XFRAME (selected_frame
);
1052 struct frame
*f
= updating_frame
? updating_frame
: sf
;
1053 unsigned char conversion_buffer
[1024];
1054 int conversion_buffer_size
= sizeof conversion_buffer
;
1056 if (write_glyphs_hook
1057 && ! FRAME_TERMCAP_P (f
))
1059 (*write_glyphs_hook
) (string
, len
);
1065 /* Don't dare write in last column of bottom line, if Auto-Wrap,
1066 since that would scroll the whole frame on some terminals. */
1069 && curY
+ 1 == FRAME_HEIGHT (sf
)
1070 && (curX
+ len
- (chars_wasted
[curY
] & 077) == FRAME_WIDTH (sf
)))
1077 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1079 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
1083 /* Identify a run of glyphs with the same face. */
1084 int face_id
= string
->face_id
;
1087 for (n
= 1; n
< len
; ++n
)
1088 if (string
[n
].face_id
!= face_id
)
1091 /* Turn appearance modes of the face of the run on. */
1092 highlight_if_desired ();
1093 turn_on_face (f
, face_id
);
1097 /* We use a fixed size (1024 bytes) of conversion buffer.
1098 Usually it is sufficient, but if not, we just repeat the
1100 produced
= encode_terminal_code (string
, conversion_buffer
,
1101 n
, conversion_buffer_size
,
1105 fwrite (conversion_buffer
, 1, produced
, stdout
);
1106 if (ferror (stdout
))
1109 fwrite (conversion_buffer
, 1, produced
, termscript
);
1116 /* Turn appearance modes off. */
1117 turn_off_face (f
, face_id
);
1118 turn_off_highlight ();
1121 /* We may have to output some codes to terminate the writing. */
1122 if (CODING_REQUIRE_FLUSHING (&terminal_coding
))
1124 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
1125 encode_coding (&terminal_coding
, "", conversion_buffer
,
1126 0, conversion_buffer_size
);
1127 if (terminal_coding
.produced
> 0)
1129 fwrite (conversion_buffer
, 1, terminal_coding
.produced
, stdout
);
1130 if (ferror (stdout
))
1133 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
1141 /* If start is zero, insert blanks instead of a string at start */
1144 insert_glyphs (start
, len
)
1145 register struct glyph
*start
;
1149 struct glyph
*glyph
;
1150 struct frame
*f
, *sf
;
1155 if (insert_glyphs_hook
)
1157 (*insert_glyphs_hook
) (start
, len
);
1161 sf
= XFRAME (selected_frame
);
1162 f
= updating_frame
? updating_frame
: sf
;
1164 if (TS_ins_multi_chars
)
1166 buf
= tparam (TS_ins_multi_chars
, 0, 0, len
);
1170 write_glyphs (start
, len
);
1176 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
1177 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
1180 int produced
, consumed
;
1181 unsigned char conversion_buffer
[1024];
1182 int conversion_buffer_size
= sizeof conversion_buffer
;
1184 OUTPUT1_IF (TS_ins_char
);
1187 conversion_buffer
[0] = SPACEGLYPH
;
1192 highlight_if_desired ();
1193 turn_on_face (f
, start
->face_id
);
1196 /* We must open sufficient space for a character which
1197 occupies more than one column. */
1198 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
1200 OUTPUT1_IF (TS_ins_char
);
1205 /* This is the last glyph. */
1206 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
1208 /* The size of conversion buffer (1024 bytes) is surely
1209 sufficient for just one glyph. */
1210 produced
= encode_terminal_code (glyph
, conversion_buffer
, 1,
1211 conversion_buffer_size
, &consumed
);
1216 fwrite (conversion_buffer
, 1, produced
, stdout
);
1217 if (ferror (stdout
))
1220 fwrite (conversion_buffer
, 1, produced
, termscript
);
1223 OUTPUT1_IF (TS_pad_inserted_char
);
1226 turn_off_face (f
, glyph
->face_id
);
1227 turn_off_highlight ();
1241 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1243 (*delete_glyphs_hook
) (n
);
1247 if (delete_in_insert_mode
)
1254 OUTPUT_IF (TS_delete_mode
);
1257 if (TS_del_multi_chars
)
1259 buf
= tparam (TS_del_multi_chars
, 0, 0, n
);
1264 for (i
= 0; i
< n
; i
++)
1265 OUTPUT1 (TS_del_char
);
1266 if (!delete_in_insert_mode
)
1267 OUTPUT_IF (TS_end_delete_mode
);
1270 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1273 ins_del_lines (vpos
, n
)
1276 char *multi
= n
> 0 ? TS_ins_multi_lines
: TS_del_multi_lines
;
1277 char *single
= n
> 0 ? TS_ins_line
: TS_del_line
;
1278 char *scroll
= n
> 0 ? TS_rev_scroll
: TS_fwd_scroll
;
1281 register int i
= n
> 0 ? n
: -n
;
1284 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1286 (*ins_del_lines_hook
) (vpos
, n
);
1290 sf
= XFRAME (selected_frame
);
1292 /* If the lines below the insertion are being pushed
1293 into the end of the window, this is the same as clearing;
1294 and we know the lines are already clear, since the matching
1295 deletion has already been done. So can ignore this. */
1296 /* If the lines below the deletion are blank lines coming
1297 out of the end of the window, don't bother,
1298 as there will be a matching inslines later that will flush them. */
1299 if (scroll_region_ok
&& vpos
+ i
>= specified_window
)
1301 if (!memory_below_frame
&& vpos
+ i
>= FRAME_HEIGHT (sf
))
1306 raw_cursor_to (vpos
, 0);
1307 background_highlight ();
1308 buf
= tparam (multi
, 0, 0, i
);
1314 raw_cursor_to (vpos
, 0);
1315 background_highlight ();
1323 set_scroll_region (vpos
, specified_window
);
1325 raw_cursor_to (specified_window
- 1, 0);
1327 raw_cursor_to (vpos
, 0);
1328 background_highlight ();
1330 OUTPUTL (scroll
, specified_window
- vpos
);
1331 set_scroll_region (0, specified_window
);
1334 if (TN_standout_width
>= 0)
1336 register int lower_limit
1339 : FRAME_HEIGHT (sf
));
1343 bcopy (&chars_wasted
[vpos
- n
], &chars_wasted
[vpos
],
1344 lower_limit
- vpos
+ n
);
1345 bzero (&chars_wasted
[lower_limit
+ n
], - n
);
1349 bcopy (&chars_wasted
[vpos
], ©buf
[vpos
], lower_limit
- vpos
- n
);
1350 bcopy (©buf
[vpos
], &chars_wasted
[vpos
+ n
],
1351 lower_limit
- vpos
- n
);
1352 bzero (&chars_wasted
[vpos
], n
);
1355 if (!scroll_region_ok
&& memory_below_frame
&& n
< 0)
1357 cursor_to (FRAME_HEIGHT (sf
) + n
, 0);
1362 /* Compute cost of sending "str", in characters,
1363 not counting any line-dependent padding. */
1371 tputs (str
, 0, evalcost
);
1375 /* Compute cost of sending "str", in characters,
1376 counting any line-dependent padding at one line. */
1379 string_cost_one_line (str
)
1384 tputs (str
, 1, evalcost
);
1388 /* Compute per line amount of line-dependent padding,
1389 in tenths of characters. */
1397 tputs (str
, 0, evalcost
);
1400 tputs (str
, 10, evalcost
);
1405 /* char_ins_del_cost[n] is cost of inserting N characters.
1406 char_ins_del_cost[-n] is cost of deleting N characters.
1407 The length of this vector is based on max_frame_width. */
1409 int *char_ins_del_vector
;
1411 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH ((f))])
1416 calculate_ins_del_char_costs (frame
)
1419 int ins_startup_cost
, del_startup_cost
;
1420 int ins_cost_per_char
, del_cost_per_char
;
1424 if (TS_ins_multi_chars
)
1426 ins_cost_per_char
= 0;
1427 ins_startup_cost
= string_cost_one_line (TS_ins_multi_chars
);
1429 else if (TS_ins_char
|| TS_pad_inserted_char
1430 || (TS_insert_mode
&& TS_end_insert_mode
))
1432 ins_startup_cost
= (30 * (string_cost (TS_insert_mode
)
1433 + string_cost (TS_end_insert_mode
))) / 100;
1434 ins_cost_per_char
= (string_cost_one_line (TS_ins_char
)
1435 + string_cost_one_line (TS_pad_inserted_char
));
1439 ins_startup_cost
= 9999;
1440 ins_cost_per_char
= 0;
1443 if (TS_del_multi_chars
)
1445 del_cost_per_char
= 0;
1446 del_startup_cost
= string_cost_one_line (TS_del_multi_chars
);
1448 else if (TS_del_char
)
1450 del_startup_cost
= (string_cost (TS_delete_mode
)
1451 + string_cost (TS_end_delete_mode
));
1452 if (delete_in_insert_mode
)
1453 del_startup_cost
/= 2;
1454 del_cost_per_char
= string_cost_one_line (TS_del_char
);
1458 del_startup_cost
= 9999;
1459 del_cost_per_char
= 0;
1462 /* Delete costs are at negative offsets */
1463 p
= &char_ins_del_cost (frame
)[0];
1464 for (i
= FRAME_WIDTH (frame
); --i
>= 0;)
1465 *--p
= (del_startup_cost
+= del_cost_per_char
);
1467 /* Doing nothing is free */
1468 p
= &char_ins_del_cost (frame
)[0];
1471 /* Insert costs are at positive offsets */
1472 for (i
= FRAME_WIDTH (frame
); --i
>= 0;)
1473 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1477 calculate_costs (frame
)
1480 register char *f
= (TS_set_scroll_region
1481 ? TS_set_scroll_region
1482 : TS_set_scroll_region_1
);
1484 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1486 scroll_region_cost
= string_cost (f
);
1488 /* These variables are only used for terminal stuff. They are allocated
1489 once for the terminal frame of X-windows emacs, but not used afterwards.
1491 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1492 X turns off char_ins_del_ok.
1494 chars_wasted and copybuf are only used here in term.c in cases where
1495 the term hook isn't called. */
1497 max_frame_height
= max (max_frame_height
, FRAME_HEIGHT (frame
));
1498 max_frame_width
= max (max_frame_width
, FRAME_WIDTH (frame
));
1500 if (chars_wasted
!= 0)
1501 chars_wasted
= (char *) xrealloc (chars_wasted
, max_frame_height
);
1503 chars_wasted
= (char *) xmalloc (max_frame_height
);
1506 copybuf
= (char *) xrealloc (copybuf
, max_frame_height
);
1508 copybuf
= (char *) xmalloc (max_frame_height
);
1510 if (char_ins_del_vector
!= 0)
1512 = (int *) xrealloc (char_ins_del_vector
,
1514 + 2 * max_frame_width
* sizeof (int)));
1517 = (int *) xmalloc (sizeof (int)
1518 + 2 * max_frame_width
* sizeof (int));
1520 bzero (chars_wasted
, max_frame_height
);
1521 bzero (copybuf
, max_frame_height
);
1522 bzero (char_ins_del_vector
, (sizeof (int)
1523 + 2 * max_frame_width
* sizeof (int)));
1525 if (f
&& (!TS_ins_line
&& !TS_del_line
))
1526 do_line_insertion_deletion_costs (frame
,
1527 TS_rev_scroll
, TS_ins_multi_lines
,
1528 TS_fwd_scroll
, TS_del_multi_lines
,
1531 do_line_insertion_deletion_costs (frame
,
1532 TS_ins_line
, TS_ins_multi_lines
,
1533 TS_del_line
, TS_del_multi_lines
,
1536 calculate_ins_del_char_costs (frame
);
1538 /* Don't use TS_repeat if its padding is worse than sending the chars */
1539 if (TS_repeat
&& per_line_cost (TS_repeat
) * baud_rate
< 9000)
1540 RPov
= string_cost (TS_repeat
);
1542 RPov
= FRAME_WIDTH (frame
) * 2;
1544 cmcostinit (); /* set up cursor motion costs */
1551 /* Termcap capability names that correspond directly to X keysyms.
1552 Some of these (marked "terminfo") aren't supplied by old-style
1553 (Berkeley) termcap entries. They're listed in X keysym order;
1554 except we put the keypad keys first, so that if they clash with
1555 other keys (as on the IBM PC keyboard) they get overridden.
1558 static struct fkey_table keys
[] =
1560 "kh", "home", /* termcap */
1561 "kl", "left", /* termcap */
1562 "ku", "up", /* termcap */
1563 "kr", "right", /* termcap */
1564 "kd", "down", /* termcap */
1565 "%8", "prior", /* terminfo */
1566 "%5", "next", /* terminfo */
1567 "@7", "end", /* terminfo */
1568 "@1", "begin", /* terminfo */
1569 "*6", "select", /* terminfo */
1570 "%9", "print", /* terminfo */
1571 "@4", "execute", /* terminfo --- actually the `command' key */
1573 * "insert" --- see below
1575 "&8", "undo", /* terminfo */
1576 "%0", "redo", /* terminfo */
1577 "%7", "menu", /* terminfo --- actually the `options' key */
1578 "@0", "find", /* terminfo */
1579 "@2", "cancel", /* terminfo */
1580 "%1", "help", /* terminfo */
1582 * "break" goes here, but can't be reliably intercepted with termcap
1584 "&4", "reset", /* terminfo --- actually `restart' */
1586 * "system" and "user" --- no termcaps
1588 "kE", "clearline", /* terminfo */
1589 "kA", "insertline", /* terminfo */
1590 "kL", "deleteline", /* terminfo */
1591 "kI", "insertchar", /* terminfo */
1592 "kD", "deletechar", /* terminfo */
1593 "kB", "backtab", /* terminfo */
1595 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1597 "@8", "kp-enter", /* terminfo */
1599 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1600 * "kp-multiply", "kp-add", "kp-separator",
1601 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1602 * --- no termcaps for any of these.
1604 "K4", "kp-1", /* terminfo */
1606 * "kp-2" --- no termcap
1608 "K5", "kp-3", /* terminfo */
1610 * "kp-4" --- no termcap
1612 "K2", "kp-5", /* terminfo */
1614 * "kp-6" --- no termcap
1616 "K1", "kp-7", /* terminfo */
1618 * "kp-8" --- no termcap
1620 "K3", "kp-9", /* terminfo */
1622 * "kp-equal" --- no termcap
1635 static char **term_get_fkeys_arg
;
1636 static Lisp_Object
term_get_fkeys_1 ();
1638 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1639 This function scans the termcap function key sequence entries, and
1640 adds entries to Vfunction_key_map for each function key it finds. */
1643 term_get_fkeys (address
)
1646 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1647 errors during the call. The only errors should be from Fdefine_key
1648 when given a key sequence containing an invalid prefix key. If the
1649 termcap defines function keys which use a prefix that is already bound
1650 to a command by the default bindings, we should silently ignore that
1651 function key specification, rather than giving the user an error and
1652 refusing to run at all on such a terminal. */
1654 extern Lisp_Object
Fidentity ();
1655 term_get_fkeys_arg
= address
;
1656 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1664 char **address
= term_get_fkeys_arg
;
1666 /* This can happen if CANNOT_DUMP or with strange options. */
1668 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1670 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1672 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1674 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1675 Fmake_vector (make_number (1),
1676 intern (keys
[i
].name
)));
1679 /* The uses of the "k0" capability are inconsistent; sometimes it
1680 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1681 We will attempt to politely accommodate both systems by testing for
1682 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1685 char *k_semi
= tgetstr ("k;", address
);
1686 char *k0
= tgetstr ("k0", address
);
1687 char *k0_name
= "f10";
1691 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1692 Fmake_vector (make_number (1), intern ("f10")));
1697 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1698 Fmake_vector (make_number (1), intern (k0_name
)));
1701 /* Set up cookies for numbered function keys above f10. */
1703 char fcap
[3], fkey
[4];
1705 fcap
[0] = 'F'; fcap
[2] = '\0';
1706 for (i
= 11; i
< 64; i
++)
1709 fcap
[1] = '1' + i
- 11;
1711 fcap
[1] = 'A' + i
- 20;
1713 fcap
[1] = 'a' + i
- 46;
1716 char *sequence
= tgetstr (fcap
, address
);
1719 sprintf (fkey
, "f%d", i
);
1720 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1721 Fmake_vector (make_number (1),
1729 * Various mappings to try and get a better fit.
1732 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1733 if (!tgetstr (cap1, address)) \
1735 char *sequence = tgetstr (cap2, address); \
1737 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1738 Fmake_vector (make_number (1), \
1742 /* if there's no key_next keycap, map key_npage to `next' keysym */
1743 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1744 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1745 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1746 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1747 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1748 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1749 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1751 /* IBM has their own non-standard dialect of terminfo.
1752 If the standard name isn't found, try the IBM name. */
1753 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1754 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1755 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1756 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1757 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1758 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1759 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1760 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1761 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1762 #undef CONDITIONAL_REASSIGN
1769 /***********************************************************************
1770 Character Display Information
1771 ***********************************************************************/
1773 static void append_glyph
P_ ((struct it
*));
1776 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1777 terminal frames if IT->glyph_row != NULL. IT->c is the character
1778 for which to produce glyphs; IT->face_id contains the character's
1779 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1786 struct glyph
*glyph
, *end
;
1789 xassert (it
->glyph_row
);
1790 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1791 + it
->glyph_row
->used
[it
->area
]);
1792 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1795 i
< it
->pixel_width
&& glyph
< end
;
1798 glyph
->type
= CHAR_GLYPH
;
1799 glyph
->pixel_width
= 1;
1800 glyph
->u
.ch
= it
->c
;
1801 glyph
->face_id
= it
->face_id
;
1802 glyph
->padding_p
= i
> 0;
1803 glyph
->charpos
= CHARPOS (it
->position
);
1804 glyph
->object
= it
->object
;
1806 ++it
->glyph_row
->used
[it
->area
];
1812 /* Produce glyphs for the display element described by IT. The
1813 function fills output fields of IT with pixel information like the
1814 pixel width and height of a character, and maybe produces glyphs at
1815 the same time if IT->glyph_row is non-null. See the explanation of
1816 struct display_iterator in dispextern.h for an overview. */
1822 /* If a hook is installed, let it do the work. */
1823 xassert (it
->what
== IT_CHARACTER
1824 || it
->what
== IT_COMPOSITION
1825 || it
->what
== IT_IMAGE
1826 || it
->what
== IT_STRETCH
);
1828 /* Nothing but characters are supported on terminal frames. For a
1829 composition sequence, it->c is the first character of the
1831 xassert (it
->what
== IT_CHARACTER
1832 || it
->what
== IT_COMPOSITION
);
1834 if (it
->c
>= 040 && it
->c
< 0177)
1836 it
->pixel_width
= it
->nglyphs
= 1;
1840 else if (it
->c
== '\n')
1841 it
->pixel_width
= it
->nglyphs
= 0;
1842 else if (it
->c
== '\t')
1844 int absolute_x
= (it
->current_x
1845 + it
->continuation_lines_width
);
1847 = (((1 + absolute_x
+ it
->tab_width
- 1)
1852 /* If part of the TAB has been displayed on the previous line
1853 which is continued now, continuation_lines_width will have
1854 been incremented already by the part that fitted on the
1855 continued line. So, we will get the right number of spaces
1857 nspaces
= next_tab_x
- absolute_x
;
1864 it
->pixel_width
= it
->len
= 1;
1872 it
->pixel_width
= nspaces
;
1873 it
->nglyphs
= nspaces
;
1875 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1877 /* Coming here means that it->c is from display table, thus we
1878 must send the code as is to the terminal. Although there's
1879 no way to know how many columns it occupies on a screen, it
1880 is a good assumption that a single byte code has 1-column
1882 it
->pixel_width
= it
->nglyphs
= 1;
1888 /* A multi-byte character. The display width is fixed for all
1889 characters of the set. Some of the glyphs may have to be
1890 ignored because they are already displayed in a continued
1892 int charset
= CHAR_CHARSET (it
->c
);
1894 it
->pixel_width
= CHARSET_WIDTH (charset
);
1895 it
->nglyphs
= it
->pixel_width
;
1901 /* Advance current_x by the pixel width as a convenience for
1903 if (it
->area
== TEXT_AREA
)
1904 it
->current_x
+= it
->pixel_width
;
1905 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1906 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1910 /* Get information about special display element WHAT in an
1911 environment described by IT. WHAT is one of IT_TRUNCATION or
1912 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1913 non-null glyph_row member. This function ensures that fields like
1914 face_id, c, len of IT are left untouched. */
1917 produce_special_glyphs (it
, what
)
1919 enum display_element_type what
;
1925 temp_it
.what
= IT_CHARACTER
;
1927 temp_it
.object
= make_number (0);
1928 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1930 if (what
== IT_CONTINUATION
)
1932 /* Continuation glyph. */
1934 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1935 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1937 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it
->dp
)));
1938 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1943 produce_glyphs (&temp_it
);
1944 it
->pixel_width
= temp_it
.pixel_width
;
1945 it
->nglyphs
= temp_it
.pixel_width
;
1947 else if (what
== IT_TRUNCATION
)
1949 /* Truncation glyph. */
1951 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1952 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1954 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it
->dp
)));
1955 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1960 produce_glyphs (&temp_it
);
1961 it
->pixel_width
= temp_it
.pixel_width
;
1962 it
->nglyphs
= temp_it
.pixel_width
;
1969 /* Return an estimation of the pixel height of mode or top lines on
1970 frame F. FACE_ID specifies what line's height to estimate. */
1973 estimate_mode_line_height (f
, face_id
)
1975 enum face_id face_id
;
1977 if (estimate_mode_line_height_hook
)
1978 return estimate_mode_line_height_hook (f
, face_id
);
1985 /***********************************************************************
1987 ***********************************************************************/
1989 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1990 one of the enumerators from enum no_color_bit, or a bit set built
1991 from them. Some display attributes may not be used together with
1992 color; the termcap capability `NC' specifies which ones. */
1994 #define MAY_USE_WITH_COLORS_P(ATTR) \
1995 (TN_max_colors > 0 \
1996 ? (TN_no_color_video & (ATTR)) == 0 \
1999 /* Turn appearances of face FACE_ID on tty frame F on. */
2002 turn_on_face (f
, face_id
)
2006 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2008 xassert (face
!= NULL
);
2010 if (face
->tty_bold_p
)
2012 if (MAY_USE_WITH_COLORS_P (NC_BOLD
))
2013 OUTPUT1_IF (TS_enter_bold_mode
);
2015 else if (face
->tty_dim_p
)
2016 if (MAY_USE_WITH_COLORS_P (NC_DIM
))
2017 OUTPUT1_IF (TS_enter_dim_mode
);
2019 /* Alternate charset and blinking not yet used. */
2020 if (face
->tty_alt_charset_p
2021 && MAY_USE_WITH_COLORS_P (NC_ALT_CHARSET
))
2022 OUTPUT1_IF (TS_enter_alt_charset_mode
);
2024 if (face
->tty_blinking_p
2025 && MAY_USE_WITH_COLORS_P (NC_BLINK
))
2026 OUTPUT1_IF (TS_enter_blink_mode
);
2028 if (face
->tty_underline_p
2029 /* Don't underline if that's difficult. */
2030 && TN_magic_cookie_glitch_ul
<= 0
2031 && MAY_USE_WITH_COLORS_P (NC_UNDERLINE
))
2032 OUTPUT1_IF (TS_enter_underline_mode
);
2034 if (MAY_USE_WITH_COLORS_P (NC_REVERSE
))
2035 if (face
->tty_reverse_p
2036 || face
->foreground
== FACE_TTY_DEFAULT_BG_COLOR
2037 || face
->background
== FACE_TTY_DEFAULT_FG_COLOR
)
2038 OUTPUT1_IF (TS_enter_reverse_mode
);
2040 if (TN_max_colors
> 0)
2044 if (face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2045 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
2046 && face
->foreground
!= FACE_TTY_DEFAULT_BG_COLOR
2047 && TS_set_foreground
)
2049 p
= tparam (TS_set_foreground
, NULL
, 0, (int) face
->foreground
);
2054 if (face
->background
!= FACE_TTY_DEFAULT_COLOR
2055 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
2056 && face
->background
!= FACE_TTY_DEFAULT_FG_COLOR
2057 && TS_set_background
)
2059 p
= tparam (TS_set_background
, NULL
, 0, (int) face
->background
);
2067 /* Turn off appearances of face FACE_ID on tty frame F. */
2070 turn_off_face (f
, face_id
)
2074 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2076 xassert (face
!= NULL
);
2078 if (TS_exit_attribute_mode
)
2080 /* Capability "me" will turn off appearance modes double-bright,
2081 half-bright, reverse-video, standout, underline. It may or
2082 may not turn off alt-char-mode. */
2083 if (face
->tty_bold_p
2085 || face
->tty_reverse_p
2086 || face
->tty_alt_charset_p
2087 || face
->tty_blinking_p
2088 || face
->tty_underline_p
)
2090 OUTPUT1_IF (TS_exit_attribute_mode
);
2091 if (strcmp (TS_exit_attribute_mode
, TS_end_standout_mode
) == 0)
2095 if (face
->tty_alt_charset_p
)
2096 OUTPUT_IF (TS_exit_alt_charset_mode
);
2100 /* If we don't have "me" we can only have those appearances
2101 that have exit sequences defined. */
2102 if (face
->tty_alt_charset_p
)
2103 OUTPUT_IF (TS_exit_alt_charset_mode
);
2105 if (face
->tty_underline_p
2106 /* We don't underline if that's difficult. */
2107 && TN_magic_cookie_glitch_ul
<= 0)
2108 OUTPUT_IF (TS_exit_underline_mode
);
2111 /* Switch back to default colors. */
2112 if (TN_max_colors
> 0
2113 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2114 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2115 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2116 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2117 OUTPUT1_IF (TS_orig_pair
);
2121 /* Return non-zero if the terminal is capable to display colors. */
2123 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2125 "Return non-nil if TTY can display colors on FRAME.")
2129 return TN_max_colors
> 0 ? Qt
: Qnil
;
2135 /***********************************************************************
2137 ***********************************************************************/
2140 term_init (terminal_type
)
2141 char *terminal_type
;
2144 char **address
= &area
;
2148 struct frame
*sf
= XFRAME (selected_frame
);
2151 initialize_w32_display ();
2155 area
= (char *) xmalloc (2044);
2160 FrameRows
= FRAME_HEIGHT (sf
);
2161 FrameCols
= FRAME_WIDTH (sf
);
2162 specified_window
= FRAME_HEIGHT (sf
);
2164 delete_in_insert_mode
= 1;
2167 scroll_region_ok
= 0;
2169 /* Seems to insert lines when it's not supposed to, messing
2170 up the display. In doing a trace, it didn't seem to be
2171 called much, so I don't think we're losing anything by
2174 line_ins_del_ok
= 0;
2175 char_ins_del_ok
= 1;
2179 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
2180 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
2181 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2184 #else /* not WINDOWSNT */
2188 status
= tgetent (buffer
, terminal_type
);
2192 fatal ("Cannot open terminfo database file");
2194 fatal ("Cannot open termcap database file");
2200 fatal ("Terminal type %s is not defined.\n\
2201 If that is not the actual type of terminal you have,\n\
2202 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2203 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2204 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2207 fatal ("Terminal type %s is not defined.\n\
2208 If that is not the actual type of terminal you have,\n\
2209 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2210 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2211 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2216 area
= (char *) xmalloc (2044);
2218 area
= (char *) xmalloc (strlen (buffer
));
2219 #endif /* not TERMINFO */
2223 TS_ins_line
= tgetstr ("al", address
);
2224 TS_ins_multi_lines
= tgetstr ("AL", address
);
2225 TS_bell
= tgetstr ("bl", address
);
2226 BackTab
= tgetstr ("bt", address
);
2227 TS_clr_to_bottom
= tgetstr ("cd", address
);
2228 TS_clr_line
= tgetstr ("ce", address
);
2229 TS_clr_frame
= tgetstr ("cl", address
);
2230 ColPosition
= NULL
; /* tgetstr ("ch", address); */
2231 AbsPosition
= tgetstr ("cm", address
);
2232 CR
= tgetstr ("cr", address
);
2233 TS_set_scroll_region
= tgetstr ("cs", address
);
2234 TS_set_scroll_region_1
= tgetstr ("cS", address
);
2235 RowPosition
= tgetstr ("cv", address
);
2236 TS_del_char
= tgetstr ("dc", address
);
2237 TS_del_multi_chars
= tgetstr ("DC", address
);
2238 TS_del_line
= tgetstr ("dl", address
);
2239 TS_del_multi_lines
= tgetstr ("DL", address
);
2240 TS_delete_mode
= tgetstr ("dm", address
);
2241 TS_end_delete_mode
= tgetstr ("ed", address
);
2242 TS_end_insert_mode
= tgetstr ("ei", address
);
2243 Home
= tgetstr ("ho", address
);
2244 TS_ins_char
= tgetstr ("ic", address
);
2245 TS_ins_multi_chars
= tgetstr ("IC", address
);
2246 TS_insert_mode
= tgetstr ("im", address
);
2247 TS_pad_inserted_char
= tgetstr ("ip", address
);
2248 TS_end_keypad_mode
= tgetstr ("ke", address
);
2249 TS_keypad_mode
= tgetstr ("ks", address
);
2250 LastLine
= tgetstr ("ll", address
);
2251 Right
= tgetstr ("nd", address
);
2252 Down
= tgetstr ("do", address
);
2254 Down
= tgetstr ("nl", address
); /* Obsolete name for "do" */
2256 /* VMS puts a carriage return before each linefeed,
2257 so it is not safe to use linefeeds. */
2258 if (Down
&& Down
[0] == '\n' && Down
[1] == '\0')
2261 if (tgetflag ("bs"))
2262 Left
= "\b"; /* can't possibly be longer! */
2263 else /* (Actually, "bs" is obsolete...) */
2264 Left
= tgetstr ("le", address
);
2266 Left
= tgetstr ("bc", address
); /* Obsolete name for "le" */
2267 TS_pad_char
= tgetstr ("pc", address
);
2268 TS_repeat
= tgetstr ("rp", address
);
2269 TS_end_standout_mode
= tgetstr ("se", address
);
2270 TS_fwd_scroll
= tgetstr ("sf", address
);
2271 TS_standout_mode
= tgetstr ("so", address
);
2272 TS_rev_scroll
= tgetstr ("sr", address
);
2273 Wcm
.cm_tab
= tgetstr ("ta", address
);
2274 TS_end_termcap_modes
= tgetstr ("te", address
);
2275 TS_termcap_modes
= tgetstr ("ti", address
);
2276 Up
= tgetstr ("up", address
);
2277 TS_visible_bell
= tgetstr ("vb", address
);
2278 TS_cursor_normal
= tgetstr ("ve", address
);
2279 TS_cursor_visible
= tgetstr ("vs", address
);
2280 TS_cursor_invisible
= tgetstr ("vi", address
);
2281 TS_set_window
= tgetstr ("wi", address
);
2283 TS_enter_underline_mode
= tgetstr ("us", address
);
2284 TS_exit_underline_mode
= tgetstr ("ue", address
);
2285 TN_magic_cookie_glitch_ul
= tgetnum ("ug");
2286 TS_enter_bold_mode
= tgetstr ("md", address
);
2287 TS_enter_dim_mode
= tgetstr ("mh", address
);
2288 TS_enter_blink_mode
= tgetstr ("mb", address
);
2289 TS_enter_reverse_mode
= tgetstr ("mr", address
);
2290 TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2291 TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2292 TS_exit_attribute_mode
= tgetstr ("me", address
);
2294 MultiUp
= tgetstr ("UP", address
);
2295 MultiDown
= tgetstr ("DO", address
);
2296 MultiLeft
= tgetstr ("LE", address
);
2297 MultiRight
= tgetstr ("RI", address
);
2299 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2300 color because we can't switch back to the default foreground and
2302 TS_orig_pair
= tgetstr ("op", address
);
2305 TS_set_foreground
= tgetstr ("AF", address
);
2306 TS_set_background
= tgetstr ("AB", address
);
2307 if (!TS_set_foreground
)
2310 TS_set_foreground
= tgetstr ("Sf", address
);
2311 TS_set_background
= tgetstr ("Sb", address
);
2314 TN_max_colors
= tgetnum ("Co");
2315 TN_max_pairs
= tgetnum ("pa");
2317 TN_no_color_video
= tgetnum ("NC");
2318 if (TN_no_color_video
== -1)
2319 TN_no_color_video
= 0;
2322 MagicWrap
= tgetflag ("xn");
2323 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2324 the former flag imply the latter. */
2325 AutoWrap
= MagicWrap
|| tgetflag ("am");
2326 memory_below_frame
= tgetflag ("db");
2327 TF_hazeltine
= tgetflag ("hz");
2328 must_write_spaces
= tgetflag ("in");
2329 meta_key
= tgetflag ("km") || tgetflag ("MT");
2330 TF_insmode_motion
= tgetflag ("mi");
2331 TF_standout_motion
= tgetflag ("ms");
2332 TF_underscore
= tgetflag ("ul");
2333 TF_xs
= tgetflag ("xs");
2334 TF_teleray
= tgetflag ("xt");
2336 term_get_fkeys (address
);
2338 /* Get frame size from system, or else from termcap. */
2341 get_frame_size (&width
, &height
);
2342 FRAME_WIDTH (sf
) = width
;
2343 FRAME_HEIGHT (sf
) = height
;
2346 if (FRAME_WIDTH (sf
) <= 0)
2347 SET_FRAME_WIDTH (sf
, tgetnum ("co"));
2349 /* Keep width and external_width consistent */
2350 SET_FRAME_WIDTH (sf
, FRAME_WIDTH (sf
));
2351 if (FRAME_HEIGHT (sf
) <= 0)
2352 FRAME_HEIGHT (sf
) = tgetnum ("li");
2354 if (FRAME_HEIGHT (sf
) < 3 || FRAME_WIDTH (sf
) < 3)
2355 fatal ("Screen size %dx%d is too small",
2356 FRAME_HEIGHT (sf
), FRAME_WIDTH (sf
));
2358 min_padding_speed
= tgetnum ("pb");
2359 TN_standout_width
= tgetnum ("sg");
2360 TabWidth
= tgetnum ("tw");
2363 /* These capabilities commonly use ^J.
2364 I don't know why, but sending them on VMS does not work;
2365 it causes following spaces to be lost, sometimes.
2366 For now, the simplest fix is to avoid using these capabilities ever. */
2367 if (Down
&& Down
[0] == '\n')
2375 TS_fwd_scroll
= Down
;
2377 PC
= TS_pad_char
? *TS_pad_char
: 0;
2382 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2383 and newer termcap doc does not seem to say there is a default.
2388 if (TS_standout_mode
== 0)
2390 TN_standout_width
= tgetnum ("ug");
2391 TS_end_standout_mode
= tgetstr ("ue", address
);
2392 TS_standout_mode
= tgetstr ("us", address
);
2395 /* If no `se' string, try using a `me' string instead.
2396 If that fails, we can't use standout mode at all. */
2397 if (TS_end_standout_mode
== 0)
2399 char *s
= tgetstr ("me", address
);
2401 TS_end_standout_mode
= s
;
2403 TS_standout_mode
= 0;
2409 /* Teleray: most programs want a space in front of TS_standout_mode,
2410 but Emacs can do without it (and give one extra column). */
2411 TS_standout_mode
= "\033RD";
2412 TN_standout_width
= 1;
2413 /* But that means we cannot rely on ^M to go to column zero! */
2415 /* LF can't be trusted either -- can alter hpos */
2416 /* if move at column 0 thru a line with TS_standout_mode */
2420 /* Special handling for certain terminal types known to need it */
2422 if (!strcmp (terminal_type
, "supdup"))
2424 memory_below_frame
= 1;
2425 Wcm
.cm_losewrap
= 1;
2427 if (!strncmp (terminal_type
, "c10", 3)
2428 || !strcmp (terminal_type
, "perq"))
2430 /* Supply a makeshift :wi string.
2431 This string is not valid in general since it works only
2432 for windows starting at the upper left corner;
2433 but that is all Emacs uses.
2435 This string works only if the frame is using
2436 the top of the video memory, because addressing is memory-relative.
2437 So first check the :ti string to see if that is true.
2439 It would be simpler if the :wi string could go in the termcap
2440 entry, but it can't because it is not fully valid.
2441 If it were in the termcap entry, it would confuse other programs. */
2444 p
= TS_termcap_modes
;
2445 while (*p
&& strcmp (p
, "\033v "))
2448 TS_set_window
= "\033v%C %C %C %C ";
2450 /* Termcap entry often fails to have :in: flag */
2451 must_write_spaces
= 1;
2452 /* :ti string typically fails to have \E^G! in it */
2453 /* This limits scope of insert-char to one line. */
2454 strcpy (area
, TS_termcap_modes
);
2455 strcat (area
, "\033\007!");
2456 TS_termcap_modes
= area
;
2457 area
+= strlen (area
) + 1;
2459 /* Change all %+ parameters to %C, to handle
2460 values above 96 correctly for the C100. */
2463 if (p
[0] == '%' && p
[1] == '+')
2469 FrameRows
= FRAME_HEIGHT (sf
);
2470 FrameCols
= FRAME_WIDTH (sf
);
2471 specified_window
= FRAME_HEIGHT (sf
);
2473 if (Wcm_init () == -1) /* can't do cursor motion */
2475 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2476 It lacks the ability to position the cursor.\n\
2477 If that is not the actual type of terminal you have, use either the\n\
2478 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2479 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2483 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2484 It lacks the ability to position the cursor.\n\
2485 If that is not the actual type of terminal you have,\n\
2486 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2487 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2488 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2490 # else /* TERMCAP */
2491 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2492 It lacks the ability to position the cursor.\n\
2493 If that is not the actual type of terminal you have,\n\
2494 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2495 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2496 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2498 # endif /* TERMINFO */
2500 if (FRAME_HEIGHT (sf
) <= 0
2501 || FRAME_WIDTH (sf
) <= 0)
2502 fatal ("The frame size has not been specified");
2504 delete_in_insert_mode
2505 = TS_delete_mode
&& TS_insert_mode
2506 && !strcmp (TS_delete_mode
, TS_insert_mode
);
2508 se_is_so
= (TS_standout_mode
2509 && TS_end_standout_mode
2510 && !strcmp (TS_standout_mode
, TS_end_standout_mode
));
2512 /* Remove width of standout marker from usable width of line */
2513 if (TN_standout_width
> 0)
2514 SET_FRAME_WIDTH (sf
, FRAME_WIDTH (sf
) - TN_standout_width
);
2516 UseTabs
= tabs_safe_p () && TabWidth
== 8;
2520 && (TS_set_window
|| TS_set_scroll_region
|| TS_set_scroll_region_1
));
2522 line_ins_del_ok
= (((TS_ins_line
|| TS_ins_multi_lines
)
2523 && (TS_del_line
|| TS_del_multi_lines
))
2524 || (scroll_region_ok
&& TS_fwd_scroll
&& TS_rev_scroll
));
2526 char_ins_del_ok
= ((TS_ins_char
|| TS_insert_mode
2527 || TS_pad_inserted_char
|| TS_ins_multi_chars
)
2528 && (TS_del_char
|| TS_del_multi_chars
));
2530 fast_clear_end_of_line
= TS_clr_line
!= 0;
2533 if (read_socket_hook
) /* Baudrate is somewhat */
2534 /* meaningless in this case */
2537 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
2538 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
2539 #endif /* WINDOWSNT */
2544 fatal (str
, arg1
, arg2
)
2545 char *str
, *arg1
, *arg2
;
2547 fprintf (stderr
, "emacs: ");
2548 fprintf (stderr
, str
, arg1
, arg2
);
2549 fprintf (stderr
, "\n");
2557 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
2558 "Non-nil means the system uses terminfo rather than termcap.\n\
2559 This variable can be used by terminal emulator packages.");
2561 system_uses_terminfo
= 1;
2563 system_uses_terminfo
= 0;
2566 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
2567 "Non-nil means call this function to ring the bell.\n\
2568 The function should accept no arguments.");
2569 Vring_bell_function
= Qnil
;
2571 defsubr (&Stty_display_color_p
);