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 ();
301 /* We aren't X windows, but we aren't termcap either. This makes me
302 uncertain as to what value to use for frame.output_method. For
303 this file, we'll define FRAME_TERMCAP_P to be zero so that our
304 output hooks get called instead of the termcap functions. Probably
305 the best long-term solution is to define an output_windows_nt... */
307 #undef FRAME_TERMCAP_P
308 #define FRAME_TERMCAP_P(_f_) 0
309 #endif /* not HAVE_NTGUI */
310 #endif /* WINDOWSNT */
314 if (! FRAME_TERMCAP_P (selected_frame
))
316 (*ring_bell_hook
) ();
319 OUTPUT (TS_visible_bell
&& visible_bell
? TS_visible_bell
: TS_bell
);
322 set_terminal_modes ()
324 if (! FRAME_TERMCAP_P (selected_frame
))
326 (*set_terminal_modes_hook
) ();
329 OUTPUT_IF (TS_termcap_modes
);
330 OUTPUT_IF (TS_visual_mode
);
331 OUTPUT_IF (TS_keypad_mode
);
335 reset_terminal_modes ()
337 if (! FRAME_TERMCAP_P (selected_frame
))
339 (*reset_terminal_modes_hook
) ();
342 if (TN_standout_width
< 0)
343 turn_off_highlight ();
345 OUTPUT_IF (TS_end_keypad_mode
);
346 OUTPUT_IF (TS_end_visual_mode
);
347 OUTPUT_IF (TS_end_termcap_modes
);
348 /* Output raw CR so kernel can track the cursor hpos. */
349 /* But on magic-cookie terminals this can erase an end-standout marker and
350 cause the rest of the frame to be in standout, so move down first. */
351 if (TN_standout_width
>= 0)
360 if (! FRAME_TERMCAP_P (updating_frame
))
361 (*update_begin_hook
) (f
);
367 if (! FRAME_TERMCAP_P (updating_frame
))
369 (*update_end_hook
) (f
);
374 background_highlight ();
375 standout_requested
= 0;
379 set_terminal_window (size
)
382 if (! FRAME_TERMCAP_P (updating_frame
))
384 (*set_terminal_window_hook
) (size
);
387 specified_window
= size
? size
: FRAME_HEIGHT (selected_frame
);
388 if (!scroll_region_ok
)
390 set_scroll_region (0, specified_window
);
393 set_scroll_region (start
, stop
)
397 if (TS_set_scroll_region
)
399 buf
= tparam (TS_set_scroll_region
, 0, 0, start
, stop
- 1);
401 else if (TS_set_scroll_region_1
)
403 buf
= tparam (TS_set_scroll_region_1
, 0, 0,
404 FRAME_HEIGHT (selected_frame
), start
,
405 FRAME_HEIGHT (selected_frame
) - stop
,
406 FRAME_HEIGHT (selected_frame
));
410 buf
= tparam (TS_set_window
, 0, 0, start
, 0, stop
, FRAME_WIDTH (selected_frame
));
420 OUTPUT (TS_insert_mode
);
427 OUTPUT (TS_end_insert_mode
);
431 /* Handle highlighting when TN_standout_width (termcap sg) is not specified.
432 In these terminals, output is affected by the value of standout
433 mode when the output is written.
435 These functions are called on all terminals, but do nothing
436 on terminals whose standout mode does not work that way. */
438 turn_off_highlight ()
440 if (TN_standout_width
< 0)
443 OUTPUT_IF (TS_end_standout_mode
);
450 if (TN_standout_width
< 0)
453 OUTPUT_IF (TS_standout_mode
);
458 /* Set standout mode to the state it should be in for
459 empty space inside windows. What this is,
460 depends on the user option inverse-video. */
462 background_highlight ()
464 if (TN_standout_width
>= 0)
467 turn_on_highlight ();
469 turn_off_highlight ();
472 /* Set standout mode to the mode specified for the text to be output. */
475 highlight_if_desired ()
477 if (TN_standout_width
>= 0)
479 if (!inverse_video
== !standout_requested
)
480 turn_off_highlight ();
482 turn_on_highlight ();
485 /* Handle standout mode for terminals in which TN_standout_width >= 0.
486 On these terminals, standout is controlled by markers that
487 live inside the terminal's memory. TN_standout_width is the width
488 that the marker occupies in memory. Standout runs from the marker
489 to the end of the line on some terminals, or to the next
490 turn-off-standout marker (TS_end_standout_mode) string
491 on other terminals. */
493 /* Write a standout marker or end-standout marker at the front of the line
494 at vertical position vpos. */
496 write_standout_marker (flag
, vpos
)
499 if (flag
|| (TS_end_standout_mode
&& !TF_teleray
&& !se_is_so
500 && !(TF_xs
&& TN_standout_width
== 0)))
503 cmplus (TN_standout_width
);
504 OUTPUT (flag
? TS_standout_mode
: TS_end_standout_mode
);
505 chars_wasted
[curY
] = TN_standout_width
| 0100;
509 /* External interface to control of standout mode.
510 Call this when about to modify line at position VPOS
511 and not change whether it is highlighted. */
513 reassert_line_highlight (highlight
, vpos
)
517 if (! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
519 (*reassert_line_highlight_hook
) (highlight
, vpos
);
522 if (TN_standout_width
< 0)
523 /* Handle terminals where standout takes affect at output time */
524 standout_requested
= highlight
;
525 else if (chars_wasted
[vpos
] == 0)
526 /* For terminals with standout markers, write one on this line
527 if there isn't one already. */
528 write_standout_marker (highlight
, vpos
);
531 /* Call this when about to modify line at position VPOS
532 and change whether it is highlighted. */
534 change_line_highlight (new_highlight
, vpos
, first_unused_hpos
)
535 int new_highlight
, vpos
, first_unused_hpos
;
537 standout_requested
= new_highlight
;
538 if (! FRAME_TERMCAP_P (updating_frame
))
540 (*change_line_highlight_hook
) (new_highlight
, vpos
, first_unused_hpos
);
546 if (TN_standout_width
< 0)
547 background_highlight ();
548 /* If line starts with a marker, delete the marker */
549 else if (TS_clr_line
&& chars_wasted
[curY
])
552 /* On Teleray, make sure to erase the SO marker. */
555 cmgoto (curY
- 1, FRAME_WIDTH (selected_frame
) - 4);
557 curY
++; /* ESC S moves to next line where the TS_standout_mode was */
561 cmgoto (curY
, 0); /* reposition to kill standout marker */
563 clear_end_of_line_raw (first_unused_hpos
);
564 reassert_line_highlight (new_highlight
, curY
);
568 /* Move to absolute position, specified origin 0 */
573 if (! FRAME_TERMCAP_P ((updating_frame
578 (*cursor_to_hook
) (row
, col
);
582 /* Detect the case where we are called from reset_sys_modes
583 and the costs have never been calculated. Do nothing. */
584 if (chars_wasted
== 0)
587 col
+= chars_wasted
[row
] & 077;
588 if (curY
== row
&& curX
== col
)
590 if (!TF_standout_motion
)
591 background_highlight ();
592 if (!TF_insmode_motion
)
597 /* Similar but don't take any account of the wasted characters. */
599 raw_cursor_to (row
, col
)
602 if (! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
604 (*raw_cursor_to_hook
) (row
, col
);
607 if (curY
== row
&& curX
== col
)
609 if (!TF_standout_motion
)
610 background_highlight ();
611 if (!TF_insmode_motion
)
616 /* Erase operations */
618 /* clear from cursor to end of frame */
623 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
625 (*clear_to_end_hook
) ();
628 if (TS_clr_to_bottom
)
630 background_highlight ();
631 OUTPUT (TS_clr_to_bottom
);
632 bzero (chars_wasted
+ curY
, FRAME_HEIGHT (selected_frame
) - curY
);
636 for (i
= curY
; i
< FRAME_HEIGHT (selected_frame
); i
++)
639 clear_end_of_line_raw (FRAME_WIDTH (selected_frame
));
644 /* Clear entire frame */
649 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
651 (*clear_frame_hook
) ();
656 background_highlight ();
657 OUTPUT (TS_clr_frame
);
658 bzero (chars_wasted
, FRAME_HEIGHT (selected_frame
));
668 /* Clear to end of line, but do not clear any standout marker.
669 Assumes that the cursor is positioned at a character of real text,
670 which implies it cannot be before a standout marker
671 unless the marker has zero width.
673 Note that the cursor may be moved. */
675 clear_end_of_line (first_unused_hpos
)
676 int first_unused_hpos
;
678 static GLYPH buf
= SPACEGLYPH
;
679 if (FRAME_TERMCAP_P (selected_frame
)
681 && TN_standout_width
== 0 && curX
== 0 && chars_wasted
[curY
] != 0)
682 write_glyphs (&buf
, 1);
683 clear_end_of_line_raw (first_unused_hpos
);
686 /* Clear from cursor to end of line.
687 Assume that the line is already clear starting at column first_unused_hpos.
688 If the cursor is at a standout marker, erase the marker.
690 Note that the cursor may be moved, on terminals lacking a `ce' string. */
692 clear_end_of_line_raw (first_unused_hpos
)
693 int first_unused_hpos
;
697 if (clear_end_of_line_hook
698 && ! FRAME_TERMCAP_P ((updating_frame
702 (*clear_end_of_line_hook
) (first_unused_hpos
);
706 /* Detect the case where we are called from reset_sys_modes
707 and the costs have never been calculated. Do nothing. */
708 if (chars_wasted
== 0)
711 first_unused_hpos
+= chars_wasted
[curY
] & 077;
712 if (curX
>= first_unused_hpos
)
714 /* Notice if we are erasing a magic cookie */
716 chars_wasted
[curY
] = 0;
717 background_highlight ();
720 OUTPUT1 (TS_clr_line
);
723 { /* have to do it the hard way */
726 /* Do not write in last row last col with Autowrap on. */
727 if (AutoWrap
&& curY
== FRAME_HEIGHT (selected_frame
) - 1
728 && first_unused_hpos
== FRAME_WIDTH (selected_frame
))
731 for (i
= curX
; i
< first_unused_hpos
; i
++)
734 fputc (' ', termscript
);
737 cmplus (first_unused_hpos
- curX
);
742 write_glyphs (string
, len
)
743 register GLYPH
*string
;
747 register int tlen
= GLYPH_TABLE_LENGTH
;
748 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
750 if (write_glyphs_hook
751 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
753 (*write_glyphs_hook
) (string
, len
);
757 highlight_if_desired ();
760 /* Don't dare write in last column of bottom line, if AutoWrap,
761 since that would scroll the whole frame on some terminals. */
764 && curY
+ 1 == FRAME_HEIGHT (selected_frame
)
765 && (curX
+ len
- (chars_wasted
[curY
] & 077)
766 == FRAME_WIDTH (selected_frame
)))
773 /* Check quickly for G beyond length of table.
774 That implies it isn't an alias and is simple. */
778 putc (g
& 0xff, stdout
);
782 putc (g
& 0xff, termscript
);
786 /* G has an entry in Vglyph_table,
787 so process any alias and then test for simpleness. */
788 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
789 g
= GLYPH_ALIAS (tbase
, g
);
790 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
794 /* Here if G (or its definition as an alias) is not simple. */
795 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
),
800 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
),
808 /* If start is zero, insert blanks instead of a string at start */
810 insert_glyphs (start
, len
)
811 register GLYPH
*start
;
816 register int tlen
= GLYPH_TABLE_LENGTH
;
817 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
819 if (insert_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
821 (*insert_glyphs_hook
) (start
, len
);
824 highlight_if_desired ();
826 if (TS_ins_multi_chars
)
828 buf
= tparam (TS_ins_multi_chars
, 0, 0, len
);
832 write_glyphs (start
, len
);
840 OUTPUT1_IF (TS_ins_char
);
846 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
848 putc (g
& 0xff, stdout
);
852 putc (g
& 0xff, termscript
);
856 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
), stdout
);
860 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
),
864 OUTPUT1_IF (TS_pad_inserted_char
);
875 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
877 (*delete_glyphs_hook
) (n
);
881 if (delete_in_insert_mode
)
888 OUTPUT_IF (TS_delete_mode
);
891 if (TS_del_multi_chars
)
893 buf
= tparam (TS_del_multi_chars
, 0, 0, n
);
898 for (i
= 0; i
< n
; i
++)
899 OUTPUT1 (TS_del_char
);
900 if (!delete_in_insert_mode
)
901 OUTPUT_IF (TS_end_delete_mode
);
904 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
906 ins_del_lines (vpos
, n
)
909 char *multi
= n
> 0 ? TS_ins_multi_lines
: TS_del_multi_lines
;
910 char *single
= n
> 0 ? TS_ins_line
: TS_del_line
;
911 char *scroll
= n
> 0 ? TS_rev_scroll
: TS_fwd_scroll
;
913 register int i
= n
> 0 ? n
: -n
;
916 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
918 (*ins_del_lines_hook
) (vpos
, n
);
922 /* If the lines below the insertion are being pushed
923 into the end of the window, this is the same as clearing;
924 and we know the lines are already clear, since the matching
925 deletion has already been done. So can ignore this. */
926 /* If the lines below the deletion are blank lines coming
927 out of the end of the window, don't bother,
928 as there will be a matching inslines later that will flush them. */
929 if (scroll_region_ok
&& vpos
+ i
>= specified_window
)
931 if (!memory_below_frame
&& vpos
+ i
>= FRAME_HEIGHT (selected_frame
))
936 raw_cursor_to (vpos
, 0);
937 background_highlight ();
938 buf
= tparam (multi
, 0, 0, i
);
944 raw_cursor_to (vpos
, 0);
945 background_highlight ();
953 set_scroll_region (vpos
, specified_window
);
955 raw_cursor_to (specified_window
- 1, 0);
957 raw_cursor_to (vpos
, 0);
958 background_highlight ();
960 OUTPUTL (scroll
, specified_window
- vpos
);
961 set_scroll_region (0, specified_window
);
964 if (TN_standout_width
>= 0)
969 : FRAME_HEIGHT (selected_frame
));
973 bcopy (&chars_wasted
[vpos
- n
], &chars_wasted
[vpos
],
974 lower_limit
- vpos
+ n
);
975 bzero (&chars_wasted
[lower_limit
+ n
], - n
);
979 bcopy (&chars_wasted
[vpos
], ©buf
[vpos
], lower_limit
- vpos
- n
);
980 bcopy (©buf
[vpos
], &chars_wasted
[vpos
+ n
],
981 lower_limit
- vpos
- n
);
982 bzero (&chars_wasted
[vpos
], n
);
985 if (!scroll_region_ok
&& memory_below_frame
&& n
< 0)
987 cursor_to (FRAME_HEIGHT (selected_frame
) + n
, 0);
992 /* Compute cost of sending "str", in characters,
993 not counting any line-dependent padding. */
1001 tputs (str
, 0, evalcost
);
1005 /* Compute cost of sending "str", in characters,
1006 counting any line-dependent padding at one line. */
1009 string_cost_one_line (str
)
1014 tputs (str
, 1, evalcost
);
1018 /* Compute per line amount of line-dependent padding,
1019 in tenths of characters. */
1027 tputs (str
, 0, evalcost
);
1030 tputs (str
, 10, evalcost
);
1035 /* char_ins_del_cost[n] is cost of inserting N characters.
1036 char_ins_del_cost[-n] is cost of deleting N characters.
1037 The length of this vector is based on max_frame_width. */
1039 int *char_ins_del_vector
;
1041 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH ((f))])
1046 calculate_ins_del_char_costs (frame
)
1049 int ins_startup_cost
, del_startup_cost
;
1050 int ins_cost_per_char
, del_cost_per_char
;
1054 if (TS_ins_multi_chars
)
1056 ins_cost_per_char
= 0;
1057 ins_startup_cost
= string_cost_one_line (TS_ins_multi_chars
);
1059 else if (TS_ins_char
|| TS_pad_inserted_char
1060 || (TS_insert_mode
&& TS_end_insert_mode
))
1062 ins_startup_cost
= (30 * (string_cost (TS_insert_mode
)
1063 + string_cost (TS_end_insert_mode
))) / 100;
1064 ins_cost_per_char
= (string_cost_one_line (TS_ins_char
)
1065 + string_cost_one_line (TS_pad_inserted_char
));
1069 ins_startup_cost
= 9999;
1070 ins_cost_per_char
= 0;
1073 if (TS_del_multi_chars
)
1075 del_cost_per_char
= 0;
1076 del_startup_cost
= string_cost_one_line (TS_del_multi_chars
);
1078 else if (TS_del_char
)
1080 del_startup_cost
= (string_cost (TS_delete_mode
)
1081 + string_cost (TS_end_delete_mode
));
1082 if (delete_in_insert_mode
)
1083 del_startup_cost
/= 2;
1084 del_cost_per_char
= string_cost_one_line (TS_del_char
);
1088 del_startup_cost
= 9999;
1089 del_cost_per_char
= 0;
1092 /* Delete costs are at negative offsets */
1093 p
= &char_ins_del_cost (frame
)[0];
1094 for (i
= FRAME_WIDTH (selected_frame
); --i
>= 0;)
1095 *--p
= (del_startup_cost
+= del_cost_per_char
);
1097 /* Doing nothing is free */
1098 p
= &char_ins_del_cost (frame
)[0];
1101 /* Insert costs are at positive offsets */
1102 for (i
= FRAME_WIDTH (frame
); --i
>= 0;)
1103 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1106 extern do_line_insertion_deletion_costs ();
1108 calculate_costs (frame
)
1111 register char *f
= (TS_set_scroll_region
1112 ? TS_set_scroll_region
1113 : TS_set_scroll_region_1
);
1115 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1117 scroll_region_cost
= string_cost (f
);
1118 #ifdef HAVE_X_WINDOWS
1119 if (FRAME_X_P (frame
))
1121 do_line_insertion_deletion_costs (frame
, 0, ".5*", 0, ".5*",
1123 x_screen_planes (frame
));
1124 scroll_region_cost
= 0;
1129 /* These variables are only used for terminal stuff. They are allocated
1130 once for the terminal frame of X-windows emacs, but not used afterwards.
1132 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1133 X turns off char_ins_del_ok.
1135 chars_wasted and copybuf are only used here in term.c in cases where
1136 the term hook isn't called. */
1138 max_frame_height
= max (max_frame_height
, FRAME_HEIGHT (frame
));
1139 max_frame_width
= max (max_frame_width
, FRAME_WIDTH (frame
));
1141 if (chars_wasted
!= 0)
1142 chars_wasted
= (char *) xrealloc (chars_wasted
, max_frame_height
);
1144 chars_wasted
= (char *) xmalloc (max_frame_height
);
1147 copybuf
= (char *) xrealloc (copybuf
, max_frame_height
);
1149 copybuf
= (char *) xmalloc (max_frame_height
);
1151 if (char_ins_del_vector
!= 0)
1153 = (int *) xrealloc (char_ins_del_vector
,
1155 + 2 * max_frame_width
* sizeof (int)));
1158 = (int *) xmalloc (sizeof (int)
1159 + 2 * max_frame_width
* sizeof (int));
1161 bzero (chars_wasted
, max_frame_height
);
1162 bzero (copybuf
, max_frame_height
);
1163 bzero (char_ins_del_vector
, (sizeof (int)
1164 + 2 * max_frame_width
* sizeof (int)));
1166 if (f
&& (!TS_ins_line
&& !TS_del_line
))
1167 do_line_insertion_deletion_costs (frame
,
1168 TS_rev_scroll
, TS_ins_multi_lines
,
1169 TS_fwd_scroll
, TS_del_multi_lines
,
1172 do_line_insertion_deletion_costs (frame
,
1173 TS_ins_line
, TS_ins_multi_lines
,
1174 TS_del_line
, TS_del_multi_lines
,
1177 calculate_ins_del_char_costs (frame
);
1179 /* Don't use TS_repeat if its padding is worse than sending the chars */
1180 if (TS_repeat
&& per_line_cost (TS_repeat
) * baud_rate
< 9000)
1181 RPov
= string_cost (TS_repeat
);
1183 RPov
= FRAME_WIDTH (frame
) * 2;
1185 cmcostinit (); /* set up cursor motion costs */
1192 /* Termcap capability names that correspond directly to X keysyms.
1193 Some of these (marked "terminfo") aren't supplied by old-style
1194 (Berkeley) termcap entries. They're listed in X keysym order;
1195 except we put the keypad keys first, so that if they clash with
1196 other keys (as on the IBM PC keyboard) they get overridden.
1199 static struct fkey_table keys
[] = {
1200 "kh", "home", /* termcap */
1201 "kl", "left", /* termcap */
1202 "ku", "up", /* termcap */
1203 "kr", "right", /* termcap */
1204 "kd", "down", /* termcap */
1205 "%8", "prior", /* terminfo */
1206 "%5", "next", /* terminfo */
1207 "@7", "end", /* terminfo */
1208 "@1", "begin", /* terminfo */
1209 "*6", "select", /* terminfo */
1210 "%9", "print", /* terminfo */
1211 "@4", "execute", /* terminfo --- actually the `command' key */
1213 * "insert" --- see below
1215 "&8", "undo", /* terminfo */
1216 "%0", "redo", /* terminfo */
1217 "%7", "menu", /* terminfo --- actually the `options' key */
1218 "@0", "find", /* terminfo */
1219 "@2", "cancel", /* terminfo */
1220 "%1", "help", /* terminfo */
1222 * "break" goes here, but can't be reliably intercepted with termcap
1224 "&4", "reset", /* terminfo --- actually `restart' */
1226 * "system" and "user" --- no termcaps
1228 "kE", "clearline", /* terminfo */
1229 "kA", "insertline", /* terminfo */
1230 "kL", "deleteline", /* terminfo */
1231 "kI", "insertchar", /* terminfo */
1232 "kD", "deletechar", /* terminfo */
1233 "kB", "backtab", /* terminfo */
1235 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1237 "@8", "kp-enter", /* terminfo */
1239 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1240 * "kp-multiply", "kp-add", "kp-separator",
1241 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1242 * --- no termcaps for any of these.
1244 "K4", "kp-1", /* terminfo */
1246 * "kp-2" --- no termcap
1248 "K5", "kp-3", /* terminfo */
1250 * "kp-4" --- no termcap
1252 "K2", "kp-5", /* terminfo */
1254 * "kp-6" --- no termcap
1256 "K1", "kp-7", /* terminfo */
1258 * "kp-8" --- no termcap
1260 "K3", "kp-9", /* terminfo */
1262 * "kp-equal" --- no termcap
1275 static char **term_get_fkeys_arg
;
1276 static Lisp_Object
term_get_fkeys_1 ();
1278 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1279 This function scans the termcap function key sequence entries, and
1280 adds entries to Vfunction_key_map for each function key it finds. */
1283 term_get_fkeys (address
)
1286 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1287 errors during the call. The only errors should be from Fdefine_key
1288 when given a key sequence containing an invalid prefix key. If the
1289 termcap defines function keys which use a prefix that is already bound
1290 to a command by the default bindings, we should silently ignore that
1291 function key specification, rather than giving the user an error and
1292 refusing to run at all on such a terminal. */
1294 extern Lisp_Object
Fidentity ();
1295 term_get_fkeys_arg
= address
;
1296 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1304 char **address
= term_get_fkeys_arg
;
1306 /* This can happen if CANNOT_DUMP or with strange options. */
1308 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1310 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1312 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1314 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1315 Fmake_vector (make_number (1),
1316 intern (keys
[i
].name
)));
1319 /* The uses of the "k0" capability are inconsistent; sometimes it
1320 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1321 We will attempt to politely accommodate both systems by testing for
1322 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1325 char *k_semi
= tgetstr ("k;", address
);
1326 char *k0
= tgetstr ("k0", address
);
1327 char *k0_name
= "f10";
1331 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1332 Fmake_vector (make_number (1), intern ("f10")));
1337 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1338 Fmake_vector (make_number (1), intern (k0_name
)));
1341 /* Set up cookies for numbered function keys above f10. */
1343 char fcap
[3], fkey
[4];
1345 fcap
[0] = 'F'; fcap
[2] = '\0';
1346 for (i
= 11; i
< 64; i
++)
1349 fcap
[1] = '1' + i
- 11;
1351 fcap
[1] = 'A' + i
- 20;
1353 fcap
[1] = 'a' + i
- 46;
1356 char *sequence
= tgetstr (fcap
, address
);
1359 sprintf (fkey
, "f%d", i
);
1360 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1361 Fmake_vector (make_number (1),
1369 * Various mappings to try and get a better fit.
1372 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1373 if (!tgetstr (cap1, address)) \
1375 char *sequence = tgetstr (cap2, address); \
1377 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1378 Fmake_vector (make_number (1), \
1382 /* if there's no key_next keycap, map key_npage to `next' keysym */
1383 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1384 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1385 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1386 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1387 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1389 /* IBM has their own non-standard dialect of terminfo.
1390 If the standard name isn't found, try the IBM name. */
1391 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1392 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1393 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1394 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1395 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1396 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1397 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1398 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1399 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1400 #undef CONDITIONAL_REASSIGN
1405 term_init (terminal_type
)
1406 char *terminal_type
;
1409 char **address
= &area
;
1415 initialize_win_nt_display ();
1419 area
= (char *) malloc (2044);
1424 FrameRows
= FRAME_HEIGHT (selected_frame
);
1425 FrameCols
= FRAME_WIDTH (selected_frame
);
1426 specified_window
= FRAME_HEIGHT (selected_frame
);
1428 delete_in_insert_mode
= 1;
1431 scroll_region_ok
= 0;
1433 /* Seems to insert lines when it's not supposed to, messing
1434 up the display. In doing a trace, it didn't seem to be
1435 called much, so I don't think we're losing anything by
1438 line_ins_del_ok
= 0;
1439 char_ins_del_ok
= 1;
1443 FRAME_CAN_HAVE_SCROLL_BARS (selected_frame
) = 0;
1444 FRAME_HAS_VERTICAL_SCROLL_BARS (selected_frame
) = 0;
1447 #endif /* WINDOWSNT */
1451 status
= tgetent (buffer
, terminal_type
);
1455 fatal ("Cannot open terminfo database file.\n");
1457 fatal ("Cannot open termcap database file.\n");
1463 fatal ("Terminal type %s is not defined.\n\
1464 If that is not the actual type of terminal you have,\n\
1465 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1466 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1467 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.\n",
1470 fatal ("Terminal type %s is not defined.\n\
1471 If that is not the actual type of terminal you have,\n\
1472 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1473 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1474 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.\n",
1479 area
= (char *) malloc (2044);
1481 area
= (char *) malloc (strlen (buffer
));
1482 #endif /* not TERMINFO */
1486 TS_ins_line
= tgetstr ("al", address
);
1487 TS_ins_multi_lines
= tgetstr ("AL", address
);
1488 TS_bell
= tgetstr ("bl", address
);
1489 BackTab
= tgetstr ("bt", address
);
1490 TS_clr_to_bottom
= tgetstr ("cd", address
);
1491 TS_clr_line
= tgetstr ("ce", address
);
1492 TS_clr_frame
= tgetstr ("cl", address
);
1493 ColPosition
= tgetstr ("ch", address
);
1494 AbsPosition
= tgetstr ("cm", address
);
1495 CR
= tgetstr ("cr", address
);
1496 TS_set_scroll_region
= tgetstr ("cs", address
);
1497 TS_set_scroll_region_1
= tgetstr ("cS", address
);
1498 RowPosition
= tgetstr ("cv", address
);
1499 TS_del_char
= tgetstr ("dc", address
);
1500 TS_del_multi_chars
= tgetstr ("DC", address
);
1501 TS_del_line
= tgetstr ("dl", address
);
1502 TS_del_multi_lines
= tgetstr ("DL", address
);
1503 TS_delete_mode
= tgetstr ("dm", address
);
1504 TS_end_delete_mode
= tgetstr ("ed", address
);
1505 TS_end_insert_mode
= tgetstr ("ei", address
);
1506 Home
= tgetstr ("ho", address
);
1507 TS_ins_char
= tgetstr ("ic", address
);
1508 TS_ins_multi_chars
= tgetstr ("IC", address
);
1509 TS_insert_mode
= tgetstr ("im", address
);
1510 TS_pad_inserted_char
= tgetstr ("ip", address
);
1511 TS_end_keypad_mode
= tgetstr ("ke", address
);
1512 TS_keypad_mode
= tgetstr ("ks", address
);
1513 LastLine
= tgetstr ("ll", address
);
1514 Right
= tgetstr ("nd", address
);
1515 Down
= tgetstr ("do", address
);
1517 Down
= tgetstr ("nl", address
); /* Obsolete name for "do" */
1519 /* VMS puts a carriage return before each linefeed,
1520 so it is not safe to use linefeeds. */
1521 if (Down
&& Down
[0] == '\n' && Down
[1] == '\0')
1524 if (tgetflag ("bs"))
1525 Left
= "\b"; /* can't possibly be longer! */
1526 else /* (Actually, "bs" is obsolete...) */
1527 Left
= tgetstr ("le", address
);
1529 Left
= tgetstr ("bc", address
); /* Obsolete name for "le" */
1530 TS_pad_char
= tgetstr ("pc", address
);
1531 TS_repeat
= tgetstr ("rp", address
);
1532 TS_end_standout_mode
= tgetstr ("se", address
);
1533 TS_fwd_scroll
= tgetstr ("sf", address
);
1534 TS_standout_mode
= tgetstr ("so", address
);
1535 TS_rev_scroll
= tgetstr ("sr", address
);
1536 Wcm
.cm_tab
= tgetstr ("ta", address
);
1537 TS_end_termcap_modes
= tgetstr ("te", address
);
1538 TS_termcap_modes
= tgetstr ("ti", address
);
1539 Up
= tgetstr ("up", address
);
1540 TS_visible_bell
= tgetstr ("vb", address
);
1541 TS_end_visual_mode
= tgetstr ("ve", address
);
1542 TS_visual_mode
= tgetstr ("vs", address
);
1543 TS_set_window
= tgetstr ("wi", address
);
1544 MultiUp
= tgetstr ("UP", address
);
1545 MultiDown
= tgetstr ("DO", address
);
1546 MultiLeft
= tgetstr ("LE", address
);
1547 MultiRight
= tgetstr ("RI", address
);
1549 MagicWrap
= tgetflag ("xn");
1550 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
1551 the former flag imply the latter. */
1552 AutoWrap
= MagicWrap
|| tgetflag ("am");
1553 memory_below_frame
= tgetflag ("db");
1554 TF_hazeltine
= tgetflag ("hz");
1555 must_write_spaces
= tgetflag ("in");
1556 meta_key
= tgetflag ("km") || tgetflag ("MT");
1557 TF_insmode_motion
= tgetflag ("mi");
1558 TF_standout_motion
= tgetflag ("ms");
1559 TF_underscore
= tgetflag ("ul");
1560 TF_xs
= tgetflag ("xs");
1561 TF_teleray
= tgetflag ("xt");
1563 term_get_fkeys (address
);
1565 /* Get frame size from system, or else from termcap. */
1566 get_frame_size (&FRAME_WIDTH (selected_frame
),
1567 &FRAME_HEIGHT (selected_frame
));
1568 if (FRAME_WIDTH (selected_frame
) <= 0)
1569 FRAME_WIDTH (selected_frame
) = tgetnum ("co");
1570 if (FRAME_HEIGHT (selected_frame
) <= 0)
1571 FRAME_HEIGHT (selected_frame
) = tgetnum ("li");
1573 if (FRAME_HEIGHT (selected_frame
) < 3
1574 || FRAME_WIDTH (selected_frame
) < 3)
1575 fatal ("Screen size %dx%d is too small.\n",
1576 FRAME_HEIGHT (selected_frame
), FRAME_WIDTH (selected_frame
));
1578 min_padding_speed
= tgetnum ("pb");
1579 TN_standout_width
= tgetnum ("sg");
1580 TabWidth
= tgetnum ("tw");
1583 /* These capabilities commonly use ^J.
1584 I don't know why, but sending them on VMS does not work;
1585 it causes following spaces to be lost, sometimes.
1586 For now, the simplest fix is to avoid using these capabilities ever. */
1587 if (Down
&& Down
[0] == '\n')
1595 TS_fwd_scroll
= Down
;
1597 PC
= TS_pad_char
? *TS_pad_char
: 0;
1602 /* Turned off since /etc/termcap seems to have :ta= for most terminals
1603 and newer termcap doc does not seem to say there is a default.
1608 if (TS_standout_mode
== 0)
1610 TN_standout_width
= tgetnum ("ug");
1611 TS_end_standout_mode
= tgetstr ("ue", address
);
1612 TS_standout_mode
= tgetstr ("us", address
);
1615 /* If no `se' string, try using a `me' string instead.
1616 If that fails, we can't use standout mode at all. */
1617 if (TS_end_standout_mode
== 0)
1619 char *s
= tgetstr ("me", address
);
1621 TS_end_standout_mode
= s
;
1623 TS_standout_mode
= 0;
1629 /* Teleray: most programs want a space in front of TS_standout_mode,
1630 but Emacs can do without it (and give one extra column). */
1631 TS_standout_mode
= "\033RD";
1632 TN_standout_width
= 1;
1633 /* But that means we cannot rely on ^M to go to column zero! */
1635 /* LF can't be trusted either -- can alter hpos */
1636 /* if move at column 0 thru a line with TS_standout_mode */
1640 /* Special handling for certain terminal types known to need it */
1642 if (!strcmp (terminal_type
, "supdup"))
1644 memory_below_frame
= 1;
1645 Wcm
.cm_losewrap
= 1;
1647 if (!strncmp (terminal_type
, "c10", 3)
1648 || !strcmp (terminal_type
, "perq"))
1650 /* Supply a makeshift :wi string.
1651 This string is not valid in general since it works only
1652 for windows starting at the upper left corner;
1653 but that is all Emacs uses.
1655 This string works only if the frame is using
1656 the top of the video memory, because addressing is memory-relative.
1657 So first check the :ti string to see if that is true.
1659 It would be simpler if the :wi string could go in the termcap
1660 entry, but it can't because it is not fully valid.
1661 If it were in the termcap entry, it would confuse other programs. */
1664 p
= TS_termcap_modes
;
1665 while (*p
&& strcmp (p
, "\033v "))
1668 TS_set_window
= "\033v%C %C %C %C ";
1670 /* Termcap entry often fails to have :in: flag */
1671 must_write_spaces
= 1;
1672 /* :ti string typically fails to have \E^G! in it */
1673 /* This limits scope of insert-char to one line. */
1674 strcpy (area
, TS_termcap_modes
);
1675 strcat (area
, "\033\007!");
1676 TS_termcap_modes
= area
;
1677 area
+= strlen (area
) + 1;
1679 /* Change all %+ parameters to %C, to handle
1680 values above 96 correctly for the C100. */
1683 if (p
[0] == '%' && p
[1] == '+')
1689 FrameRows
= FRAME_HEIGHT (selected_frame
);
1690 FrameCols
= FRAME_WIDTH (selected_frame
);
1691 specified_window
= FRAME_HEIGHT (selected_frame
);
1693 if (Wcm_init () == -1) /* can't do cursor motion */
1695 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1696 It lacks the ability to position the cursor.\n\
1697 If that is not the actual type of terminal you have, use either the\n\
1698 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
1699 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.\n",
1703 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1704 It lacks the ability to position the cursor.\n\
1705 If that is not the actual type of terminal you have,\n\
1706 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1707 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1708 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.\n",
1710 # else /* TERMCAP */
1711 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1712 It lacks the ability to position the cursor.\n\
1713 If that is not the actual type of terminal you have,\n\
1714 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1715 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1716 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.\n",
1718 # endif /* TERMINFO */
1720 if (FRAME_HEIGHT (selected_frame
) <= 0
1721 || FRAME_WIDTH (selected_frame
) <= 0)
1722 fatal ("The frame size has not been specified.");
1724 delete_in_insert_mode
1725 = TS_delete_mode
&& TS_insert_mode
1726 && !strcmp (TS_delete_mode
, TS_insert_mode
);
1728 se_is_so
= (TS_standout_mode
1729 && TS_end_standout_mode
1730 && !strcmp (TS_standout_mode
, TS_end_standout_mode
));
1732 /* Remove width of standout marker from usable width of line */
1733 if (TN_standout_width
> 0)
1734 FRAME_WIDTH (selected_frame
) -= TN_standout_width
;
1736 UseTabs
= tabs_safe_p () && TabWidth
== 8;
1740 && (TS_set_window
|| TS_set_scroll_region
|| TS_set_scroll_region_1
));
1742 line_ins_del_ok
= (((TS_ins_line
|| TS_ins_multi_lines
)
1743 && (TS_del_line
|| TS_del_multi_lines
))
1744 || (scroll_region_ok
&& TS_fwd_scroll
&& TS_rev_scroll
));
1746 char_ins_del_ok
= ((TS_ins_char
|| TS_insert_mode
1747 || TS_pad_inserted_char
|| TS_ins_multi_chars
)
1748 && (TS_del_char
|| TS_del_multi_chars
));
1750 fast_clear_end_of_line
= TS_clr_line
!= 0;
1753 if (read_socket_hook
) /* Baudrate is somewhat */
1754 /* meaningless in this case */
1757 FRAME_CAN_HAVE_SCROLL_BARS (selected_frame
) = 0;
1758 FRAME_HAS_VERTICAL_SCROLL_BARS (selected_frame
) = 0;
1762 fatal (str
, arg1
, arg2
)
1763 char *str
, *arg1
, *arg2
;
1765 fprintf (stderr
, "emacs: ");
1766 fprintf (stderr
, str
, arg1
, arg2
);
1773 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
1774 "Non-nil means the system uses terminfo rather than termcap.\n\
1775 This variable can be used by terminal emulator packages.");
1777 system_uses_terminfo
= 1;
1779 system_uses_terminfo
= 0;