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 scroll_region_cost
; /* Cost of setting a scroll window,
58 measured in characters */
59 int memory_below_frame
; /* Terminal remembers lines
60 scrolled off bottom */
61 int fast_clear_end_of_line
; /* Terminal has a `ce' string */
63 /* Nonzero means no need to redraw the entire frame on resuming
64 a suspended Emacs. This is useful on terminals with multiple pages,
65 where one page is used for Emacs and another for all else. */
66 int no_redraw_on_reenter
;
68 /* Hook functions that you can set to snap out the functions in this file.
69 These are all extern'd in termhooks.h */
71 int (*cursor_to_hook
) ();
72 int (*raw_cursor_to_hook
) ();
74 int (*clear_to_end_hook
) ();
75 int (*clear_frame_hook
) ();
76 int (*clear_end_of_line_hook
) ();
78 int (*ins_del_lines_hook
) ();
80 int (*change_line_highlight_hook
) ();
81 int (*reassert_line_highlight_hook
) ();
83 int (*insert_glyphs_hook
) ();
84 int (*write_glyphs_hook
) ();
85 int (*delete_glyphs_hook
) ();
87 int (*ring_bell_hook
) ();
89 int (*reset_terminal_modes_hook
) ();
90 int (*set_terminal_modes_hook
) ();
91 int (*update_begin_hook
) ();
92 int (*update_end_hook
) ();
93 int (*set_terminal_window_hook
) ();
95 int (*read_socket_hook
) ();
97 int (*frame_up_to_date_hook
) ();
99 /* Return the current position of the mouse.
101 Set *f to the frame the mouse is in, or zero if the mouse is in no
102 Emacs frame. If it is set to zero, all the other arguments are
105 If the motion started in a scroll bar, set *bar_window to the
106 scroll bar's window, *part to the part the mouse is currently over,
107 *x to the position of the mouse along the scroll bar, and *y to the
108 overall length of the scroll bar.
110 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
111 row of the character cell the mouse is over.
113 Set *time to the time the mouse was at the returned position.
115 This should clear mouse_moved until the next motion
117 void (*mouse_position_hook
) ( /* FRAME_PTR *f,
118 Lisp_Object *bar_window,
119 enum scroll_bar_part *part,
122 unsigned long *time */ );
124 /* When reading from a minibuffer in a different frame, Emacs wants
125 to shift the highlight from the selected frame to the minibuffer's
126 frame; under X, this means it lies about where the focus is.
127 This hook tells the window system code to re-decide where to put
129 void (*frame_rehighlight_hook
) ( /* FRAME_PTR f */ );
131 /* If we're displaying frames using a window system that can stack
132 frames on top of each other, this hook allows you to bring a frame
133 to the front, or bury it behind all the other windows. If this
134 hook is zero, that means the device we're displaying on doesn't
135 support overlapping frames, so there's no need to raise or lower
138 If RAISE is non-zero, F is brought to the front, before all other
139 windows. If RAISE is zero, F is sent to the back, behind all other
141 void (*frame_raise_lower_hook
) ( /* FRAME_PTR f, int raise */ );
143 /* Set the vertical scroll bar for WINDOW to have its upper left corner
144 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
145 indicate that we are displaying PORTION characters out of a total
146 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
147 have a scroll bar, create one for it. */
148 void (*set_vertical_scroll_bar_hook
)
149 ( /* struct window *window,
150 int portion, int whole, int position */ );
153 /* The following three hooks are used when we're doing a thorough
154 redisplay of the frame. We don't explicitly know which scroll bars
155 are going to be deleted, because keeping track of when windows go
156 away is a real pain - can you say set-window-configuration?
157 Instead, we just assert at the beginning of redisplay that *all*
158 scroll bars are to be removed, and then save scroll bars from the
159 firey pit when we actually redisplay their window. */
161 /* Arrange for all scroll bars on FRAME to be removed at the next call
162 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
163 `*redeem_scroll_bar_hook' is applied to its window before the judgement.
165 This should be applied to each frame each time its window tree is
166 redisplayed, even if it is not displaying scroll bars at the moment;
167 if the HAS_SCROLL_BARS flag has just been turned off, only calling
168 this and the judge_scroll_bars_hook will get rid of them.
170 If non-zero, this hook should be safe to apply to any frame,
171 whether or not it can support scroll bars, and whether or not it is
172 currently displaying them. */
173 void (*condemn_scroll_bars_hook
)( /* FRAME_PTR *frame */ );
175 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
176 Note that it's okay to redeem a scroll bar that is not condemned. */
177 void (*redeem_scroll_bar_hook
)( /* struct window *window */ );
179 /* Remove all scroll bars on FRAME that haven't been saved since the
180 last call to `*condemn_scroll_bars_hook'.
182 This should be applied to each frame after each time its window
183 tree is redisplayed, even if it is not displaying scroll bars at the
184 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
185 calling this and condemn_scroll_bars_hook will get rid of them.
187 If non-zero, this hook should be safe to apply to any frame,
188 whether or not it can support scroll bars, and whether or not it is
189 currently displaying them. */
190 void (*judge_scroll_bars_hook
)( /* FRAME_PTR *FRAME */ );
193 /* Strings, numbers and flags taken from the termcap entry. */
195 char *TS_ins_line
; /* termcap "al" */
196 char *TS_ins_multi_lines
; /* "AL" (one parameter, # lines to insert) */
197 char *TS_bell
; /* "bl" */
198 char *TS_clr_to_bottom
; /* "cd" */
199 char *TS_clr_line
; /* "ce", clear to end of line */
200 char *TS_clr_frame
; /* "cl" */
201 char *TS_set_scroll_region
; /* "cs" (2 params, first line and last line) */
202 char *TS_set_scroll_region_1
; /* "cS" (4 params: total lines,
203 lines above scroll region, lines below it,
204 total lines again) */
205 char *TS_del_char
; /* "dc" */
206 char *TS_del_multi_chars
; /* "DC" (one parameter, # chars to delete) */
207 char *TS_del_line
; /* "dl" */
208 char *TS_del_multi_lines
; /* "DL" (one parameter, # lines to delete) */
209 char *TS_delete_mode
; /* "dm", enter character-delete mode */
210 char *TS_end_delete_mode
; /* "ed", leave character-delete mode */
211 char *TS_end_insert_mode
; /* "ei", leave character-insert mode */
212 char *TS_ins_char
; /* "ic" */
213 char *TS_ins_multi_chars
; /* "IC" (one parameter, # chars to insert) */
214 char *TS_insert_mode
; /* "im", enter character-insert mode */
215 char *TS_pad_inserted_char
; /* "ip". Just padding, no commands. */
216 char *TS_end_keypad_mode
; /* "ke" */
217 char *TS_keypad_mode
; /* "ks" */
218 char *TS_pad_char
; /* "pc", char to use as padding */
219 char *TS_repeat
; /* "rp" (2 params, # times to repeat
220 and character to be repeated) */
221 char *TS_end_standout_mode
; /* "se" */
222 char *TS_fwd_scroll
; /* "sf" */
223 char *TS_standout_mode
; /* "so" */
224 char *TS_rev_scroll
; /* "sr" */
225 char *TS_end_termcap_modes
; /* "te" */
226 char *TS_termcap_modes
; /* "ti" */
227 char *TS_visible_bell
; /* "vb" */
228 char *TS_end_visual_mode
; /* "ve" */
229 char *TS_visual_mode
; /* "vi" */
230 char *TS_set_window
; /* "wi" (4 params, start and end of window,
231 each as vpos and hpos) */
233 int TF_hazeltine
; /* termcap hz flag. */
234 int TF_insmode_motion
; /* termcap mi flag: can move while in insert mode. */
235 int TF_standout_motion
; /* termcap mi flag: can move while in standout mode. */
236 int TF_underscore
; /* termcap ul flag: _ underlines if overstruck on
237 nonblank position. Must clear before writing _. */
238 int TF_teleray
; /* termcap xt flag: many weird consequences.
241 int TF_xs
; /* Nonzero for "xs". If set together with
242 TN_standout_width == 0, it means don't bother
243 to write any end-standout cookies. */
245 int TN_standout_width
; /* termcap sg number: width occupied by standout
248 static int RPov
; /* # chars to start a TS_repeat */
250 static int delete_in_insert_mode
; /* delete mode == insert mode */
252 static int se_is_so
; /* 1 if same string both enters and leaves
257 /* Number of chars of space used for standout marker at beginning of line,
258 or'd with 0100. Zero if no standout marker at all.
260 Used IFF TN_standout_width >= 0. */
262 static char *chars_wasted
;
263 static char *copybuf
;
265 /* nonzero means supposed to write text in standout mode. */
266 int standout_requested
;
268 int insert_mode
; /* Nonzero when in insert mode. */
269 int standout_mode
; /* Nonzero when in standout mode. */
271 /* Size of window specified by higher levels.
272 This is the number of lines, from the top of frame downwards,
273 which can participate in insert-line/delete-line operations.
275 Effectively it excludes the bottom frame_height - specified_window_size
276 lines from those operations. */
278 int specified_window
;
280 /* Frame currently being redisplayed; 0 if not currently redisplaying.
281 (Direct output does not count). */
283 FRAME_PTR updating_frame
;
285 /* Provided for lisp packages. */
286 static int system_uses_terminfo
;
290 extern char *tgetstr ();
294 /* We aren't X windows, but we aren't termcap either. This makes me
295 uncertain as to what value to use for frame.output_method. For
296 this file, we'll define FRAME_TERMCAP_P to be zero so that our
297 output hooks get called instead of the termcap functions. Probably
298 the best long-term solution is to define an output_windows_nt... */
300 #undef FRAME_TERMCAP_P
301 #define FRAME_TERMCAP_P(_f_) 0
302 #endif /* WINDOWSNT */
306 if (! FRAME_TERMCAP_P (selected_frame
))
308 (*ring_bell_hook
) ();
311 OUTPUT (TS_visible_bell
&& visible_bell
? TS_visible_bell
: TS_bell
);
314 set_terminal_modes ()
316 if (! FRAME_TERMCAP_P (selected_frame
))
318 (*set_terminal_modes_hook
) ();
321 OUTPUT_IF (TS_termcap_modes
);
322 OUTPUT_IF (TS_visual_mode
);
323 OUTPUT_IF (TS_keypad_mode
);
327 reset_terminal_modes ()
329 if (! FRAME_TERMCAP_P (selected_frame
))
331 (*reset_terminal_modes_hook
) ();
334 if (TN_standout_width
< 0)
335 turn_off_highlight ();
337 OUTPUT_IF (TS_end_keypad_mode
);
338 OUTPUT_IF (TS_end_visual_mode
);
339 OUTPUT_IF (TS_end_termcap_modes
);
340 /* Output raw CR so kernel can track the cursor hpos. */
341 /* But on magic-cookie terminals this can erase an end-standout marker and
342 cause the rest of the frame to be in standout, so move down first. */
343 if (TN_standout_width
>= 0)
352 if (! FRAME_TERMCAP_P (updating_frame
))
353 (*update_begin_hook
) (f
);
359 if (! FRAME_TERMCAP_P (updating_frame
))
361 (*update_end_hook
) (f
);
366 background_highlight ();
367 standout_requested
= 0;
371 set_terminal_window (size
)
374 if (! FRAME_TERMCAP_P (updating_frame
))
376 (*set_terminal_window_hook
) (size
);
379 specified_window
= size
? size
: FRAME_HEIGHT (selected_frame
);
380 if (!scroll_region_ok
)
382 set_scroll_region (0, specified_window
);
385 set_scroll_region (start
, stop
)
389 if (TS_set_scroll_region
)
391 buf
= tparam (TS_set_scroll_region
, 0, 0, start
, stop
- 1);
393 else if (TS_set_scroll_region_1
)
395 buf
= tparam (TS_set_scroll_region_1
, 0, 0,
396 FRAME_HEIGHT (selected_frame
), start
,
397 FRAME_HEIGHT (selected_frame
) - stop
,
398 FRAME_HEIGHT (selected_frame
));
402 buf
= tparam (TS_set_window
, 0, 0, start
, 0, stop
, FRAME_WIDTH (selected_frame
));
412 OUTPUT (TS_insert_mode
);
419 OUTPUT (TS_end_insert_mode
);
423 /* Handle highlighting when TN_standout_width (termcap sg) is not specified.
424 In these terminals, output is affected by the value of standout
425 mode when the output is written.
427 These functions are called on all terminals, but do nothing
428 on terminals whose standout mode does not work that way. */
430 turn_off_highlight ()
432 if (TN_standout_width
< 0)
435 OUTPUT_IF (TS_end_standout_mode
);
442 if (TN_standout_width
< 0)
445 OUTPUT_IF (TS_standout_mode
);
450 /* Set standout mode to the state it should be in for
451 empty space inside windows. What this is,
452 depends on the user option inverse-video. */
454 background_highlight ()
456 if (TN_standout_width
>= 0)
459 turn_on_highlight ();
461 turn_off_highlight ();
464 /* Set standout mode to the mode specified for the text to be output. */
467 highlight_if_desired ()
469 if (TN_standout_width
>= 0)
471 if (!inverse_video
== !standout_requested
)
472 turn_off_highlight ();
474 turn_on_highlight ();
477 /* Handle standout mode for terminals in which TN_standout_width >= 0.
478 On these terminals, standout is controlled by markers that
479 live inside the terminal's memory. TN_standout_width is the width
480 that the marker occupies in memory. Standout runs from the marker
481 to the end of the line on some terminals, or to the next
482 turn-off-standout marker (TS_end_standout_mode) string
483 on other terminals. */
485 /* Write a standout marker or end-standout marker at the front of the line
486 at vertical position vpos. */
488 write_standout_marker (flag
, vpos
)
491 if (flag
|| (TS_end_standout_mode
&& !TF_teleray
&& !se_is_so
492 && !(TF_xs
&& TN_standout_width
== 0)))
495 cmplus (TN_standout_width
);
496 OUTPUT (flag
? TS_standout_mode
: TS_end_standout_mode
);
497 chars_wasted
[curY
] = TN_standout_width
| 0100;
501 /* External interface to control of standout mode.
502 Call this when about to modify line at position VPOS
503 and not change whether it is highlighted. */
505 reassert_line_highlight (highlight
, vpos
)
509 if (! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
511 (*reassert_line_highlight_hook
) (highlight
, vpos
);
514 if (TN_standout_width
< 0)
515 /* Handle terminals where standout takes affect at output time */
516 standout_requested
= highlight
;
517 else if (chars_wasted
[vpos
] == 0)
518 /* For terminals with standout markers, write one on this line
519 if there isn't one already. */
520 write_standout_marker (highlight
, vpos
);
523 /* Call this when about to modify line at position VPOS
524 and change whether it is highlighted. */
526 change_line_highlight (new_highlight
, vpos
, first_unused_hpos
)
527 int new_highlight
, vpos
, first_unused_hpos
;
529 standout_requested
= new_highlight
;
530 if (! FRAME_TERMCAP_P (updating_frame
))
532 (*change_line_highlight_hook
) (new_highlight
, vpos
, first_unused_hpos
);
538 if (TN_standout_width
< 0)
539 background_highlight ();
540 /* If line starts with a marker, delete the marker */
541 else if (TS_clr_line
&& chars_wasted
[curY
])
544 /* On Teleray, make sure to erase the SO marker. */
547 cmgoto (curY
- 1, FRAME_WIDTH (selected_frame
) - 4);
549 curY
++; /* ESC S moves to next line where the TS_standout_mode was */
553 cmgoto (curY
, 0); /* reposition to kill standout marker */
555 clear_end_of_line_raw (first_unused_hpos
);
556 reassert_line_highlight (new_highlight
, curY
);
560 /* Move to absolute position, specified origin 0 */
565 if (! FRAME_TERMCAP_P ((updating_frame
570 (*cursor_to_hook
) (row
, col
);
574 col
+= chars_wasted
[row
] & 077;
575 if (curY
== row
&& curX
== col
)
577 if (!TF_standout_motion
)
578 background_highlight ();
579 if (!TF_insmode_motion
)
584 /* Similar but don't take any account of the wasted characters. */
586 raw_cursor_to (row
, col
)
589 if (! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
591 (*raw_cursor_to_hook
) (row
, col
);
594 if (curY
== row
&& curX
== col
)
596 if (!TF_standout_motion
)
597 background_highlight ();
598 if (!TF_insmode_motion
)
603 /* Erase operations */
605 /* clear from cursor to end of frame */
610 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
612 (*clear_to_end_hook
) ();
615 if (TS_clr_to_bottom
)
617 background_highlight ();
618 OUTPUT (TS_clr_to_bottom
);
619 bzero (chars_wasted
+ curY
, FRAME_HEIGHT (selected_frame
) - curY
);
623 for (i
= curY
; i
< FRAME_HEIGHT (selected_frame
); i
++)
626 clear_end_of_line_raw (FRAME_WIDTH (selected_frame
));
631 /* Clear entire frame */
636 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
638 (*clear_frame_hook
) ();
643 background_highlight ();
644 OUTPUT (TS_clr_frame
);
645 bzero (chars_wasted
, FRAME_HEIGHT (selected_frame
));
655 /* Clear to end of line, but do not clear any standout marker.
656 Assumes that the cursor is positioned at a character of real text,
657 which implies it cannot be before a standout marker
658 unless the marker has zero width.
660 Note that the cursor may be moved. */
662 clear_end_of_line (first_unused_hpos
)
663 int first_unused_hpos
;
665 static GLYPH buf
= SPACEGLYPH
;
666 if (FRAME_TERMCAP_P (selected_frame
)
667 && TN_standout_width
== 0 && curX
== 0 && chars_wasted
[curY
] != 0)
668 write_glyphs (&buf
, 1);
669 clear_end_of_line_raw (first_unused_hpos
);
672 /* Clear from cursor to end of line.
673 Assume that the line is already clear starting at column first_unused_hpos.
674 If the cursor is at a standout marker, erase the marker.
676 Note that the cursor may be moved, on terminals lacking a `ce' string. */
678 clear_end_of_line_raw (first_unused_hpos
)
679 int first_unused_hpos
;
683 if (clear_end_of_line_hook
684 && ! FRAME_TERMCAP_P ((updating_frame
688 (*clear_end_of_line_hook
) (first_unused_hpos
);
692 first_unused_hpos
+= chars_wasted
[curY
] & 077;
693 if (curX
>= first_unused_hpos
)
695 /* Notice if we are erasing a magic cookie */
697 chars_wasted
[curY
] = 0;
698 background_highlight ();
701 OUTPUT1 (TS_clr_line
);
704 { /* have to do it the hard way */
707 /* Do not write in last row last col with Autowrap on. */
708 if (AutoWrap
&& curY
== FRAME_HEIGHT (selected_frame
) - 1
709 && first_unused_hpos
== FRAME_WIDTH (selected_frame
))
712 for (i
= curX
; i
< first_unused_hpos
; i
++)
715 fputc (' ', termscript
);
718 cmplus (first_unused_hpos
- curX
);
723 write_glyphs (string
, len
)
724 register GLYPH
*string
;
728 register int tlen
= GLYPH_TABLE_LENGTH
;
729 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
731 if (write_glyphs_hook
732 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
734 (*write_glyphs_hook
) (string
, len
);
738 highlight_if_desired ();
741 /* Don't dare write in last column of bottom line, if AutoWrap,
742 since that would scroll the whole frame on some terminals. */
745 && curY
+ 1 == FRAME_HEIGHT (selected_frame
)
746 && (curX
+ len
- (chars_wasted
[curY
] & 077)
747 == FRAME_WIDTH (selected_frame
)))
754 /* Check quickly for G beyond length of table.
755 That implies it isn't an alias and is simple. */
759 putc (g
& 0xff, stdout
);
763 putc (g
& 0xff, termscript
);
767 /* G has an entry in Vglyph_table,
768 so process any alias and then test for simpleness. */
769 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
770 g
= GLYPH_ALIAS (tbase
, g
);
771 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
775 /* Here if G (or its definition as an alias) is not simple. */
776 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
),
781 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
);
856 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
858 (*delete_glyphs_hook
) (n
);
862 if (delete_in_insert_mode
)
869 OUTPUT_IF (TS_delete_mode
);
872 if (TS_del_multi_chars
)
874 buf
= tparam (TS_del_multi_chars
, 0, 0, n
);
879 for (i
= 0; i
< n
; i
++)
880 OUTPUT1 (TS_del_char
);
881 if (!delete_in_insert_mode
)
882 OUTPUT_IF (TS_end_delete_mode
);
885 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
887 ins_del_lines (vpos
, n
)
890 char *multi
= n
> 0 ? TS_ins_multi_lines
: TS_del_multi_lines
;
891 char *single
= n
> 0 ? TS_ins_line
: TS_del_line
;
892 char *scroll
= n
> 0 ? TS_rev_scroll
: TS_fwd_scroll
;
894 register int i
= n
> 0 ? n
: -n
;
897 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
899 (*ins_del_lines_hook
) (vpos
, n
);
903 /* If the lines below the insertion are being pushed
904 into the end of the window, this is the same as clearing;
905 and we know the lines are already clear, since the matching
906 deletion has already been done. So can ignore this. */
907 /* If the lines below the deletion are blank lines coming
908 out of the end of the window, don't bother,
909 as there will be a matching inslines later that will flush them. */
910 if (scroll_region_ok
&& vpos
+ i
>= specified_window
)
912 if (!memory_below_frame
&& vpos
+ i
>= FRAME_HEIGHT (selected_frame
))
917 raw_cursor_to (vpos
, 0);
918 background_highlight ();
919 buf
= tparam (multi
, 0, 0, i
);
925 raw_cursor_to (vpos
, 0);
926 background_highlight ();
934 set_scroll_region (vpos
, specified_window
);
936 raw_cursor_to (specified_window
- 1, 0);
938 raw_cursor_to (vpos
, 0);
939 background_highlight ();
941 OUTPUTL (scroll
, specified_window
- vpos
);
942 set_scroll_region (0, specified_window
);
945 if (TN_standout_width
>= 0)
950 : FRAME_HEIGHT (selected_frame
));
954 bcopy (&chars_wasted
[vpos
- n
], &chars_wasted
[vpos
],
955 lower_limit
- vpos
+ n
);
956 bzero (&chars_wasted
[lower_limit
+ n
], - n
);
960 bcopy (&chars_wasted
[vpos
], ©buf
[vpos
], lower_limit
- vpos
- n
);
961 bcopy (©buf
[vpos
], &chars_wasted
[vpos
+ n
],
962 lower_limit
- vpos
- n
);
963 bzero (&chars_wasted
[vpos
], n
);
966 if (!scroll_region_ok
&& memory_below_frame
&& n
< 0)
968 cursor_to (FRAME_HEIGHT (selected_frame
) + n
, 0);
973 /* Compute cost of sending "str", in characters,
974 not counting any line-dependent padding. */
982 tputs (str
, 0, evalcost
);
986 /* Compute cost of sending "str", in characters,
987 counting any line-dependent padding at one line. */
990 string_cost_one_line (str
)
995 tputs (str
, 1, evalcost
);
999 /* Compute per line amount of line-dependent padding,
1000 in tenths of characters. */
1008 tputs (str
, 0, evalcost
);
1011 tputs (str
, 10, evalcost
);
1016 /* char_ins_del_cost[n] is cost of inserting N characters.
1017 char_ins_del_cost[-n] is cost of deleting N characters. */
1019 int *char_ins_del_vector
;
1021 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH ((f))])
1026 calculate_ins_del_char_costs (frame
)
1029 int ins_startup_cost
, del_startup_cost
;
1030 int ins_cost_per_char
, del_cost_per_char
;
1034 if (TS_ins_multi_chars
)
1036 ins_cost_per_char
= 0;
1037 ins_startup_cost
= string_cost_one_line (TS_ins_multi_chars
);
1039 else if (TS_ins_char
|| TS_pad_inserted_char
1040 || (TS_insert_mode
&& TS_end_insert_mode
))
1042 ins_startup_cost
= (30 * (string_cost (TS_insert_mode
)
1043 + string_cost (TS_end_insert_mode
))) / 100;
1044 ins_cost_per_char
= (string_cost_one_line (TS_ins_char
)
1045 + string_cost_one_line (TS_pad_inserted_char
));
1049 ins_startup_cost
= 9999;
1050 ins_cost_per_char
= 0;
1053 if (TS_del_multi_chars
)
1055 del_cost_per_char
= 0;
1056 del_startup_cost
= string_cost_one_line (TS_del_multi_chars
);
1058 else if (TS_del_char
)
1060 del_startup_cost
= (string_cost (TS_delete_mode
)
1061 + string_cost (TS_end_delete_mode
));
1062 if (delete_in_insert_mode
)
1063 del_startup_cost
/= 2;
1064 del_cost_per_char
= string_cost_one_line (TS_del_char
);
1068 del_startup_cost
= 9999;
1069 del_cost_per_char
= 0;
1072 /* Delete costs are at negative offsets */
1073 p
= &char_ins_del_cost (frame
)[0];
1074 for (i
= FRAME_WIDTH (selected_frame
); --i
>= 0;)
1075 *--p
= (del_startup_cost
+= del_cost_per_char
);
1077 /* Doing nothing is free */
1078 p
= &char_ins_del_cost (frame
)[0];
1081 /* Insert costs are at positive offsets */
1082 for (i
= FRAME_WIDTH (frame
); --i
>= 0;)
1083 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1086 extern do_line_insertion_deletion_costs ();
1088 calculate_costs (frame
)
1091 register char *f
= (TS_set_scroll_region
1092 ? TS_set_scroll_region
1093 : TS_set_scroll_region_1
);
1095 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1097 scroll_region_cost
= string_cost (f
);
1098 #ifdef HAVE_X_WINDOWS
1099 if (FRAME_X_P (frame
))
1101 do_line_insertion_deletion_costs (frame
, 0, ".5*", 0, ".5*",
1103 x_screen_planes (frame
));
1104 scroll_region_cost
= 0;
1109 /* These variables are only used for terminal stuff. They are allocated
1110 once for the terminal frame of X-windows emacs, but not used afterwards.
1112 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1113 X turns off char_ins_del_ok.
1115 chars_wasted and copybuf are only used here in term.c in cases where
1116 the term hook isn't called. */
1118 if (chars_wasted
!= 0)
1119 chars_wasted
= (char *) xrealloc (chars_wasted
, FRAME_HEIGHT (frame
));
1121 chars_wasted
= (char *) xmalloc (FRAME_HEIGHT (frame
));
1124 copybuf
= (char *) xrealloc (copybuf
, FRAME_HEIGHT (frame
));
1126 copybuf
= (char *) xmalloc (FRAME_HEIGHT (frame
));
1128 if (char_ins_del_vector
!= 0)
1130 = (int *) xrealloc (char_ins_del_vector
,
1132 + 2 * FRAME_WIDTH (frame
) * sizeof (int)));
1135 = (int *) xmalloc (sizeof (int)
1136 + 2 * FRAME_WIDTH (frame
) * sizeof (int));
1138 bzero (chars_wasted
, FRAME_HEIGHT (frame
));
1139 bzero (copybuf
, FRAME_HEIGHT (frame
));
1140 bzero (char_ins_del_vector
, (sizeof (int)
1141 + 2 * FRAME_WIDTH (frame
) * sizeof (int)));
1143 if (f
&& (!TS_ins_line
&& !TS_del_line
))
1144 do_line_insertion_deletion_costs (frame
,
1145 TS_rev_scroll
, TS_ins_multi_lines
,
1146 TS_fwd_scroll
, TS_del_multi_lines
,
1149 do_line_insertion_deletion_costs (frame
,
1150 TS_ins_line
, TS_ins_multi_lines
,
1151 TS_del_line
, TS_del_multi_lines
,
1154 calculate_ins_del_char_costs (frame
);
1156 /* Don't use TS_repeat if its padding is worse than sending the chars */
1157 if (TS_repeat
&& per_line_cost (TS_repeat
) * baud_rate
< 9000)
1158 RPov
= string_cost (TS_repeat
);
1160 RPov
= FRAME_WIDTH (frame
) * 2;
1162 cmcostinit (); /* set up cursor motion costs */
1169 /* Termcap capability names that correspond directly to X keysyms.
1170 Some of these (marked "terminfo") aren't supplied by old-style
1171 (Berkeley) termcap entries. They're listed in X keysym order;
1172 except we put the keypad keys first, so that if they clash with
1173 other keys (as on the IBM PC keyboard) they get overridden.
1176 static struct fkey_table keys
[] = {
1177 "kh", "home", /* termcap */
1178 "kl", "left", /* termcap */
1179 "ku", "up", /* termcap */
1180 "kr", "right", /* termcap */
1181 "kd", "down", /* termcap */
1182 "%8", "prior", /* terminfo */
1183 "%5", "next", /* terminfo */
1184 "@7", "end", /* terminfo */
1185 "@1", "begin", /* terminfo */
1186 "*6", "select", /* terminfo */
1187 "%9", "print", /* terminfo */
1188 "@4", "execute", /* terminfo --- actually the `command' key */
1190 * "insert" --- see below
1192 "&8", "undo", /* terminfo */
1193 "%0", "redo", /* terminfo */
1194 "%7", "menu", /* terminfo --- actually the `options' key */
1195 "@0", "find", /* terminfo */
1196 "@2", "cancel", /* terminfo */
1197 "%1", "help", /* terminfo */
1199 * "break" goes here, but can't be reliably intercepted with termcap
1201 "&4", "reset", /* terminfo --- actually `restart' */
1203 * "system" and "user" --- no termcaps
1205 "kE", "clearline", /* terminfo */
1206 "kA", "insertline", /* terminfo */
1207 "kL", "deleteline", /* terminfo */
1208 "kI", "insertchar", /* terminfo */
1209 "kD", "deletechar", /* terminfo */
1210 "kB", "backtab", /* terminfo */
1212 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1214 "@8", "kp-enter", /* terminfo */
1216 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1217 * "kp-multiply", "kp-add", "kp-separator",
1218 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1219 * --- no termcaps for any of these.
1221 "K4", "kp-1", /* terminfo */
1223 * "kp-2" --- no termcap
1225 "K5", "kp-3", /* terminfo */
1227 * "kp-4" --- no termcap
1229 "K2", "kp-5", /* terminfo */
1231 * "kp-6" --- no termcap
1233 "K1", "kp-7", /* terminfo */
1235 * "kp-8" --- no termcap
1237 "K3", "kp-9", /* terminfo */
1239 * "kp-equal" --- no termcap
1252 static char **term_get_fkeys_arg
;
1253 static Lisp_Object
term_get_fkeys_1 ();
1255 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1256 This function scans the termcap function key sequence entries, and
1257 adds entries to Vfunction_key_map for each function key it finds. */
1260 term_get_fkeys (address
)
1263 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1264 errors during the call. The only errors should be from Fdefine_key
1265 when given a key sequence containing an invalid prefix key. If the
1266 termcap defines function keys which use a prefix that is already bound
1267 to a command by the default bindings, we should silently ignore that
1268 function key specification, rather than giving the user an error and
1269 refusing to run at all on such a terminal. */
1271 extern Lisp_Object
Fidentity ();
1272 term_get_fkeys_arg
= address
;
1273 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1281 char **address
= term_get_fkeys_arg
;
1283 /* This can happen if CANNOT_DUMP or with strange options. */
1285 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1287 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1289 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1291 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1292 Fmake_vector (make_number (1),
1293 intern (keys
[i
].name
)));
1296 /* The uses of the "k0" capability are inconsistent; sometimes it
1297 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1298 We will attempt to politely accommodate both systems by testing for
1299 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1302 char *k_semi
= tgetstr ("k;", address
);
1303 char *k0
= tgetstr ("k0", address
);
1304 char *k0_name
= "f10";
1308 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1309 Fmake_vector (make_number (1), intern ("f10")));
1314 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1315 Fmake_vector (make_number (1), intern (k0_name
)));
1318 /* Set up cookies for numbered function keys above f10. */
1320 char fcap
[3], fkey
[4];
1322 fcap
[0] = 'F'; fcap
[2] = '\0';
1323 for (i
= 11; i
< 64; i
++)
1326 fcap
[1] = '1' + i
- 11;
1328 fcap
[1] = 'A' + i
- 20;
1330 fcap
[1] = 'a' + i
- 46;
1333 char *sequence
= tgetstr (fcap
, address
);
1336 sprintf (fkey
, "f%d", i
);
1337 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1338 Fmake_vector (make_number (1),
1346 * Various mappings to try and get a better fit.
1349 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1350 if (!tgetstr (cap1, address)) \
1352 char *sequence = tgetstr (cap2, address); \
1354 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1355 Fmake_vector (make_number (1), \
1359 /* if there's no key_next keycap, map key_npage to `next' keysym */
1360 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1361 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1362 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1363 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1364 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1366 /* IBM has their own non-standard dialect of terminfo.
1367 If the standard name isn't found, try the IBM name. */
1368 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1369 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1370 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1371 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1372 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1373 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1374 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1375 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1376 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1377 #undef CONDITIONAL_REASSIGN
1382 term_init (terminal_type
)
1383 char *terminal_type
;
1386 char **address
= &area
;
1392 initialize_win_nt_display ();
1396 area
= (char *) malloc (2044);
1401 FrameRows
= FRAME_HEIGHT (selected_frame
);
1402 FrameCols
= FRAME_WIDTH (selected_frame
);
1403 specified_window
= FRAME_HEIGHT (selected_frame
);
1405 delete_in_insert_mode
= 1;
1408 scroll_region_ok
= 0;
1410 /* Seems to insert lines when it's not supposed to, messing
1411 up the display. In doing a trace, it didn't seem to be
1412 called much, so I don't think we're losing anything by
1415 line_ins_del_ok
= 0;
1416 char_ins_del_ok
= 1;
1420 FRAME_CAN_HAVE_SCROLL_BARS (selected_frame
) = 0;
1421 FRAME_HAS_VERTICAL_SCROLL_BARS (selected_frame
) = 0;
1424 #endif /* WINDOWSNT */
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 if (FRAME_HEIGHT (selected_frame
) < 3
1533 || FRAME_WIDTH (selected_frame
) < 3)
1534 fatal ("Screen size %dx%d is too small.\n",
1535 FRAME_HEIGHT (selected_frame
), FRAME_WIDTH (selected_frame
));
1537 min_padding_speed
= tgetnum ("pb");
1538 TN_standout_width
= tgetnum ("sg");
1539 TabWidth
= tgetnum ("tw");
1542 /* These capabilities commonly use ^J.
1543 I don't know why, but sending them on VMS does not work;
1544 it causes following spaces to be lost, sometimes.
1545 For now, the simplest fix is to avoid using these capabilities ever. */
1546 if (Down
&& Down
[0] == '\n')
1554 TS_fwd_scroll
= Down
;
1556 PC
= TS_pad_char
? *TS_pad_char
: 0;
1561 /* Turned off since /etc/termcap seems to have :ta= for most terminals
1562 and newer termcap doc does not seem to say there is a default.
1567 if (TS_standout_mode
== 0)
1569 TN_standout_width
= tgetnum ("ug");
1570 TS_end_standout_mode
= tgetstr ("ue", address
);
1571 TS_standout_mode
= tgetstr ("us", address
);
1574 /* If no `se' string, try using a `me' string instead.
1575 If that fails, we can't use standout mode at all. */
1576 if (TS_end_standout_mode
== 0)
1578 char *s
= tgetstr ("me", address
);
1580 TS_end_standout_mode
= s
;
1582 TS_standout_mode
= 0;
1588 /* Teleray: most programs want a space in front of TS_standout_mode,
1589 but Emacs can do without it (and give one extra column). */
1590 TS_standout_mode
= "\033RD";
1591 TN_standout_width
= 1;
1592 /* But that means we cannot rely on ^M to go to column zero! */
1594 /* LF can't be trusted either -- can alter hpos */
1595 /* if move at column 0 thru a line with TS_standout_mode */
1599 /* Special handling for certain terminal types known to need it */
1601 if (!strcmp (terminal_type
, "supdup"))
1603 memory_below_frame
= 1;
1604 Wcm
.cm_losewrap
= 1;
1606 if (!strncmp (terminal_type
, "c10", 3)
1607 || !strcmp (terminal_type
, "perq"))
1609 /* Supply a makeshift :wi string.
1610 This string is not valid in general since it works only
1611 for windows starting at the upper left corner;
1612 but that is all Emacs uses.
1614 This string works only if the frame is using
1615 the top of the video memory, because addressing is memory-relative.
1616 So first check the :ti string to see if that is true.
1618 It would be simpler if the :wi string could go in the termcap
1619 entry, but it can't because it is not fully valid.
1620 If it were in the termcap entry, it would confuse other programs. */
1623 p
= TS_termcap_modes
;
1624 while (*p
&& strcmp (p
, "\033v "))
1627 TS_set_window
= "\033v%C %C %C %C ";
1629 /* Termcap entry often fails to have :in: flag */
1630 must_write_spaces
= 1;
1631 /* :ti string typically fails to have \E^G! in it */
1632 /* This limits scope of insert-char to one line. */
1633 strcpy (area
, TS_termcap_modes
);
1634 strcat (area
, "\033\007!");
1635 TS_termcap_modes
= area
;
1636 area
+= strlen (area
) + 1;
1638 /* Change all %+ parameters to %C, to handle
1639 values above 96 correctly for the C100. */
1642 if (p
[0] == '%' && p
[1] == '+')
1648 FrameRows
= FRAME_HEIGHT (selected_frame
);
1649 FrameCols
= FRAME_WIDTH (selected_frame
);
1650 specified_window
= FRAME_HEIGHT (selected_frame
);
1652 if (Wcm_init () == -1) /* can't do cursor motion */
1654 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1655 It lacks the ability to position the cursor.\n\
1656 If that is not the actual type of terminal you have, use either the\n\
1657 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
1658 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.\n",
1661 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1662 It lacks the ability to position the cursor.\n\
1663 If that is not the actual type of terminal you have,\n\
1664 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1665 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1666 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.\n",
1669 if (FRAME_HEIGHT (selected_frame
) <= 0
1670 || FRAME_WIDTH (selected_frame
) <= 0)
1671 fatal ("The frame size has not been specified.");
1673 delete_in_insert_mode
1674 = TS_delete_mode
&& TS_insert_mode
1675 && !strcmp (TS_delete_mode
, TS_insert_mode
);
1677 se_is_so
= (TS_standout_mode
1678 && TS_end_standout_mode
1679 && !strcmp (TS_standout_mode
, TS_end_standout_mode
));
1681 /* Remove width of standout marker from usable width of line */
1682 if (TN_standout_width
> 0)
1683 FRAME_WIDTH (selected_frame
) -= TN_standout_width
;
1685 UseTabs
= tabs_safe_p () && TabWidth
== 8;
1689 && (TS_set_window
|| TS_set_scroll_region
|| TS_set_scroll_region_1
));
1691 line_ins_del_ok
= (((TS_ins_line
|| TS_ins_multi_lines
)
1692 && (TS_del_line
|| TS_del_multi_lines
))
1693 || (scroll_region_ok
&& TS_fwd_scroll
&& TS_rev_scroll
));
1695 char_ins_del_ok
= ((TS_ins_char
|| TS_insert_mode
1696 || TS_pad_inserted_char
|| TS_ins_multi_chars
)
1697 && (TS_del_char
|| TS_del_multi_chars
));
1699 fast_clear_end_of_line
= TS_clr_line
!= 0;
1702 if (read_socket_hook
) /* Baudrate is somewhat */
1703 /* meaningless in this case */
1706 FRAME_CAN_HAVE_SCROLL_BARS (selected_frame
) = 0;
1707 FRAME_HAS_VERTICAL_SCROLL_BARS (selected_frame
) = 0;
1711 fatal (str
, arg1
, arg2
)
1712 char *str
, *arg1
, *arg2
;
1714 fprintf (stderr
, "emacs: ");
1715 fprintf (stderr
, str
, arg1
, arg2
);
1722 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
1723 "Non-nil means the system uses terminfo rather than termcap.\n\
1724 This variable can be used by terminal emulator packages.");
1726 system_uses_terminfo
= 1;
1728 system_uses_terminfo
= 0;