1 /* terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 86, 87, 93, 94, 95 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, int insist,
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 /* The largest frame width in any call to calculate_costs. */
259 /* The largest frame height in any call to calculate_costs. */
260 int max_frame_height
;
262 /* Number of chars of space used for standout marker at beginning of line,
263 or'd with 0100. Zero if no standout marker at all.
264 The length of these vectors is max_frame_height.
266 Used IFF TN_standout_width >= 0. */
268 static char *chars_wasted
;
269 static char *copybuf
;
271 /* nonzero means supposed to write text in standout mode. */
272 int standout_requested
;
274 int insert_mode
; /* Nonzero when in insert mode. */
275 int standout_mode
; /* Nonzero when in standout mode. */
277 /* Size of window specified by higher levels.
278 This is the number of lines, from the top of frame downwards,
279 which can participate in insert-line/delete-line operations.
281 Effectively it excludes the bottom frame_height - specified_window_size
282 lines from those operations. */
284 int specified_window
;
286 /* Frame currently being redisplayed; 0 if not currently redisplaying.
287 (Direct output does not count). */
289 FRAME_PTR updating_frame
;
291 /* Provided for lisp packages. */
292 static int system_uses_terminfo
;
296 extern char *tgetstr ();
300 /* We aren't X windows, but we aren't termcap either. This makes me
301 uncertain as to what value to use for frame.output_method. For
302 this file, we'll define FRAME_TERMCAP_P to be zero so that our
303 output hooks get called instead of the termcap functions. Probably
304 the best long-term solution is to define an output_windows_nt... */
306 #undef FRAME_TERMCAP_P
307 #define FRAME_TERMCAP_P(_f_) 0
308 #endif /* WINDOWSNT */
312 if (! FRAME_TERMCAP_P (selected_frame
))
314 (*ring_bell_hook
) ();
317 OUTPUT (TS_visible_bell
&& visible_bell
? TS_visible_bell
: TS_bell
);
320 set_terminal_modes ()
322 if (! FRAME_TERMCAP_P (selected_frame
))
324 (*set_terminal_modes_hook
) ();
327 OUTPUT_IF (TS_termcap_modes
);
328 OUTPUT_IF (TS_visual_mode
);
329 OUTPUT_IF (TS_keypad_mode
);
333 reset_terminal_modes ()
335 if (! FRAME_TERMCAP_P (selected_frame
))
337 (*reset_terminal_modes_hook
) ();
340 if (TN_standout_width
< 0)
341 turn_off_highlight ();
343 OUTPUT_IF (TS_end_keypad_mode
);
344 OUTPUT_IF (TS_end_visual_mode
);
345 OUTPUT_IF (TS_end_termcap_modes
);
346 /* Output raw CR so kernel can track the cursor hpos. */
347 /* But on magic-cookie terminals this can erase an end-standout marker and
348 cause the rest of the frame to be in standout, so move down first. */
349 if (TN_standout_width
>= 0)
358 if (! FRAME_TERMCAP_P (updating_frame
))
359 (*update_begin_hook
) (f
);
365 if (! FRAME_TERMCAP_P (updating_frame
))
367 (*update_end_hook
) (f
);
372 background_highlight ();
373 standout_requested
= 0;
377 set_terminal_window (size
)
380 if (! FRAME_TERMCAP_P (updating_frame
))
382 (*set_terminal_window_hook
) (size
);
385 specified_window
= size
? size
: FRAME_HEIGHT (selected_frame
);
386 if (!scroll_region_ok
)
388 set_scroll_region (0, specified_window
);
391 set_scroll_region (start
, stop
)
395 if (TS_set_scroll_region
)
397 buf
= tparam (TS_set_scroll_region
, 0, 0, start
, stop
- 1);
399 else if (TS_set_scroll_region_1
)
401 buf
= tparam (TS_set_scroll_region_1
, 0, 0,
402 FRAME_HEIGHT (selected_frame
), start
,
403 FRAME_HEIGHT (selected_frame
) - stop
,
404 FRAME_HEIGHT (selected_frame
));
408 buf
= tparam (TS_set_window
, 0, 0, start
, 0, stop
, FRAME_WIDTH (selected_frame
));
418 OUTPUT (TS_insert_mode
);
425 OUTPUT (TS_end_insert_mode
);
429 /* Handle highlighting when TN_standout_width (termcap sg) is not specified.
430 In these terminals, output is affected by the value of standout
431 mode when the output is written.
433 These functions are called on all terminals, but do nothing
434 on terminals whose standout mode does not work that way. */
436 turn_off_highlight ()
438 if (TN_standout_width
< 0)
441 OUTPUT_IF (TS_end_standout_mode
);
448 if (TN_standout_width
< 0)
451 OUTPUT_IF (TS_standout_mode
);
456 /* Set standout mode to the state it should be in for
457 empty space inside windows. What this is,
458 depends on the user option inverse-video. */
460 background_highlight ()
462 if (TN_standout_width
>= 0)
465 turn_on_highlight ();
467 turn_off_highlight ();
470 /* Set standout mode to the mode specified for the text to be output. */
473 highlight_if_desired ()
475 if (TN_standout_width
>= 0)
477 if (!inverse_video
== !standout_requested
)
478 turn_off_highlight ();
480 turn_on_highlight ();
483 /* Handle standout mode for terminals in which TN_standout_width >= 0.
484 On these terminals, standout is controlled by markers that
485 live inside the terminal's memory. TN_standout_width is the width
486 that the marker occupies in memory. Standout runs from the marker
487 to the end of the line on some terminals, or to the next
488 turn-off-standout marker (TS_end_standout_mode) string
489 on other terminals. */
491 /* Write a standout marker or end-standout marker at the front of the line
492 at vertical position vpos. */
494 write_standout_marker (flag
, vpos
)
497 if (flag
|| (TS_end_standout_mode
&& !TF_teleray
&& !se_is_so
498 && !(TF_xs
&& TN_standout_width
== 0)))
501 cmplus (TN_standout_width
);
502 OUTPUT (flag
? TS_standout_mode
: TS_end_standout_mode
);
503 chars_wasted
[curY
] = TN_standout_width
| 0100;
507 /* External interface to control of standout mode.
508 Call this when about to modify line at position VPOS
509 and not change whether it is highlighted. */
511 reassert_line_highlight (highlight
, vpos
)
515 if (! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
517 (*reassert_line_highlight_hook
) (highlight
, vpos
);
520 if (TN_standout_width
< 0)
521 /* Handle terminals where standout takes affect at output time */
522 standout_requested
= highlight
;
523 else if (chars_wasted
[vpos
] == 0)
524 /* For terminals with standout markers, write one on this line
525 if there isn't one already. */
526 write_standout_marker (highlight
, vpos
);
529 /* Call this when about to modify line at position VPOS
530 and change whether it is highlighted. */
532 change_line_highlight (new_highlight
, vpos
, first_unused_hpos
)
533 int new_highlight
, vpos
, first_unused_hpos
;
535 standout_requested
= new_highlight
;
536 if (! FRAME_TERMCAP_P (updating_frame
))
538 (*change_line_highlight_hook
) (new_highlight
, vpos
, first_unused_hpos
);
544 if (TN_standout_width
< 0)
545 background_highlight ();
546 /* If line starts with a marker, delete the marker */
547 else if (TS_clr_line
&& chars_wasted
[curY
])
550 /* On Teleray, make sure to erase the SO marker. */
553 cmgoto (curY
- 1, FRAME_WIDTH (selected_frame
) - 4);
555 curY
++; /* ESC S moves to next line where the TS_standout_mode was */
559 cmgoto (curY
, 0); /* reposition to kill standout marker */
561 clear_end_of_line_raw (first_unused_hpos
);
562 reassert_line_highlight (new_highlight
, curY
);
566 /* Move to absolute position, specified origin 0 */
571 if (! FRAME_TERMCAP_P ((updating_frame
576 (*cursor_to_hook
) (row
, col
);
580 col
+= chars_wasted
[row
] & 077;
581 if (curY
== row
&& curX
== col
)
583 if (!TF_standout_motion
)
584 background_highlight ();
585 if (!TF_insmode_motion
)
590 /* Similar but don't take any account of the wasted characters. */
592 raw_cursor_to (row
, col
)
595 if (! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
597 (*raw_cursor_to_hook
) (row
, col
);
600 if (curY
== row
&& curX
== col
)
602 if (!TF_standout_motion
)
603 background_highlight ();
604 if (!TF_insmode_motion
)
609 /* Erase operations */
611 /* clear from cursor to end of frame */
616 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
618 (*clear_to_end_hook
) ();
621 if (TS_clr_to_bottom
)
623 background_highlight ();
624 OUTPUT (TS_clr_to_bottom
);
625 bzero (chars_wasted
+ curY
, FRAME_HEIGHT (selected_frame
) - curY
);
629 for (i
= curY
; i
< FRAME_HEIGHT (selected_frame
); i
++)
632 clear_end_of_line_raw (FRAME_WIDTH (selected_frame
));
637 /* Clear entire frame */
642 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
644 (*clear_frame_hook
) ();
649 background_highlight ();
650 OUTPUT (TS_clr_frame
);
651 bzero (chars_wasted
, FRAME_HEIGHT (selected_frame
));
661 /* Clear to end of line, but do not clear any standout marker.
662 Assumes that the cursor is positioned at a character of real text,
663 which implies it cannot be before a standout marker
664 unless the marker has zero width.
666 Note that the cursor may be moved. */
668 clear_end_of_line (first_unused_hpos
)
669 int first_unused_hpos
;
671 static GLYPH buf
= SPACEGLYPH
;
672 if (FRAME_TERMCAP_P (selected_frame
)
673 && TN_standout_width
== 0 && curX
== 0 && chars_wasted
[curY
] != 0)
674 write_glyphs (&buf
, 1);
675 clear_end_of_line_raw (first_unused_hpos
);
678 /* Clear from cursor to end of line.
679 Assume that the line is already clear starting at column first_unused_hpos.
680 If the cursor is at a standout marker, erase the marker.
682 Note that the cursor may be moved, on terminals lacking a `ce' string. */
684 clear_end_of_line_raw (first_unused_hpos
)
685 int first_unused_hpos
;
689 if (clear_end_of_line_hook
690 && ! FRAME_TERMCAP_P ((updating_frame
694 (*clear_end_of_line_hook
) (first_unused_hpos
);
698 first_unused_hpos
+= chars_wasted
[curY
] & 077;
699 if (curX
>= first_unused_hpos
)
701 /* Notice if we are erasing a magic cookie */
703 chars_wasted
[curY
] = 0;
704 background_highlight ();
707 OUTPUT1 (TS_clr_line
);
710 { /* have to do it the hard way */
713 /* Do not write in last row last col with Autowrap on. */
714 if (AutoWrap
&& curY
== FRAME_HEIGHT (selected_frame
) - 1
715 && first_unused_hpos
== FRAME_WIDTH (selected_frame
))
718 for (i
= curX
; i
< first_unused_hpos
; i
++)
721 fputc (' ', termscript
);
724 cmplus (first_unused_hpos
- curX
);
729 write_glyphs (string
, len
)
730 register GLYPH
*string
;
734 register int tlen
= GLYPH_TABLE_LENGTH
;
735 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
737 if (write_glyphs_hook
738 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
740 (*write_glyphs_hook
) (string
, len
);
744 highlight_if_desired ();
747 /* Don't dare write in last column of bottom line, if AutoWrap,
748 since that would scroll the whole frame on some terminals. */
751 && curY
+ 1 == FRAME_HEIGHT (selected_frame
)
752 && (curX
+ len
- (chars_wasted
[curY
] & 077)
753 == FRAME_WIDTH (selected_frame
)))
760 /* Check quickly for G beyond length of table.
761 That implies it isn't an alias and is simple. */
765 putc (g
& 0xff, stdout
);
769 putc (g
& 0xff, termscript
);
773 /* G has an entry in Vglyph_table,
774 so process any alias and then test for simpleness. */
775 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
776 g
= GLYPH_ALIAS (tbase
, g
);
777 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
781 /* Here if G (or its definition as an alias) is not simple. */
782 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
),
787 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
),
795 /* If start is zero, insert blanks instead of a string at start */
797 insert_glyphs (start
, len
)
798 register GLYPH
*start
;
803 register int tlen
= GLYPH_TABLE_LENGTH
;
804 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
806 if (insert_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
808 (*insert_glyphs_hook
) (start
, len
);
811 highlight_if_desired ();
813 if (TS_ins_multi_chars
)
815 buf
= tparam (TS_ins_multi_chars
, 0, 0, len
);
819 write_glyphs (start
, len
);
827 OUTPUT1_IF (TS_ins_char
);
833 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
835 putc (g
& 0xff, stdout
);
839 putc (g
& 0xff, termscript
);
843 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
), stdout
);
847 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
),
851 OUTPUT1_IF (TS_pad_inserted_char
);
862 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
864 (*delete_glyphs_hook
) (n
);
868 if (delete_in_insert_mode
)
875 OUTPUT_IF (TS_delete_mode
);
878 if (TS_del_multi_chars
)
880 buf
= tparam (TS_del_multi_chars
, 0, 0, n
);
885 for (i
= 0; i
< n
; i
++)
886 OUTPUT1 (TS_del_char
);
887 if (!delete_in_insert_mode
)
888 OUTPUT_IF (TS_end_delete_mode
);
891 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
893 ins_del_lines (vpos
, n
)
896 char *multi
= n
> 0 ? TS_ins_multi_lines
: TS_del_multi_lines
;
897 char *single
= n
> 0 ? TS_ins_line
: TS_del_line
;
898 char *scroll
= n
> 0 ? TS_rev_scroll
: TS_fwd_scroll
;
900 register int i
= n
> 0 ? n
: -n
;
903 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
905 (*ins_del_lines_hook
) (vpos
, n
);
909 /* If the lines below the insertion are being pushed
910 into the end of the window, this is the same as clearing;
911 and we know the lines are already clear, since the matching
912 deletion has already been done. So can ignore this. */
913 /* If the lines below the deletion are blank lines coming
914 out of the end of the window, don't bother,
915 as there will be a matching inslines later that will flush them. */
916 if (scroll_region_ok
&& vpos
+ i
>= specified_window
)
918 if (!memory_below_frame
&& vpos
+ i
>= FRAME_HEIGHT (selected_frame
))
923 raw_cursor_to (vpos
, 0);
924 background_highlight ();
925 buf
= tparam (multi
, 0, 0, i
);
931 raw_cursor_to (vpos
, 0);
932 background_highlight ();
940 set_scroll_region (vpos
, specified_window
);
942 raw_cursor_to (specified_window
- 1, 0);
944 raw_cursor_to (vpos
, 0);
945 background_highlight ();
947 OUTPUTL (scroll
, specified_window
- vpos
);
948 set_scroll_region (0, specified_window
);
951 if (TN_standout_width
>= 0)
956 : FRAME_HEIGHT (selected_frame
));
960 bcopy (&chars_wasted
[vpos
- n
], &chars_wasted
[vpos
],
961 lower_limit
- vpos
+ n
);
962 bzero (&chars_wasted
[lower_limit
+ n
], - n
);
966 bcopy (&chars_wasted
[vpos
], ©buf
[vpos
], lower_limit
- vpos
- n
);
967 bcopy (©buf
[vpos
], &chars_wasted
[vpos
+ n
],
968 lower_limit
- vpos
- n
);
969 bzero (&chars_wasted
[vpos
], n
);
972 if (!scroll_region_ok
&& memory_below_frame
&& n
< 0)
974 cursor_to (FRAME_HEIGHT (selected_frame
) + n
, 0);
979 /* Compute cost of sending "str", in characters,
980 not counting any line-dependent padding. */
988 tputs (str
, 0, evalcost
);
992 /* Compute cost of sending "str", in characters,
993 counting any line-dependent padding at one line. */
996 string_cost_one_line (str
)
1001 tputs (str
, 1, evalcost
);
1005 /* Compute per line amount of line-dependent padding,
1006 in tenths of characters. */
1014 tputs (str
, 0, evalcost
);
1017 tputs (str
, 10, evalcost
);
1022 /* char_ins_del_cost[n] is cost of inserting N characters.
1023 char_ins_del_cost[-n] is cost of deleting N characters.
1024 The length of this vector is based on max_frame_width. */
1026 int *char_ins_del_vector
;
1028 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH ((f))])
1033 calculate_ins_del_char_costs (frame
)
1036 int ins_startup_cost
, del_startup_cost
;
1037 int ins_cost_per_char
, del_cost_per_char
;
1041 if (TS_ins_multi_chars
)
1043 ins_cost_per_char
= 0;
1044 ins_startup_cost
= string_cost_one_line (TS_ins_multi_chars
);
1046 else if (TS_ins_char
|| TS_pad_inserted_char
1047 || (TS_insert_mode
&& TS_end_insert_mode
))
1049 ins_startup_cost
= (30 * (string_cost (TS_insert_mode
)
1050 + string_cost (TS_end_insert_mode
))) / 100;
1051 ins_cost_per_char
= (string_cost_one_line (TS_ins_char
)
1052 + string_cost_one_line (TS_pad_inserted_char
));
1056 ins_startup_cost
= 9999;
1057 ins_cost_per_char
= 0;
1060 if (TS_del_multi_chars
)
1062 del_cost_per_char
= 0;
1063 del_startup_cost
= string_cost_one_line (TS_del_multi_chars
);
1065 else if (TS_del_char
)
1067 del_startup_cost
= (string_cost (TS_delete_mode
)
1068 + string_cost (TS_end_delete_mode
));
1069 if (delete_in_insert_mode
)
1070 del_startup_cost
/= 2;
1071 del_cost_per_char
= string_cost_one_line (TS_del_char
);
1075 del_startup_cost
= 9999;
1076 del_cost_per_char
= 0;
1079 /* Delete costs are at negative offsets */
1080 p
= &char_ins_del_cost (frame
)[0];
1081 for (i
= FRAME_WIDTH (selected_frame
); --i
>= 0;)
1082 *--p
= (del_startup_cost
+= del_cost_per_char
);
1084 /* Doing nothing is free */
1085 p
= &char_ins_del_cost (frame
)[0];
1088 /* Insert costs are at positive offsets */
1089 for (i
= FRAME_WIDTH (frame
); --i
>= 0;)
1090 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1093 extern do_line_insertion_deletion_costs ();
1095 calculate_costs (frame
)
1098 register char *f
= (TS_set_scroll_region
1099 ? TS_set_scroll_region
1100 : TS_set_scroll_region_1
);
1102 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1104 scroll_region_cost
= string_cost (f
);
1105 #ifdef HAVE_X_WINDOWS
1106 if (FRAME_X_P (frame
))
1108 do_line_insertion_deletion_costs (frame
, 0, ".5*", 0, ".5*",
1110 x_screen_planes (frame
));
1111 scroll_region_cost
= 0;
1116 /* These variables are only used for terminal stuff. They are allocated
1117 once for the terminal frame of X-windows emacs, but not used afterwards.
1119 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1120 X turns off char_ins_del_ok.
1122 chars_wasted and copybuf are only used here in term.c in cases where
1123 the term hook isn't called. */
1125 max_frame_height
= max (max_frame_height
, FRAME_HEIGHT (frame
));
1126 max_frame_width
= max (max_frame_width
, FRAME_WIDTH (frame
));
1128 if (chars_wasted
!= 0)
1129 chars_wasted
= (char *) xrealloc (chars_wasted
, max_frame_height
);
1131 chars_wasted
= (char *) xmalloc (max_frame_height
);
1134 copybuf
= (char *) xrealloc (copybuf
, max_frame_height
);
1136 copybuf
= (char *) xmalloc (max_frame_height
);
1138 if (char_ins_del_vector
!= 0)
1140 = (int *) xrealloc (char_ins_del_vector
,
1142 + 2 * max_frame_width
* sizeof (int)));
1145 = (int *) xmalloc (sizeof (int)
1146 + 2 * max_frame_width
* sizeof (int));
1148 bzero (chars_wasted
, max_frame_height
);
1149 bzero (copybuf
, max_frame_height
);
1150 bzero (char_ins_del_vector
, (sizeof (int)
1151 + 2 * max_frame_width
* sizeof (int)));
1153 if (f
&& (!TS_ins_line
&& !TS_del_line
))
1154 do_line_insertion_deletion_costs (frame
,
1155 TS_rev_scroll
, TS_ins_multi_lines
,
1156 TS_fwd_scroll
, TS_del_multi_lines
,
1159 do_line_insertion_deletion_costs (frame
,
1160 TS_ins_line
, TS_ins_multi_lines
,
1161 TS_del_line
, TS_del_multi_lines
,
1164 calculate_ins_del_char_costs (frame
);
1166 /* Don't use TS_repeat if its padding is worse than sending the chars */
1167 if (TS_repeat
&& per_line_cost (TS_repeat
) * baud_rate
< 9000)
1168 RPov
= string_cost (TS_repeat
);
1170 RPov
= FRAME_WIDTH (frame
) * 2;
1172 cmcostinit (); /* set up cursor motion costs */
1179 /* Termcap capability names that correspond directly to X keysyms.
1180 Some of these (marked "terminfo") aren't supplied by old-style
1181 (Berkeley) termcap entries. They're listed in X keysym order;
1182 except we put the keypad keys first, so that if they clash with
1183 other keys (as on the IBM PC keyboard) they get overridden.
1186 static struct fkey_table keys
[] = {
1187 "kh", "home", /* termcap */
1188 "kl", "left", /* termcap */
1189 "ku", "up", /* termcap */
1190 "kr", "right", /* termcap */
1191 "kd", "down", /* termcap */
1192 "%8", "prior", /* terminfo */
1193 "%5", "next", /* terminfo */
1194 "@7", "end", /* terminfo */
1195 "@1", "begin", /* terminfo */
1196 "*6", "select", /* terminfo */
1197 "%9", "print", /* terminfo */
1198 "@4", "execute", /* terminfo --- actually the `command' key */
1200 * "insert" --- see below
1202 "&8", "undo", /* terminfo */
1203 "%0", "redo", /* terminfo */
1204 "%7", "menu", /* terminfo --- actually the `options' key */
1205 "@0", "find", /* terminfo */
1206 "@2", "cancel", /* terminfo */
1207 "%1", "help", /* terminfo */
1209 * "break" goes here, but can't be reliably intercepted with termcap
1211 "&4", "reset", /* terminfo --- actually `restart' */
1213 * "system" and "user" --- no termcaps
1215 "kE", "clearline", /* terminfo */
1216 "kA", "insertline", /* terminfo */
1217 "kL", "deleteline", /* terminfo */
1218 "kI", "insertchar", /* terminfo */
1219 "kD", "deletechar", /* terminfo */
1220 "kB", "backtab", /* terminfo */
1222 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1224 "@8", "kp-enter", /* terminfo */
1226 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1227 * "kp-multiply", "kp-add", "kp-separator",
1228 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1229 * --- no termcaps for any of these.
1231 "K4", "kp-1", /* terminfo */
1233 * "kp-2" --- no termcap
1235 "K5", "kp-3", /* terminfo */
1237 * "kp-4" --- no termcap
1239 "K2", "kp-5", /* terminfo */
1241 * "kp-6" --- no termcap
1243 "K1", "kp-7", /* terminfo */
1245 * "kp-8" --- no termcap
1247 "K3", "kp-9", /* terminfo */
1249 * "kp-equal" --- no termcap
1262 static char **term_get_fkeys_arg
;
1263 static Lisp_Object
term_get_fkeys_1 ();
1265 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1266 This function scans the termcap function key sequence entries, and
1267 adds entries to Vfunction_key_map for each function key it finds. */
1270 term_get_fkeys (address
)
1273 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1274 errors during the call. The only errors should be from Fdefine_key
1275 when given a key sequence containing an invalid prefix key. If the
1276 termcap defines function keys which use a prefix that is already bound
1277 to a command by the default bindings, we should silently ignore that
1278 function key specification, rather than giving the user an error and
1279 refusing to run at all on such a terminal. */
1281 extern Lisp_Object
Fidentity ();
1282 term_get_fkeys_arg
= address
;
1283 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1291 char **address
= term_get_fkeys_arg
;
1293 /* This can happen if CANNOT_DUMP or with strange options. */
1295 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1297 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1299 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1301 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1302 Fmake_vector (make_number (1),
1303 intern (keys
[i
].name
)));
1306 /* The uses of the "k0" capability are inconsistent; sometimes it
1307 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1308 We will attempt to politely accommodate both systems by testing for
1309 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1312 char *k_semi
= tgetstr ("k;", address
);
1313 char *k0
= tgetstr ("k0", address
);
1314 char *k0_name
= "f10";
1318 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1319 Fmake_vector (make_number (1), intern ("f10")));
1324 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1325 Fmake_vector (make_number (1), intern (k0_name
)));
1328 /* Set up cookies for numbered function keys above f10. */
1330 char fcap
[3], fkey
[4];
1332 fcap
[0] = 'F'; fcap
[2] = '\0';
1333 for (i
= 11; i
< 64; i
++)
1336 fcap
[1] = '1' + i
- 11;
1338 fcap
[1] = 'A' + i
- 20;
1340 fcap
[1] = 'a' + i
- 46;
1343 char *sequence
= tgetstr (fcap
, address
);
1346 sprintf (fkey
, "f%d", i
);
1347 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1348 Fmake_vector (make_number (1),
1356 * Various mappings to try and get a better fit.
1359 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1360 if (!tgetstr (cap1, address)) \
1362 char *sequence = tgetstr (cap2, address); \
1364 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1365 Fmake_vector (make_number (1), \
1369 /* if there's no key_next keycap, map key_npage to `next' keysym */
1370 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1371 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1372 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1373 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1374 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1376 /* IBM has their own non-standard dialect of terminfo.
1377 If the standard name isn't found, try the IBM name. */
1378 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1379 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1380 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1381 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1382 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1383 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1384 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1385 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1386 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1387 #undef CONDITIONAL_REASSIGN
1392 term_init (terminal_type
)
1393 char *terminal_type
;
1396 char **address
= &area
;
1402 initialize_win_nt_display ();
1406 area
= (char *) malloc (2044);
1411 FrameRows
= FRAME_HEIGHT (selected_frame
);
1412 FrameCols
= FRAME_WIDTH (selected_frame
);
1413 specified_window
= FRAME_HEIGHT (selected_frame
);
1415 delete_in_insert_mode
= 1;
1418 scroll_region_ok
= 0;
1420 /* Seems to insert lines when it's not supposed to, messing
1421 up the display. In doing a trace, it didn't seem to be
1422 called much, so I don't think we're losing anything by
1425 line_ins_del_ok
= 0;
1426 char_ins_del_ok
= 1;
1430 FRAME_CAN_HAVE_SCROLL_BARS (selected_frame
) = 0;
1431 FRAME_HAS_VERTICAL_SCROLL_BARS (selected_frame
) = 0;
1434 #endif /* WINDOWSNT */
1438 status
= tgetent (buffer
, terminal_type
);
1442 fatal ("Cannot open terminfo database file.\n");
1444 fatal ("Cannot open termcap database file.\n");
1450 fatal ("Terminal type %s is not defined.\n\
1451 If that is not the actual type of terminal you have,\n\
1452 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1453 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1454 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.\n",
1457 fatal ("Terminal type %s is not defined.\n\
1458 If that is not the actual type of terminal you have,\n\
1459 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1460 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1461 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.\n",
1466 area
= (char *) malloc (2044);
1468 area
= (char *) malloc (strlen (buffer
));
1469 #endif /* not TERMINFO */
1473 TS_ins_line
= tgetstr ("al", address
);
1474 TS_ins_multi_lines
= tgetstr ("AL", address
);
1475 TS_bell
= tgetstr ("bl", address
);
1476 BackTab
= tgetstr ("bt", address
);
1477 TS_clr_to_bottom
= tgetstr ("cd", address
);
1478 TS_clr_line
= tgetstr ("ce", address
);
1479 TS_clr_frame
= tgetstr ("cl", address
);
1480 ColPosition
= tgetstr ("ch", address
);
1481 AbsPosition
= tgetstr ("cm", address
);
1482 CR
= tgetstr ("cr", address
);
1483 TS_set_scroll_region
= tgetstr ("cs", address
);
1484 TS_set_scroll_region_1
= tgetstr ("cS", address
);
1485 RowPosition
= tgetstr ("cv", address
);
1486 TS_del_char
= tgetstr ("dc", address
);
1487 TS_del_multi_chars
= tgetstr ("DC", address
);
1488 TS_del_line
= tgetstr ("dl", address
);
1489 TS_del_multi_lines
= tgetstr ("DL", address
);
1490 TS_delete_mode
= tgetstr ("dm", address
);
1491 TS_end_delete_mode
= tgetstr ("ed", address
);
1492 TS_end_insert_mode
= tgetstr ("ei", address
);
1493 Home
= tgetstr ("ho", address
);
1494 TS_ins_char
= tgetstr ("ic", address
);
1495 TS_ins_multi_chars
= tgetstr ("IC", address
);
1496 TS_insert_mode
= tgetstr ("im", address
);
1497 TS_pad_inserted_char
= tgetstr ("ip", address
);
1498 TS_end_keypad_mode
= tgetstr ("ke", address
);
1499 TS_keypad_mode
= tgetstr ("ks", address
);
1500 LastLine
= tgetstr ("ll", address
);
1501 Right
= tgetstr ("nd", address
);
1502 Down
= tgetstr ("do", address
);
1504 Down
= tgetstr ("nl", address
); /* Obsolete name for "do" */
1506 /* VMS puts a carriage return before each linefeed,
1507 so it is not safe to use linefeeds. */
1508 if (Down
&& Down
[0] == '\n' && Down
[1] == '\0')
1511 if (tgetflag ("bs"))
1512 Left
= "\b"; /* can't possibly be longer! */
1513 else /* (Actually, "bs" is obsolete...) */
1514 Left
= tgetstr ("le", address
);
1516 Left
= tgetstr ("bc", address
); /* Obsolete name for "le" */
1517 TS_pad_char
= tgetstr ("pc", address
);
1518 TS_repeat
= tgetstr ("rp", address
);
1519 TS_end_standout_mode
= tgetstr ("se", address
);
1520 TS_fwd_scroll
= tgetstr ("sf", address
);
1521 TS_standout_mode
= tgetstr ("so", address
);
1522 TS_rev_scroll
= tgetstr ("sr", address
);
1523 Wcm
.cm_tab
= tgetstr ("ta", address
);
1524 TS_end_termcap_modes
= tgetstr ("te", address
);
1525 TS_termcap_modes
= tgetstr ("ti", address
);
1526 Up
= tgetstr ("up", address
);
1527 TS_visible_bell
= tgetstr ("vb", address
);
1528 TS_end_visual_mode
= tgetstr ("ve", address
);
1529 TS_visual_mode
= tgetstr ("vs", address
);
1530 TS_set_window
= tgetstr ("wi", address
);
1531 MultiUp
= tgetstr ("UP", address
);
1532 MultiDown
= tgetstr ("DO", address
);
1533 MultiLeft
= tgetstr ("LE", address
);
1534 MultiRight
= tgetstr ("RI", address
);
1536 AutoWrap
= tgetflag ("am");
1537 memory_below_frame
= tgetflag ("db");
1538 TF_hazeltine
= tgetflag ("hz");
1539 must_write_spaces
= tgetflag ("in");
1540 meta_key
= tgetflag ("km") || tgetflag ("MT");
1541 TF_insmode_motion
= tgetflag ("mi");
1542 TF_standout_motion
= tgetflag ("ms");
1543 TF_underscore
= tgetflag ("ul");
1544 MagicWrap
= tgetflag ("xn");
1545 TF_xs
= tgetflag ("xs");
1546 TF_teleray
= tgetflag ("xt");
1548 term_get_fkeys (address
);
1550 /* Get frame size from system, or else from termcap. */
1551 get_frame_size (&FRAME_WIDTH (selected_frame
),
1552 &FRAME_HEIGHT (selected_frame
));
1553 if (FRAME_WIDTH (selected_frame
) <= 0)
1554 FRAME_WIDTH (selected_frame
) = tgetnum ("co");
1555 if (FRAME_HEIGHT (selected_frame
) <= 0)
1556 FRAME_HEIGHT (selected_frame
) = tgetnum ("li");
1558 if (FRAME_HEIGHT (selected_frame
) < 3
1559 || FRAME_WIDTH (selected_frame
) < 3)
1560 fatal ("Screen size %dx%d is too small.\n",
1561 FRAME_HEIGHT (selected_frame
), FRAME_WIDTH (selected_frame
));
1563 min_padding_speed
= tgetnum ("pb");
1564 TN_standout_width
= tgetnum ("sg");
1565 TabWidth
= tgetnum ("tw");
1568 /* These capabilities commonly use ^J.
1569 I don't know why, but sending them on VMS does not work;
1570 it causes following spaces to be lost, sometimes.
1571 For now, the simplest fix is to avoid using these capabilities ever. */
1572 if (Down
&& Down
[0] == '\n')
1580 TS_fwd_scroll
= Down
;
1582 PC
= TS_pad_char
? *TS_pad_char
: 0;
1587 /* Turned off since /etc/termcap seems to have :ta= for most terminals
1588 and newer termcap doc does not seem to say there is a default.
1593 if (TS_standout_mode
== 0)
1595 TN_standout_width
= tgetnum ("ug");
1596 TS_end_standout_mode
= tgetstr ("ue", address
);
1597 TS_standout_mode
= tgetstr ("us", address
);
1600 /* If no `se' string, try using a `me' string instead.
1601 If that fails, we can't use standout mode at all. */
1602 if (TS_end_standout_mode
== 0)
1604 char *s
= tgetstr ("me", address
);
1606 TS_end_standout_mode
= s
;
1608 TS_standout_mode
= 0;
1614 /* Teleray: most programs want a space in front of TS_standout_mode,
1615 but Emacs can do without it (and give one extra column). */
1616 TS_standout_mode
= "\033RD";
1617 TN_standout_width
= 1;
1618 /* But that means we cannot rely on ^M to go to column zero! */
1620 /* LF can't be trusted either -- can alter hpos */
1621 /* if move at column 0 thru a line with TS_standout_mode */
1625 /* Special handling for certain terminal types known to need it */
1627 if (!strcmp (terminal_type
, "supdup"))
1629 memory_below_frame
= 1;
1630 Wcm
.cm_losewrap
= 1;
1632 if (!strncmp (terminal_type
, "c10", 3)
1633 || !strcmp (terminal_type
, "perq"))
1635 /* Supply a makeshift :wi string.
1636 This string is not valid in general since it works only
1637 for windows starting at the upper left corner;
1638 but that is all Emacs uses.
1640 This string works only if the frame is using
1641 the top of the video memory, because addressing is memory-relative.
1642 So first check the :ti string to see if that is true.
1644 It would be simpler if the :wi string could go in the termcap
1645 entry, but it can't because it is not fully valid.
1646 If it were in the termcap entry, it would confuse other programs. */
1649 p
= TS_termcap_modes
;
1650 while (*p
&& strcmp (p
, "\033v "))
1653 TS_set_window
= "\033v%C %C %C %C ";
1655 /* Termcap entry often fails to have :in: flag */
1656 must_write_spaces
= 1;
1657 /* :ti string typically fails to have \E^G! in it */
1658 /* This limits scope of insert-char to one line. */
1659 strcpy (area
, TS_termcap_modes
);
1660 strcat (area
, "\033\007!");
1661 TS_termcap_modes
= area
;
1662 area
+= strlen (area
) + 1;
1664 /* Change all %+ parameters to %C, to handle
1665 values above 96 correctly for the C100. */
1668 if (p
[0] == '%' && p
[1] == '+')
1674 FrameRows
= FRAME_HEIGHT (selected_frame
);
1675 FrameCols
= FRAME_WIDTH (selected_frame
);
1676 specified_window
= FRAME_HEIGHT (selected_frame
);
1678 if (Wcm_init () == -1) /* can't do cursor motion */
1680 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1681 It lacks the ability to position the cursor.\n\
1682 If that is not the actual type of terminal you have, use either the\n\
1683 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
1684 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.\n",
1687 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1688 It lacks the ability to position the cursor.\n\
1689 If that is not the actual type of terminal you have,\n\
1690 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1691 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1692 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.\n",
1695 if (FRAME_HEIGHT (selected_frame
) <= 0
1696 || FRAME_WIDTH (selected_frame
) <= 0)
1697 fatal ("The frame size has not been specified.");
1699 delete_in_insert_mode
1700 = TS_delete_mode
&& TS_insert_mode
1701 && !strcmp (TS_delete_mode
, TS_insert_mode
);
1703 se_is_so
= (TS_standout_mode
1704 && TS_end_standout_mode
1705 && !strcmp (TS_standout_mode
, TS_end_standout_mode
));
1707 /* Remove width of standout marker from usable width of line */
1708 if (TN_standout_width
> 0)
1709 FRAME_WIDTH (selected_frame
) -= TN_standout_width
;
1711 UseTabs
= tabs_safe_p () && TabWidth
== 8;
1715 && (TS_set_window
|| TS_set_scroll_region
|| TS_set_scroll_region_1
));
1717 line_ins_del_ok
= (((TS_ins_line
|| TS_ins_multi_lines
)
1718 && (TS_del_line
|| TS_del_multi_lines
))
1719 || (scroll_region_ok
&& TS_fwd_scroll
&& TS_rev_scroll
));
1721 char_ins_del_ok
= ((TS_ins_char
|| TS_insert_mode
1722 || TS_pad_inserted_char
|| TS_ins_multi_chars
)
1723 && (TS_del_char
|| TS_del_multi_chars
));
1725 fast_clear_end_of_line
= TS_clr_line
!= 0;
1728 if (read_socket_hook
) /* Baudrate is somewhat */
1729 /* meaningless in this case */
1732 FRAME_CAN_HAVE_SCROLL_BARS (selected_frame
) = 0;
1733 FRAME_HAS_VERTICAL_SCROLL_BARS (selected_frame
) = 0;
1737 fatal (str
, arg1
, arg2
)
1738 char *str
, *arg1
, *arg2
;
1740 fprintf (stderr
, "emacs: ");
1741 fprintf (stderr
, str
, arg1
, arg2
);
1748 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
1749 "Non-nil means the system uses terminfo rather than termcap.\n\
1750 This variable can be used by terminal emulator packages.");
1752 system_uses_terminfo
= 1;
1754 system_uses_terminfo
= 0;