1 /* terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 1986, 1987, 1993, 1994 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
31 #include "termhooks.h"
34 extern Lisp_Object
Fmake_sparse_keymap ();
36 #define max(a, b) ((a) > (b) ? (a) : (b))
37 #define min(a, b) ((a) < (b) ? (a) : (b))
39 #define OUTPUT(a) tputs (a, FRAME_HEIGHT (selected_frame) - curY, cmputc)
40 #define OUTPUT1(a) tputs (a, 1, cmputc)
41 #define OUTPUTL(a, lines) tputs (a, lines, cmputc)
42 #define OUTPUT_IF(a) { if (a) tputs (a, FRAME_HEIGHT (selected_frame) - curY, cmputc); }
43 #define OUTPUT1_IF(a) { if (a) tputs (a, 1, cmputc); }
45 /* Terminal characteristics that higher levels want to look at.
46 These are all extern'd in termchar.h */
48 int must_write_spaces
; /* Nonzero means spaces in the text
49 must actually be output; can't just skip
50 over some columns to leave them blank. */
51 int min_padding_speed
; /* Speed below which no padding necessary */
53 int line_ins_del_ok
; /* Terminal can insert and delete lines */
54 int char_ins_del_ok
; /* Terminal can insert and delete chars */
55 int scroll_region_ok
; /* Terminal supports setting the
57 int memory_below_frame
; /* Terminal remembers lines
58 scrolled off bottom */
59 int fast_clear_end_of_line
; /* Terminal has a `ce' string */
61 int dont_calculate_costs
; /* Nonzero means don't bother computing */
62 /* various cost tables; we won't use them. */
64 /* Nonzero means no need to redraw the entire frame on resuming
65 a suspended Emacs. This is useful on terminals with multiple pages,
66 where one page is used for Emacs and another for all else. */
67 int no_redraw_on_reenter
;
69 /* Hook functions that you can set to snap out the functions in this file.
70 These are all extern'd in termhooks.h */
72 int (*cursor_to_hook
) ();
73 int (*raw_cursor_to_hook
) ();
75 int (*clear_to_end_hook
) ();
76 int (*clear_frame_hook
) ();
77 int (*clear_end_of_line_hook
) ();
79 int (*ins_del_lines_hook
) ();
81 int (*change_line_highlight_hook
) ();
82 int (*reassert_line_highlight_hook
) ();
84 int (*insert_glyphs_hook
) ();
85 int (*write_glyphs_hook
) ();
86 int (*delete_glyphs_hook
) ();
88 int (*ring_bell_hook
) ();
90 int (*reset_terminal_modes_hook
) ();
91 int (*set_terminal_modes_hook
) ();
92 int (*update_begin_hook
) ();
93 int (*update_end_hook
) ();
94 int (*set_terminal_window_hook
) ();
96 int (*read_socket_hook
) ();
98 int (*frame_up_to_date_hook
) ();
100 /* Return the current position of the mouse.
102 Set *f to the frame the mouse is in, or zero if the mouse is in no
103 Emacs frame. If it is set to zero, all the other arguments are
106 If the motion started in a scroll bar, set *bar_window to the
107 scroll bar's window, *part to the part the mouse is currently over,
108 *x to the position of the mouse along the scroll bar, and *y to the
109 overall length of the scroll bar.
111 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
112 row of the character cell the mouse is over.
114 Set *time to the time the mouse was at the returned position.
116 This should clear mouse_moved until the next motion
118 void (*mouse_position_hook
) ( /* FRAME_PTR *f,
119 Lisp_Object *bar_window,
120 enum scroll_bar_part *part,
123 unsigned long *time */ );
125 /* When reading from a minibuffer in a different frame, Emacs wants
126 to shift the highlight from the selected frame to the minibuffer's
127 frame; under X, this means it lies about where the focus is.
128 This hook tells the window system code to re-decide where to put
130 void (*frame_rehighlight_hook
) ( /* FRAME_PTR f */ );
132 /* If we're displaying frames using a window system that can stack
133 frames on top of each other, this hook allows you to bring a frame
134 to the front, or bury it behind all the other windows. If this
135 hook is zero, that means the device we're displaying on doesn't
136 support overlapping frames, so there's no need to raise or lower
139 If RAISE is non-zero, F is brought to the front, before all other
140 windows. If RAISE is zero, F is sent to the back, behind all other
142 void (*frame_raise_lower_hook
) ( /* FRAME_PTR f, int raise */ );
144 /* Set the vertical scroll bar for WINDOW to have its upper left corner
145 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
146 indicate that we are displaying PORTION characters out of a total
147 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
148 have a scroll bar, create one for it. */
149 void (*set_vertical_scroll_bar_hook
)
150 ( /* struct window *window,
151 int portion, int whole, int position */ );
154 /* The following three hooks are used when we're doing a thorough
155 redisplay of the frame. We don't explicitly know which scroll bars
156 are going to be deleted, because keeping track of when windows go
157 away is a real pain - can you say set-window-configuration?
158 Instead, we just assert at the beginning of redisplay that *all*
159 scroll bars are to be removed, and then save scroll bars from the
160 firey pit when we actually redisplay their window. */
162 /* Arrange for all scroll bars on FRAME to be removed at the next call
163 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
164 `*redeem_scroll_bar_hook' is applied to its window before the judgement.
166 This should be applied to each frame each time its window tree is
167 redisplayed, even if it is not displaying scroll bars at the moment;
168 if the HAS_SCROLL_BARS flag has just been turned off, only calling
169 this and the judge_scroll_bars_hook will get rid of them.
171 If non-zero, this hook should be safe to apply to any frame,
172 whether or not it can support scroll bars, and whether or not it is
173 currently displaying them. */
174 void (*condemn_scroll_bars_hook
)( /* FRAME_PTR *frame */ );
176 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
177 Note that it's okay to redeem a scroll bar that is not condemned. */
178 void (*redeem_scroll_bar_hook
)( /* struct window *window */ );
180 /* Remove all scroll bars on FRAME that haven't been saved since the
181 last call to `*condemn_scroll_bars_hook'.
183 This should be applied to each frame after each time its window
184 tree is redisplayed, even if it is not displaying scroll bars at the
185 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
186 calling this and condemn_scroll_bars_hook will get rid of them.
188 If non-zero, this hook should be safe to apply to any frame,
189 whether or not it can support scroll bars, and whether or not it is
190 currently displaying them. */
191 void (*judge_scroll_bars_hook
)( /* FRAME_PTR *FRAME */ );
194 /* Strings, numbers and flags taken from the termcap entry. */
196 char *TS_ins_line
; /* termcap "al" */
197 char *TS_ins_multi_lines
; /* "AL" (one parameter, # lines to insert) */
198 char *TS_bell
; /* "bl" */
199 char *TS_clr_to_bottom
; /* "cd" */
200 char *TS_clr_line
; /* "ce", clear to end of line */
201 char *TS_clr_frame
; /* "cl" */
202 char *TS_set_scroll_region
; /* "cs" (2 params, first line and last line) */
203 char *TS_set_scroll_region_1
; /* "cS" (4 params: total lines,
204 lines above scroll region, lines below it,
205 total lines again) */
206 char *TS_del_char
; /* "dc" */
207 char *TS_del_multi_chars
; /* "DC" (one parameter, # chars to delete) */
208 char *TS_del_line
; /* "dl" */
209 char *TS_del_multi_lines
; /* "DL" (one parameter, # lines to delete) */
210 char *TS_delete_mode
; /* "dm", enter character-delete mode */
211 char *TS_end_delete_mode
; /* "ed", leave character-delete mode */
212 char *TS_end_insert_mode
; /* "ei", leave character-insert mode */
213 char *TS_ins_char
; /* "ic" */
214 char *TS_ins_multi_chars
; /* "IC" (one parameter, # chars to insert) */
215 char *TS_insert_mode
; /* "im", enter character-insert mode */
216 char *TS_pad_inserted_char
; /* "ip". Just padding, no commands. */
217 char *TS_end_keypad_mode
; /* "ke" */
218 char *TS_keypad_mode
; /* "ks" */
219 char *TS_pad_char
; /* "pc", char to use as padding */
220 char *TS_repeat
; /* "rp" (2 params, # times to repeat
221 and character to be repeated) */
222 char *TS_end_standout_mode
; /* "se" */
223 char *TS_fwd_scroll
; /* "sf" */
224 char *TS_standout_mode
; /* "so" */
225 char *TS_rev_scroll
; /* "sr" */
226 char *TS_end_termcap_modes
; /* "te" */
227 char *TS_termcap_modes
; /* "ti" */
228 char *TS_visible_bell
; /* "vb" */
229 char *TS_end_visual_mode
; /* "ve" */
230 char *TS_visual_mode
; /* "vi" */
231 char *TS_set_window
; /* "wi" (4 params, start and end of window,
232 each as vpos and hpos) */
234 int TF_hazeltine
; /* termcap hz flag. */
235 int TF_insmode_motion
; /* termcap mi flag: can move while in insert mode. */
236 int TF_standout_motion
; /* termcap mi flag: can move while in standout mode. */
237 int TF_underscore
; /* termcap ul flag: _ underlines if overstruck on
238 nonblank position. Must clear before writing _. */
239 int TF_teleray
; /* termcap xt flag: many weird consequences.
242 int TF_xs
; /* Nonzero for "xs". If set together with
243 TN_standout_width == 0, it means don't bother
244 to write any end-standout cookies. */
246 int TN_standout_width
; /* termcap sg number: width occupied by standout
249 static int RPov
; /* # chars to start a TS_repeat */
251 static int delete_in_insert_mode
; /* delete mode == insert mode */
253 static int se_is_so
; /* 1 if same string both enters and leaves
258 /* Number of chars of space used for standout marker at beginning of line,
259 or'd with 0100. Zero if no standout marker at all.
261 Used IFF TN_standout_width >= 0. */
263 static char *chars_wasted
;
264 static char *copybuf
;
266 /* nonzero means supposed to write text in standout mode. */
267 int standout_requested
;
269 int insert_mode
; /* Nonzero when in insert mode. */
270 int standout_mode
; /* Nonzero when in standout mode. */
272 /* Size of window specified by higher levels.
273 This is the number of lines, from the top of frame downwards,
274 which can participate in insert-line/delete-line operations.
276 Effectively it excludes the bottom frame_height - specified_window_size
277 lines from those operations. */
279 int specified_window
;
281 /* Frame currently being redisplayed; 0 if not currently redisplaying.
282 (Direct output does not count). */
284 FRAME_PTR updating_frame
;
286 /* Provided for lisp packages. */
287 static int system_uses_terminfo
;
291 extern char *tgetstr ();
295 /* We aren't X windows, but we aren't termcap either. This makes me
296 uncertain as to what value to use for frame.output_method. For
297 this file, we'll define FRAME_TERMCAP_P to be zero so that our
298 output hooks get called instead of the termcap functions. Probably
299 the best long-term solution is to define an output_windows_nt... */
301 #undef FRAME_TERMCAP_P
302 #define FRAME_TERMCAP_P(_f_) 0
303 #endif /* WINDOWSNT */
307 if (! FRAME_TERMCAP_P (selected_frame
))
309 (*ring_bell_hook
) ();
312 OUTPUT (TS_visible_bell
&& visible_bell
? TS_visible_bell
: TS_bell
);
315 set_terminal_modes ()
317 if (! FRAME_TERMCAP_P (selected_frame
))
319 (*set_terminal_modes_hook
) ();
322 OUTPUT_IF (TS_termcap_modes
);
323 OUTPUT_IF (TS_visual_mode
);
324 OUTPUT_IF (TS_keypad_mode
);
328 reset_terminal_modes ()
330 if (! FRAME_TERMCAP_P (selected_frame
))
332 (*reset_terminal_modes_hook
) ();
335 if (TN_standout_width
< 0)
336 turn_off_highlight ();
338 OUTPUT_IF (TS_end_keypad_mode
);
339 OUTPUT_IF (TS_end_visual_mode
);
340 OUTPUT_IF (TS_end_termcap_modes
);
341 /* Output raw CR so kernel can track the cursor hpos. */
342 /* But on magic-cookie terminals this can erase an end-standout marker and
343 cause the rest of the frame to be in standout, so move down first. */
344 if (TN_standout_width
>= 0)
353 if (! FRAME_TERMCAP_P (updating_frame
))
354 (*update_begin_hook
) (f
);
360 if (! FRAME_TERMCAP_P (updating_frame
))
362 (*update_end_hook
) (f
);
367 background_highlight ();
368 standout_requested
= 0;
372 set_terminal_window (size
)
375 if (! FRAME_TERMCAP_P (updating_frame
))
377 (*set_terminal_window_hook
) (size
);
380 specified_window
= size
? size
: FRAME_HEIGHT (selected_frame
);
381 if (!scroll_region_ok
)
383 set_scroll_region (0, specified_window
);
386 set_scroll_region (start
, stop
)
390 if (TS_set_scroll_region
)
392 buf
= tparam (TS_set_scroll_region
, 0, 0, start
, stop
- 1);
394 else if (TS_set_scroll_region_1
)
396 buf
= tparam (TS_set_scroll_region_1
, 0, 0,
397 FRAME_HEIGHT (selected_frame
), start
,
398 FRAME_HEIGHT (selected_frame
) - stop
,
399 FRAME_HEIGHT (selected_frame
));
403 buf
= tparam (TS_set_window
, 0, 0, start
, 0, stop
, FRAME_WIDTH (selected_frame
));
413 OUTPUT (TS_insert_mode
);
420 OUTPUT (TS_end_insert_mode
);
424 /* Handle highlighting when TN_standout_width (termcap sg) is not specified.
425 In these terminals, output is affected by the value of standout
426 mode when the output is written.
428 These functions are called on all terminals, but do nothing
429 on terminals whose standout mode does not work that way. */
431 turn_off_highlight ()
433 if (TN_standout_width
< 0)
436 OUTPUT_IF (TS_end_standout_mode
);
443 if (TN_standout_width
< 0)
446 OUTPUT_IF (TS_standout_mode
);
451 /* Set standout mode to the state it should be in for
452 empty space inside windows. What this is,
453 depends on the user option inverse-video. */
455 background_highlight ()
457 if (TN_standout_width
>= 0)
460 turn_on_highlight ();
462 turn_off_highlight ();
465 /* Set standout mode to the mode specified for the text to be output. */
468 highlight_if_desired ()
470 if (TN_standout_width
>= 0)
472 if (!inverse_video
== !standout_requested
)
473 turn_off_highlight ();
475 turn_on_highlight ();
478 /* Handle standout mode for terminals in which TN_standout_width >= 0.
479 On these terminals, standout is controlled by markers that
480 live inside the terminal's memory. TN_standout_width is the width
481 that the marker occupies in memory. Standout runs from the marker
482 to the end of the line on some terminals, or to the next
483 turn-off-standout marker (TS_end_standout_mode) string
484 on other terminals. */
486 /* Write a standout marker or end-standout marker at the front of the line
487 at vertical position vpos. */
489 write_standout_marker (flag
, vpos
)
492 if (flag
|| (TS_end_standout_mode
&& !TF_teleray
&& !se_is_so
493 && !(TF_xs
&& TN_standout_width
== 0)))
496 cmplus (TN_standout_width
);
497 OUTPUT (flag
? TS_standout_mode
: TS_end_standout_mode
);
498 chars_wasted
[curY
] = TN_standout_width
| 0100;
502 /* External interface to control of standout mode.
503 Call this when about to modify line at position VPOS
504 and not change whether it is highlighted. */
506 reassert_line_highlight (highlight
, vpos
)
510 if (! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
512 (*reassert_line_highlight_hook
) (highlight
, vpos
);
515 if (TN_standout_width
< 0)
516 /* Handle terminals where standout takes affect at output time */
517 standout_requested
= highlight
;
518 else if (chars_wasted
[vpos
] == 0)
519 /* For terminals with standout markers, write one on this line
520 if there isn't one already. */
521 write_standout_marker (highlight
, vpos
);
524 /* Call this when about to modify line at position VPOS
525 and change whether it is highlighted. */
527 change_line_highlight (new_highlight
, vpos
, first_unused_hpos
)
528 int new_highlight
, vpos
, first_unused_hpos
;
530 standout_requested
= new_highlight
;
531 if (! FRAME_TERMCAP_P (updating_frame
))
533 (*change_line_highlight_hook
) (new_highlight
, vpos
, first_unused_hpos
);
539 if (TN_standout_width
< 0)
540 background_highlight ();
541 /* If line starts with a marker, delete the marker */
542 else if (TS_clr_line
&& chars_wasted
[curY
])
545 /* On Teleray, make sure to erase the SO marker. */
548 cmgoto (curY
- 1, FRAME_WIDTH (selected_frame
) - 4);
550 curY
++; /* ESC S moves to next line where the TS_standout_mode was */
554 cmgoto (curY
, 0); /* reposition to kill standout marker */
556 clear_end_of_line_raw (first_unused_hpos
);
557 reassert_line_highlight (new_highlight
, curY
);
561 /* Move to absolute position, specified origin 0 */
566 if (! FRAME_TERMCAP_P ((updating_frame
571 (*cursor_to_hook
) (row
, col
);
575 col
+= chars_wasted
[row
] & 077;
576 if (curY
== row
&& curX
== col
)
578 if (!TF_standout_motion
)
579 background_highlight ();
580 if (!TF_insmode_motion
)
585 /* Similar but don't take any account of the wasted characters. */
587 raw_cursor_to (row
, col
)
590 if (! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
592 (*raw_cursor_to_hook
) (row
, col
);
595 if (curY
== row
&& curX
== col
)
597 if (!TF_standout_motion
)
598 background_highlight ();
599 if (!TF_insmode_motion
)
604 /* Erase operations */
606 /* clear from cursor to end of frame */
611 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
613 (*clear_to_end_hook
) ();
616 if (TS_clr_to_bottom
)
618 background_highlight ();
619 OUTPUT (TS_clr_to_bottom
);
620 bzero (chars_wasted
+ curY
, FRAME_HEIGHT (selected_frame
) - curY
);
624 for (i
= curY
; i
< FRAME_HEIGHT (selected_frame
); i
++)
627 clear_end_of_line_raw (FRAME_WIDTH (selected_frame
));
632 /* Clear entire frame */
637 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
639 (*clear_frame_hook
) ();
644 background_highlight ();
645 OUTPUT (TS_clr_frame
);
646 bzero (chars_wasted
, FRAME_HEIGHT (selected_frame
));
656 /* Clear to end of line, but do not clear any standout marker.
657 Assumes that the cursor is positioned at a character of real text,
658 which implies it cannot be before a standout marker
659 unless the marker has zero width.
661 Note that the cursor may be moved. */
663 clear_end_of_line (first_unused_hpos
)
664 int first_unused_hpos
;
666 static GLYPH buf
= SPACEGLYPH
;
667 if (FRAME_TERMCAP_P (selected_frame
)
668 && TN_standout_width
== 0 && curX
== 0 && chars_wasted
[curY
] != 0)
669 write_glyphs (&buf
, 1);
670 clear_end_of_line_raw (first_unused_hpos
);
673 /* Clear from cursor to end of line.
674 Assume that the line is already clear starting at column first_unused_hpos.
675 If the cursor is at a standout marker, erase the marker.
677 Note that the cursor may be moved, on terminals lacking a `ce' string. */
679 clear_end_of_line_raw (first_unused_hpos
)
680 int first_unused_hpos
;
684 if (clear_end_of_line_hook
685 && ! FRAME_TERMCAP_P ((updating_frame
689 (*clear_end_of_line_hook
) (first_unused_hpos
);
693 first_unused_hpos
+= chars_wasted
[curY
] & 077;
694 if (curX
>= first_unused_hpos
)
696 /* Notice if we are erasing a magic cookie */
698 chars_wasted
[curY
] = 0;
699 background_highlight ();
702 OUTPUT1 (TS_clr_line
);
705 { /* have to do it the hard way */
708 /* Do not write in last row last col with Autowrap on. */
709 if (AutoWrap
&& curY
== FRAME_HEIGHT (selected_frame
) - 1
710 && first_unused_hpos
== FRAME_WIDTH (selected_frame
))
713 for (i
= curX
; i
< first_unused_hpos
; i
++)
716 fputc (' ', termscript
);
719 cmplus (first_unused_hpos
- curX
);
724 write_glyphs (string
, len
)
725 register GLYPH
*string
;
729 register int tlen
= GLYPH_TABLE_LENGTH
;
730 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
732 if (write_glyphs_hook
733 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
735 (*write_glyphs_hook
) (string
, len
);
739 highlight_if_desired ();
742 /* Don't dare write in last column of bottom line, if AutoWrap,
743 since that would scroll the whole frame on some terminals. */
746 && curY
+ 1 == FRAME_HEIGHT (selected_frame
)
747 && (curX
+ len
- (chars_wasted
[curY
] & 077)
748 == FRAME_WIDTH (selected_frame
)))
755 /* Check quickly for G beyond length of table.
756 That implies it isn't an alias and is simple. */
760 putc (g
& 0xff, stdout
);
764 putc (g
& 0xff, termscript
);
768 /* G has an entry in Vglyph_table,
769 so process any alias and then test for simpleness. */
770 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
771 g
= GLYPH_ALIAS (tbase
, g
);
772 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
776 /* Here if G (or its definition as an alias) is not simple. */
777 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
),
782 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
),
789 /* If start is zero, insert blanks instead of a string at start */
791 insert_glyphs (start
, len
)
792 register GLYPH
*start
;
797 register int tlen
= GLYPH_TABLE_LENGTH
;
798 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
800 if (insert_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
802 (*insert_glyphs_hook
) (start
, len
);
805 highlight_if_desired ();
807 if (TS_ins_multi_chars
)
809 buf
= tparam (TS_ins_multi_chars
, 0, 0, len
);
813 write_glyphs (start
, len
);
821 OUTPUT1_IF (TS_ins_char
);
827 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
829 putc (g
& 0xff, stdout
);
833 putc (g
& 0xff, termscript
);
837 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
), stdout
);
841 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
),
845 OUTPUT1_IF (TS_pad_inserted_char
);
855 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
857 (*delete_glyphs_hook
) (n
);
861 if (delete_in_insert_mode
)
868 OUTPUT_IF (TS_delete_mode
);
871 if (TS_del_multi_chars
)
873 buf
= tparam (TS_del_multi_chars
, 0, 0, n
);
878 for (i
= 0; i
< n
; i
++)
879 OUTPUT1 (TS_del_char
);
880 if (!delete_in_insert_mode
)
881 OUTPUT_IF (TS_end_delete_mode
);
884 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
886 ins_del_lines (vpos
, n
)
889 char *multi
= n
> 0 ? TS_ins_multi_lines
: TS_del_multi_lines
;
890 char *single
= n
> 0 ? TS_ins_line
: TS_del_line
;
891 char *scroll
= n
> 0 ? TS_rev_scroll
: TS_fwd_scroll
;
893 register int i
= n
> 0 ? n
: -n
;
896 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
898 (*ins_del_lines_hook
) (vpos
, n
);
902 /* If the lines below the insertion are being pushed
903 into the end of the window, this is the same as clearing;
904 and we know the lines are already clear, since the matching
905 deletion has already been done. So can ignore this. */
906 /* If the lines below the deletion are blank lines coming
907 out of the end of the window, don't bother,
908 as there will be a matching inslines later that will flush them. */
909 if (scroll_region_ok
&& vpos
+ i
>= specified_window
)
911 if (!memory_below_frame
&& vpos
+ i
>= FRAME_HEIGHT (selected_frame
))
916 raw_cursor_to (vpos
, 0);
917 background_highlight ();
918 buf
= tparam (multi
, 0, 0, i
);
924 raw_cursor_to (vpos
, 0);
925 background_highlight ();
933 set_scroll_region (vpos
, specified_window
);
935 raw_cursor_to (specified_window
- 1, 0);
937 raw_cursor_to (vpos
, 0);
938 background_highlight ();
940 OUTPUTL (scroll
, specified_window
- vpos
);
941 set_scroll_region (0, specified_window
);
944 if (TN_standout_width
>= 0)
949 : FRAME_HEIGHT (selected_frame
));
953 bcopy (&chars_wasted
[vpos
- n
], &chars_wasted
[vpos
],
954 lower_limit
- vpos
+ n
);
955 bzero (&chars_wasted
[lower_limit
+ n
], - n
);
959 bcopy (&chars_wasted
[vpos
], ©buf
[vpos
], lower_limit
- vpos
- n
);
960 bcopy (©buf
[vpos
], &chars_wasted
[vpos
+ n
],
961 lower_limit
- vpos
- n
);
962 bzero (&chars_wasted
[vpos
], n
);
965 if (!scroll_region_ok
&& memory_below_frame
&& n
< 0)
967 cursor_to (FRAME_HEIGHT (selected_frame
) + n
, 0);
972 /* Compute cost of sending "str", in characters,
973 not counting any line-dependent padding. */
981 tputs (str
, 0, evalcost
);
985 /* Compute cost of sending "str", in characters,
986 counting any line-dependent padding at one line. */
989 string_cost_one_line (str
)
994 tputs (str
, 1, evalcost
);
998 /* Compute per line amount of line-dependent padding,
999 in tenths of characters. */
1007 tputs (str
, 0, evalcost
);
1010 tputs (str
, 10, evalcost
);
1015 /* char_ins_del_cost[n] is cost of inserting N characters.
1016 char_ins_del_cost[-n] is cost of deleting N characters. */
1018 int *char_ins_del_vector
;
1020 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH ((f))])
1025 calculate_ins_del_char_costs (frame
)
1028 int ins_startup_cost
, del_startup_cost
;
1029 int ins_cost_per_char
, del_cost_per_char
;
1033 if (TS_ins_multi_chars
)
1035 ins_cost_per_char
= 0;
1036 ins_startup_cost
= string_cost_one_line (TS_ins_multi_chars
);
1038 else if (TS_ins_char
|| TS_pad_inserted_char
1039 || (TS_insert_mode
&& TS_end_insert_mode
))
1041 ins_startup_cost
= (30 * (string_cost (TS_insert_mode
)
1042 + string_cost (TS_end_insert_mode
))) / 100;
1043 ins_cost_per_char
= (string_cost_one_line (TS_ins_char
)
1044 + string_cost_one_line (TS_pad_inserted_char
));
1048 ins_startup_cost
= 9999;
1049 ins_cost_per_char
= 0;
1052 if (TS_del_multi_chars
)
1054 del_cost_per_char
= 0;
1055 del_startup_cost
= string_cost_one_line (TS_del_multi_chars
);
1057 else if (TS_del_char
)
1059 del_startup_cost
= (string_cost (TS_delete_mode
)
1060 + string_cost (TS_end_delete_mode
));
1061 if (delete_in_insert_mode
)
1062 del_startup_cost
/= 2;
1063 del_cost_per_char
= string_cost_one_line (TS_del_char
);
1067 del_startup_cost
= 9999;
1068 del_cost_per_char
= 0;
1071 /* Delete costs are at negative offsets */
1072 p
= &char_ins_del_cost (frame
)[0];
1073 for (i
= FRAME_WIDTH (selected_frame
); --i
>= 0;)
1074 *--p
= (del_startup_cost
+= del_cost_per_char
);
1076 /* Doing nothing is free */
1077 p
= &char_ins_del_cost (frame
)[0];
1080 /* Insert costs are at positive offsets */
1081 for (i
= FRAME_WIDTH (frame
); --i
>= 0;)
1082 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1085 extern do_line_insertion_deletion_costs ();
1087 calculate_costs (frame
)
1090 register char *f
= TS_set_scroll_region
?
1091 TS_set_scroll_region
1092 : TS_set_scroll_region_1
;
1094 if (dont_calculate_costs
)
1097 #ifdef HAVE_X_WINDOWS
1098 if (FRAME_X_P (frame
))
1100 do_line_insertion_deletion_costs (frame
, 0, ".5*", 0, ".5*",
1102 x_screen_planes (frame
));
1107 /* These variables are only used for terminal stuff. They are allocated
1108 once for the terminal frame of X-windows emacs, but not used afterwards.
1110 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1111 X turns off char_ins_del_ok.
1113 chars_wasted and copybuf are only used here in term.c in cases where
1114 the term hook isn't called. */
1116 if (chars_wasted
!= 0)
1117 chars_wasted
= (char *) xrealloc (chars_wasted
, FRAME_HEIGHT (frame
));
1119 chars_wasted
= (char *) xmalloc (FRAME_HEIGHT (frame
));
1122 copybuf
= (char *) xrealloc (copybuf
, FRAME_HEIGHT (frame
));
1124 copybuf
= (char *) xmalloc (FRAME_HEIGHT (frame
));
1126 if (char_ins_del_vector
!= 0)
1128 = (int *) xrealloc (char_ins_del_vector
,
1130 + 2 * FRAME_WIDTH (frame
) * sizeof (int)));
1133 = (int *) xmalloc (sizeof (int)
1134 + 2 * FRAME_WIDTH (frame
) * sizeof (int));
1136 bzero (chars_wasted
, FRAME_HEIGHT (frame
));
1137 bzero (copybuf
, FRAME_HEIGHT (frame
));
1138 bzero (char_ins_del_vector
, (sizeof (int)
1139 + 2 * FRAME_WIDTH (frame
) * sizeof (int)));
1141 if (f
&& (!TS_ins_line
&& !TS_del_line
))
1142 do_line_insertion_deletion_costs (frame
,
1143 TS_rev_scroll
, TS_ins_multi_lines
,
1144 TS_fwd_scroll
, TS_del_multi_lines
,
1147 do_line_insertion_deletion_costs (frame
,
1148 TS_ins_line
, TS_ins_multi_lines
,
1149 TS_del_line
, TS_del_multi_lines
,
1152 calculate_ins_del_char_costs (frame
);
1154 /* Don't use TS_repeat if its padding is worse than sending the chars */
1155 if (TS_repeat
&& per_line_cost (TS_repeat
) * baud_rate
< 9000)
1156 RPov
= string_cost (TS_repeat
);
1158 RPov
= FRAME_WIDTH (frame
) * 2;
1160 cmcostinit (); /* set up cursor motion costs */
1167 /* Termcap capability names that correspond directly to X keysyms.
1168 Some of these (marked "terminfo") aren't supplied by old-style
1169 (Berkeley) termcap entries. They're listed in X keysym order;
1170 except we put the keypad keys first, so that if they clash with
1171 other keys (as on the IBM PC keyboard) they get overridden.
1174 static struct fkey_table keys
[] = {
1175 "kh", "home", /* termcap */
1176 "kl", "left", /* termcap */
1177 "ku", "up", /* termcap */
1178 "kr", "right", /* termcap */
1179 "kd", "down", /* termcap */
1180 "%8", "prior", /* terminfo */
1181 "%5", "next", /* terminfo */
1182 "@7", "end", /* terminfo */
1183 "@1", "begin", /* terminfo */
1184 "*6", "select", /* terminfo */
1185 "%9", "print", /* terminfo */
1186 "@4", "execute", /* terminfo --- actually the `command' key */
1188 * "insert" --- see below
1190 "&8", "undo", /* terminfo */
1191 "%0", "redo", /* terminfo */
1192 "%7", "menu", /* terminfo --- actually the `options' key */
1193 "@0", "find", /* terminfo */
1194 "@2", "cancel", /* terminfo */
1195 "%1", "help", /* terminfo */
1197 * "break" goes here, but can't be reliably intercepted with termcap
1199 "&4", "reset", /* terminfo --- actually `restart' */
1201 * "system" and "user" --- no termcaps
1203 "kE", "clearline", /* terminfo */
1204 "kA", "insertline", /* terminfo */
1205 "kL", "deleteline", /* terminfo */
1206 "kI", "insertchar", /* terminfo */
1207 "kD", "deletechar", /* terminfo */
1208 "kB", "backtab", /* terminfo */
1210 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1212 "@8", "kp-enter", /* terminfo */
1214 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1215 * "kp-multiply", "kp-add", "kp-separator",
1216 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1217 * --- no termcaps for any of these.
1219 "K4", "kp-1", /* terminfo */
1221 * "kp-2" --- no termcap
1223 "K5", "kp-3", /* terminfo */
1225 * "kp-4" --- no termcap
1227 "K2", "kp-5", /* terminfo */
1229 * "kp-6" --- no termcap
1231 "K1", "kp-7", /* terminfo */
1233 * "kp-8" --- no termcap
1235 "K3", "kp-9", /* terminfo */
1237 * "kp-equal" --- no termcap
1250 static char **term_get_fkeys_arg
;
1251 static Lisp_Object
term_get_fkeys_1 ();
1253 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1254 This function scans the termcap function key sequence entries, and
1255 adds entries to Vfunction_key_map for each function key it finds. */
1258 term_get_fkeys (address
)
1261 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1262 errors during the call. The only errors should be from Fdefine_key
1263 when given a key sequence containing an invalid prefix key. If the
1264 termcap defines function keys which use a prefix that is already bound
1265 to a command by the default bindings, we should silently ignore that
1266 function key specification, rather than giving the user an error and
1267 refusing to run at all on such a terminal. */
1269 extern Lisp_Object
Fidentity ();
1270 term_get_fkeys_arg
= address
;
1271 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1279 char **address
= term_get_fkeys_arg
;
1281 /* This can happen if CANNOT_DUMP or with strange options. */
1283 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1285 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1287 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1289 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1290 Fmake_vector (make_number (1),
1291 intern (keys
[i
].name
)));
1294 /* The uses of the "k0" capability are inconsistent; sometimes it
1295 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1296 We will attempt to politely accommodate both systems by testing for
1297 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1300 char *k_semi
= tgetstr ("k;", address
);
1301 char *k0
= tgetstr ("k0", address
);
1302 char *k0_name
= "f10";
1306 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1307 Fmake_vector (make_number (1), intern ("f10")));
1312 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1313 Fmake_vector (make_number (1), intern (k0_name
)));
1316 /* Set up cookies for numbered function keys above f10. */
1318 char fcap
[3], fkey
[4];
1320 fcap
[0] = 'F'; fcap
[2] = '\0';
1321 for (i
= 11; i
< 64; i
++)
1324 fcap
[1] = '1' + i
- 11;
1326 fcap
[1] = 'A' + i
- 11;
1328 fcap
[1] = 'a' + i
- 11;
1331 char *sequence
= tgetstr (fcap
, address
);
1334 sprintf (fkey
, "f%d", i
);
1335 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1336 Fmake_vector (make_number (1),
1344 * Various mappings to try and get a better fit.
1347 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1348 if (!tgetstr (cap1, address)) \
1350 char *sequence = tgetstr (cap2, address); \
1352 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1353 Fmake_vector (make_number (1), \
1357 /* if there's no key_next keycap, map key_npage to `next' keysym */
1358 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1359 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1360 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1361 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1362 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1364 /* IBM has their own non-standard dialect of terminfo.
1365 If the standard name isn't found, try the IBM name. */
1366 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1367 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1368 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1369 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1370 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1371 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1372 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1373 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1374 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1375 #undef CONDITIONAL_REASSIGN
1380 term_init (terminal_type
)
1381 char *terminal_type
;
1384 char **address
= &area
;
1390 initialize_win_nt_display ();
1393 dont_calculate_costs
= 0;
1395 area
= (char *) malloc (2044);
1400 FrameRows
= FRAME_HEIGHT (selected_frame
);
1401 FrameCols
= FRAME_WIDTH (selected_frame
);
1402 specified_window
= FRAME_HEIGHT (selected_frame
);
1404 delete_in_insert_mode
= 1;
1407 scroll_region_ok
= 0;
1409 /* Seems to insert lines when it's not supposed to, messing
1410 up the display. In doing a trace, it didn't seem to be
1411 called much, so I don't think we're losing anything by
1414 line_ins_del_ok
= 0;
1415 char_ins_del_ok
= 1;
1419 FRAME_CAN_HAVE_SCROLL_BARS (selected_frame
) = 0;
1420 FRAME_HAS_VERTICAL_SCROLL_BARS (selected_frame
) = 0;
1423 #endif /* WINDOWSNT */
1426 dont_calculate_costs
= 0;
1428 status
= tgetent (buffer
, terminal_type
);
1430 fatal ("Cannot open termcap database file.\n");
1432 fatal ("Terminal type %s is not defined.\n\
1433 If that is not the actual type of terminal you have,\n\
1434 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1435 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1436 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.\n",
1440 area
= (char *) malloc (2044);
1442 area
= (char *) malloc (strlen (buffer
));
1443 #endif /* not TERMINFO */
1447 TS_ins_line
= tgetstr ("al", address
);
1448 TS_ins_multi_lines
= tgetstr ("AL", address
);
1449 TS_bell
= tgetstr ("bl", address
);
1450 BackTab
= tgetstr ("bt", address
);
1451 TS_clr_to_bottom
= tgetstr ("cd", address
);
1452 TS_clr_line
= tgetstr ("ce", address
);
1453 TS_clr_frame
= tgetstr ("cl", address
);
1454 ColPosition
= tgetstr ("ch", address
);
1455 AbsPosition
= tgetstr ("cm", address
);
1456 CR
= tgetstr ("cr", address
);
1457 TS_set_scroll_region
= tgetstr ("cs", address
);
1458 TS_set_scroll_region_1
= tgetstr ("cS", address
);
1459 RowPosition
= tgetstr ("cv", address
);
1460 TS_del_char
= tgetstr ("dc", address
);
1461 TS_del_multi_chars
= tgetstr ("DC", address
);
1462 TS_del_line
= tgetstr ("dl", address
);
1463 TS_del_multi_lines
= tgetstr ("DL", address
);
1464 TS_delete_mode
= tgetstr ("dm", address
);
1465 TS_end_delete_mode
= tgetstr ("ed", address
);
1466 TS_end_insert_mode
= tgetstr ("ei", address
);
1467 Home
= tgetstr ("ho", address
);
1468 TS_ins_char
= tgetstr ("ic", address
);
1469 TS_ins_multi_chars
= tgetstr ("IC", address
);
1470 TS_insert_mode
= tgetstr ("im", address
);
1471 TS_pad_inserted_char
= tgetstr ("ip", address
);
1472 TS_end_keypad_mode
= tgetstr ("ke", address
);
1473 TS_keypad_mode
= tgetstr ("ks", address
);
1474 LastLine
= tgetstr ("ll", address
);
1475 Right
= tgetstr ("nd", address
);
1476 Down
= tgetstr ("do", address
);
1478 Down
= tgetstr ("nl", address
); /* Obsolete name for "do" */
1480 /* VMS puts a carriage return before each linefeed,
1481 so it is not safe to use linefeeds. */
1482 if (Down
&& Down
[0] == '\n' && Down
[1] == '\0')
1485 if (tgetflag ("bs"))
1486 Left
= "\b"; /* can't possibly be longer! */
1487 else /* (Actually, "bs" is obsolete...) */
1488 Left
= tgetstr ("le", address
);
1490 Left
= tgetstr ("bc", address
); /* Obsolete name for "le" */
1491 TS_pad_char
= tgetstr ("pc", address
);
1492 TS_repeat
= tgetstr ("rp", address
);
1493 TS_end_standout_mode
= tgetstr ("se", address
);
1494 TS_fwd_scroll
= tgetstr ("sf", address
);
1495 TS_standout_mode
= tgetstr ("so", address
);
1496 TS_rev_scroll
= tgetstr ("sr", address
);
1497 Wcm
.cm_tab
= tgetstr ("ta", address
);
1498 TS_end_termcap_modes
= tgetstr ("te", address
);
1499 TS_termcap_modes
= tgetstr ("ti", address
);
1500 Up
= tgetstr ("up", address
);
1501 TS_visible_bell
= tgetstr ("vb", address
);
1502 TS_end_visual_mode
= tgetstr ("ve", address
);
1503 TS_visual_mode
= tgetstr ("vs", address
);
1504 TS_set_window
= tgetstr ("wi", address
);
1505 MultiUp
= tgetstr ("UP", address
);
1506 MultiDown
= tgetstr ("DO", address
);
1507 MultiLeft
= tgetstr ("LE", address
);
1508 MultiRight
= tgetstr ("RI", address
);
1510 AutoWrap
= tgetflag ("am");
1511 memory_below_frame
= tgetflag ("db");
1512 TF_hazeltine
= tgetflag ("hz");
1513 must_write_spaces
= tgetflag ("in");
1514 meta_key
= tgetflag ("km") || tgetflag ("MT");
1515 TF_insmode_motion
= tgetflag ("mi");
1516 TF_standout_motion
= tgetflag ("ms");
1517 TF_underscore
= tgetflag ("ul");
1518 MagicWrap
= tgetflag ("xn");
1519 TF_xs
= tgetflag ("xs");
1520 TF_teleray
= tgetflag ("xt");
1522 term_get_fkeys (address
);
1524 /* Get frame size from system, or else from termcap. */
1525 get_frame_size (&FRAME_WIDTH (selected_frame
),
1526 &FRAME_HEIGHT (selected_frame
));
1527 if (FRAME_WIDTH (selected_frame
) <= 0)
1528 FRAME_WIDTH (selected_frame
) = tgetnum ("co");
1529 if (FRAME_HEIGHT (selected_frame
) <= 0)
1530 FRAME_HEIGHT (selected_frame
) = tgetnum ("li");
1532 min_padding_speed
= tgetnum ("pb");
1533 TN_standout_width
= tgetnum ("sg");
1534 TabWidth
= tgetnum ("tw");
1537 /* These capabilities commonly use ^J.
1538 I don't know why, but sending them on VMS does not work;
1539 it causes following spaces to be lost, sometimes.
1540 For now, the simplest fix is to avoid using these capabilities ever. */
1541 if (Down
&& Down
[0] == '\n')
1549 TS_fwd_scroll
= Down
;
1551 PC
= TS_pad_char
? *TS_pad_char
: 0;
1556 /* Turned off since /etc/termcap seems to have :ta= for most terminals
1557 and newer termcap doc does not seem to say there is a default.
1562 if (TS_standout_mode
== 0)
1564 TN_standout_width
= tgetnum ("ug");
1565 TS_end_standout_mode
= tgetstr ("ue", address
);
1566 TS_standout_mode
= tgetstr ("us", address
);
1569 /* If no `se' string, try using a `me' string instead.
1570 If that fails, we can't use standout mode at all. */
1571 if (TS_end_standout_mode
== 0)
1573 char *s
= tgetstr ("me", address
);
1575 TS_end_standout_mode
= s
;
1577 TS_standout_mode
= 0;
1583 /* Teleray: most programs want a space in front of TS_standout_mode,
1584 but Emacs can do without it (and give one extra column). */
1585 TS_standout_mode
= "\033RD";
1586 TN_standout_width
= 1;
1587 /* But that means we cannot rely on ^M to go to column zero! */
1589 /* LF can't be trusted either -- can alter hpos */
1590 /* if move at column 0 thru a line with TS_standout_mode */
1594 /* Special handling for certain terminal types known to need it */
1596 if (!strcmp (terminal_type
, "supdup"))
1598 memory_below_frame
= 1;
1599 Wcm
.cm_losewrap
= 1;
1601 if (!strncmp (terminal_type
, "c10", 3)
1602 || !strcmp (terminal_type
, "perq"))
1604 /* Supply a makeshift :wi string.
1605 This string is not valid in general since it works only
1606 for windows starting at the upper left corner;
1607 but that is all Emacs uses.
1609 This string works only if the frame is using
1610 the top of the video memory, because addressing is memory-relative.
1611 So first check the :ti string to see if that is true.
1613 It would be simpler if the :wi string could go in the termcap
1614 entry, but it can't because it is not fully valid.
1615 If it were in the termcap entry, it would confuse other programs. */
1618 p
= TS_termcap_modes
;
1619 while (*p
&& strcmp (p
, "\033v "))
1622 TS_set_window
= "\033v%C %C %C %C ";
1624 /* Termcap entry often fails to have :in: flag */
1625 must_write_spaces
= 1;
1626 /* :ti string typically fails to have \E^G! in it */
1627 /* This limits scope of insert-char to one line. */
1628 strcpy (area
, TS_termcap_modes
);
1629 strcat (area
, "\033\007!");
1630 TS_termcap_modes
= area
;
1631 area
+= strlen (area
) + 1;
1633 /* Change all %+ parameters to %C, to handle
1634 values above 96 correctly for the C100. */
1637 if (p
[0] == '%' && p
[1] == '+')
1643 FrameRows
= FRAME_HEIGHT (selected_frame
);
1644 FrameCols
= FRAME_WIDTH (selected_frame
);
1645 specified_window
= FRAME_HEIGHT (selected_frame
);
1647 if (Wcm_init () == -1) /* can't do cursor motion */
1649 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1650 It lacks the ability to position the cursor.\n\
1651 If that is not the actual type of terminal you have, use either the\n\
1652 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
1653 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.\n",
1656 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1657 It lacks the ability to position the cursor.\n\
1658 If that is not the actual type of terminal you have,\n\
1659 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1660 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1661 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.\n",
1664 if (FRAME_HEIGHT (selected_frame
) <= 0
1665 || FRAME_WIDTH (selected_frame
) <= 0)
1666 fatal ("The frame size has not been specified.");
1668 delete_in_insert_mode
1669 = TS_delete_mode
&& TS_insert_mode
1670 && !strcmp (TS_delete_mode
, TS_insert_mode
);
1672 se_is_so
= (TS_standout_mode
1673 && TS_end_standout_mode
1674 && !strcmp (TS_standout_mode
, TS_end_standout_mode
));
1676 /* Remove width of standout marker from usable width of line */
1677 if (TN_standout_width
> 0)
1678 FRAME_WIDTH (selected_frame
) -= TN_standout_width
;
1680 UseTabs
= tabs_safe_p () && TabWidth
== 8;
1684 && (TS_set_window
|| TS_set_scroll_region
|| TS_set_scroll_region_1
));
1686 line_ins_del_ok
= (((TS_ins_line
|| TS_ins_multi_lines
)
1687 && (TS_del_line
|| TS_del_multi_lines
))
1688 || (scroll_region_ok
&& TS_fwd_scroll
&& TS_rev_scroll
));
1690 char_ins_del_ok
= ((TS_ins_char
|| TS_insert_mode
1691 || TS_pad_inserted_char
|| TS_ins_multi_chars
)
1692 && (TS_del_char
|| TS_del_multi_chars
));
1694 fast_clear_end_of_line
= TS_clr_line
!= 0;
1697 if (read_socket_hook
) /* Baudrate is somewhat */
1698 /* meaningless in this case */
1701 FRAME_CAN_HAVE_SCROLL_BARS (selected_frame
) = 0;
1702 FRAME_HAS_VERTICAL_SCROLL_BARS (selected_frame
) = 0;
1706 fatal (str
, arg1
, arg2
)
1707 char *str
, *arg1
, *arg2
;
1709 fprintf (stderr
, "emacs: ");
1710 fprintf (stderr
, str
, arg1
, arg2
);
1717 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
1718 "Non-nil means the system uses terminfo rather than termcap.\n\
1719 This variable can be used by terminal emulator packages.");
1721 system_uses_terminfo
= 1;
1723 system_uses_terminfo
= 0;