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, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
32 #include "termhooks.h"
35 extern Lisp_Object
Fmake_sparse_keymap ();
37 #define max(a, b) ((a) > (b) ? (a) : (b))
38 #define min(a, b) ((a) < (b) ? (a) : (b))
40 #define OUTPUT(a) tputs (a, FRAME_HEIGHT (selected_frame) - curY, cmputc)
41 #define OUTPUT1(a) tputs (a, 1, cmputc)
42 #define OUTPUTL(a, lines) tputs (a, lines, cmputc)
43 #define OUTPUT_IF(a) { if (a) tputs (a, FRAME_HEIGHT (selected_frame) - curY, cmputc); }
44 #define OUTPUT1_IF(a) { if (a) tputs (a, 1, cmputc); }
46 /* Terminal characteristics that higher levels want to look at.
47 These are all extern'd in termchar.h */
49 int must_write_spaces
; /* Nonzero means spaces in the text
50 must actually be output; can't just skip
51 over some columns to leave them blank. */
52 int min_padding_speed
; /* Speed below which no padding necessary */
54 int line_ins_del_ok
; /* Terminal can insert and delete lines */
55 int char_ins_del_ok
; /* Terminal can insert and delete chars */
56 int scroll_region_ok
; /* Terminal supports setting the
58 int scroll_region_cost
; /* Cost of setting a scroll window,
59 measured in characters */
60 int memory_below_frame
; /* Terminal remembers lines
61 scrolled off bottom */
62 int fast_clear_end_of_line
; /* Terminal has a `ce' string */
64 /* Nonzero means no need to redraw the entire frame on resuming
65 a suspended Emacs. This is useful on terminals with multiple pages,
66 where one page is used for Emacs and another for all else. */
67 int no_redraw_on_reenter
;
69 /* Hook functions that you can set to snap out the functions in this file.
70 These are all extern'd in termhooks.h */
72 int (*cursor_to_hook
) ();
73 int (*raw_cursor_to_hook
) ();
75 int (*clear_to_end_hook
) ();
76 int (*clear_frame_hook
) ();
77 int (*clear_end_of_line_hook
) ();
79 int (*ins_del_lines_hook
) ();
81 int (*change_line_highlight_hook
) ();
82 int (*reassert_line_highlight_hook
) ();
84 int (*insert_glyphs_hook
) ();
85 int (*write_glyphs_hook
) ();
86 int (*delete_glyphs_hook
) ();
88 int (*ring_bell_hook
) ();
90 int (*reset_terminal_modes_hook
) ();
91 int (*set_terminal_modes_hook
) ();
92 int (*update_begin_hook
) ();
93 int (*update_end_hook
) ();
94 int (*set_terminal_window_hook
) ();
96 int (*read_socket_hook
) ();
98 int (*frame_up_to_date_hook
) ();
100 /* Return the current position of the mouse.
102 Set *f to the frame the mouse is in, or zero if the mouse is in no
103 Emacs frame. If it is set to zero, all the other arguments are
106 If the motion started in a scroll bar, set *bar_window to the
107 scroll bar's window, *part to the part the mouse is currently over,
108 *x to the position of the mouse along the scroll bar, and *y to the
109 overall length of the scroll bar.
111 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
112 row of the character cell the mouse is over.
114 Set *time to the time the mouse was at the returned position.
116 This should clear mouse_moved until the next motion
118 void (*mouse_position_hook
) ( /* FRAME_PTR *f, int insist,
119 Lisp_Object *bar_window,
120 enum scroll_bar_part *part,
123 unsigned long *time */ );
125 /* When reading from a minibuffer in a different frame, Emacs wants
126 to shift the highlight from the selected frame to the minibuffer's
127 frame; under X, this means it lies about where the focus is.
128 This hook tells the window system code to re-decide where to put
130 void (*frame_rehighlight_hook
) ( /* FRAME_PTR f */ );
132 /* If we're displaying frames using a window system that can stack
133 frames on top of each other, this hook allows you to bring a frame
134 to the front, or bury it behind all the other windows. If this
135 hook is zero, that means the device we're displaying on doesn't
136 support overlapping frames, so there's no need to raise or lower
139 If RAISE is non-zero, F is brought to the front, before all other
140 windows. If RAISE is zero, F is sent to the back, behind all other
142 void (*frame_raise_lower_hook
) ( /* FRAME_PTR f, int raise */ );
144 /* Set the vertical scroll bar for WINDOW to have its upper left corner
145 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
146 indicate that we are displaying PORTION characters out of a total
147 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
148 have a scroll bar, create one for it. */
149 void (*set_vertical_scroll_bar_hook
)
150 ( /* struct window *window,
151 int portion, int whole, int position */ );
154 /* The following three hooks are used when we're doing a thorough
155 redisplay of the frame. We don't explicitly know which scroll bars
156 are going to be deleted, because keeping track of when windows go
157 away is a real pain - can you say set-window-configuration?
158 Instead, we just assert at the beginning of redisplay that *all*
159 scroll bars are to be removed, and then save scroll bars from the
160 fiery pit when we actually redisplay their window. */
162 /* Arrange for all scroll bars on FRAME to be removed at the next call
163 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
164 `*redeem_scroll_bar_hook' is applied to its window before the judgement.
166 This should be applied to each frame each time its window tree is
167 redisplayed, even if it is not displaying scroll bars at the moment;
168 if the HAS_SCROLL_BARS flag has just been turned off, only calling
169 this and the judge_scroll_bars_hook will get rid of them.
171 If non-zero, this hook should be safe to apply to any frame,
172 whether or not it can support scroll bars, and whether or not it is
173 currently displaying them. */
174 void (*condemn_scroll_bars_hook
)( /* FRAME_PTR *frame */ );
176 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
177 Note that it's okay to redeem a scroll bar that is not condemned. */
178 void (*redeem_scroll_bar_hook
)( /* struct window *window */ );
180 /* Remove all scroll bars on FRAME that haven't been saved since the
181 last call to `*condemn_scroll_bars_hook'.
183 This should be applied to each frame after each time its window
184 tree is redisplayed, even if it is not displaying scroll bars at the
185 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
186 calling this and condemn_scroll_bars_hook will get rid of them.
188 If non-zero, this hook should be safe to apply to any frame,
189 whether or not it can support scroll bars, and whether or not it is
190 currently displaying them. */
191 void (*judge_scroll_bars_hook
)( /* FRAME_PTR *FRAME */ );
194 /* Strings, numbers and flags taken from the termcap entry. */
196 char *TS_ins_line
; /* termcap "al" */
197 char *TS_ins_multi_lines
; /* "AL" (one parameter, # lines to insert) */
198 char *TS_bell
; /* "bl" */
199 char *TS_clr_to_bottom
; /* "cd" */
200 char *TS_clr_line
; /* "ce", clear to end of line */
201 char *TS_clr_frame
; /* "cl" */
202 char *TS_set_scroll_region
; /* "cs" (2 params, first line and last line) */
203 char *TS_set_scroll_region_1
; /* "cS" (4 params: total lines,
204 lines above scroll region, lines below it,
205 total lines again) */
206 char *TS_del_char
; /* "dc" */
207 char *TS_del_multi_chars
; /* "DC" (one parameter, # chars to delete) */
208 char *TS_del_line
; /* "dl" */
209 char *TS_del_multi_lines
; /* "DL" (one parameter, # lines to delete) */
210 char *TS_delete_mode
; /* "dm", enter character-delete mode */
211 char *TS_end_delete_mode
; /* "ed", leave character-delete mode */
212 char *TS_end_insert_mode
; /* "ei", leave character-insert mode */
213 char *TS_ins_char
; /* "ic" */
214 char *TS_ins_multi_chars
; /* "IC" (one parameter, # chars to insert) */
215 char *TS_insert_mode
; /* "im", enter character-insert mode */
216 char *TS_pad_inserted_char
; /* "ip". Just padding, no commands. */
217 char *TS_end_keypad_mode
; /* "ke" */
218 char *TS_keypad_mode
; /* "ks" */
219 char *TS_pad_char
; /* "pc", char to use as padding */
220 char *TS_repeat
; /* "rp" (2 params, # times to repeat
221 and character to be repeated) */
222 char *TS_end_standout_mode
; /* "se" */
223 char *TS_fwd_scroll
; /* "sf" */
224 char *TS_standout_mode
; /* "so" */
225 char *TS_rev_scroll
; /* "sr" */
226 char *TS_end_termcap_modes
; /* "te" */
227 char *TS_termcap_modes
; /* "ti" */
228 char *TS_visible_bell
; /* "vb" */
229 char *TS_end_visual_mode
; /* "ve" */
230 char *TS_visual_mode
; /* "vi" */
231 char *TS_set_window
; /* "wi" (4 params, start and end of window,
232 each as vpos and hpos) */
234 int TF_hazeltine
; /* termcap hz flag. */
235 int TF_insmode_motion
; /* termcap mi flag: can move while in insert mode. */
236 int TF_standout_motion
; /* termcap mi flag: can move while in standout mode. */
237 int TF_underscore
; /* termcap ul flag: _ underlines if overstruck on
238 nonblank position. Must clear before writing _. */
239 int TF_teleray
; /* termcap xt flag: many weird consequences.
242 int TF_xs
; /* Nonzero for "xs". If set together with
243 TN_standout_width == 0, it means don't bother
244 to write any end-standout cookies. */
246 int TN_standout_width
; /* termcap sg number: width occupied by standout
249 static int RPov
; /* # chars to start a TS_repeat */
251 static int delete_in_insert_mode
; /* delete mode == insert mode */
253 static int se_is_so
; /* 1 if same string both enters and leaves
258 /* The largest frame width in any call to calculate_costs. */
260 /* The largest frame height in any call to calculate_costs. */
261 int max_frame_height
;
263 /* Number of chars of space used for standout marker at beginning of line,
264 or'd with 0100. Zero if no standout marker at all.
265 The length of these vectors is max_frame_height.
267 Used IFF TN_standout_width >= 0. */
269 static char *chars_wasted
;
270 static char *copybuf
;
272 /* nonzero means supposed to write text in standout mode. */
273 int standout_requested
;
275 int insert_mode
; /* Nonzero when in insert mode. */
276 int standout_mode
; /* Nonzero when in standout mode. */
278 /* Size of window specified by higher levels.
279 This is the number of lines, from the top of frame downwards,
280 which can participate in insert-line/delete-line operations.
282 Effectively it excludes the bottom frame_height - specified_window_size
283 lines from those operations. */
285 int specified_window
;
287 /* Frame currently being redisplayed; 0 if not currently redisplaying.
288 (Direct output does not count). */
290 FRAME_PTR updating_frame
;
292 /* Provided for lisp packages. */
293 static int system_uses_terminfo
;
297 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 /* WINDOWSNT */
313 if (! FRAME_TERMCAP_P (selected_frame
))
315 (*ring_bell_hook
) ();
318 OUTPUT (TS_visible_bell
&& visible_bell
? TS_visible_bell
: TS_bell
);
321 set_terminal_modes ()
323 if (! FRAME_TERMCAP_P (selected_frame
))
325 (*set_terminal_modes_hook
) ();
328 OUTPUT_IF (TS_termcap_modes
);
329 OUTPUT_IF (TS_visual_mode
);
330 OUTPUT_IF (TS_keypad_mode
);
334 reset_terminal_modes ()
336 if (! FRAME_TERMCAP_P (selected_frame
))
338 (*reset_terminal_modes_hook
) ();
341 if (TN_standout_width
< 0)
342 turn_off_highlight ();
344 OUTPUT_IF (TS_end_keypad_mode
);
345 OUTPUT_IF (TS_end_visual_mode
);
346 OUTPUT_IF (TS_end_termcap_modes
);
347 /* Output raw CR so kernel can track the cursor hpos. */
348 /* But on magic-cookie terminals this can erase an end-standout marker and
349 cause the rest of the frame to be in standout, so move down first. */
350 if (TN_standout_width
>= 0)
359 if (! FRAME_TERMCAP_P (updating_frame
))
360 (*update_begin_hook
) (f
);
366 if (! FRAME_TERMCAP_P (updating_frame
))
368 (*update_end_hook
) (f
);
373 background_highlight ();
374 standout_requested
= 0;
378 set_terminal_window (size
)
381 if (! FRAME_TERMCAP_P (updating_frame
))
383 (*set_terminal_window_hook
) (size
);
386 specified_window
= size
? size
: FRAME_HEIGHT (selected_frame
);
387 if (!scroll_region_ok
)
389 set_scroll_region (0, specified_window
);
392 set_scroll_region (start
, stop
)
396 if (TS_set_scroll_region
)
398 buf
= tparam (TS_set_scroll_region
, 0, 0, start
, stop
- 1);
400 else if (TS_set_scroll_region_1
)
402 buf
= tparam (TS_set_scroll_region_1
, 0, 0,
403 FRAME_HEIGHT (selected_frame
), start
,
404 FRAME_HEIGHT (selected_frame
) - stop
,
405 FRAME_HEIGHT (selected_frame
));
409 buf
= tparam (TS_set_window
, 0, 0, start
, 0, stop
, FRAME_WIDTH (selected_frame
));
419 OUTPUT (TS_insert_mode
);
426 OUTPUT (TS_end_insert_mode
);
430 /* Handle highlighting when TN_standout_width (termcap sg) is not specified.
431 In these terminals, output is affected by the value of standout
432 mode when the output is written.
434 These functions are called on all terminals, but do nothing
435 on terminals whose standout mode does not work that way. */
437 turn_off_highlight ()
439 if (TN_standout_width
< 0)
442 OUTPUT_IF (TS_end_standout_mode
);
449 if (TN_standout_width
< 0)
452 OUTPUT_IF (TS_standout_mode
);
457 /* Set standout mode to the state it should be in for
458 empty space inside windows. What this is,
459 depends on the user option inverse-video. */
461 background_highlight ()
463 if (TN_standout_width
>= 0)
466 turn_on_highlight ();
468 turn_off_highlight ();
471 /* Set standout mode to the mode specified for the text to be output. */
474 highlight_if_desired ()
476 if (TN_standout_width
>= 0)
478 if (!inverse_video
== !standout_requested
)
479 turn_off_highlight ();
481 turn_on_highlight ();
484 /* Handle standout mode for terminals in which TN_standout_width >= 0.
485 On these terminals, standout is controlled by markers that
486 live inside the terminal's memory. TN_standout_width is the width
487 that the marker occupies in memory. Standout runs from the marker
488 to the end of the line on some terminals, or to the next
489 turn-off-standout marker (TS_end_standout_mode) string
490 on other terminals. */
492 /* Write a standout marker or end-standout marker at the front of the line
493 at vertical position vpos. */
495 write_standout_marker (flag
, vpos
)
498 if (flag
|| (TS_end_standout_mode
&& !TF_teleray
&& !se_is_so
499 && !(TF_xs
&& TN_standout_width
== 0)))
502 cmplus (TN_standout_width
);
503 OUTPUT (flag
? TS_standout_mode
: TS_end_standout_mode
);
504 chars_wasted
[curY
] = TN_standout_width
| 0100;
508 /* External interface to control of standout mode.
509 Call this when about to modify line at position VPOS
510 and not change whether it is highlighted. */
512 reassert_line_highlight (highlight
, vpos
)
516 if (! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
518 (*reassert_line_highlight_hook
) (highlight
, vpos
);
521 if (TN_standout_width
< 0)
522 /* Handle terminals where standout takes affect at output time */
523 standout_requested
= highlight
;
524 else if (chars_wasted
[vpos
] == 0)
525 /* For terminals with standout markers, write one on this line
526 if there isn't one already. */
527 write_standout_marker (highlight
, vpos
);
530 /* Call this when about to modify line at position VPOS
531 and change whether it is highlighted. */
533 change_line_highlight (new_highlight
, vpos
, first_unused_hpos
)
534 int new_highlight
, vpos
, first_unused_hpos
;
536 standout_requested
= new_highlight
;
537 if (! FRAME_TERMCAP_P (updating_frame
))
539 (*change_line_highlight_hook
) (new_highlight
, vpos
, first_unused_hpos
);
545 if (TN_standout_width
< 0)
546 background_highlight ();
547 /* If line starts with a marker, delete the marker */
548 else if (TS_clr_line
&& chars_wasted
[curY
])
551 /* On Teleray, make sure to erase the SO marker. */
554 cmgoto (curY
- 1, FRAME_WIDTH (selected_frame
) - 4);
556 curY
++; /* ESC S moves to next line where the TS_standout_mode was */
560 cmgoto (curY
, 0); /* reposition to kill standout marker */
562 clear_end_of_line_raw (first_unused_hpos
);
563 reassert_line_highlight (new_highlight
, curY
);
567 /* Move to absolute position, specified origin 0 */
572 if (! FRAME_TERMCAP_P ((updating_frame
577 (*cursor_to_hook
) (row
, col
);
581 /* Detect the case where we are called from reset_sys_modes
582 and the costs have never been calculated. Do nothing. */
583 if (chars_wasted
== 0)
586 col
+= chars_wasted
[row
] & 077;
587 if (curY
== row
&& curX
== col
)
589 if (!TF_standout_motion
)
590 background_highlight ();
591 if (!TF_insmode_motion
)
596 /* Similar but don't take any account of the wasted characters. */
598 raw_cursor_to (row
, col
)
601 if (! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
603 (*raw_cursor_to_hook
) (row
, col
);
606 if (curY
== row
&& curX
== col
)
608 if (!TF_standout_motion
)
609 background_highlight ();
610 if (!TF_insmode_motion
)
615 /* Erase operations */
617 /* clear from cursor to end of frame */
622 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
624 (*clear_to_end_hook
) ();
627 if (TS_clr_to_bottom
)
629 background_highlight ();
630 OUTPUT (TS_clr_to_bottom
);
631 bzero (chars_wasted
+ curY
, FRAME_HEIGHT (selected_frame
) - curY
);
635 for (i
= curY
; i
< FRAME_HEIGHT (selected_frame
); i
++)
638 clear_end_of_line_raw (FRAME_WIDTH (selected_frame
));
643 /* Clear entire frame */
648 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
650 (*clear_frame_hook
) ();
655 background_highlight ();
656 OUTPUT (TS_clr_frame
);
657 bzero (chars_wasted
, FRAME_HEIGHT (selected_frame
));
667 /* Clear to end of line, but do not clear any standout marker.
668 Assumes that the cursor is positioned at a character of real text,
669 which implies it cannot be before a standout marker
670 unless the marker has zero width.
672 Note that the cursor may be moved. */
674 clear_end_of_line (first_unused_hpos
)
675 int first_unused_hpos
;
677 static GLYPH buf
= SPACEGLYPH
;
678 if (FRAME_TERMCAP_P (selected_frame
)
680 && TN_standout_width
== 0 && curX
== 0 && chars_wasted
[curY
] != 0)
681 write_glyphs (&buf
, 1);
682 clear_end_of_line_raw (first_unused_hpos
);
685 /* Clear from cursor to end of line.
686 Assume that the line is already clear starting at column first_unused_hpos.
687 If the cursor is at a standout marker, erase the marker.
689 Note that the cursor may be moved, on terminals lacking a `ce' string. */
691 clear_end_of_line_raw (first_unused_hpos
)
692 int first_unused_hpos
;
696 if (clear_end_of_line_hook
697 && ! FRAME_TERMCAP_P ((updating_frame
701 (*clear_end_of_line_hook
) (first_unused_hpos
);
705 /* Detect the case where we are called from reset_sys_modes
706 and the costs have never been calculated. Do nothing. */
707 if (chars_wasted
== 0)
710 first_unused_hpos
+= chars_wasted
[curY
] & 077;
711 if (curX
>= first_unused_hpos
)
713 /* Notice if we are erasing a magic cookie */
715 chars_wasted
[curY
] = 0;
716 background_highlight ();
719 OUTPUT1 (TS_clr_line
);
722 { /* have to do it the hard way */
725 /* Do not write in last row last col with Autowrap on. */
726 if (AutoWrap
&& curY
== FRAME_HEIGHT (selected_frame
) - 1
727 && first_unused_hpos
== FRAME_WIDTH (selected_frame
))
730 for (i
= curX
; i
< first_unused_hpos
; i
++)
733 fputc (' ', termscript
);
736 cmplus (first_unused_hpos
- curX
);
741 write_glyphs (string
, len
)
742 register GLYPH
*string
;
746 register int tlen
= GLYPH_TABLE_LENGTH
;
747 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
749 if (write_glyphs_hook
750 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
752 (*write_glyphs_hook
) (string
, len
);
756 highlight_if_desired ();
759 /* Don't dare write in last column of bottom line, if AutoWrap,
760 since that would scroll the whole frame on some terminals. */
763 && curY
+ 1 == FRAME_HEIGHT (selected_frame
)
764 && (curX
+ len
- (chars_wasted
[curY
] & 077)
765 == FRAME_WIDTH (selected_frame
)))
772 /* Check quickly for G beyond length of table.
773 That implies it isn't an alias and is simple. */
777 putc (g
& 0xff, stdout
);
781 putc (g
& 0xff, termscript
);
785 /* G has an entry in Vglyph_table,
786 so process any alias and then test for simpleness. */
787 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
788 g
= GLYPH_ALIAS (tbase
, g
);
789 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
793 /* Here if G (or its definition as an alias) is not simple. */
794 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
),
799 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
),
807 /* If start is zero, insert blanks instead of a string at start */
809 insert_glyphs (start
, len
)
810 register GLYPH
*start
;
815 register int tlen
= GLYPH_TABLE_LENGTH
;
816 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
818 if (insert_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
820 (*insert_glyphs_hook
) (start
, len
);
823 highlight_if_desired ();
825 if (TS_ins_multi_chars
)
827 buf
= tparam (TS_ins_multi_chars
, 0, 0, len
);
831 write_glyphs (start
, len
);
839 OUTPUT1_IF (TS_ins_char
);
845 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
847 putc (g
& 0xff, stdout
);
851 putc (g
& 0xff, termscript
);
855 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
), stdout
);
859 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
),
863 OUTPUT1_IF (TS_pad_inserted_char
);
874 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
876 (*delete_glyphs_hook
) (n
);
880 if (delete_in_insert_mode
)
887 OUTPUT_IF (TS_delete_mode
);
890 if (TS_del_multi_chars
)
892 buf
= tparam (TS_del_multi_chars
, 0, 0, n
);
897 for (i
= 0; i
< n
; i
++)
898 OUTPUT1 (TS_del_char
);
899 if (!delete_in_insert_mode
)
900 OUTPUT_IF (TS_end_delete_mode
);
903 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
905 ins_del_lines (vpos
, n
)
908 char *multi
= n
> 0 ? TS_ins_multi_lines
: TS_del_multi_lines
;
909 char *single
= n
> 0 ? TS_ins_line
: TS_del_line
;
910 char *scroll
= n
> 0 ? TS_rev_scroll
: TS_fwd_scroll
;
912 register int i
= n
> 0 ? n
: -n
;
915 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
917 (*ins_del_lines_hook
) (vpos
, n
);
921 /* If the lines below the insertion are being pushed
922 into the end of the window, this is the same as clearing;
923 and we know the lines are already clear, since the matching
924 deletion has already been done. So can ignore this. */
925 /* If the lines below the deletion are blank lines coming
926 out of the end of the window, don't bother,
927 as there will be a matching inslines later that will flush them. */
928 if (scroll_region_ok
&& vpos
+ i
>= specified_window
)
930 if (!memory_below_frame
&& vpos
+ i
>= FRAME_HEIGHT (selected_frame
))
935 raw_cursor_to (vpos
, 0);
936 background_highlight ();
937 buf
= tparam (multi
, 0, 0, i
);
943 raw_cursor_to (vpos
, 0);
944 background_highlight ();
952 set_scroll_region (vpos
, specified_window
);
954 raw_cursor_to (specified_window
- 1, 0);
956 raw_cursor_to (vpos
, 0);
957 background_highlight ();
959 OUTPUTL (scroll
, specified_window
- vpos
);
960 set_scroll_region (0, specified_window
);
963 if (TN_standout_width
>= 0)
968 : FRAME_HEIGHT (selected_frame
));
972 bcopy (&chars_wasted
[vpos
- n
], &chars_wasted
[vpos
],
973 lower_limit
- vpos
+ n
);
974 bzero (&chars_wasted
[lower_limit
+ n
], - n
);
978 bcopy (&chars_wasted
[vpos
], ©buf
[vpos
], lower_limit
- vpos
- n
);
979 bcopy (©buf
[vpos
], &chars_wasted
[vpos
+ n
],
980 lower_limit
- vpos
- n
);
981 bzero (&chars_wasted
[vpos
], n
);
984 if (!scroll_region_ok
&& memory_below_frame
&& n
< 0)
986 cursor_to (FRAME_HEIGHT (selected_frame
) + n
, 0);
991 /* Compute cost of sending "str", in characters,
992 not counting any line-dependent padding. */
1000 tputs (str
, 0, evalcost
);
1004 /* Compute cost of sending "str", in characters,
1005 counting any line-dependent padding at one line. */
1008 string_cost_one_line (str
)
1013 tputs (str
, 1, evalcost
);
1017 /* Compute per line amount of line-dependent padding,
1018 in tenths of characters. */
1026 tputs (str
, 0, evalcost
);
1029 tputs (str
, 10, evalcost
);
1034 /* char_ins_del_cost[n] is cost of inserting N characters.
1035 char_ins_del_cost[-n] is cost of deleting N characters.
1036 The length of this vector is based on max_frame_width. */
1038 int *char_ins_del_vector
;
1040 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH ((f))])
1045 calculate_ins_del_char_costs (frame
)
1048 int ins_startup_cost
, del_startup_cost
;
1049 int ins_cost_per_char
, del_cost_per_char
;
1053 if (TS_ins_multi_chars
)
1055 ins_cost_per_char
= 0;
1056 ins_startup_cost
= string_cost_one_line (TS_ins_multi_chars
);
1058 else if (TS_ins_char
|| TS_pad_inserted_char
1059 || (TS_insert_mode
&& TS_end_insert_mode
))
1061 ins_startup_cost
= (30 * (string_cost (TS_insert_mode
)
1062 + string_cost (TS_end_insert_mode
))) / 100;
1063 ins_cost_per_char
= (string_cost_one_line (TS_ins_char
)
1064 + string_cost_one_line (TS_pad_inserted_char
));
1068 ins_startup_cost
= 9999;
1069 ins_cost_per_char
= 0;
1072 if (TS_del_multi_chars
)
1074 del_cost_per_char
= 0;
1075 del_startup_cost
= string_cost_one_line (TS_del_multi_chars
);
1077 else if (TS_del_char
)
1079 del_startup_cost
= (string_cost (TS_delete_mode
)
1080 + string_cost (TS_end_delete_mode
));
1081 if (delete_in_insert_mode
)
1082 del_startup_cost
/= 2;
1083 del_cost_per_char
= string_cost_one_line (TS_del_char
);
1087 del_startup_cost
= 9999;
1088 del_cost_per_char
= 0;
1091 /* Delete costs are at negative offsets */
1092 p
= &char_ins_del_cost (frame
)[0];
1093 for (i
= FRAME_WIDTH (frame
); --i
>= 0;)
1094 *--p
= (del_startup_cost
+= del_cost_per_char
);
1096 /* Doing nothing is free */
1097 p
= &char_ins_del_cost (frame
)[0];
1100 /* Insert costs are at positive offsets */
1101 for (i
= FRAME_WIDTH (frame
); --i
>= 0;)
1102 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1105 extern do_line_insertion_deletion_costs ();
1107 calculate_costs (frame
)
1110 register char *f
= (TS_set_scroll_region
1111 ? TS_set_scroll_region
1112 : TS_set_scroll_region_1
);
1114 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1116 scroll_region_cost
= string_cost (f
);
1117 #ifdef HAVE_X_WINDOWS
1118 if (FRAME_X_P (frame
))
1120 do_line_insertion_deletion_costs (frame
, 0, ".5*", 0, ".5*",
1122 x_screen_planes (frame
));
1123 scroll_region_cost
= 0;
1128 /* These variables are only used for terminal stuff. They are allocated
1129 once for the terminal frame of X-windows emacs, but not used afterwards.
1131 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1132 X turns off char_ins_del_ok.
1134 chars_wasted and copybuf are only used here in term.c in cases where
1135 the term hook isn't called. */
1137 max_frame_height
= max (max_frame_height
, FRAME_HEIGHT (frame
));
1138 max_frame_width
= max (max_frame_width
, FRAME_WIDTH (frame
));
1140 if (chars_wasted
!= 0)
1141 chars_wasted
= (char *) xrealloc (chars_wasted
, max_frame_height
);
1143 chars_wasted
= (char *) xmalloc (max_frame_height
);
1146 copybuf
= (char *) xrealloc (copybuf
, max_frame_height
);
1148 copybuf
= (char *) xmalloc (max_frame_height
);
1150 if (char_ins_del_vector
!= 0)
1152 = (int *) xrealloc (char_ins_del_vector
,
1154 + 2 * max_frame_width
* sizeof (int)));
1157 = (int *) xmalloc (sizeof (int)
1158 + 2 * max_frame_width
* sizeof (int));
1160 bzero (chars_wasted
, max_frame_height
);
1161 bzero (copybuf
, max_frame_height
);
1162 bzero (char_ins_del_vector
, (sizeof (int)
1163 + 2 * max_frame_width
* sizeof (int)));
1165 if (f
&& (!TS_ins_line
&& !TS_del_line
))
1166 do_line_insertion_deletion_costs (frame
,
1167 TS_rev_scroll
, TS_ins_multi_lines
,
1168 TS_fwd_scroll
, TS_del_multi_lines
,
1171 do_line_insertion_deletion_costs (frame
,
1172 TS_ins_line
, TS_ins_multi_lines
,
1173 TS_del_line
, TS_del_multi_lines
,
1176 calculate_ins_del_char_costs (frame
);
1178 /* Don't use TS_repeat if its padding is worse than sending the chars */
1179 if (TS_repeat
&& per_line_cost (TS_repeat
) * baud_rate
< 9000)
1180 RPov
= string_cost (TS_repeat
);
1182 RPov
= FRAME_WIDTH (frame
) * 2;
1184 cmcostinit (); /* set up cursor motion costs */
1191 /* Termcap capability names that correspond directly to X keysyms.
1192 Some of these (marked "terminfo") aren't supplied by old-style
1193 (Berkeley) termcap entries. They're listed in X keysym order;
1194 except we put the keypad keys first, so that if they clash with
1195 other keys (as on the IBM PC keyboard) they get overridden.
1198 static struct fkey_table keys
[] = {
1199 "kh", "home", /* termcap */
1200 "kl", "left", /* termcap */
1201 "ku", "up", /* termcap */
1202 "kr", "right", /* termcap */
1203 "kd", "down", /* termcap */
1204 "%8", "prior", /* terminfo */
1205 "%5", "next", /* terminfo */
1206 "@7", "end", /* terminfo */
1207 "@1", "begin", /* terminfo */
1208 "*6", "select", /* terminfo */
1209 "%9", "print", /* terminfo */
1210 "@4", "execute", /* terminfo --- actually the `command' key */
1212 * "insert" --- see below
1214 "&8", "undo", /* terminfo */
1215 "%0", "redo", /* terminfo */
1216 "%7", "menu", /* terminfo --- actually the `options' key */
1217 "@0", "find", /* terminfo */
1218 "@2", "cancel", /* terminfo */
1219 "%1", "help", /* terminfo */
1221 * "break" goes here, but can't be reliably intercepted with termcap
1223 "&4", "reset", /* terminfo --- actually `restart' */
1225 * "system" and "user" --- no termcaps
1227 "kE", "clearline", /* terminfo */
1228 "kA", "insertline", /* terminfo */
1229 "kL", "deleteline", /* terminfo */
1230 "kI", "insertchar", /* terminfo */
1231 "kD", "deletechar", /* terminfo */
1232 "kB", "backtab", /* terminfo */
1234 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1236 "@8", "kp-enter", /* terminfo */
1238 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1239 * "kp-multiply", "kp-add", "kp-separator",
1240 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1241 * --- no termcaps for any of these.
1243 "K4", "kp-1", /* terminfo */
1245 * "kp-2" --- no termcap
1247 "K5", "kp-3", /* terminfo */
1249 * "kp-4" --- no termcap
1251 "K2", "kp-5", /* terminfo */
1253 * "kp-6" --- no termcap
1255 "K1", "kp-7", /* terminfo */
1257 * "kp-8" --- no termcap
1259 "K3", "kp-9", /* terminfo */
1261 * "kp-equal" --- no termcap
1274 static char **term_get_fkeys_arg
;
1275 static Lisp_Object
term_get_fkeys_1 ();
1277 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1278 This function scans the termcap function key sequence entries, and
1279 adds entries to Vfunction_key_map for each function key it finds. */
1282 term_get_fkeys (address
)
1285 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1286 errors during the call. The only errors should be from Fdefine_key
1287 when given a key sequence containing an invalid prefix key. If the
1288 termcap defines function keys which use a prefix that is already bound
1289 to a command by the default bindings, we should silently ignore that
1290 function key specification, rather than giving the user an error and
1291 refusing to run at all on such a terminal. */
1293 extern Lisp_Object
Fidentity ();
1294 term_get_fkeys_arg
= address
;
1295 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1303 char **address
= term_get_fkeys_arg
;
1305 /* This can happen if CANNOT_DUMP or with strange options. */
1307 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1309 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1311 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1313 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1314 Fmake_vector (make_number (1),
1315 intern (keys
[i
].name
)));
1318 /* The uses of the "k0" capability are inconsistent; sometimes it
1319 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1320 We will attempt to politely accommodate both systems by testing for
1321 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1324 char *k_semi
= tgetstr ("k;", address
);
1325 char *k0
= tgetstr ("k0", address
);
1326 char *k0_name
= "f10";
1330 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1331 Fmake_vector (make_number (1), intern ("f10")));
1336 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1337 Fmake_vector (make_number (1), intern (k0_name
)));
1340 /* Set up cookies for numbered function keys above f10. */
1342 char fcap
[3], fkey
[4];
1344 fcap
[0] = 'F'; fcap
[2] = '\0';
1345 for (i
= 11; i
< 64; i
++)
1348 fcap
[1] = '1' + i
- 11;
1350 fcap
[1] = 'A' + i
- 20;
1352 fcap
[1] = 'a' + i
- 46;
1355 char *sequence
= tgetstr (fcap
, address
);
1358 sprintf (fkey
, "f%d", i
);
1359 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1360 Fmake_vector (make_number (1),
1368 * Various mappings to try and get a better fit.
1371 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1372 if (!tgetstr (cap1, address)) \
1374 char *sequence = tgetstr (cap2, address); \
1376 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1377 Fmake_vector (make_number (1), \
1381 /* if there's no key_next keycap, map key_npage to `next' keysym */
1382 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1383 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1384 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1385 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1386 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1388 /* IBM has their own non-standard dialect of terminfo.
1389 If the standard name isn't found, try the IBM name. */
1390 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1391 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1392 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1393 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1394 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1395 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1396 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1397 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1398 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1399 #undef CONDITIONAL_REASSIGN
1404 term_init (terminal_type
)
1405 char *terminal_type
;
1408 char **address
= &area
;
1414 initialize_win_nt_display ();
1418 area
= (char *) malloc (2044);
1423 FrameRows
= FRAME_HEIGHT (selected_frame
);
1424 FrameCols
= FRAME_WIDTH (selected_frame
);
1425 specified_window
= FRAME_HEIGHT (selected_frame
);
1427 delete_in_insert_mode
= 1;
1430 scroll_region_ok
= 0;
1432 /* Seems to insert lines when it's not supposed to, messing
1433 up the display. In doing a trace, it didn't seem to be
1434 called much, so I don't think we're losing anything by
1437 line_ins_del_ok
= 0;
1438 char_ins_del_ok
= 1;
1442 FRAME_CAN_HAVE_SCROLL_BARS (selected_frame
) = 0;
1443 FRAME_HAS_VERTICAL_SCROLL_BARS (selected_frame
) = 0;
1446 #endif /* WINDOWSNT */
1450 status
= tgetent (buffer
, terminal_type
);
1454 fatal ("Cannot open terminfo database file.\n");
1456 fatal ("Cannot open termcap database file.\n");
1462 fatal ("Terminal type %s is not defined.\n\
1463 If that is not the actual type of terminal you have,\n\
1464 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1465 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1466 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.\n",
1469 fatal ("Terminal type %s is not defined.\n\
1470 If that is not the actual type of terminal you have,\n\
1471 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1472 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1473 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.\n",
1478 area
= (char *) malloc (2044);
1480 area
= (char *) malloc (strlen (buffer
));
1481 #endif /* not TERMINFO */
1485 TS_ins_line
= tgetstr ("al", address
);
1486 TS_ins_multi_lines
= tgetstr ("AL", address
);
1487 TS_bell
= tgetstr ("bl", address
);
1488 BackTab
= tgetstr ("bt", address
);
1489 TS_clr_to_bottom
= tgetstr ("cd", address
);
1490 TS_clr_line
= tgetstr ("ce", address
);
1491 TS_clr_frame
= tgetstr ("cl", address
);
1492 ColPosition
= tgetstr ("ch", address
);
1493 AbsPosition
= tgetstr ("cm", address
);
1494 CR
= tgetstr ("cr", address
);
1495 TS_set_scroll_region
= tgetstr ("cs", address
);
1496 TS_set_scroll_region_1
= tgetstr ("cS", address
);
1497 RowPosition
= tgetstr ("cv", address
);
1498 TS_del_char
= tgetstr ("dc", address
);
1499 TS_del_multi_chars
= tgetstr ("DC", address
);
1500 TS_del_line
= tgetstr ("dl", address
);
1501 TS_del_multi_lines
= tgetstr ("DL", address
);
1502 TS_delete_mode
= tgetstr ("dm", address
);
1503 TS_end_delete_mode
= tgetstr ("ed", address
);
1504 TS_end_insert_mode
= tgetstr ("ei", address
);
1505 Home
= tgetstr ("ho", address
);
1506 TS_ins_char
= tgetstr ("ic", address
);
1507 TS_ins_multi_chars
= tgetstr ("IC", address
);
1508 TS_insert_mode
= tgetstr ("im", address
);
1509 TS_pad_inserted_char
= tgetstr ("ip", address
);
1510 TS_end_keypad_mode
= tgetstr ("ke", address
);
1511 TS_keypad_mode
= tgetstr ("ks", address
);
1512 LastLine
= tgetstr ("ll", address
);
1513 Right
= tgetstr ("nd", address
);
1514 Down
= tgetstr ("do", address
);
1516 Down
= tgetstr ("nl", address
); /* Obsolete name for "do" */
1518 /* VMS puts a carriage return before each linefeed,
1519 so it is not safe to use linefeeds. */
1520 if (Down
&& Down
[0] == '\n' && Down
[1] == '\0')
1523 if (tgetflag ("bs"))
1524 Left
= "\b"; /* can't possibly be longer! */
1525 else /* (Actually, "bs" is obsolete...) */
1526 Left
= tgetstr ("le", address
);
1528 Left
= tgetstr ("bc", address
); /* Obsolete name for "le" */
1529 TS_pad_char
= tgetstr ("pc", address
);
1530 TS_repeat
= tgetstr ("rp", address
);
1531 TS_end_standout_mode
= tgetstr ("se", address
);
1532 TS_fwd_scroll
= tgetstr ("sf", address
);
1533 TS_standout_mode
= tgetstr ("so", address
);
1534 TS_rev_scroll
= tgetstr ("sr", address
);
1535 Wcm
.cm_tab
= tgetstr ("ta", address
);
1536 TS_end_termcap_modes
= tgetstr ("te", address
);
1537 TS_termcap_modes
= tgetstr ("ti", address
);
1538 Up
= tgetstr ("up", address
);
1539 TS_visible_bell
= tgetstr ("vb", address
);
1540 TS_end_visual_mode
= tgetstr ("ve", address
);
1541 TS_visual_mode
= tgetstr ("vs", address
);
1542 TS_set_window
= tgetstr ("wi", address
);
1543 MultiUp
= tgetstr ("UP", address
);
1544 MultiDown
= tgetstr ("DO", address
);
1545 MultiLeft
= tgetstr ("LE", address
);
1546 MultiRight
= tgetstr ("RI", address
);
1548 MagicWrap
= tgetflag ("xn");
1549 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
1550 the former flag imply the latter. */
1551 AutoWrap
= MagicWrap
|| tgetflag ("am");
1552 memory_below_frame
= tgetflag ("db");
1553 TF_hazeltine
= tgetflag ("hz");
1554 must_write_spaces
= tgetflag ("in");
1555 meta_key
= tgetflag ("km") || tgetflag ("MT");
1556 TF_insmode_motion
= tgetflag ("mi");
1557 TF_standout_motion
= tgetflag ("ms");
1558 TF_underscore
= tgetflag ("ul");
1559 TF_xs
= tgetflag ("xs");
1560 TF_teleray
= tgetflag ("xt");
1562 term_get_fkeys (address
);
1564 /* Get frame size from system, or else from termcap. */
1565 get_frame_size (&FRAME_WIDTH (selected_frame
),
1566 &FRAME_HEIGHT (selected_frame
));
1567 if (FRAME_WIDTH (selected_frame
) <= 0)
1568 FRAME_WIDTH (selected_frame
) = tgetnum ("co");
1569 if (FRAME_HEIGHT (selected_frame
) <= 0)
1570 FRAME_HEIGHT (selected_frame
) = tgetnum ("li");
1572 if (FRAME_HEIGHT (selected_frame
) < 3
1573 || FRAME_WIDTH (selected_frame
) < 3)
1574 fatal ("Screen size %dx%d is too small.\n",
1575 FRAME_HEIGHT (selected_frame
), FRAME_WIDTH (selected_frame
));
1577 min_padding_speed
= tgetnum ("pb");
1578 TN_standout_width
= tgetnum ("sg");
1579 TabWidth
= tgetnum ("tw");
1582 /* These capabilities commonly use ^J.
1583 I don't know why, but sending them on VMS does not work;
1584 it causes following spaces to be lost, sometimes.
1585 For now, the simplest fix is to avoid using these capabilities ever. */
1586 if (Down
&& Down
[0] == '\n')
1594 TS_fwd_scroll
= Down
;
1596 PC
= TS_pad_char
? *TS_pad_char
: 0;
1601 /* Turned off since /etc/termcap seems to have :ta= for most terminals
1602 and newer termcap doc does not seem to say there is a default.
1607 if (TS_standout_mode
== 0)
1609 TN_standout_width
= tgetnum ("ug");
1610 TS_end_standout_mode
= tgetstr ("ue", address
);
1611 TS_standout_mode
= tgetstr ("us", address
);
1614 /* If no `se' string, try using a `me' string instead.
1615 If that fails, we can't use standout mode at all. */
1616 if (TS_end_standout_mode
== 0)
1618 char *s
= tgetstr ("me", address
);
1620 TS_end_standout_mode
= s
;
1622 TS_standout_mode
= 0;
1628 /* Teleray: most programs want a space in front of TS_standout_mode,
1629 but Emacs can do without it (and give one extra column). */
1630 TS_standout_mode
= "\033RD";
1631 TN_standout_width
= 1;
1632 /* But that means we cannot rely on ^M to go to column zero! */
1634 /* LF can't be trusted either -- can alter hpos */
1635 /* if move at column 0 thru a line with TS_standout_mode */
1639 /* Special handling for certain terminal types known to need it */
1641 if (!strcmp (terminal_type
, "supdup"))
1643 memory_below_frame
= 1;
1644 Wcm
.cm_losewrap
= 1;
1646 if (!strncmp (terminal_type
, "c10", 3)
1647 || !strcmp (terminal_type
, "perq"))
1649 /* Supply a makeshift :wi string.
1650 This string is not valid in general since it works only
1651 for windows starting at the upper left corner;
1652 but that is all Emacs uses.
1654 This string works only if the frame is using
1655 the top of the video memory, because addressing is memory-relative.
1656 So first check the :ti string to see if that is true.
1658 It would be simpler if the :wi string could go in the termcap
1659 entry, but it can't because it is not fully valid.
1660 If it were in the termcap entry, it would confuse other programs. */
1663 p
= TS_termcap_modes
;
1664 while (*p
&& strcmp (p
, "\033v "))
1667 TS_set_window
= "\033v%C %C %C %C ";
1669 /* Termcap entry often fails to have :in: flag */
1670 must_write_spaces
= 1;
1671 /* :ti string typically fails to have \E^G! in it */
1672 /* This limits scope of insert-char to one line. */
1673 strcpy (area
, TS_termcap_modes
);
1674 strcat (area
, "\033\007!");
1675 TS_termcap_modes
= area
;
1676 area
+= strlen (area
) + 1;
1678 /* Change all %+ parameters to %C, to handle
1679 values above 96 correctly for the C100. */
1682 if (p
[0] == '%' && p
[1] == '+')
1688 FrameRows
= FRAME_HEIGHT (selected_frame
);
1689 FrameCols
= FRAME_WIDTH (selected_frame
);
1690 specified_window
= FRAME_HEIGHT (selected_frame
);
1692 if (Wcm_init () == -1) /* can't do cursor motion */
1694 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1695 It lacks the ability to position the cursor.\n\
1696 If that is not the actual type of terminal you have, use either the\n\
1697 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
1698 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.\n",
1702 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1703 It lacks the ability to position the cursor.\n\
1704 If that is not the actual type of terminal you have,\n\
1705 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1706 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1707 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.\n",
1709 # else /* TERMCAP */
1710 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1711 It lacks the ability to position the cursor.\n\
1712 If that is not the actual type of terminal you have,\n\
1713 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1714 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1715 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.\n",
1717 # endif /* TERMINFO */
1719 if (FRAME_HEIGHT (selected_frame
) <= 0
1720 || FRAME_WIDTH (selected_frame
) <= 0)
1721 fatal ("The frame size has not been specified.");
1723 delete_in_insert_mode
1724 = TS_delete_mode
&& TS_insert_mode
1725 && !strcmp (TS_delete_mode
, TS_insert_mode
);
1727 se_is_so
= (TS_standout_mode
1728 && TS_end_standout_mode
1729 && !strcmp (TS_standout_mode
, TS_end_standout_mode
));
1731 /* Remove width of standout marker from usable width of line */
1732 if (TN_standout_width
> 0)
1733 FRAME_WIDTH (selected_frame
) -= TN_standout_width
;
1735 UseTabs
= tabs_safe_p () && TabWidth
== 8;
1739 && (TS_set_window
|| TS_set_scroll_region
|| TS_set_scroll_region_1
));
1741 line_ins_del_ok
= (((TS_ins_line
|| TS_ins_multi_lines
)
1742 && (TS_del_line
|| TS_del_multi_lines
))
1743 || (scroll_region_ok
&& TS_fwd_scroll
&& TS_rev_scroll
));
1745 char_ins_del_ok
= ((TS_ins_char
|| TS_insert_mode
1746 || TS_pad_inserted_char
|| TS_ins_multi_chars
)
1747 && (TS_del_char
|| TS_del_multi_chars
));
1749 fast_clear_end_of_line
= TS_clr_line
!= 0;
1752 if (read_socket_hook
) /* Baudrate is somewhat */
1753 /* meaningless in this case */
1756 FRAME_CAN_HAVE_SCROLL_BARS (selected_frame
) = 0;
1757 FRAME_HAS_VERTICAL_SCROLL_BARS (selected_frame
) = 0;
1761 fatal (str
, arg1
, arg2
)
1762 char *str
, *arg1
, *arg2
;
1764 fprintf (stderr
, "emacs: ");
1765 fprintf (stderr
, str
, arg1
, arg2
);
1772 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
1773 "Non-nil means the system uses terminfo rather than termcap.\n\
1774 This variable can be used by terminal emulator packages.");
1776 system_uses_terminfo
= 1;
1778 system_uses_terminfo
= 0;