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. */
33 #include "termhooks.h"
35 #include "dispextern.h"
41 #define max(a, b) ((a) > (b) ? (a) : (b))
42 #define min(a, b) ((a) < (b) ? (a) : (b))
44 #define OUTPUT(a) tputs (a, (int) (FRAME_HEIGHT (selected_frame) - curY), cmputc)
45 #define OUTPUT1(a) tputs (a, 1, cmputc)
46 #define OUTPUTL(a, lines) tputs (a, lines, cmputc)
47 #define OUTPUT_IF(a) { if (a) tputs (a, (int) (FRAME_HEIGHT (selected_frame) - curY), cmputc); }
48 #define OUTPUT1_IF(a) { if (a) tputs (a, 1, cmputc); }
50 /* Function to use to ring the bell. */
51 Lisp_Object Vring_bell_function
;
53 /* Terminal characteristics that higher levels want to look at.
54 These are all extern'd in termchar.h */
56 int must_write_spaces
; /* Nonzero means spaces in the text
57 must actually be output; can't just skip
58 over some columns to leave them blank. */
59 int min_padding_speed
; /* Speed below which no padding necessary */
61 int line_ins_del_ok
; /* Terminal can insert and delete lines */
62 int char_ins_del_ok
; /* Terminal can insert and delete chars */
63 int scroll_region_ok
; /* Terminal supports setting the
65 int scroll_region_cost
; /* Cost of setting a scroll window,
66 measured in characters */
67 int memory_below_frame
; /* Terminal remembers lines
68 scrolled off bottom */
69 int fast_clear_end_of_line
; /* Terminal has a `ce' string */
71 /* Nonzero means no need to redraw the entire frame on resuming
72 a suspended Emacs. This is useful on terminals with multiple pages,
73 where one page is used for Emacs and another for all else. */
74 int no_redraw_on_reenter
;
76 /* Hook functions that you can set to snap out the functions in this file.
77 These are all extern'd in termhooks.h */
79 void (*cursor_to_hook
) P_ ((int, int));
80 void (*raw_cursor_to_hook
) P_ ((int, int));
82 void (*clear_to_end_hook
) P_ ((void));
83 void (*clear_frame_hook
) P_ ((void));
84 void (*clear_end_of_line_hook
) P_ ((int));
86 void (*ins_del_lines_hook
) P_ ((int, int));
88 void (*change_line_highlight_hook
) P_ ((int, int, int));
89 void (*reassert_line_highlight_hook
) P_ ((int, int));
91 void (*insert_glyphs_hook
) P_ ((GLYPH
*, int));
92 void (*write_glyphs_hook
) P_ ((GLYPH
*, int));
93 void (*delete_glyphs_hook
) P_ ((int));
95 void (*ring_bell_hook
) P_ ((void));
97 void (*reset_terminal_modes_hook
) P_ ((void));
98 void (*set_terminal_modes_hook
) P_ ((void));
99 void (*update_begin_hook
) P_ ((struct frame
*));
100 void (*update_end_hook
) P_ ((struct frame
*));
101 void (*set_terminal_window_hook
) P_ ((int));
103 int (*read_socket_hook
) P_ ((int, struct input_event
*, int, int));
105 void (*frame_up_to_date_hook
) P_ ((struct frame
*));
107 /* Return the current position of the mouse.
109 Set *f to the frame the mouse is in, or zero if the mouse is in no
110 Emacs frame. If it is set to zero, all the other arguments are
113 If the motion started in a scroll bar, set *bar_window to the
114 scroll bar's window, *part to the part the mouse is currently over,
115 *x to the position of the mouse along the scroll bar, and *y to the
116 overall length of the scroll bar.
118 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
119 row of the character cell the mouse is over.
121 Set *time to the time the mouse was at the returned position.
123 This should clear mouse_moved until the next motion
125 void (*mouse_position_hook
) P_ ((FRAME_PTR
*f
, int insist
,
126 Lisp_Object
*bar_window
,
127 enum scroll_bar_part
*part
,
130 unsigned long *time
));
132 /* When reading from a minibuffer in a different frame, Emacs wants
133 to shift the highlight from the selected frame to the minibuffer's
134 frame; under X, this means it lies about where the focus is.
135 This hook tells the window system code to re-decide where to put
137 void (*frame_rehighlight_hook
) P_ ((FRAME_PTR f
));
139 /* If we're displaying frames using a window system that can stack
140 frames on top of each other, this hook allows you to bring a frame
141 to the front, or bury it behind all the other windows. If this
142 hook is zero, that means the device we're displaying on doesn't
143 support overlapping frames, so there's no need to raise or lower
146 If RAISE is non-zero, F is brought to the front, before all other
147 windows. If RAISE is zero, F is sent to the back, behind all other
149 void (*frame_raise_lower_hook
) P_ ((FRAME_PTR f
, int raise
));
151 /* Set the vertical scroll bar for WINDOW to have its upper left corner
152 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
153 indicate that we are displaying PORTION characters out of a total
154 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
155 have a scroll bar, create one for it. */
156 void (*set_vertical_scroll_bar_hook
)
157 P_ ((struct window
*window
,
158 int portion
, int whole
, int position
));
161 /* The following three hooks are used when we're doing a thorough
162 redisplay of the frame. We don't explicitly know which scroll bars
163 are going to be deleted, because keeping track of when windows go
164 away is a real pain - can you say set-window-configuration?
165 Instead, we just assert at the beginning of redisplay that *all*
166 scroll bars are to be removed, and then save scroll bars from the
167 fiery pit when we actually redisplay their window. */
169 /* Arrange for all scroll bars on FRAME to be removed at the next call
170 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
171 `*redeem_scroll_bar_hook' is applied to its window before the judgement.
173 This should be applied to each frame each time its window tree is
174 redisplayed, even if it is not displaying scroll bars at the moment;
175 if the HAS_SCROLL_BARS flag has just been turned off, only calling
176 this and the judge_scroll_bars_hook will get rid of them.
178 If non-zero, this hook should be safe to apply to any frame,
179 whether or not it can support scroll bars, and whether or not it is
180 currently displaying them. */
181 void (*condemn_scroll_bars_hook
) P_ ((FRAME_PTR frame
));
183 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
184 Note that it's okay to redeem a scroll bar that is not condemned. */
185 void (*redeem_scroll_bar_hook
) P_ ((struct window
*window
));
187 /* Remove all scroll bars on FRAME that haven't been saved since the
188 last call to `*condemn_scroll_bars_hook'.
190 This should be applied to each frame after each time its window
191 tree is redisplayed, even if it is not displaying scroll bars at the
192 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
193 calling this and condemn_scroll_bars_hook will get rid of them.
195 If non-zero, this hook should be safe to apply to any frame,
196 whether or not it can support scroll bars, and whether or not it is
197 currently displaying them. */
198 void (*judge_scroll_bars_hook
) P_ ((FRAME_PTR FRAME
));
201 /* Strings, numbers and flags taken from the termcap entry. */
203 char *TS_end_italic_mode
; /* termcap "ae" */
204 char *TS_ins_line
; /* "al" */
205 char *TS_italic_mode
; /* "as" */
206 char *TS_ins_multi_lines
; /* "AL" (one parameter, # lines to insert) */
207 char *TS_bell
; /* "bl" */
208 char *TS_clr_to_bottom
; /* "cd" */
209 char *TS_clr_line
; /* "ce", clear to end of line */
210 char *TS_clr_frame
; /* "cl" */
211 char *TS_set_scroll_region
; /* "cs" (2 params, first line and last line) */
212 char *TS_set_scroll_region_1
; /* "cS" (4 params: total lines,
213 lines above scroll region, lines below it,
214 total lines again) */
215 char *TS_del_char
; /* "dc" */
216 char *TS_del_multi_chars
; /* "DC" (one parameter, # chars to delete) */
217 char *TS_del_line
; /* "dl" */
218 char *TS_del_multi_lines
; /* "DL" (one parameter, # lines to delete) */
219 char *TS_delete_mode
; /* "dm", enter character-delete mode */
220 char *TS_end_delete_mode
; /* "ed", leave character-delete mode */
221 char *TS_end_insert_mode
; /* "ei", leave character-insert mode */
222 char *TS_ins_char
; /* "ic" */
223 char *TS_ins_multi_chars
; /* "IC" (one parameter, # chars to insert) */
224 char *TS_insert_mode
; /* "im", enter character-insert mode */
225 char *TS_pad_inserted_char
; /* "ip". Just padding, no commands. */
226 char *TS_end_keypad_mode
; /* "ke" */
227 char *TS_keypad_mode
; /* "ks" */
228 char *TS_bold_mode
; /* "md" */
229 char *TS_end_bold_mode
; /* "me" */
230 char *TS_pad_char
; /* "pc", char to use as padding */
231 char *TS_repeat
; /* "rp" (2 params, # times to repeat
232 and character to be repeated) */
233 char *TS_end_standout_mode
; /* "se" */
234 char *TS_fwd_scroll
; /* "sf" */
235 char *TS_standout_mode
; /* "so" */
236 char *TS_rev_scroll
; /* "sr" */
237 char *TS_end_termcap_modes
; /* "te" */
238 char *TS_termcap_modes
; /* "ti" */
239 char *TS_end_underscore_mode
; /* "ue" */
240 char *TS_underscore_mode
; /* "us" */
241 char *TS_visible_bell
; /* "vb" */
242 char *TS_end_visual_mode
; /* "ve" */
243 char *TS_visual_mode
; /* "vi" */
244 char *TS_set_window
; /* "wi" (4 params, start and end of window,
245 each as vpos and hpos) */
247 int TF_hazeltine
; /* termcap hz flag. */
248 int TF_insmode_motion
; /* termcap mi flag: can move while in insert mode. */
249 int TF_standout_motion
; /* termcap mi flag: can move while in standout mode. */
250 int TF_underscore
; /* termcap ul flag: _ underlines if overstruck on
251 nonblank position. Must clear before writing _. */
252 int TF_teleray
; /* termcap xt flag: many weird consequences.
255 int TF_xs
; /* Nonzero for "xs". If set together with
256 TN_standout_width == 0, it means don't bother
257 to write any end-standout cookies. */
259 int TN_standout_width
; /* termcap sg number: width occupied by standout
262 static int RPov
; /* # chars to start a TS_repeat */
264 static int delete_in_insert_mode
; /* delete mode == insert mode */
266 static int se_is_so
; /* 1 if same string both enters and leaves
271 /* The largest frame width in any call to calculate_costs. */
273 /* The largest frame height in any call to calculate_costs. */
274 int max_frame_height
;
276 /* Number of chars of space used for standout marker at beginning of line,
277 or'd with 0100. Zero if no standout marker at all.
278 The length of these vectors is max_frame_height.
280 Used IFF TN_standout_width >= 0. */
282 static char *chars_wasted
;
283 static char *copybuf
;
285 /* nonzero means supposed to write text in standout mode. */
286 int standout_requested
;
288 int insert_mode
; /* Nonzero when in insert mode. */
289 int standout_mode
; /* Nonzero when in standout mode. */
291 /* Size of window specified by higher levels.
292 This is the number of lines, from the top of frame downwards,
293 which can participate in insert-line/delete-line operations.
295 Effectively it excludes the bottom frame_height - specified_window_size
296 lines from those operations. */
298 int specified_window
;
300 /* Frame currently being redisplayed; 0 if not currently redisplaying.
301 (Direct output does not count). */
303 FRAME_PTR updating_frame
;
305 /* Provided for lisp packages. */
306 static int system_uses_terminfo
;
310 extern char *tgetstr ();
314 /* We aren't X windows, but we aren't termcap either. This makes me
315 uncertain as to what value to use for frame.output_method. For
316 this file, we'll define FRAME_TERMCAP_P to be zero so that our
317 output hooks get called instead of the termcap functions. Probably
318 the best long-term solution is to define an output_windows_nt... */
320 #undef FRAME_TERMCAP_P
321 #define FRAME_TERMCAP_P(_f_) 0
322 #endif /* WINDOWSNT */
327 if (! NILP (Vring_bell_function
))
329 Lisp_Object function
;
331 /* Temporarily set the global variable to nil
332 so that if we get an error, it stays nil
333 and we don't call it over and over.
335 We don't specbind it, because that would carefully
336 restore the bad value if there's an error
337 and make the loop of errors happen anyway. */
338 function
= Vring_bell_function
;
339 Vring_bell_function
= Qnil
;
343 Vring_bell_function
= function
;
347 if (! FRAME_TERMCAP_P (selected_frame
))
349 (*ring_bell_hook
) ();
352 OUTPUT (TS_visible_bell
&& visible_bell
? TS_visible_bell
: TS_bell
);
356 set_terminal_modes ()
358 if (! FRAME_TERMCAP_P (selected_frame
))
360 (*set_terminal_modes_hook
) ();
363 OUTPUT_IF (TS_termcap_modes
);
364 OUTPUT_IF (TS_visual_mode
);
365 OUTPUT_IF (TS_keypad_mode
);
370 reset_terminal_modes ()
372 if (! FRAME_TERMCAP_P (selected_frame
))
374 if (reset_terminal_modes_hook
)
375 (*reset_terminal_modes_hook
) ();
378 if (TN_standout_width
< 0)
379 turn_off_highlight ();
381 OUTPUT_IF (TS_end_keypad_mode
);
382 OUTPUT_IF (TS_end_visual_mode
);
383 OUTPUT_IF (TS_end_termcap_modes
);
384 /* Output raw CR so kernel can track the cursor hpos. */
385 /* But on magic-cookie terminals this can erase an end-standout marker and
386 cause the rest of the frame to be in standout, so move down first. */
387 if (TN_standout_width
>= 0)
397 if (! FRAME_TERMCAP_P (updating_frame
))
398 (*update_begin_hook
) (f
);
405 if (! FRAME_TERMCAP_P (updating_frame
))
407 (*update_end_hook
) (f
);
412 background_highlight ();
413 standout_requested
= 0;
418 set_terminal_window (size
)
421 if (! FRAME_TERMCAP_P (updating_frame
))
423 (*set_terminal_window_hook
) (size
);
426 specified_window
= size
? size
: FRAME_HEIGHT (selected_frame
);
427 if (!scroll_region_ok
)
429 set_scroll_region (0, specified_window
);
433 set_scroll_region (start
, stop
)
437 if (TS_set_scroll_region
)
439 buf
= tparam (TS_set_scroll_region
, 0, 0, start
, stop
- 1);
441 else if (TS_set_scroll_region_1
)
443 buf
= tparam (TS_set_scroll_region_1
, 0, 0,
444 FRAME_HEIGHT (selected_frame
), start
,
445 FRAME_HEIGHT (selected_frame
) - stop
,
446 FRAME_HEIGHT (selected_frame
));
450 buf
= tparam (TS_set_window
, 0, 0, start
, 0, stop
, FRAME_WIDTH (selected_frame
));
461 OUTPUT (TS_insert_mode
);
469 OUTPUT (TS_end_insert_mode
);
473 /* Handle highlighting when TN_standout_width (termcap sg) is not specified.
474 In these terminals, output is affected by the value of standout
475 mode when the output is written.
477 These functions are called on all terminals, but do nothing
478 on terminals whose standout mode does not work that way. */
481 turn_off_highlight ()
483 if (TN_standout_width
< 0)
486 OUTPUT_IF (TS_end_standout_mode
);
494 if (TN_standout_width
< 0)
497 OUTPUT_IF (TS_standout_mode
);
502 /* Set standout mode to the state it should be in for
503 empty space inside windows. What this is,
504 depends on the user option inverse-video. */
507 background_highlight ()
509 if (TN_standout_width
>= 0)
512 turn_on_highlight ();
514 turn_off_highlight ();
517 /* Set standout mode to the mode specified for the text to be output. */
520 highlight_if_desired ()
522 if (TN_standout_width
>= 0)
524 if (!inverse_video
== !standout_requested
)
525 turn_off_highlight ();
527 turn_on_highlight ();
530 /* Handle standout mode for terminals in which TN_standout_width >= 0.
531 On these terminals, standout is controlled by markers that
532 live inside the terminal's memory. TN_standout_width is the width
533 that the marker occupies in memory. Standout runs from the marker
534 to the end of the line on some terminals, or to the next
535 turn-off-standout marker (TS_end_standout_mode) string
536 on other terminals. */
538 /* Write a standout marker or end-standout marker at the front of the line
539 at vertical position vpos. */
542 write_standout_marker (flag
, vpos
)
545 if (flag
|| (TS_end_standout_mode
&& !TF_teleray
&& !se_is_so
546 && !(TF_xs
&& TN_standout_width
== 0)))
549 cmplus (TN_standout_width
);
550 OUTPUT (flag
? TS_standout_mode
: TS_end_standout_mode
);
551 chars_wasted
[curY
] = TN_standout_width
| 0100;
555 /* External interface to control of standout mode.
556 Call this when about to modify line at position VPOS
557 and not change whether it is highlighted. */
560 reassert_line_highlight (highlight
, vpos
)
564 if (! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
566 (*reassert_line_highlight_hook
) (highlight
, vpos
);
569 if (TN_standout_width
< 0)
570 /* Handle terminals where standout takes affect at output time */
571 standout_requested
= highlight
;
572 else if (chars_wasted
[vpos
] == 0)
573 /* For terminals with standout markers, write one on this line
574 if there isn't one already. */
575 write_standout_marker (highlight
, vpos
);
578 /* Call this when about to modify line at position VPOS
579 and change whether it is highlighted. */
582 change_line_highlight (new_highlight
, vpos
, first_unused_hpos
)
583 int new_highlight
, vpos
, first_unused_hpos
;
585 standout_requested
= new_highlight
;
586 if (! FRAME_TERMCAP_P (updating_frame
))
588 (*change_line_highlight_hook
) (new_highlight
, vpos
, first_unused_hpos
);
594 if (TN_standout_width
< 0)
595 background_highlight ();
596 /* If line starts with a marker, delete the marker */
597 else if (TS_clr_line
&& chars_wasted
[curY
])
600 /* On Teleray, make sure to erase the SO marker. */
603 cmgoto (curY
- 1, FRAME_WIDTH (selected_frame
) - 4);
605 curY
++; /* ESC S moves to next line where the TS_standout_mode was */
609 cmgoto (curY
, 0); /* reposition to kill standout marker */
611 clear_end_of_line_raw (first_unused_hpos
);
612 reassert_line_highlight (new_highlight
, curY
);
616 /* Move to absolute position, specified origin 0 */
622 if (! FRAME_TERMCAP_P ((updating_frame
627 (*cursor_to_hook
) (row
, col
);
631 /* Detect the case where we are called from reset_sys_modes
632 and the costs have never been calculated. Do nothing. */
633 if (chars_wasted
== 0)
636 col
+= chars_wasted
[row
] & 077;
637 if (curY
== row
&& curX
== col
)
639 if (!TF_standout_motion
)
640 background_highlight ();
641 if (!TF_insmode_motion
)
646 /* Similar but don't take any account of the wasted characters. */
649 raw_cursor_to (row
, col
)
652 if (! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
654 (*raw_cursor_to_hook
) (row
, col
);
657 if (curY
== row
&& curX
== col
)
659 if (!TF_standout_motion
)
660 background_highlight ();
661 if (!TF_insmode_motion
)
666 /* Erase operations */
668 /* clear from cursor to end of frame */
674 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
676 (*clear_to_end_hook
) ();
679 if (TS_clr_to_bottom
)
681 background_highlight ();
682 OUTPUT (TS_clr_to_bottom
);
683 bzero (chars_wasted
+ curY
, FRAME_HEIGHT (selected_frame
) - curY
);
687 for (i
= curY
; i
< FRAME_HEIGHT (selected_frame
); i
++)
690 clear_end_of_line_raw (FRAME_WIDTH (selected_frame
));
695 /* Clear entire frame */
701 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
703 (*clear_frame_hook
) ();
708 background_highlight ();
709 OUTPUT (TS_clr_frame
);
710 bzero (chars_wasted
, FRAME_HEIGHT (selected_frame
));
720 /* Clear to end of line, but do not clear any standout marker.
721 Assumes that the cursor is positioned at a character of real text,
722 which implies it cannot be before a standout marker
723 unless the marker has zero width.
725 Note that the cursor may be moved. */
728 clear_end_of_line (first_unused_hpos
)
729 int first_unused_hpos
;
731 static GLYPH buf
= SPACEGLYPH
;
732 if (FRAME_TERMCAP_P (selected_frame
)
734 && TN_standout_width
== 0 && curX
== 0 && chars_wasted
[curY
] != 0)
735 write_glyphs (&buf
, 1);
736 clear_end_of_line_raw (first_unused_hpos
);
739 /* Clear from cursor to end of line.
740 Assume that the line is already clear starting at column first_unused_hpos.
741 If the cursor is at a standout marker, erase the marker.
743 Note that the cursor may be moved, on terminals lacking a `ce' string. */
746 clear_end_of_line_raw (first_unused_hpos
)
747 int first_unused_hpos
;
751 if (clear_end_of_line_hook
752 && ! FRAME_TERMCAP_P ((updating_frame
756 (*clear_end_of_line_hook
) (first_unused_hpos
);
760 /* Detect the case where we are called from reset_sys_modes
761 and the costs have never been calculated. Do nothing. */
762 if (chars_wasted
== 0)
765 first_unused_hpos
+= chars_wasted
[curY
] & 077;
766 if (curX
>= first_unused_hpos
)
768 /* Notice if we are erasing a magic cookie */
770 chars_wasted
[curY
] = 0;
771 background_highlight ();
774 OUTPUT1 (TS_clr_line
);
777 { /* have to do it the hard way */
780 /* Do not write in last row last col with Autowrap on. */
781 if (AutoWrap
&& curY
== FRAME_HEIGHT (selected_frame
) - 1
782 && first_unused_hpos
== FRAME_WIDTH (selected_frame
))
785 for (i
= curX
; i
< first_unused_hpos
; i
++)
788 fputc (' ', termscript
);
791 cmplus (first_unused_hpos
- curX
);
795 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
796 store them at DST. Do not write more than DST_LEN bytes. That may
797 require stopping before all SRC_LEN input glyphs have been
800 We store the number of glyphs actually converted in *CONSUMED. The
801 return value is the number of bytes store in DST. */
804 encode_terminal_code (src
, dst
, src_len
, dst_len
, consumed
)
808 int dst_len
, *consumed
;
810 GLYPH
*src_start
= src
, *src_end
= src
+ src_len
;
811 unsigned char *dst_start
= dst
, *dst_end
= dst
+ dst_len
;
814 unsigned char workbuf
[4], *buf
;
816 register int tlen
= GLYPH_TABLE_LENGTH
;
817 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
818 struct coding_system
*coding
;
820 coding
= (CODING_REQUIRE_ENCODING (&terminal_coding
)
822 : &safe_terminal_coding
);
824 while (src
< src_end
)
827 /* We must skip glyphs to be padded for a wide character. */
828 if (! (g
& GLYPH_MASK_PADDING
))
830 if ((c
= GLYPH_CHAR (selected_frame
, g
)) > MAX_CHAR
)
833 g
= MAKE_GLYPH (selected_frame
, c
,
834 GLYPH_FACE (selected_frame
, g
));
836 if (COMPOSITE_CHAR_P (c
))
838 /* If C is a composite character, we can display
839 only the first component. */
840 g
= cmpchar_table
[COMPOSITE_CHAR_ID (c
)]->glyph
[0],
841 c
= GLYPH_CHAR (selected_frame
, g
);
845 /* G has an entry in Vglyph_table,
846 so process any alias before testing for simpleness. */
847 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
848 c
= GLYPH_CHAR (selected_frame
, g
);
850 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
851 /* We set the multi-byte form of C at BUF. */
852 len
= CHAR_STRING (c
, workbuf
, buf
);
855 /* We have a string in Vglyph_table. */
856 len
= GLYPH_LENGTH (tbase
, g
);
857 buf
= GLYPH_STRING (tbase
, g
);
860 encode_coding (coding
, buf
, dst
, len
, dst_end
- dst
);
861 if (coding
->consumed
< len
)
862 /* We get a carryover because the remaining output
863 buffer is too short. We must break the loop here
864 without increasing SRC so that the next call of
865 this function start from the same glyph. */
867 dst
+= coding
->produced
;
871 *consumed
= src
- src_start
;
872 return (dst
- dst_start
);
877 write_glyphs (string
, len
)
878 register GLYPH
*string
;
882 register int tlen
= GLYPH_TABLE_LENGTH
;
883 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
884 int produced
, consumed
;
886 if (write_glyphs_hook
887 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: selected_frame
)))
889 (*write_glyphs_hook
) (string
, len
);
893 highlight_if_desired ();
896 /* Don't dare write in last column of bottom line, if AutoWrap,
897 since that would scroll the whole frame on some terminals. */
900 && curY
+ 1 == FRAME_HEIGHT (selected_frame
)
901 && (curX
+ len
- (chars_wasted
[curY
] & 077)
902 == FRAME_WIDTH (selected_frame
)))
908 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
910 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
913 /* We use shared conversion buffer of the current size (1024
914 bytes at least). Usually it is sufficient, but if not, we
915 just repeat the loop. */
916 produced
= encode_terminal_code (string
, conversion_buffer
,
917 len
, conversion_buffer_size
, &consumed
);
920 fwrite (conversion_buffer
, 1, produced
, stdout
);
924 fwrite (conversion_buffer
, 1, produced
, termscript
);
929 /* We may have to output some codes to terminate the writing. */
930 if (CODING_REQUIRE_FLUSHING (&terminal_coding
))
932 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
933 encode_coding (&terminal_coding
, (char *)0, conversion_buffer
,
934 0, conversion_buffer_size
);
935 if (terminal_coding
.produced
> 0)
937 fwrite (conversion_buffer
, 1, terminal_coding
.produced
, stdout
);
941 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
948 /* If start is zero, insert blanks instead of a string at start */
951 insert_glyphs (start
, len
)
952 register GLYPH
*start
;
957 register int tlen
= GLYPH_TABLE_LENGTH
;
958 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
963 if (insert_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
965 (*insert_glyphs_hook
) (start
, len
);
968 highlight_if_desired ();
970 if (TS_ins_multi_chars
)
972 buf
= tparam (TS_ins_multi_chars
, 0, 0, len
);
976 write_glyphs (start
, len
);
982 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
983 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
986 int produced
, consumed
;
988 OUTPUT1_IF (TS_ins_char
);
994 /* We must open sufficient space for a character which
995 occupies more than one column. */
996 while (*start
& GLYPH_MASK_PADDING
)
998 OUTPUT1_IF (TS_ins_char
);
1004 /* This is the last glyph. */
1005 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
1007 /* We use shared conversion buffer of the current size (1024
1008 bytes at least). It is surely sufficient for just one glyph. */
1009 produced
= encode_terminal_code (&g
, conversion_buffer
,
1010 1, conversion_buffer_size
, &consumed
);
1013 fwrite (conversion_buffer
, 1, produced
, stdout
);
1014 if (ferror (stdout
))
1017 fwrite (conversion_buffer
, 1, produced
, termscript
);
1020 OUTPUT1_IF (TS_pad_inserted_char
);
1032 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1034 (*delete_glyphs_hook
) (n
);
1038 if (delete_in_insert_mode
)
1045 OUTPUT_IF (TS_delete_mode
);
1048 if (TS_del_multi_chars
)
1050 buf
= tparam (TS_del_multi_chars
, 0, 0, n
);
1055 for (i
= 0; i
< n
; i
++)
1056 OUTPUT1 (TS_del_char
);
1057 if (!delete_in_insert_mode
)
1058 OUTPUT_IF (TS_end_delete_mode
);
1061 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1064 ins_del_lines (vpos
, n
)
1067 char *multi
= n
> 0 ? TS_ins_multi_lines
: TS_del_multi_lines
;
1068 char *single
= n
> 0 ? TS_ins_line
: TS_del_line
;
1069 char *scroll
= n
> 0 ? TS_rev_scroll
: TS_fwd_scroll
;
1071 register int i
= n
> 0 ? n
: -n
;
1074 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1076 (*ins_del_lines_hook
) (vpos
, n
);
1080 /* If the lines below the insertion are being pushed
1081 into the end of the window, this is the same as clearing;
1082 and we know the lines are already clear, since the matching
1083 deletion has already been done. So can ignore this. */
1084 /* If the lines below the deletion are blank lines coming
1085 out of the end of the window, don't bother,
1086 as there will be a matching inslines later that will flush them. */
1087 if (scroll_region_ok
&& vpos
+ i
>= specified_window
)
1089 if (!memory_below_frame
&& vpos
+ i
>= FRAME_HEIGHT (selected_frame
))
1094 raw_cursor_to (vpos
, 0);
1095 background_highlight ();
1096 buf
= tparam (multi
, 0, 0, i
);
1102 raw_cursor_to (vpos
, 0);
1103 background_highlight ();
1111 set_scroll_region (vpos
, specified_window
);
1113 raw_cursor_to (specified_window
- 1, 0);
1115 raw_cursor_to (vpos
, 0);
1116 background_highlight ();
1118 OUTPUTL (scroll
, specified_window
- vpos
);
1119 set_scroll_region (0, specified_window
);
1122 if (TN_standout_width
>= 0)
1124 register int lower_limit
1127 : FRAME_HEIGHT (selected_frame
));
1131 bcopy (&chars_wasted
[vpos
- n
], &chars_wasted
[vpos
],
1132 lower_limit
- vpos
+ n
);
1133 bzero (&chars_wasted
[lower_limit
+ n
], - n
);
1137 bcopy (&chars_wasted
[vpos
], ©buf
[vpos
], lower_limit
- vpos
- n
);
1138 bcopy (©buf
[vpos
], &chars_wasted
[vpos
+ n
],
1139 lower_limit
- vpos
- n
);
1140 bzero (&chars_wasted
[vpos
], n
);
1143 if (!scroll_region_ok
&& memory_below_frame
&& n
< 0)
1145 cursor_to (FRAME_HEIGHT (selected_frame
) + n
, 0);
1150 /* Compute cost of sending "str", in characters,
1151 not counting any line-dependent padding. */
1159 tputs (str
, 0, evalcost
);
1163 /* Compute cost of sending "str", in characters,
1164 counting any line-dependent padding at one line. */
1167 string_cost_one_line (str
)
1172 tputs (str
, 1, evalcost
);
1176 /* Compute per line amount of line-dependent padding,
1177 in tenths of characters. */
1185 tputs (str
, 0, evalcost
);
1188 tputs (str
, 10, evalcost
);
1193 /* char_ins_del_cost[n] is cost of inserting N characters.
1194 char_ins_del_cost[-n] is cost of deleting N characters.
1195 The length of this vector is based on max_frame_width. */
1197 int *char_ins_del_vector
;
1199 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH ((f))])
1204 calculate_ins_del_char_costs (frame
)
1207 int ins_startup_cost
, del_startup_cost
;
1208 int ins_cost_per_char
, del_cost_per_char
;
1212 if (TS_ins_multi_chars
)
1214 ins_cost_per_char
= 0;
1215 ins_startup_cost
= string_cost_one_line (TS_ins_multi_chars
);
1217 else if (TS_ins_char
|| TS_pad_inserted_char
1218 || (TS_insert_mode
&& TS_end_insert_mode
))
1220 ins_startup_cost
= (30 * (string_cost (TS_insert_mode
)
1221 + string_cost (TS_end_insert_mode
))) / 100;
1222 ins_cost_per_char
= (string_cost_one_line (TS_ins_char
)
1223 + string_cost_one_line (TS_pad_inserted_char
));
1227 ins_startup_cost
= 9999;
1228 ins_cost_per_char
= 0;
1231 if (TS_del_multi_chars
)
1233 del_cost_per_char
= 0;
1234 del_startup_cost
= string_cost_one_line (TS_del_multi_chars
);
1236 else if (TS_del_char
)
1238 del_startup_cost
= (string_cost (TS_delete_mode
)
1239 + string_cost (TS_end_delete_mode
));
1240 if (delete_in_insert_mode
)
1241 del_startup_cost
/= 2;
1242 del_cost_per_char
= string_cost_one_line (TS_del_char
);
1246 del_startup_cost
= 9999;
1247 del_cost_per_char
= 0;
1250 /* Delete costs are at negative offsets */
1251 p
= &char_ins_del_cost (frame
)[0];
1252 for (i
= FRAME_WIDTH (frame
); --i
>= 0;)
1253 *--p
= (del_startup_cost
+= del_cost_per_char
);
1255 /* Doing nothing is free */
1256 p
= &char_ins_del_cost (frame
)[0];
1259 /* Insert costs are at positive offsets */
1260 for (i
= FRAME_WIDTH (frame
); --i
>= 0;)
1261 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1265 calculate_costs (frame
)
1268 register char *f
= (TS_set_scroll_region
1269 ? TS_set_scroll_region
1270 : TS_set_scroll_region_1
);
1272 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1274 scroll_region_cost
= string_cost (f
);
1275 #ifdef HAVE_X_WINDOWS
1276 if (FRAME_X_P (frame
))
1278 do_line_insertion_deletion_costs (frame
, 0, ".5*", 0, ".5*",
1280 x_screen_planes (frame
));
1281 scroll_region_cost
= 0;
1286 /* These variables are only used for terminal stuff. They are allocated
1287 once for the terminal frame of X-windows emacs, but not used afterwards.
1289 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1290 X turns off char_ins_del_ok.
1292 chars_wasted and copybuf are only used here in term.c in cases where
1293 the term hook isn't called. */
1295 max_frame_height
= max (max_frame_height
, FRAME_HEIGHT (frame
));
1296 max_frame_width
= max (max_frame_width
, FRAME_WIDTH (frame
));
1298 if (chars_wasted
!= 0)
1299 chars_wasted
= (char *) xrealloc (chars_wasted
, max_frame_height
);
1301 chars_wasted
= (char *) xmalloc (max_frame_height
);
1304 copybuf
= (char *) xrealloc (copybuf
, max_frame_height
);
1306 copybuf
= (char *) xmalloc (max_frame_height
);
1308 if (char_ins_del_vector
!= 0)
1310 = (int *) xrealloc (char_ins_del_vector
,
1312 + 2 * max_frame_width
* sizeof (int)));
1315 = (int *) xmalloc (sizeof (int)
1316 + 2 * max_frame_width
* sizeof (int));
1318 bzero (chars_wasted
, max_frame_height
);
1319 bzero (copybuf
, max_frame_height
);
1320 bzero (char_ins_del_vector
, (sizeof (int)
1321 + 2 * max_frame_width
* sizeof (int)));
1323 if (f
&& (!TS_ins_line
&& !TS_del_line
))
1324 do_line_insertion_deletion_costs (frame
,
1325 TS_rev_scroll
, TS_ins_multi_lines
,
1326 TS_fwd_scroll
, TS_del_multi_lines
,
1329 do_line_insertion_deletion_costs (frame
,
1330 TS_ins_line
, TS_ins_multi_lines
,
1331 TS_del_line
, TS_del_multi_lines
,
1334 calculate_ins_del_char_costs (frame
);
1336 /* Don't use TS_repeat if its padding is worse than sending the chars */
1337 if (TS_repeat
&& per_line_cost (TS_repeat
) * baud_rate
< 9000)
1338 RPov
= string_cost (TS_repeat
);
1340 RPov
= FRAME_WIDTH (frame
) * 2;
1342 cmcostinit (); /* set up cursor motion costs */
1349 /* Termcap capability names that correspond directly to X keysyms.
1350 Some of these (marked "terminfo") aren't supplied by old-style
1351 (Berkeley) termcap entries. They're listed in X keysym order;
1352 except we put the keypad keys first, so that if they clash with
1353 other keys (as on the IBM PC keyboard) they get overridden.
1356 static struct fkey_table keys
[] = {
1357 "kh", "home", /* termcap */
1358 "kl", "left", /* termcap */
1359 "ku", "up", /* termcap */
1360 "kr", "right", /* termcap */
1361 "kd", "down", /* termcap */
1362 "%8", "prior", /* terminfo */
1363 "%5", "next", /* terminfo */
1364 "@7", "end", /* terminfo */
1365 "@1", "begin", /* terminfo */
1366 "*6", "select", /* terminfo */
1367 "%9", "print", /* terminfo */
1368 "@4", "execute", /* terminfo --- actually the `command' key */
1370 * "insert" --- see below
1372 "&8", "undo", /* terminfo */
1373 "%0", "redo", /* terminfo */
1374 "%7", "menu", /* terminfo --- actually the `options' key */
1375 "@0", "find", /* terminfo */
1376 "@2", "cancel", /* terminfo */
1377 "%1", "help", /* terminfo */
1379 * "break" goes here, but can't be reliably intercepted with termcap
1381 "&4", "reset", /* terminfo --- actually `restart' */
1383 * "system" and "user" --- no termcaps
1385 "kE", "clearline", /* terminfo */
1386 "kA", "insertline", /* terminfo */
1387 "kL", "deleteline", /* terminfo */
1388 "kI", "insertchar", /* terminfo */
1389 "kD", "deletechar", /* terminfo */
1390 "kB", "backtab", /* terminfo */
1392 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1394 "@8", "kp-enter", /* terminfo */
1396 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1397 * "kp-multiply", "kp-add", "kp-separator",
1398 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1399 * --- no termcaps for any of these.
1401 "K4", "kp-1", /* terminfo */
1403 * "kp-2" --- no termcap
1405 "K5", "kp-3", /* terminfo */
1407 * "kp-4" --- no termcap
1409 "K2", "kp-5", /* terminfo */
1411 * "kp-6" --- no termcap
1413 "K1", "kp-7", /* terminfo */
1415 * "kp-8" --- no termcap
1417 "K3", "kp-9", /* terminfo */
1419 * "kp-equal" --- no termcap
1432 static char **term_get_fkeys_arg
;
1433 static Lisp_Object
term_get_fkeys_1 ();
1435 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1436 This function scans the termcap function key sequence entries, and
1437 adds entries to Vfunction_key_map for each function key it finds. */
1440 term_get_fkeys (address
)
1443 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1444 errors during the call. The only errors should be from Fdefine_key
1445 when given a key sequence containing an invalid prefix key. If the
1446 termcap defines function keys which use a prefix that is already bound
1447 to a command by the default bindings, we should silently ignore that
1448 function key specification, rather than giving the user an error and
1449 refusing to run at all on such a terminal. */
1451 extern Lisp_Object
Fidentity ();
1452 term_get_fkeys_arg
= address
;
1453 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1461 char **address
= term_get_fkeys_arg
;
1463 /* This can happen if CANNOT_DUMP or with strange options. */
1465 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1467 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1469 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1471 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1472 Fmake_vector (make_number (1),
1473 intern (keys
[i
].name
)));
1476 /* The uses of the "k0" capability are inconsistent; sometimes it
1477 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1478 We will attempt to politely accommodate both systems by testing for
1479 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1482 char *k_semi
= tgetstr ("k;", address
);
1483 char *k0
= tgetstr ("k0", address
);
1484 char *k0_name
= "f10";
1488 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1489 Fmake_vector (make_number (1), intern ("f10")));
1494 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1495 Fmake_vector (make_number (1), intern (k0_name
)));
1498 /* Set up cookies for numbered function keys above f10. */
1500 char fcap
[3], fkey
[4];
1502 fcap
[0] = 'F'; fcap
[2] = '\0';
1503 for (i
= 11; i
< 64; i
++)
1506 fcap
[1] = '1' + i
- 11;
1508 fcap
[1] = 'A' + i
- 20;
1510 fcap
[1] = 'a' + i
- 46;
1513 char *sequence
= tgetstr (fcap
, address
);
1516 sprintf (fkey
, "f%d", i
);
1517 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1518 Fmake_vector (make_number (1),
1526 * Various mappings to try and get a better fit.
1529 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1530 if (!tgetstr (cap1, address)) \
1532 char *sequence = tgetstr (cap2, address); \
1534 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1535 Fmake_vector (make_number (1), \
1539 /* if there's no key_next keycap, map key_npage to `next' keysym */
1540 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1541 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1542 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1543 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1544 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1545 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1546 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1548 /* IBM has their own non-standard dialect of terminfo.
1549 If the standard name isn't found, try the IBM name. */
1550 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1551 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1552 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1553 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1554 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1555 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1556 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1557 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1558 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1559 #undef CONDITIONAL_REASSIGN
1565 term_init (terminal_type
)
1566 char *terminal_type
;
1569 char **address
= &area
;
1575 initialize_w32_display ();
1579 area
= (char *) malloc (2044);
1584 FrameRows
= FRAME_HEIGHT (selected_frame
);
1585 FrameCols
= FRAME_WIDTH (selected_frame
);
1586 specified_window
= FRAME_HEIGHT (selected_frame
);
1588 delete_in_insert_mode
= 1;
1591 scroll_region_ok
= 0;
1593 /* Seems to insert lines when it's not supposed to, messing
1594 up the display. In doing a trace, it didn't seem to be
1595 called much, so I don't think we're losing anything by
1598 line_ins_del_ok
= 0;
1599 char_ins_del_ok
= 1;
1603 FRAME_CAN_HAVE_SCROLL_BARS (selected_frame
) = 0;
1604 FRAME_VERTICAL_SCROLL_BAR_TYPE (selected_frame
) = vertical_scroll_bar_none
;
1607 #else /* not WINDOWSNT */
1611 status
= tgetent (buffer
, terminal_type
);
1615 fatal ("Cannot open terminfo database file");
1617 fatal ("Cannot open termcap database file");
1623 fatal ("Terminal type %s is not defined.\n\
1624 If that is not the actual type of terminal you have,\n\
1625 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1626 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1627 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
1630 fatal ("Terminal type %s is not defined.\n\
1631 If that is not the actual type of terminal you have,\n\
1632 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1633 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1634 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
1639 area
= (char *) malloc (2044);
1641 area
= (char *) malloc (strlen (buffer
));
1642 #endif /* not TERMINFO */
1646 TS_ins_line
= tgetstr ("al", address
);
1647 TS_ins_multi_lines
= tgetstr ("AL", address
);
1648 TS_bell
= tgetstr ("bl", address
);
1649 BackTab
= tgetstr ("bt", address
);
1650 TS_clr_to_bottom
= tgetstr ("cd", address
);
1651 TS_clr_line
= tgetstr ("ce", address
);
1652 TS_clr_frame
= tgetstr ("cl", address
);
1653 ColPosition
= tgetstr ("ch", address
);
1654 AbsPosition
= tgetstr ("cm", address
);
1655 CR
= tgetstr ("cr", address
);
1656 TS_set_scroll_region
= tgetstr ("cs", address
);
1657 TS_set_scroll_region_1
= tgetstr ("cS", address
);
1658 RowPosition
= tgetstr ("cv", address
);
1659 TS_del_char
= tgetstr ("dc", address
);
1660 TS_del_multi_chars
= tgetstr ("DC", address
);
1661 TS_del_line
= tgetstr ("dl", address
);
1662 TS_del_multi_lines
= tgetstr ("DL", address
);
1663 TS_delete_mode
= tgetstr ("dm", address
);
1664 TS_end_delete_mode
= tgetstr ("ed", address
);
1665 TS_end_insert_mode
= tgetstr ("ei", address
);
1666 Home
= tgetstr ("ho", address
);
1667 TS_ins_char
= tgetstr ("ic", address
);
1668 TS_ins_multi_chars
= tgetstr ("IC", address
);
1669 TS_insert_mode
= tgetstr ("im", address
);
1670 TS_pad_inserted_char
= tgetstr ("ip", address
);
1671 TS_end_keypad_mode
= tgetstr ("ke", address
);
1672 TS_keypad_mode
= tgetstr ("ks", address
);
1673 LastLine
= tgetstr ("ll", address
);
1674 Right
= tgetstr ("nd", address
);
1675 Down
= tgetstr ("do", address
);
1677 Down
= tgetstr ("nl", address
); /* Obsolete name for "do" */
1679 /* VMS puts a carriage return before each linefeed,
1680 so it is not safe to use linefeeds. */
1681 if (Down
&& Down
[0] == '\n' && Down
[1] == '\0')
1684 if (tgetflag ("bs"))
1685 Left
= "\b"; /* can't possibly be longer! */
1686 else /* (Actually, "bs" is obsolete...) */
1687 Left
= tgetstr ("le", address
);
1689 Left
= tgetstr ("bc", address
); /* Obsolete name for "le" */
1690 TS_pad_char
= tgetstr ("pc", address
);
1691 TS_repeat
= tgetstr ("rp", address
);
1692 TS_end_standout_mode
= tgetstr ("se", address
);
1693 TS_fwd_scroll
= tgetstr ("sf", address
);
1694 TS_standout_mode
= tgetstr ("so", address
);
1695 TS_rev_scroll
= tgetstr ("sr", address
);
1696 Wcm
.cm_tab
= tgetstr ("ta", address
);
1697 TS_end_termcap_modes
= tgetstr ("te", address
);
1698 TS_termcap_modes
= tgetstr ("ti", address
);
1699 TS_bold_mode
= tgetstr ("md", address
);
1700 TS_end_bold_mode
= tgetstr ("me", address
);
1701 TS_underscore_mode
= tgetstr ("us", address
);
1702 TS_end_underscore_mode
= tgetstr ("ue", address
);
1703 Up
= tgetstr ("up", address
);
1704 TS_visible_bell
= tgetstr ("vb", address
);
1705 TS_end_visual_mode
= tgetstr ("ve", address
);
1706 TS_visual_mode
= tgetstr ("vs", address
);
1707 TS_set_window
= tgetstr ("wi", address
);
1708 MultiUp
= tgetstr ("UP", address
);
1709 MultiDown
= tgetstr ("DO", address
);
1710 MultiLeft
= tgetstr ("LE", address
);
1711 MultiRight
= tgetstr ("RI", address
);
1713 MagicWrap
= tgetflag ("xn");
1714 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
1715 the former flag imply the latter. */
1716 AutoWrap
= MagicWrap
|| tgetflag ("am");
1717 memory_below_frame
= tgetflag ("db");
1718 TF_hazeltine
= tgetflag ("hz");
1719 must_write_spaces
= tgetflag ("in");
1720 meta_key
= tgetflag ("km") || tgetflag ("MT");
1721 TF_insmode_motion
= tgetflag ("mi");
1722 TF_standout_motion
= tgetflag ("ms");
1723 TF_underscore
= tgetflag ("ul");
1724 TF_xs
= tgetflag ("xs");
1725 TF_teleray
= tgetflag ("xt");
1727 term_get_fkeys (address
);
1729 /* Get frame size from system, or else from termcap. */
1732 get_frame_size (&width
, &height
);
1733 FRAME_WIDTH (selected_frame
) = width
;
1734 FRAME_HEIGHT (selected_frame
) = height
;
1737 if (FRAME_WIDTH (selected_frame
) <= 0)
1738 SET_FRAME_WIDTH (selected_frame
, tgetnum ("co"));
1740 /* Keep width and external_width consistent */
1741 SET_FRAME_WIDTH (selected_frame
, FRAME_WIDTH (selected_frame
));
1742 if (FRAME_HEIGHT (selected_frame
) <= 0)
1743 FRAME_HEIGHT (selected_frame
) = tgetnum ("li");
1745 if (FRAME_HEIGHT (selected_frame
) < 3
1746 || FRAME_WIDTH (selected_frame
) < 3)
1747 fatal ("Screen size %dx%d is too small",
1748 FRAME_HEIGHT (selected_frame
), FRAME_WIDTH (selected_frame
));
1750 min_padding_speed
= tgetnum ("pb");
1751 TN_standout_width
= tgetnum ("sg");
1752 TabWidth
= tgetnum ("tw");
1755 /* These capabilities commonly use ^J.
1756 I don't know why, but sending them on VMS does not work;
1757 it causes following spaces to be lost, sometimes.
1758 For now, the simplest fix is to avoid using these capabilities ever. */
1759 if (Down
&& Down
[0] == '\n')
1767 TS_fwd_scroll
= Down
;
1769 PC
= TS_pad_char
? *TS_pad_char
: 0;
1774 /* Turned off since /etc/termcap seems to have :ta= for most terminals
1775 and newer termcap doc does not seem to say there is a default.
1780 if (TS_standout_mode
== 0)
1782 TN_standout_width
= tgetnum ("ug");
1783 TS_end_standout_mode
= tgetstr ("ue", address
);
1784 TS_standout_mode
= tgetstr ("us", address
);
1787 /* If no `se' string, try using a `me' string instead.
1788 If that fails, we can't use standout mode at all. */
1789 if (TS_end_standout_mode
== 0)
1791 char *s
= tgetstr ("me", address
);
1793 TS_end_standout_mode
= s
;
1795 TS_standout_mode
= 0;
1801 /* Teleray: most programs want a space in front of TS_standout_mode,
1802 but Emacs can do without it (and give one extra column). */
1803 TS_standout_mode
= "\033RD";
1804 TN_standout_width
= 1;
1805 /* But that means we cannot rely on ^M to go to column zero! */
1807 /* LF can't be trusted either -- can alter hpos */
1808 /* if move at column 0 thru a line with TS_standout_mode */
1812 /* Special handling for certain terminal types known to need it */
1814 if (!strcmp (terminal_type
, "supdup"))
1816 memory_below_frame
= 1;
1817 Wcm
.cm_losewrap
= 1;
1819 if (!strncmp (terminal_type
, "c10", 3)
1820 || !strcmp (terminal_type
, "perq"))
1822 /* Supply a makeshift :wi string.
1823 This string is not valid in general since it works only
1824 for windows starting at the upper left corner;
1825 but that is all Emacs uses.
1827 This string works only if the frame is using
1828 the top of the video memory, because addressing is memory-relative.
1829 So first check the :ti string to see if that is true.
1831 It would be simpler if the :wi string could go in the termcap
1832 entry, but it can't because it is not fully valid.
1833 If it were in the termcap entry, it would confuse other programs. */
1836 p
= TS_termcap_modes
;
1837 while (*p
&& strcmp (p
, "\033v "))
1840 TS_set_window
= "\033v%C %C %C %C ";
1842 /* Termcap entry often fails to have :in: flag */
1843 must_write_spaces
= 1;
1844 /* :ti string typically fails to have \E^G! in it */
1845 /* This limits scope of insert-char to one line. */
1846 strcpy (area
, TS_termcap_modes
);
1847 strcat (area
, "\033\007!");
1848 TS_termcap_modes
= area
;
1849 area
+= strlen (area
) + 1;
1851 /* Change all %+ parameters to %C, to handle
1852 values above 96 correctly for the C100. */
1855 if (p
[0] == '%' && p
[1] == '+')
1861 FrameRows
= FRAME_HEIGHT (selected_frame
);
1862 FrameCols
= FRAME_WIDTH (selected_frame
);
1863 specified_window
= FRAME_HEIGHT (selected_frame
);
1865 if (Wcm_init () == -1) /* can't do cursor motion */
1867 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1868 It lacks the ability to position the cursor.\n\
1869 If that is not the actual type of terminal you have, use either the\n\
1870 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
1871 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
1875 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1876 It lacks the ability to position the cursor.\n\
1877 If that is not the actual type of terminal you have,\n\
1878 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1879 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1880 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
1882 # else /* TERMCAP */
1883 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1884 It lacks the ability to position the cursor.\n\
1885 If that is not the actual type of terminal you have,\n\
1886 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
1887 `setenv TERM ...') to specify the correct type. It may be necessary\n\
1888 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
1890 # endif /* TERMINFO */
1892 if (FRAME_HEIGHT (selected_frame
) <= 0
1893 || FRAME_WIDTH (selected_frame
) <= 0)
1894 fatal ("The frame size has not been specified");
1896 delete_in_insert_mode
1897 = TS_delete_mode
&& TS_insert_mode
1898 && !strcmp (TS_delete_mode
, TS_insert_mode
);
1900 se_is_so
= (TS_standout_mode
1901 && TS_end_standout_mode
1902 && !strcmp (TS_standout_mode
, TS_end_standout_mode
));
1904 /* Remove width of standout marker from usable width of line */
1905 if (TN_standout_width
> 0)
1906 SET_FRAME_WIDTH (selected_frame
,
1907 FRAME_WIDTH (selected_frame
) - TN_standout_width
);
1909 UseTabs
= tabs_safe_p () && TabWidth
== 8;
1913 && (TS_set_window
|| TS_set_scroll_region
|| TS_set_scroll_region_1
));
1915 line_ins_del_ok
= (((TS_ins_line
|| TS_ins_multi_lines
)
1916 && (TS_del_line
|| TS_del_multi_lines
))
1917 || (scroll_region_ok
&& TS_fwd_scroll
&& TS_rev_scroll
));
1919 char_ins_del_ok
= ((TS_ins_char
|| TS_insert_mode
1920 || TS_pad_inserted_char
|| TS_ins_multi_chars
)
1921 && (TS_del_char
|| TS_del_multi_chars
));
1923 fast_clear_end_of_line
= TS_clr_line
!= 0;
1926 if (read_socket_hook
) /* Baudrate is somewhat */
1927 /* meaningless in this case */
1930 FRAME_CAN_HAVE_SCROLL_BARS (selected_frame
) = 0;
1931 FRAME_VERTICAL_SCROLL_BAR_TYPE (selected_frame
) = vertical_scroll_bar_none
;
1932 #endif /* WINDOWSNT */
1937 fatal (str
, arg1
, arg2
)
1938 char *str
, *arg1
, *arg2
;
1940 fprintf (stderr
, "emacs: ");
1941 fprintf (stderr
, str
, arg1
, arg2
);
1942 fprintf (stderr
, "\n");
1950 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
1951 "Non-nil means the system uses terminfo rather than termcap.\n\
1952 This variable can be used by terminal emulator packages.");
1954 system_uses_terminfo
= 1;
1956 system_uses_terminfo
= 0;
1959 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
1960 "Non-nil means call this function to ring the bell.\n\
1961 The function should accept no arguments.");
1962 Vring_bell_function
= Qnil
;