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>. */
37 #include "termhooks.h"
38 #include "dispextern.h"
41 /* For now, don't try to include termcap.h. On some systems,
42 configure finds a non-standard termcap.h that the main build
45 #if defined HAVE_TERMCAP_H && 0
48 extern void tputs
P_ ((const char *, int, int (*)(int)));
49 extern int tgetent
P_ ((char *, const char *));
50 extern int tgetflag
P_ ((char *id
));
51 extern int tgetnum
P_ ((char *id
));
62 static void turn_on_face
P_ ((struct frame
*, int face_id
));
63 static void turn_off_face
P_ ((struct frame
*, int face_id
));
64 static void tty_show_cursor
P_ ((void));
65 static void tty_hide_cursor
P_ ((void));
67 #define max(a, b) ((a) > (b) ? (a) : (b))
68 #define min(a, b) ((a) < (b) ? (a) : (b))
71 tputs (a, (int) (FRAME_HEIGHT (XFRAME (selected_frame)) - curY), cmputc)
72 #define OUTPUT1(a) tputs (a, 1, cmputc)
73 #define OUTPUTL(a, lines) tputs (a, lines, cmputc)
75 #define OUTPUT_IF(a) \
78 tputs (a, (int) (FRAME_HEIGHT (XFRAME (selected_frame)) \
82 #define OUTPUT1_IF(a) do { if (a) tputs (a, 1, cmputc); } while (0)
84 /* Function to use to ring the bell. */
86 Lisp_Object Vring_bell_function
;
88 /* Terminal characteristics that higher levels want to look at.
89 These are all extern'd in termchar.h */
91 int must_write_spaces
; /* Nonzero means spaces in the text
92 must actually be output; can't just skip
93 over some columns to leave them blank. */
94 int min_padding_speed
; /* Speed below which no padding necessary */
96 int line_ins_del_ok
; /* Terminal can insert and delete lines */
97 int char_ins_del_ok
; /* Terminal can insert and delete chars */
98 int scroll_region_ok
; /* Terminal supports setting the
100 int scroll_region_cost
; /* Cost of setting a scroll window,
101 measured in characters */
102 int memory_below_frame
; /* Terminal remembers lines
103 scrolled off bottom */
104 int fast_clear_end_of_line
; /* Terminal has a `ce' string */
106 /* Nonzero means no need to redraw the entire frame on resuming
107 a suspended Emacs. This is useful on terminals with multiple pages,
108 where one page is used for Emacs and another for all else. */
110 int no_redraw_on_reenter
;
112 /* Hook functions that you can set to snap out the functions in this file.
113 These are all extern'd in termhooks.h */
115 void (*cursor_to_hook
) P_ ((int, int));
116 void (*raw_cursor_to_hook
) P_ ((int, int));
117 void (*clear_to_end_hook
) P_ ((void));
118 void (*clear_frame_hook
) P_ ((void));
119 void (*clear_end_of_line_hook
) P_ ((int));
121 void (*ins_del_lines_hook
) P_ ((int, int));
123 void (*change_line_highlight_hook
) P_ ((int, int, int, int));
124 void (*reassert_line_highlight_hook
) P_ ((int, int));
126 void (*delete_glyphs_hook
) P_ ((int));
128 void (*ring_bell_hook
) P_ ((void));
130 void (*reset_terminal_modes_hook
) P_ ((void));
131 void (*set_terminal_modes_hook
) P_ ((void));
132 void (*update_begin_hook
) P_ ((struct frame
*));
133 void (*update_end_hook
) P_ ((struct frame
*));
134 void (*set_terminal_window_hook
) P_ ((int));
135 void (*insert_glyphs_hook
) P_ ((struct glyph
*, int));
136 void (*write_glyphs_hook
) P_ ((struct glyph
*, int));
137 void (*delete_glyphs_hook
) P_ ((int));
139 int (*read_socket_hook
) P_ ((int, struct input_event
*, int, int));
141 void (*frame_up_to_date_hook
) P_ ((struct frame
*));
143 /* Return the current position of the mouse.
145 Set *f to the frame the mouse is in, or zero if the mouse is in no
146 Emacs frame. If it is set to zero, all the other arguments are
149 If the motion started in a scroll bar, set *bar_window to the
150 scroll bar's window, *part to the part the mouse is currently over,
151 *x to the position of the mouse along the scroll bar, and *y to the
152 overall length of the scroll bar.
154 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
155 row of the character cell the mouse is over.
157 Set *time to the time the mouse was at the returned position.
159 This should clear mouse_moved until the next motion
161 void (*mouse_position_hook
) P_ ((FRAME_PTR
*f
, int insist
,
162 Lisp_Object
*bar_window
,
163 enum scroll_bar_part
*part
,
166 unsigned long *time
));
168 /* When reading from a minibuffer in a different frame, Emacs wants
169 to shift the highlight from the selected frame to the mini-buffer's
170 frame; under X, this means it lies about where the focus is.
171 This hook tells the window system code to re-decide where to put
173 void (*frame_rehighlight_hook
) P_ ((FRAME_PTR f
));
175 /* If we're displaying frames using a window system that can stack
176 frames on top of each other, this hook allows you to bring a frame
177 to the front, or bury it behind all the other windows. If this
178 hook is zero, that means the device we're displaying on doesn't
179 support overlapping frames, so there's no need to raise or lower
182 If RAISE is non-zero, F is brought to the front, before all other
183 windows. If RAISE is zero, F is sent to the back, behind all other
185 void (*frame_raise_lower_hook
) P_ ((FRAME_PTR f
, int raise
));
187 /* Set the vertical scroll bar for WINDOW to have its upper left corner
188 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
189 indicate that we are displaying PORTION characters out of a total
190 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
191 have a scroll bar, create one for it. */
193 void (*set_vertical_scroll_bar_hook
)
194 P_ ((struct window
*window
,
195 int portion
, int whole
, int position
));
198 /* The following three hooks are used when we're doing a thorough
199 redisplay of the frame. We don't explicitly know which scroll bars
200 are going to be deleted, because keeping track of when windows go
201 away is a real pain - can you say set-window-configuration?
202 Instead, we just assert at the beginning of redisplay that *all*
203 scroll bars are to be removed, and then save scroll bars from the
204 fiery pit when we actually redisplay their window. */
206 /* Arrange for all scroll bars on FRAME to be removed at the next call
207 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
208 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
210 This should be applied to each frame each time its window tree is
211 redisplayed, even if it is not displaying scroll bars at the moment;
212 if the HAS_SCROLL_BARS flag has just been turned off, only calling
213 this and the judge_scroll_bars_hook will get rid of them.
215 If non-zero, this hook should be safe to apply to any frame,
216 whether or not it can support scroll bars, and whether or not it is
217 currently displaying them. */
218 void (*condemn_scroll_bars_hook
) P_ ((FRAME_PTR frame
));
220 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
221 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. */
235 void (*judge_scroll_bars_hook
) P_ ((FRAME_PTR FRAME
));
237 /* Hook to call in estimate_mode_line_height, if any. */
239 int (* estimate_mode_line_height_hook
) P_ ((struct frame
*f
, enum face_id
));
242 /* Strings, numbers and flags taken from the termcap entry. */
244 char *TS_ins_line
; /* "al" */
245 char *TS_ins_multi_lines
; /* "AL" (one parameter, # lines to insert) */
246 char *TS_bell
; /* "bl" */
247 char *TS_clr_to_bottom
; /* "cd" */
248 char *TS_clr_line
; /* "ce", clear to end of line */
249 char *TS_clr_frame
; /* "cl" */
250 char *TS_set_scroll_region
; /* "cs" (2 params, first line and last line) */
251 char *TS_set_scroll_region_1
; /* "cS" (4 params: total lines,
252 lines above scroll region, lines below it,
253 total lines again) */
254 char *TS_del_char
; /* "dc" */
255 char *TS_del_multi_chars
; /* "DC" (one parameter, # chars to delete) */
256 char *TS_del_line
; /* "dl" */
257 char *TS_del_multi_lines
; /* "DL" (one parameter, # lines to delete) */
258 char *TS_delete_mode
; /* "dm", enter character-delete mode */
259 char *TS_end_delete_mode
; /* "ed", leave character-delete mode */
260 char *TS_end_insert_mode
; /* "ei", leave character-insert mode */
261 char *TS_ins_char
; /* "ic" */
262 char *TS_ins_multi_chars
; /* "IC" (one parameter, # chars to insert) */
263 char *TS_insert_mode
; /* "im", enter character-insert mode */
264 char *TS_pad_inserted_char
; /* "ip". Just padding, no commands. */
265 char *TS_end_keypad_mode
; /* "ke" */
266 char *TS_keypad_mode
; /* "ks" */
267 char *TS_pad_char
; /* "pc", char to use as padding */
268 char *TS_repeat
; /* "rp" (2 params, # times to repeat
269 and character to be repeated) */
270 char *TS_end_standout_mode
; /* "se" */
271 char *TS_fwd_scroll
; /* "sf" */
272 char *TS_standout_mode
; /* "so" */
273 char *TS_rev_scroll
; /* "sr" */
274 char *TS_end_termcap_modes
; /* "te" */
275 char *TS_termcap_modes
; /* "ti" */
276 char *TS_visible_bell
; /* "vb" */
277 char *TS_cursor_normal
; /* "ve" */
278 char *TS_cursor_visible
; /* "vs" */
279 char *TS_cursor_invisible
; /* "vi" */
280 char *TS_set_window
; /* "wi" (4 params, start and end of window,
281 each as vpos and hpos) */
283 /* Value of the "NC" (no_color_video) capability, or 0 if not
286 static int TN_no_color_video
;
288 /* Meaning of bits in no_color_video. Each bit set means that the
289 corresponding attribute cannot be combined with colors. */
293 NC_STANDOUT
= 1 << 0,
294 NC_UNDERLINE
= 1 << 1,
301 NC_ALT_CHARSET
= 1 << 8
304 /* "md" -- turn on bold (extra bright mode). */
306 char *TS_enter_bold_mode
;
308 /* "mh" -- turn on half-bright mode. */
310 char *TS_enter_dim_mode
;
312 /* "mb" -- enter blinking mode. */
314 char *TS_enter_blink_mode
;
316 /* "mr" -- enter reverse video mode. */
318 char *TS_enter_reverse_mode
;
320 /* "us"/"ue" -- start/end underlining. */
322 char *TS_exit_underline_mode
, *TS_enter_underline_mode
;
324 /* "ug" -- number of blanks left by underline. */
326 int TN_magic_cookie_glitch_ul
;
328 /* "as"/"ae" -- start/end alternate character set. Not really
331 char *TS_enter_alt_charset_mode
, *TS_exit_alt_charset_mode
;
333 /* "me" -- switch appearances off. */
335 char *TS_exit_attribute_mode
;
337 /* "Co" -- number of colors. */
341 /* "pa" -- max. number of color pairs on screen. Not handled yet.
342 Could be a problem if not equal to TN_max_colors * TN_max_colors. */
346 /* "op" -- SVr4 set default pair to its original value. */
350 /* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
351 1 param, the color index. */
353 char *TS_set_foreground
, *TS_set_background
;
355 int TF_hazeltine
; /* termcap hz flag. */
356 int TF_insmode_motion
; /* termcap mi flag: can move while in insert mode. */
357 int TF_standout_motion
; /* termcap mi flag: can move while in standout mode. */
358 int TF_underscore
; /* termcap ul flag: _ underlines if over-struck on
359 non-blank position. Must clear before writing _. */
360 int TF_teleray
; /* termcap xt flag: many weird consequences.
363 int TF_xs
; /* Nonzero for "xs". If set together with
364 TN_standout_width == 0, it means don't bother
365 to write any end-standout cookies. */
367 int TN_standout_width
; /* termcap sg number: width occupied by standout
370 static int RPov
; /* # chars to start a TS_repeat */
372 static int delete_in_insert_mode
; /* delete mode == insert mode */
374 static int se_is_so
; /* 1 if same string both enters and leaves
379 /* The largest frame width in any call to calculate_costs. */
383 /* The largest frame height in any call to calculate_costs. */
385 int max_frame_height
;
387 /* Number of chars of space used for standout marker at beginning of line,
388 or'd with 0100. Zero if no standout marker at all.
389 The length of these vectors is max_frame_height.
391 Used IFF TN_standout_width >= 0. */
393 static char *chars_wasted
;
394 static char *copybuf
;
396 /* nonzero means supposed to write text in standout mode. */
398 int standout_requested
;
400 int insert_mode
; /* Nonzero when in insert mode. */
401 int standout_mode
; /* Nonzero when in standout mode. */
403 /* Size of window specified by higher levels.
404 This is the number of lines, from the top of frame downwards,
405 which can participate in insert-line/delete-line operations.
407 Effectively it excludes the bottom frame_height - specified_window_size
408 lines from those operations. */
410 int specified_window
;
412 /* Frame currently being redisplayed; 0 if not currently redisplaying.
413 (Direct output does not count). */
415 FRAME_PTR updating_frame
;
417 /* Provided for lisp packages. */
419 static int system_uses_terminfo
;
423 extern char *tgetstr ();
429 if (! NILP (Vring_bell_function
))
431 Lisp_Object function
;
433 /* Temporarily set the global variable to nil
434 so that if we get an error, it stays nil
435 and we don't call it over and over.
437 We don't specbind it, because that would carefully
438 restore the bad value if there's an error
439 and make the loop of errors happen anyway. */
440 function
= Vring_bell_function
;
441 Vring_bell_function
= Qnil
;
445 Vring_bell_function
= function
;
449 if (! FRAME_TERMCAP_P (XFRAME (selected_frame
)))
451 (*ring_bell_hook
) ();
454 OUTPUT (TS_visible_bell
&& visible_bell
? TS_visible_bell
: TS_bell
);
458 set_terminal_modes ()
460 if (! FRAME_TERMCAP_P (XFRAME (selected_frame
)))
462 (*set_terminal_modes_hook
) ();
465 OUTPUT_IF (TS_termcap_modes
);
466 OUTPUT_IF (TS_cursor_visible
);
467 OUTPUT_IF (TS_keypad_mode
);
472 reset_terminal_modes ()
474 if (! FRAME_TERMCAP_P (XFRAME (selected_frame
)))
476 if (reset_terminal_modes_hook
)
477 (*reset_terminal_modes_hook
) ();
480 if (TN_standout_width
< 0)
481 turn_off_highlight ();
483 OUTPUT_IF (TS_end_keypad_mode
);
484 OUTPUT_IF (TS_cursor_normal
);
485 OUTPUT_IF (TS_end_termcap_modes
);
486 OUTPUT_IF (TS_orig_pair
);
487 /* Output raw CR so kernel can track the cursor hpos. */
488 /* But on magic-cookie terminals this can erase an end-standout marker and
489 cause the rest of the frame to be in standout, so move down first. */
490 if (TN_standout_width
>= 0)
500 if (! FRAME_TERMCAP_P (updating_frame
))
501 (*update_begin_hook
) (f
);
510 if (! FRAME_TERMCAP_P (updating_frame
))
512 (*update_end_hook
) (f
);
517 if (!XWINDOW (selected_window
)->cursor_off_p
)
521 background_highlight ();
522 standout_requested
= 0;
527 set_terminal_window (size
)
530 if (! FRAME_TERMCAP_P (updating_frame
))
532 (*set_terminal_window_hook
) (size
);
535 specified_window
= size
? size
: FRAME_HEIGHT (XFRAME (selected_frame
));
536 if (!scroll_region_ok
)
538 set_scroll_region (0, specified_window
);
542 set_scroll_region (start
, stop
)
546 struct frame
*sf
= XFRAME (selected_frame
);
548 if (TS_set_scroll_region
)
550 buf
= tparam (TS_set_scroll_region
, 0, 0, start
, stop
- 1);
552 else if (TS_set_scroll_region_1
)
554 buf
= tparam (TS_set_scroll_region_1
, 0, 0,
555 FRAME_HEIGHT (sf
), start
,
556 FRAME_HEIGHT (sf
) - stop
,
561 buf
= tparam (TS_set_window
, 0, 0, start
, 0, stop
, FRAME_WIDTH (sf
));
572 OUTPUT (TS_insert_mode
);
580 OUTPUT (TS_end_insert_mode
);
584 /* Handle highlighting when TN_standout_width (termcap sg) is not specified.
585 In these terminals, output is affected by the value of standout
586 mode when the output is written.
588 These functions are called on all terminals, but do nothing
589 on terminals whose standout mode does not work that way. */
592 turn_off_highlight ()
594 if (TN_standout_width
< 0)
597 OUTPUT_IF (TS_end_standout_mode
);
605 if (TN_standout_width
< 0)
608 OUTPUT_IF (TS_standout_mode
);
614 /* Make cursor invisible. */
619 OUTPUT_IF (TS_cursor_invisible
);
623 /* Ensure that cursor is visible. */
628 OUTPUT_IF (TS_cursor_normal
);
629 OUTPUT_IF (TS_cursor_visible
);
633 /* Set standout mode to the state it should be in for
634 empty space inside windows. What this is,
635 depends on the user option inverse-video. */
638 background_highlight ()
640 if (TN_standout_width
>= 0)
643 turn_on_highlight ();
645 turn_off_highlight ();
648 /* Set standout mode to the mode specified for the text to be output. */
651 highlight_if_desired ()
653 if (TN_standout_width
>= 0)
655 if (!inverse_video
== !standout_requested
)
656 turn_off_highlight ();
658 turn_on_highlight ();
661 /* Handle standout mode for terminals in which TN_standout_width >= 0.
662 On these terminals, standout is controlled by markers that
663 live inside the terminal's memory. TN_standout_width is the width
664 that the marker occupies in memory. Standout runs from the marker
665 to the end of the line on some terminals, or to the next
666 turn-off-standout marker (TS_end_standout_mode) string
667 on other terminals. */
669 /* Write a standout marker or end-standout marker at the front of the line
670 at vertical position vpos. */
673 write_standout_marker (flag
, vpos
)
676 if (flag
|| (TS_end_standout_mode
&& !TF_teleray
&& !se_is_so
677 && !(TF_xs
&& TN_standout_width
== 0)))
680 cmplus (TN_standout_width
);
681 OUTPUT (flag
? TS_standout_mode
: TS_end_standout_mode
);
682 chars_wasted
[curY
] = TN_standout_width
| 0100;
686 /* External interface to control of standout mode.
687 Call this when about to modify line at position VPOS
688 and not change whether it is highlighted. */
691 reassert_line_highlight (highlight
, vpos
)
695 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
696 if (! FRAME_TERMCAP_P (f
))
698 (*reassert_line_highlight_hook
) (highlight
, vpos
);
701 if (TN_standout_width
< 0)
702 /* Handle terminals where standout takes affect at output time */
703 standout_requested
= highlight
;
704 else if (chars_wasted
&& chars_wasted
[vpos
] == 0)
705 /* For terminals with standout markers, write one on this line
706 if there isn't one already. */
707 write_standout_marker (inverse_video
? !highlight
: highlight
, vpos
);
710 /* Call this when about to modify line at position VPOS
711 and change whether it is highlighted. */
714 change_line_highlight (new_highlight
, vpos
, y
, first_unused_hpos
)
715 int new_highlight
, vpos
, y
, first_unused_hpos
;
717 standout_requested
= new_highlight
;
718 if (! FRAME_TERMCAP_P (updating_frame
))
720 (*change_line_highlight_hook
) (new_highlight
, vpos
, y
, first_unused_hpos
);
726 if (TN_standout_width
< 0)
727 background_highlight ();
728 /* If line starts with a marker, delete the marker */
729 else if (TS_clr_line
&& chars_wasted
[curY
])
732 /* On Teleray, make sure to erase the SO marker. */
735 cmgoto (curY
- 1, FRAME_WIDTH (XFRAME (selected_frame
)) - 4);
737 curY
++; /* ESC S moves to next line where the TS_standout_mode was */
741 cmgoto (curY
, 0); /* reposition to kill standout marker */
743 clear_end_of_line_raw (first_unused_hpos
);
744 reassert_line_highlight (new_highlight
, curY
);
748 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
749 frame-relative coordinates. */
752 cursor_to (vpos
, hpos
)
755 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
757 if (! FRAME_TERMCAP_P (f
) && cursor_to_hook
)
759 (*cursor_to_hook
) (vpos
, hpos
);
763 /* Detect the case where we are called from reset_sys_modes
764 and the costs have never been calculated. Do nothing. */
765 if (chars_wasted
== 0)
768 hpos
+= chars_wasted
[vpos
] & 077;
769 if (curY
== vpos
&& curX
== hpos
)
771 if (!TF_standout_motion
)
772 background_highlight ();
773 if (!TF_insmode_motion
)
778 /* Similar but don't take any account of the wasted characters. */
781 raw_cursor_to (row
, col
)
784 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
785 if (! FRAME_TERMCAP_P (f
))
787 (*raw_cursor_to_hook
) (row
, col
);
790 if (curY
== row
&& curX
== col
)
792 if (!TF_standout_motion
)
793 background_highlight ();
794 if (!TF_insmode_motion
)
799 /* Erase operations */
801 /* clear from cursor to end of frame */
807 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
809 (*clear_to_end_hook
) ();
812 if (TS_clr_to_bottom
)
814 background_highlight ();
815 OUTPUT (TS_clr_to_bottom
);
816 bzero (chars_wasted
+ curY
,
817 FRAME_HEIGHT (XFRAME (selected_frame
)) - curY
);
821 for (i
= curY
; i
< FRAME_HEIGHT (XFRAME (selected_frame
)); i
++)
824 clear_end_of_line_raw (FRAME_WIDTH (XFRAME (selected_frame
)));
829 /* Clear entire frame */
834 struct frame
*sf
= XFRAME (selected_frame
);
837 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: sf
)))
839 (*clear_frame_hook
) ();
844 background_highlight ();
845 OUTPUT (TS_clr_frame
);
846 bzero (chars_wasted
, FRAME_HEIGHT (sf
));
856 /* Clear to end of line, but do not clear any standout marker.
857 Assumes that the cursor is positioned at a character of real text,
858 which implies it cannot be before a standout marker
859 unless the marker has zero width.
861 Note that the cursor may be moved. */
864 clear_end_of_line (first_unused_hpos
)
865 int first_unused_hpos
;
867 if (FRAME_TERMCAP_P (XFRAME (selected_frame
))
869 && TN_standout_width
== 0 && curX
== 0 && chars_wasted
[curY
] != 0)
870 write_glyphs (&space_glyph
, 1);
871 clear_end_of_line_raw (first_unused_hpos
);
874 /* Clear from cursor to end of line.
875 Assume that the line is already clear starting at column first_unused_hpos.
876 If the cursor is at a standout marker, erase the marker.
878 Note that the cursor may be moved, on terminals lacking a `ce' string. */
881 clear_end_of_line_raw (first_unused_hpos
)
882 int first_unused_hpos
;
886 if (clear_end_of_line_hook
887 && ! FRAME_TERMCAP_P ((updating_frame
889 : XFRAME (selected_frame
))))
891 (*clear_end_of_line_hook
) (first_unused_hpos
);
895 /* Detect the case where we are called from reset_sys_modes
896 and the costs have never been calculated. Do nothing. */
897 if (chars_wasted
== 0)
900 first_unused_hpos
+= chars_wasted
[curY
] & 077;
901 if (curX
>= first_unused_hpos
)
903 /* Notice if we are erasing a magic cookie */
905 chars_wasted
[curY
] = 0;
906 background_highlight ();
909 OUTPUT1 (TS_clr_line
);
912 { /* have to do it the hard way */
913 struct frame
*sf
= XFRAME (selected_frame
);
916 /* Do not write in last row last col with Auto-wrap on. */
917 if (AutoWrap
&& curY
== FRAME_HEIGHT (sf
) - 1
918 && first_unused_hpos
== FRAME_WIDTH (sf
))
921 for (i
= curX
; i
< first_unused_hpos
; i
++)
924 fputc (' ', termscript
);
927 cmplus (first_unused_hpos
- curX
);
931 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
932 store them at DST. Do not write more than DST_LEN bytes. That may
933 require stopping before all SRC_LEN input glyphs have been
936 We store the number of glyphs actually converted in *CONSUMED. The
937 return value is the number of bytes store in DST. */
940 encode_terminal_code (src
, dst
, src_len
, dst_len
, consumed
)
944 int dst_len
, *consumed
;
946 struct glyph
*src_start
= src
, *src_end
= src
+ src_len
;
947 unsigned char *dst_start
= dst
, *dst_end
= dst
+ dst_len
;
949 unsigned char workbuf
[MAX_MULTIBYTE_LENGTH
], *buf
;
951 register int tlen
= GLYPH_TABLE_LENGTH
;
952 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
954 struct coding_system
*coding
;
956 /* If terminal_coding does any conversion, use it, otherwise use
957 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
958 because it always return 1 if the member src_multibyte is 1. */
959 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
961 : &safe_terminal_coding
);
963 while (src
< src_end
)
965 /* We must skip glyphs to be padded for a wide character. */
966 if (! CHAR_GLYPH_PADDING_P (*src
))
968 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
970 if (g
< 0 || g
>= tlen
)
972 /* This glyph doesn't has an entry in Vglyph_table. */
973 if (! CHAR_VALID_P (src
->u
.ch
, 0))
977 coding
->src_multibyte
= 0;
981 len
= CHAR_STRING (src
->u
.ch
, workbuf
);
983 coding
->src_multibyte
= 1;
988 /* This glyph has an entry in Vglyph_table,
989 so process any alias before testing for simpleness. */
990 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
992 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
994 /* We set the multi-byte form of a character in G
995 (that should be an ASCII character) at
997 workbuf
[0] = FAST_GLYPH_CHAR (g
);
1000 coding
->src_multibyte
= 0;
1004 /* We have a string in Vglyph_table. */
1005 len
= GLYPH_LENGTH (tbase
, g
);
1006 buf
= GLYPH_STRING (tbase
, g
);
1007 coding
->src_multibyte
= STRING_MULTIBYTE (tbase
[g
]);
1011 result
= encode_coding (coding
, buf
, dst
, len
, dst_end
- dst
);
1012 len
-= coding
->consumed
;
1013 dst
+= coding
->produced
;
1014 if (result
== CODING_FINISH_INSUFFICIENT_DST
1015 || (result
== CODING_FINISH_INSUFFICIENT_SRC
1016 && len
> dst_end
- dst
))
1017 /* The remaining output buffer is too short. We must
1018 break the loop here without increasing SRC so that the
1019 next call of this function starts from the same glyph. */
1024 /* This is the case that a code of the range 0200..0237
1025 exists in buf. We must just write out such a code. */
1026 buf
+= coding
->consumed
;
1034 *consumed
= src
- src_start
;
1035 return (dst
- dst_start
);
1040 write_glyphs (string
, len
)
1041 register struct glyph
*string
;
1044 int produced
, consumed
;
1045 struct frame
*sf
= XFRAME (selected_frame
);
1046 struct frame
*f
= updating_frame
? updating_frame
: sf
;
1047 unsigned char conversion_buffer
[1024];
1048 int conversion_buffer_size
= sizeof conversion_buffer
;
1050 if (write_glyphs_hook
1051 && ! FRAME_TERMCAP_P (f
))
1053 (*write_glyphs_hook
) (string
, len
);
1059 /* Don't dare write in last column of bottom line, if Auto-Wrap,
1060 since that would scroll the whole frame on some terminals. */
1063 && curY
+ 1 == FRAME_HEIGHT (sf
)
1064 && (curX
+ len
- (chars_wasted
[curY
] & 077) == FRAME_WIDTH (sf
)))
1071 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1073 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
1077 /* Identify a run of glyphs with the same face. */
1078 int face_id
= string
->face_id
;
1081 for (n
= 1; n
< len
; ++n
)
1082 if (string
[n
].face_id
!= face_id
)
1085 /* Turn appearance modes of the face of the run on. */
1086 highlight_if_desired ();
1087 turn_on_face (f
, face_id
);
1091 /* We use a fixed size (1024 bytes) of conversion buffer.
1092 Usually it is sufficient, but if not, we just repeat the
1094 produced
= encode_terminal_code (string
, conversion_buffer
,
1095 n
, conversion_buffer_size
,
1099 fwrite (conversion_buffer
, 1, produced
, stdout
);
1100 if (ferror (stdout
))
1103 fwrite (conversion_buffer
, 1, produced
, termscript
);
1110 /* Turn appearance modes off. */
1111 turn_off_face (f
, face_id
);
1112 turn_off_highlight ();
1115 /* We may have to output some codes to terminate the writing. */
1116 if (CODING_REQUIRE_FLUSHING (&terminal_coding
))
1118 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
1119 encode_coding (&terminal_coding
, "", conversion_buffer
,
1120 0, conversion_buffer_size
);
1121 if (terminal_coding
.produced
> 0)
1123 fwrite (conversion_buffer
, 1, terminal_coding
.produced
, stdout
);
1124 if (ferror (stdout
))
1127 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
1135 /* If start is zero, insert blanks instead of a string at start */
1138 insert_glyphs (start
, len
)
1139 register struct glyph
*start
;
1143 struct glyph
*glyph
= NULL
;
1144 struct frame
*f
, *sf
;
1149 if (insert_glyphs_hook
)
1151 (*insert_glyphs_hook
) (start
, len
);
1155 sf
= XFRAME (selected_frame
);
1156 f
= updating_frame
? updating_frame
: sf
;
1158 if (TS_ins_multi_chars
)
1160 buf
= tparam (TS_ins_multi_chars
, 0, 0, len
);
1164 write_glyphs (start
, len
);
1170 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
1171 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
1174 int produced
, consumed
;
1175 unsigned char conversion_buffer
[1024];
1176 int conversion_buffer_size
= sizeof conversion_buffer
;
1178 OUTPUT1_IF (TS_ins_char
);
1181 conversion_buffer
[0] = SPACEGLYPH
;
1186 highlight_if_desired ();
1187 turn_on_face (f
, start
->face_id
);
1190 /* We must open sufficient space for a character which
1191 occupies more than one column. */
1192 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
1194 OUTPUT1_IF (TS_ins_char
);
1199 /* This is the last glyph. */
1200 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
1202 /* The size of conversion buffer (1024 bytes) is surely
1203 sufficient for just one glyph. */
1204 produced
= encode_terminal_code (glyph
, conversion_buffer
, 1,
1205 conversion_buffer_size
, &consumed
);
1210 fwrite (conversion_buffer
, 1, produced
, stdout
);
1211 if (ferror (stdout
))
1214 fwrite (conversion_buffer
, 1, produced
, termscript
);
1217 OUTPUT1_IF (TS_pad_inserted_char
);
1220 turn_off_face (f
, glyph
->face_id
);
1221 turn_off_highlight ();
1235 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1237 (*delete_glyphs_hook
) (n
);
1241 if (delete_in_insert_mode
)
1248 OUTPUT_IF (TS_delete_mode
);
1251 if (TS_del_multi_chars
)
1253 buf
= tparam (TS_del_multi_chars
, 0, 0, n
);
1258 for (i
= 0; i
< n
; i
++)
1259 OUTPUT1 (TS_del_char
);
1260 if (!delete_in_insert_mode
)
1261 OUTPUT_IF (TS_end_delete_mode
);
1264 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1267 ins_del_lines (vpos
, n
)
1270 char *multi
= n
> 0 ? TS_ins_multi_lines
: TS_del_multi_lines
;
1271 char *single
= n
> 0 ? TS_ins_line
: TS_del_line
;
1272 char *scroll
= n
> 0 ? TS_rev_scroll
: TS_fwd_scroll
;
1275 register int i
= n
> 0 ? n
: -n
;
1278 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1280 (*ins_del_lines_hook
) (vpos
, n
);
1284 sf
= XFRAME (selected_frame
);
1286 /* If the lines below the insertion are being pushed
1287 into the end of the window, this is the same as clearing;
1288 and we know the lines are already clear, since the matching
1289 deletion has already been done. So can ignore this. */
1290 /* If the lines below the deletion are blank lines coming
1291 out of the end of the window, don't bother,
1292 as there will be a matching inslines later that will flush them. */
1293 if (scroll_region_ok
&& vpos
+ i
>= specified_window
)
1295 if (!memory_below_frame
&& vpos
+ i
>= FRAME_HEIGHT (sf
))
1300 raw_cursor_to (vpos
, 0);
1301 background_highlight ();
1302 buf
= tparam (multi
, 0, 0, i
);
1308 raw_cursor_to (vpos
, 0);
1309 background_highlight ();
1317 set_scroll_region (vpos
, specified_window
);
1319 raw_cursor_to (specified_window
- 1, 0);
1321 raw_cursor_to (vpos
, 0);
1322 background_highlight ();
1324 OUTPUTL (scroll
, specified_window
- vpos
);
1325 set_scroll_region (0, specified_window
);
1328 if (TN_standout_width
>= 0)
1330 register int lower_limit
1333 : FRAME_HEIGHT (sf
));
1337 bcopy (&chars_wasted
[vpos
- n
], &chars_wasted
[vpos
],
1338 lower_limit
- vpos
+ n
);
1339 bzero (&chars_wasted
[lower_limit
+ n
], - n
);
1343 bcopy (&chars_wasted
[vpos
], ©buf
[vpos
], lower_limit
- vpos
- n
);
1344 bcopy (©buf
[vpos
], &chars_wasted
[vpos
+ n
],
1345 lower_limit
- vpos
- n
);
1346 bzero (&chars_wasted
[vpos
], n
);
1349 if (!scroll_region_ok
&& memory_below_frame
&& n
< 0)
1351 cursor_to (FRAME_HEIGHT (sf
) + n
, 0);
1356 /* Compute cost of sending "str", in characters,
1357 not counting any line-dependent padding. */
1365 tputs (str
, 0, evalcost
);
1369 /* Compute cost of sending "str", in characters,
1370 counting any line-dependent padding at one line. */
1373 string_cost_one_line (str
)
1378 tputs (str
, 1, evalcost
);
1382 /* Compute per line amount of line-dependent padding,
1383 in tenths of characters. */
1391 tputs (str
, 0, evalcost
);
1394 tputs (str
, 10, evalcost
);
1399 /* char_ins_del_cost[n] is cost of inserting N characters.
1400 char_ins_del_cost[-n] is cost of deleting N characters.
1401 The length of this vector is based on max_frame_width. */
1403 int *char_ins_del_vector
;
1405 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH ((f))])
1410 calculate_ins_del_char_costs (frame
)
1413 int ins_startup_cost
, del_startup_cost
;
1414 int ins_cost_per_char
, del_cost_per_char
;
1418 if (TS_ins_multi_chars
)
1420 ins_cost_per_char
= 0;
1421 ins_startup_cost
= string_cost_one_line (TS_ins_multi_chars
);
1423 else if (TS_ins_char
|| TS_pad_inserted_char
1424 || (TS_insert_mode
&& TS_end_insert_mode
))
1426 ins_startup_cost
= (30 * (string_cost (TS_insert_mode
)
1427 + string_cost (TS_end_insert_mode
))) / 100;
1428 ins_cost_per_char
= (string_cost_one_line (TS_ins_char
)
1429 + string_cost_one_line (TS_pad_inserted_char
));
1433 ins_startup_cost
= 9999;
1434 ins_cost_per_char
= 0;
1437 if (TS_del_multi_chars
)
1439 del_cost_per_char
= 0;
1440 del_startup_cost
= string_cost_one_line (TS_del_multi_chars
);
1442 else if (TS_del_char
)
1444 del_startup_cost
= (string_cost (TS_delete_mode
)
1445 + string_cost (TS_end_delete_mode
));
1446 if (delete_in_insert_mode
)
1447 del_startup_cost
/= 2;
1448 del_cost_per_char
= string_cost_one_line (TS_del_char
);
1452 del_startup_cost
= 9999;
1453 del_cost_per_char
= 0;
1456 /* Delete costs are at negative offsets */
1457 p
= &char_ins_del_cost (frame
)[0];
1458 for (i
= FRAME_WIDTH (frame
); --i
>= 0;)
1459 *--p
= (del_startup_cost
+= del_cost_per_char
);
1461 /* Doing nothing is free */
1462 p
= &char_ins_del_cost (frame
)[0];
1465 /* Insert costs are at positive offsets */
1466 for (i
= FRAME_WIDTH (frame
); --i
>= 0;)
1467 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1471 calculate_costs (frame
)
1474 register char *f
= (TS_set_scroll_region
1475 ? TS_set_scroll_region
1476 : TS_set_scroll_region_1
);
1478 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1480 scroll_region_cost
= string_cost (f
);
1482 /* These variables are only used for terminal stuff. They are allocated
1483 once for the terminal frame of X-windows emacs, but not used afterwards.
1485 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1486 X turns off char_ins_del_ok.
1488 chars_wasted and copybuf are only used here in term.c in cases where
1489 the term hook isn't called. */
1491 max_frame_height
= max (max_frame_height
, FRAME_HEIGHT (frame
));
1492 max_frame_width
= max (max_frame_width
, FRAME_WIDTH (frame
));
1494 if (chars_wasted
!= 0)
1495 chars_wasted
= (char *) xrealloc (chars_wasted
, max_frame_height
);
1497 chars_wasted
= (char *) xmalloc (max_frame_height
);
1500 copybuf
= (char *) xrealloc (copybuf
, max_frame_height
);
1502 copybuf
= (char *) xmalloc (max_frame_height
);
1504 if (char_ins_del_vector
!= 0)
1506 = (int *) xrealloc (char_ins_del_vector
,
1508 + 2 * max_frame_width
* sizeof (int)));
1511 = (int *) xmalloc (sizeof (int)
1512 + 2 * max_frame_width
* sizeof (int));
1514 bzero (chars_wasted
, max_frame_height
);
1515 bzero (copybuf
, max_frame_height
);
1516 bzero (char_ins_del_vector
, (sizeof (int)
1517 + 2 * max_frame_width
* sizeof (int)));
1519 if (f
&& (!TS_ins_line
&& !TS_del_line
))
1520 do_line_insertion_deletion_costs (frame
,
1521 TS_rev_scroll
, TS_ins_multi_lines
,
1522 TS_fwd_scroll
, TS_del_multi_lines
,
1525 do_line_insertion_deletion_costs (frame
,
1526 TS_ins_line
, TS_ins_multi_lines
,
1527 TS_del_line
, TS_del_multi_lines
,
1530 calculate_ins_del_char_costs (frame
);
1532 /* Don't use TS_repeat if its padding is worse than sending the chars */
1533 if (TS_repeat
&& per_line_cost (TS_repeat
) * baud_rate
< 9000)
1534 RPov
= string_cost (TS_repeat
);
1536 RPov
= FRAME_WIDTH (frame
) * 2;
1538 cmcostinit (); /* set up cursor motion costs */
1545 /* Termcap capability names that correspond directly to X keysyms.
1546 Some of these (marked "terminfo") aren't supplied by old-style
1547 (Berkeley) termcap entries. They're listed in X keysym order;
1548 except we put the keypad keys first, so that if they clash with
1549 other keys (as on the IBM PC keyboard) they get overridden.
1552 static struct fkey_table keys
[] =
1554 "kh", "home", /* termcap */
1555 "kl", "left", /* termcap */
1556 "ku", "up", /* termcap */
1557 "kr", "right", /* termcap */
1558 "kd", "down", /* termcap */
1559 "%8", "prior", /* terminfo */
1560 "%5", "next", /* terminfo */
1561 "@7", "end", /* terminfo */
1562 "@1", "begin", /* terminfo */
1563 "*6", "select", /* terminfo */
1564 "%9", "print", /* terminfo */
1565 "@4", "execute", /* terminfo --- actually the `command' key */
1567 * "insert" --- see below
1569 "&8", "undo", /* terminfo */
1570 "%0", "redo", /* terminfo */
1571 "%7", "menu", /* terminfo --- actually the `options' key */
1572 "@0", "find", /* terminfo */
1573 "@2", "cancel", /* terminfo */
1574 "%1", "help", /* terminfo */
1576 * "break" goes here, but can't be reliably intercepted with termcap
1578 "&4", "reset", /* terminfo --- actually `restart' */
1580 * "system" and "user" --- no termcaps
1582 "kE", "clearline", /* terminfo */
1583 "kA", "insertline", /* terminfo */
1584 "kL", "deleteline", /* terminfo */
1585 "kI", "insertchar", /* terminfo */
1586 "kD", "deletechar", /* terminfo */
1587 "kB", "backtab", /* terminfo */
1589 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1591 "@8", "kp-enter", /* terminfo */
1593 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1594 * "kp-multiply", "kp-add", "kp-separator",
1595 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1596 * --- no termcaps for any of these.
1598 "K4", "kp-1", /* terminfo */
1600 * "kp-2" --- no termcap
1602 "K5", "kp-3", /* terminfo */
1604 * "kp-4" --- no termcap
1606 "K2", "kp-5", /* terminfo */
1608 * "kp-6" --- no termcap
1610 "K1", "kp-7", /* terminfo */
1612 * "kp-8" --- no termcap
1614 "K3", "kp-9", /* terminfo */
1616 * "kp-equal" --- no termcap
1629 static char **term_get_fkeys_arg
;
1630 static Lisp_Object
term_get_fkeys_1 ();
1632 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1633 This function scans the termcap function key sequence entries, and
1634 adds entries to Vfunction_key_map for each function key it finds. */
1637 term_get_fkeys (address
)
1640 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1641 errors during the call. The only errors should be from Fdefine_key
1642 when given a key sequence containing an invalid prefix key. If the
1643 termcap defines function keys which use a prefix that is already bound
1644 to a command by the default bindings, we should silently ignore that
1645 function key specification, rather than giving the user an error and
1646 refusing to run at all on such a terminal. */
1648 extern Lisp_Object
Fidentity ();
1649 term_get_fkeys_arg
= address
;
1650 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1658 char **address
= term_get_fkeys_arg
;
1660 /* This can happen if CANNOT_DUMP or with strange options. */
1662 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1664 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1666 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1668 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1669 Fmake_vector (make_number (1),
1670 intern (keys
[i
].name
)));
1673 /* The uses of the "k0" capability are inconsistent; sometimes it
1674 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1675 We will attempt to politely accommodate both systems by testing for
1676 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1679 char *k_semi
= tgetstr ("k;", address
);
1680 char *k0
= tgetstr ("k0", address
);
1681 char *k0_name
= "f10";
1685 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1686 Fmake_vector (make_number (1), intern ("f10")));
1691 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1692 Fmake_vector (make_number (1), intern (k0_name
)));
1695 /* Set up cookies for numbered function keys above f10. */
1697 char fcap
[3], fkey
[4];
1699 fcap
[0] = 'F'; fcap
[2] = '\0';
1700 for (i
= 11; i
< 64; i
++)
1703 fcap
[1] = '1' + i
- 11;
1705 fcap
[1] = 'A' + i
- 20;
1707 fcap
[1] = 'a' + i
- 46;
1710 char *sequence
= tgetstr (fcap
, address
);
1713 sprintf (fkey
, "f%d", i
);
1714 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1715 Fmake_vector (make_number (1),
1723 * Various mappings to try and get a better fit.
1726 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1727 if (!tgetstr (cap1, address)) \
1729 char *sequence = tgetstr (cap2, address); \
1731 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1732 Fmake_vector (make_number (1), \
1736 /* if there's no key_next keycap, map key_npage to `next' keysym */
1737 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1738 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1739 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1740 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1741 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1742 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1743 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1745 /* IBM has their own non-standard dialect of terminfo.
1746 If the standard name isn't found, try the IBM name. */
1747 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1748 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1749 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1750 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1751 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1752 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1753 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1754 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1755 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1756 #undef CONDITIONAL_REASSIGN
1763 /***********************************************************************
1764 Character Display Information
1765 ***********************************************************************/
1767 static void append_glyph
P_ ((struct it
*));
1770 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1771 terminal frames if IT->glyph_row != NULL. IT->c is the character
1772 for which to produce glyphs; IT->face_id contains the character's
1773 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1780 struct glyph
*glyph
, *end
;
1783 xassert (it
->glyph_row
);
1784 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1785 + it
->glyph_row
->used
[it
->area
]);
1786 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1789 i
< it
->pixel_width
&& glyph
< end
;
1792 glyph
->type
= CHAR_GLYPH
;
1793 glyph
->pixel_width
= 1;
1794 glyph
->u
.ch
= it
->c
;
1795 glyph
->face_id
= it
->face_id
;
1796 glyph
->padding_p
= i
> 0;
1797 glyph
->charpos
= CHARPOS (it
->position
);
1798 glyph
->object
= it
->object
;
1800 ++it
->glyph_row
->used
[it
->area
];
1806 /* Produce glyphs for the display element described by IT. The
1807 function fills output fields of IT with pixel information like the
1808 pixel width and height of a character, and maybe produces glyphs at
1809 the same time if IT->glyph_row is non-null. See the explanation of
1810 struct display_iterator in dispextern.h for an overview. */
1816 /* If a hook is installed, let it do the work. */
1817 xassert (it
->what
== IT_CHARACTER
1818 || it
->what
== IT_COMPOSITION
1819 || it
->what
== IT_IMAGE
1820 || it
->what
== IT_STRETCH
);
1822 /* Nothing but characters are supported on terminal frames. For a
1823 composition sequence, it->c is the first character of the
1825 xassert (it
->what
== IT_CHARACTER
1826 || it
->what
== IT_COMPOSITION
);
1828 if (it
->c
>= 040 && it
->c
< 0177)
1830 it
->pixel_width
= it
->nglyphs
= 1;
1834 else if (it
->c
== '\n')
1835 it
->pixel_width
= it
->nglyphs
= 0;
1836 else if (it
->c
== '\t')
1838 int absolute_x
= (it
->current_x
1839 + it
->continuation_lines_width
);
1841 = (((1 + absolute_x
+ it
->tab_width
- 1)
1846 /* If part of the TAB has been displayed on the previous line
1847 which is continued now, continuation_lines_width will have
1848 been incremented already by the part that fitted on the
1849 continued line. So, we will get the right number of spaces
1851 nspaces
= next_tab_x
- absolute_x
;
1858 it
->pixel_width
= it
->len
= 1;
1866 it
->pixel_width
= nspaces
;
1867 it
->nglyphs
= nspaces
;
1869 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1871 /* Coming here means that it->c is from display table, thus we
1872 must send the code as is to the terminal. Although there's
1873 no way to know how many columns it occupies on a screen, it
1874 is a good assumption that a single byte code has 1-column
1876 it
->pixel_width
= it
->nglyphs
= 1;
1882 /* A multi-byte character. The display width is fixed for all
1883 characters of the set. Some of the glyphs may have to be
1884 ignored because they are already displayed in a continued
1886 int charset
= CHAR_CHARSET (it
->c
);
1888 it
->pixel_width
= CHARSET_WIDTH (charset
);
1889 it
->nglyphs
= it
->pixel_width
;
1895 /* Advance current_x by the pixel width as a convenience for
1897 if (it
->area
== TEXT_AREA
)
1898 it
->current_x
+= it
->pixel_width
;
1899 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1900 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1904 /* Get information about special display element WHAT in an
1905 environment described by IT. WHAT is one of IT_TRUNCATION or
1906 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1907 non-null glyph_row member. This function ensures that fields like
1908 face_id, c, len of IT are left untouched. */
1911 produce_special_glyphs (it
, what
)
1913 enum display_element_type what
;
1919 temp_it
.what
= IT_CHARACTER
;
1921 temp_it
.object
= make_number (0);
1922 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1924 if (what
== IT_CONTINUATION
)
1926 /* Continuation glyph. */
1928 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1929 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1931 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it
->dp
)));
1932 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1937 produce_glyphs (&temp_it
);
1938 it
->pixel_width
= temp_it
.pixel_width
;
1939 it
->nglyphs
= temp_it
.pixel_width
;
1941 else if (what
== IT_TRUNCATION
)
1943 /* Truncation glyph. */
1945 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1946 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1948 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it
->dp
)));
1949 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1954 produce_glyphs (&temp_it
);
1955 it
->pixel_width
= temp_it
.pixel_width
;
1956 it
->nglyphs
= temp_it
.pixel_width
;
1963 /* Return an estimation of the pixel height of mode or top lines on
1964 frame F. FACE_ID specifies what line's height to estimate. */
1967 estimate_mode_line_height (f
, face_id
)
1969 enum face_id face_id
;
1971 if (estimate_mode_line_height_hook
)
1972 return estimate_mode_line_height_hook (f
, face_id
);
1979 /***********************************************************************
1981 ***********************************************************************/
1983 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1984 one of the enumerators from enum no_color_bit, or a bit set built
1985 from them. Some display attributes may not be used together with
1986 color; the termcap capability `NC' specifies which ones. */
1988 #define MAY_USE_WITH_COLORS_P(ATTR) \
1989 (TN_max_colors > 0 \
1990 ? (TN_no_color_video & (ATTR)) == 0 \
1993 /* Turn appearances of face FACE_ID on tty frame F on. */
1996 turn_on_face (f
, face_id
)
2000 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2002 xassert (face
!= NULL
);
2004 if (face
->tty_bold_p
)
2006 if (MAY_USE_WITH_COLORS_P (NC_BOLD
))
2007 OUTPUT1_IF (TS_enter_bold_mode
);
2009 else if (face
->tty_dim_p
)
2010 if (MAY_USE_WITH_COLORS_P (NC_DIM
))
2011 OUTPUT1_IF (TS_enter_dim_mode
);
2013 /* Alternate charset and blinking not yet used. */
2014 if (face
->tty_alt_charset_p
2015 && MAY_USE_WITH_COLORS_P (NC_ALT_CHARSET
))
2016 OUTPUT1_IF (TS_enter_alt_charset_mode
);
2018 if (face
->tty_blinking_p
2019 && MAY_USE_WITH_COLORS_P (NC_BLINK
))
2020 OUTPUT1_IF (TS_enter_blink_mode
);
2022 if (face
->tty_underline_p
2023 /* Don't underline if that's difficult. */
2024 && TN_magic_cookie_glitch_ul
<= 0
2025 && MAY_USE_WITH_COLORS_P (NC_UNDERLINE
))
2026 OUTPUT1_IF (TS_enter_underline_mode
);
2028 if (MAY_USE_WITH_COLORS_P (NC_REVERSE
))
2029 if (face
->tty_reverse_p
2030 || face
->foreground
== FACE_TTY_DEFAULT_BG_COLOR
2031 || face
->background
== FACE_TTY_DEFAULT_FG_COLOR
)
2032 OUTPUT1_IF (TS_enter_reverse_mode
);
2034 if (TN_max_colors
> 0)
2038 if (face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2039 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
2040 && face
->foreground
!= FACE_TTY_DEFAULT_BG_COLOR
2041 && TS_set_foreground
)
2043 p
= tparam (TS_set_foreground
, NULL
, 0, (int) face
->foreground
);
2048 if (face
->background
!= FACE_TTY_DEFAULT_COLOR
2049 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
2050 && face
->background
!= FACE_TTY_DEFAULT_FG_COLOR
2051 && TS_set_background
)
2053 p
= tparam (TS_set_background
, NULL
, 0, (int) face
->background
);
2061 /* Turn off appearances of face FACE_ID on tty frame F. */
2064 turn_off_face (f
, face_id
)
2068 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2070 xassert (face
!= NULL
);
2072 if (TS_exit_attribute_mode
)
2074 /* Capability "me" will turn off appearance modes double-bright,
2075 half-bright, reverse-video, standout, underline. It may or
2076 may not turn off alt-char-mode. */
2077 if (face
->tty_bold_p
2079 || face
->tty_reverse_p
2080 || face
->tty_alt_charset_p
2081 || face
->tty_blinking_p
2082 || face
->tty_underline_p
)
2084 OUTPUT1_IF (TS_exit_attribute_mode
);
2085 if (strcmp (TS_exit_attribute_mode
, TS_end_standout_mode
) == 0)
2089 if (face
->tty_alt_charset_p
)
2090 OUTPUT_IF (TS_exit_alt_charset_mode
);
2094 /* If we don't have "me" we can only have those appearances
2095 that have exit sequences defined. */
2096 if (face
->tty_alt_charset_p
)
2097 OUTPUT_IF (TS_exit_alt_charset_mode
);
2099 if (face
->tty_underline_p
2100 /* We don't underline if that's difficult. */
2101 && TN_magic_cookie_glitch_ul
<= 0)
2102 OUTPUT_IF (TS_exit_underline_mode
);
2105 /* Switch back to default colors. */
2106 if (TN_max_colors
> 0
2107 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2108 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2109 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2110 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2111 OUTPUT1_IF (TS_orig_pair
);
2115 /* Return non-zero if the terminal is capable to display colors. */
2117 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2119 "Return non-nil if TTY can display colors on FRAME.")
2123 return TN_max_colors
> 0 ? Qt
: Qnil
;
2129 /***********************************************************************
2131 ***********************************************************************/
2134 term_init (terminal_type
)
2135 char *terminal_type
;
2138 char **address
= &area
;
2142 struct frame
*sf
= XFRAME (selected_frame
);
2145 initialize_w32_display ();
2149 area
= (char *) xmalloc (2044);
2154 FrameRows
= FRAME_HEIGHT (sf
);
2155 FrameCols
= FRAME_WIDTH (sf
);
2156 specified_window
= FRAME_HEIGHT (sf
);
2158 delete_in_insert_mode
= 1;
2161 scroll_region_ok
= 0;
2163 /* Seems to insert lines when it's not supposed to, messing
2164 up the display. In doing a trace, it didn't seem to be
2165 called much, so I don't think we're losing anything by
2168 line_ins_del_ok
= 0;
2169 char_ins_del_ok
= 1;
2173 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
2174 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
2175 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2178 #else /* not WINDOWSNT */
2182 status
= tgetent (buffer
, terminal_type
);
2186 fatal ("Cannot open terminfo database file");
2188 fatal ("Cannot open termcap database file");
2194 fatal ("Terminal type %s is not defined.\n\
2195 If that is not the actual type of terminal you have,\n\
2196 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2197 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2198 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2201 fatal ("Terminal type %s is not defined.\n\
2202 If that is not the actual type of terminal you have,\n\
2203 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2204 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2205 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2210 area
= (char *) xmalloc (2044);
2212 area
= (char *) xmalloc (strlen (buffer
));
2213 #endif /* not TERMINFO */
2217 TS_ins_line
= tgetstr ("al", address
);
2218 TS_ins_multi_lines
= tgetstr ("AL", address
);
2219 TS_bell
= tgetstr ("bl", address
);
2220 BackTab
= tgetstr ("bt", address
);
2221 TS_clr_to_bottom
= tgetstr ("cd", address
);
2222 TS_clr_line
= tgetstr ("ce", address
);
2223 TS_clr_frame
= tgetstr ("cl", address
);
2224 ColPosition
= NULL
; /* tgetstr ("ch", address); */
2225 AbsPosition
= tgetstr ("cm", address
);
2226 CR
= tgetstr ("cr", address
);
2227 TS_set_scroll_region
= tgetstr ("cs", address
);
2228 TS_set_scroll_region_1
= tgetstr ("cS", address
);
2229 RowPosition
= tgetstr ("cv", address
);
2230 TS_del_char
= tgetstr ("dc", address
);
2231 TS_del_multi_chars
= tgetstr ("DC", address
);
2232 TS_del_line
= tgetstr ("dl", address
);
2233 TS_del_multi_lines
= tgetstr ("DL", address
);
2234 TS_delete_mode
= tgetstr ("dm", address
);
2235 TS_end_delete_mode
= tgetstr ("ed", address
);
2236 TS_end_insert_mode
= tgetstr ("ei", address
);
2237 Home
= tgetstr ("ho", address
);
2238 TS_ins_char
= tgetstr ("ic", address
);
2239 TS_ins_multi_chars
= tgetstr ("IC", address
);
2240 TS_insert_mode
= tgetstr ("im", address
);
2241 TS_pad_inserted_char
= tgetstr ("ip", address
);
2242 TS_end_keypad_mode
= tgetstr ("ke", address
);
2243 TS_keypad_mode
= tgetstr ("ks", address
);
2244 LastLine
= tgetstr ("ll", address
);
2245 Right
= tgetstr ("nd", address
);
2246 Down
= tgetstr ("do", address
);
2248 Down
= tgetstr ("nl", address
); /* Obsolete name for "do" */
2250 /* VMS puts a carriage return before each linefeed,
2251 so it is not safe to use linefeeds. */
2252 if (Down
&& Down
[0] == '\n' && Down
[1] == '\0')
2255 if (tgetflag ("bs"))
2256 Left
= "\b"; /* can't possibly be longer! */
2257 else /* (Actually, "bs" is obsolete...) */
2258 Left
= tgetstr ("le", address
);
2260 Left
= tgetstr ("bc", address
); /* Obsolete name for "le" */
2261 TS_pad_char
= tgetstr ("pc", address
);
2262 TS_repeat
= tgetstr ("rp", address
);
2263 TS_end_standout_mode
= tgetstr ("se", address
);
2264 TS_fwd_scroll
= tgetstr ("sf", address
);
2265 TS_standout_mode
= tgetstr ("so", address
);
2266 TS_rev_scroll
= tgetstr ("sr", address
);
2267 Wcm
.cm_tab
= tgetstr ("ta", address
);
2268 TS_end_termcap_modes
= tgetstr ("te", address
);
2269 TS_termcap_modes
= tgetstr ("ti", address
);
2270 Up
= tgetstr ("up", address
);
2271 TS_visible_bell
= tgetstr ("vb", address
);
2272 TS_cursor_normal
= tgetstr ("ve", address
);
2273 TS_cursor_visible
= tgetstr ("vs", address
);
2274 TS_cursor_invisible
= tgetstr ("vi", address
);
2275 TS_set_window
= tgetstr ("wi", address
);
2277 TS_enter_underline_mode
= tgetstr ("us", address
);
2278 TS_exit_underline_mode
= tgetstr ("ue", address
);
2279 TN_magic_cookie_glitch_ul
= tgetnum ("ug");
2280 TS_enter_bold_mode
= tgetstr ("md", address
);
2281 TS_enter_dim_mode
= tgetstr ("mh", address
);
2282 TS_enter_blink_mode
= tgetstr ("mb", address
);
2283 TS_enter_reverse_mode
= tgetstr ("mr", address
);
2284 TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2285 TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2286 TS_exit_attribute_mode
= tgetstr ("me", address
);
2288 MultiUp
= tgetstr ("UP", address
);
2289 MultiDown
= tgetstr ("DO", address
);
2290 MultiLeft
= tgetstr ("LE", address
);
2291 MultiRight
= tgetstr ("RI", address
);
2293 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2294 color because we can't switch back to the default foreground and
2296 TS_orig_pair
= tgetstr ("op", address
);
2299 TS_set_foreground
= tgetstr ("AF", address
);
2300 TS_set_background
= tgetstr ("AB", address
);
2301 if (!TS_set_foreground
)
2304 TS_set_foreground
= tgetstr ("Sf", address
);
2305 TS_set_background
= tgetstr ("Sb", address
);
2308 TN_max_colors
= tgetnum ("Co");
2309 TN_max_pairs
= tgetnum ("pa");
2311 TN_no_color_video
= tgetnum ("NC");
2312 if (TN_no_color_video
== -1)
2313 TN_no_color_video
= 0;
2316 MagicWrap
= tgetflag ("xn");
2317 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2318 the former flag imply the latter. */
2319 AutoWrap
= MagicWrap
|| tgetflag ("am");
2320 memory_below_frame
= tgetflag ("db");
2321 TF_hazeltine
= tgetflag ("hz");
2322 must_write_spaces
= tgetflag ("in");
2323 meta_key
= tgetflag ("km") || tgetflag ("MT");
2324 TF_insmode_motion
= tgetflag ("mi");
2325 TF_standout_motion
= tgetflag ("ms");
2326 TF_underscore
= tgetflag ("ul");
2327 TF_xs
= tgetflag ("xs");
2328 TF_teleray
= tgetflag ("xt");
2330 term_get_fkeys (address
);
2332 /* Get frame size from system, or else from termcap. */
2335 get_frame_size (&width
, &height
);
2336 FRAME_WIDTH (sf
) = width
;
2337 FRAME_HEIGHT (sf
) = height
;
2340 if (FRAME_WIDTH (sf
) <= 0)
2341 SET_FRAME_WIDTH (sf
, tgetnum ("co"));
2343 /* Keep width and external_width consistent */
2344 SET_FRAME_WIDTH (sf
, FRAME_WIDTH (sf
));
2345 if (FRAME_HEIGHT (sf
) <= 0)
2346 FRAME_HEIGHT (sf
) = tgetnum ("li");
2348 if (FRAME_HEIGHT (sf
) < 3 || FRAME_WIDTH (sf
) < 3)
2349 fatal ("Screen size %dx%d is too small",
2350 FRAME_HEIGHT (sf
), FRAME_WIDTH (sf
));
2352 min_padding_speed
= tgetnum ("pb");
2353 TN_standout_width
= tgetnum ("sg");
2354 TabWidth
= tgetnum ("tw");
2357 /* These capabilities commonly use ^J.
2358 I don't know why, but sending them on VMS does not work;
2359 it causes following spaces to be lost, sometimes.
2360 For now, the simplest fix is to avoid using these capabilities ever. */
2361 if (Down
&& Down
[0] == '\n')
2369 TS_fwd_scroll
= Down
;
2371 PC
= TS_pad_char
? *TS_pad_char
: 0;
2376 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2377 and newer termcap doc does not seem to say there is a default.
2382 if (TS_standout_mode
== 0)
2384 TN_standout_width
= tgetnum ("ug");
2385 TS_end_standout_mode
= tgetstr ("ue", address
);
2386 TS_standout_mode
= tgetstr ("us", address
);
2389 /* If no `se' string, try using a `me' string instead.
2390 If that fails, we can't use standout mode at all. */
2391 if (TS_end_standout_mode
== 0)
2393 char *s
= tgetstr ("me", address
);
2395 TS_end_standout_mode
= s
;
2397 TS_standout_mode
= 0;
2403 /* Teleray: most programs want a space in front of TS_standout_mode,
2404 but Emacs can do without it (and give one extra column). */
2405 TS_standout_mode
= "\033RD";
2406 TN_standout_width
= 1;
2407 /* But that means we cannot rely on ^M to go to column zero! */
2409 /* LF can't be trusted either -- can alter hpos */
2410 /* if move at column 0 thru a line with TS_standout_mode */
2414 /* Special handling for certain terminal types known to need it */
2416 if (!strcmp (terminal_type
, "supdup"))
2418 memory_below_frame
= 1;
2419 Wcm
.cm_losewrap
= 1;
2421 if (!strncmp (terminal_type
, "c10", 3)
2422 || !strcmp (terminal_type
, "perq"))
2424 /* Supply a makeshift :wi string.
2425 This string is not valid in general since it works only
2426 for windows starting at the upper left corner;
2427 but that is all Emacs uses.
2429 This string works only if the frame is using
2430 the top of the video memory, because addressing is memory-relative.
2431 So first check the :ti string to see if that is true.
2433 It would be simpler if the :wi string could go in the termcap
2434 entry, but it can't because it is not fully valid.
2435 If it were in the termcap entry, it would confuse other programs. */
2438 p
= TS_termcap_modes
;
2439 while (*p
&& strcmp (p
, "\033v "))
2442 TS_set_window
= "\033v%C %C %C %C ";
2444 /* Termcap entry often fails to have :in: flag */
2445 must_write_spaces
= 1;
2446 /* :ti string typically fails to have \E^G! in it */
2447 /* This limits scope of insert-char to one line. */
2448 strcpy (area
, TS_termcap_modes
);
2449 strcat (area
, "\033\007!");
2450 TS_termcap_modes
= area
;
2451 area
+= strlen (area
) + 1;
2453 /* Change all %+ parameters to %C, to handle
2454 values above 96 correctly for the C100. */
2457 if (p
[0] == '%' && p
[1] == '+')
2463 FrameRows
= FRAME_HEIGHT (sf
);
2464 FrameCols
= FRAME_WIDTH (sf
);
2465 specified_window
= FRAME_HEIGHT (sf
);
2467 if (Wcm_init () == -1) /* can't do cursor motion */
2469 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2470 It lacks the ability to position the cursor.\n\
2471 If that is not the actual type of terminal you have, use either the\n\
2472 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2473 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2477 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2478 It lacks the ability to position the cursor.\n\
2479 If that is not the actual type of terminal you have,\n\
2480 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2481 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2482 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2484 # else /* TERMCAP */
2485 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2486 It lacks the ability to position the cursor.\n\
2487 If that is not the actual type of terminal you have,\n\
2488 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2489 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2490 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2492 # endif /* TERMINFO */
2494 if (FRAME_HEIGHT (sf
) <= 0
2495 || FRAME_WIDTH (sf
) <= 0)
2496 fatal ("The frame size has not been specified");
2498 delete_in_insert_mode
2499 = TS_delete_mode
&& TS_insert_mode
2500 && !strcmp (TS_delete_mode
, TS_insert_mode
);
2502 se_is_so
= (TS_standout_mode
2503 && TS_end_standout_mode
2504 && !strcmp (TS_standout_mode
, TS_end_standout_mode
));
2506 /* Remove width of standout marker from usable width of line */
2507 if (TN_standout_width
> 0)
2508 SET_FRAME_WIDTH (sf
, FRAME_WIDTH (sf
) - TN_standout_width
);
2510 UseTabs
= tabs_safe_p () && TabWidth
== 8;
2514 && (TS_set_window
|| TS_set_scroll_region
|| TS_set_scroll_region_1
));
2516 line_ins_del_ok
= (((TS_ins_line
|| TS_ins_multi_lines
)
2517 && (TS_del_line
|| TS_del_multi_lines
))
2518 || (scroll_region_ok
&& TS_fwd_scroll
&& TS_rev_scroll
));
2520 char_ins_del_ok
= ((TS_ins_char
|| TS_insert_mode
2521 || TS_pad_inserted_char
|| TS_ins_multi_chars
)
2522 && (TS_del_char
|| TS_del_multi_chars
));
2524 fast_clear_end_of_line
= TS_clr_line
!= 0;
2527 if (read_socket_hook
) /* Baudrate is somewhat */
2528 /* meaningless in this case */
2531 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
2532 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
2533 #endif /* WINDOWSNT */
2538 fatal (str
, arg1
, arg2
)
2539 char *str
, *arg1
, *arg2
;
2541 fprintf (stderr
, "emacs: ");
2542 fprintf (stderr
, str
, arg1
, arg2
);
2543 fprintf (stderr
, "\n");
2551 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
2552 "Non-nil means the system uses terminfo rather than termcap.\n\
2553 This variable can be used by terminal emulator packages.");
2555 system_uses_terminfo
= 1;
2557 system_uses_terminfo
= 0;
2560 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
2561 "Non-nil means call this function to ring the bell.\n\
2562 The function should accept no arguments.");
2563 Vring_bell_function
= Qnil
;
2565 defsubr (&Stty_display_color_p
);