* scroll.c (FRAME_IS_TERMCAP, FRAME_IS_X, FRAME_HAS_MINIBUF):
[bpt/emacs.git] / src / term.c
CommitLineData
08a24c47 1/* terminal control module for terminals described by TERMCAP
4746118a 2 Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc.
08a24c47
JB
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
4746118a 8the Free Software Foundation; either version 2, or (at your option)
08a24c47
JB
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21#include <stdio.h>
22#include <ctype.h>
23#include "config.h"
24#include "termchar.h"
25#include "termopts.h"
26#include "cm.h"
27#undef NULL
28#include "lisp.h"
ff11dfa1 29#include "frame.h"
08a24c47
JB
30#include "disptab.h"
31#include "termhooks.h"
5c2c7893 32#include "keyboard.h"
08a24c47
JB
33
34#define max(a, b) ((a) > (b) ? (a) : (b))
35#define min(a, b) ((a) < (b) ? (a) : (b))
36
ff11dfa1 37#define OUTPUT(a) tputs (a, FRAME_HEIGHT (selected_frame) - curY, cmputc)
08a24c47
JB
38#define OUTPUT1(a) tputs (a, 1, cmputc)
39#define OUTPUTL(a, lines) tputs (a, lines, cmputc)
ff11dfa1 40#define OUTPUT_IF(a) { if (a) tputs (a, FRAME_HEIGHT (selected_frame) - curY, cmputc); }
08a24c47
JB
41#define OUTPUT1_IF(a) { if (a) tputs (a, 1, cmputc); }
42
43/* Terminal charateristics that higher levels want to look at.
44 These are all extern'd in termchar.h */
45
08a24c47
JB
46int must_write_spaces; /* Nonzero means spaces in the text
47 must actually be output; can't just skip
48 over some columns to leave them blank. */
49int min_padding_speed; /* Speed below which no padding necessary */
50
51int line_ins_del_ok; /* Terminal can insert and delete lines */
52int char_ins_del_ok; /* Terminal can insert and delete chars */
53int scroll_region_ok; /* Terminal supports setting the
54 scroll window */
ff11dfa1 55int memory_below_frame; /* Terminal remembers lines
08a24c47
JB
56 scrolled off bottom */
57int fast_clear_end_of_line; /* Terminal has a `ce' string */
58
59int dont_calculate_costs; /* Nonzero means don't bother computing */
60 /* various cost tables; we won't use them. */
61
ff11dfa1 62/* Nonzero means no need to redraw the entire frame on resuming
08a24c47
JB
63 a suspended Emacs. This is useful on terminals with multiple pages,
64 where one page is used for Emacs and another for all else. */
65int no_redraw_on_reenter;
66
67/* Hook functions that you can set to snap out the functions in this file.
68 These are all extern'd in termhooks.h */
69
70int (*cursor_to_hook) ();
71int (*raw_cursor_to_hook) ();
72
73int (*clear_to_end_hook) ();
ff11dfa1 74int (*clear_frame_hook) ();
08a24c47
JB
75int (*clear_end_of_line_hook) ();
76
77int (*ins_del_lines_hook) ();
78
79int (*change_line_highlight_hook) ();
80int (*reassert_line_highlight_hook) ();
81
82int (*insert_glyphs_hook) ();
83int (*write_glyphs_hook) ();
84int (*delete_glyphs_hook) ();
85
86int (*ring_bell_hook) ();
87
88int (*reset_terminal_modes_hook) ();
89int (*set_terminal_modes_hook) ();
90int (*update_begin_hook) ();
91int (*update_end_hook) ();
92int (*set_terminal_window_hook) ();
93
94int (*read_socket_hook) ();
95
69a46d1c
JB
96/* Return the current position of the mouse. This should clear
97 mouse_moved until the next motion event arrives. */
ff11dfa1 98void (*mouse_position_hook) ( /* FRAME_PTR *f,
69a46d1c
JB
99 Lisp_Object *x,
100 Lisp_Object *y,
e5d77022 101 unsigned long *time */ );
08a24c47 102
ff11dfa1
JB
103/* When reading from a minibuffer in a different frame, Emacs wants
104 to shift the highlight from the selected frame to the minibuffer's
105 frame; under X, this means it lies about where the focus is.
2e146aa4
JB
106 This hook tells the window system code to re-decide where to put
107 the highlight. */
ff11dfa1 108void (*frame_rehighlight_hook) ( /* FRAME_PTR f */ );
2e146aa4 109
08a24c47
JB
110/* Strings, numbers and flags taken from the termcap entry. */
111
112char *TS_ins_line; /* termcap "al" */
113char *TS_ins_multi_lines; /* "AL" (one parameter, # lines to insert) */
114char *TS_bell; /* "bl" */
115char *TS_clr_to_bottom; /* "cd" */
116char *TS_clr_line; /* "ce", clear to end of line */
ff11dfa1 117char *TS_clr_frame; /* "cl" */
08a24c47
JB
118char *TS_set_scroll_region; /* "cs" (2 params, first line and last line) */
119char *TS_set_scroll_region_1; /* "cS" (4 params: total lines,
120 lines above scroll region, lines below it,
121 total lines again) */
122char *TS_del_char; /* "dc" */
123char *TS_del_multi_chars; /* "DC" (one parameter, # chars to delete) */
124char *TS_del_line; /* "dl" */
125char *TS_del_multi_lines; /* "DL" (one parameter, # lines to delete) */
126char *TS_delete_mode; /* "dm", enter character-delete mode */
127char *TS_end_delete_mode; /* "ed", leave character-delete mode */
128char *TS_end_insert_mode; /* "ei", leave character-insert mode */
129char *TS_ins_char; /* "ic" */
130char *TS_ins_multi_chars; /* "IC" (one parameter, # chars to insert) */
131char *TS_insert_mode; /* "im", enter character-insert mode */
132char *TS_pad_inserted_char; /* "ip". Just padding, no commands. */
133char *TS_end_keypad_mode; /* "ke" */
134char *TS_keypad_mode; /* "ks" */
135char *TS_pad_char; /* "pc", char to use as padding */
136char *TS_repeat; /* "rp" (2 params, # times to repeat
137 and character to be repeated) */
138char *TS_end_standout_mode; /* "se" */
139char *TS_fwd_scroll; /* "sf" */
140char *TS_standout_mode; /* "so" */
141char *TS_rev_scroll; /* "sr" */
142char *TS_end_termcap_modes; /* "te" */
143char *TS_termcap_modes; /* "ti" */
144char *TS_visible_bell; /* "vb" */
145char *TS_end_visual_mode; /* "ve" */
146char *TS_visual_mode; /* "vi" */
147char *TS_set_window; /* "wi" (4 params, start and end of window,
148 each as vpos and hpos) */
149
150int TF_hazeltine; /* termcap hz flag. */
151int TF_insmode_motion; /* termcap mi flag: can move while in insert mode. */
152int TF_standout_motion; /* termcap mi flag: can move while in standout mode. */
153int TF_underscore; /* termcap ul flag: _ underlines if overstruck on
154 nonblank position. Must clear before writing _. */
155int TF_teleray; /* termcap xt flag: many weird consequences.
156 For t1061. */
157
158int TF_xs; /* Nonzero for "xs". If set together with
159 TN_standout_width == 0, it means don't bother
160 to write any end-standout cookies. */
161
162int TN_standout_width; /* termcap sg number: width occupied by standout
163 markers */
164
165static int RPov; /* # chars to start a TS_repeat */
166
167static int delete_in_insert_mode; /* delete mode == insert mode */
168
169static int se_is_so; /* 1 if same string both enters and leaves
170 standout mode */
171
172/* internal state */
173
174/* Number of chars of space used for standout marker at beginning of line,
175 or'd with 0100. Zero if no standout marker at all.
176
177 Used IFF TN_standout_width >= 0. */
178
179static char *chars_wasted;
180static char *copybuf;
181
182/* nonzero means supposed to write text in standout mode. */
183int standout_requested;
184
185int insert_mode; /* Nonzero when in insert mode. */
186int standout_mode; /* Nonzero when in standout mode. */
187
188/* Size of window specified by higher levels.
ff11dfa1 189 This is the number of lines, from the top of frame downwards,
08a24c47
JB
190 which can participate in insert-line/delete-line operations.
191
ff11dfa1 192 Effectively it excludes the bottom frame_height - specified_window_size
08a24c47
JB
193 lines from those operations. */
194
195int specified_window;
196
ff11dfa1 197/* Frame currently being redisplayed; 0 if not currently redisplaying.
08a24c47
JB
198 (Direct output does not count). */
199
ff11dfa1 200FRAME_PTR updating_frame;
08a24c47
JB
201
202char *tparam ();
203\f
204ring_bell ()
205{
ff11dfa1 206 if (! FRAME_IS_TERMCAP (selected_frame))
08a24c47
JB
207 {
208 (*ring_bell_hook) ();
209 return;
210 }
211 OUTPUT (TS_visible_bell && visible_bell ? TS_visible_bell : TS_bell);
212}
213
214set_terminal_modes ()
215{
ff11dfa1 216 if (! FRAME_IS_TERMCAP (selected_frame))
08a24c47
JB
217 {
218 (*set_terminal_modes_hook) ();
219 return;
220 }
221 OUTPUT_IF (TS_termcap_modes);
222 OUTPUT_IF (TS_visual_mode);
223 OUTPUT_IF (TS_keypad_mode);
224 losecursor ();
225}
226
227reset_terminal_modes ()
228{
ff11dfa1 229 if (! FRAME_IS_TERMCAP (selected_frame))
08a24c47
JB
230 {
231 (*reset_terminal_modes_hook) ();
232 return;
233 }
234 if (TN_standout_width < 0)
235 turn_off_highlight ();
236 turn_off_insert ();
237 OUTPUT_IF (TS_end_keypad_mode);
238 OUTPUT_IF (TS_end_visual_mode);
239 OUTPUT_IF (TS_end_termcap_modes);
240 /* Output raw CR so kernel can track the cursor hpos. */
241 /* But on magic-cookie terminals this can erase an end-standout marker and
ff11dfa1 242 cause the rest of the frame to be in standout, so move down first. */
08a24c47
JB
243 if (TN_standout_width >= 0)
244 cmputc ('\n');
245 cmputc ('\r');
246}
247
ff11dfa1
JB
248update_begin (f)
249 FRAME_PTR f;
08a24c47 250{
ff11dfa1
JB
251 updating_frame = f;
252 if (! FRAME_IS_TERMCAP (updating_frame))
253 (*update_begin_hook) (f);
08a24c47
JB
254}
255
ff11dfa1
JB
256update_end (f)
257 FRAME_PTR f;
08a24c47 258{
ff11dfa1 259 if (! FRAME_IS_TERMCAP (updating_frame))
08a24c47 260 {
ff11dfa1
JB
261 (*update_end_hook) (f);
262 updating_frame = 0;
08a24c47
JB
263 return;
264 }
265 turn_off_insert ();
266 background_highlight ();
267 standout_requested = 0;
ff11dfa1 268 updating_frame = 0;
08a24c47
JB
269}
270
271set_terminal_window (size)
272 int size;
273{
ff11dfa1 274 if (! FRAME_IS_TERMCAP (updating_frame))
08a24c47
JB
275 {
276 (*set_terminal_window_hook) (size);
277 return;
278 }
ff11dfa1 279 specified_window = size ? size : FRAME_HEIGHT (selected_frame);
08a24c47
JB
280 if (!scroll_region_ok)
281 return;
282 set_scroll_region (0, specified_window);
283}
284
285set_scroll_region (start, stop)
286 int start, stop;
287{
288 char *buf;
289 if (TS_set_scroll_region)
290 {
291 buf = tparam (TS_set_scroll_region, 0, 0, start, stop - 1);
292 }
293 else if (TS_set_scroll_region_1)
294 {
295 buf = tparam (TS_set_scroll_region_1, 0, 0,
ff11dfa1
JB
296 FRAME_HEIGHT (selected_frame), start,
297 FRAME_HEIGHT (selected_frame) - stop,
298 FRAME_HEIGHT (selected_frame));
08a24c47
JB
299 }
300 else
301 {
ff11dfa1 302 buf = tparam (TS_set_window, 0, 0, start, 0, stop, FRAME_WIDTH (selected_frame));
08a24c47
JB
303 }
304 OUTPUT (buf);
305 free (buf);
306 losecursor ();
307}
308\f
309turn_on_insert ()
310{
311 if (!insert_mode)
312 OUTPUT (TS_insert_mode);
313 insert_mode = 1;
314}
315
316turn_off_insert ()
317{
318 if (insert_mode)
319 OUTPUT (TS_end_insert_mode);
320 insert_mode = 0;
321}
322\f
323/* Handle highlighting when TN_standout_width (termcap sg) is not specified.
324 In these terminals, output is affected by the value of standout
325 mode when the output is written.
326
327 These functions are called on all terminals, but do nothing
328 on terminals whose standout mode does not work that way. */
329
330turn_off_highlight ()
331{
332 if (TN_standout_width < 0)
333 {
334 if (standout_mode)
335 OUTPUT_IF (TS_end_standout_mode);
336 standout_mode = 0;
337 }
338}
339
340turn_on_highlight ()
341{
342 if (TN_standout_width < 0)
343 {
344 if (!standout_mode)
345 OUTPUT_IF (TS_standout_mode);
346 standout_mode = 1;
347 }
348}
349
350/* Set standout mode to the state it should be in for
351 empty space inside windows. What this is,
352 depends on the user option inverse-video. */
353
354background_highlight ()
355{
356 if (TN_standout_width >= 0)
357 return;
358 if (inverse_video)
359 turn_on_highlight ();
360 else
361 turn_off_highlight ();
362}
363
364/* Set standout mode to the mode specified for the text to be output. */
365
366static
367highlight_if_desired ()
368{
369 if (TN_standout_width >= 0)
370 return;
371 if (!inverse_video == !standout_requested)
372 turn_off_highlight ();
373 else
374 turn_on_highlight ();
375}
376\f
377/* Handle standout mode for terminals in which TN_standout_width >= 0.
378 On these terminals, standout is controlled by markers that
ff11dfa1 379 live inside the terminal's memory. TN_standout_width is the width
08a24c47
JB
380 that the marker occupies in memory. Standout runs from the marker
381 to the end of the line on some terminals, or to the next
382 turn-off-standout marker (TS_end_standout_mode) string
383 on other terminals. */
384
385/* Write a standout marker or end-standout marker at the front of the line
386 at vertical position vpos. */
387
388write_standout_marker (flag, vpos)
389 int flag, vpos;
390{
391 if (flag || (TS_end_standout_mode && !TF_teleray && !se_is_so
392 && !(TF_xs && TN_standout_width == 0)))
393 {
394 cmgoto (vpos, 0);
395 cmplus (TN_standout_width);
396 OUTPUT (flag ? TS_standout_mode : TS_end_standout_mode);
397 chars_wasted[curY] = TN_standout_width | 0100;
398 }
399}
400\f
401/* External interface to control of standout mode.
402 Call this when about to modify line at position VPOS
403 and not change whether it is highlighted. */
404
405reassert_line_highlight (highlight, vpos)
406 int highlight;
407 int vpos;
408{
ff11dfa1 409 if (! FRAME_IS_TERMCAP ((updating_frame ? updating_frame : selected_frame)))
08a24c47
JB
410 {
411 (*reassert_line_highlight_hook) (highlight, vpos);
412 return;
413 }
414 if (TN_standout_width < 0)
415 /* Handle terminals where standout takes affect at output time */
416 standout_requested = highlight;
417 else if (chars_wasted[vpos] == 0)
418 /* For terminals with standout markers, write one on this line
419 if there isn't one already. */
420 write_standout_marker (highlight, vpos);
421}
422
423/* Call this when about to modify line at position VPOS
424 and change whether it is highlighted. */
425
426change_line_highlight (new_highlight, vpos, first_unused_hpos)
427 int new_highlight, vpos, first_unused_hpos;
428{
429 standout_requested = new_highlight;
ff11dfa1 430 if (! FRAME_IS_TERMCAP (updating_frame))
08a24c47
JB
431 {
432 (*change_line_highlight_hook) (new_highlight, vpos, first_unused_hpos);
433 return;
434 }
435
436 cursor_to (vpos, 0);
437
438 if (TN_standout_width < 0)
439 background_highlight ();
440 /* If line starts with a marker, delete the marker */
441 else if (TS_clr_line && chars_wasted[curY])
442 {
443 turn_off_insert ();
444 /* On Teleray, make sure to erase the SO marker. */
445 if (TF_teleray)
446 {
ff11dfa1 447 cmgoto (curY - 1, FRAME_WIDTH (selected_frame) - 4);
08a24c47
JB
448 OUTPUT ("\033S");
449 curY++; /* ESC S moves to next line where the TS_standout_mode was */
450 curX = 0;
451 }
452 else
453 cmgoto (curY, 0); /* reposition to kill standout marker */
454 }
455 clear_end_of_line_raw (first_unused_hpos);
456 reassert_line_highlight (new_highlight, curY);
457}
458\f
459
460/* Move to absolute position, specified origin 0 */
461
462cursor_to (row, col)
4746118a 463 int row, col;
08a24c47 464{
ff11dfa1
JB
465 if (! FRAME_IS_TERMCAP ((updating_frame
466 ? updating_frame
467 : selected_frame))
08a24c47
JB
468 && cursor_to_hook)
469 {
470 (*cursor_to_hook) (row, col);
471 return;
472 }
473
474 col += chars_wasted[row] & 077;
475 if (curY == row && curX == col)
476 return;
477 if (!TF_standout_motion)
478 background_highlight ();
479 if (!TF_insmode_motion)
480 turn_off_insert ();
481 cmgoto (row, col);
482}
483
484/* Similar but don't take any account of the wasted characters. */
485
486raw_cursor_to (row, col)
4746118a 487 int row, col;
08a24c47 488{
ff11dfa1 489 if (! FRAME_IS_TERMCAP ((updating_frame ? updating_frame : selected_frame)))
08a24c47
JB
490 {
491 (*raw_cursor_to_hook) (row, col);
492 return;
493 }
494 if (curY == row && curX == col)
495 return;
496 if (!TF_standout_motion)
497 background_highlight ();
498 if (!TF_insmode_motion)
499 turn_off_insert ();
500 cmgoto (row, col);
501}
502\f
503/* Erase operations */
504
ff11dfa1 505/* clear from cursor to end of frame */
08a24c47
JB
506clear_to_end ()
507{
508 register int i;
509
ff11dfa1 510 if (clear_to_end_hook && FRAME_IS_TERMCAP (updating_frame))
08a24c47
JB
511 {
512 (*clear_to_end_hook) ();
513 return;
514 }
515 if (TS_clr_to_bottom)
516 {
517 background_highlight ();
518 OUTPUT (TS_clr_to_bottom);
ff11dfa1 519 bzero (chars_wasted + curY, FRAME_HEIGHT (selected_frame) - curY);
08a24c47
JB
520 }
521 else
522 {
ff11dfa1 523 for (i = curY; i < FRAME_HEIGHT (selected_frame); i++)
08a24c47
JB
524 {
525 cursor_to (i, 0);
ff11dfa1 526 clear_end_of_line_raw (FRAME_WIDTH (selected_frame));
08a24c47
JB
527 }
528 }
529}
530
ff11dfa1 531/* Clear entire frame */
08a24c47 532
ff11dfa1 533clear_frame ()
08a24c47 534{
ff11dfa1
JB
535 if (clear_frame_hook
536 && ! FRAME_IS_TERMCAP ((updating_frame ? updating_frame : selected_frame)))
08a24c47 537 {
ff11dfa1 538 (*clear_frame_hook) ();
08a24c47
JB
539 return;
540 }
ff11dfa1 541 if (TS_clr_frame)
08a24c47
JB
542 {
543 background_highlight ();
ff11dfa1
JB
544 OUTPUT (TS_clr_frame);
545 bzero (chars_wasted, FRAME_HEIGHT (selected_frame));
08a24c47
JB
546 cmat (0, 0);
547 }
548 else
549 {
550 cursor_to (0, 0);
551 clear_to_end ();
552 }
553}
554
555/* Clear to end of line, but do not clear any standout marker.
556 Assumes that the cursor is positioned at a character of real text,
557 which implies it cannot be before a standout marker
558 unless the marker has zero width.
559
560 Note that the cursor may be moved. */
561
562clear_end_of_line (first_unused_hpos)
563 int first_unused_hpos;
564{
565 static GLYPH buf[1] = {SPACEGLYPH};
ff11dfa1 566 if (FRAME_IS_TERMCAP (selected_frame)
08a24c47
JB
567 && TN_standout_width == 0 && curX == 0 && chars_wasted[curY] != 0)
568 write_glyphs (buf, 1);
569 clear_end_of_line_raw (first_unused_hpos);
570}
571
572/* Clear from cursor to end of line.
573 Assume that the line is already clear starting at column first_unused_hpos.
574 If the cursor is at a standout marker, erase the marker.
575
576 Note that the cursor may be moved, on terminals lacking a `ce' string. */
577
578clear_end_of_line_raw (first_unused_hpos)
579 int first_unused_hpos;
580{
581 register int i;
582
583 if (clear_end_of_line_hook
ff11dfa1
JB
584 && ! FRAME_IS_TERMCAP ((updating_frame
585 ? updating_frame
586 : selected_frame)))
08a24c47
JB
587 {
588 (*clear_end_of_line_hook) (first_unused_hpos);
589 return;
590 }
591
592 first_unused_hpos += chars_wasted[curY] & 077;
593 if (curX >= first_unused_hpos)
594 return;
595 /* Notice if we are erasing a magic cookie */
596 if (curX == 0)
597 chars_wasted[curY] = 0;
598 background_highlight ();
599 if (TS_clr_line)
600 {
601 OUTPUT1 (TS_clr_line);
602 }
603 else
604 { /* have to do it the hard way */
605 turn_off_insert ();
606
607 /* Do not write in last row last col with Autowrap on. */
ff11dfa1
JB
608 if (AutoWrap && curY == FRAME_HEIGHT (selected_frame) - 1
609 && first_unused_hpos == FRAME_WIDTH (selected_frame))
08a24c47
JB
610 first_unused_hpos--;
611
612 for (i = curX; i < first_unused_hpos; i++)
613 {
614 if (termscript)
615 fputc (' ', termscript);
616 putchar (' ');
617 }
618 cmplus (first_unused_hpos - curX);
619 }
620}
621\f
622
623write_glyphs (string, len)
624 register GLYPH *string;
625 register int len;
626{
627 register GLYPH g;
628 register int tlen = GLYPH_TABLE_LENGTH;
629 register Lisp_Object *tbase = GLYPH_TABLE_BASE;
630
631 if (write_glyphs_hook
ff11dfa1 632 && ! FRAME_IS_TERMCAP ((updating_frame ? updating_frame : selected_frame)))
08a24c47
JB
633 {
634 (*write_glyphs_hook) (string, len);
635 return;
636 }
637
638 highlight_if_desired ();
639 turn_off_insert ();
640
641 /* Don't dare write in last column of bottom line, if AutoWrap,
ff11dfa1 642 since that would scroll the whole frame on some terminals. */
08a24c47
JB
643
644 if (AutoWrap
ff11dfa1 645 && curY + 1 == FRAME_HEIGHT (selected_frame)
08a24c47 646 && (curX + len - (chars_wasted[curY] & 077)
ff11dfa1 647 == FRAME_WIDTH (selected_frame)))
08a24c47
JB
648 len --;
649
650 cmplus (len);
651 while (--len >= 0)
652 {
653 g = *string++;
654 /* Check quickly for G beyond length of table.
655 That implies it isn't an alias and is simple. */
656 if (g >= tlen)
657 {
658 simple:
659 putc (g & 0xff, stdout);
660 if (ferror (stdout))
661 clearerr (stdout);
662 if (termscript)
663 putc (g & 0xff, termscript);
664 }
665 else
666 {
667 /* G has an entry in Vglyph_table,
668 so process any alias and then test for simpleness. */
669 while (GLYPH_ALIAS_P (tbase, tlen, g))
670 g = GLYPH_ALIAS (tbase, g);
671 if (GLYPH_SIMPLE_P (tbase, tlen, g))
672 goto simple;
673 else
674 {
675 /* Here if G (or its definition as an alias) is not simple. */
676 fwrite (GLYPH_STRING (tbase, g), 1, GLYPH_LENGTH (tbase, g),
677 stdout);
678 if (ferror (stdout))
679 clearerr (stdout);
680 if (termscript)
681 fwrite (GLYPH_STRING (tbase, g), 1, GLYPH_LENGTH (tbase, g),
682 termscript);
683 }
684 }
685 }
686}
687
688/* If start is zero, insert blanks instead of a string at start */
689
690insert_glyphs (start, len)
691 register GLYPH *start;
692 register int len;
693{
694 char *buf;
695 register GLYPH g;
696 register int tlen = GLYPH_TABLE_LENGTH;
697 register Lisp_Object *tbase = GLYPH_TABLE_BASE;
698
ff11dfa1 699 if (insert_glyphs_hook && ! FRAME_IS_TERMCAP (updating_frame))
08a24c47
JB
700 {
701 (*insert_glyphs_hook) (start, len);
702 return;
703 }
704 highlight_if_desired ();
705
706 if (TS_ins_multi_chars)
707 {
708 buf = tparam (TS_ins_multi_chars, 0, 0, len);
709 OUTPUT1 (buf);
710 free (buf);
711 if (start)
712 write_glyphs (start, len);
713 return;
714 }
715
716 turn_on_insert ();
717 cmplus (len);
718 while (--len >= 0)
719 {
720 OUTPUT1_IF (TS_ins_char);
721 if (!start)
722 g = SPACEGLYPH;
723 else
724 g = *start++;
725
726 if (GLYPH_SIMPLE_P (tbase, tlen, g))
727 {
728 putc (g & 0xff, stdout);
729 if (ferror (stdout))
730 clearerr (stdout);
731 if (termscript)
732 putc (g & 0xff, termscript);
733 }
734 else
735 {
736 fwrite (GLYPH_STRING (tbase, g), 1, GLYPH_LENGTH (tbase, g), stdout);
737 if (ferror (stdout))
738 clearerr (stdout);
739 if (termscript)
740 fwrite (GLYPH_STRING (tbase, g), 1, GLYPH_LENGTH (tbase, g),
741 termscript);
742 }
743
744 OUTPUT1_IF (TS_pad_inserted_char);
745 }
746}
747
748delete_glyphs (n)
749 register int n;
750{
751 char *buf;
752 register int i;
753
ff11dfa1 754 if (delete_glyphs_hook && ! FRAME_IS_TERMCAP (updating_frame))
08a24c47
JB
755 {
756 (*delete_glyphs_hook) (n);
757 return;
758 }
759
760 if (delete_in_insert_mode)
761 {
762 turn_on_insert ();
763 }
764 else
765 {
766 turn_off_insert ();
767 OUTPUT_IF (TS_delete_mode);
768 }
769
770 if (TS_del_multi_chars)
771 {
772 buf = tparam (TS_del_multi_chars, 0, 0, n);
773 OUTPUT1 (buf);
774 free (buf);
775 }
776 else
777 for (i = 0; i < n; i++)
778 OUTPUT1 (TS_del_char);
779 if (!delete_in_insert_mode)
780 OUTPUT_IF (TS_end_delete_mode);
781}
782\f
783/* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
784
785ins_del_lines (vpos, n)
786 int vpos, n;
787{
788 char *multi = n > 0 ? TS_ins_multi_lines : TS_del_multi_lines;
789 char *single = n > 0 ? TS_ins_line : TS_del_line;
790 char *scroll = n > 0 ? TS_rev_scroll : TS_fwd_scroll;
791
792 register int i = n > 0 ? n : -n;
793 register char *buf;
794
ff11dfa1 795 if (ins_del_lines_hook && ! FRAME_IS_TERMCAP (updating_frame))
08a24c47
JB
796 {
797 (*ins_del_lines_hook) (vpos, n);
798 return;
799 }
800
801 /* If the lines below the insertion are being pushed
802 into the end of the window, this is the same as clearing;
803 and we know the lines are already clear, since the matching
804 deletion has already been done. So can ignore this. */
805 /* If the lines below the deletion are blank lines coming
806 out of the end of the window, don't bother,
807 as there will be a matching inslines later that will flush them. */
808 if (scroll_region_ok && vpos + i >= specified_window)
809 return;
ff11dfa1 810 if (!memory_below_frame && vpos + i >= FRAME_HEIGHT (selected_frame))
08a24c47
JB
811 return;
812
813 if (multi)
814 {
815 raw_cursor_to (vpos, 0);
816 background_highlight ();
817 buf = tparam (multi, 0, 0, i);
818 OUTPUT (buf);
819 free (buf);
820 }
821 else if (single)
822 {
823 raw_cursor_to (vpos, 0);
824 background_highlight ();
825 while (--i >= 0)
826 OUTPUT (single);
827 if (TF_teleray)
828 curX = 0;
829 }
830 else
831 {
832 set_scroll_region (vpos, specified_window);
833 if (n < 0)
834 raw_cursor_to (specified_window - 1, 0);
835 else
836 raw_cursor_to (vpos, 0);
837 background_highlight ();
838 while (--i >= 0)
839 OUTPUTL (scroll, specified_window - vpos);
840 set_scroll_region (0, specified_window);
841 }
842
843 if (TN_standout_width >= 0)
844 {
845 register lower_limit
846 = (scroll_region_ok
847 ? specified_window
ff11dfa1 848 : FRAME_HEIGHT (selected_frame));
08a24c47
JB
849
850 if (n < 0)
851 {
852 bcopy (&chars_wasted[vpos - n], &chars_wasted[vpos],
853 lower_limit - vpos + n);
854 bzero (&chars_wasted[lower_limit + n], - n);
855 }
856 else
857 {
858 bcopy (&chars_wasted[vpos], &copybuf[vpos], lower_limit - vpos - n);
859 bcopy (&copybuf[vpos], &chars_wasted[vpos + n],
860 lower_limit - vpos - n);
861 bzero (&chars_wasted[vpos], n);
862 }
863 }
ff11dfa1 864 if (!scroll_region_ok && memory_below_frame && n < 0)
08a24c47 865 {
ff11dfa1 866 cursor_to (FRAME_HEIGHT (selected_frame) + n, 0);
08a24c47
JB
867 clear_to_end ();
868 }
869}
870\f
871/* Compute cost of sending "str", in characters,
872 not counting any line-dependent padding. */
873
874int
875string_cost (str)
876 char *str;
877{
878 cost = 0;
879 if (str)
880 tputs (str, 0, evalcost);
881 return cost;
882}
883
884/* Compute cost of sending "str", in characters,
885 counting any line-dependent padding at one line. */
886
887static int
888string_cost_one_line (str)
889 char *str;
890{
891 cost = 0;
892 if (str)
893 tputs (str, 1, evalcost);
894 return cost;
895}
896
897/* Compute per line amount of line-dependent padding,
898 in tenths of characters. */
899
900int
901per_line_cost (str)
902 register char *str;
903{
904 cost = 0;
905 if (str)
906 tputs (str, 0, evalcost);
907 cost = - cost;
908 if (str)
909 tputs (str, 10, evalcost);
910 return cost;
911}
912
913#ifndef old
914/* char_ins_del_cost[n] is cost of inserting N characters.
915 char_ins_del_cost[-n] is cost of deleting N characters. */
916
917int *char_ins_del_vector;
918
ff11dfa1 919#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH ((f))])
08a24c47
JB
920#endif
921
922/* ARGSUSED */
923static void
ff11dfa1
JB
924calculate_ins_del_char_costs (frame)
925 FRAME_PTR frame;
08a24c47
JB
926{
927 int ins_startup_cost, del_startup_cost;
928 int ins_cost_per_char, del_cost_per_char;
929 register int i;
930 register int *p;
931
932 if (TS_ins_multi_chars)
933 {
934 ins_cost_per_char = 0;
935 ins_startup_cost = string_cost_one_line (TS_ins_multi_chars);
936 }
937 else if (TS_ins_char || TS_pad_inserted_char
938 || (TS_insert_mode && TS_end_insert_mode))
939 {
940 ins_startup_cost = (30 * (string_cost (TS_insert_mode)
941 + string_cost (TS_end_insert_mode))) / 100;
942 ins_cost_per_char = (string_cost_one_line (TS_ins_char)
943 + string_cost_one_line (TS_pad_inserted_char));
944 }
945 else
946 {
947 ins_startup_cost = 9999;
948 ins_cost_per_char = 0;
949 }
950
951 if (TS_del_multi_chars)
952 {
953 del_cost_per_char = 0;
954 del_startup_cost = string_cost_one_line (TS_del_multi_chars);
955 }
956 else if (TS_del_char)
957 {
958 del_startup_cost = (string_cost (TS_delete_mode)
959 + string_cost (TS_end_delete_mode));
960 if (delete_in_insert_mode)
961 del_startup_cost /= 2;
962 del_cost_per_char = string_cost_one_line (TS_del_char);
963 }
964 else
965 {
966 del_startup_cost = 9999;
967 del_cost_per_char = 0;
968 }
969
970 /* Delete costs are at negative offsets */
ff11dfa1
JB
971 p = &char_ins_del_cost (frame)[0];
972 for (i = FRAME_WIDTH (selected_frame); --i >= 0;)
08a24c47
JB
973 *--p = (del_startup_cost += del_cost_per_char);
974
975 /* Doing nothing is free */
ff11dfa1 976 p = &char_ins_del_cost (frame)[0];
08a24c47
JB
977 *p++ = 0;
978
979 /* Insert costs are at positive offsets */
ff11dfa1 980 for (i = FRAME_WIDTH (frame); --i >= 0;)
08a24c47
JB
981 *p++ = (ins_startup_cost += ins_cost_per_char);
982}
983
984#ifdef HAVE_X_WINDOWS
e7308e06 985extern int x_screen_planes;
08a24c47
JB
986#endif
987
ff11dfa1
JB
988calculate_costs (frame)
989 FRAME_PTR frame;
08a24c47 990{
ff11dfa1 991 register char *f = TS_set_scroll_region ?
08a24c47
JB
992 TS_set_scroll_region
993 : TS_set_scroll_region_1;
994
995 if (dont_calculate_costs)
996 return;
997
998#ifdef HAVE_X_WINDOWS
ff11dfa1 999 if (FRAME_IS_X (frame))
08a24c47 1000 {
ff11dfa1 1001 do_line_insertion_deletion_costs (frame, 0, ".5*", 0, ".5*",
e7308e06 1002 0, 0, x_screen_planes);
08a24c47
JB
1003 return;
1004 }
1005#endif
1006
1007 /* These variables are only used for terminal stuff. They are allocated
ff11dfa1 1008 once for the terminal frame of X-windows emacs, but not used afterwards.
08a24c47
JB
1009
1010 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1011 X turns off char_ins_del_ok.
1012
1013 chars_wasted and copybuf are only used here in term.c in cases where
1014 the term hook isn't called. */
1015
1016 if (chars_wasted != 0)
ff11dfa1 1017 chars_wasted = (char *) xrealloc (chars_wasted, FRAME_HEIGHT (frame));
08a24c47 1018 else
ff11dfa1 1019 chars_wasted = (char *) xmalloc (FRAME_HEIGHT (frame));
08a24c47
JB
1020
1021 if (copybuf != 0)
ff11dfa1 1022 copybuf = (char *) xrealloc (copybuf, FRAME_HEIGHT (frame));
08a24c47 1023 else
ff11dfa1 1024 copybuf = (char *) xmalloc (FRAME_HEIGHT (frame));
08a24c47
JB
1025
1026 if (char_ins_del_vector != 0)
1027 char_ins_del_vector
1028 = (int *) xrealloc (char_ins_del_vector,
1029 (sizeof (int)
ff11dfa1 1030 + 2 * FRAME_WIDTH (frame) * sizeof (int)));
08a24c47
JB
1031 else
1032 char_ins_del_vector
1033 = (int *) xmalloc (sizeof (int)
ff11dfa1 1034 + 2 * FRAME_WIDTH (frame) * sizeof (int));
08a24c47 1035
ff11dfa1
JB
1036 bzero (chars_wasted, FRAME_HEIGHT (frame));
1037 bzero (copybuf, FRAME_HEIGHT (frame));
08a24c47 1038 bzero (char_ins_del_vector, (sizeof (int)
ff11dfa1 1039 + 2 * FRAME_WIDTH (frame) * sizeof (int)));
08a24c47 1040
ff11dfa1
JB
1041 if (f && (!TS_ins_line && !TS_del_line))
1042 do_line_insertion_deletion_costs (frame,
08a24c47
JB
1043 TS_rev_scroll, TS_ins_multi_lines,
1044 TS_fwd_scroll, TS_del_multi_lines,
ff11dfa1 1045 f, f, 1);
08a24c47 1046 else
ff11dfa1 1047 do_line_insertion_deletion_costs (frame,
08a24c47
JB
1048 TS_ins_line, TS_ins_multi_lines,
1049 TS_del_line, TS_del_multi_lines,
1050 0, 0, 1);
1051
ff11dfa1 1052 calculate_ins_del_char_costs (frame);
08a24c47
JB
1053
1054 /* Don't use TS_repeat if its padding is worse than sending the chars */
1055 if (TS_repeat && per_line_cost (TS_repeat) * baud_rate < 9000)
1056 RPov = string_cost (TS_repeat);
1057 else
ff11dfa1 1058 RPov = FRAME_WIDTH (frame) * 2;
08a24c47
JB
1059
1060 cmcostinit (); /* set up cursor motion costs */
1061}
1062\f
5c2c7893
JB
1063/* Find the escape codes sent by the function keys for Vfunction_key_map.
1064 This function scans the termcap function key sequence entries, and
1065 adds entries to Vfunction_key_map for each function key it finds. */
1066
1067void
1068term_get_fkeys (address)
1069 char **address;
1070{
1071 extern char *tgetstr ();
1072 struct fkey_table {
1073 char *cap, *name;
1074 };
1075 static struct fkey_table keys[] = {
1076 "kl", "left",
1077 "kr", "right",
1078 "ku", "up",
1079 "kd", "down",
1080 "kh", "home",
1081 "k1", "f1",
1082 "k2", "f2",
1083 "k3", "f3",
1084 "k4", "f4",
1085 "k5", "f5",
1086 "k6", "f6",
1087 "k7", "f7",
1088 "k8", "f8",
1089 "k9", "f9",
1090 "k0", "f10",
1091 "kH", "home-down",
1092 "ka", "clear-tabs",
1093 "kt", "clear-tab",
1094 "kT", "set-tab",
1095 "kC", "clear",
1096 "kL", "deleteline",
1097 "kM", "exit-insert",
1098 "kE", "clear-eol",
1099 "kS", "clear-eos",
1100 "kI", "insert",
1101 "kA", "insertline",
1102 "kN", "next",
1103 "kP", "prior",
1104 "kF", "scroll-forward",
1105 "kR", "scroll-reverse"
1106 };
1107 int i;
1108
1109 for (i = 0; i < (sizeof (keys)/sizeof (keys[0])); i++)
1110 {
1111 char *sequence = tgetstr (keys[i].cap, address);
1112 if (sequence)
1113 Fdefine_key (Vfunction_key_map,
1114 build_string (sequence),
1115 Fmake_vector (make_number (1), intern (keys[i].name)));
1116 }
1117}
1118
1119\f
08a24c47
JB
1120term_init (terminal_type)
1121 char *terminal_type;
1122{
1123 char *area;
1124 char **address = &area;
1125 char buffer[2044];
1126 register char *p;
1127 int status;
1128
1129 extern char *tgetstr ();
1130
1131 Wcm_clear ();
1132 dont_calculate_costs = 0;
1133
1134 status = tgetent (buffer, terminal_type);
1135 if (status < 0)
1136 fatal ("Cannot open termcap database file.\n");
1137 if (status == 0)
1138 fatal ("Terminal type %s is not defined.\n", terminal_type);
1139
1140#ifdef TERMINFO
1141 area = (char *) malloc (2044);
1142#else
1143 area = (char *) malloc (strlen (buffer));
1144#endif /* not TERMINFO */
1145 if (area == 0)
1146 abort ();
1147
1148 TS_ins_line = tgetstr ("al", address);
1149 TS_ins_multi_lines = tgetstr ("AL", address);
1150 TS_bell = tgetstr ("bl", address);
1151 BackTab = tgetstr ("bt", address);
1152 TS_clr_to_bottom = tgetstr ("cd", address);
1153 TS_clr_line = tgetstr ("ce", address);
ff11dfa1 1154 TS_clr_frame = tgetstr ("cl", address);
08a24c47
JB
1155 ColPosition = tgetstr ("ch", address);
1156 AbsPosition = tgetstr ("cm", address);
1157 CR = tgetstr ("cr", address);
1158 TS_set_scroll_region = tgetstr ("cs", address);
1159 TS_set_scroll_region_1 = tgetstr ("cS", address);
1160 RowPosition = tgetstr ("cv", address);
1161 TS_del_char = tgetstr ("dc", address);
1162 TS_del_multi_chars = tgetstr ("DC", address);
1163 TS_del_line = tgetstr ("dl", address);
1164 TS_del_multi_lines = tgetstr ("DL", address);
1165 TS_delete_mode = tgetstr ("dm", address);
1166 TS_end_delete_mode = tgetstr ("ed", address);
1167 TS_end_insert_mode = tgetstr ("ei", address);
1168 Home = tgetstr ("ho", address);
1169 TS_ins_char = tgetstr ("ic", address);
1170 TS_ins_multi_chars = tgetstr ("IC", address);
1171 TS_insert_mode = tgetstr ("im", address);
1172 TS_pad_inserted_char = tgetstr ("ip", address);
1173 TS_end_keypad_mode = tgetstr ("ke", address);
1174 TS_keypad_mode = tgetstr ("ks", address);
1175 LastLine = tgetstr ("ll", address);
1176 Right = tgetstr ("nd", address);
1177 Down = tgetstr ("do", address);
1178 if (!Down)
1179 Down = tgetstr ("nl", address); /* Obsolete name for "do" */
1180#ifdef VMS
1181 /* VMS puts a carriage return before each linefeed,
1182 so it is not safe to use linefeeds. */
1183 if (Down && Down[0] == '\n' && Down[1] == '\0')
1184 Down = 0;
1185#endif /* VMS */
1186 if (tgetflag ("bs"))
1187 Left = "\b"; /* can't possibly be longer! */
1188 else /* (Actually, "bs" is obsolete...) */
1189 Left = tgetstr ("le", address);
1190 if (!Left)
1191 Left = tgetstr ("bc", address); /* Obsolete name for "le" */
1192 TS_pad_char = tgetstr ("pc", address);
1193 TS_repeat = tgetstr ("rp", address);
1194 TS_end_standout_mode = tgetstr ("se", address);
1195 TS_fwd_scroll = tgetstr ("sf", address);
1196 TS_standout_mode = tgetstr ("so", address);
1197 TS_rev_scroll = tgetstr ("sr", address);
1198 Wcm.cm_tab = tgetstr ("ta", address);
1199 TS_end_termcap_modes = tgetstr ("te", address);
1200 TS_termcap_modes = tgetstr ("ti", address);
1201 Up = tgetstr ("up", address);
1202 TS_visible_bell = tgetstr ("vb", address);
1203 TS_end_visual_mode = tgetstr ("ve", address);
1204 TS_visual_mode = tgetstr ("vs", address);
1205 TS_set_window = tgetstr ("wi", address);
1206 MultiUp = tgetstr ("UP", address);
1207 MultiDown = tgetstr ("DO", address);
1208 MultiLeft = tgetstr ("LE", address);
1209 MultiRight = tgetstr ("RI", address);
1210
1211 AutoWrap = tgetflag ("am");
ff11dfa1 1212 memory_below_frame = tgetflag ("db");
08a24c47
JB
1213 TF_hazeltine = tgetflag ("hz");
1214 must_write_spaces = tgetflag ("in");
1215 meta_key = tgetflag ("km") || tgetflag ("MT");
1216 TF_insmode_motion = tgetflag ("mi");
1217 TF_standout_motion = tgetflag ("ms");
1218 TF_underscore = tgetflag ("ul");
1219 MagicWrap = tgetflag ("xn");
1220 TF_xs = tgetflag ("xs");
1221 TF_teleray = tgetflag ("xt");
1222
5c2c7893
JB
1223 term_get_fkeys (address);
1224
ff11dfa1
JB
1225 /* Get frame size from system, or else from termcap. */
1226 get_frame_size (&FRAME_WIDTH (selected_frame),
1227 &FRAME_HEIGHT (selected_frame));
1228 if (FRAME_WIDTH (selected_frame) <= 0)
1229 FRAME_WIDTH (selected_frame) = tgetnum ("co");
1230 if (FRAME_HEIGHT (selected_frame) <= 0)
1231 FRAME_HEIGHT (selected_frame) = tgetnum ("li");
08a24c47
JB
1232
1233 min_padding_speed = tgetnum ("pb");
1234 TN_standout_width = tgetnum ("sg");
1235 TabWidth = tgetnum ("tw");
1236
1237#ifdef VMS
1238 /* These capabilities commonly use ^J.
1239 I don't know why, but sending them on VMS does not work;
1240 it causes following spaces to be lost, sometimes.
1241 For now, the simplest fix is to avoid using these capabilities ever. */
1242 if (Down && Down[0] == '\n')
1243 Down = 0;
1244#endif /* VMS */
1245
1246 if (!TS_bell)
1247 TS_bell = "\07";
1248
1249 if (!TS_fwd_scroll)
1250 TS_fwd_scroll = Down;
1251
1252 PC = TS_pad_char ? *TS_pad_char : 0;
1253
1254 if (TabWidth < 0)
1255 TabWidth = 8;
1256
1257/* Turned off since /etc/termcap seems to have :ta= for most terminals
1258 and newer termcap doc does not seem to say there is a default.
1259 if (!Wcm.cm_tab)
1260 Wcm.cm_tab = "\t";
1261*/
1262
1263 if (TS_standout_mode == 0)
1264 {
1265 TN_standout_width = tgetnum ("ug");
1266 TS_end_standout_mode = tgetstr ("ue", address);
1267 TS_standout_mode = tgetstr ("us", address);
1268 }
1269
1270 if (TF_teleray)
1271 {
1272 Wcm.cm_tab = 0;
1273 /* Teleray: most programs want a space in front of TS_standout_mode,
1274 but Emacs can do without it (and give one extra column). */
1275 TS_standout_mode = "\033RD";
1276 TN_standout_width = 1;
1277 /* But that means we cannot rely on ^M to go to column zero! */
1278 CR = 0;
1279 /* LF can't be trusted either -- can alter hpos */
1280 /* if move at column 0 thru a line with TS_standout_mode */
1281 Down = 0;
1282 }
1283
1284 /* Special handling for certain terminal types known to need it */
1285
1286 if (!strcmp (terminal_type, "supdup"))
1287 {
ff11dfa1 1288 memory_below_frame = 1;
08a24c47
JB
1289 Wcm.cm_losewrap = 1;
1290 }
1291 if (!strncmp (terminal_type, "c10", 3)
1292 || !strcmp (terminal_type, "perq"))
1293 {
1294 /* Supply a makeshift :wi string.
1295 This string is not valid in general since it works only
1296 for windows starting at the upper left corner;
1297 but that is all Emacs uses.
1298
ff11dfa1 1299 This string works only if the frame is using
08a24c47
JB
1300 the top of the video memory, because addressing is memory-relative.
1301 So first check the :ti string to see if that is true.
1302
1303 It would be simpler if the :wi string could go in the termcap
1304 entry, but it can't because it is not fully valid.
1305 If it were in the termcap entry, it would confuse other programs. */
1306 if (!TS_set_window)
1307 {
1308 p = TS_termcap_modes;
1309 while (*p && strcmp (p, "\033v "))
1310 p++;
1311 if (*p)
1312 TS_set_window = "\033v%C %C %C %C ";
1313 }
1314 /* Termcap entry often fails to have :in: flag */
1315 must_write_spaces = 1;
1316 /* :ti string typically fails to have \E^G! in it */
1317 /* This limits scope of insert-char to one line. */
1318 strcpy (area, TS_termcap_modes);
1319 strcat (area, "\033\007!");
1320 TS_termcap_modes = area;
1321 area += strlen (area) + 1;
1322 p = AbsPosition;
1323 /* Change all %+ parameters to %C, to handle
1324 values above 96 correctly for the C100. */
1325 while (*p)
1326 {
1327 if (p[0] == '%' && p[1] == '+')
1328 p[1] = 'C';
1329 p++;
1330 }
1331 }
1332
ff11dfa1
JB
1333 FrameRows = FRAME_HEIGHT (selected_frame);
1334 FrameCols = FRAME_WIDTH (selected_frame);
1335 specified_window = FRAME_HEIGHT (selected_frame);
08a24c47
JB
1336
1337 if (Wcm_init () == -1) /* can't do cursor motion */
1338#ifdef VMS
1339 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1340It lacks the ability to position the cursor.\n\
1341If that is not the actual type of terminal you have, use either the\n\
1342DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
1343or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.\n",
1344 terminal_type);
1345#else
1346 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
1347It lacks the ability to position the cursor.\n\
1348If that is not the actual type of terminal you have,\n\
1349use the C-shell command `setenv TERM ...' to specify the correct type.\n\
1350It may be necessary to do `unsetenv TERMCAP' as well.\n",
1351 terminal_type);
1352#endif
ff11dfa1
JB
1353 if (FRAME_HEIGHT (selected_frame) <= 0
1354 || FRAME_WIDTH (selected_frame) <= 0)
1355 fatal ("The frame size has not been specified.");
08a24c47
JB
1356
1357 delete_in_insert_mode
1358 = TS_delete_mode && TS_insert_mode
1359 && !strcmp (TS_delete_mode, TS_insert_mode);
1360
1361 se_is_so = (TS_standout_mode
1362 && TS_end_standout_mode
1363 && !strcmp (TS_standout_mode, TS_end_standout_mode));
1364
1365 /* Remove width of standout marker from usable width of line */
1366 if (TN_standout_width > 0)
ff11dfa1 1367 FRAME_WIDTH (selected_frame) -= TN_standout_width;
08a24c47
JB
1368
1369 UseTabs = tabs_safe_p () && TabWidth == 8;
1370
1371 scroll_region_ok
1372 = (Wcm.cm_abs
1373 && (TS_set_window || TS_set_scroll_region || TS_set_scroll_region_1));
1374
1375 line_ins_del_ok = (((TS_ins_line || TS_ins_multi_lines)
1376 && (TS_del_line || TS_del_multi_lines))
1377 || (scroll_region_ok && TS_fwd_scroll && TS_rev_scroll));
1378
1379 char_ins_del_ok = ((TS_ins_char || TS_insert_mode
1380 || TS_pad_inserted_char || TS_ins_multi_chars)
1381 && (TS_del_char || TS_del_multi_chars));
1382
1383 fast_clear_end_of_line = TS_clr_line != 0;
1384
1385 init_baud_rate ();
1386 if (read_socket_hook) /* Baudrate is somewhat */
1387 /* meaningless in this case */
1388 baud_rate = 9600;
1389}
1390
1391/* VARARGS 1 */
1392fatal (str, arg1, arg2)
4746118a 1393 char *str, *arg1, *arg2;
08a24c47
JB
1394{
1395 fprintf (stderr, "emacs: ");
1396 fprintf (stderr, str, arg1, arg2);
1397 fflush (stderr);
1398 exit (1);
1399}