(insert_glyphs): Pass glyph, not &glyph, to
[bpt/emacs.git] / src / term.c
CommitLineData
08a24c47 1/* terminal control module for terminals described by TERMCAP
a168702a
GM
2 Copyright (C) 1985, 86, 87, 93, 94, 95, 98
3 Free Software Foundation, Inc.
08a24c47
JB
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
4746118a 9the Free Software Foundation; either version 2, or (at your option)
08a24c47
JB
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
3b7ad313
EN
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
08a24c47 21
a168702a
GM
22/* New redisplay, TTY faces by Gerd Moellmann <gerd@acm.org>. */
23
08a24c47 24
565620a5 25#include <config.h>
08a24c47
JB
26#include <stdio.h>
27#include <ctype.h>
a168702a 28#include <string.h>
08a24c47
JB
29#include "termchar.h"
30#include "termopts.h"
08a24c47 31#include "lisp.h"
a4decb7f
KH
32#include "charset.h"
33#include "coding.h"
ff11dfa1 34#include "frame.h"
08a24c47
JB
35#include "disptab.h"
36#include "termhooks.h"
5c2c7893 37#include "keyboard.h"
dfcf069d 38#include "dispextern.h"
a168702a
GM
39#include "window.h"
40
b0f61f15
GM
41#ifdef HAVE_TERMCAP_H
42#include <termcap.h>
43#endif
44
eccec691 45#include "cm.h"
dfcf069d
AS
46#ifdef HAVE_X_WINDOWS
47#include "xterm.h"
48#endif
c8951b18 49
a168702a
GM
50static void turn_on_face P_ ((struct frame *, int face_id));
51static void turn_off_face P_ ((struct frame *, int face_id));
52static void tty_show_cursor P_ ((void));
53static void tty_hide_cursor P_ ((void));
54
08a24c47
JB
55#define max(a, b) ((a) > (b) ? (a) : (b))
56#define min(a, b) ((a) < (b) ? (a) : (b))
57
e52f4e08
GM
58#define OUTPUT(a) \
59 tputs (a, (int) (FRAME_HEIGHT (XFRAME (selected_frame)) - curY), cmputc)
08a24c47
JB
60#define OUTPUT1(a) tputs (a, 1, cmputc)
61#define OUTPUTL(a, lines) tputs (a, lines, cmputc)
a168702a 62
b0f61f15
GM
63#define OUTPUT_IF(a) \
64 do { \
65 if (a) \
66 tputs (a, (int) (FRAME_HEIGHT (XFRAME (selected_frame)) \
67 - curY), cmputc); \
68 } while (0)
a168702a 69
b0f61f15 70#define OUTPUT1_IF(a) do { if (a) tputs (a, 1, cmputc); } while (0)
08a24c47 71
c291d9ef 72/* Function to use to ring the bell. */
a168702a 73
c291d9ef
RS
74Lisp_Object Vring_bell_function;
75
eb8c3be9 76/* Terminal characteristics that higher levels want to look at.
08a24c47
JB
77 These are all extern'd in termchar.h */
78
08a24c47
JB
79int must_write_spaces; /* Nonzero means spaces in the text
80 must actually be output; can't just skip
81 over some columns to leave them blank. */
82int min_padding_speed; /* Speed below which no padding necessary */
83
84int line_ins_del_ok; /* Terminal can insert and delete lines */
85int char_ins_del_ok; /* Terminal can insert and delete chars */
86int scroll_region_ok; /* Terminal supports setting the
87 scroll window */
be7cd44f
RS
88int scroll_region_cost; /* Cost of setting a scroll window,
89 measured in characters */
ff11dfa1 90int memory_below_frame; /* Terminal remembers lines
08a24c47
JB
91 scrolled off bottom */
92int fast_clear_end_of_line; /* Terminal has a `ce' string */
93
ff11dfa1 94/* Nonzero means no need to redraw the entire frame on resuming
08a24c47
JB
95 a suspended Emacs. This is useful on terminals with multiple pages,
96 where one page is used for Emacs and another for all else. */
a168702a 97
08a24c47
JB
98int no_redraw_on_reenter;
99
100/* Hook functions that you can set to snap out the functions in this file.
101 These are all extern'd in termhooks.h */
102
dfcf069d
AS
103void (*cursor_to_hook) P_ ((int, int));
104void (*raw_cursor_to_hook) P_ ((int, int));
dfcf069d
AS
105void (*clear_to_end_hook) P_ ((void));
106void (*clear_frame_hook) P_ ((void));
107void (*clear_end_of_line_hook) P_ ((int));
08a24c47 108
dfcf069d 109void (*ins_del_lines_hook) P_ ((int, int));
08a24c47 110
a168702a 111void (*change_line_highlight_hook) P_ ((int, int, int, int));
dfcf069d 112void (*reassert_line_highlight_hook) P_ ((int, int));
08a24c47 113
dfcf069d 114void (*delete_glyphs_hook) P_ ((int));
08a24c47 115
dfcf069d 116void (*ring_bell_hook) P_ ((void));
08a24c47 117
dfcf069d
AS
118void (*reset_terminal_modes_hook) P_ ((void));
119void (*set_terminal_modes_hook) P_ ((void));
120void (*update_begin_hook) P_ ((struct frame *));
121void (*update_end_hook) P_ ((struct frame *));
122void (*set_terminal_window_hook) P_ ((int));
a168702a
GM
123void (*insert_glyphs_hook) P_ ((struct glyph *, int));
124void (*write_glyphs_hook) P_ ((struct glyph *, int));
125void (*delete_glyphs_hook) P_ ((int));
08a24c47 126
dfcf069d 127int (*read_socket_hook) P_ ((int, struct input_event *, int, int));
08a24c47 128
dfcf069d 129void (*frame_up_to_date_hook) P_ ((struct frame *));
55cc089c 130
20a558dc 131/* Return the current position of the mouse.
371fbaeb
JB
132
133 Set *f to the frame the mouse is in, or zero if the mouse is in no
134 Emacs frame. If it is set to zero, all the other arguments are
135 garbage.
136
a3c87d4e
JB
137 If the motion started in a scroll bar, set *bar_window to the
138 scroll bar's window, *part to the part the mouse is currently over,
139 *x to the position of the mouse along the scroll bar, and *y to the
140 overall length of the scroll bar.
371fbaeb
JB
141
142 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
143 row of the character cell the mouse is over.
144
145 Set *time to the time the mouse was at the returned position.
146
147 This should clear mouse_moved until the next motion
148 event arrives. */
dfcf069d 149void (*mouse_position_hook) P_ ((FRAME_PTR *f, int insist,
371fbaeb 150 Lisp_Object *bar_window,
a3c87d4e 151 enum scroll_bar_part *part,
20a558dc
JB
152 Lisp_Object *x,
153 Lisp_Object *y,
dfcf069d 154 unsigned long *time));
08a24c47 155
ff11dfa1 156/* When reading from a minibuffer in a different frame, Emacs wants
a168702a 157 to shift the highlight from the selected frame to the mini-buffer's
ff11dfa1 158 frame; under X, this means it lies about where the focus is.
2e146aa4
JB
159 This hook tells the window system code to re-decide where to put
160 the highlight. */
dfcf069d 161void (*frame_rehighlight_hook) P_ ((FRAME_PTR f));
2e146aa4 162
dbc4e1c1
JB
163/* If we're displaying frames using a window system that can stack
164 frames on top of each other, this hook allows you to bring a frame
165 to the front, or bury it behind all the other windows. If this
166 hook is zero, that means the device we're displaying on doesn't
167 support overlapping frames, so there's no need to raise or lower
168 anything.
169
170 If RAISE is non-zero, F is brought to the front, before all other
171 windows. If RAISE is zero, F is sent to the back, behind all other
172 windows. */
dfcf069d 173void (*frame_raise_lower_hook) P_ ((FRAME_PTR f, int raise));
dbc4e1c1 174
a3c87d4e 175/* Set the vertical scroll bar for WINDOW to have its upper left corner
371fbaeb
JB
176 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
177 indicate that we are displaying PORTION characters out of a total
178 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
a3c87d4e 179 have a scroll bar, create one for it. */
a168702a 180
a3c87d4e 181void (*set_vertical_scroll_bar_hook)
dfcf069d
AS
182 P_ ((struct window *window,
183 int portion, int whole, int position));
20a558dc 184
371fbaeb 185
20a558dc 186/* The following three hooks are used when we're doing a thorough
a3c87d4e 187 redisplay of the frame. We don't explicitly know which scroll bars
20a558dc
JB
188 are going to be deleted, because keeping track of when windows go
189 away is a real pain - can you say set-window-configuration?
190 Instead, we just assert at the beginning of redisplay that *all*
a3c87d4e 191 scroll bars are to be removed, and then save scroll bars from the
8e6208c5 192 fiery pit when we actually redisplay their window. */
20a558dc 193
a3c87d4e
JB
194/* Arrange for all scroll bars on FRAME to be removed at the next call
195 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
a168702a 196 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
20a558dc 197
371fbaeb 198 This should be applied to each frame each time its window tree is
a3c87d4e
JB
199 redisplayed, even if it is not displaying scroll bars at the moment;
200 if the HAS_SCROLL_BARS flag has just been turned off, only calling
201 this and the judge_scroll_bars_hook will get rid of them.
371fbaeb
JB
202
203 If non-zero, this hook should be safe to apply to any frame,
a3c87d4e 204 whether or not it can support scroll bars, and whether or not it is
371fbaeb 205 currently displaying them. */
dfcf069d 206void (*condemn_scroll_bars_hook) P_ ((FRAME_PTR frame));
371fbaeb 207
a3c87d4e
JB
208/* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
209 Note that it's okay to redeem a scroll bar that is not condemned. */
dfcf069d 210void (*redeem_scroll_bar_hook) P_ ((struct window *window));
20a558dc 211
a3c87d4e
JB
212/* Remove all scroll bars on FRAME that haven't been saved since the
213 last call to `*condemn_scroll_bars_hook'.
20a558dc 214
371fbaeb 215 This should be applied to each frame after each time its window
a3c87d4e
JB
216 tree is redisplayed, even if it is not displaying scroll bars at the
217 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
218 calling this and condemn_scroll_bars_hook will get rid of them.
371fbaeb
JB
219
220 If non-zero, this hook should be safe to apply to any frame,
a3c87d4e 221 whether or not it can support scroll bars, and whether or not it is
371fbaeb 222 currently displaying them. */
dfcf069d 223void (*judge_scroll_bars_hook) P_ ((FRAME_PTR FRAME));
20a558dc 224
a168702a
GM
225/* Hook to call in estimate_mode_line_height, if any. */
226
227int (* estimate_mode_line_height_hook) P_ ((struct frame *f, enum face_id));
228
20a558dc 229
08a24c47
JB
230/* Strings, numbers and flags taken from the termcap entry. */
231
a4decb7f 232char *TS_ins_line; /* "al" */
08a24c47
JB
233char *TS_ins_multi_lines; /* "AL" (one parameter, # lines to insert) */
234char *TS_bell; /* "bl" */
235char *TS_clr_to_bottom; /* "cd" */
236char *TS_clr_line; /* "ce", clear to end of line */
ff11dfa1 237char *TS_clr_frame; /* "cl" */
08a24c47
JB
238char *TS_set_scroll_region; /* "cs" (2 params, first line and last line) */
239char *TS_set_scroll_region_1; /* "cS" (4 params: total lines,
240 lines above scroll region, lines below it,
241 total lines again) */
242char *TS_del_char; /* "dc" */
243char *TS_del_multi_chars; /* "DC" (one parameter, # chars to delete) */
244char *TS_del_line; /* "dl" */
245char *TS_del_multi_lines; /* "DL" (one parameter, # lines to delete) */
246char *TS_delete_mode; /* "dm", enter character-delete mode */
247char *TS_end_delete_mode; /* "ed", leave character-delete mode */
248char *TS_end_insert_mode; /* "ei", leave character-insert mode */
249char *TS_ins_char; /* "ic" */
250char *TS_ins_multi_chars; /* "IC" (one parameter, # chars to insert) */
251char *TS_insert_mode; /* "im", enter character-insert mode */
252char *TS_pad_inserted_char; /* "ip". Just padding, no commands. */
253char *TS_end_keypad_mode; /* "ke" */
254char *TS_keypad_mode; /* "ks" */
255char *TS_pad_char; /* "pc", char to use as padding */
256char *TS_repeat; /* "rp" (2 params, # times to repeat
257 and character to be repeated) */
258char *TS_end_standout_mode; /* "se" */
259char *TS_fwd_scroll; /* "sf" */
260char *TS_standout_mode; /* "so" */
261char *TS_rev_scroll; /* "sr" */
262char *TS_end_termcap_modes; /* "te" */
263char *TS_termcap_modes; /* "ti" */
264char *TS_visible_bell; /* "vb" */
a168702a
GM
265char *TS_cursor_normal; /* "ve" */
266char *TS_cursor_visible; /* "vs" */
267char *TS_cursor_invisible; /* "vi" */
08a24c47
JB
268char *TS_set_window; /* "wi" (4 params, start and end of window,
269 each as vpos and hpos) */
270
a168702a
GM
271/* "md" -- turn on bold (extra bright mode). */
272
273char *TS_enter_bold_mode;
274
275/* "mh" -- turn on half-bright mode. */
276
277char *TS_enter_dim_mode;
278
279/* "mb" -- enter blinking mode. */
280
281char *TS_enter_blink_mode;
282
283/* "mr" -- enter reverse video mode. */
284
285char *TS_enter_reverse_mode;
286
287/* "us"/"ue" -- start/end underlining. */
288
289char *TS_exit_underline_mode, *TS_enter_underline_mode;
290
291/* "ug" -- number of blanks left by underline. */
292
293int TN_magic_cookie_glitch_ul;
294
295/* "as"/"ae" -- start/end alternate character set. Not really
296 supported, yet. */
297
298char *TS_enter_alt_charset_mode, *TS_exit_alt_charset_mode;
299
300/* "me" -- switch appearances off. */
301
302char *TS_exit_attribute_mode;
303
304/* "Co" -- number of colors. */
305
306int TN_max_colors;
307
308/* "pa" -- max. number of color pairs on screen. Not handled yet.
309 Could be a problem if not equal to TN_max_colors * TN_max_colors. */
310
311int TN_max_pairs;
312
313/* "op" -- SVr4 set default pair to its original value. */
314
315char *TS_orig_pair;
316
317/* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
318 1 param, the color index. */
319
320char *TS_set_foreground, *TS_set_background;
321
08a24c47
JB
322int TF_hazeltine; /* termcap hz flag. */
323int TF_insmode_motion; /* termcap mi flag: can move while in insert mode. */
324int TF_standout_motion; /* termcap mi flag: can move while in standout mode. */
a168702a
GM
325int TF_underscore; /* termcap ul flag: _ underlines if over-struck on
326 non-blank position. Must clear before writing _. */
08a24c47
JB
327int TF_teleray; /* termcap xt flag: many weird consequences.
328 For t1061. */
329
330int TF_xs; /* Nonzero for "xs". If set together with
331 TN_standout_width == 0, it means don't bother
332 to write any end-standout cookies. */
333
334int TN_standout_width; /* termcap sg number: width occupied by standout
335 markers */
336
337static int RPov; /* # chars to start a TS_repeat */
338
339static int delete_in_insert_mode; /* delete mode == insert mode */
340
341static int se_is_so; /* 1 if same string both enters and leaves
342 standout mode */
343
344/* internal state */
345
8dd0c7cb 346/* The largest frame width in any call to calculate_costs. */
a168702a 347
8dd0c7cb 348int max_frame_width;
a168702a 349
8dd0c7cb 350/* The largest frame height in any call to calculate_costs. */
a168702a 351
8dd0c7cb
RS
352int max_frame_height;
353
08a24c47
JB
354/* Number of chars of space used for standout marker at beginning of line,
355 or'd with 0100. Zero if no standout marker at all.
8dd0c7cb 356 The length of these vectors is max_frame_height.
08a24c47
JB
357
358 Used IFF TN_standout_width >= 0. */
359
360static char *chars_wasted;
361static char *copybuf;
362
363/* nonzero means supposed to write text in standout mode. */
a168702a 364
08a24c47
JB
365int standout_requested;
366
367int insert_mode; /* Nonzero when in insert mode. */
368int standout_mode; /* Nonzero when in standout mode. */
369
370/* Size of window specified by higher levels.
ff11dfa1 371 This is the number of lines, from the top of frame downwards,
08a24c47
JB
372 which can participate in insert-line/delete-line operations.
373
ff11dfa1 374 Effectively it excludes the bottom frame_height - specified_window_size
08a24c47
JB
375 lines from those operations. */
376
377int specified_window;
378
ff11dfa1 379/* Frame currently being redisplayed; 0 if not currently redisplaying.
08a24c47
JB
380 (Direct output does not count). */
381
ff11dfa1 382FRAME_PTR updating_frame;
08a24c47 383
07c57952 384/* Provided for lisp packages. */
a168702a 385
07c57952
KH
386static int system_uses_terminfo;
387
08a24c47 388char *tparam ();
e4bfb3b6
RS
389
390extern char *tgetstr ();
08a24c47 391\f
cb28b9c2
RS
392
393#ifdef WINDOWSNT
a168702a 394
cb28b9c2
RS
395/* We aren't X windows, but we aren't termcap either. This makes me
396 uncertain as to what value to use for frame.output_method. For
397 this file, we'll define FRAME_TERMCAP_P to be zero so that our
398 output hooks get called instead of the termcap functions. Probably
399 the best long-term solution is to define an output_windows_nt... */
400
401#undef FRAME_TERMCAP_P
402#define FRAME_TERMCAP_P(_f_) 0
403#endif /* WINDOWSNT */
404
dfcf069d 405void
08a24c47
JB
406ring_bell ()
407{
c291d9ef
RS
408 if (! NILP (Vring_bell_function))
409 {
410 Lisp_Object function;
411
412 /* Temporarily set the global variable to nil
413 so that if we get an error, it stays nil
414 and we don't call it over and over.
415
416 We don't specbind it, because that would carefully
417 restore the bad value if there's an error
418 and make the loop of errors happen anyway. */
419 function = Vring_bell_function;
420 Vring_bell_function = Qnil;
421
422 call0 (function);
423
424 Vring_bell_function = function;
425 return;
426 }
427
e52f4e08 428 if (! FRAME_TERMCAP_P (XFRAME (selected_frame)))
08a24c47
JB
429 {
430 (*ring_bell_hook) ();
431 return;
432 }
433 OUTPUT (TS_visible_bell && visible_bell ? TS_visible_bell : TS_bell);
434}
435
dfcf069d 436void
08a24c47
JB
437set_terminal_modes ()
438{
e52f4e08 439 if (! FRAME_TERMCAP_P (XFRAME (selected_frame)))
08a24c47
JB
440 {
441 (*set_terminal_modes_hook) ();
442 return;
443 }
444 OUTPUT_IF (TS_termcap_modes);
a168702a 445 OUTPUT_IF (TS_cursor_visible);
08a24c47
JB
446 OUTPUT_IF (TS_keypad_mode);
447 losecursor ();
448}
449
dfcf069d 450void
08a24c47
JB
451reset_terminal_modes ()
452{
e52f4e08 453 if (! FRAME_TERMCAP_P (XFRAME (selected_frame)))
08a24c47 454 {
b3e1cb05
GV
455 if (reset_terminal_modes_hook)
456 (*reset_terminal_modes_hook) ();
08a24c47
JB
457 return;
458 }
459 if (TN_standout_width < 0)
460 turn_off_highlight ();
461 turn_off_insert ();
462 OUTPUT_IF (TS_end_keypad_mode);
a168702a 463 OUTPUT_IF (TS_cursor_normal);
08a24c47 464 OUTPUT_IF (TS_end_termcap_modes);
a168702a 465 OUTPUT_IF (TS_orig_pair);
08a24c47
JB
466 /* Output raw CR so kernel can track the cursor hpos. */
467 /* But on magic-cookie terminals this can erase an end-standout marker and
ff11dfa1 468 cause the rest of the frame to be in standout, so move down first. */
08a24c47
JB
469 if (TN_standout_width >= 0)
470 cmputc ('\n');
471 cmputc ('\r');
472}
473
dfcf069d 474void
ff11dfa1
JB
475update_begin (f)
476 FRAME_PTR f;
08a24c47 477{
ff11dfa1 478 updating_frame = f;
1820044b 479 if (! FRAME_TERMCAP_P (updating_frame))
ff11dfa1 480 (*update_begin_hook) (f);
a168702a
GM
481 else
482 tty_hide_cursor ();
08a24c47
JB
483}
484
dfcf069d 485void
ff11dfa1
JB
486update_end (f)
487 FRAME_PTR f;
08a24c47 488{
1820044b 489 if (! FRAME_TERMCAP_P (updating_frame))
08a24c47 490 {
7a8e3e30 491 (*update_end_hook) (f);
cc4ee3c7 492 updating_frame = 0;
08a24c47
JB
493 return;
494 }
a168702a
GM
495
496 if (!XWINDOW (selected_window)->cursor_off_p)
497 tty_show_cursor ();
498
08a24c47
JB
499 turn_off_insert ();
500 background_highlight ();
501 standout_requested = 0;
ff11dfa1 502 updating_frame = 0;
08a24c47
JB
503}
504
dfcf069d 505void
08a24c47
JB
506set_terminal_window (size)
507 int size;
508{
1820044b 509 if (! FRAME_TERMCAP_P (updating_frame))
08a24c47
JB
510 {
511 (*set_terminal_window_hook) (size);
512 return;
513 }
e52f4e08 514 specified_window = size ? size : FRAME_HEIGHT (XFRAME (selected_frame));
08a24c47
JB
515 if (!scroll_region_ok)
516 return;
517 set_scroll_region (0, specified_window);
518}
519
dfcf069d 520void
08a24c47
JB
521set_scroll_region (start, stop)
522 int start, stop;
523{
524 char *buf;
e52f4e08
GM
525 struct frame *sf = XFRAME (selected_frame);
526
08a24c47
JB
527 if (TS_set_scroll_region)
528 {
529 buf = tparam (TS_set_scroll_region, 0, 0, start, stop - 1);
530 }
531 else if (TS_set_scroll_region_1)
532 {
533 buf = tparam (TS_set_scroll_region_1, 0, 0,
e52f4e08
GM
534 FRAME_HEIGHT (sf), start,
535 FRAME_HEIGHT (sf) - stop,
536 FRAME_HEIGHT (sf));
08a24c47
JB
537 }
538 else
539 {
e52f4e08 540 buf = tparam (TS_set_window, 0, 0, start, 0, stop, FRAME_WIDTH (sf));
08a24c47
JB
541 }
542 OUTPUT (buf);
9ac0d9e0 543 xfree (buf);
08a24c47
JB
544 losecursor ();
545}
546\f
dfcf069d 547void
08a24c47
JB
548turn_on_insert ()
549{
550 if (!insert_mode)
551 OUTPUT (TS_insert_mode);
552 insert_mode = 1;
553}
554
dfcf069d 555void
08a24c47
JB
556turn_off_insert ()
557{
558 if (insert_mode)
559 OUTPUT (TS_end_insert_mode);
560 insert_mode = 0;
561}
562\f
563/* Handle highlighting when TN_standout_width (termcap sg) is not specified.
564 In these terminals, output is affected by the value of standout
565 mode when the output is written.
566
567 These functions are called on all terminals, but do nothing
568 on terminals whose standout mode does not work that way. */
569
dfcf069d 570void
08a24c47
JB
571turn_off_highlight ()
572{
573 if (TN_standout_width < 0)
574 {
575 if (standout_mode)
576 OUTPUT_IF (TS_end_standout_mode);
577 standout_mode = 0;
578 }
579}
580
dfcf069d 581void
08a24c47
JB
582turn_on_highlight ()
583{
584 if (TN_standout_width < 0)
585 {
586 if (!standout_mode)
587 OUTPUT_IF (TS_standout_mode);
588 standout_mode = 1;
589 }
590}
591
a168702a
GM
592
593/* Make cursor invisible. */
594
595static void
596tty_hide_cursor ()
597{
598 OUTPUT_IF (TS_cursor_invisible);
599}
600
601
602/* Ensure that cursor is visible. */
603
604static void
605tty_show_cursor ()
606{
607 OUTPUT_IF (TS_cursor_normal);
608 OUTPUT_IF (TS_cursor_visible);
609}
610
611
08a24c47
JB
612/* Set standout mode to the state it should be in for
613 empty space inside windows. What this is,
614 depends on the user option inverse-video. */
615
dfcf069d 616void
08a24c47
JB
617background_highlight ()
618{
619 if (TN_standout_width >= 0)
620 return;
621 if (inverse_video)
622 turn_on_highlight ();
623 else
624 turn_off_highlight ();
625}
626
627/* Set standout mode to the mode specified for the text to be output. */
628
dfcf069d 629static void
08a24c47
JB
630highlight_if_desired ()
631{
632 if (TN_standout_width >= 0)
633 return;
634 if (!inverse_video == !standout_requested)
635 turn_off_highlight ();
636 else
637 turn_on_highlight ();
638}
639\f
640/* Handle standout mode for terminals in which TN_standout_width >= 0.
641 On these terminals, standout is controlled by markers that
ff11dfa1 642 live inside the terminal's memory. TN_standout_width is the width
08a24c47
JB
643 that the marker occupies in memory. Standout runs from the marker
644 to the end of the line on some terminals, or to the next
645 turn-off-standout marker (TS_end_standout_mode) string
646 on other terminals. */
647
648/* Write a standout marker or end-standout marker at the front of the line
649 at vertical position vpos. */
650
dfcf069d 651void
08a24c47
JB
652write_standout_marker (flag, vpos)
653 int flag, vpos;
654{
655 if (flag || (TS_end_standout_mode && !TF_teleray && !se_is_so
656 && !(TF_xs && TN_standout_width == 0)))
657 {
658 cmgoto (vpos, 0);
659 cmplus (TN_standout_width);
660 OUTPUT (flag ? TS_standout_mode : TS_end_standout_mode);
661 chars_wasted[curY] = TN_standout_width | 0100;
662 }
663}
664\f
665/* External interface to control of standout mode.
666 Call this when about to modify line at position VPOS
667 and not change whether it is highlighted. */
668
dfcf069d 669void
08a24c47
JB
670reassert_line_highlight (highlight, vpos)
671 int highlight;
672 int vpos;
673{
e52f4e08
GM
674 struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame);
675 if (! FRAME_TERMCAP_P (f))
08a24c47
JB
676 {
677 (*reassert_line_highlight_hook) (highlight, vpos);
678 return;
679 }
680 if (TN_standout_width < 0)
681 /* Handle terminals where standout takes affect at output time */
682 standout_requested = highlight;
a168702a 683 else if (chars_wasted && chars_wasted[vpos] == 0)
08a24c47
JB
684 /* For terminals with standout markers, write one on this line
685 if there isn't one already. */
686 write_standout_marker (highlight, vpos);
687}
688
689/* Call this when about to modify line at position VPOS
690 and change whether it is highlighted. */
691
dfcf069d 692void
a168702a
GM
693change_line_highlight (new_highlight, vpos, y, first_unused_hpos)
694 int new_highlight, vpos, y, first_unused_hpos;
08a24c47
JB
695{
696 standout_requested = new_highlight;
1820044b 697 if (! FRAME_TERMCAP_P (updating_frame))
08a24c47 698 {
a168702a 699 (*change_line_highlight_hook) (new_highlight, vpos, y, first_unused_hpos);
08a24c47
JB
700 return;
701 }
702
703 cursor_to (vpos, 0);
704
705 if (TN_standout_width < 0)
706 background_highlight ();
707 /* If line starts with a marker, delete the marker */
708 else if (TS_clr_line && chars_wasted[curY])
709 {
710 turn_off_insert ();
711 /* On Teleray, make sure to erase the SO marker. */
712 if (TF_teleray)
713 {
e52f4e08 714 cmgoto (curY - 1, FRAME_WIDTH (XFRAME (selected_frame)) - 4);
08a24c47
JB
715 OUTPUT ("\033S");
716 curY++; /* ESC S moves to next line where the TS_standout_mode was */
717 curX = 0;
718 }
719 else
720 cmgoto (curY, 0); /* reposition to kill standout marker */
721 }
722 clear_end_of_line_raw (first_unused_hpos);
723 reassert_line_highlight (new_highlight, curY);
724}
725\f
726
a168702a
GM
727/* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
728 frame-relative coordinates. */
08a24c47 729
dfcf069d 730void
a168702a
GM
731cursor_to (vpos, hpos)
732 int vpos, hpos;
08a24c47 733{
e52f4e08
GM
734 struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame);
735
736 if (! FRAME_TERMCAP_P (f) && cursor_to_hook)
08a24c47 737 {
a168702a 738 (*cursor_to_hook) (vpos, hpos);
08a24c47
JB
739 return;
740 }
741
36cae867
KH
742 /* Detect the case where we are called from reset_sys_modes
743 and the costs have never been calculated. Do nothing. */
744 if (chars_wasted == 0)
745 return;
746
a168702a
GM
747 hpos += chars_wasted[vpos] & 077;
748 if (curY == vpos && curX == hpos)
08a24c47
JB
749 return;
750 if (!TF_standout_motion)
751 background_highlight ();
752 if (!TF_insmode_motion)
753 turn_off_insert ();
a168702a 754 cmgoto (vpos, hpos);
08a24c47
JB
755}
756
757/* Similar but don't take any account of the wasted characters. */
758
dfcf069d 759void
08a24c47 760raw_cursor_to (row, col)
4746118a 761 int row, col;
08a24c47 762{
e52f4e08
GM
763 struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame);
764 if (! FRAME_TERMCAP_P (f))
08a24c47
JB
765 {
766 (*raw_cursor_to_hook) (row, col);
767 return;
768 }
769 if (curY == row && curX == col)
770 return;
771 if (!TF_standout_motion)
772 background_highlight ();
773 if (!TF_insmode_motion)
774 turn_off_insert ();
775 cmgoto (row, col);
776}
777\f
778/* Erase operations */
779
ff11dfa1 780/* clear from cursor to end of frame */
dfcf069d 781void
08a24c47
JB
782clear_to_end ()
783{
784 register int i;
785
759d9005 786 if (clear_to_end_hook && ! FRAME_TERMCAP_P (updating_frame))
08a24c47
JB
787 {
788 (*clear_to_end_hook) ();
789 return;
790 }
791 if (TS_clr_to_bottom)
792 {
793 background_highlight ();
794 OUTPUT (TS_clr_to_bottom);
e52f4e08
GM
795 bzero (chars_wasted + curY,
796 FRAME_HEIGHT (XFRAME (selected_frame)) - curY);
08a24c47
JB
797 }
798 else
799 {
e52f4e08 800 for (i = curY; i < FRAME_HEIGHT (XFRAME (selected_frame)); i++)
08a24c47
JB
801 {
802 cursor_to (i, 0);
e52f4e08 803 clear_end_of_line_raw (FRAME_WIDTH (XFRAME (selected_frame)));
08a24c47
JB
804 }
805 }
806}
807
ff11dfa1 808/* Clear entire frame */
08a24c47 809
dfcf069d 810void
ff11dfa1 811clear_frame ()
08a24c47 812{
e52f4e08
GM
813 struct frame *sf = XFRAME (selected_frame);
814
ff11dfa1 815 if (clear_frame_hook
e52f4e08 816 && ! FRAME_TERMCAP_P ((updating_frame ? updating_frame : sf)))
08a24c47 817 {
ff11dfa1 818 (*clear_frame_hook) ();
08a24c47
JB
819 return;
820 }
ff11dfa1 821 if (TS_clr_frame)
08a24c47
JB
822 {
823 background_highlight ();
ff11dfa1 824 OUTPUT (TS_clr_frame);
e52f4e08 825 bzero (chars_wasted, FRAME_HEIGHT (sf));
08a24c47
JB
826 cmat (0, 0);
827 }
828 else
829 {
830 cursor_to (0, 0);
831 clear_to_end ();
832 }
833}
834
835/* Clear to end of line, but do not clear any standout marker.
836 Assumes that the cursor is positioned at a character of real text,
837 which implies it cannot be before a standout marker
838 unless the marker has zero width.
839
840 Note that the cursor may be moved. */
841
dfcf069d 842void
08a24c47
JB
843clear_end_of_line (first_unused_hpos)
844 int first_unused_hpos;
845{
e52f4e08 846 if (FRAME_TERMCAP_P (XFRAME (selected_frame))
36cae867 847 && chars_wasted != 0
08a24c47 848 && TN_standout_width == 0 && curX == 0 && chars_wasted[curY] != 0)
a168702a 849 write_glyphs (&space_glyph, 1);
08a24c47
JB
850 clear_end_of_line_raw (first_unused_hpos);
851}
852
853/* Clear from cursor to end of line.
854 Assume that the line is already clear starting at column first_unused_hpos.
855 If the cursor is at a standout marker, erase the marker.
856
857 Note that the cursor may be moved, on terminals lacking a `ce' string. */
858
dfcf069d 859void
08a24c47
JB
860clear_end_of_line_raw (first_unused_hpos)
861 int first_unused_hpos;
862{
863 register int i;
864
865 if (clear_end_of_line_hook
1820044b 866 && ! FRAME_TERMCAP_P ((updating_frame
ff11dfa1 867 ? updating_frame
e52f4e08 868 : XFRAME (selected_frame))))
08a24c47
JB
869 {
870 (*clear_end_of_line_hook) (first_unused_hpos);
871 return;
872 }
873
36cae867
KH
874 /* Detect the case where we are called from reset_sys_modes
875 and the costs have never been calculated. Do nothing. */
876 if (chars_wasted == 0)
877 return;
878
08a24c47
JB
879 first_unused_hpos += chars_wasted[curY] & 077;
880 if (curX >= first_unused_hpos)
881 return;
882 /* Notice if we are erasing a magic cookie */
883 if (curX == 0)
884 chars_wasted[curY] = 0;
885 background_highlight ();
886 if (TS_clr_line)
887 {
888 OUTPUT1 (TS_clr_line);
889 }
890 else
891 { /* have to do it the hard way */
e52f4e08 892 struct frame *sf = XFRAME (selected_frame);
08a24c47
JB
893 turn_off_insert ();
894
a168702a 895 /* Do not write in last row last col with Auto-wrap on. */
e52f4e08
GM
896 if (AutoWrap && curY == FRAME_HEIGHT (sf) - 1
897 && first_unused_hpos == FRAME_WIDTH (sf))
08a24c47
JB
898 first_unused_hpos--;
899
900 for (i = curX; i < first_unused_hpos; i++)
901 {
902 if (termscript)
903 fputc (' ', termscript);
904 putchar (' ');
905 }
906 cmplus (first_unused_hpos - curX);
907 }
908}
909\f
a4decb7f
KH
910/* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
911 store them at DST. Do not write more than DST_LEN bytes. That may
912 require stopping before all SRC_LEN input glyphs have been
913 converted.
914
915 We store the number of glyphs actually converted in *CONSUMED. The
916 return value is the number of bytes store in DST. */
917
918int
919encode_terminal_code (src, dst, src_len, dst_len, consumed)
a168702a 920 struct glyph *src;
a4decb7f
KH
921 int src_len;
922 unsigned char *dst;
923 int dst_len, *consumed;
924{
a168702a 925 struct glyph *src_start = src, *src_end = src + src_len;
a4decb7f 926 unsigned char *dst_start = dst, *dst_end = dst + dst_len;
085d5908
KH
927 register GLYPH g;
928 unsigned int c;
c7cba11d 929 unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *buf;
6589fd67 930 int len;
a4decb7f
KH
931 register int tlen = GLYPH_TABLE_LENGTH;
932 register Lisp_Object *tbase = GLYPH_TABLE_BASE;
f3ac545f 933 int result;
6589fd67
KH
934 struct coding_system *coding;
935
936 coding = (CODING_REQUIRE_ENCODING (&terminal_coding)
937 ? &terminal_coding
938 : &safe_terminal_coding);
a4decb7f
KH
939
940 while (src < src_end)
941 {
a4decb7f 942 /* We must skip glyphs to be padded for a wide character. */
a168702a 943 if (! CHAR_GLYPH_PADDING_P (*src))
a4decb7f 944 {
32de38e4
KH
945 g = GLYPH_FROM_CHAR_GLYPH (src[0]);
946
947 if (g < 0 || g >= tlen)
085d5908 948 {
32de38e4
KH
949 /* This glyph doesn't has an entry in Vglyph_table. */
950 if (! CHAR_VALID_P (src->u.ch, 0))
951 {
952 len = 1;
953 buf = " ";
954 }
955 else
956 {
957 len = CHAR_STRING (src->u.ch, workbuf);
958 buf = workbuf;
959 }
085d5908 960 }
32de38e4 961 else
a4decb7f 962 {
32de38e4 963 /* This glyph has an entry in Vglyph_table,
a4decb7f
KH
964 so process any alias before testing for simpleness. */
965 GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
32de38e4
KH
966
967 if (GLYPH_SIMPLE_P (tbase, tlen, g))
968 {
969 /* We set the multi-byte form of C at WORKBUF. */
970 len = CHAR_STRING (src->u.ch, workbuf);
971 buf = workbuf;
972 }
973 else
974 {
975 /* We have a string in Vglyph_table. */
976 len = GLYPH_LENGTH (tbase, g);
977 buf = GLYPH_STRING (tbase, g);
978 }
171d7f24 979 }
a4decb7f 980
f3ac545f 981 result = encode_coding (coding, buf, dst, len, dst_end - dst);
c42869c4 982 len -= coding->consumed;
6589fd67 983 dst += coding->produced;
f3ac545f
KH
984 if (result == CODING_FINISH_INSUFFICIENT_DST
985 || (result == CODING_FINISH_INSUFFICIENT_SRC
986 && len > dst_end - dst))
987 /* The remaining output buffer is too short. We must
988 break the loop here without increasing SRC so that the
989 next call of this function starts from the same glyph. */
990 break;
991
c42869c4
KH
992 if (len > 0)
993 {
f3ac545f
KH
994 /* This is the case that a code of the range 0200..0237
995 exists in buf. We must just write out such a code. */
996 buf += coding->consumed;
997 while (len--)
998 *dst++ = *buf++;
c42869c4 999 }
a4decb7f
KH
1000 }
1001 src++;
1002 }
a168702a 1003
a4decb7f
KH
1004 *consumed = src - src_start;
1005 return (dst - dst_start);
1006}
1007
08a24c47 1008
dfcf069d 1009void
08a24c47 1010write_glyphs (string, len)
a168702a 1011 register struct glyph *string;
08a24c47
JB
1012 register int len;
1013{
a4decb7f 1014 int produced, consumed;
e52f4e08
GM
1015 struct frame *sf = XFRAME (selected_frame);
1016 struct frame *f = updating_frame ? updating_frame : sf;
08a24c47
JB
1017
1018 if (write_glyphs_hook
a168702a 1019 && ! FRAME_TERMCAP_P (f))
08a24c47
JB
1020 {
1021 (*write_glyphs_hook) (string, len);
1022 return;
1023 }
1024
1025 highlight_if_desired ();
1026 turn_off_insert ();
1027
a168702a 1028 /* Don't dare write in last column of bottom line, if Auto-Wrap,
ff11dfa1 1029 since that would scroll the whole frame on some terminals. */
08a24c47
JB
1030
1031 if (AutoWrap
e52f4e08
GM
1032 && curY + 1 == FRAME_HEIGHT (sf)
1033 && (curX + len - (chars_wasted[curY] & 077) == FRAME_WIDTH (sf)))
08a24c47 1034 len --;
a4decb7f
KH
1035 if (len <= 0)
1036 return;
08a24c47
JB
1037
1038 cmplus (len);
a168702a 1039
6589fd67
KH
1040 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1041 the tail. */
1042 terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
a168702a 1043
a4decb7f 1044 while (len > 0)
08a24c47 1045 {
a168702a 1046 /* Identify a run of glyphs with the same face. */
32de38e4 1047 int face_id = string->face_id;
a168702a
GM
1048 int n;
1049
1050 for (n = 1; n < len; ++n)
32de38e4 1051 if (string[n].face_id != face_id)
a168702a
GM
1052 break;
1053
1054 /* Turn appearance modes of the face of the run on. */
1055 turn_on_face (f, face_id);
1056
1057 while (n > 0)
08a24c47 1058 {
a168702a
GM
1059 /* We use a shared conversion buffer of the current size
1060 (1024 bytes at least). Usually it is sufficient, but if
1061 not, we just repeat the loop. */
1062 produced = encode_terminal_code (string, conversion_buffer,
1063 n, conversion_buffer_size,
1064 &consumed);
1065 if (produced > 0)
1066 {
1067 fwrite (conversion_buffer, 1, produced, stdout);
1068 if (ferror (stdout))
1069 clearerr (stdout);
1070 if (termscript)
1071 fwrite (conversion_buffer, 1, produced, termscript);
1072 }
1073 len -= consumed;
1074 n -= consumed;
1075 string += consumed;
08a24c47 1076 }
a168702a
GM
1077
1078 /* Turn appearance modes off. */
1079 turn_off_face (f, face_id);
a4decb7f 1080 }
a168702a 1081
a4decb7f 1082 /* We may have to output some codes to terminate the writing. */
ca1e6a13 1083 if (CODING_REQUIRE_FLUSHING (&terminal_coding))
a4decb7f 1084 {
6589fd67 1085 terminal_coding.mode |= CODING_MODE_LAST_BLOCK;
1814bd62 1086 encode_coding (&terminal_coding, "", conversion_buffer,
6589fd67
KH
1087 0, conversion_buffer_size);
1088 if (terminal_coding.produced > 0)
df8bf431 1089 {
6589fd67 1090 fwrite (conversion_buffer, 1, terminal_coding.produced, stdout);
df8bf431
KH
1091 if (ferror (stdout))
1092 clearerr (stdout);
1093 if (termscript)
6589fd67
KH
1094 fwrite (conversion_buffer, 1, terminal_coding.produced,
1095 termscript);
df8bf431 1096 }
08a24c47 1097 }
a168702a 1098
9a6b6f92 1099 cmcheckmagic ();
08a24c47
JB
1100}
1101
1102/* If start is zero, insert blanks instead of a string at start */
1103
dfcf069d 1104void
08a24c47 1105insert_glyphs (start, len)
a168702a 1106 register struct glyph *start;
08a24c47
JB
1107 register int len;
1108{
1109 char *buf;
32de38e4 1110 struct glyph *glyph;
e52f4e08 1111 struct frame *f, *sf;
08a24c47 1112
a4decb7f
KH
1113 if (len <= 0)
1114 return;
1115
a168702a 1116 if (insert_glyphs_hook)
08a24c47
JB
1117 {
1118 (*insert_glyphs_hook) (start, len);
1119 return;
1120 }
a168702a 1121
e52f4e08
GM
1122 sf = XFRAME (selected_frame);
1123 f = updating_frame ? updating_frame : sf;
08a24c47
JB
1124 highlight_if_desired ();
1125
1126 if (TS_ins_multi_chars)
1127 {
1128 buf = tparam (TS_ins_multi_chars, 0, 0, len);
1129 OUTPUT1 (buf);
9ac0d9e0 1130 xfree (buf);
08a24c47
JB
1131 if (start)
1132 write_glyphs (start, len);
1133 return;
1134 }
1135
1136 turn_on_insert ();
1137 cmplus (len);
6589fd67
KH
1138 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
1139 terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
07109bf9 1140 while (len-- > 0)
08a24c47 1141 {
a4decb7f
KH
1142 int produced, consumed;
1143
08a24c47
JB
1144 OUTPUT1_IF (TS_ins_char);
1145 if (!start)
32de38e4
KH
1146 {
1147 conversion_buffer[0] = SPACEGLYPH;
1148 produced = 1;
1149 }
08a24c47 1150 else
08a24c47 1151 {
32de38e4 1152 turn_on_face (f, start->face_id);
816be8b8 1153 glyph = start;
a168702a 1154 ++start;
a4decb7f
KH
1155 /* We must open sufficient space for a character which
1156 occupies more than one column. */
a168702a 1157 while (len && CHAR_GLYPH_PADDING_P (*start))
a4decb7f
KH
1158 {
1159 OUTPUT1_IF (TS_ins_char);
1160 start++, len--;
1161 }
a4decb7f 1162
32de38e4
KH
1163 if (len <= 0)
1164 /* This is the last glyph. */
1165 terminal_coding.mode |= CODING_MODE_LAST_BLOCK;
1166
1167 /* We use shared conversion buffer of the current size (1024
1168 bytes at least). It is surely sufficient for just one glyph. */
816be8b8 1169 produced = encode_terminal_code (glyph, conversion_buffer, 1,
32de38e4
KH
1170 conversion_buffer_size, &consumed);
1171 }
a4decb7f 1172
a4decb7f 1173 if (produced > 0)
08a24c47 1174 {
a4decb7f 1175 fwrite (conversion_buffer, 1, produced, stdout);
08a24c47
JB
1176 if (ferror (stdout))
1177 clearerr (stdout);
1178 if (termscript)
a4decb7f 1179 fwrite (conversion_buffer, 1, produced, termscript);
08a24c47
JB
1180 }
1181
9a6b6f92 1182 OUTPUT1_IF (TS_pad_inserted_char);
32de38e4
KH
1183 if (start)
1184 turn_off_face (f, glyph->face_id);
9a6b6f92 1185 }
a168702a 1186
9a6b6f92 1187 cmcheckmagic ();
08a24c47
JB
1188}
1189
dfcf069d 1190void
08a24c47
JB
1191delete_glyphs (n)
1192 register int n;
1193{
1194 char *buf;
1195 register int i;
1196
1820044b 1197 if (delete_glyphs_hook && ! FRAME_TERMCAP_P (updating_frame))
08a24c47
JB
1198 {
1199 (*delete_glyphs_hook) (n);
1200 return;
1201 }
1202
1203 if (delete_in_insert_mode)
1204 {
1205 turn_on_insert ();
1206 }
1207 else
1208 {
1209 turn_off_insert ();
1210 OUTPUT_IF (TS_delete_mode);
1211 }
1212
1213 if (TS_del_multi_chars)
1214 {
1215 buf = tparam (TS_del_multi_chars, 0, 0, n);
1216 OUTPUT1 (buf);
9ac0d9e0 1217 xfree (buf);
08a24c47
JB
1218 }
1219 else
1220 for (i = 0; i < n; i++)
1221 OUTPUT1 (TS_del_char);
1222 if (!delete_in_insert_mode)
1223 OUTPUT_IF (TS_end_delete_mode);
1224}
1225\f
1226/* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1227
dfcf069d 1228void
08a24c47
JB
1229ins_del_lines (vpos, n)
1230 int vpos, n;
1231{
1232 char *multi = n > 0 ? TS_ins_multi_lines : TS_del_multi_lines;
1233 char *single = n > 0 ? TS_ins_line : TS_del_line;
1234 char *scroll = n > 0 ? TS_rev_scroll : TS_fwd_scroll;
e52f4e08 1235 struct frame *sf;
08a24c47
JB
1236
1237 register int i = n > 0 ? n : -n;
1238 register char *buf;
1239
1820044b 1240 if (ins_del_lines_hook && ! FRAME_TERMCAP_P (updating_frame))
08a24c47
JB
1241 {
1242 (*ins_del_lines_hook) (vpos, n);
1243 return;
1244 }
1245
e52f4e08
GM
1246 sf = XFRAME (selected_frame);
1247
08a24c47
JB
1248 /* If the lines below the insertion are being pushed
1249 into the end of the window, this is the same as clearing;
1250 and we know the lines are already clear, since the matching
1251 deletion has already been done. So can ignore this. */
1252 /* If the lines below the deletion are blank lines coming
1253 out of the end of the window, don't bother,
1254 as there will be a matching inslines later that will flush them. */
1255 if (scroll_region_ok && vpos + i >= specified_window)
1256 return;
e52f4e08 1257 if (!memory_below_frame && vpos + i >= FRAME_HEIGHT (sf))
08a24c47
JB
1258 return;
1259
1260 if (multi)
1261 {
1262 raw_cursor_to (vpos, 0);
1263 background_highlight ();
1264 buf = tparam (multi, 0, 0, i);
1265 OUTPUT (buf);
9ac0d9e0 1266 xfree (buf);
08a24c47
JB
1267 }
1268 else if (single)
1269 {
1270 raw_cursor_to (vpos, 0);
1271 background_highlight ();
1272 while (--i >= 0)
1273 OUTPUT (single);
1274 if (TF_teleray)
1275 curX = 0;
1276 }
1277 else
1278 {
1279 set_scroll_region (vpos, specified_window);
1280 if (n < 0)
1281 raw_cursor_to (specified_window - 1, 0);
1282 else
1283 raw_cursor_to (vpos, 0);
1284 background_highlight ();
1285 while (--i >= 0)
1286 OUTPUTL (scroll, specified_window - vpos);
1287 set_scroll_region (0, specified_window);
1288 }
1289
1290 if (TN_standout_width >= 0)
1291 {
dfcf069d 1292 register int lower_limit
08a24c47
JB
1293 = (scroll_region_ok
1294 ? specified_window
e52f4e08 1295 : FRAME_HEIGHT (sf));
08a24c47
JB
1296
1297 if (n < 0)
1298 {
1299 bcopy (&chars_wasted[vpos - n], &chars_wasted[vpos],
1300 lower_limit - vpos + n);
1301 bzero (&chars_wasted[lower_limit + n], - n);
1302 }
1303 else
1304 {
1305 bcopy (&chars_wasted[vpos], &copybuf[vpos], lower_limit - vpos - n);
1306 bcopy (&copybuf[vpos], &chars_wasted[vpos + n],
1307 lower_limit - vpos - n);
1308 bzero (&chars_wasted[vpos], n);
1309 }
1310 }
ff11dfa1 1311 if (!scroll_region_ok && memory_below_frame && n < 0)
08a24c47 1312 {
e52f4e08 1313 cursor_to (FRAME_HEIGHT (sf) + n, 0);
08a24c47
JB
1314 clear_to_end ();
1315 }
1316}
1317\f
1318/* Compute cost of sending "str", in characters,
1319 not counting any line-dependent padding. */
1320
1321int
1322string_cost (str)
1323 char *str;
1324{
1325 cost = 0;
1326 if (str)
1327 tputs (str, 0, evalcost);
1328 return cost;
1329}
1330
1331/* Compute cost of sending "str", in characters,
1332 counting any line-dependent padding at one line. */
1333
1334static int
1335string_cost_one_line (str)
1336 char *str;
1337{
1338 cost = 0;
1339 if (str)
1340 tputs (str, 1, evalcost);
1341 return cost;
1342}
1343
1344/* Compute per line amount of line-dependent padding,
1345 in tenths of characters. */
1346
1347int
1348per_line_cost (str)
1349 register char *str;
1350{
1351 cost = 0;
1352 if (str)
1353 tputs (str, 0, evalcost);
1354 cost = - cost;
1355 if (str)
1356 tputs (str, 10, evalcost);
1357 return cost;
1358}
1359
1360#ifndef old
1361/* char_ins_del_cost[n] is cost of inserting N characters.
8dd0c7cb
RS
1362 char_ins_del_cost[-n] is cost of deleting N characters.
1363 The length of this vector is based on max_frame_width. */
08a24c47
JB
1364
1365int *char_ins_del_vector;
1366
ff11dfa1 1367#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH ((f))])
08a24c47
JB
1368#endif
1369
1370/* ARGSUSED */
1371static void
ff11dfa1
JB
1372calculate_ins_del_char_costs (frame)
1373 FRAME_PTR frame;
08a24c47
JB
1374{
1375 int ins_startup_cost, del_startup_cost;
1376 int ins_cost_per_char, del_cost_per_char;
1377 register int i;
1378 register int *p;
1379
1380 if (TS_ins_multi_chars)
1381 {
1382 ins_cost_per_char = 0;
1383 ins_startup_cost = string_cost_one_line (TS_ins_multi_chars);
1384 }
1385 else if (TS_ins_char || TS_pad_inserted_char
1386 || (TS_insert_mode && TS_end_insert_mode))
1387 {
1388 ins_startup_cost = (30 * (string_cost (TS_insert_mode)
1389 + string_cost (TS_end_insert_mode))) / 100;
1390 ins_cost_per_char = (string_cost_one_line (TS_ins_char)
1391 + string_cost_one_line (TS_pad_inserted_char));
1392 }
1393 else
1394 {
1395 ins_startup_cost = 9999;
1396 ins_cost_per_char = 0;
1397 }
1398
1399 if (TS_del_multi_chars)
1400 {
1401 del_cost_per_char = 0;
1402 del_startup_cost = string_cost_one_line (TS_del_multi_chars);
1403 }
1404 else if (TS_del_char)
1405 {
1406 del_startup_cost = (string_cost (TS_delete_mode)
1407 + string_cost (TS_end_delete_mode));
1408 if (delete_in_insert_mode)
1409 del_startup_cost /= 2;
1410 del_cost_per_char = string_cost_one_line (TS_del_char);
1411 }
1412 else
1413 {
1414 del_startup_cost = 9999;
1415 del_cost_per_char = 0;
1416 }
1417
1418 /* Delete costs are at negative offsets */
ff11dfa1 1419 p = &char_ins_del_cost (frame)[0];
db71d414 1420 for (i = FRAME_WIDTH (frame); --i >= 0;)
08a24c47
JB
1421 *--p = (del_startup_cost += del_cost_per_char);
1422
1423 /* Doing nothing is free */
ff11dfa1 1424 p = &char_ins_del_cost (frame)[0];
08a24c47
JB
1425 *p++ = 0;
1426
1427 /* Insert costs are at positive offsets */
ff11dfa1 1428 for (i = FRAME_WIDTH (frame); --i >= 0;)
08a24c47
JB
1429 *p++ = (ins_startup_cost += ins_cost_per_char);
1430}
1431
dfcf069d 1432void
ff11dfa1
JB
1433calculate_costs (frame)
1434 FRAME_PTR frame;
08a24c47 1435{
9f732a77
RS
1436 register char *f = (TS_set_scroll_region
1437 ? TS_set_scroll_region
1438 : TS_set_scroll_region_1);
08a24c47 1439
9f732a77 1440 FRAME_COST_BAUD_RATE (frame) = baud_rate;
08a24c47 1441
be7cd44f 1442 scroll_region_cost = string_cost (f);
08a24c47 1443#ifdef HAVE_X_WINDOWS
1820044b 1444 if (FRAME_X_P (frame))
08a24c47 1445 {
ff11dfa1 1446 do_line_insertion_deletion_costs (frame, 0, ".5*", 0, ".5*",
7dac35c8
RS
1447 0, 0,
1448 x_screen_planes (frame));
be7cd44f 1449 scroll_region_cost = 0;
08a24c47
JB
1450 return;
1451 }
1452#endif
1453
1454 /* These variables are only used for terminal stuff. They are allocated
ff11dfa1 1455 once for the terminal frame of X-windows emacs, but not used afterwards.
08a24c47
JB
1456
1457 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1458 X turns off char_ins_del_ok.
1459
1460 chars_wasted and copybuf are only used here in term.c in cases where
1461 the term hook isn't called. */
1462
8dd0c7cb
RS
1463 max_frame_height = max (max_frame_height, FRAME_HEIGHT (frame));
1464 max_frame_width = max (max_frame_width, FRAME_WIDTH (frame));
1465
08a24c47 1466 if (chars_wasted != 0)
8dd0c7cb 1467 chars_wasted = (char *) xrealloc (chars_wasted, max_frame_height);
08a24c47 1468 else
8dd0c7cb 1469 chars_wasted = (char *) xmalloc (max_frame_height);
08a24c47
JB
1470
1471 if (copybuf != 0)
8dd0c7cb 1472 copybuf = (char *) xrealloc (copybuf, max_frame_height);
08a24c47 1473 else
8dd0c7cb 1474 copybuf = (char *) xmalloc (max_frame_height);
08a24c47
JB
1475
1476 if (char_ins_del_vector != 0)
1477 char_ins_del_vector
1478 = (int *) xrealloc (char_ins_del_vector,
1479 (sizeof (int)
8dd0c7cb 1480 + 2 * max_frame_width * sizeof (int)));
08a24c47
JB
1481 else
1482 char_ins_del_vector
1483 = (int *) xmalloc (sizeof (int)
8dd0c7cb 1484 + 2 * max_frame_width * sizeof (int));
08a24c47 1485
8dd0c7cb
RS
1486 bzero (chars_wasted, max_frame_height);
1487 bzero (copybuf, max_frame_height);
08a24c47 1488 bzero (char_ins_del_vector, (sizeof (int)
8dd0c7cb 1489 + 2 * max_frame_width * sizeof (int)));
08a24c47 1490
ff11dfa1
JB
1491 if (f && (!TS_ins_line && !TS_del_line))
1492 do_line_insertion_deletion_costs (frame,
08a24c47
JB
1493 TS_rev_scroll, TS_ins_multi_lines,
1494 TS_fwd_scroll, TS_del_multi_lines,
ff11dfa1 1495 f, f, 1);
08a24c47 1496 else
ff11dfa1 1497 do_line_insertion_deletion_costs (frame,
08a24c47
JB
1498 TS_ins_line, TS_ins_multi_lines,
1499 TS_del_line, TS_del_multi_lines,
1500 0, 0, 1);
1501
ff11dfa1 1502 calculate_ins_del_char_costs (frame);
08a24c47
JB
1503
1504 /* Don't use TS_repeat if its padding is worse than sending the chars */
1505 if (TS_repeat && per_line_cost (TS_repeat) * baud_rate < 9000)
1506 RPov = string_cost (TS_repeat);
1507 else
ff11dfa1 1508 RPov = FRAME_WIDTH (frame) * 2;
08a24c47
JB
1509
1510 cmcostinit (); /* set up cursor motion costs */
1511}
1512\f
a796ac82
JB
1513struct fkey_table {
1514 char *cap, *name;
1515};
1516
01d8deb0
ER
1517 /* Termcap capability names that correspond directly to X keysyms.
1518 Some of these (marked "terminfo") aren't supplied by old-style
1519 (Berkeley) termcap entries. They're listed in X keysym order;
1520 except we put the keypad keys first, so that if they clash with
1521 other keys (as on the IBM PC keyboard) they get overridden.
1522 */
1523
a168702a
GM
1524static struct fkey_table keys[] =
1525{
01d8deb0
ER
1526 "kh", "home", /* termcap */
1527 "kl", "left", /* termcap */
1528 "ku", "up", /* termcap */
1529 "kr", "right", /* termcap */
1530 "kd", "down", /* termcap */
1531 "%8", "prior", /* terminfo */
1532 "%5", "next", /* terminfo */
1533 "@7", "end", /* terminfo */
1534 "@1", "begin", /* terminfo */
1535 "*6", "select", /* terminfo */
1536 "%9", "print", /* terminfo */
1537 "@4", "execute", /* terminfo --- actually the `command' key */
1538 /*
1539 * "insert" --- see below
1540 */
1541 "&8", "undo", /* terminfo */
1542 "%0", "redo", /* terminfo */
1543 "%7", "menu", /* terminfo --- actually the `options' key */
1544 "@0", "find", /* terminfo */
1545 "@2", "cancel", /* terminfo */
1546 "%1", "help", /* terminfo */
1547 /*
1548 * "break" goes here, but can't be reliably intercepted with termcap
1549 */
1550 "&4", "reset", /* terminfo --- actually `restart' */
1551 /*
1552 * "system" and "user" --- no termcaps
1553 */
1554 "kE", "clearline", /* terminfo */
1555 "kA", "insertline", /* terminfo */
1556 "kL", "deleteline", /* terminfo */
1557 "kI", "insertchar", /* terminfo */
1558 "kD", "deletechar", /* terminfo */
1559 "kB", "backtab", /* terminfo */
1560 /*
1561 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1562 */
1563 "@8", "kp-enter", /* terminfo */
1564 /*
1565 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1566 * "kp-multiply", "kp-add", "kp-separator",
1567 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1568 * --- no termcaps for any of these.
1569 */
1570 "K4", "kp-1", /* terminfo */
1571 /*
1572 * "kp-2" --- no termcap
1573 */
1574 "K5", "kp-3", /* terminfo */
1575 /*
1576 * "kp-4" --- no termcap
1577 */
1578 "K2", "kp-5", /* terminfo */
1579 /*
1580 * "kp-6" --- no termcap
1581 */
1582 "K1", "kp-7", /* terminfo */
1583 /*
1584 * "kp-8" --- no termcap
1585 */
1586 "K3", "kp-9", /* terminfo */
1587 /*
1588 * "kp-equal" --- no termcap
1589 */
1590 "k1", "f1",
1591 "k2", "f2",
1592 "k3", "f3",
1593 "k4", "f4",
1594 "k5", "f5",
1595 "k6", "f6",
1596 "k7", "f7",
1597 "k8", "f8",
1598 "k9", "f9",
a796ac82
JB
1599 };
1600
f2a00342
RM
1601static char **term_get_fkeys_arg;
1602static Lisp_Object term_get_fkeys_1 ();
465db27b 1603
01d8deb0
ER
1604/* Find the escape codes sent by the function keys for Vfunction_key_map.
1605 This function scans the termcap function key sequence entries, and
1606 adds entries to Vfunction_key_map for each function key it finds. */
1607
5c2c7893
JB
1608void
1609term_get_fkeys (address)
1610 char **address;
f2a00342
RM
1611{
1612 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1613 errors during the call. The only errors should be from Fdefine_key
1614 when given a key sequence containing an invalid prefix key. If the
1615 termcap defines function keys which use a prefix that is already bound
1616 to a command by the default bindings, we should silently ignore that
1617 function key specification, rather than giving the user an error and
1618 refusing to run at all on such a terminal. */
1619
1620 extern Lisp_Object Fidentity ();
f2a00342
RM
1621 term_get_fkeys_arg = address;
1622 internal_condition_case (term_get_fkeys_1, Qerror, Fidentity);
1623}
1624
1625static Lisp_Object
1626term_get_fkeys_1 ()
5c2c7893 1627{
5c2c7893
JB
1628 int i;
1629
37085233 1630 char **address = term_get_fkeys_arg;
f778aff2 1631
3e65092f
RS
1632 /* This can happen if CANNOT_DUMP or with strange options. */
1633 if (!initialized)
1634 Vfunction_key_map = Fmake_sparse_keymap (Qnil);
1635
5c2c7893
JB
1636 for (i = 0; i < (sizeof (keys)/sizeof (keys[0])); i++)
1637 {
1638 char *sequence = tgetstr (keys[i].cap, address);
1639 if (sequence)
f2a00342
RM
1640 Fdefine_key (Vfunction_key_map, build_string (sequence),
1641 Fmake_vector (make_number (1),
1642 intern (keys[i].name)));
5c2c7893 1643 }
a796ac82
JB
1644
1645 /* The uses of the "k0" capability are inconsistent; sometimes it
1646 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
eb8c3be9 1647 We will attempt to politely accommodate both systems by testing for
a796ac82
JB
1648 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1649 */
1650 {
1651 char *k_semi = tgetstr ("k;", address);
1652 char *k0 = tgetstr ("k0", address);
1653 char *k0_name = "f10";
1654
1655 if (k_semi)
1656 {
f2a00342
RM
1657 Fdefine_key (Vfunction_key_map, build_string (k_semi),
1658 Fmake_vector (make_number (1), intern ("f10")));
a796ac82
JB
1659 k0_name = "f0";
1660 }
1661
1662 if (k0)
f2a00342
RM
1663 Fdefine_key (Vfunction_key_map, build_string (k0),
1664 Fmake_vector (make_number (1), intern (k0_name)));
a796ac82 1665 }
01d8deb0
ER
1666
1667 /* Set up cookies for numbered function keys above f10. */
1668 {
1669 char fcap[3], fkey[4];
1670
fc4f24da 1671 fcap[0] = 'F'; fcap[2] = '\0';
01d8deb0
ER
1672 for (i = 11; i < 64; i++)
1673 {
1674 if (i <= 19)
1675 fcap[1] = '1' + i - 11;
1676 else if (i <= 45)
b59ab95c 1677 fcap[1] = 'A' + i - 20;
01d8deb0 1678 else
b59ab95c 1679 fcap[1] = 'a' + i - 46;
01d8deb0 1680
fc4f24da
RS
1681 {
1682 char *sequence = tgetstr (fcap, address);
1683 if (sequence)
1684 {
465db27b 1685 sprintf (fkey, "f%d", i);
f2a00342
RM
1686 Fdefine_key (Vfunction_key_map, build_string (sequence),
1687 Fmake_vector (make_number (1),
1688 intern (fkey)));
fc4f24da
RS
1689 }
1690 }
01d8deb0
ER
1691 }
1692 }
1693
1694 /*
1695 * Various mappings to try and get a better fit.
1696 */
1697 {
fc4f24da
RS
1698#define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1699 if (!tgetstr (cap1, address)) \
1700 { \
1701 char *sequence = tgetstr (cap2, address); \
1702 if (sequence) \
f2a00342
RM
1703 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1704 Fmake_vector (make_number (1), \
1705 intern (sym))); \
fc4f24da 1706 }
01d8deb0
ER
1707
1708 /* if there's no key_next keycap, map key_npage to `next' keysym */
27b61785 1709 CONDITIONAL_REASSIGN ("%5", "kN", "next");
01d8deb0 1710 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
381d11a1 1711 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
01d8deb0 1712 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
27b61785 1713 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
403c995b
RS
1714 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1715 CONDITIONAL_REASSIGN ("@7", "kH", "end");
0a7f697a
KH
1716
1717 /* IBM has their own non-standard dialect of terminfo.
1718 If the standard name isn't found, try the IBM name. */
1719 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1720 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1721 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1722 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1723 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1724 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1725 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1726 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1727 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1dd40212 1728#undef CONDITIONAL_REASSIGN
01d8deb0 1729 }
a168702a
GM
1730
1731 return Qnil;
5c2c7893
JB
1732}
1733
1734\f
a168702a
GM
1735/***********************************************************************
1736 Character Display Information
1737 ***********************************************************************/
1738
1739static void append_glyph P_ ((struct it *));
1740
1741
1742/* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1743 terminal frames if IT->glyph_row != NULL. IT->c is the character
1744 for which to produce glyphs; IT->face_id contains the character's
1745 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1746 1. */
1747
1748static void
1749append_glyph (it)
1750 struct it *it;
1751{
1752 struct glyph *glyph, *end;
1753 int i;
1754
1755 xassert (it->glyph_row);
1756 glyph = (it->glyph_row->glyphs[it->area]
1757 + it->glyph_row->used[it->area]);
1758 end = it->glyph_row->glyphs[1 + it->area];
1759
1760 for (i = 0;
1761 i < it->pixel_width && glyph < end;
1762 ++i)
1763 {
1764 glyph->type = CHAR_GLYPH;
1765 glyph->pixel_width = 1;
32de38e4
KH
1766 glyph->u.ch = it->c;
1767 glyph->face_id = it->face_id;
1768 glyph->padding_p = i > 0;
a168702a
GM
1769 glyph->charpos = CHARPOS (it->position);
1770 glyph->object = it->object;
1771
1772 ++it->glyph_row->used[it->area];
1773 ++glyph;
1774 }
1775}
1776
1777
1778/* Produce glyphs for the display element described by IT. The
1779 function fills output fields of IT with pixel information like the
1780 pixel width and height of a character, and maybe produces glyphs at
1781 the same time if IT->glyph_row is non-null. See the explanation of
1782 struct display_iterator in dispextern.h for an overview. */
1783
1784void
1785produce_glyphs (it)
1786 struct it *it;
1787{
1788 /* If a hook is installed, let it do the work. */
1789 xassert (it->what == IT_CHARACTER
c7cba11d 1790 || it->what == IT_COMPOSITION
a168702a
GM
1791 || it->what == IT_IMAGE
1792 || it->what == IT_STRETCH);
1793
c7cba11d
KH
1794 /* Nothing but characters are supported on terminal frames. For a
1795 composition sequence, it->c is the first character of the
1796 sequence. */
1797 xassert (it->what == IT_CHARACTER
1798 || it->what == IT_COMPOSITION);
a168702a
GM
1799
1800 if (it->c >= 040 && it->c < 0177)
1801 {
1802 it->pixel_width = it->nglyphs = 1;
1803 if (it->glyph_row)
1804 append_glyph (it);
1805 }
1806 else if (it->c == '\n')
1807 it->pixel_width = it->nglyphs = 0;
1808 else if (it->c == '\t')
1809 {
1810 int absolute_x = (it->current_x - it->prompt_width
1811 + it->continuation_lines_width);
1812 int next_tab_x
1813 = (((1 + absolute_x + it->tab_width - 1)
1814 / it->tab_width)
1815 * it->tab_width);
1816 int nspaces;
1817
1818 /* If part of the TAB has been displayed on the previous line
1819 which is continued now, continuation_lines_width will have
1820 been incremented already by the part that fitted on the
1821 continued line. So, we will get the right number of spaces
1822 here. */
1823 nspaces = next_tab_x - absolute_x;
1824
1825 if (it->glyph_row)
1826 {
1827 int n = nspaces;
1828
1829 it->c = ' ';
1830 it->pixel_width = it->len = 1;
1831
1832 while (n--)
1833 append_glyph (it);
1834
1835 it->c = '\t';
1836 }
1837
1838 it->pixel_width = nspaces;
1839 it->nglyphs = nspaces;
1840 }
1841 else
1842 {
c7cba11d
KH
1843 /* A multi-byte character. The display width is fixed for all
1844 characters of the set. Some of the glyphs may have to be
1845 ignored because they are already displayed in a continued
1846 line. */
a168702a
GM
1847 int charset = CHAR_CHARSET (it->c);
1848
c7cba11d 1849 it->pixel_width = CHARSET_WIDTH (charset);
a168702a
GM
1850 it->nglyphs = it->pixel_width;
1851
1852 if (it->glyph_row)
1853 append_glyph (it);
1854 }
1855
1856 /* Advance current_x by the pixel width as a convenience for
1857 the caller. */
1858 if (it->area == TEXT_AREA)
1859 it->current_x += it->pixel_width;
cfe8a05e
GM
1860 it->ascent = it->max_ascent = it->phys_ascent = it->max_phys_ascent = 0;
1861 it->descent = it->max_descent = it->phys_descent = it->max_phys_descent = 1;
a168702a
GM
1862}
1863
1864
1865/* Get information about special display element WHAT in an
1866 environment described by IT. WHAT is one of IT_TRUNCATION or
1867 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1868 non-null glyph_row member. This function ensures that fields like
1869 face_id, c, len of IT are left untouched. */
1870
1871void
1872produce_special_glyphs (it, what)
1873 struct it *it;
1874 enum display_element_type what;
1875{
1876 struct it temp_it;
1877
1878 temp_it = *it;
1879 temp_it.dp = NULL;
1880 temp_it.what = IT_CHARACTER;
1881 temp_it.len = 1;
1882 temp_it.object = 0;
1883 bzero (&temp_it.current, sizeof temp_it.current);
1884
1885 if (what == IT_CONTINUATION)
1886 {
1887 /* Continuation glyph. */
1888 if (it->dp
1889 && INTEGERP (DISP_CONTINUE_GLYPH (it->dp))
1890 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it->dp))))
1891 {
1892 temp_it.c = FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it->dp)));
1893 temp_it.len = CHAR_LEN (temp_it.c);
1894 }
1895 else
1896 temp_it.c = '\\';
1897
1898 produce_glyphs (&temp_it);
1899 it->pixel_width = temp_it.pixel_width;
1900 it->nglyphs = temp_it.pixel_width;
1901 }
1902 else if (what == IT_TRUNCATION)
1903 {
1904 /* Truncation glyph. */
1905 if (it->dp
1906 && INTEGERP (DISP_TRUNC_GLYPH (it->dp))
1907 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it->dp))))
1908 {
1909 temp_it.c = FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it->dp)));
1910 temp_it.len = CHAR_LEN (temp_it.c);
1911 }
1912 else
1913 temp_it.c = '$';
1914
1915 produce_glyphs (&temp_it);
1916 it->pixel_width = temp_it.pixel_width;
1917 it->nglyphs = temp_it.pixel_width;
1918 }
1919 else
1920 abort ();
1921}
1922
1923
1924/* Return an estimation of the pixel height of mode or top lines on
1925 frame F. FACE_ID specifies what line's height to estimate. */
1926
1927int
1928estimate_mode_line_height (f, face_id)
1929 struct frame *f;
1930 enum face_id face_id;
1931{
1932 if (estimate_mode_line_height_hook)
1933 return estimate_mode_line_height_hook (f, face_id);
1934 else
1935 return 1;
1936}
1937
1938
1939\f
1940/***********************************************************************
1941 Faces
1942 ***********************************************************************/
1943
1944
1945/* Turn appearances of face FACE_ID on tty frame F on. */
1946
1947static void
1948turn_on_face (f, face_id)
1949 struct frame *f;
1950 int face_id;
1951{
1952 struct face *face = FACE_FROM_ID (f, face_id);
1953
1954 xassert (face != NULL);
1955
1956 if (face->tty_bold_p)
1957 OUTPUT1_IF (TS_enter_bold_mode);
1958 else if (face->tty_dim_p)
1959 OUTPUT1_IF (TS_enter_dim_mode);
1960
1961 /* Alternate charset and blinking not yet used. */
1962 if (face->tty_alt_charset_p)
1963 OUTPUT1_IF (TS_enter_alt_charset_mode);
1964
1965 if (face->tty_blinking_p)
1966 OUTPUT1_IF (TS_enter_blink_mode);
1967
1968 if (face->tty_underline_p
1969 /* Don't underline if that's difficult. */
1970 && TN_magic_cookie_glitch_ul <= 0)
1971 OUTPUT1_IF (TS_enter_underline_mode);
1972
f9d2fdc4
EZ
1973 if (face->tty_reverse_p
1974 || face->foreground == FACE_TTY_DEFAULT_BG_COLOR
1975 || face->background == FACE_TTY_DEFAULT_FG_COLOR)
a168702a
GM
1976 OUTPUT1_IF (TS_enter_reverse_mode);
1977
1978 if (TN_max_colors > 0)
1979 {
1980 char *p;
1981
1982 if (face->foreground != FACE_TTY_DEFAULT_COLOR
f9d2fdc4
EZ
1983 && face->foreground != FACE_TTY_DEFAULT_FG_COLOR
1984 && face->foreground != FACE_TTY_DEFAULT_BG_COLOR
a168702a
GM
1985 && TS_set_foreground)
1986 {
1987 p = tparam (TS_set_foreground, NULL, 0, (int) face->foreground);
1988 OUTPUT (p);
1989 xfree (p);
1990 }
1991
1992 if (face->background != FACE_TTY_DEFAULT_COLOR
f9d2fdc4
EZ
1993 && face->background != FACE_TTY_DEFAULT_BG_COLOR
1994 && face->background != FACE_TTY_DEFAULT_FG_COLOR
a168702a
GM
1995 && TS_set_background)
1996 {
1997 p = tparam (TS_set_background, NULL, 0, (int) face->background);
1998 OUTPUT (p);
1999 xfree (p);
2000 }
2001 }
2002}
2003
2004
2005/* Turn off appearances of face FACE_ID on tty frame F. */
2006
2007static void
2008turn_off_face (f, face_id)
2009 struct frame *f;
2010 int face_id;
2011{
2012 struct face *face = FACE_FROM_ID (f, face_id);
a168702a
GM
2013
2014 xassert (face != NULL);
2015
2016 if (TS_exit_attribute_mode)
2017 {
2018 /* Capability "me" will turn off appearance modes double-bright,
2019 half-bright, reverse-video, standout, underline. It may or
2020 may not turn off alt-char-mode. */
2021 if (face->tty_bold_p
2022 || face->tty_dim_p
2023 || face->tty_reverse_p
2024 || face->tty_alt_charset_p
2025 || face->tty_blinking_p
2026 || face->tty_underline_p)
2027 OUTPUT1_IF (TS_exit_attribute_mode);
2028
2029 if (face->tty_alt_charset_p)
2030 OUTPUT_IF (TS_exit_alt_charset_mode);
2031 }
2032 else
2033 {
2034 /* If we don't have "me" we can only have those appearances
2035 that have exit sequences defined. */
2036 if (face->tty_alt_charset_p)
2037 OUTPUT_IF (TS_exit_alt_charset_mode);
2038
2039 if (face->tty_underline_p
2040 /* We don't underline if that's difficult. */
2041 && TN_magic_cookie_glitch_ul <= 0)
2042 OUTPUT_IF (TS_exit_underline_mode);
2043 }
2044
2045 /* Switch back to default colors. */
2046 if (TN_max_colors > 0
f9d2fdc4
EZ
2047 && ((face->foreground != FACE_TTY_DEFAULT_COLOR
2048 && face->foreground != FACE_TTY_DEFAULT_FG_COLOR)
2049 || (face->background != FACE_TTY_DEFAULT_COLOR
2050 && face->background != FACE_TTY_DEFAULT_BG_COLOR)))
a168702a
GM
2051 OUTPUT1_IF (TS_orig_pair);
2052}
2053
2054
2055/* Return non-zero if the terminal is capable to display colors. */
2056
2057DEFUN ("tty-display-color-p", Ftty_display_color_p, Stty_display_color_p,
2058 0, 0, 0,
2059 "Return non-nil if TTY can display colors.")
2060 ()
2061{
2062 return TN_max_colors > 0 ? Qt : Qnil;
2063}
2064
2065
2066
2067\f
2068/***********************************************************************
2069 Initialization
2070 ***********************************************************************/
2071
dfcf069d 2072void
08a24c47
JB
2073term_init (terminal_type)
2074 char *terminal_type;
2075{
2076 char *area;
2077 char **address = &area;
2078 char buffer[2044];
2079 register char *p;
2080 int status;
e52f4e08 2081 struct frame *sf = XFRAME (selected_frame);
08a24c47 2082
cb28b9c2 2083#ifdef WINDOWSNT
29f27c39 2084 initialize_w32_display ();
cb28b9c2
RS
2085
2086 Wcm_clear ();
cb28b9c2 2087
a678d9ff 2088 area = (char *) xmalloc (2044);
cb28b9c2
RS
2089
2090 if (area == 0)
2091 abort ();
2092
e52f4e08
GM
2093 FrameRows = FRAME_HEIGHT (sf);
2094 FrameCols = FRAME_WIDTH (sf);
2095 specified_window = FRAME_HEIGHT (sf);
cb28b9c2
RS
2096
2097 delete_in_insert_mode = 1;
2098
2099 UseTabs = 0;
2100 scroll_region_ok = 0;
2101
2102 /* Seems to insert lines when it's not supposed to, messing
2103 up the display. In doing a trace, it didn't seem to be
2104 called much, so I don't think we're losing anything by
2105 turning it off. */
2106
2107 line_ins_del_ok = 0;
2108 char_ins_del_ok = 1;
2109
2110 baud_rate = 19200;
2111
e52f4e08
GM
2112 FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
2113 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
cb28b9c2
RS
2114
2115 return;
eccec691 2116#else /* not WINDOWSNT */
cb28b9c2 2117
08a24c47 2118 Wcm_clear ();
08a24c47
JB
2119
2120 status = tgetent (buffer, terminal_type);
2121 if (status < 0)
b0347178
KH
2122 {
2123#ifdef TERMINFO
e12c1054 2124 fatal ("Cannot open terminfo database file");
b0347178 2125#else
e12c1054 2126 fatal ("Cannot open termcap database file");
b0347178
KH
2127#endif
2128 }
08a24c47 2129 if (status == 0)
b0347178
KH
2130 {
2131#ifdef TERMINFO
2132 fatal ("Terminal type %s is not defined.\n\
2133If that is not the actual type of terminal you have,\n\
2134use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2135`setenv TERM ...') to specify the correct type. It may be necessary\n\
e12c1054 2136to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
b0347178
KH
2137 terminal_type);
2138#else
2139 fatal ("Terminal type %s is not defined.\n\
c5a9c3e6
RS
2140If that is not the actual type of terminal you have,\n\
2141use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2142`setenv TERM ...') to specify the correct type. It may be necessary\n\
e12c1054 2143to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
b0347178
KH
2144 terminal_type);
2145#endif
2146 }
08a24c47 2147#ifdef TERMINFO
a678d9ff 2148 area = (char *) xmalloc (2044);
08a24c47 2149#else
a678d9ff 2150 area = (char *) xmalloc (strlen (buffer));
08a24c47
JB
2151#endif /* not TERMINFO */
2152 if (area == 0)
2153 abort ();
2154
2155 TS_ins_line = tgetstr ("al", address);
2156 TS_ins_multi_lines = tgetstr ("AL", address);
2157 TS_bell = tgetstr ("bl", address);
2158 BackTab = tgetstr ("bt", address);
2159 TS_clr_to_bottom = tgetstr ("cd", address);
2160 TS_clr_line = tgetstr ("ce", address);
ff11dfa1 2161 TS_clr_frame = tgetstr ("cl", address);
08a24c47
JB
2162 ColPosition = tgetstr ("ch", address);
2163 AbsPosition = tgetstr ("cm", address);
2164 CR = tgetstr ("cr", address);
2165 TS_set_scroll_region = tgetstr ("cs", address);
2166 TS_set_scroll_region_1 = tgetstr ("cS", address);
2167 RowPosition = tgetstr ("cv", address);
2168 TS_del_char = tgetstr ("dc", address);
2169 TS_del_multi_chars = tgetstr ("DC", address);
2170 TS_del_line = tgetstr ("dl", address);
2171 TS_del_multi_lines = tgetstr ("DL", address);
2172 TS_delete_mode = tgetstr ("dm", address);
2173 TS_end_delete_mode = tgetstr ("ed", address);
2174 TS_end_insert_mode = tgetstr ("ei", address);
2175 Home = tgetstr ("ho", address);
2176 TS_ins_char = tgetstr ("ic", address);
2177 TS_ins_multi_chars = tgetstr ("IC", address);
2178 TS_insert_mode = tgetstr ("im", address);
2179 TS_pad_inserted_char = tgetstr ("ip", address);
2180 TS_end_keypad_mode = tgetstr ("ke", address);
2181 TS_keypad_mode = tgetstr ("ks", address);
2182 LastLine = tgetstr ("ll", address);
2183 Right = tgetstr ("nd", address);
2184 Down = tgetstr ("do", address);
2185 if (!Down)
2186 Down = tgetstr ("nl", address); /* Obsolete name for "do" */
2187#ifdef VMS
2188 /* VMS puts a carriage return before each linefeed,
2189 so it is not safe to use linefeeds. */
2190 if (Down && Down[0] == '\n' && Down[1] == '\0')
2191 Down = 0;
2192#endif /* VMS */
2193 if (tgetflag ("bs"))
2194 Left = "\b"; /* can't possibly be longer! */
2195 else /* (Actually, "bs" is obsolete...) */
2196 Left = tgetstr ("le", address);
2197 if (!Left)
2198 Left = tgetstr ("bc", address); /* Obsolete name for "le" */
2199 TS_pad_char = tgetstr ("pc", address);
2200 TS_repeat = tgetstr ("rp", address);
2201 TS_end_standout_mode = tgetstr ("se", address);
2202 TS_fwd_scroll = tgetstr ("sf", address);
2203 TS_standout_mode = tgetstr ("so", address);
2204 TS_rev_scroll = tgetstr ("sr", address);
2205 Wcm.cm_tab = tgetstr ("ta", address);
2206 TS_end_termcap_modes = tgetstr ("te", address);
2207 TS_termcap_modes = tgetstr ("ti", address);
2208 Up = tgetstr ("up", address);
2209 TS_visible_bell = tgetstr ("vb", address);
a168702a
GM
2210 TS_cursor_normal = tgetstr ("ve", address);
2211 TS_cursor_visible = tgetstr ("vs", address);
2212 TS_cursor_invisible = tgetstr ("vi", address);
08a24c47 2213 TS_set_window = tgetstr ("wi", address);
a168702a
GM
2214
2215 TS_enter_underline_mode = tgetstr ("us", address);
2216 TS_exit_underline_mode = tgetstr ("ue", address);
2217 TN_magic_cookie_glitch_ul = tgetnum ("ug");
2218 TS_enter_bold_mode = tgetstr ("md", address);
2219 TS_enter_dim_mode = tgetstr ("mh", address);
2220 TS_enter_blink_mode = tgetstr ("mb", address);
2221 TS_enter_reverse_mode = tgetstr ("mr", address);
2222 TS_enter_alt_charset_mode = tgetstr ("as", address);
2223 TS_exit_alt_charset_mode = tgetstr ("ae", address);
2224 TS_exit_attribute_mode = tgetstr ("me", address);
2225
08a24c47
JB
2226 MultiUp = tgetstr ("UP", address);
2227 MultiDown = tgetstr ("DO", address);
2228 MultiLeft = tgetstr ("LE", address);
2229 MultiRight = tgetstr ("RI", address);
2230
e7f90eab
GM
2231 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2232 color because we can't switch back to the default foreground and
2233 background. */
a168702a 2234 TS_orig_pair = tgetstr ("op", address);
e7f90eab 2235 if (TS_orig_pair)
a168702a 2236 {
e7f90eab
GM
2237 TS_set_foreground = tgetstr ("AF", address);
2238 TS_set_background = tgetstr ("AB", address);
2239 if (!TS_set_foreground)
2240 {
2241 /* SVr4. */
2242 TS_set_foreground = tgetstr ("Sf", address);
2243 TS_set_background = tgetstr ("Sb", address);
2244 }
2245 TN_max_colors = tgetnum ("Co");
2246 TN_max_pairs = tgetnum ("pa");
a168702a 2247 }
a168702a 2248
e4058338
KH
2249 MagicWrap = tgetflag ("xn");
2250 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2251 the former flag imply the latter. */
2252 AutoWrap = MagicWrap || tgetflag ("am");
ff11dfa1 2253 memory_below_frame = tgetflag ("db");
08a24c47
JB
2254 TF_hazeltine = tgetflag ("hz");
2255 must_write_spaces = tgetflag ("in");
2256 meta_key = tgetflag ("km") || tgetflag ("MT");
2257 TF_insmode_motion = tgetflag ("mi");
2258 TF_standout_motion = tgetflag ("ms");
2259 TF_underscore = tgetflag ("ul");
08a24c47
JB
2260 TF_xs = tgetflag ("xs");
2261 TF_teleray = tgetflag ("xt");
2262
5c2c7893
JB
2263 term_get_fkeys (address);
2264
ff11dfa1 2265 /* Get frame size from system, or else from termcap. */
3b12ce12
RS
2266 {
2267 int height, width;
2268 get_frame_size (&width, &height);
e52f4e08
GM
2269 FRAME_WIDTH (sf) = width;
2270 FRAME_HEIGHT (sf) = height;
3b12ce12
RS
2271 }
2272
e52f4e08
GM
2273 if (FRAME_WIDTH (sf) <= 0)
2274 SET_FRAME_WIDTH (sf, tgetnum ("co"));
1efd8636
RS
2275 else
2276 /* Keep width and external_width consistent */
e52f4e08
GM
2277 SET_FRAME_WIDTH (sf, FRAME_WIDTH (sf));
2278 if (FRAME_HEIGHT (sf) <= 0)
2279 FRAME_HEIGHT (sf) = tgetnum ("li");
1efd8636 2280
e52f4e08 2281 if (FRAME_HEIGHT (sf) < 3 || FRAME_WIDTH (sf) < 3)
e12c1054 2282 fatal ("Screen size %dx%d is too small",
e52f4e08 2283 FRAME_HEIGHT (sf), FRAME_WIDTH (sf));
ee7a2de4 2284
08a24c47
JB
2285 min_padding_speed = tgetnum ("pb");
2286 TN_standout_width = tgetnum ("sg");
2287 TabWidth = tgetnum ("tw");
2288
2289#ifdef VMS
2290 /* These capabilities commonly use ^J.
2291 I don't know why, but sending them on VMS does not work;
2292 it causes following spaces to be lost, sometimes.
2293 For now, the simplest fix is to avoid using these capabilities ever. */
2294 if (Down && Down[0] == '\n')
2295 Down = 0;
2296#endif /* VMS */
2297
2298 if (!TS_bell)
2299 TS_bell = "\07";
2300
2301 if (!TS_fwd_scroll)
2302 TS_fwd_scroll = Down;
2303
2304 PC = TS_pad_char ? *TS_pad_char : 0;
2305
2306 if (TabWidth < 0)
2307 TabWidth = 8;
2308
2309/* Turned off since /etc/termcap seems to have :ta= for most terminals
2310 and newer termcap doc does not seem to say there is a default.
2311 if (!Wcm.cm_tab)
2312 Wcm.cm_tab = "\t";
2313*/
2314
2315 if (TS_standout_mode == 0)
2316 {
2317 TN_standout_width = tgetnum ("ug");
2318 TS_end_standout_mode = tgetstr ("ue", address);
2319 TS_standout_mode = tgetstr ("us", address);
2320 }
2321
afd359c4
RS
2322 /* If no `se' string, try using a `me' string instead.
2323 If that fails, we can't use standout mode at all. */
2324 if (TS_end_standout_mode == 0)
2325 {
e4bfb3b6 2326 char *s = tgetstr ("me", address);
afd359c4
RS
2327 if (s != 0)
2328 TS_end_standout_mode = s;
2329 else
2330 TS_standout_mode = 0;
2331 }
2332
08a24c47
JB
2333 if (TF_teleray)
2334 {
2335 Wcm.cm_tab = 0;
2336 /* Teleray: most programs want a space in front of TS_standout_mode,
2337 but Emacs can do without it (and give one extra column). */
2338 TS_standout_mode = "\033RD";
2339 TN_standout_width = 1;
2340 /* But that means we cannot rely on ^M to go to column zero! */
2341 CR = 0;
2342 /* LF can't be trusted either -- can alter hpos */
2343 /* if move at column 0 thru a line with TS_standout_mode */
2344 Down = 0;
2345 }
2346
2347 /* Special handling for certain terminal types known to need it */
2348
2349 if (!strcmp (terminal_type, "supdup"))
2350 {
ff11dfa1 2351 memory_below_frame = 1;
08a24c47
JB
2352 Wcm.cm_losewrap = 1;
2353 }
2354 if (!strncmp (terminal_type, "c10", 3)
2355 || !strcmp (terminal_type, "perq"))
2356 {
2357 /* Supply a makeshift :wi string.
2358 This string is not valid in general since it works only
2359 for windows starting at the upper left corner;
2360 but that is all Emacs uses.
2361
ff11dfa1 2362 This string works only if the frame is using
08a24c47
JB
2363 the top of the video memory, because addressing is memory-relative.
2364 So first check the :ti string to see if that is true.
2365
2366 It would be simpler if the :wi string could go in the termcap
2367 entry, but it can't because it is not fully valid.
2368 If it were in the termcap entry, it would confuse other programs. */
2369 if (!TS_set_window)
2370 {
2371 p = TS_termcap_modes;
2372 while (*p && strcmp (p, "\033v "))
2373 p++;
2374 if (*p)
2375 TS_set_window = "\033v%C %C %C %C ";
2376 }
2377 /* Termcap entry often fails to have :in: flag */
2378 must_write_spaces = 1;
2379 /* :ti string typically fails to have \E^G! in it */
2380 /* This limits scope of insert-char to one line. */
2381 strcpy (area, TS_termcap_modes);
2382 strcat (area, "\033\007!");
2383 TS_termcap_modes = area;
2384 area += strlen (area) + 1;
2385 p = AbsPosition;
2386 /* Change all %+ parameters to %C, to handle
2387 values above 96 correctly for the C100. */
2388 while (*p)
2389 {
2390 if (p[0] == '%' && p[1] == '+')
2391 p[1] = 'C';
2392 p++;
2393 }
2394 }
2395
e52f4e08
GM
2396 FrameRows = FRAME_HEIGHT (sf);
2397 FrameCols = FRAME_WIDTH (sf);
2398 specified_window = FRAME_HEIGHT (sf);
08a24c47
JB
2399
2400 if (Wcm_init () == -1) /* can't do cursor motion */
2401#ifdef VMS
2402 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2403It lacks the ability to position the cursor.\n\
2404If that is not the actual type of terminal you have, use either the\n\
2405DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
e12c1054 2406or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
08a24c47 2407 terminal_type);
37dad45a
RS
2408#else /* not VMS */
2409# ifdef TERMINFO
2410 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2411It lacks the ability to position the cursor.\n\
2412If that is not the actual type of terminal you have,\n\
2413use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2414`setenv TERM ...') to specify the correct type. It may be necessary\n\
e12c1054 2415to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
37dad45a
RS
2416 terminal_type);
2417# else /* TERMCAP */
08a24c47
JB
2418 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2419It lacks the ability to position the cursor.\n\
2420If that is not the actual type of terminal you have,\n\
c5a9c3e6
RS
2421use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2422`setenv TERM ...') to specify the correct type. It may be necessary\n\
e12c1054 2423to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
08a24c47 2424 terminal_type);
37dad45a
RS
2425# endif /* TERMINFO */
2426#endif /*VMS */
e52f4e08
GM
2427 if (FRAME_HEIGHT (sf) <= 0
2428 || FRAME_WIDTH (sf) <= 0)
e12c1054 2429 fatal ("The frame size has not been specified");
08a24c47
JB
2430
2431 delete_in_insert_mode
2432 = TS_delete_mode && TS_insert_mode
2433 && !strcmp (TS_delete_mode, TS_insert_mode);
2434
2435 se_is_so = (TS_standout_mode
2436 && TS_end_standout_mode
2437 && !strcmp (TS_standout_mode, TS_end_standout_mode));
2438
2439 /* Remove width of standout marker from usable width of line */
2440 if (TN_standout_width > 0)
e52f4e08 2441 SET_FRAME_WIDTH (sf, FRAME_WIDTH (sf) - TN_standout_width);
08a24c47
JB
2442
2443 UseTabs = tabs_safe_p () && TabWidth == 8;
2444
2445 scroll_region_ok
2446 = (Wcm.cm_abs
2447 && (TS_set_window || TS_set_scroll_region || TS_set_scroll_region_1));
2448
2449 line_ins_del_ok = (((TS_ins_line || TS_ins_multi_lines)
2450 && (TS_del_line || TS_del_multi_lines))
2451 || (scroll_region_ok && TS_fwd_scroll && TS_rev_scroll));
2452
2453 char_ins_del_ok = ((TS_ins_char || TS_insert_mode
2454 || TS_pad_inserted_char || TS_ins_multi_chars)
2455 && (TS_del_char || TS_del_multi_chars));
2456
2457 fast_clear_end_of_line = TS_clr_line != 0;
2458
2459 init_baud_rate ();
2460 if (read_socket_hook) /* Baudrate is somewhat */
2461 /* meaningless in this case */
2462 baud_rate = 9600;
20a558dc 2463
e52f4e08
GM
2464 FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
2465 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
eccec691 2466#endif /* WINDOWSNT */
08a24c47
JB
2467}
2468
2469/* VARARGS 1 */
dfcf069d 2470void
08a24c47 2471fatal (str, arg1, arg2)
4746118a 2472 char *str, *arg1, *arg2;
08a24c47
JB
2473{
2474 fprintf (stderr, "emacs: ");
2475 fprintf (stderr, str, arg1, arg2);
e12c1054 2476 fprintf (stderr, "\n");
08a24c47
JB
2477 fflush (stderr);
2478 exit (1);
2479}
07c57952 2480
dfcf069d 2481void
07c57952
KH
2482syms_of_term ()
2483{
2484 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo,
2485 "Non-nil means the system uses terminfo rather than termcap.\n\
2486This variable can be used by terminal emulator packages.");
2487#ifdef TERMINFO
2488 system_uses_terminfo = 1;
2489#else
2490 system_uses_terminfo = 0;
2491#endif
c291d9ef
RS
2492
2493 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function,
2494 "Non-nil means call this function to ring the bell.\n\
2495The function should accept no arguments.");
2496 Vring_bell_function = Qnil;
a168702a
GM
2497
2498 defsubr (&Stty_display_color_p);
07c57952 2499}
a168702a 2500