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 /* Function to use to ring the bell. */
47 Lisp_Object Vring_bell_function
;
49 /* Terminal characteristics that higher levels want to look at.
50 These are all extern'd in termchar.h */
52 int must_write_spaces
; /* Nonzero means spaces in the text
53 must actually be output; can't just skip
54 over some columns to leave them blank. */
55 int min_padding_speed
; /* Speed below which no padding necessary */
57 int line_ins_del_ok
; /* Terminal can insert and delete lines */
58 int char_ins_del_ok
; /* Terminal can insert and delete chars */
59 int scroll_region_ok
; /* Terminal supports setting the
61 int scroll_region_cost
; /* Cost of setting a scroll window,
62 measured in characters */
63 int memory_below_frame
; /* Terminal remembers lines
64 scrolled off bottom */
65 int fast_clear_end_of_line
; /* Terminal has a `ce' string */
67 /* Nonzero means no need to redraw the entire frame on resuming
68 a suspended Emacs. This is useful on terminals with multiple pages,
69 where one page is used for Emacs and another for all else. */
70 int no_redraw_on_reenter
;
72 /* Hook functions that you can set to snap out the functions in this file.
73 These are all extern'd in termhooks.h */
75 int (*cursor_to_hook
) ();
76 int (*raw_cursor_to_hook
) ();
78 int (*clear_to_end_hook
) ();
79 int (*clear_frame_hook
) ();
80 int (*clear_end_of_line_hook
) ();
82 int (*ins_del_lines_hook
) ();
84 int (*change_line_highlight_hook
) ();
85 int (*reassert_line_highlight_hook
) ();
87 int (*insert_glyphs_hook
) ();
88 int (*write_glyphs_hook
) ();
89 int (*delete_glyphs_hook
) ();
91 int (*ring_bell_hook
) ();
93 int (*reset_terminal_modes_hook
) ();
94 int (*set_terminal_modes_hook
) ();
95 int (*update_begin_hook
) ();
96 int (*update_end_hook
) ();
97 int (*set_terminal_window_hook
) ();
99 int (*read_socket_hook
) ();
101 int (*frame_up_to_date_hook
) ();
103 /* Return the current position of the mouse.
105 Set *f to the frame the mouse is in, or zero if the mouse is in no
106 Emacs frame. If it is set to zero, all the other arguments are
109 If the motion started in a scroll bar, set *bar_window to the
110 scroll bar's window, *part to the part the mouse is currently over,
111 *x to the position of the mouse along the scroll bar, and *y to the
112 overall length of the scroll bar.
114 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
115 row of the character cell the mouse is over.
117 Set *time to the time the mouse was at the returned position.
119 This should clear mouse_moved until the next motion
121 void (*mouse_position_hook
) ( /* FRAME_PTR *f, int insist,
122 Lisp_Object *bar_window,
123 enum scroll_bar_part *part,
126 unsigned long *time */ );
128 /* When reading from a minibuffer in a different frame, Emacs wants
129 to shift the highlight from the selected frame to the minibuffer's
130 frame; under X, this means it lies about where the focus is.
131 This hook tells the window system code to re-decide where to put
133 void (*frame_rehighlight_hook
) ( /* FRAME_PTR f */ );
135 /* If we're displaying frames using a window system that can stack
136 frames on top of each other, this hook allows you to bring a frame
137 to the front, or bury it behind all the other windows. If this
138 hook is zero, that means the device we're displaying on doesn't
139 support overlapping frames, so there's no need to raise or lower
142 If RAISE is non-zero, F is brought to the front, before all other
143 windows. If RAISE is zero, F is sent to the back, behind all other
145 void (*frame_raise_lower_hook
) ( /* FRAME_PTR f, int raise */ );
147 /* Set the vertical scroll bar for WINDOW to have its upper left corner
148 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
149 indicate that we are displaying PORTION characters out of a total
150 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
151 have a scroll bar, create one for it. */
152 void (*set_vertical_scroll_bar_hook
)
153 ( /* struct window *window,
154 int portion, int whole, int position */ );
157 /* The following three hooks are used when we're doing a thorough
158 redisplay of the frame. We don't explicitly know which scroll bars
159 are going to be deleted, because keeping track of when windows go
160 away is a real pain - can you say set-window-configuration?
161 Instead, we just assert at the beginning of redisplay that *all*
162 scroll bars are to be removed, and then save scroll bars from the
163 fiery pit when we actually redisplay their window. */
165 /* Arrange for all scroll bars on FRAME to be removed at the next call
166 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
167 `*redeem_scroll_bar_hook' is applied to its window before the judgement.
169 This should be applied to each frame each time its window tree is
170 redisplayed, even if it is not displaying scroll bars at the moment;
171 if the HAS_SCROLL_BARS flag has just been turned off, only calling
172 this and the judge_scroll_bars_hook will get rid of them.
174 If non-zero, this hook should be safe to apply to any frame,
175 whether or not it can support scroll bars, and whether or not it is
176 currently displaying them. */
177 void (*condemn_scroll_bars_hook
)( /* FRAME_PTR *frame */ );
179 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
180 Note that it's okay to redeem a scroll bar that is not condemned. */
181 void (*redeem_scroll_bar_hook
)( /* struct window *window */ );
183 /* Remove all scroll bars on FRAME that haven't been saved since the
184 last call to `*condemn_scroll_bars_hook'.
186 This should be applied to each frame after each time its window
187 tree is redisplayed, even if it is not displaying scroll bars at the
188 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
189 calling this and condemn_scroll_bars_hook will get rid of them.
191 If non-zero, this hook should be safe to apply to any frame,
192 whether or not it can support scroll bars, and whether or not it is
193 currently displaying them. */
194 void (*judge_scroll_bars_hook
)( /* FRAME_PTR *FRAME */ );
197 /* Strings, numbers and flags taken from the termcap entry. */
199 char *TS_ins_line
; /* termcap "al" */
200 char *TS_ins_multi_lines
; /* "AL" (one parameter, # lines to insert) */
201 char *TS_bell
; /* "bl" */
202 char *TS_clr_to_bottom
; /* "cd" */
203 char *TS_clr_line
; /* "ce", clear to end of line */
204 char *TS_clr_frame
; /* "cl" */
205 char *TS_set_scroll_region
; /* "cs" (2 params, first line and last line) */
206 char *TS_set_scroll_region_1
; /* "cS" (4 params: total lines,
207 lines above scroll region, lines below it,
208 total lines again) */
209 char *TS_del_char
; /* "dc" */
210 char *TS_del_multi_chars
; /* "DC" (one parameter, # chars to delete) */
211 char *TS_del_line
; /* "dl" */
212 char *TS_del_multi_lines
; /* "DL" (one parameter, # lines to delete) */
213 char *TS_delete_mode
; /* "dm", enter character-delete mode */
214 char *TS_end_delete_mode
; /* "ed", leave character-delete mode */
215 char *TS_end_insert_mode
; /* "ei", leave character-insert mode */
216 char *TS_ins_char
; /* "ic" */
217 char *TS_ins_multi_chars
; /* "IC" (one parameter, # chars to insert) */
218 char *TS_insert_mode
; /* "im", enter character-insert mode */
219 char *TS_pad_inserted_char
; /* "ip". Just padding, no commands. */
220 char *TS_end_keypad_mode
; /* "ke" */
221 char *TS_keypad_mode
; /* "ks" */
222 char *TS_pad_char
; /* "pc", char to use as padding */
223 char *TS_repeat
; /* "rp" (2 params, # times to repeat
224 and character to be repeated) */
225 char *TS_end_standout_mode
; /* "se" */
226 char *TS_fwd_scroll
; /* "sf" */
227 char *TS_standout_mode
; /* "so" */
228 char *TS_rev_scroll
; /* "sr" */
229 char *TS_end_termcap_modes
; /* "te" */
230 char *TS_termcap_modes
; /* "ti" */
231 char *TS_visible_bell
; /* "vb" */
232 char *TS_end_visual_mode
; /* "ve" */
233 char *TS_visual_mode
; /* "vi" */
234 char *TS_set_window
; /* "wi" (4 params, start and end of window,
235 each as vpos and hpos) */
237 int TF_hazeltine
; /* termcap hz flag. */
238 int TF_insmode_motion
; /* termcap mi flag: can move while in insert mode. */
239 int TF_standout_motion
; /* termcap mi flag: can move while in standout mode. */
240 int TF_underscore
; /* termcap ul flag: _ underlines if overstruck on
241 nonblank position. Must clear before writing _. */
242 int TF_teleray
; /* termcap xt flag: many weird consequences.
245 int TF_xs
; /* Nonzero for "xs". If set together with
246 TN_standout_width == 0, it means don't bother
247 to write any end-standout cookies. */
249 int TN_standout_width
; /* termcap sg number: width occupied by standout
252 static int RPov
; /* # chars to start a TS_repeat */
254 static int delete_in_insert_mode
; /* delete mode == insert mode */
256 static int se_is_so
; /* 1 if same string both enters and leaves
261 /* The largest frame width in any call to calculate_costs. */
263 /* The largest frame height in any call to calculate_costs. */
264 int max_frame_height
;
266 /* Number of chars of space used for standout marker at beginning of line,
267 or'd with 0100. Zero if no standout marker at all.
268 The length of these vectors is max_frame_height.
270 Used IFF TN_standout_width >= 0. */
272 static char *chars_wasted
;
273 static char *copybuf
;
275 /* nonzero means supposed to write text in standout mode. */
276 int standout_requested
;
278 int insert_mode
; /* Nonzero when in insert mode. */
279 int standout_mode
; /* Nonzero when in standout mode. */
281 /* Size of window specified by higher levels.
282 This is the number of lines, from the top of frame downwards,
283 which can participate in insert-line/delete-line operations.
285 Effectively it excludes the bottom frame_height - specified_window_size
286 lines from those operations. */
288 int specified_window
;
290 /* Frame currently being redisplayed; 0 if not currently redisplaying.
291 (Direct output does not count). */
293 FRAME_PTR updating_frame
;
295 /* Provided for lisp packages. */
296 static int system_uses_terminfo
;
300 extern char *tgetstr ();
304 /* We aren't X windows, but we aren't termcap either. This makes me
305 uncertain as to what value to use for frame.output_method. For
306 this file, we'll define FRAME_TERMCAP_P to be zero so that our
307 output hooks get called instead of the termcap functions. Probably
308 the best long-term solution is to define an output_windows_nt... */
310 #undef FRAME_TERMCAP_P
311 #define FRAME_TERMCAP_P(_f_) 0
312 #endif /* WINDOWSNT */
316 if (! NILP (Vring_bell_function
))
318 Lisp_Object function
;
320 /* Temporarily set the global variable to nil
321 so that if we get an error, it stays nil
322 and we don't call it over and over.
324 We don't specbind it, because that would carefully
325 restore the bad value if there's an error
326 and make the loop of errors happen anyway. */
327 function
= Vring_bell_function
;
328 Vring_bell_function
= Qnil
;
332 Vring_bell_function
= function
;
336 if (! FRAME_TERMCAP_P (selected_frame
))
338 (*ring_bell_hook
) ();
341 OUTPUT (TS_visible_bell
&& visible_bell
? TS_visible_bell
: TS_bell
);
344 set_terminal_modes ()
346 if (! FRAME_TERMCAP_P (selected_frame
))
348 (*set_terminal_modes_hook
) ();
351 OUTPUT_IF (TS_termcap_modes
);
352 OUTPUT_IF (TS_visual_mode
);
353 OUTPUT_IF (TS_keypad_mode
);
357 reset_terminal_modes ()
359 if (! FRAME_TERMCAP_P (selected_frame
))
361 (*reset_terminal_modes_hook
) ();
364 if (TN_standout_width
< 0)
365 turn_off_highlight ();
367 OUTPUT_IF (TS_end_keypad_mode
);
368 OUTPUT_IF (TS_end_visual_mode
);
369 OUTPUT_IF (TS_end_termcap_modes
);
370 /* Output raw CR so kernel can track the cursor hpos. */
371 /* But on magic-cookie terminals this can erase an end-standout marker and
372 cause the rest of the frame to be in standout, so move down first. */
373 if (TN_standout_width
>= 0)
382 if (! FRAME_TERMCAP_P (updating_frame
))
383 (*update_begin_hook
) (f
);
389 if (! FRAME_TERMCAP_P (updating_frame
))
391 (*update_end_hook
) (f
);
396 background_highlight ();
397 standout_requested
= 0;
401 set_terminal_window (size
)
404 if (! FRAME_TERMCAP_P (updating_frame
))
406 (*set_terminal_window_hook
) (size
);
409 specified_window
= size
? size
: FRAME_HEIGHT (selected_frame
);
410 if (!scroll_region_ok
)
412 set_scroll_region (0, specified_window
);
415 set_scroll_region (start
, stop
)
419 if (TS_set_scroll_region
)
421 buf
= tparam (TS_set_scroll_region
, 0, 0, start
, stop
- 1);
423 else if (TS_set_scroll_region_1
)
425 buf
= tparam (TS_set_scroll_region_1
, 0, 0,
426 FRAME_HEIGHT (selected_frame
), start
,
427 FRAME_HEIGHT (selected_frame
) - stop
,
428 FRAME_HEIGHT (selected_frame
));
432 buf
= tparam (TS_set_window
, 0, 0, start
, 0, stop
, FRAME_WIDTH (selected_frame
));
442 OUTPUT (TS_insert_mode
);
449 OUTPUT (TS_end_insert_mode
);
453 /* Handle highlighting when TN_standout_width (termcap sg) is not specified.
454 In these terminals, output is affected by the value of standout
455 mode when the output is written.
457 These functions are called on all terminals, but do nothing
458 on terminals whose standout mode does not work that way. */
460 turn_off_highlight ()
462 if (TN_standout_width
< 0)
465 OUTPUT_IF (TS_end_standout_mode
);
472 if (TN_standout_width
< 0)
475 OUTPUT_IF (TS_standout_mode
);
480 /* Set standout mode to the state it should be in for
481 empty space inside windows. What this is,
482 depends on the user option inverse-video. */
484 background_highlight ()
486 if (TN_standout_width
>= 0)
489 turn_on_highlight ();
491 turn_off_highlight ();
494 /* Set standout mode to the mode specified for the text to be output. */
497 highlight_if_desired ()
499 if (TN_standout_width
>= 0)
501 if (!inverse_video
== !standout_requested
)
502 turn_off_highlight ();
504 turn_on_highlight ();
507 /* Handle standout mode for terminals in which TN_standout_width >= 0.
508 On these terminals, standout is controlled by markers that
509 live inside the terminal's memory. TN_standout_width is the width
510 that the marker occupies in memory. Standout runs from the marker
511 to the end of the line on some terminals, or to the next
512 turn-off-standout marker (TS_end_standout_mode) string
513 on other terminals. */
515 /* Write a standout marker or end-standout marker at the front of the line
516 at vertical position vpos. */
518 write_standout_marker (flag
, vpos
)
521 if (flag
|| (TS_end_standout_mode
&& !TF_teleray
&& !se_is_so
522 && !(TF_xs
&& TN_standout_width
== 0)))
525 cmplus (TN_standout_width
);
526 OUTPUT (flag
? TS_standout_mode
: TS_end_standout_mode
);
527 chars_wasted
[curY
] = TN_standout_width
| 0100;
531 /* External interface to control of standout mode.
532 Call this when about to modify line at position VPOS
533 and not change whether it is highlighted. */
535 reassert_line_highlight (highlight
, vpos
)
539 if (! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
541 (*reassert_line_highlight_hook
) (highlight
, vpos
);
544 if (TN_standout_width
< 0)
545 /* Handle terminals where standout takes affect at output time */
546 standout_requested
= highlight
;
547 else if (chars_wasted
[vpos
] == 0)
548 /* For terminals with standout markers, write one on this line
549 if there isn't one already. */
550 write_standout_marker (highlight
, vpos
);
553 /* Call this when about to modify line at position VPOS
554 and change whether it is highlighted. */
556 change_line_highlight (new_highlight
, vpos
, first_unused_hpos
)
557 int new_highlight
, vpos
, first_unused_hpos
;
559 standout_requested
= new_highlight
;
560 if (! FRAME_TERMCAP_P (updating_frame
))
562 (*change_line_highlight_hook
) (new_highlight
, vpos
, first_unused_hpos
);
568 if (TN_standout_width
< 0)
569 background_highlight ();
570 /* If line starts with a marker, delete the marker */
571 else if (TS_clr_line
&& chars_wasted
[curY
])
574 /* On Teleray, make sure to erase the SO marker. */
577 cmgoto (curY
- 1, FRAME_WIDTH (selected_frame
) - 4);
579 curY
++; /* ESC S moves to next line where the TS_standout_mode was */
583 cmgoto (curY
, 0); /* reposition to kill standout marker */
585 clear_end_of_line_raw (first_unused_hpos
);
586 reassert_line_highlight (new_highlight
, curY
);
590 /* Move to absolute position, specified origin 0 */
595 if (! FRAME_TERMCAP_P ((updating_frame
600 (*cursor_to_hook
) (row
, col
);
604 /* Detect the case where we are called from reset_sys_modes
605 and the costs have never been calculated. Do nothing. */
606 if (chars_wasted
== 0)
609 col
+= chars_wasted
[row
] & 077;
610 if (curY
== row
&& curX
== col
)
612 if (!TF_standout_motion
)
613 background_highlight ();
614 if (!TF_insmode_motion
)
619 /* Similar but don't take any account of the wasted characters. */
621 raw_cursor_to (row
, col
)
624 if (! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
626 (*raw_cursor_to_hook
) (row
, col
);
629 if (curY
== row
&& curX
== col
)
631 if (!TF_standout_motion
)
632 background_highlight ();
633 if (!TF_insmode_motion
)
638 /* Erase operations */
640 /* clear from cursor to end of frame */
645 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
647 (*clear_to_end_hook
) ();
650 if (TS_clr_to_bottom
)
652 background_highlight ();
653 OUTPUT (TS_clr_to_bottom
);
654 bzero (chars_wasted
+ curY
, FRAME_HEIGHT (selected_frame
) - curY
);
658 for (i
= curY
; i
< FRAME_HEIGHT (selected_frame
); i
++)
661 clear_end_of_line_raw (FRAME_WIDTH (selected_frame
));
666 /* Clear entire frame */
671 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
673 (*clear_frame_hook
) ();
678 background_highlight ();
679 OUTPUT (TS_clr_frame
);
680 bzero (chars_wasted
, FRAME_HEIGHT (selected_frame
));
690 /* Clear to end of line, but do not clear any standout marker.
691 Assumes that the cursor is positioned at a character of real text,
692 which implies it cannot be before a standout marker
693 unless the marker has zero width.
695 Note that the cursor may be moved. */
697 clear_end_of_line (first_unused_hpos
)
698 int first_unused_hpos
;
700 static GLYPH buf
= SPACEGLYPH
;
701 if (FRAME_TERMCAP_P (selected_frame
)
703 && TN_standout_width
== 0 && curX
== 0 && chars_wasted
[curY
] != 0)
704 write_glyphs (&buf
, 1);
705 clear_end_of_line_raw (first_unused_hpos
);
708 /* Clear from cursor to end of line.
709 Assume that the line is already clear starting at column first_unused_hpos.
710 If the cursor is at a standout marker, erase the marker.
712 Note that the cursor may be moved, on terminals lacking a `ce' string. */
714 clear_end_of_line_raw (first_unused_hpos
)
715 int first_unused_hpos
;
719 if (clear_end_of_line_hook
720 && ! FRAME_TERMCAP_P ((updating_frame
724 (*clear_end_of_line_hook
) (first_unused_hpos
);
728 /* Detect the case where we are called from reset_sys_modes
729 and the costs have never been calculated. Do nothing. */
730 if (chars_wasted
== 0)
733 first_unused_hpos
+= chars_wasted
[curY
] & 077;
734 if (curX
>= first_unused_hpos
)
736 /* Notice if we are erasing a magic cookie */
738 chars_wasted
[curY
] = 0;
739 background_highlight ();
742 OUTPUT1 (TS_clr_line
);
745 { /* have to do it the hard way */
748 /* Do not write in last row last col with Autowrap on. */
749 if (AutoWrap
&& curY
== FRAME_HEIGHT (selected_frame
) - 1
750 && first_unused_hpos
== FRAME_WIDTH (selected_frame
))
753 for (i
= curX
; i
< first_unused_hpos
; i
++)
756 fputc (' ', termscript
);
759 cmplus (first_unused_hpos
- curX
);
764 write_glyphs (string
, len
)
765 register GLYPH
*string
;
769 register int tlen
= GLYPH_TABLE_LENGTH
;
770 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
772 if (write_glyphs_hook
773 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
775 (*write_glyphs_hook
) (string
, len
);
779 highlight_if_desired ();
782 /* Don't dare write in last column of bottom line, if AutoWrap,
783 since that would scroll the whole frame on some terminals. */
786 && curY
+ 1 == FRAME_HEIGHT (selected_frame
)
787 && (curX
+ len
- (chars_wasted
[curY
] & 077)
788 == FRAME_WIDTH (selected_frame
)))
795 /* Check quickly for G beyond length of table.
796 That implies it isn't an alias and is simple. */
800 putc (g
& 0xff, stdout
);
804 putc (g
& 0xff, termscript
);
808 /* G has an entry in Vglyph_table,
809 so process any alias and then test for simpleness. */
810 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
811 g
= GLYPH_ALIAS (tbase
, g
);
812 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
816 /* Here if G (or its definition as an alias) is not simple. */
817 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
),
822 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
),
830 /* If start is zero, insert blanks instead of a string at start */
832 insert_glyphs (start
, len
)
833 register GLYPH
*start
;
838 register int tlen
= GLYPH_TABLE_LENGTH
;
839 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
841 if (insert_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
843 (*insert_glyphs_hook
) (start
, len
);
846 highlight_if_desired ();
848 if (TS_ins_multi_chars
)
850 buf
= tparam (TS_ins_multi_chars
, 0, 0, len
);
854 write_glyphs (start
, len
);
862 OUTPUT1_IF (TS_ins_char
);
868 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
870 putc (g
& 0xff, stdout
);
874 putc (g
& 0xff, termscript
);
878 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
), stdout
);
882 fwrite (GLYPH_STRING (tbase
, g
), 1, GLYPH_LENGTH (tbase
, g
),
886 OUTPUT1_IF (TS_pad_inserted_char
);
897 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
899 (*delete_glyphs_hook
) (n
);
903 if (delete_in_insert_mode
)
910 OUTPUT_IF (TS_delete_mode
);
913 if (TS_del_multi_chars
)
915 buf
= tparam (TS_del_multi_chars
, 0, 0, n
);
920 for (i
= 0; i
< n
; i
++)
921 OUTPUT1 (TS_del_char
);
922 if (!delete_in_insert_mode
)
923 OUTPUT_IF (TS_end_delete_mode
);
926 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
928 ins_del_lines (vpos
, n
)
931 char *multi
= n
> 0 ? TS_ins_multi_lines
: TS_del_multi_lines
;
932 char *single
= n
> 0 ? TS_ins_line
: TS_del_line
;
933 char *scroll
= n
> 0 ? TS_rev_scroll
: TS_fwd_scroll
;
935 register int i
= n
> 0 ? n
: -n
;
938 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
940 (*ins_del_lines_hook
) (vpos
, n
);
944 /* If the lines below the insertion are being pushed
945 into the end of the window, this is the same as clearing;
946 and we know the lines are already clear, since the matching
947 deletion has already been done. So can ignore this. */
948 /* If the lines below the deletion are blank lines coming
949 out of the end of the window, don't bother,
950 as there will be a matching inslines later that will flush them. */
951 if (scroll_region_ok
&& vpos
+ i
>= specified_window
)
953 if (!memory_below_frame
&& vpos
+ i
>= FRAME_HEIGHT (selected_frame
))
958 raw_cursor_to (vpos
, 0);
959 background_highlight ();
960 buf
= tparam (multi
, 0, 0, i
);
966 raw_cursor_to (vpos
, 0);
967 background_highlight ();
975 set_scroll_region (vpos
, specified_window
);
977 raw_cursor_to (specified_window
- 1, 0);
979 raw_cursor_to (vpos
, 0);
980 background_highlight ();
982 OUTPUTL (scroll
, specified_window
- vpos
);
983 set_scroll_region (0, specified_window
);
986 if (TN_standout_width
>= 0)
991 : FRAME_HEIGHT (selected_frame
));
995 bcopy (&chars_wasted
[vpos
- n
], &chars_wasted
[vpos
],
996 lower_limit
- vpos
+ n
);
997 bzero (&chars_wasted
[lower_limit
+ n
], - n
);
1001 bcopy (&chars_wasted
[vpos
], ©buf
[vpos
], lower_limit
- vpos
- n
);
1002 bcopy (©buf
[vpos
], &chars_wasted
[vpos
+ n
],
1003 lower_limit
- vpos
- n
);
1004 bzero (&chars_wasted
[vpos
], n
);
1007 if (!scroll_region_ok
&& memory_below_frame
&& n
< 0)
1009 cursor_to (FRAME_HEIGHT (selected_frame
) + n
, 0);
1014 /* Compute cost of sending "str", in characters,
1015 not counting any line-dependent padding. */
1023 tputs (str
, 0, evalcost
);
1027 /* Compute cost of sending "str", in characters,
1028 counting any line-dependent padding at one line. */
1031 string_cost_one_line (str
)
1036 tputs (str
, 1, evalcost
);
1040 /* Compute per line amount of line-dependent padding,
1041 in tenths of characters. */
1049 tputs (str
, 0, evalcost
);
1052 tputs (str
, 10, evalcost
);
1057 /* char_ins_del_cost[n] is cost of inserting N characters.
1058 char_ins_del_cost[-n] is cost of deleting N characters.
1059 The length of this vector is based on max_frame_width. */
1061 int *char_ins_del_vector
;
1063 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH ((f))])
1068 calculate_ins_del_char_costs (frame
)
1071 int ins_startup_cost
, del_startup_cost
;
1072 int ins_cost_per_char
, del_cost_per_char
;
1076 if (TS_ins_multi_chars
)
1078 ins_cost_per_char
= 0;
1079 ins_startup_cost
= string_cost_one_line (TS_ins_multi_chars
);
1081 else if (TS_ins_char
|| TS_pad_inserted_char
1082 || (TS_insert_mode
&& TS_end_insert_mode
))
1084 ins_startup_cost
= (30 * (string_cost (TS_insert_mode
)
1085 + string_cost (TS_end_insert_mode
))) / 100;
1086 ins_cost_per_char
= (string_cost_one_line (TS_ins_char
)
1087 + string_cost_one_line (TS_pad_inserted_char
));
1091 ins_startup_cost
= 9999;
1092 ins_cost_per_char
= 0;
1095 if (TS_del_multi_chars
)
1097 del_cost_per_char
= 0;
1098 del_startup_cost
= string_cost_one_line (TS_del_multi_chars
);
1100 else if (TS_del_char
)
1102 del_startup_cost
= (string_cost (TS_delete_mode
)
1103 + string_cost (TS_end_delete_mode
));
1104 if (delete_in_insert_mode
)
1105 del_startup_cost
/= 2;
1106 del_cost_per_char
= string_cost_one_line (TS_del_char
);
1110 del_startup_cost
= 9999;
1111 del_cost_per_char
= 0;
1114 /* Delete costs are at negative offsets */
1115 p
= &char_ins_del_cost (frame
)[0];
1116 for (i
= FRAME_WIDTH (frame
); --i
>= 0;)
1117 *--p
= (del_startup_cost
+= del_cost_per_char
);
1119 /* Doing nothing is free */
1120 p
= &char_ins_del_cost (frame
)[0];
1123 /* Insert costs are at positive offsets */
1124 for (i
= FRAME_WIDTH (frame
); --i
>= 0;)
1125 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1128 extern do_line_insertion_deletion_costs ();
1130 calculate_costs (frame
)
1133 register char *f
= (TS_set_scroll_region
1134 ? TS_set_scroll_region
1135 : TS_set_scroll_region_1
);
1137 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1139 scroll_region_cost
= string_cost (f
);
1140 #ifdef HAVE_X_WINDOWS
1141 if (FRAME_X_P (frame
))
1143 do_line_insertion_deletion_costs (frame
, 0, ".5*", 0, ".5*",
1145 x_screen_planes (frame
));
1146 scroll_region_cost
= 0;
1151 /* These variables are only used for terminal stuff. They are allocated
1152 once for the terminal frame of X-windows emacs, but not used afterwards.
1154 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1155 X turns off char_ins_del_ok.
1157 chars_wasted and copybuf are only used here in term.c in cases where
1158 the term hook isn't called. */
1160 max_frame_height
= max (max_frame_height
, FRAME_HEIGHT (frame
));
1161 max_frame_width
= max (max_frame_width
, FRAME_WIDTH (frame
));
1163 if (chars_wasted
!= 0)
1164 chars_wasted
= (char *) xrealloc (chars_wasted
, max_frame_height
);
1166 chars_wasted
= (char *) xmalloc (max_frame_height
);
1169 copybuf
= (char *) xrealloc (copybuf
, max_frame_height
);
1171 copybuf
= (char *) xmalloc (max_frame_height
);
1173 if (char_ins_del_vector
!= 0)
1175 = (int *) xrealloc (char_ins_del_vector
,
1177 + 2 * max_frame_width
* sizeof (int)));
1180 = (int *) xmalloc (sizeof (int)
1181 + 2 * max_frame_width
* sizeof (int));
1183 bzero (chars_wasted
, max_frame_height
);
1184 bzero (copybuf
, max_frame_height
);
1185 bzero (char_ins_del_vector
, (sizeof (int)
1186 + 2 * max_frame_width
* sizeof (int)));
1188 if (f
&& (!TS_ins_line
&& !TS_del_line
))
1189 do_line_insertion_deletion_costs (frame
,
1190 TS_rev_scroll
, TS_ins_multi_lines
,
1191 TS_fwd_scroll
, TS_del_multi_lines
,
1194 do_line_insertion_deletion_costs (frame
,
1195 TS_ins_line
, TS_ins_multi_lines
,
1196 TS_del_line
, TS_del_multi_lines
,
1199 calculate_ins_del_char_costs (frame
);
1201 /* Don't use TS_repeat if its padding is worse than sending the chars */
1202 if (TS_repeat
&& per_line_cost (TS_repeat
) * baud_rate
< 9000)
1203 RPov
= string_cost (TS_repeat
);
1205 RPov
= FRAME_WIDTH (frame
) * 2;
1207 cmcostinit (); /* set up cursor motion costs */
1214 /* Termcap capability names that correspond directly to X keysyms.
1215 Some of these (marked "terminfo") aren't supplied by old-style
1216 (Berkeley) termcap entries. They're listed in X keysym order;
1217 except we put the keypad keys first, so that if they clash with
1218 other keys (as on the IBM PC keyboard) they get overridden.
1221 static struct fkey_table keys
[] = {
1222 "kh", "home", /* termcap */
1223 "kl", "left", /* termcap */
1224 "ku", "up", /* termcap */
1225 "kr", "right", /* termcap */
1226 "kd", "down", /* termcap */
1227 "%8", "prior", /* terminfo */
1228 "%5", "next", /* terminfo */
1229 "@7", "end", /* terminfo */
1230 "@1", "begin", /* terminfo */
1231 "*6", "select", /* terminfo */
1232 "%9", "print", /* terminfo */
1233 "@4", "execute", /* terminfo --- actually the `command' key */
1235 * "insert" --- see below
1237 "&8", "undo", /* terminfo */
1238 "%0", "redo", /* terminfo */
1239 "%7", "menu", /* terminfo --- actually the `options' key */
1240 "@0", "find", /* terminfo */
1241 "@2", "cancel", /* terminfo */
1242 "%1", "help", /* terminfo */
1244 * "break" goes here, but can't be reliably intercepted with termcap
1246 "&4", "reset", /* terminfo --- actually `restart' */
1248 * "system" and "user" --- no termcaps
1250 "kE", "clearline", /* terminfo */
1251 "kA", "insertline", /* terminfo */
1252 "kL", "deleteline", /* terminfo */
1253 "kI", "insertchar", /* terminfo */
1254 "kD", "deletechar", /* terminfo */
1255 "kB", "backtab", /* terminfo */
1257 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1259 "@8", "kp-enter", /* terminfo */
1261 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1262 * "kp-multiply", "kp-add", "kp-separator",
1263 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1264 * --- no termcaps for any of these.
1266 "K4", "kp-1", /* terminfo */
1268 * "kp-2" --- no termcap
1270 "K5", "kp-3", /* terminfo */
1272 * "kp-4" --- no termcap
1274 "K2", "kp-5", /* terminfo */
1276 * "kp-6" --- no termcap
1278 "K1", "kp-7", /* terminfo */
1280 * "kp-8" --- no termcap
1282 "K3", "kp-9", /* terminfo */
1284 * "kp-equal" --- no termcap
1297 static char **term_get_fkeys_arg
;
1298 static Lisp_Object
term_get_fkeys_1 ();
1300 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1301 This function scans the termcap function key sequence entries, and
1302 adds entries to Vfunction_key_map for each function key it finds. */
1305 term_get_fkeys (address
)
1308 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1309 errors during the call. The only errors should be from Fdefine_key
1310 when given a key sequence containing an invalid prefix key. If the
1311 termcap defines function keys which use a prefix that is already bound
1312 to a command by the default bindings, we should silently ignore that
1313 function key specification, rather than giving the user an error and
1314 refusing to run at all on such a terminal. */
1316 extern Lisp_Object
Fidentity ();
1317 term_get_fkeys_arg
= address
;
1318 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1326 char **address
= term_get_fkeys_arg
;
1328 /* This can happen if CANNOT_DUMP or with strange options. */
1330 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1332 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1334 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1336 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1337 Fmake_vector (make_number (1),
1338 intern (keys
[i
].name
)));
1341 /* The uses of the "k0" capability are inconsistent; sometimes it
1342 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1343 We will attempt to politely accommodate both systems by testing for
1344 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1347 char *k_semi
= tgetstr ("k;", address
);
1348 char *k0
= tgetstr ("k0", address
);
1349 char *k0_name
= "f10";
1353 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1354 Fmake_vector (make_number (1), intern ("f10")));
1359 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1360 Fmake_vector (make_number (1), intern (k0_name
)));
1363 /* Set up cookies for numbered function keys above f10. */
1365 char fcap
[3], fkey
[4];
1367 fcap
[0] = 'F'; fcap
[2] = '\0';
1368 for (i
= 11; i
< 64; i
++)
1371 fcap
[1] = '1' + i
- 11;
1373 fcap
[1] = 'A' + i
- 20;
1375 fcap
[1] = 'a' + i
- 46;
1378 char *sequence
= tgetstr (fcap
, address
);
1381 sprintf (fkey
, "f%d", i
);
1382 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1383 Fmake_vector (make_number (1),
1391 * Various mappings to try and get a better fit.
1394 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1395 if (!tgetstr (cap1, address)) \
1397 char *sequence = tgetstr (cap2, address); \
1399 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1400 Fmake_vector (make_number (1), \
1404 /* if there's no key_next keycap, map key_npage to `next' keysym */
1405 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1406 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1407 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1408 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1409 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1411 /* IBM has their own non-standard dialect of terminfo.
1412 If the standard name isn't found, try the IBM name. */
1413 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1414 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1415 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1416 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1417 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1418 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1419 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1420 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1421 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1422 #undef CONDITIONAL_REASSIGN
1427 term_init (terminal_type
)
1428 char *terminal_type
;
1431 char **address
= &area
;
1437 initialize_win_nt_display ();
1441 area
= (char *) malloc (2044);
1446 FrameRows
= FRAME_HEIGHT (selected_frame
);
1447 FrameCols
= FRAME_WIDTH (selected_frame
);
1448 specified_window
= FRAME_HEIGHT (selected_frame
);
1450 delete_in_insert_mode
= 1;
1453 scroll_region_ok
= 0;
1455 /* Seems to insert lines when it's not supposed to, messing
1456 up the display. In doing a trace, it didn't seem to be
1457 called much, so I don't think we're losing anything by
1460 line_ins_del_ok
= 0;
1461 char_ins_del_ok
= 1;
1465 FRAME_CAN_HAVE_SCROLL_BARS (selected_frame
) = 0;
1466 FRAME_HAS_VERTICAL_SCROLL_BARS (selected_frame
) = 0;
1469 #endif /* WINDOWSNT */
1473 status
= tgetent (buffer
, terminal_type
);
1477 fatal ("Cannot open terminfo database file.\n");
1479 fatal ("Cannot open termcap database file.\n");
1485 fatal ("Terminal type %s is not defined.\n\
1486 If that is not the actual type of terminal you have,\n\
1487 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1488 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1489 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.\n",
1492 fatal ("Terminal type %s is not defined.\n\
1493 If that is not the actual type of terminal you have,\n\
1494 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1495 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1496 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.\n",
1501 area
= (char *) malloc (2044);
1503 area
= (char *) malloc (strlen (buffer
));
1504 #endif /* not TERMINFO */
1508 TS_ins_line
= tgetstr ("al", address
);
1509 TS_ins_multi_lines
= tgetstr ("AL", address
);
1510 TS_bell
= tgetstr ("bl", address
);
1511 BackTab
= tgetstr ("bt", address
);
1512 TS_clr_to_bottom
= tgetstr ("cd", address
);
1513 TS_clr_line
= tgetstr ("ce", address
);
1514 TS_clr_frame
= tgetstr ("cl", address
);
1515 ColPosition
= tgetstr ("ch", address
);
1516 AbsPosition
= tgetstr ("cm", address
);
1517 CR
= tgetstr ("cr", address
);
1518 TS_set_scroll_region
= tgetstr ("cs", address
);
1519 TS_set_scroll_region_1
= tgetstr ("cS", address
);
1520 RowPosition
= tgetstr ("cv", address
);
1521 TS_del_char
= tgetstr ("dc", address
);
1522 TS_del_multi_chars
= tgetstr ("DC", address
);
1523 TS_del_line
= tgetstr ("dl", address
);
1524 TS_del_multi_lines
= tgetstr ("DL", address
);
1525 TS_delete_mode
= tgetstr ("dm", address
);
1526 TS_end_delete_mode
= tgetstr ("ed", address
);
1527 TS_end_insert_mode
= tgetstr ("ei", address
);
1528 Home
= tgetstr ("ho", address
);
1529 TS_ins_char
= tgetstr ("ic", address
);
1530 TS_ins_multi_chars
= tgetstr ("IC", address
);
1531 TS_insert_mode
= tgetstr ("im", address
);
1532 TS_pad_inserted_char
= tgetstr ("ip", address
);
1533 TS_end_keypad_mode
= tgetstr ("ke", address
);
1534 TS_keypad_mode
= tgetstr ("ks", address
);
1535 LastLine
= tgetstr ("ll", address
);
1536 Right
= tgetstr ("nd", address
);
1537 Down
= tgetstr ("do", address
);
1539 Down
= tgetstr ("nl", address
); /* Obsolete name for "do" */
1541 /* VMS puts a carriage return before each linefeed,
1542 so it is not safe to use linefeeds. */
1543 if (Down
&& Down
[0] == '\n' && Down
[1] == '\0')
1546 if (tgetflag ("bs"))
1547 Left
= "\b"; /* can't possibly be longer! */
1548 else /* (Actually, "bs" is obsolete...) */
1549 Left
= tgetstr ("le", address
);
1551 Left
= tgetstr ("bc", address
); /* Obsolete name for "le" */
1552 TS_pad_char
= tgetstr ("pc", address
);
1553 TS_repeat
= tgetstr ("rp", address
);
1554 TS_end_standout_mode
= tgetstr ("se", address
);
1555 TS_fwd_scroll
= tgetstr ("sf", address
);
1556 TS_standout_mode
= tgetstr ("so", address
);
1557 TS_rev_scroll
= tgetstr ("sr", address
);
1558 Wcm
.cm_tab
= tgetstr ("ta", address
);
1559 TS_end_termcap_modes
= tgetstr ("te", address
);
1560 TS_termcap_modes
= tgetstr ("ti", address
);
1561 Up
= tgetstr ("up", address
);
1562 TS_visible_bell
= tgetstr ("vb", address
);
1563 TS_end_visual_mode
= tgetstr ("ve", address
);
1564 TS_visual_mode
= tgetstr ("vs", address
);
1565 TS_set_window
= tgetstr ("wi", address
);
1566 MultiUp
= tgetstr ("UP", address
);
1567 MultiDown
= tgetstr ("DO", address
);
1568 MultiLeft
= tgetstr ("LE", address
);
1569 MultiRight
= tgetstr ("RI", address
);
1571 MagicWrap
= tgetflag ("xn");
1572 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
1573 the former flag imply the latter. */
1574 AutoWrap
= MagicWrap
|| tgetflag ("am");
1575 memory_below_frame
= tgetflag ("db");
1576 TF_hazeltine
= tgetflag ("hz");
1577 must_write_spaces
= tgetflag ("in");
1578 meta_key
= tgetflag ("km") || tgetflag ("MT");
1579 TF_insmode_motion
= tgetflag ("mi");
1580 TF_standout_motion
= tgetflag ("ms");
1581 TF_underscore
= tgetflag ("ul");
1582 TF_xs
= tgetflag ("xs");
1583 TF_teleray
= tgetflag ("xt");
1585 term_get_fkeys (address
);
1587 /* Get frame size from system, or else from termcap. */
1588 get_frame_size (&FRAME_WIDTH (selected_frame
),
1589 &FRAME_HEIGHT (selected_frame
));
1590 if (FRAME_WIDTH (selected_frame
) <= 0)
1591 FRAME_WIDTH (selected_frame
) = tgetnum ("co");
1592 if (FRAME_HEIGHT (selected_frame
) <= 0)
1593 FRAME_HEIGHT (selected_frame
) = tgetnum ("li");
1595 if (FRAME_HEIGHT (selected_frame
) < 3
1596 || FRAME_WIDTH (selected_frame
) < 3)
1597 fatal ("Screen size %dx%d is too small.\n",
1598 FRAME_HEIGHT (selected_frame
), FRAME_WIDTH (selected_frame
));
1600 min_padding_speed
= tgetnum ("pb");
1601 TN_standout_width
= tgetnum ("sg");
1602 TabWidth
= tgetnum ("tw");
1605 /* These capabilities commonly use ^J.
1606 I don't know why, but sending them on VMS does not work;
1607 it causes following spaces to be lost, sometimes.
1608 For now, the simplest fix is to avoid using these capabilities ever. */
1609 if (Down
&& Down
[0] == '\n')
1617 TS_fwd_scroll
= Down
;
1619 PC
= TS_pad_char
? *TS_pad_char
: 0;
1624 /* Turned off since /etc/termcap seems to have :ta= for most terminals
1625 and newer termcap doc does not seem to say there is a default.
1630 if (TS_standout_mode
== 0)
1632 TN_standout_width
= tgetnum ("ug");
1633 TS_end_standout_mode
= tgetstr ("ue", address
);
1634 TS_standout_mode
= tgetstr ("us", address
);
1637 /* If no `se' string, try using a `me' string instead.
1638 If that fails, we can't use standout mode at all. */
1639 if (TS_end_standout_mode
== 0)
1641 char *s
= tgetstr ("me", address
);
1643 TS_end_standout_mode
= s
;
1645 TS_standout_mode
= 0;
1651 /* Teleray: most programs want a space in front of TS_standout_mode,
1652 but Emacs can do without it (and give one extra column). */
1653 TS_standout_mode
= "\033RD";
1654 TN_standout_width
= 1;
1655 /* But that means we cannot rely on ^M to go to column zero! */
1657 /* LF can't be trusted either -- can alter hpos */
1658 /* if move at column 0 thru a line with TS_standout_mode */
1662 /* Special handling for certain terminal types known to need it */
1664 if (!strcmp (terminal_type
, "supdup"))
1666 memory_below_frame
= 1;
1667 Wcm
.cm_losewrap
= 1;
1669 if (!strncmp (terminal_type
, "c10", 3)
1670 || !strcmp (terminal_type
, "perq"))
1672 /* Supply a makeshift :wi string.
1673 This string is not valid in general since it works only
1674 for windows starting at the upper left corner;
1675 but that is all Emacs uses.
1677 This string works only if the frame is using
1678 the top of the video memory, because addressing is memory-relative.
1679 So first check the :ti string to see if that is true.
1681 It would be simpler if the :wi string could go in the termcap
1682 entry, but it can't because it is not fully valid.
1683 If it were in the termcap entry, it would confuse other programs. */
1686 p
= TS_termcap_modes
;
1687 while (*p
&& strcmp (p
, "\033v "))
1690 TS_set_window
= "\033v%C %C %C %C ";
1692 /* Termcap entry often fails to have :in: flag */
1693 must_write_spaces
= 1;
1694 /* :ti string typically fails to have \E^G! in it */
1695 /* This limits scope of insert-char to one line. */
1696 strcpy (area
, TS_termcap_modes
);
1697 strcat (area
, "\033\007!");
1698 TS_termcap_modes
= area
;
1699 area
+= strlen (area
) + 1;
1701 /* Change all %+ parameters to %C, to handle
1702 values above 96 correctly for the C100. */
1705 if (p
[0] == '%' && p
[1] == '+')
1711 FrameRows
= FRAME_HEIGHT (selected_frame
);
1712 FrameCols
= FRAME_WIDTH (selected_frame
);
1713 specified_window
= FRAME_HEIGHT (selected_frame
);
1715 if (Wcm_init () == -1) /* can't do cursor motion */
1717 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1718 It lacks the ability to position the cursor.\n\
1719 If that is not the actual type of terminal you have, use either the\n\
1720 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
1721 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.\n",
1725 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1726 It lacks the ability to position the cursor.\n\
1727 If that is not the actual type of terminal you have,\n\
1728 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1729 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1730 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.\n",
1732 # else /* TERMCAP */
1733 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1734 It lacks the ability to position the cursor.\n\
1735 If that is not the actual type of terminal you have,\n\
1736 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1737 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1738 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.\n",
1740 # endif /* TERMINFO */
1742 if (FRAME_HEIGHT (selected_frame
) <= 0
1743 || FRAME_WIDTH (selected_frame
) <= 0)
1744 fatal ("The frame size has not been specified.");
1746 delete_in_insert_mode
1747 = TS_delete_mode
&& TS_insert_mode
1748 && !strcmp (TS_delete_mode
, TS_insert_mode
);
1750 se_is_so
= (TS_standout_mode
1751 && TS_end_standout_mode
1752 && !strcmp (TS_standout_mode
, TS_end_standout_mode
));
1754 /* Remove width of standout marker from usable width of line */
1755 if (TN_standout_width
> 0)
1756 FRAME_WIDTH (selected_frame
) -= TN_standout_width
;
1758 UseTabs
= tabs_safe_p () && TabWidth
== 8;
1762 && (TS_set_window
|| TS_set_scroll_region
|| TS_set_scroll_region_1
));
1764 line_ins_del_ok
= (((TS_ins_line
|| TS_ins_multi_lines
)
1765 && (TS_del_line
|| TS_del_multi_lines
))
1766 || (scroll_region_ok
&& TS_fwd_scroll
&& TS_rev_scroll
));
1768 char_ins_del_ok
= ((TS_ins_char
|| TS_insert_mode
1769 || TS_pad_inserted_char
|| TS_ins_multi_chars
)
1770 && (TS_del_char
|| TS_del_multi_chars
));
1772 fast_clear_end_of_line
= TS_clr_line
!= 0;
1775 if (read_socket_hook
) /* Baudrate is somewhat */
1776 /* meaningless in this case */
1779 FRAME_CAN_HAVE_SCROLL_BARS (selected_frame
) = 0;
1780 FRAME_HAS_VERTICAL_SCROLL_BARS (selected_frame
) = 0;
1784 fatal (str
, arg1
, arg2
)
1785 char *str
, *arg1
, *arg2
;
1787 fprintf (stderr
, "emacs: ");
1788 fprintf (stderr
, str
, arg1
, arg2
);
1795 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
1796 "Non-nil means the system uses terminfo rather than termcap.\n\
1797 This variable can be used by terminal emulator packages.");
1799 system_uses_terminfo
= 1;
1801 system_uses_terminfo
= 0;
1804 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
1805 "Non-nil means call this function to ring the bell.\n\
1806 The function should accept no arguments.");
1807 Vring_bell_function
= Qnil
;