Merged from miles@gnu.org--gnu-2005 (patch 116-117, 544-550)
[bpt/emacs.git] / src / term.c
CommitLineData
d284f58f 1/* Terminal control module for terminals described by TERMCAP
0b5538bd
TTN
2 Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001,
3 2002, 2003, 2004, 2005 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
4fc5845f
LK
19the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20Boston, MA 02110-1301, USA. */
08a24c47 21
d284f58f 22/* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
08a24c47 23
565620a5 24#include <config.h>
08a24c47
JB
25#include <stdio.h>
26#include <ctype.h>
a168702a 27#include <string.h>
7ee72033 28
28d440ab
KL
29#include <sys/file.h>
30
0c72d684 31#include <unistd.h> /* For isatty. */
67ad74df
KL
32
33#if HAVE_TERMIOS_H
34#include <termios.h> /* For TIOCNOTTY. */
35#endif
03a1d6bd
KL
36
37#include <signal.h>
0c72d684 38
9628b887 39#include "lisp.h"
08a24c47
JB
40#include "termchar.h"
41#include "termopts.h"
a4decb7f
KH
42#include "charset.h"
43#include "coding.h"
2538fae4 44#include "keyboard.h"
ff11dfa1 45#include "frame.h"
08a24c47
JB
46#include "disptab.h"
47#include "termhooks.h"
dfcf069d 48#include "dispextern.h"
a168702a 49#include "window.h"
8feddab4 50#include "keymap.h"
03a1d6bd
KL
51#include "syssignal.h"
52#include "systty.h"
a168702a 53
ff23e1dd
GM
54/* For now, don't try to include termcap.h. On some systems,
55 configure finds a non-standard termcap.h that the main build
56 won't find. */
57
58#if defined HAVE_TERMCAP_H && 0
b0f61f15 59#include <termcap.h>
46d1b2bc
DL
60#else
61extern void tputs P_ ((const char *, int, int (*)(int)));
62extern int tgetent P_ ((char *, const char *));
63extern int tgetflag P_ ((char *id));
64extern int tgetnum P_ ((char *id));
b0f61f15
GM
65#endif
66
eccec691 67#include "cm.h"
dfcf069d
AS
68#ifdef HAVE_X_WINDOWS
69#include "xterm.h"
70#endif
e0f712ba 71#ifdef MAC_OS
1a578e9b
AC
72#include "macterm.h"
73#endif
c8951b18 74
28d440ab
KL
75#ifndef O_RDWR
76#define O_RDWR 2
77#endif
78
0c72d684
KL
79#ifndef O_NOCTTY
80#define O_NOCTTY 0
81#endif
82
a168702a
GM
83static void turn_on_face P_ ((struct frame *, int face_id));
84static void turn_off_face P_ ((struct frame *, int face_id));
28d7d09f
KL
85static void tty_show_cursor P_ ((struct tty_display_info *));
86static void tty_hide_cursor P_ ((struct tty_display_info *));
fca177d4 87
7e59217d 88void delete_initial_device P_ ((struct device *));
428a555e
KL
89void create_tty_output P_ ((struct frame *));
90void delete_tty_output P_ ((struct frame *));
a168702a 91
6548cf00
KL
92#define OUTPUT(tty, a) \
93 emacs_tputs ((tty), a, \
94 (int) (FRAME_LINES (XFRAME (selected_frame)) \
95 - curY (tty)), \
96 cmputc)
97
28d440ab
KL
98#define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
99#define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
a168702a 100
28d440ab 101#define OUTPUT_IF(tty, a) \
6548cf00
KL
102 do { \
103 if (a) \
104 emacs_tputs ((tty), a, \
105 (int) (FRAME_LINES (XFRAME (selected_frame)) \
106 - curY (tty) ), \
107 cmputc); \
108 } while (0)
177c0ea7 109
28d440ab 110#define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
08a24c47 111
f46c2aff
KS
112/* Display space properties */
113
114extern Lisp_Object Qspace, QCalign_to, QCwidth;
115
c291d9ef 116/* Function to use to ring the bell. */
a168702a 117
c291d9ef
RS
118Lisp_Object Vring_bell_function;
119
0b0d3e0b
KL
120/* Functions to call after suspending a tty. */
121Lisp_Object Vsuspend_tty_functions;
122
123/* Functions to call after resuming a tty. */
124Lisp_Object Vresume_tty_functions;
125
428a555e 126/* Chain of all displays currently in use. */
7e59217d 127struct device *device_list;
28d440ab 128
3224dac1 129/* The initial display device, created by initial_term_init. */
7e59217d 130struct device *initial_device;
3224dac1 131
428a555e 132/* Chain of all tty device parameters. */
28d7d09f 133struct tty_display_info *tty_list;
08a24c47 134
fca177d4
KL
135/* Nonzero means no need to redraw the entire frame on resuming a
136 suspended Emacs. This is useful on terminals with multiple
137 pages, where one page is used for Emacs and another for all
138 else. */
08a24c47 139int no_redraw_on_reenter;
819b8f00 140
4e6ba4a4
GM
141
142/* Meaning of bits in no_color_video. Each bit set means that the
143 corresponding attribute cannot be combined with colors. */
144
145enum no_color_bit
146{
147 NC_STANDOUT = 1 << 0,
148 NC_UNDERLINE = 1 << 1,
149 NC_REVERSE = 1 << 2,
150 NC_BLINK = 1 << 3,
151 NC_DIM = 1 << 4,
152 NC_BOLD = 1 << 5,
153 NC_INVIS = 1 << 6,
154 NC_PROTECT = 1 << 7,
155 NC_ALT_CHARSET = 1 << 8
156};
157
08a24c47
JB
158/* internal state */
159
8dd0c7cb 160/* The largest frame width in any call to calculate_costs. */
a168702a 161
9882535b 162int max_frame_cols;
a168702a 163
8dd0c7cb 164/* The largest frame height in any call to calculate_costs. */
a168702a 165
9882535b 166int max_frame_lines;
8dd0c7cb 167
0c72d684
KL
168/* Non-zero if we have dropped our controlling tty and therefore
169 should not open a frame on stdout. */
170static int no_controlling_tty;
171
b6660415 172/* The first unallocated display id. */
7e59217d 173static int next_device_id;
b6660415 174
07c57952 175/* Provided for lisp packages. */
a168702a 176
07c57952
KH
177static int system_uses_terminfo;
178
08a24c47 179char *tparam ();
e4bfb3b6
RS
180
181extern char *tgetstr ();
08a24c47 182\f
cb28b9c2 183
1a89b7c6
AI
184#ifdef WINDOWSNT
185/* We aren't X windows, but we aren't termcap either. This makes me
186 uncertain as to what value to use for frame.output_method. For
187 this file, we'll define FRAME_TERMCAP_P to be zero so that our
188 output hooks get called instead of the termcap functions. Probably
189 the best long-term solution is to define an output_windows_nt... */
190
191#undef FRAME_TERMCAP_P
192#define FRAME_TERMCAP_P(_f_) 0
193#endif /* WINDOWSNT */
194
dfcf069d 195void
385ed61f 196ring_bell (struct frame *f)
08a24c47 197{
d284f58f 198 if (!NILP (Vring_bell_function))
c291d9ef
RS
199 {
200 Lisp_Object function;
201
202 /* Temporarily set the global variable to nil
203 so that if we get an error, it stays nil
204 and we don't call it over and over.
205
206 We don't specbind it, because that would carefully
207 restore the bad value if there's an error
208 and make the loop of errors happen anyway. */
177c0ea7 209
c291d9ef
RS
210 function = Vring_bell_function;
211 Vring_bell_function = Qnil;
212
213 call0 (function);
214
215 Vring_bell_function = function;
08a24c47 216 }
7e59217d
KL
217 else if (FRAME_DEVICE (f)->ring_bell_hook)
218 (*FRAME_DEVICE (f)->ring_bell_hook) (f);
08a24c47
JB
219}
220
da8e1115
KL
221/* Ring the bell on a tty. */
222
3224dac1 223void
385ed61f 224tty_ring_bell (struct frame *f)
3224dac1 225{
3224dac1
KL
226 struct tty_display_info *tty = FRAME_TTY (f);
227
b6660415
KL
228 if (tty->output)
229 {
230 OUTPUT (tty, (tty->TS_visible_bell && visible_bell
231 ? tty->TS_visible_bell
232 : tty->TS_bell));
233 fflush (tty->output);
234 }
3224dac1
KL
235}
236
da8e1115
KL
237/* Set up termcap modes for Emacs. */
238
239void
7e59217d 240tty_set_terminal_modes (struct device *display)
fca177d4 241{
3224dac1
KL
242 struct tty_display_info *tty = display->display_info.tty;
243
0b0d3e0b
KL
244 if (tty->output)
245 {
fbf34973
KL
246 if (tty->TS_termcap_modes)
247 OUTPUT (tty, tty->TS_termcap_modes);
248 else
249 {
250 /* Output enough newlines to scroll all the old screen contents
251 off the screen, so it won't be overwritten and lost. */
252 int i;
253 for (i = 0; i < FRAME_LINES (XFRAME (selected_frame)); i++)
254 putchar ('\n');
255 }
256
0b0d3e0b
KL
257 OUTPUT_IF (tty, tty->TS_termcap_modes);
258 OUTPUT_IF (tty, tty->TS_cursor_visible);
259 OUTPUT_IF (tty, tty->TS_keypad_mode);
260 losecursor (tty);
2f98e6e3 261 fflush (tty->output);
0b0d3e0b 262 }
fca177d4
KL
263}
264
da8e1115
KL
265/* Reset termcap modes before exiting Emacs. */
266
267void
7e59217d 268tty_reset_terminal_modes (struct device *display)
fca177d4 269{
3224dac1 270 struct tty_display_info *tty = display->display_info.tty;
0b0d3e0b
KL
271
272 if (tty->output)
273 {
274 turn_off_highlight (tty);
275 turn_off_insert (tty);
276 OUTPUT_IF (tty, tty->TS_end_keypad_mode);
277 OUTPUT_IF (tty, tty->TS_cursor_normal);
278 OUTPUT_IF (tty, tty->TS_end_termcap_modes);
279 OUTPUT_IF (tty, tty->TS_orig_pair);
280 /* Output raw CR so kernel can track the cursor hpos. */
281 current_tty = tty;
282 cmputc ('\r');
2f98e6e3 283 fflush (tty->output);
0b0d3e0b 284 }
fca177d4
KL
285}
286
dfcf069d 287void
6839f1e2 288update_begin (struct frame *f)
08a24c47 289{
7e59217d
KL
290 if (FRAME_DEVICE (f)->update_begin_hook)
291 (*FRAME_DEVICE (f)->update_begin_hook) (f);
08a24c47
JB
292}
293
dfcf069d 294void
6839f1e2 295update_end (struct frame *f)
08a24c47 296{
7e59217d
KL
297 if (FRAME_DEVICE (f)->update_end_hook)
298 (*FRAME_DEVICE (f)->update_end_hook) (f);
08a24c47
JB
299}
300
da8e1115
KL
301/* Flag the end of a display update on a termcap display. */
302
3224dac1
KL
303void
304tty_update_end (struct frame *f)
305{
306 struct tty_display_info *tty = FRAME_TTY (f);
307
308 if (!XWINDOW (selected_window)->cursor_off_p)
309 tty_show_cursor (tty);
310 turn_off_insert (tty);
311 background_highlight (tty);
312}
313
da8e1115
KL
314/* Specify how many text lines, from the top of the window,
315 should be affected by insert-lines and delete-lines operations.
316 This, and those operations, are used only within an update
317 that is bounded by calls to update_begin and update_end. */
318
dfcf069d 319void
6839f1e2 320set_terminal_window (struct frame *f, int size)
08a24c47 321{
7e59217d
KL
322 if (FRAME_DEVICE (f)->set_terminal_window_hook)
323 (*FRAME_DEVICE (f)->set_terminal_window_hook) (f, size);
3224dac1
KL
324}
325
da8e1115
KL
326/* The implementation of set_terminal_window for termcap frames. */
327
3224dac1 328void
385ed61f 329tty_set_terminal_window (struct frame *f, int size)
3224dac1 330{
3224dac1
KL
331 struct tty_display_info *tty = FRAME_TTY (f);
332
333 tty->specified_window = size ? size : FRAME_LINES (f);
334 if (FRAME_SCROLL_REGION_OK (f))
385ed61f 335 set_scroll_region (f, 0, tty->specified_window);
08a24c47
JB
336}
337
dfcf069d 338void
6839f1e2 339set_scroll_region (struct frame *f, int start, int stop)
08a24c47
JB
340{
341 char *buf;
28d7d09f 342 struct tty_display_info *tty = FRAME_TTY (f);
177c0ea7 343
fca177d4
KL
344 if (tty->TS_set_scroll_region)
345 buf = tparam (tty->TS_set_scroll_region, 0, 0, start, stop - 1);
346 else if (tty->TS_set_scroll_region_1)
347 buf = tparam (tty->TS_set_scroll_region_1, 0, 0,
ed02974b
KL
348 FRAME_LINES (f), start,
349 FRAME_LINES (f) - stop,
350 FRAME_LINES (f));
08a24c47 351 else
fca177d4 352 buf = tparam (tty->TS_set_window, 0, 0, start, 0, stop, FRAME_COLS (f));
177c0ea7 353
6548cf00 354 OUTPUT (tty, buf);
9ac0d9e0 355 xfree (buf);
6548cf00 356 losecursor (tty);
08a24c47 357}
d284f58f 358
08a24c47 359\f
d284f58f 360static void
28d7d09f 361turn_on_insert (struct tty_display_info *tty)
08a24c47 362{
fca177d4
KL
363 if (!tty->insert_mode)
364 OUTPUT (tty, tty->TS_insert_mode);
365 tty->insert_mode = 1;
08a24c47
JB
366}
367
dfcf069d 368void
28d7d09f 369turn_off_insert (struct tty_display_info *tty)
08a24c47 370{
fca177d4
KL
371 if (tty->insert_mode)
372 OUTPUT (tty, tty->TS_end_insert_mode);
373 tty->insert_mode = 0;
08a24c47
JB
374}
375\f
54800acb 376/* Handle highlighting. */
08a24c47 377
dfcf069d 378void
28d7d09f 379turn_off_highlight (struct tty_display_info *tty)
08a24c47 380{
fca177d4
KL
381 if (tty->standout_mode)
382 OUTPUT_IF (tty, tty->TS_end_standout_mode);
383 tty->standout_mode = 0;
08a24c47
JB
384}
385
d284f58f 386static void
28d7d09f 387turn_on_highlight (struct tty_display_info *tty)
08a24c47 388{
fca177d4
KL
389 if (!tty->standout_mode)
390 OUTPUT_IF (tty, tty->TS_standout_mode);
391 tty->standout_mode = 1;
08a24c47
JB
392}
393
86a7d192 394static void
28d7d09f 395toggle_highlight (struct tty_display_info *tty)
86a7d192 396{
fca177d4
KL
397 if (tty->standout_mode)
398 turn_off_highlight (tty);
86a7d192 399 else
fca177d4 400 turn_on_highlight (tty);
86a7d192
GM
401}
402
a168702a
GM
403
404/* Make cursor invisible. */
405
406static void
28d7d09f 407tty_hide_cursor (struct tty_display_info *tty)
a168702a 408{
fca177d4 409 if (tty->cursor_hidden == 0)
d284f58f 410 {
fca177d4
KL
411 tty->cursor_hidden = 1;
412 OUTPUT_IF (tty, tty->TS_cursor_invisible);
d284f58f 413 }
a168702a
GM
414}
415
416
417/* Ensure that cursor is visible. */
418
419static void
28d7d09f 420tty_show_cursor (struct tty_display_info *tty)
a168702a 421{
fca177d4 422 if (tty->cursor_hidden)
d284f58f 423 {
fca177d4
KL
424 tty->cursor_hidden = 0;
425 OUTPUT_IF (tty, tty->TS_cursor_normal);
426 OUTPUT_IF (tty, tty->TS_cursor_visible);
d284f58f 427 }
a168702a
GM
428}
429
430
08a24c47
JB
431/* Set standout mode to the state it should be in for
432 empty space inside windows. What this is,
433 depends on the user option inverse-video. */
434
dfcf069d 435void
28d7d09f 436background_highlight (struct tty_display_info *tty)
08a24c47 437{
08a24c47 438 if (inverse_video)
fca177d4 439 turn_on_highlight (tty);
08a24c47 440 else
fca177d4 441 turn_off_highlight (tty);
08a24c47
JB
442}
443
444/* Set standout mode to the mode specified for the text to be output. */
445
dfcf069d 446static void
28d7d09f 447highlight_if_desired (struct tty_display_info *tty)
08a24c47 448{
8ede64a5 449 if (inverse_video)
fca177d4 450 turn_on_highlight (tty);
8ede64a5 451 else
fca177d4 452 turn_off_highlight (tty);
08a24c47
JB
453}
454\f
455
a168702a
GM
456/* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
457 frame-relative coordinates. */
08a24c47 458
dfcf069d 459void
6839f1e2 460cursor_to (struct frame *f, int vpos, int hpos)
08a24c47 461{
7e59217d
KL
462 if (FRAME_DEVICE (f)->cursor_to_hook)
463 (*FRAME_DEVICE (f)->cursor_to_hook) (f, vpos, hpos);
3224dac1 464}
08a24c47 465
3224dac1 466void
385ed61f 467tty_cursor_to (struct frame *f, int vpos, int hpos)
3224dac1 468{
3224dac1 469 struct tty_display_info *tty = FRAME_TTY (f);
6548cf00 470
36cae867
KH
471 /* Detect the case where we are called from reset_sys_modes
472 and the costs have never been calculated. Do nothing. */
fca177d4 473 if (! tty->costs_set)
36cae867
KH
474 return;
475
6548cf00
KL
476 if (curY (tty) == vpos
477 && curX (tty) == hpos)
08a24c47 478 return;
fca177d4
KL
479 if (!tty->TF_standout_motion)
480 background_highlight (tty);
481 if (!tty->TF_insmode_motion)
482 turn_off_insert (tty);
6548cf00 483 cmgoto (tty, vpos, hpos);
08a24c47
JB
484}
485
486/* Similar but don't take any account of the wasted characters. */
487
dfcf069d 488void
6839f1e2 489raw_cursor_to (struct frame *f, int row, int col)
08a24c47 490{
7e59217d
KL
491 if (FRAME_DEVICE (f)->raw_cursor_to_hook)
492 (*FRAME_DEVICE (f)->raw_cursor_to_hook) (f, row, col);
3224dac1
KL
493}
494
495void
385ed61f 496tty_raw_cursor_to (struct frame *f, int row, int col)
3224dac1 497{
3224dac1
KL
498 struct tty_display_info *tty = FRAME_TTY (f);
499
6548cf00
KL
500 if (curY (tty) == row
501 && curX (tty) == col)
08a24c47 502 return;
fca177d4
KL
503 if (!tty->TF_standout_motion)
504 background_highlight (tty);
505 if (!tty->TF_insmode_motion)
506 turn_off_insert (tty);
6548cf00 507 cmgoto (tty, row, col);
08a24c47
JB
508}
509\f
510/* Erase operations */
511
da8e1115 512/* Clear from cursor to end of frame. */
dfcf069d 513void
385ed61f 514clear_to_end (struct frame *f)
08a24c47 515{
7e59217d
KL
516 if (FRAME_DEVICE (f)->clear_to_end_hook)
517 (*FRAME_DEVICE (f)->clear_to_end_hook) (f);
3224dac1
KL
518}
519
da8e1115
KL
520/* Clear from cursor to end of frame on a termcap device. */
521
3224dac1 522void
385ed61f 523tty_clear_to_end (struct frame *f)
3224dac1
KL
524{
525 register int i;
3224dac1
KL
526 struct tty_display_info *tty = FRAME_TTY (f);
527
fca177d4 528 if (tty->TS_clr_to_bottom)
08a24c47 529 {
fca177d4
KL
530 background_highlight (tty);
531 OUTPUT (tty, tty->TS_clr_to_bottom);
08a24c47
JB
532 }
533 else
534 {
6548cf00 535 for (i = curY (tty); i < FRAME_LINES (f); i++)
08a24c47 536 {
385ed61f
KL
537 cursor_to (f, i, 0);
538 clear_end_of_line (f, FRAME_COLS (f));
08a24c47
JB
539 }
540 }
541}
542
ff11dfa1 543/* Clear entire frame */
08a24c47 544
dfcf069d 545void
385ed61f 546clear_frame (struct frame *f)
08a24c47 547{
7e59217d
KL
548 if (FRAME_DEVICE (f)->clear_frame_hook)
549 (*FRAME_DEVICE (f)->clear_frame_hook) (f);
3224dac1
KL
550}
551
da8e1115
KL
552/* Clear an entire termcap frame. */
553
3224dac1 554void
385ed61f 555tty_clear_frame (struct frame *f)
3224dac1 556{
3224dac1
KL
557 struct tty_display_info *tty = FRAME_TTY (f);
558
fca177d4 559 if (tty->TS_clr_frame)
08a24c47 560 {
fca177d4
KL
561 background_highlight (tty);
562 OUTPUT (tty, tty->TS_clr_frame);
6548cf00 563 cmat (tty, 0, 0);
08a24c47
JB
564 }
565 else
566 {
385ed61f
KL
567 cursor_to (f, 0, 0);
568 clear_to_end (f);
08a24c47
JB
569 }
570}
571
08a24c47
JB
572/* Clear from cursor to end of line.
573 Assume that the line is already clear starting at column first_unused_hpos.
08a24c47
JB
574
575 Note that the cursor may be moved, on terminals lacking a `ce' string. */
576
dfcf069d 577void
6839f1e2 578clear_end_of_line (struct frame *f, int first_unused_hpos)
08a24c47 579{
7e59217d
KL
580 if (FRAME_DEVICE (f)->clear_end_of_line_hook)
581 (*FRAME_DEVICE (f)->clear_end_of_line_hook) (f, first_unused_hpos);
0a125897 582}
6548cf00 583
da8e1115
KL
584/* An implementation of clear_end_of_line for termcap frames.
585
586 Note that the cursor may be moved, on terminals lacking a `ce' string. */
587
0a125897 588void
385ed61f 589tty_clear_end_of_line (struct frame *f, int first_unused_hpos)
0a125897
KL
590{
591 register int i;
3224dac1
KL
592 struct tty_display_info *tty = FRAME_TTY (f);
593
36cae867
KH
594 /* Detect the case where we are called from reset_sys_modes
595 and the costs have never been calculated. Do nothing. */
fca177d4 596 if (! tty->costs_set)
36cae867
KH
597 return;
598
6548cf00 599 if (curX (tty) >= first_unused_hpos)
08a24c47 600 return;
fca177d4
KL
601 background_highlight (tty);
602 if (tty->TS_clr_line)
08a24c47 603 {
fca177d4 604 OUTPUT1 (tty, tty->TS_clr_line);
08a24c47
JB
605 }
606 else
607 { /* have to do it the hard way */
fca177d4 608 turn_off_insert (tty);
08a24c47 609
a168702a 610 /* Do not write in last row last col with Auto-wrap on. */
6548cf00 611 if (AutoWrap (tty)
0a125897
KL
612 && curY (tty) == FrameRows (tty) - 1
613 && first_unused_hpos == FrameCols (tty))
08a24c47
JB
614 first_unused_hpos--;
615
6548cf00 616 for (i = curX (tty); i < first_unused_hpos; i++)
08a24c47 617 {
0b0d3e0b
KL
618 if (tty->termscript)
619 fputc (' ', tty->termscript);
620 fputc (' ', tty->output);
08a24c47 621 }
6548cf00 622 cmplus (tty, first_unused_hpos - curX (tty));
08a24c47
JB
623 }
624}
625\f
af645abf
KH
626/* Buffer to store the source and result of code conversion for terminal. */
627static unsigned char *encode_terminal_buf;
628/* Allocated size of the above buffer. */
629static int encode_terminal_bufsize;
a4decb7f 630
af645abf
KH
631/* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
632 Set CODING->produced to the byte-length of the resulting byte
633 sequence, and return a pointer to that byte sequence. */
a4decb7f 634
302db699 635unsigned char *
af645abf 636encode_terminal_code (src, src_len, coding)
a168702a 637 struct glyph *src;
a4decb7f 638 int src_len;
af645abf 639 struct coding_system *coding;
a4decb7f 640{
a168702a 641 struct glyph *src_start = src, *src_end = src + src_len;
085d5908 642 register GLYPH g;
af645abf
KH
643 unsigned char *buf;
644 int nchars, nbytes, required;
a4decb7f
KH
645 register int tlen = GLYPH_TABLE_LENGTH;
646 register Lisp_Object *tbase = GLYPH_TABLE_BASE;
6589fd67 647
af645abf
KH
648 /* Allocate sufficient size of buffer to store all characters in
649 multibyte-form. But, it may be enlarged on demand if
650 Vglyph_table contains a string. */
651 required = MAX_MULTIBYTE_LENGTH * src_len;
652 if (encode_terminal_bufsize < required)
653 {
af645abf
KH
654 if (encode_terminal_bufsize == 0)
655 encode_terminal_buf = xmalloc (required);
656 else
657 encode_terminal_buf = xrealloc (encode_terminal_buf, required);
d6d31e57 658 encode_terminal_bufsize = required;
af645abf 659 }
a4decb7f 660
af645abf
KH
661 buf = encode_terminal_buf;
662 nchars = 0;
a4decb7f
KH
663 while (src < src_end)
664 {
a4decb7f 665 /* We must skip glyphs to be padded for a wide character. */
a168702a 666 if (! CHAR_GLYPH_PADDING_P (*src))
a4decb7f 667 {
32de38e4
KH
668 g = GLYPH_FROM_CHAR_GLYPH (src[0]);
669
670 if (g < 0 || g >= tlen)
085d5908 671 {
32de38e4 672 /* This glyph doesn't has an entry in Vglyph_table. */
af645abf
KH
673 if (CHAR_VALID_P (src->u.ch, 0))
674 buf += CHAR_STRING (src->u.ch, buf);
32de38e4 675 else
af645abf
KH
676 *buf++ = SPACEGLYPH;
677 nchars++;
085d5908 678 }
32de38e4 679 else
a4decb7f 680 {
32de38e4 681 /* This glyph has an entry in Vglyph_table,
a4decb7f
KH
682 so process any alias before testing for simpleness. */
683 GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
32de38e4
KH
684
685 if (GLYPH_SIMPLE_P (tbase, tlen, g))
686 {
af645abf
KH
687 int c = FAST_GLYPH_CHAR (g);
688
689 if (CHAR_VALID_P (c, 0))
690 buf += CHAR_STRING (c, buf);
691 else
692 *buf++ = SPACEGLYPH;
693 nchars++;
32de38e4
KH
694 }
695 else
696 {
697 /* We have a string in Vglyph_table. */
af645abf
KH
698 Lisp_Object string;
699
700 string = tbase[g];
701 if (! STRING_MULTIBYTE (string))
702 string = string_to_multibyte (string);
703 nbytes = buf - encode_terminal_buf;
fd4a9f8f 704 if (encode_terminal_bufsize < nbytes + SBYTES (string))
af645abf
KH
705 {
706 encode_terminal_bufsize = nbytes + SBYTES (string);
707 encode_terminal_buf = xrealloc (encode_terminal_buf,
708 encode_terminal_bufsize);
709 buf = encode_terminal_buf + nbytes;
710 }
711 bcopy (SDATA (string), buf, SBYTES (string));
712 buf += SBYTES (string);
713 nchars += SCHARS (string);
32de38e4 714 }
171d7f24 715 }
a4decb7f
KH
716 }
717 src++;
718 }
177c0ea7 719
af645abf
KH
720 nbytes = buf - encode_terminal_buf;
721 coding->src_multibyte = 1;
722 coding->dst_multibyte = 0;
723 if (SYMBOLP (coding->pre_write_conversion)
724 && ! NILP (Ffboundp (coding->pre_write_conversion)))
725 {
726 run_pre_write_conversin_on_c_str (&encode_terminal_buf,
727 &encode_terminal_bufsize,
728 nchars, nbytes, coding);
729 nchars = coding->produced_char;
730 nbytes = coding->produced;
731 }
732 required = nbytes + encoding_buffer_size (coding, nbytes);
733 if (encode_terminal_bufsize < required)
734 {
735 encode_terminal_bufsize = required;
736 encode_terminal_buf = xrealloc (encode_terminal_buf, required);
737 }
a4decb7f 738
af645abf
KH
739 encode_coding (coding, encode_terminal_buf, encode_terminal_buf + nbytes,
740 nbytes, encode_terminal_bufsize - nbytes);
741 return encode_terminal_buf + nbytes;
a4decb7f
KH
742}
743
08a24c47 744
da8e1115
KL
745/* Output LEN glyphs starting at STRING at the nominal cursor position.
746 Advance the nominal cursor over the text. */
747
dfcf069d 748void
6839f1e2 749write_glyphs (struct frame *f, struct glyph *string, int len)
3224dac1 750{
7e59217d
KL
751 if (FRAME_DEVICE (f)->write_glyphs_hook)
752 (*FRAME_DEVICE (f)->write_glyphs_hook) (f, string, len);
3224dac1
KL
753}
754
da8e1115
KL
755/* An implementation of write_glyphs for termcap frames. */
756
3224dac1 757void
385ed61f 758tty_write_glyphs (struct frame *f, struct glyph *string, int len)
08a24c47 759{
af645abf
KH
760 unsigned char *conversion_buffer;
761 struct coding_system *coding;
08a24c47 762
3224dac1 763 struct tty_display_info *tty = FRAME_TTY (f);
6548cf00 764
fca177d4
KL
765 turn_off_insert (tty);
766 tty_hide_cursor (tty);
08a24c47 767
a168702a 768 /* Don't dare write in last column of bottom line, if Auto-Wrap,
ff11dfa1 769 since that would scroll the whole frame on some terminals. */
08a24c47 770
6548cf00
KL
771 if (AutoWrap (tty)
772 && curY (tty) + 1 == FRAME_LINES (f)
773 && (curX (tty) + len) == FRAME_COLS (f))
08a24c47 774 len --;
a4decb7f
KH
775 if (len <= 0)
776 return;
08a24c47 777
6548cf00 778 cmplus (tty, len);
177c0ea7 779
af645abf
KH
780 /* If terminal_coding does any conversion, use it, otherwise use
781 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
782 because it always return 1 if the member src_multibyte is 1. */
fad2f685
KL
783 coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK
784 ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding);
6589fd67
KH
785 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
786 the tail. */
af645abf 787 coding->mode &= ~CODING_MODE_LAST_BLOCK;
177c0ea7 788
a4decb7f 789 while (len > 0)
08a24c47 790 {
a168702a 791 /* Identify a run of glyphs with the same face. */
32de38e4 792 int face_id = string->face_id;
a168702a 793 int n;
177c0ea7 794
a168702a 795 for (n = 1; n < len; ++n)
32de38e4 796 if (string[n].face_id != face_id)
a168702a
GM
797 break;
798
799 /* Turn appearance modes of the face of the run on. */
fca177d4 800 highlight_if_desired (tty);
a168702a
GM
801 turn_on_face (f, face_id);
802
af645abf
KH
803 if (n == len)
804 /* This is the last run. */
805 coding->mode |= CODING_MODE_LAST_BLOCK;
806 conversion_buffer = encode_terminal_code (string, n, coding);
807 if (coding->produced > 0)
08a24c47 808 {
fad2f685
KL
809 fwrite (conversion_buffer, 1, coding->produced, tty->output);
810 if (ferror (tty->output))
811 clearerr (tty->output);
812 if (tty->termscript)
813 fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
08a24c47 814 }
af645abf
KH
815 len -= n;
816 string += n;
a168702a
GM
817
818 /* Turn appearance modes off. */
819 turn_off_face (f, face_id);
fca177d4 820 turn_off_highlight (tty);
a4decb7f 821 }
177c0ea7 822
6548cf00 823 cmcheckmagic (tty);
08a24c47
JB
824}
825
da8e1115
KL
826/* Insert LEN glyphs from START at the nominal cursor position.
827
828 If start is zero, insert blanks instead of a string at start */
177c0ea7 829
dfcf069d 830void
6839f1e2 831insert_glyphs (struct frame *f, struct glyph *start, int len)
08a24c47 832{
a4decb7f
KH
833 if (len <= 0)
834 return;
835
7e59217d
KL
836 if (FRAME_DEVICE (f)->insert_glyphs_hook)
837 (*FRAME_DEVICE (f)->insert_glyphs_hook) (f, start, len);
3224dac1 838}
a168702a 839
da8e1115
KL
840/* An implementation of insert_glyphs for termcap frames. */
841
3224dac1 842void
385ed61f 843tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
3224dac1
KL
844{
845 char *buf;
846 struct glyph *glyph = NULL;
af645abf
KH
847 unsigned char *conversion_buffer;
848 unsigned char space[1];
849 struct coding_system *coding;
3224dac1
KL
850
851 struct tty_display_info *tty = FRAME_TTY (f);
08a24c47 852
fca177d4 853 if (tty->TS_ins_multi_chars)
08a24c47 854 {
fca177d4 855 buf = tparam (tty->TS_ins_multi_chars, 0, 0, len);
6548cf00 856 OUTPUT1 (tty, buf);
9ac0d9e0 857 xfree (buf);
08a24c47 858 if (start)
385ed61f 859 write_glyphs (f, start, len);
08a24c47
JB
860 return;
861 }
862
fca177d4 863 turn_on_insert (tty);
6548cf00 864 cmplus (tty, len);
af645abf
KH
865
866 if (! start)
867 space[0] = SPACEGLYPH;
868
869 /* If terminal_coding does any conversion, use it, otherwise use
870 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
871 because it always return 1 if the member src_multibyte is 1. */
fad2f685
KL
872 coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK
873 ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding);
af645abf
KH
874 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
875 the tail. */
876 coding->mode &= ~CODING_MODE_LAST_BLOCK;
877
07109bf9 878 while (len-- > 0)
08a24c47 879 {
fca177d4 880 OUTPUT1_IF (tty, tty->TS_ins_char);
08a24c47 881 if (!start)
32de38e4 882 {
af645abf
KH
883 conversion_buffer = space;
884 coding->produced = 1;
32de38e4 885 }
08a24c47 886 else
08a24c47 887 {
fca177d4 888 highlight_if_desired (tty);
32de38e4 889 turn_on_face (f, start->face_id);
816be8b8 890 glyph = start;
a168702a 891 ++start;
a4decb7f
KH
892 /* We must open sufficient space for a character which
893 occupies more than one column. */
a168702a 894 while (len && CHAR_GLYPH_PADDING_P (*start))
a4decb7f 895 {
fca177d4 896 OUTPUT1_IF (tty, tty->TS_ins_char);
a4decb7f
KH
897 start++, len--;
898 }
a4decb7f 899
32de38e4
KH
900 if (len <= 0)
901 /* This is the last glyph. */
af645abf 902 coding->mode |= CODING_MODE_LAST_BLOCK;
32de38e4 903
fad2f685 904 conversion_buffer = encode_terminal_code (glyph, 1, coding);
32de38e4 905 }
a4decb7f 906
af645abf 907 if (coding->produced > 0)
08a24c47 908 {
fad2f685 909 fwrite (conversion_buffer, 1, coding->produced, tty->output);
0b0d3e0b
KL
910 if (ferror (tty->output))
911 clearerr (tty->output);
912 if (tty->termscript)
fad2f685 913 fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
08a24c47
JB
914 }
915
fca177d4 916 OUTPUT1_IF (tty, tty->TS_pad_inserted_char);
32de38e4 917 if (start)
65aa5e85
GM
918 {
919 turn_off_face (f, glyph->face_id);
fca177d4 920 turn_off_highlight (tty);
65aa5e85 921 }
9a6b6f92 922 }
177c0ea7 923
6548cf00 924 cmcheckmagic (tty);
08a24c47
JB
925}
926
da8e1115
KL
927/* Delete N glyphs at the nominal cursor position. */
928
dfcf069d 929void
6839f1e2 930delete_glyphs (struct frame *f, int n)
08a24c47 931{
7e59217d
KL
932 if (FRAME_DEVICE (f)->delete_glyphs_hook)
933 (*FRAME_DEVICE (f)->delete_glyphs_hook) (f, n);
3224dac1 934}
08a24c47 935
da8e1115
KL
936/* An implementation of delete_glyphs for termcap frames. */
937
3224dac1 938void
385ed61f 939tty_delete_glyphs (struct frame *f, int n)
3224dac1
KL
940{
941 char *buf;
942 register int i;
3224dac1
KL
943
944 struct tty_display_info *tty = FRAME_TTY (f);
6548cf00 945
fca177d4 946 if (tty->delete_in_insert_mode)
08a24c47 947 {
fca177d4 948 turn_on_insert (tty);
08a24c47
JB
949 }
950 else
951 {
fca177d4
KL
952 turn_off_insert (tty);
953 OUTPUT_IF (tty, tty->TS_delete_mode);
08a24c47 954 }
daf01701 955
fca177d4 956 if (tty->TS_del_multi_chars)
08a24c47 957 {
fca177d4 958 buf = tparam (tty->TS_del_multi_chars, 0, 0, n);
6548cf00 959 OUTPUT1 (tty, buf);
9ac0d9e0 960 xfree (buf);
08a24c47
JB
961 }
962 else
963 for (i = 0; i < n; i++)
fca177d4
KL
964 OUTPUT1 (tty, tty->TS_del_char);
965 if (!tty->delete_in_insert_mode)
966 OUTPUT_IF (tty, tty->TS_end_delete_mode);
08a24c47
JB
967}
968\f
969/* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
970
dfcf069d 971void
6839f1e2 972ins_del_lines (struct frame *f, int vpos, int n)
08a24c47 973{
7e59217d
KL
974 if (FRAME_DEVICE (f)->ins_del_lines_hook)
975 (*FRAME_DEVICE (f)->ins_del_lines_hook) (f, vpos, n);
3224dac1
KL
976}
977
da8e1115
KL
978/* An implementation of ins_del_lines for termcap frames. */
979
3224dac1 980void
385ed61f 981tty_ins_del_lines (struct frame *f, int vpos, int n)
3224dac1 982{
3224dac1
KL
983 struct tty_display_info *tty = FRAME_TTY (f);
984 char *multi = n > 0 ? tty->TS_ins_multi_lines : tty->TS_del_multi_lines;
985 char *single = n > 0 ? tty->TS_ins_line : tty->TS_del_line;
986 char *scroll = n > 0 ? tty->TS_rev_scroll : tty->TS_fwd_scroll;
987
988 register int i = n > 0 ? n : -n;
989 register char *buf;
990
991 /* If the lines below the insertion are being pushed
992 into the end of the window, this is the same as clearing;
993 and we know the lines are already clear, since the matching
994 deletion has already been done. So can ignore this. */
995 /* If the lines below the deletion are blank lines coming
996 out of the end of the window, don't bother,
997 as there will be a matching inslines later that will flush them. */
998 if (FRAME_SCROLL_REGION_OK (f)
999 && vpos + i >= tty->specified_window)
1000 return;
1001 if (!FRAME_MEMORY_BELOW_FRAME (f)
1002 && vpos + i >= FRAME_LINES (f))
1003 return;
1004
1005 if (multi)
08a24c47 1006 {
6839f1e2 1007 raw_cursor_to (f, vpos, 0);
3224dac1
KL
1008 background_highlight (tty);
1009 buf = tparam (multi, 0, 0, i);
1010 OUTPUT (tty, buf);
1011 xfree (buf);
1012 }
1013 else if (single)
1014 {
6839f1e2 1015 raw_cursor_to (f, vpos, 0);
3224dac1
KL
1016 background_highlight (tty);
1017 while (--i >= 0)
1018 OUTPUT (tty, single);
1019 if (tty->TF_teleray)
1020 curX (tty) = 0;
08a24c47 1021 }
08a24c47
JB
1022 else
1023 {
385ed61f 1024 set_scroll_region (f, vpos, tty->specified_window);
3224dac1 1025 if (n < 0)
6839f1e2 1026 raw_cursor_to (f, tty->specified_window - 1, 0);
08a24c47 1027 else
6839f1e2 1028 raw_cursor_to (f, vpos, 0);
3224dac1
KL
1029 background_highlight (tty);
1030 while (--i >= 0)
1031 OUTPUTL (tty, scroll, tty->specified_window - vpos);
385ed61f 1032 set_scroll_region (f, 0, tty->specified_window);
3224dac1
KL
1033 }
1034
1035 if (!FRAME_SCROLL_REGION_OK (f)
1036 && FRAME_MEMORY_BELOW_FRAME (f)
1037 && n < 0)
1038 {
385ed61f
KL
1039 cursor_to (f, FRAME_LINES (f) + n, 0);
1040 clear_to_end (f);
08a24c47
JB
1041 }
1042}
1043\f
1044/* Compute cost of sending "str", in characters,
1045 not counting any line-dependent padding. */
1046
1047int
6839f1e2 1048string_cost (char *str)
08a24c47
JB
1049{
1050 cost = 0;
1051 if (str)
1052 tputs (str, 0, evalcost);
1053 return cost;
1054}
1055
1056/* Compute cost of sending "str", in characters,
1057 counting any line-dependent padding at one line. */
1058
1059static int
6839f1e2 1060string_cost_one_line (char *str)
08a24c47
JB
1061{
1062 cost = 0;
1063 if (str)
1064 tputs (str, 1, evalcost);
1065 return cost;
1066}
1067
1068/* Compute per line amount of line-dependent padding,
1069 in tenths of characters. */
1070
1071int
6839f1e2 1072per_line_cost (char *str)
08a24c47
JB
1073{
1074 cost = 0;
1075 if (str)
1076 tputs (str, 0, evalcost);
1077 cost = - cost;
1078 if (str)
1079 tputs (str, 10, evalcost);
1080 return cost;
1081}
1082
1083#ifndef old
1084/* char_ins_del_cost[n] is cost of inserting N characters.
8dd0c7cb 1085 char_ins_del_cost[-n] is cost of deleting N characters.
9882535b 1086 The length of this vector is based on max_frame_cols. */
08a24c47
JB
1087
1088int *char_ins_del_vector;
1089
9882535b 1090#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
08a24c47
JB
1091#endif
1092
1093/* ARGSUSED */
1094static void
6839f1e2 1095calculate_ins_del_char_costs (struct frame *f)
08a24c47 1096{
28d7d09f 1097 struct tty_display_info *tty = FRAME_TTY (f);
08a24c47
JB
1098 int ins_startup_cost, del_startup_cost;
1099 int ins_cost_per_char, del_cost_per_char;
1100 register int i;
1101 register int *p;
1102
fca177d4 1103 if (tty->TS_ins_multi_chars)
08a24c47
JB
1104 {
1105 ins_cost_per_char = 0;
fca177d4 1106 ins_startup_cost = string_cost_one_line (tty->TS_ins_multi_chars);
08a24c47 1107 }
fca177d4
KL
1108 else if (tty->TS_ins_char || tty->TS_pad_inserted_char
1109 || (tty->TS_insert_mode && tty->TS_end_insert_mode))
08a24c47 1110 {
fca177d4
KL
1111 ins_startup_cost = (30 * (string_cost (tty->TS_insert_mode)
1112 + string_cost (tty->TS_end_insert_mode))) / 100;
1113 ins_cost_per_char = (string_cost_one_line (tty->TS_ins_char)
1114 + string_cost_one_line (tty->TS_pad_inserted_char));
08a24c47
JB
1115 }
1116 else
1117 {
1118 ins_startup_cost = 9999;
1119 ins_cost_per_char = 0;
1120 }
1121
fca177d4 1122 if (tty->TS_del_multi_chars)
08a24c47
JB
1123 {
1124 del_cost_per_char = 0;
fca177d4 1125 del_startup_cost = string_cost_one_line (tty->TS_del_multi_chars);
08a24c47 1126 }
fca177d4 1127 else if (tty->TS_del_char)
08a24c47 1128 {
fca177d4
KL
1129 del_startup_cost = (string_cost (tty->TS_delete_mode)
1130 + string_cost (tty->TS_end_delete_mode));
1131 if (tty->delete_in_insert_mode)
08a24c47 1132 del_startup_cost /= 2;
fca177d4 1133 del_cost_per_char = string_cost_one_line (tty->TS_del_char);
08a24c47
JB
1134 }
1135 else
1136 {
1137 del_startup_cost = 9999;
1138 del_cost_per_char = 0;
1139 }
1140
1141 /* Delete costs are at negative offsets */
fca177d4
KL
1142 p = &char_ins_del_cost (f)[0];
1143 for (i = FRAME_COLS (f); --i >= 0;)
08a24c47
JB
1144 *--p = (del_startup_cost += del_cost_per_char);
1145
1146 /* Doing nothing is free */
fca177d4 1147 p = &char_ins_del_cost (f)[0];
08a24c47
JB
1148 *p++ = 0;
1149
1150 /* Insert costs are at positive offsets */
fca177d4 1151 for (i = FRAME_COLS (f); --i >= 0;)
08a24c47
JB
1152 *p++ = (ins_startup_cost += ins_cost_per_char);
1153}
1154
dfcf069d 1155void
6839f1e2 1156calculate_costs (struct frame *frame)
08a24c47 1157{
9f732a77 1158 FRAME_COST_BAUD_RATE (frame) = baud_rate;
08a24c47 1159
28d440ab 1160 if (FRAME_TERMCAP_P (frame))
daf01701
KL
1161 {
1162 struct tty_display_info *tty = FRAME_TTY (frame);
1163 register char *f = (tty->TS_set_scroll_region
1164 ? tty->TS_set_scroll_region
1165 : tty->TS_set_scroll_region_1);
08a24c47 1166
daf01701 1167 FRAME_SCROLL_REGION_COST (frame) = string_cost (f);
08a24c47 1168
daf01701 1169 tty->costs_set = 1;
08a24c47 1170
daf01701
KL
1171 /* These variables are only used for terminal stuff. They are
1172 allocated once for the terminal frame of X-windows emacs, but not
1173 used afterwards.
8dd0c7cb 1174
daf01701
KL
1175 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1176 X turns off char_ins_del_ok. */
08a24c47 1177
daf01701
KL
1178 max_frame_lines = max (max_frame_lines, FRAME_LINES (frame));
1179 max_frame_cols = max (max_frame_cols, FRAME_COLS (frame));
08a24c47 1180
daf01701
KL
1181 if (char_ins_del_vector != 0)
1182 char_ins_del_vector
1183 = (int *) xrealloc (char_ins_del_vector,
1184 (sizeof (int)
1185 + 2 * max_frame_cols * sizeof (int)));
1186 else
1187 char_ins_del_vector
1188 = (int *) xmalloc (sizeof (int)
1189 + 2 * max_frame_cols * sizeof (int));
08a24c47 1190
daf01701
KL
1191 bzero (char_ins_del_vector, (sizeof (int)
1192 + 2 * max_frame_cols * sizeof (int)));
1193
1194
1195 if (f && (!tty->TS_ins_line && !tty->TS_del_line))
1196 do_line_insertion_deletion_costs (frame,
1197 tty->TS_rev_scroll, tty->TS_ins_multi_lines,
1198 tty->TS_fwd_scroll, tty->TS_del_multi_lines,
1199 f, f, 1);
1200 else
1201 do_line_insertion_deletion_costs (frame,
1202 tty->TS_ins_line, tty->TS_ins_multi_lines,
1203 tty->TS_del_line, tty->TS_del_multi_lines,
1204 0, 0, 1);
1205
1206 calculate_ins_del_char_costs (frame);
1207
1208 /* Don't use TS_repeat if its padding is worse than sending the chars */
1209 if (tty->TS_repeat && per_line_cost (tty->TS_repeat) * baud_rate < 9000)
1210 tty->RPov = string_cost (tty->TS_repeat);
1211 else
1212 tty->RPov = FRAME_COLS (frame) * 2;
08a24c47 1213
daf01701
KL
1214 cmcostinit (FRAME_TTY (frame)); /* set up cursor motion costs */
1215 }
08a24c47
JB
1216}
1217\f
a796ac82
JB
1218struct fkey_table {
1219 char *cap, *name;
1220};
1221
01d8deb0
ER
1222 /* Termcap capability names that correspond directly to X keysyms.
1223 Some of these (marked "terminfo") aren't supplied by old-style
1224 (Berkeley) termcap entries. They're listed in X keysym order;
1225 except we put the keypad keys first, so that if they clash with
1226 other keys (as on the IBM PC keyboard) they get overridden.
1227 */
1228
a168702a
GM
1229static struct fkey_table keys[] =
1230{
8103ad1a
PJ
1231 {"kh", "home"}, /* termcap */
1232 {"kl", "left"}, /* termcap */
1233 {"ku", "up"}, /* termcap */
1234 {"kr", "right"}, /* termcap */
1235 {"kd", "down"}, /* termcap */
1236 {"%8", "prior"}, /* terminfo */
1237 {"%5", "next"}, /* terminfo */
1238 {"@7", "end"}, /* terminfo */
1239 {"@1", "begin"}, /* terminfo */
1240 {"*6", "select"}, /* terminfo */
1241 {"%9", "print"}, /* terminfo */
1242 {"@4", "execute"}, /* terminfo --- actually the `command' key */
01d8deb0
ER
1243 /*
1244 * "insert" --- see below
1245 */
8103ad1a
PJ
1246 {"&8", "undo"}, /* terminfo */
1247 {"%0", "redo"}, /* terminfo */
1248 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1249 {"@0", "find"}, /* terminfo */
1250 {"@2", "cancel"}, /* terminfo */
1251 {"%1", "help"}, /* terminfo */
01d8deb0
ER
1252 /*
1253 * "break" goes here, but can't be reliably intercepted with termcap
1254 */
8103ad1a 1255 {"&4", "reset"}, /* terminfo --- actually `restart' */
01d8deb0
ER
1256 /*
1257 * "system" and "user" --- no termcaps
1258 */
8103ad1a
PJ
1259 {"kE", "clearline"}, /* terminfo */
1260 {"kA", "insertline"}, /* terminfo */
1261 {"kL", "deleteline"}, /* terminfo */
1262 {"kI", "insertchar"}, /* terminfo */
1263 {"kD", "deletechar"}, /* terminfo */
1264 {"kB", "backtab"}, /* terminfo */
01d8deb0
ER
1265 /*
1266 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1267 */
8103ad1a 1268 {"@8", "kp-enter"}, /* terminfo */
01d8deb0
ER
1269 /*
1270 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1271 * "kp-multiply", "kp-add", "kp-separator",
1272 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1273 * --- no termcaps for any of these.
1274 */
8103ad1a 1275 {"K4", "kp-1"}, /* terminfo */
01d8deb0
ER
1276 /*
1277 * "kp-2" --- no termcap
1278 */
8103ad1a 1279 {"K5", "kp-3"}, /* terminfo */
01d8deb0
ER
1280 /*
1281 * "kp-4" --- no termcap
1282 */
8103ad1a 1283 {"K2", "kp-5"}, /* terminfo */
01d8deb0
ER
1284 /*
1285 * "kp-6" --- no termcap
1286 */
8103ad1a 1287 {"K1", "kp-7"}, /* terminfo */
01d8deb0
ER
1288 /*
1289 * "kp-8" --- no termcap
1290 */
8103ad1a 1291 {"K3", "kp-9"}, /* terminfo */
01d8deb0
ER
1292 /*
1293 * "kp-equal" --- no termcap
1294 */
8103ad1a
PJ
1295 {"k1", "f1"},
1296 {"k2", "f2"},
1297 {"k3", "f3"},
1298 {"k4", "f4"},
1299 {"k5", "f5"},
1300 {"k6", "f6"},
1301 {"k7", "f7"},
1302 {"k8", "f8"},
60ec7b7e
DN
1303 {"k9", "f9"},
1304
1305 {"&0", "S-cancel"}, /*shifted cancel key*/
1306 {"&9", "S-begin"}, /*shifted begin key*/
1307 {"*0", "S-find"}, /*shifted find key*/
1308 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1309 {"*4", "S-delete"}, /*shifted delete-character key*/
1310 {"*7", "S-end"}, /*shifted end key*/
1311 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1312 {"#1", "S-help"}, /*shifted help key*/
1313 {"#2", "S-home"}, /*shifted home key*/
1314 {"#3", "S-insert"}, /*shifted insert-character key*/
1315 {"#4", "S-left"}, /*shifted left-arrow key*/
1316 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1317 {"%c", "S-next"}, /*shifted next key*/
1318 {"%e", "S-prior"}, /*shifted previous key*/
1319 {"%f", "S-print"}, /*shifted print key*/
1320 {"%g", "S-redo"}, /*shifted redo key*/
1321 {"%i", "S-right"}, /*shifted right-arrow key*/
1322 {"!3", "S-undo"} /*shifted undo key*/
a796ac82
JB
1323 };
1324
e7cf0fa0
KL
1325static char **term_get_fkeys_address;
1326static KBOARD *term_get_fkeys_kboard;
f2a00342 1327static Lisp_Object term_get_fkeys_1 ();
465db27b 1328
01d8deb0 1329/* Find the escape codes sent by the function keys for Vfunction_key_map.
177c0ea7 1330 This function scans the termcap function key sequence entries, and
01d8deb0
ER
1331 adds entries to Vfunction_key_map for each function key it finds. */
1332
5c2c7893 1333void
e7cf0fa0 1334term_get_fkeys (address, kboard)
5c2c7893 1335 char **address;
e7cf0fa0 1336 KBOARD *kboard;
f2a00342
RM
1337{
1338 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1339 errors during the call. The only errors should be from Fdefine_key
1340 when given a key sequence containing an invalid prefix key. If the
1341 termcap defines function keys which use a prefix that is already bound
1342 to a command by the default bindings, we should silently ignore that
1343 function key specification, rather than giving the user an error and
1344 refusing to run at all on such a terminal. */
1345
1346 extern Lisp_Object Fidentity ();
e7cf0fa0
KL
1347 term_get_fkeys_address = address;
1348 term_get_fkeys_kboard = kboard;
f2a00342
RM
1349 internal_condition_case (term_get_fkeys_1, Qerror, Fidentity);
1350}
1351
1352static Lisp_Object
1353term_get_fkeys_1 ()
5c2c7893 1354{
5c2c7893
JB
1355 int i;
1356
e7cf0fa0
KL
1357 char **address = term_get_fkeys_address;
1358 KBOARD *kboard = term_get_fkeys_kboard;
1359
3e65092f
RS
1360 /* This can happen if CANNOT_DUMP or with strange options. */
1361 if (!initialized)
ac09dc1e 1362 kboard->Vlocal_function_key_map = Fmake_sparse_keymap (Qnil);
3e65092f 1363
5c2c7893
JB
1364 for (i = 0; i < (sizeof (keys)/sizeof (keys[0])); i++)
1365 {
1366 char *sequence = tgetstr (keys[i].cap, address);
1367 if (sequence)
ac09dc1e 1368 Fdefine_key (kboard->Vlocal_function_key_map, build_string (sequence),
f2a00342
RM
1369 Fmake_vector (make_number (1),
1370 intern (keys[i].name)));
5c2c7893 1371 }
a796ac82
JB
1372
1373 /* The uses of the "k0" capability are inconsistent; sometimes it
1374 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
eb8c3be9 1375 We will attempt to politely accommodate both systems by testing for
a796ac82
JB
1376 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1377 */
1378 {
1379 char *k_semi = tgetstr ("k;", address);
1380 char *k0 = tgetstr ("k0", address);
1381 char *k0_name = "f10";
1382
1383 if (k_semi)
1384 {
95c11956
SM
1385 if (k0)
1386 /* Define f0 first, so that f10 takes precedence in case the
1387 key sequences happens to be the same. */
ac09dc1e 1388 Fdefine_key (kboard->Vlocal_function_key_map, build_string (k0),
95c11956 1389 Fmake_vector (make_number (1), intern ("f0")));
ac09dc1e 1390 Fdefine_key (kboard->Vlocal_function_key_map, build_string (k_semi),
f2a00342 1391 Fmake_vector (make_number (1), intern ("f10")));
a796ac82 1392 }
95c11956 1393 else if (k0)
ac09dc1e 1394 Fdefine_key (kboard->Vlocal_function_key_map, build_string (k0),
f2a00342 1395 Fmake_vector (make_number (1), intern (k0_name)));
a796ac82 1396 }
01d8deb0
ER
1397
1398 /* Set up cookies for numbered function keys above f10. */
1399 {
1400 char fcap[3], fkey[4];
1401
fc4f24da 1402 fcap[0] = 'F'; fcap[2] = '\0';
01d8deb0
ER
1403 for (i = 11; i < 64; i++)
1404 {
1405 if (i <= 19)
1406 fcap[1] = '1' + i - 11;
1407 else if (i <= 45)
b59ab95c 1408 fcap[1] = 'A' + i - 20;
01d8deb0 1409 else
b59ab95c 1410 fcap[1] = 'a' + i - 46;
01d8deb0 1411
fc4f24da
RS
1412 {
1413 char *sequence = tgetstr (fcap, address);
1414 if (sequence)
1415 {
465db27b 1416 sprintf (fkey, "f%d", i);
ac09dc1e 1417 Fdefine_key (kboard->Vlocal_function_key_map, build_string (sequence),
f2a00342
RM
1418 Fmake_vector (make_number (1),
1419 intern (fkey)));
fc4f24da
RS
1420 }
1421 }
01d8deb0
ER
1422 }
1423 }
1424
1425 /*
1426 * Various mappings to try and get a better fit.
1427 */
1428 {
fc4f24da
RS
1429#define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1430 if (!tgetstr (cap1, address)) \
1431 { \
1432 char *sequence = tgetstr (cap2, address); \
e7cf0fa0 1433 if (sequence) \
ac09dc1e 1434 Fdefine_key (kboard->Vlocal_function_key_map, build_string (sequence), \
e7cf0fa0
KL
1435 Fmake_vector (make_number (1), \
1436 intern (sym))); \
fc4f24da 1437 }
177c0ea7 1438
01d8deb0 1439 /* if there's no key_next keycap, map key_npage to `next' keysym */
27b61785 1440 CONDITIONAL_REASSIGN ("%5", "kN", "next");
01d8deb0 1441 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
381d11a1 1442 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
01d8deb0 1443 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
27b61785 1444 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
403c995b
RS
1445 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1446 CONDITIONAL_REASSIGN ("@7", "kH", "end");
0a7f697a
KH
1447
1448 /* IBM has their own non-standard dialect of terminfo.
1449 If the standard name isn't found, try the IBM name. */
1450 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1451 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1452 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1453 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1454 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1455 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1456 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1457 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1458 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1dd40212 1459#undef CONDITIONAL_REASSIGN
01d8deb0 1460 }
a168702a
GM
1461
1462 return Qnil;
5c2c7893
JB
1463}
1464
1465\f
a168702a
GM
1466/***********************************************************************
1467 Character Display Information
1468 ***********************************************************************/
1469
1470static void append_glyph P_ ((struct it *));
f46c2aff 1471static void produce_stretch_glyph P_ ((struct it *));
a168702a
GM
1472
1473
1474/* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1475 terminal frames if IT->glyph_row != NULL. IT->c is the character
1476 for which to produce glyphs; IT->face_id contains the character's
1477 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1478 1. */
177c0ea7 1479
a168702a
GM
1480static void
1481append_glyph (it)
1482 struct it *it;
1483{
1484 struct glyph *glyph, *end;
1485 int i;
1486
1487 xassert (it->glyph_row);
1488 glyph = (it->glyph_row->glyphs[it->area]
1489 + it->glyph_row->used[it->area]);
1490 end = it->glyph_row->glyphs[1 + it->area];
1491
177c0ea7
JB
1492 for (i = 0;
1493 i < it->pixel_width && glyph < end;
a168702a
GM
1494 ++i)
1495 {
1496 glyph->type = CHAR_GLYPH;
d13f3e2e 1497 glyph->pixel_width = 1;
32de38e4
KH
1498 glyph->u.ch = it->c;
1499 glyph->face_id = it->face_id;
1500 glyph->padding_p = i > 0;
a168702a
GM
1501 glyph->charpos = CHARPOS (it->position);
1502 glyph->object = it->object;
177c0ea7 1503
a168702a
GM
1504 ++it->glyph_row->used[it->area];
1505 ++glyph;
1506 }
1507}
1508
1509
b50fe468
RS
1510/* Produce glyphs for the display element described by IT. *IT
1511 specifies what we want to produce a glyph for (character, image, ...),
1512 and where in the glyph matrix we currently are (glyph row and hpos).
1513 produce_glyphs fills in output fields of *IT with information such as the
1514 pixel width and height of a character, and maybe output actual glyphs at
a168702a 1515 the same time if IT->glyph_row is non-null. See the explanation of
b50fe468
RS
1516 struct display_iterator in dispextern.h for an overview.
1517
1518 produce_glyphs also stores the result of glyph width, ascent
1519 etc. computations in *IT.
1520
1521 IT->glyph_row may be null, in which case produce_glyphs does not
1522 actually fill in the glyphs. This is used in the move_* functions
1523 in xdisp.c for text width and height computations.
1524
1525 Callers usually don't call produce_glyphs directly;
1526 instead they use the macro PRODUCE_GLYPHS. */
a168702a 1527
177c0ea7 1528void
a168702a
GM
1529produce_glyphs (it)
1530 struct it *it;
1531{
1532 /* If a hook is installed, let it do the work. */
1533 xassert (it->what == IT_CHARACTER
c7cba11d 1534 || it->what == IT_COMPOSITION
a168702a 1535 || it->what == IT_STRETCH);
177c0ea7 1536
f46c2aff
KS
1537 if (it->what == IT_STRETCH)
1538 {
1539 produce_stretch_glyph (it);
1540 goto done;
1541 }
1542
c7cba11d
KH
1543 /* Nothing but characters are supported on terminal frames. For a
1544 composition sequence, it->c is the first character of the
1545 sequence. */
1546 xassert (it->what == IT_CHARACTER
1547 || it->what == IT_COMPOSITION);
a168702a
GM
1548
1549 if (it->c >= 040 && it->c < 0177)
1550 {
1551 it->pixel_width = it->nglyphs = 1;
1552 if (it->glyph_row)
1553 append_glyph (it);
1554 }
1555 else if (it->c == '\n')
1556 it->pixel_width = it->nglyphs = 0;
1557 else if (it->c == '\t')
1558 {
2efdbcdd 1559 int absolute_x = (it->current_x
a168702a 1560 + it->continuation_lines_width);
177c0ea7
JB
1561 int next_tab_x
1562 = (((1 + absolute_x + it->tab_width - 1)
a168702a
GM
1563 / it->tab_width)
1564 * it->tab_width);
1565 int nspaces;
1566
1567 /* If part of the TAB has been displayed on the previous line
1568 which is continued now, continuation_lines_width will have
1569 been incremented already by the part that fitted on the
1570 continued line. So, we will get the right number of spaces
1571 here. */
1572 nspaces = next_tab_x - absolute_x;
177c0ea7 1573
a168702a
GM
1574 if (it->glyph_row)
1575 {
1576 int n = nspaces;
177c0ea7 1577
a168702a
GM
1578 it->c = ' ';
1579 it->pixel_width = it->len = 1;
177c0ea7 1580
a168702a
GM
1581 while (n--)
1582 append_glyph (it);
177c0ea7 1583
a168702a
GM
1584 it->c = '\t';
1585 }
1586
1587 it->pixel_width = nspaces;
1588 it->nglyphs = nspaces;
1589 }
add44890
EZ
1590 else if (SINGLE_BYTE_CHAR_P (it->c))
1591 {
cf872af5 1592 /* Coming here means that it->c is from display table, thus we
add44890
EZ
1593 must send the code as is to the terminal. Although there's
1594 no way to know how many columns it occupies on a screen, it
1595 is a good assumption that a single byte code has 1-column
1596 width. */
1597 it->pixel_width = it->nglyphs = 1;
1598 if (it->glyph_row)
1599 append_glyph (it);
1600 }
a168702a
GM
1601 else
1602 {
c7cba11d
KH
1603 /* A multi-byte character. The display width is fixed for all
1604 characters of the set. Some of the glyphs may have to be
1605 ignored because they are already displayed in a continued
1606 line. */
a168702a
GM
1607 int charset = CHAR_CHARSET (it->c);
1608
c7cba11d 1609 it->pixel_width = CHARSET_WIDTH (charset);
a168702a 1610 it->nglyphs = it->pixel_width;
177c0ea7 1611
a168702a
GM
1612 if (it->glyph_row)
1613 append_glyph (it);
1614 }
1615
f46c2aff 1616 done:
177c0ea7 1617 /* Advance current_x by the pixel width as a convenience for
a168702a
GM
1618 the caller. */
1619 if (it->area == TEXT_AREA)
1620 it->current_x += it->pixel_width;
cfe8a05e
GM
1621 it->ascent = it->max_ascent = it->phys_ascent = it->max_phys_ascent = 0;
1622 it->descent = it->max_descent = it->phys_descent = it->max_phys_descent = 1;
a168702a
GM
1623}
1624
1625
f46c2aff
KS
1626/* Produce a stretch glyph for iterator IT. IT->object is the value
1627 of the glyph property displayed. The value must be a list
1628 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1629 being recognized:
1630
1631 1. `:width WIDTH' specifies that the space should be WIDTH *
1632 canonical char width wide. WIDTH may be an integer or floating
1633 point number.
1634
1635 2. `:align-to HPOS' specifies that the space should be wide enough
1636 to reach HPOS, a value in canonical character units. */
1637
1638static void
1639produce_stretch_glyph (it)
1640 struct it *it;
1641{
1642 /* (space :width WIDTH ...) */
1643 Lisp_Object prop, plist;
1644 int width = 0, align_to = -1;
1645 int zero_width_ok_p = 0;
1646 double tem;
1647
1648 /* List should start with `space'. */
1649 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
1650 plist = XCDR (it->object);
1651
1652 /* Compute the width of the stretch. */
1653 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
1654 && calc_pixel_width_or_height (&tem, it, prop, 0, 1, 0))
1655 {
1656 /* Absolute width `:width WIDTH' specified and valid. */
1657 zero_width_ok_p = 1;
1658 width = (int)(tem + 0.5);
1659 }
1660 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
1661 && calc_pixel_width_or_height (&tem, it, prop, 0, 1, &align_to))
1662 {
1663 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
1664 align_to = (align_to < 0
1665 ? 0
1666 : align_to - window_box_left_offset (it->w, TEXT_AREA));
1667 else if (align_to < 0)
1668 align_to = window_box_left_offset (it->w, TEXT_AREA);
1669 width = max (0, (int)(tem + 0.5) + align_to - it->current_x);
1670 zero_width_ok_p = 1;
1671 }
1672 else
1673 /* Nothing specified -> width defaults to canonical char width. */
1674 width = FRAME_COLUMN_WIDTH (it->f);
1675
1676 if (width <= 0 && (width < 0 || !zero_width_ok_p))
1677 width = 1;
1678
1679 if (width > 0 && it->glyph_row)
1680 {
1681 Lisp_Object o_object = it->object;
1682 Lisp_Object object = it->stack[it->sp - 1].string;
1683 int n = width;
1684 int c = it->c;
1685
1686 if (!STRINGP (object))
1687 object = it->w->buffer;
1688 it->object = object;
1689 it->c = ' ';
1690 it->pixel_width = it->len = 1;
1691 while (n--)
1692 append_glyph (it);
1693 it->object = o_object;
1694 it->c = c;
1695 }
1696 it->pixel_width = width;
1697 it->nglyphs = width;
1698}
1699
1700
a168702a
GM
1701/* Get information about special display element WHAT in an
1702 environment described by IT. WHAT is one of IT_TRUNCATION or
1703 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1704 non-null glyph_row member. This function ensures that fields like
1705 face_id, c, len of IT are left untouched. */
1706
1707void
1708produce_special_glyphs (it, what)
1709 struct it *it;
1710 enum display_element_type what;
1711{
1712 struct it temp_it;
072d84a6 1713 GLYPH glyph;
177c0ea7 1714
a168702a
GM
1715 temp_it = *it;
1716 temp_it.dp = NULL;
1717 temp_it.what = IT_CHARACTER;
1718 temp_it.len = 1;
7c752c80 1719 temp_it.object = make_number (0);
a168702a
GM
1720 bzero (&temp_it.current, sizeof temp_it.current);
1721
1722 if (what == IT_CONTINUATION)
1723 {
1724 /* Continuation glyph. */
1725 if (it->dp
1726 && INTEGERP (DISP_CONTINUE_GLYPH (it->dp))
1727 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it->dp))))
1728 {
072d84a6
RS
1729 glyph = XINT (DISP_CONTINUE_GLYPH (it->dp));
1730 glyph = spec_glyph_lookup_face (XWINDOW (it->window), glyph);
a168702a
GM
1731 }
1732 else
072d84a6 1733 glyph = '\\';
a168702a
GM
1734 }
1735 else if (what == IT_TRUNCATION)
1736 {
1737 /* Truncation glyph. */
1738 if (it->dp
1739 && INTEGERP (DISP_TRUNC_GLYPH (it->dp))
1740 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it->dp))))
1741 {
072d84a6
RS
1742 glyph = XINT (DISP_TRUNC_GLYPH (it->dp));
1743 glyph = spec_glyph_lookup_face (XWINDOW (it->window), glyph);
a168702a
GM
1744 }
1745 else
072d84a6 1746 glyph = '$';
a168702a
GM
1747 }
1748 else
1749 abort ();
072d84a6
RS
1750
1751 temp_it.c = FAST_GLYPH_CHAR (glyph);
1752 temp_it.face_id = FAST_GLYPH_FACE (glyph);
1753 temp_it.len = CHAR_BYTES (temp_it.c);
1754
1755 produce_glyphs (&temp_it);
1756 it->pixel_width = temp_it.pixel_width;
1757 it->nglyphs = temp_it.pixel_width;
a168702a
GM
1758}
1759
1760
a168702a
GM
1761\f
1762/***********************************************************************
1763 Faces
1764 ***********************************************************************/
1765
4e6ba4a4
GM
1766/* Value is non-zero if attribute ATTR may be used. ATTR should be
1767 one of the enumerators from enum no_color_bit, or a bit set built
1768 from them. Some display attributes may not be used together with
1769 color; the termcap capability `NC' specifies which ones. */
1770
fca177d4
KL
1771#define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1772 (tty->TN_max_colors > 0 \
1773 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1774 : 1)
a168702a 1775
072d84a6
RS
1776/* Turn appearances of face FACE_ID on tty frame F on.
1777 FACE_ID is a realized face ID number, in the face cache. */
a168702a
GM
1778
1779static void
1780turn_on_face (f, face_id)
1781 struct frame *f;
1782 int face_id;
1783{
1784 struct face *face = FACE_FROM_ID (f, face_id);
86a7d192
GM
1785 long fg = face->foreground;
1786 long bg = face->background;
28d7d09f 1787 struct tty_display_info *tty = FRAME_TTY (f);
a168702a 1788
86a7d192
GM
1789 /* Do this first because TS_end_standout_mode may be the same
1790 as TS_exit_attribute_mode, which turns all appearances off. */
fca177d4 1791 if (MAY_USE_WITH_COLORS_P (tty, NC_REVERSE))
86a7d192 1792 {
fca177d4 1793 if (tty->TN_max_colors > 0)
86a7d192
GM
1794 {
1795 if (fg >= 0 && bg >= 0)
1796 {
1797 /* If the terminal supports colors, we can set them
1798 below without using reverse video. The face's fg
1799 and bg colors are set as they should appear on
1800 the screen, i.e. they take the inverse-video'ness
1801 of the face already into account. */
1802 }
1803 else if (inverse_video)
1804 {
1805 if (fg == FACE_TTY_DEFAULT_FG_COLOR
1806 || bg == FACE_TTY_DEFAULT_BG_COLOR)
fca177d4 1807 toggle_highlight (tty);
86a7d192
GM
1808 }
1809 else
1810 {
1811 if (fg == FACE_TTY_DEFAULT_BG_COLOR
1812 || bg == FACE_TTY_DEFAULT_FG_COLOR)
fca177d4 1813 toggle_highlight (tty);
86a7d192
GM
1814 }
1815 }
1816 else
1817 {
1818 /* If we can't display colors, use reverse video
1819 if the face specifies that. */
37526b42
GM
1820 if (inverse_video)
1821 {
1822 if (fg == FACE_TTY_DEFAULT_FG_COLOR
1823 || bg == FACE_TTY_DEFAULT_BG_COLOR)
fca177d4 1824 toggle_highlight (tty);
37526b42
GM
1825 }
1826 else
1827 {
1828 if (fg == FACE_TTY_DEFAULT_BG_COLOR
1829 || bg == FACE_TTY_DEFAULT_FG_COLOR)
fca177d4 1830 toggle_highlight (tty);
37526b42 1831 }
86a7d192
GM
1832 }
1833 }
a168702a
GM
1834
1835 if (face->tty_bold_p)
4e6ba4a4 1836 {
fca177d4
KL
1837 if (MAY_USE_WITH_COLORS_P (tty, NC_BOLD))
1838 OUTPUT1_IF (tty, tty->TS_enter_bold_mode);
4e6ba4a4 1839 }
a168702a 1840 else if (face->tty_dim_p)
fca177d4
KL
1841 if (MAY_USE_WITH_COLORS_P (tty, NC_DIM))
1842 OUTPUT1_IF (tty, tty->TS_enter_dim_mode);
a168702a
GM
1843
1844 /* Alternate charset and blinking not yet used. */
4e6ba4a4 1845 if (face->tty_alt_charset_p
fca177d4
KL
1846 && MAY_USE_WITH_COLORS_P (tty, NC_ALT_CHARSET))
1847 OUTPUT1_IF (tty, tty->TS_enter_alt_charset_mode);
a168702a 1848
4e6ba4a4 1849 if (face->tty_blinking_p
fca177d4
KL
1850 && MAY_USE_WITH_COLORS_P (tty, NC_BLINK))
1851 OUTPUT1_IF (tty, tty->TS_enter_blink_mode);
a168702a 1852
fca177d4
KL
1853 if (face->tty_underline_p && MAY_USE_WITH_COLORS_P (tty, NC_UNDERLINE))
1854 OUTPUT1_IF (tty, tty->TS_enter_underline_mode);
a168702a 1855
fca177d4 1856 if (tty->TN_max_colors > 0)
a168702a 1857 {
753d161b 1858 char *ts, *p;
177c0ea7 1859
fbf34973 1860 ts = tty->standout_mode ? tty->TS_set_background : tty->TS_set_foreground;
753d161b 1861 if (fg >= 0 && ts)
a168702a 1862 {
fbf34973 1863 p = tparam (ts, NULL, 0, (int) fg);
6548cf00 1864 OUTPUT (tty, p);
a168702a
GM
1865 xfree (p);
1866 }
1867
fbf34973 1868 ts = tty->standout_mode ? tty->TS_set_foreground : tty->TS_set_background;
753d161b 1869 if (bg >= 0 && ts)
a168702a 1870 {
fbf34973 1871 p = tparam (ts, NULL, 0, (int) bg);
6548cf00 1872 OUTPUT (tty, p);
a168702a
GM
1873 xfree (p);
1874 }
1875 }
1876}
177c0ea7 1877
a168702a
GM
1878
1879/* Turn off appearances of face FACE_ID on tty frame F. */
1880
1881static void
1882turn_off_face (f, face_id)
1883 struct frame *f;
1884 int face_id;
1885{
1886 struct face *face = FACE_FROM_ID (f, face_id);
28d7d09f 1887 struct tty_display_info *tty = FRAME_TTY (f);
a168702a
GM
1888
1889 xassert (face != NULL);
1890
fca177d4 1891 if (tty->TS_exit_attribute_mode)
a168702a
GM
1892 {
1893 /* Capability "me" will turn off appearance modes double-bright,
1894 half-bright, reverse-video, standout, underline. It may or
1895 may not turn off alt-char-mode. */
1896 if (face->tty_bold_p
1897 || face->tty_dim_p
1898 || face->tty_reverse_p
1899 || face->tty_alt_charset_p
1900 || face->tty_blinking_p
1901 || face->tty_underline_p)
65aa5e85 1902 {
fca177d4
KL
1903 OUTPUT1_IF (tty, tty->TS_exit_attribute_mode);
1904 if (strcmp (tty->TS_exit_attribute_mode, tty->TS_end_standout_mode) == 0)
1905 tty->standout_mode = 0;
65aa5e85 1906 }
a168702a
GM
1907
1908 if (face->tty_alt_charset_p)
fca177d4 1909 OUTPUT_IF (tty, tty->TS_exit_alt_charset_mode);
a168702a
GM
1910 }
1911 else
1912 {
1913 /* If we don't have "me" we can only have those appearances
1914 that have exit sequences defined. */
1915 if (face->tty_alt_charset_p)
fca177d4 1916 OUTPUT_IF (tty, tty->TS_exit_alt_charset_mode);
a168702a 1917
54800acb 1918 if (face->tty_underline_p)
fca177d4 1919 OUTPUT_IF (tty, tty->TS_exit_underline_mode);
a168702a
GM
1920 }
1921
1922 /* Switch back to default colors. */
fca177d4 1923 if (tty->TN_max_colors > 0
f9d2fdc4
EZ
1924 && ((face->foreground != FACE_TTY_DEFAULT_COLOR
1925 && face->foreground != FACE_TTY_DEFAULT_FG_COLOR)
1926 || (face->background != FACE_TTY_DEFAULT_COLOR
1927 && face->background != FACE_TTY_DEFAULT_BG_COLOR)))
fca177d4 1928 OUTPUT1_IF (tty, tty->TS_orig_pair);
a168702a 1929}
177c0ea7
JB
1930
1931
b63a55ac
MB
1932/* Return non-zero if the terminal on frame F supports all of the
1933 capabilities in CAPS simultaneously, with foreground and background
1934 colors FG and BG. */
1935
4a8130f2 1936int
fca177d4 1937tty_capable_p (tty, caps, fg, bg)
28d7d09f 1938 struct tty_display_info *tty;
b63a55ac
MB
1939 unsigned caps;
1940 unsigned long fg, bg;
1941{
fca177d4
KL
1942#define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
1943 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
b63a55ac
MB
1944 return 0;
1945
fca177d4
KL
1946 TTY_CAPABLE_P_TRY (tty, TTY_CAP_INVERSE, tty->TS_standout_mode, NC_REVERSE);
1947 TTY_CAPABLE_P_TRY (tty, TTY_CAP_UNDERLINE, tty->TS_enter_underline_mode, NC_UNDERLINE);
1948 TTY_CAPABLE_P_TRY (tty, TTY_CAP_BOLD, tty->TS_enter_bold_mode, NC_BOLD);
1949 TTY_CAPABLE_P_TRY (tty, TTY_CAP_DIM, tty->TS_enter_dim_mode, NC_DIM);
1950 TTY_CAPABLE_P_TRY (tty, TTY_CAP_BLINK, tty->TS_enter_blink_mode, NC_BLINK);
1951 TTY_CAPABLE_P_TRY (tty, TTY_CAP_ALT_CHARSET, tty->TS_enter_alt_charset_mode, NC_ALT_CHARSET);
b63a55ac
MB
1952
1953 /* We can do it! */
1954 return 1;
1955}
1956
a168702a
GM
1957/* Return non-zero if the terminal is capable to display colors. */
1958
1959DEFUN ("tty-display-color-p", Ftty_display_color_p, Stty_display_color_p,
981e4297 1960 0, 1, 0,
7e59217d
KL
1961 doc: /* Return non-nil if the display device DEVICE can display colors.
1962DEVICE must be a tty device. */)
1963 (device)
1964 Lisp_Object device;
a168702a 1965{
7e59217d 1966 struct device *d = get_tty_device (device);
3224dac1 1967 if (!d)
428a555e 1968 return Qnil;
3224dac1
KL
1969 else
1970 return d->display_info.tty->TN_max_colors > 0 ? Qt : Qnil;
a168702a
GM
1971}
1972
bfa62f96
EZ
1973/* Return the number of supported colors. */
1974DEFUN ("tty-display-color-cells", Ftty_display_color_cells,
1975 Stty_display_color_cells, 0, 1, 0,
7e59217d
KL
1976 doc: /* Return the number of colors supported by the tty device DEVICE. */)
1977 (device)
1978 Lisp_Object device;
bfa62f96 1979{
7e59217d 1980 struct device *d = get_tty_device (device);
3224dac1 1981 if (!d)
8c8d5f35 1982 return make_number (0);
3224dac1
KL
1983 else
1984 return make_number (d->display_info.tty->TN_max_colors);
bfa62f96
EZ
1985}
1986
ace28297 1987#ifndef WINDOWSNT
a168702a 1988
ace28297
EZ
1989/* Save or restore the default color-related capabilities of this
1990 terminal. */
1991static void
28d7d09f 1992tty_default_color_capabilities (struct tty_display_info *tty, int save)
ace28297
EZ
1993{
1994 static char
1995 *default_orig_pair, *default_set_foreground, *default_set_background;
1996 static int default_max_colors, default_max_pairs, default_no_color_video;
1997
1998 if (save)
1999 {
2000 if (default_orig_pair)
2001 xfree (default_orig_pair);
fca177d4 2002 default_orig_pair = tty->TS_orig_pair ? xstrdup (tty->TS_orig_pair) : NULL;
ace28297
EZ
2003
2004 if (default_set_foreground)
2005 xfree (default_set_foreground);
fca177d4 2006 default_set_foreground = tty->TS_set_foreground ? xstrdup (tty->TS_set_foreground)
ace28297
EZ
2007 : NULL;
2008
2009 if (default_set_background)
2010 xfree (default_set_background);
fca177d4 2011 default_set_background = tty->TS_set_background ? xstrdup (tty->TS_set_background)
ace28297
EZ
2012 : NULL;
2013
fca177d4
KL
2014 default_max_colors = tty->TN_max_colors;
2015 default_max_pairs = tty->TN_max_pairs;
2016 default_no_color_video = tty->TN_no_color_video;
ace28297
EZ
2017 }
2018 else
2019 {
fca177d4
KL
2020 tty->TS_orig_pair = default_orig_pair;
2021 tty->TS_set_foreground = default_set_foreground;
2022 tty->TS_set_background = default_set_background;
2023 tty->TN_max_colors = default_max_colors;
2024 tty->TN_max_pairs = default_max_pairs;
2025 tty->TN_no_color_video = default_no_color_video;
ace28297
EZ
2026 }
2027}
2028
2029/* Setup one of the standard tty color schemes according to MODE.
2030 MODE's value is generally the number of colors which we want to
2031 support; zero means set up for the default capabilities, the ones
a4c6993d 2032 we saw at init_tty time; -1 means turn off color support. */
ace28297 2033void
28d7d09f 2034tty_setup_colors (struct tty_display_info *tty, int mode)
ace28297 2035{
40409f05
EZ
2036 /* Canonicalize all negative values of MODE. */
2037 if (mode < -1)
2038 mode = -1;
2039
ace28297
EZ
2040 switch (mode)
2041 {
2042 case -1: /* no colors at all */
fca177d4
KL
2043 tty->TN_max_colors = 0;
2044 tty->TN_max_pairs = 0;
2045 tty->TN_no_color_video = 0;
2046 tty->TS_set_foreground = tty->TS_set_background = tty->TS_orig_pair = NULL;
ace28297
EZ
2047 break;
2048 case 0: /* default colors, if any */
2049 default:
fca177d4 2050 tty_default_color_capabilities (tty, 0);
ace28297
EZ
2051 break;
2052 case 8: /* 8 standard ANSI colors */
fca177d4 2053 tty->TS_orig_pair = "\033[0m";
ace28297 2054#ifdef TERMINFO
fca177d4
KL
2055 tty->TS_set_foreground = "\033[3%p1%dm";
2056 tty->TS_set_background = "\033[4%p1%dm";
ace28297 2057#else
fca177d4
KL
2058 tty->TS_set_foreground = "\033[3%dm";
2059 tty->TS_set_background = "\033[4%dm";
ace28297 2060#endif
fca177d4
KL
2061 tty->TN_max_colors = 8;
2062 tty->TN_max_pairs = 64;
2063 tty->TN_no_color_video = 0;
ace28297
EZ
2064 break;
2065 }
2066}
2067
2068void
2069set_tty_color_mode (f, val)
2070 struct frame *f;
2071 Lisp_Object val;
2072{
dfc7a077 2073 Lisp_Object color_mode_spec, current_mode_spec;
ace28297
EZ
2074 Lisp_Object color_mode, current_mode;
2075 int mode, old_mode;
2076 extern Lisp_Object Qtty_color_mode;
2077 Lisp_Object tty_color_mode_alist;
2078
2079 tty_color_mode_alist = Fintern_soft (build_string ("tty-color-mode-alist"),
2080 Qnil);
2081
9ac61a89 2082 if (INTEGERP (val))
ace28297
EZ
2083 color_mode = val;
2084 else
2085 {
2086 if (NILP (tty_color_mode_alist))
2087 color_mode_spec = Qnil;
2088 else
2089 color_mode_spec = Fassq (val, XSYMBOL (tty_color_mode_alist)->value);
ace28297
EZ
2090
2091 if (CONSP (color_mode_spec))
2092 color_mode = XCDR (color_mode_spec);
2093 else
2094 color_mode = Qnil;
2095 }
545d91d5
RS
2096
2097 current_mode_spec = assq_no_quit (Qtty_color_mode, f->param_alist);
2098
ace28297
EZ
2099 if (CONSP (current_mode_spec))
2100 current_mode = XCDR (current_mode_spec);
2101 else
2102 current_mode = Qnil;
9ac61a89 2103 if (INTEGERP (color_mode))
ace28297
EZ
2104 mode = XINT (color_mode);
2105 else
2106 mode = 0; /* meaning default */
9ac61a89 2107 if (INTEGERP (current_mode))
ace28297
EZ
2108 old_mode = XINT (current_mode);
2109 else
2110 old_mode = 0;
2111
2112 if (mode != old_mode)
2113 {
fca177d4 2114 tty_setup_colors (FRAME_TTY (f), mode);
ace28297
EZ
2115 /* This recomputes all the faces given the new color
2116 definitions. */
2117 call0 (intern ("tty-set-up-initial-frame-faces"));
2118 redraw_frame (f);
2119 }
2120}
2121
2122#endif /* !WINDOWSNT */
a168702a
GM
2123
2124\f
28d440ab 2125
7e59217d 2126/* Return the display object specified by DEVICE. DEVICE may be a
b6660415 2127 display id, a frame, or nil for the display device of the current
68bba4e4
KL
2128 frame. If THROW is zero, return NULL for failure, otherwise throw
2129 an error. */
b6660415 2130
7e59217d
KL
2131struct device *
2132get_device (Lisp_Object device, int throw)
b6660415 2133{
7e59217d 2134 struct device *result = NULL;
68bba4e4 2135
7e59217d
KL
2136 if (NILP (device))
2137 device = selected_frame;
b6660415 2138
7e59217d 2139 if (INTEGERP (device))
b6660415 2140 {
7e59217d 2141 struct device *d;
b6660415 2142
7e59217d 2143 for (d = device_list; d; d = d->next_device)
b6660415 2144 {
7e59217d 2145 if (d->id == XINT (device))
68bba4e4
KL
2146 {
2147 result = d;
2148 break;
2149 }
b6660415 2150 }
b6660415 2151 }
7e59217d 2152 else if (FRAMEP (device))
b6660415 2153 {
7e59217d 2154 result = FRAME_DEVICE (XFRAME (device));
b6660415 2155 }
68bba4e4
KL
2156
2157 if (result == NULL && throw)
7e59217d 2158 wrong_type_argument (Qdisplay_live_p, device);
68bba4e4
KL
2159
2160 return result;
b6660415
KL
2161}
2162
7e59217d 2163/* Return the tty display object specified by DEVICE. */
b6660415 2164
62af879c
KL
2165struct device *
2166get_tty_device (Lisp_Object terminal)
b6660415 2167{
62af879c
KL
2168 struct device *d = get_device (terminal, 0);
2169
d7e4838f
KL
2170 if (d && d->type == output_initial)
2171 d = NULL;
2172
b6660415 2173 if (d && d->type != output_termcap)
7e59217d 2174 error ("Device %d is not a termcap display device", d->id);
b6660415
KL
2175
2176 return d;
2177}
2178
7e59217d
KL
2179/* Return the active termcap device that uses the tty device with the
2180 given name. If NAME is NULL, return the device corresponding to
b6660415
KL
2181 our controlling terminal.
2182
7e59217d 2183 This function ignores suspended devices.
da8e1115
KL
2184
2185 Returns NULL if the named terminal device is not opened. */
2186
7e59217d
KL
2187struct device *
2188get_named_tty (name)
28d440ab
KL
2189 char *name;
2190{
7e59217d 2191 struct device *d;
428a555e 2192
7e59217d 2193 for (d = device_list; d; d = d->next_device) {
428a555e
KL
2194 if (d->type == output_termcap
2195 && ((d->display_info.tty->name == 0 && name == 0)
2196 || (name && d->display_info.tty->name
b6660415 2197 && !strcmp (d->display_info.tty->name, name)))
7e59217d 2198 && DEVICE_ACTIVE_P (d))
428a555e 2199 return d;
28d440ab
KL
2200 };
2201
2202 return 0;
2203}
2204
2205\f
819b8f00 2206
b6660415 2207DEFUN ("display-name", Fdisplay_name, Sdisplay_name, 0, 1, 0,
7e59217d
KL
2208 doc: /* Return the name of the display device DEVICE.
2209It is not guaranteed that the returned value is unique among opened devices.
819b8f00 2210
7e59217d
KL
2211DEVICE may be a display device id, a frame, or nil (meaning the
2212selected frame's display device). */)
2213 (device)
2214 Lisp_Object device;
b6660415 2215{
7e59217d 2216 struct device *d = get_device (device, 1);
819b8f00 2217
b6660415
KL
2218 if (d->name)
2219 return build_string (d->name);
819b8f00
KL
2220 else
2221 return Qnil;
2222}
2223
b6660415 2224DEFUN ("display-tty-type", Fdisplay_tty_type, Sdisplay_tty_type, 0, 1, 0,
7e59217d 2225 doc: /* Return the type of the tty device that DEVICE uses.
a3fbb897 2226
7e59217d
KL
2227DEVICE may be a display device id, a frame, or nil (meaning the
2228selected frame's display device). */)
2229 (device)
2230 Lisp_Object device;
b6660415 2231{
7e59217d 2232 struct device *d = get_device (device, 1);
819b8f00 2233
b6660415
KL
2234 if (d->type != output_termcap)
2235 error ("Display %d is not a termcap display", d->id);
2236
2237 if (d->display_info.tty->type)
2238 return build_string (d->display_info.tty->type);
819b8f00
KL
2239 else
2240 return Qnil;
2241}
2242
4a933ef8 2243DEFUN ("display-controlling-tty-p", Fdisplay_controlling_tty_p, Sdisplay_controlling_tty_p, 0, 1, 0,
7e59217d 2244 doc: /* Return non-nil if DEVICE is on the controlling tty of the Emacs process.
a3fbb897 2245
7e59217d
KL
2246DEVICE may be a display device id, a frame, or nil (meaning the
2247selected frame's display device). */)
2248 (device)
2249 Lisp_Object device;
4a933ef8 2250{
7e59217d 2251 struct device *d = get_device (device, 1);
4a933ef8
KL
2252
2253 if (d->type != output_termcap || d->display_info.tty->name)
2254 return Qnil;
2255 else
2256 return Qt;
2257}
2258
a3fbb897 2259DEFUN ("tty-no-underline", Ftty_no_underline, Stty_no_underline, 0, 1, 0,
7e59217d 2260 doc: /* Declare that the tty used by DEVICE does not handle underlining.
a3fbb897
KL
2261This is used to override the terminfo data, for certain terminals that
2262do not really do underlining, but say that they do. This function has
2263no effect if used on a non-tty display.
2264
7e59217d
KL
2265DEVICE may be a display device id, a frame, or nil (meaning the
2266selected frame's display device). */)
2267 (device)
2268 Lisp_Object device;
a3fbb897 2269{
7e59217d 2270 struct device *d = get_device (device, 1);
a3fbb897
KL
2271
2272 if (d->type == output_termcap)
2273 d->display_info.tty->TS_enter_underline_mode = 0;
2274 return Qnil;
2275}
2276
2277
819b8f00 2278\f
a168702a
GM
2279/***********************************************************************
2280 Initialization
2281 ***********************************************************************/
2282
3224dac1 2283/* Create the bootstrap display device for the initial frame.
7e59217d 2284 Returns a device of type output_initial. */
3224dac1 2285
7e59217d
KL
2286struct device *
2287init_initial_device (void)
28d440ab 2288{
7e59217d 2289 if (initialized || device_list || tty_list)
428a555e
KL
2290 abort ();
2291
7e59217d
KL
2292 initial_device = create_device ();
2293 initial_device->type = output_initial;
2294 initial_device->name = xstrdup ("initial_device");
2295 initial_device->kboard = initial_kboard;
b6660415 2296
7e59217d 2297 initial_device->delete_device_hook = &delete_initial_device;
3224dac1 2298 /* All other hooks are NULL. */
bedb9c0e 2299
7e59217d 2300 return initial_device;
3224dac1
KL
2301}
2302
2303/* Deletes the bootstrap display device.
7e59217d 2304 Called through delete_device_hook. */
da8e1115 2305
3224dac1 2306void
7e59217d 2307delete_initial_device (struct device *device)
3224dac1 2308{
7e59217d 2309 if (device != initial_device)
3224dac1
KL
2310 abort ();
2311
7e59217d
KL
2312 delete_device (device);
2313 initial_device = NULL;
28d440ab
KL
2314}
2315
03a1d6bd
KL
2316/* Drop the controlling terminal if fd is the same device. */
2317void
2318dissociate_if_controlling_tty (int fd)
2319{
03a1d6bd 2320 int pgid;
8516815b 2321 EMACS_GET_TTY_PGRP (fd, &pgid); /* If tcgetpgrp succeeds, fd is the ctty. */
03a1d6bd
KL
2322 if (pgid != -1)
2323 {
8516815b 2324#if defined (USG) && !defined (BSD_PGRPS)
03a1d6bd
KL
2325 setpgrp ();
2326 no_controlling_tty = 1;
03a1d6bd
KL
2327#else
2328#ifdef TIOCNOTTY /* Try BSD ioctls. */
8516815b
KL
2329 sigblock (sigmask (SIGTTOU));
2330 fd = emacs_open ("/dev/tty", O_RDWR, 0);
2331 if (fd != -1 && ioctl (fd, TIOCNOTTY, 0) != -1)
2332 {
2333 no_controlling_tty = 1;
2334 }
2335 if (fd != -1)
2336 emacs_close (fd);
2337 sigunblock (sigmask (SIGTTOU));
03a1d6bd 2338#else
8516815b
KL
2339 /* Unknown system. */
2340 croak ();
03a1d6bd
KL
2341#endif /* ! TIOCNOTTY */
2342#endif /* ! USG */
71a96040 2343 }
03a1d6bd
KL
2344}
2345
520c4dfd
KL
2346static void maybe_fatal();
2347
3224dac1
KL
2348/* Create a termcap display on the tty device with the given name and
2349 type.
2350
2351 If NAME is NULL, then use the controlling tty, i.e., stdin/stdout.
2352 Otherwise NAME should be a path to the tty device file,
2353 e.g. "/dev/pts/7".
28d440ab 2354
3224dac1
KL
2355 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
2356
2357 If MUST_SUCCEED is true, then all errors are fatal. */
da8e1115 2358
7e59217d 2359struct device *
a4c6993d 2360init_tty (char *name, char *terminal_type, int must_succeed)
08a24c47
JB
2361{
2362 char *area;
2363 char **address = &area;
3a06a6d9 2364 char *buffer = NULL;
5846981b 2365 int buffer_size = 4096;
08a24c47
JB
2366 register char *p;
2367 int status;
28d7d09f 2368 struct tty_display_info *tty;
7e59217d 2369 struct device *device;
28d440ab 2370
3224dac1
KL
2371 if (!terminal_type)
2372 maybe_fatal (must_succeed, 0, 0,
2373 "Unknown terminal type",
2374 "Unknown terminal type");
b6660415 2375
7e59217d
KL
2376 /* If we already have a display on the given device, use that. If
2377 all such displays are suspended, create a new one instead. */
a4c6993d 2378 /* XXX Perhaps this should be made explicit by having init_tty
7e59217d 2379 always create a new display and separating device and frame
b6660415 2380 creation on Lisp level. */
7e59217d
KL
2381 device = get_named_tty (name);
2382 if (device)
2383 return device;
428a555e 2384
7e59217d 2385 device = create_device ();
3224dac1
KL
2386 tty = (struct tty_display_info *) xmalloc (sizeof (struct tty_display_info));
2387 bzero (tty, sizeof (struct tty_display_info));
2388 tty->next = tty_list;
2389 tty_list = tty;
428a555e 2390
7e59217d
KL
2391 device->type = output_termcap;
2392 device->display_info.tty = tty;
2393 tty->device = device;
28d440ab 2394
7b00d185
KL
2395 tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm));
2396 Wcm_clear (tty);
daf01701 2397
7e59217d 2398 device->rif = 0; /* ttys don't support window-based redisplay. */
3224dac1 2399
7e59217d
KL
2400 device->cursor_to_hook = &tty_cursor_to;
2401 device->raw_cursor_to_hook = &tty_raw_cursor_to;
3224dac1 2402
7e59217d
KL
2403 device->clear_to_end_hook = &tty_clear_to_end;
2404 device->clear_frame_hook = &tty_clear_frame;
2405 device->clear_end_of_line_hook = &tty_clear_end_of_line;
3224dac1 2406
7e59217d 2407 device->ins_del_lines_hook = &tty_ins_del_lines;
3224dac1 2408
7e59217d
KL
2409 device->insert_glyphs_hook = &tty_insert_glyphs;
2410 device->write_glyphs_hook = &tty_write_glyphs;
2411 device->delete_glyphs_hook = &tty_delete_glyphs;
3224dac1 2412
7e59217d 2413 device->ring_bell_hook = &tty_ring_bell;
3224dac1 2414
7e59217d
KL
2415 device->reset_terminal_modes_hook = &tty_reset_terminal_modes;
2416 device->set_terminal_modes_hook = &tty_set_terminal_modes;
2417 device->update_begin_hook = 0; /* Not needed. */
2418 device->update_end_hook = &tty_update_end;
2419 device->set_terminal_window_hook = &tty_set_terminal_window;
2420
2421 device->mouse_position_hook = 0; /* Not needed. */
2422 device->frame_rehighlight_hook = 0; /* Not needed. */
2423 device->frame_raise_lower_hook = 0; /* Not needed. */
2424
2425 device->set_vertical_scroll_bar_hook = 0; /* Not needed. */
2426 device->condemn_scroll_bars_hook = 0; /* Not needed. */
2427 device->redeem_scroll_bar_hook = 0; /* Not needed. */
2428 device->judge_scroll_bars_hook = 0; /* Not needed. */
2429
2430 device->read_socket_hook = &tty_read_avail_input; /* keyboard.c */
2431 device->frame_up_to_date_hook = 0; /* Not needed. */
3224dac1 2432
7e59217d
KL
2433 device->delete_frame_hook = &delete_tty_output;
2434 device->delete_device_hook = &delete_tty;
428a555e 2435
28d440ab
KL
2436 if (name)
2437 {
2438 int fd;
0a125897 2439 FILE *file;
0c72d684
KL
2440
2441#ifdef O_IGNORE_CTTY
2442 /* Open the terminal device. Don't recognize it as our
2443 controlling terminal, and don't make it the controlling tty
2444 if we don't have one at the moment. */
2445 fd = emacs_open (name, O_RDWR | O_IGNORE_CTTY | O_NOCTTY, 0);
2446#else
2666355c
KL
2447 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
2448 defined on Hurd. On other systems, we need to dissociate
2449 ourselves from the controlling tty when we want to open a
03a1d6bd 2450 frame on the same terminal. */
0c72d684
KL
2451
2452 fd = emacs_open (name, O_RDWR | O_NOCTTY, 0);
03a1d6bd 2453
0c72d684
KL
2454#endif /* O_IGNORE_CTTY */
2455
28d440ab
KL
2456 if (fd < 0)
2457 {
7e59217d 2458 delete_tty (device);
fca177d4 2459 error ("Could not open file: %s", name);
28d440ab 2460 }
e7cf0fa0 2461 if (!isatty (fd))
0c72d684
KL
2462 {
2463 close (fd);
2464 error ("Not a tty device: %s", name);
2465 }
2466
03a1d6bd
KL
2467 dissociate_if_controlling_tty (fd);
2468
0a125897 2469 file = fdopen (fd, "w+");
28d7d09f 2470 tty->name = xstrdup (name);
7e59217d 2471 device->name = xstrdup (name);
28d7d09f
KL
2472 tty->input = file;
2473 tty->output = file;
28d440ab
KL
2474 }
2475 else
2476 {
0c72d684
KL
2477 if (no_controlling_tty)
2478 {
2479 /* Opening a frame on stdout is unsafe if we have
2480 disconnected our controlling terminal. */
2481 error ("There is no controlling terminal any more");
2482 }
28d7d09f 2483 tty->name = 0;
7e59217d 2484 device->name = xstrdup (ttyname (0));
28d7d09f
KL
2485 tty->input = stdin;
2486 tty->output = stdout;
28d440ab
KL
2487 }
2488
28d7d09f 2489 tty->type = xstrdup (terminal_type);
28d440ab 2490
819b8f00 2491 add_keyboard_wait_descriptor (fileno (tty->input));
daf01701 2492
af645abf
KH
2493 encode_terminal_bufsize = 0;
2494
cb28b9c2 2495#ifdef WINDOWSNT
29f27c39 2496 initialize_w32_display ();
cb28b9c2 2497
fca177d4 2498 Wcm_clear (tty);
cb28b9c2 2499
a678d9ff 2500 area = (char *) xmalloc (2044);
cb28b9c2 2501
428a555e
KL
2502 FrameRows (tty) = FRAME_LINES (f); /* XXX */
2503 FrameCols (tty) = FRAME_COLS (f); /* XXX */
2504 tty->specified_window = FRAME_LINES (f); /* XXX */
cb28b9c2 2505
7e59217d 2506 tty->device->delete_in_insert_mode = 1;
cb28b9c2 2507
daf01701 2508 UseTabs (tty) = 0;
7e59217d 2509 device->scroll_region_ok = 0;
cb28b9c2 2510
7e59217d
KL
2511 /* Seems to insert lines when it's not supposed to, messing up the
2512 device. In doing a trace, it didn't seem to be called much, so I
2513 don't think we're losing anything by turning it off. */
2514 device->line_ins_del_ok = 0;
2515 device->char_ins_del_ok = 1;
cb28b9c2
RS
2516
2517 baud_rate = 19200;
2518
428a555e
KL
2519 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; /* XXX */
2520 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; /* XXX */
acfcd5cd 2521 TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */
cb28b9c2 2522
7e59217d 2523 return device;
eccec691 2524#else /* not WINDOWSNT */
cb28b9c2 2525
6548cf00 2526 Wcm_clear (tty);
08a24c47 2527
3a06a6d9 2528 buffer = (char *) xmalloc (buffer_size);
03a1d6bd
KL
2529
2530 /* On some systems, tgetent tries to access the controlling
2531 terminal. */
2532 sigblock (sigmask (SIGTTOU));
08a24c47 2533 status = tgetent (buffer, terminal_type);
03a1d6bd
KL
2534 sigunblock (sigmask (SIGTTOU));
2535
08a24c47 2536 if (status < 0)
b0347178
KH
2537 {
2538#ifdef TERMINFO
7e59217d 2539 maybe_fatal (must_succeed, buffer, device,
3224dac1
KL
2540 "Cannot open terminfo database file",
2541 "Cannot open terminfo database file");
b0347178 2542#else
7e59217d 2543 maybe_fatal (must_succeed, buffer, device,
3224dac1
KL
2544 "Cannot open termcap database file",
2545 "Cannot open termcap database file");
b0347178
KH
2546#endif
2547 }
08a24c47 2548 if (status == 0)
b0347178
KH
2549 {
2550#ifdef TERMINFO
7e59217d 2551 maybe_fatal (must_succeed, buffer, device,
3224dac1
KL
2552 "Terminal type %s is not defined",
2553 "Terminal type %s is not defined.\n\
0a125897 2554If that is not the actual type of terminal you have,\n\
b0347178
KH
2555use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2556`setenv TERM ...') to specify the correct type. It may be necessary\n\
e12c1054 2557to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3224dac1 2558 terminal_type);
b0347178 2559#else
7e59217d 2560 maybe_fatal (must_succeed, buffer, device,
3224dac1
KL
2561 "Terminal type %s is not defined",
2562 "Terminal type %s is not defined.\n\
0a125897 2563If that is not the actual type of terminal you have,\n\
c5a9c3e6
RS
2564use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2565`setenv TERM ...') to specify the correct type. It may be necessary\n\
e12c1054 2566to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3224dac1 2567 terminal_type);
b0347178
KH
2568#endif
2569 }
3a06a6d9 2570
f730033e 2571#ifndef TERMINFO
3a06a6d9 2572 if (strlen (buffer) >= buffer_size)
08a24c47 2573 abort ();
f730033e 2574 buffer_size = strlen (buffer);
3dd3a502 2575#endif
f730033e 2576 area = (char *) xmalloc (buffer_size);
08a24c47 2577
fca177d4
KL
2578 tty->TS_ins_line = tgetstr ("al", address);
2579 tty->TS_ins_multi_lines = tgetstr ("AL", address);
2580 tty->TS_bell = tgetstr ("bl", address);
6548cf00 2581 BackTab (tty) = tgetstr ("bt", address);
fca177d4
KL
2582 tty->TS_clr_to_bottom = tgetstr ("cd", address);
2583 tty->TS_clr_line = tgetstr ("ce", address);
2584 tty->TS_clr_frame = tgetstr ("cl", address);
6548cf00
KL
2585 ColPosition (tty) = NULL; /* tgetstr ("ch", address); */
2586 AbsPosition (tty) = tgetstr ("cm", address);
2587 CR (tty) = tgetstr ("cr", address);
fca177d4
KL
2588 tty->TS_set_scroll_region = tgetstr ("cs", address);
2589 tty->TS_set_scroll_region_1 = tgetstr ("cS", address);
6548cf00 2590 RowPosition (tty) = tgetstr ("cv", address);
fca177d4
KL
2591 tty->TS_del_char = tgetstr ("dc", address);
2592 tty->TS_del_multi_chars = tgetstr ("DC", address);
2593 tty->TS_del_line = tgetstr ("dl", address);
2594 tty->TS_del_multi_lines = tgetstr ("DL", address);
2595 tty->TS_delete_mode = tgetstr ("dm", address);
2596 tty->TS_end_delete_mode = tgetstr ("ed", address);
2597 tty->TS_end_insert_mode = tgetstr ("ei", address);
6548cf00 2598 Home (tty) = tgetstr ("ho", address);
fca177d4
KL
2599 tty->TS_ins_char = tgetstr ("ic", address);
2600 tty->TS_ins_multi_chars = tgetstr ("IC", address);
2601 tty->TS_insert_mode = tgetstr ("im", address);
2602 tty->TS_pad_inserted_char = tgetstr ("ip", address);
2603 tty->TS_end_keypad_mode = tgetstr ("ke", address);
2604 tty->TS_keypad_mode = tgetstr ("ks", address);
6548cf00
KL
2605 LastLine (tty) = tgetstr ("ll", address);
2606 Right (tty) = tgetstr ("nd", address);
2607 Down (tty) = tgetstr ("do", address);
2608 if (!Down (tty))
2609 Down (tty) = tgetstr ("nl", address); /* Obsolete name for "do" */
08a24c47
JB
2610#ifdef VMS
2611 /* VMS puts a carriage return before each linefeed,
2612 so it is not safe to use linefeeds. */
6548cf00
KL
2613 if (Down (tty) && Down (tty)[0] == '\n' && Down (tty)[1] == '\0')
2614 Down (tty) = 0;
08a24c47
JB
2615#endif /* VMS */
2616 if (tgetflag ("bs"))
6548cf00 2617 Left (tty) = "\b"; /* can't possibly be longer! */
08a24c47 2618 else /* (Actually, "bs" is obsolete...) */
6548cf00
KL
2619 Left (tty) = tgetstr ("le", address);
2620 if (!Left (tty))
2621 Left (tty) = tgetstr ("bc", address); /* Obsolete name for "le" */
fca177d4
KL
2622 tty->TS_pad_char = tgetstr ("pc", address);
2623 tty->TS_repeat = tgetstr ("rp", address);
2624 tty->TS_end_standout_mode = tgetstr ("se", address);
2625 tty->TS_fwd_scroll = tgetstr ("sf", address);
2626 tty->TS_standout_mode = tgetstr ("so", address);
2627 tty->TS_rev_scroll = tgetstr ("sr", address);
6548cf00 2628 tty->Wcm->cm_tab = tgetstr ("ta", address);
fca177d4
KL
2629 tty->TS_end_termcap_modes = tgetstr ("te", address);
2630 tty->TS_termcap_modes = tgetstr ("ti", address);
6548cf00 2631 Up (tty) = tgetstr ("up", address);
fca177d4
KL
2632 tty->TS_visible_bell = tgetstr ("vb", address);
2633 tty->TS_cursor_normal = tgetstr ("ve", address);
2634 tty->TS_cursor_visible = tgetstr ("vs", address);
2635 tty->TS_cursor_invisible = tgetstr ("vi", address);
2636 tty->TS_set_window = tgetstr ("wi", address);
2637
2638 tty->TS_enter_underline_mode = tgetstr ("us", address);
2639 tty->TS_exit_underline_mode = tgetstr ("ue", address);
2640 tty->TS_enter_bold_mode = tgetstr ("md", address);
2641 tty->TS_enter_dim_mode = tgetstr ("mh", address);
2642 tty->TS_enter_blink_mode = tgetstr ("mb", address);
2643 tty->TS_enter_reverse_mode = tgetstr ("mr", address);
2644 tty->TS_enter_alt_charset_mode = tgetstr ("as", address);
2645 tty->TS_exit_alt_charset_mode = tgetstr ("ae", address);
2646 tty->TS_exit_attribute_mode = tgetstr ("me", address);
177c0ea7 2647
6548cf00
KL
2648 MultiUp (tty) = tgetstr ("UP", address);
2649 MultiDown (tty) = tgetstr ("DO", address);
2650 MultiLeft (tty) = tgetstr ("LE", address);
2651 MultiRight (tty) = tgetstr ("RI", address);
08a24c47 2652
e7f90eab
GM
2653 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2654 color because we can't switch back to the default foreground and
2655 background. */
fca177d4
KL
2656 tty->TS_orig_pair = tgetstr ("op", address);
2657 if (tty->TS_orig_pair)
a168702a 2658 {
fca177d4
KL
2659 tty->TS_set_foreground = tgetstr ("AF", address);
2660 tty->TS_set_background = tgetstr ("AB", address);
2661 if (!tty->TS_set_foreground)
e7f90eab
GM
2662 {
2663 /* SVr4. */
fca177d4
KL
2664 tty->TS_set_foreground = tgetstr ("Sf", address);
2665 tty->TS_set_background = tgetstr ("Sb", address);
e7f90eab 2666 }
177c0ea7 2667
fca177d4
KL
2668 tty->TN_max_colors = tgetnum ("Co");
2669 tty->TN_max_pairs = tgetnum ("pa");
177c0ea7 2670
fca177d4
KL
2671 tty->TN_no_color_video = tgetnum ("NC");
2672 if (tty->TN_no_color_video == -1)
2673 tty->TN_no_color_video = 0;
a168702a 2674 }
a168702a 2675
fca177d4 2676 tty_default_color_capabilities (tty, 1);
ace28297 2677
6548cf00 2678 MagicWrap (tty) = tgetflag ("xn");
e4058338
KH
2679 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2680 the former flag imply the latter. */
6548cf00 2681 AutoWrap (tty) = MagicWrap (tty) || tgetflag ("am");
7e59217d 2682 device->memory_below_frame = tgetflag ("db");
fca177d4 2683 tty->TF_hazeltine = tgetflag ("hz");
7e59217d 2684 device->must_write_spaces = tgetflag ("in");
fca177d4
KL
2685 tty->meta_key = tgetflag ("km") || tgetflag ("MT");
2686 tty->TF_insmode_motion = tgetflag ("mi");
2687 tty->TF_standout_motion = tgetflag ("ms");
2688 tty->TF_underscore = tgetflag ("ul");
2689 tty->TF_teleray = tgetflag ("xt");
08a24c47 2690
e7cf0fa0 2691#ifdef MULTI_KBOARD
7e59217d
KL
2692 device->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
2693 init_kboard (device->kboard);
2694 device->kboard->next_kboard = all_kboards;
2695 all_kboards = device->kboard;
2696 device->kboard->reference_count++;
e7cf0fa0
KL
2697 /* Don't let the initial kboard remain current longer than necessary.
2698 That would cause problems if a file loaded on startup tries to
2699 prompt in the mini-buffer. */
2700 if (current_kboard == initial_kboard)
7e59217d 2701 current_kboard = device->kboard;
e7cf0fa0
KL
2702#endif
2703
7e59217d 2704 term_get_fkeys (address, device->kboard);
5c2c7893 2705
ff11dfa1 2706 /* Get frame size from system, or else from termcap. */
3b12ce12
RS
2707 {
2708 int height, width;
0b0d3e0b 2709 get_tty_size (fileno (tty->input), &width, &height);
0a125897
KL
2710 FrameCols (tty) = width;
2711 FrameRows (tty) = height;
3b12ce12
RS
2712 }
2713
0a125897
KL
2714 if (FrameCols (tty) <= 0)
2715 FrameCols (tty) = tgetnum ("co");
2716 if (FrameRows (tty) <= 0)
2717 FrameRows (tty) = tgetnum ("li");
177c0ea7 2718
0a125897 2719 if (FrameRows (tty) < 3 || FrameCols (tty) < 3)
7e59217d 2720 maybe_fatal (must_succeed, NULL, device,
3224dac1
KL
2721 "Screen size %dx%d is too small"
2722 "Screen size %dx%d is too small",
0a125897 2723 FrameCols (tty), FrameRows (tty));
ee7a2de4 2724
8a56675d 2725#if 0 /* This is not used anywhere. */
7e59217d 2726 tty->device->min_padding_speed = tgetnum ("pb");
8a56675d 2727#endif
28d440ab 2728
6548cf00 2729 TabWidth (tty) = tgetnum ("tw");
08a24c47
JB
2730
2731#ifdef VMS
2732 /* These capabilities commonly use ^J.
2733 I don't know why, but sending them on VMS does not work;
2734 it causes following spaces to be lost, sometimes.
2735 For now, the simplest fix is to avoid using these capabilities ever. */
6548cf00
KL
2736 if (Down (tty) && Down (tty)[0] == '\n')
2737 Down (tty) = 0;
08a24c47
JB
2738#endif /* VMS */
2739
fca177d4
KL
2740 if (!tty->TS_bell)
2741 tty->TS_bell = "\07";
08a24c47 2742
fca177d4
KL
2743 if (!tty->TS_fwd_scroll)
2744 tty->TS_fwd_scroll = Down (tty);
08a24c47 2745
fca177d4 2746 PC = tty->TS_pad_char ? *tty->TS_pad_char : 0;
08a24c47 2747
6548cf00
KL
2748 if (TabWidth (tty) < 0)
2749 TabWidth (tty) = 8;
177c0ea7 2750
08a24c47
JB
2751/* Turned off since /etc/termcap seems to have :ta= for most terminals
2752 and newer termcap doc does not seem to say there is a default.
6548cf00
KL
2753 if (!tty->Wcm->cm_tab)
2754 tty->Wcm->cm_tab = "\t";
08a24c47
JB
2755*/
2756
54800acb
MB
2757 /* We don't support standout modes that use `magic cookies', so
2758 turn off any that do. */
fca177d4 2759 if (tty->TS_standout_mode && tgetnum ("sg") >= 0)
54800acb 2760 {
fca177d4
KL
2761 tty->TS_standout_mode = 0;
2762 tty->TS_end_standout_mode = 0;
54800acb 2763 }
fca177d4 2764 if (tty->TS_enter_underline_mode && tgetnum ("ug") >= 0)
54800acb 2765 {
fca177d4
KL
2766 tty->TS_enter_underline_mode = 0;
2767 tty->TS_exit_underline_mode = 0;
54800acb
MB
2768 }
2769
2770 /* If there's no standout mode, try to use underlining instead. */
fca177d4 2771 if (tty->TS_standout_mode == 0)
08a24c47 2772 {
fca177d4
KL
2773 tty->TS_standout_mode = tty->TS_enter_underline_mode;
2774 tty->TS_end_standout_mode = tty->TS_exit_underline_mode;
08a24c47
JB
2775 }
2776
afd359c4
RS
2777 /* If no `se' string, try using a `me' string instead.
2778 If that fails, we can't use standout mode at all. */
fca177d4 2779 if (tty->TS_end_standout_mode == 0)
afd359c4 2780 {
e4bfb3b6 2781 char *s = tgetstr ("me", address);
afd359c4 2782 if (s != 0)
fca177d4 2783 tty->TS_end_standout_mode = s;
afd359c4 2784 else
fca177d4 2785 tty->TS_standout_mode = 0;
afd359c4
RS
2786 }
2787
fca177d4 2788 if (tty->TF_teleray)
08a24c47 2789 {
6548cf00 2790 tty->Wcm->cm_tab = 0;
54800acb 2791 /* We can't support standout mode, because it uses magic cookies. */
fca177d4 2792 tty->TS_standout_mode = 0;
08a24c47 2793 /* But that means we cannot rely on ^M to go to column zero! */
6548cf00 2794 CR (tty) = 0;
08a24c47
JB
2795 /* LF can't be trusted either -- can alter hpos */
2796 /* if move at column 0 thru a line with TS_standout_mode */
6548cf00 2797 Down (tty) = 0;
08a24c47
JB
2798 }
2799
2800 /* Special handling for certain terminal types known to need it */
2801
2802 if (!strcmp (terminal_type, "supdup"))
2803 {
7e59217d 2804 device->memory_below_frame = 1;
6548cf00 2805 tty->Wcm->cm_losewrap = 1;
08a24c47
JB
2806 }
2807 if (!strncmp (terminal_type, "c10", 3)
2808 || !strcmp (terminal_type, "perq"))
2809 {
2810 /* Supply a makeshift :wi string.
2811 This string is not valid in general since it works only
2812 for windows starting at the upper left corner;
2813 but that is all Emacs uses.
daf01701 2814
ff11dfa1 2815 This string works only if the frame is using
08a24c47
JB
2816 the top of the video memory, because addressing is memory-relative.
2817 So first check the :ti string to see if that is true.
2818
2819 It would be simpler if the :wi string could go in the termcap
2820 entry, but it can't because it is not fully valid.
2821 If it were in the termcap entry, it would confuse other programs. */
fca177d4 2822 if (!tty->TS_set_window)
08a24c47 2823 {
fca177d4 2824 p = tty->TS_termcap_modes;
08a24c47
JB
2825 while (*p && strcmp (p, "\033v "))
2826 p++;
2827 if (*p)
fca177d4 2828 tty->TS_set_window = "\033v%C %C %C %C ";
08a24c47
JB
2829 }
2830 /* Termcap entry often fails to have :in: flag */
7e59217d 2831 device->must_write_spaces = 1;
08a24c47
JB
2832 /* :ti string typically fails to have \E^G! in it */
2833 /* This limits scope of insert-char to one line. */
fca177d4 2834 strcpy (area, tty->TS_termcap_modes);
08a24c47 2835 strcat (area, "\033\007!");
fca177d4 2836 tty->TS_termcap_modes = area;
08a24c47 2837 area += strlen (area) + 1;
6548cf00 2838 p = AbsPosition (tty);
08a24c47 2839 /* Change all %+ parameters to %C, to handle
28d440ab 2840 values above 96 correctly for the C100. */
08a24c47 2841 while (*p)
28d440ab
KL
2842 {
2843 if (p[0] == '%' && p[1] == '+')
2844 p[1] = 'C';
2845 p++;
2846 }
08a24c47
JB
2847 }
2848
0a125897 2849 tty->specified_window = FrameRows (tty);
08a24c47 2850
6548cf00 2851 if (Wcm_init (tty) == -1) /* can't do cursor motion */
3224dac1 2852 {
7e59217d 2853 maybe_fatal (must_succeed, NULL, device,
3224dac1 2854 "Terminal type \"%s\" is not powerful enough to run Emacs",
08a24c47 2855#ifdef VMS
3224dac1 2856 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
08a24c47
JB
2857It lacks the ability to position the cursor.\n\
2858If that is not the actual type of terminal you have, use either the\n\
2859DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
e12c1054 2860or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
37dad45a
RS
2861#else /* not VMS */
2862# ifdef TERMINFO
3224dac1 2863 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
0a125897
KL
2864It lacks the ability to position the cursor.\n\
2865If that is not the actual type of terminal you have,\n\
37dad45a
RS
2866use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2867`setenv TERM ...') to specify the correct type. It may be necessary\n\
e12c1054 2868to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
37dad45a 2869# else /* TERMCAP */
3224dac1 2870 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
0a125897 2871It lacks the ability to position the cursor.\n\
08a24c47 2872If that is not the actual type of terminal you have,\n\
c5a9c3e6
RS
2873use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2874`setenv TERM ...') to specify the correct type. It may be necessary\n\
e12c1054 2875to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
37dad45a
RS
2876# endif /* TERMINFO */
2877#endif /*VMS */
3224dac1 2878 terminal_type);
fca177d4 2879 }
daf01701 2880
0a125897 2881 if (FrameRows (tty) <= 0 || FrameCols (tty) <= 0)
7e59217d 2882 maybe_fatal (must_succeed, NULL, device,
3224dac1
KL
2883 "Could not determine the frame size",
2884 "Could not determine the frame size");
08a24c47 2885
fca177d4
KL
2886 tty->delete_in_insert_mode
2887 = tty->TS_delete_mode && tty->TS_insert_mode
2888 && !strcmp (tty->TS_delete_mode, tty->TS_insert_mode);
08a24c47 2889
fca177d4
KL
2890 tty->se_is_so = (tty->TS_standout_mode
2891 && tty->TS_end_standout_mode
2892 && !strcmp (tty->TS_standout_mode, tty->TS_end_standout_mode));
08a24c47 2893
0b0d3e0b 2894 UseTabs (tty) = tabs_safe_p (fileno (tty->input)) && TabWidth (tty) == 8;
08a24c47 2895
7e59217d 2896 device->scroll_region_ok
6548cf00 2897 = (tty->Wcm->cm_abs
fca177d4 2898 && (tty->TS_set_window || tty->TS_set_scroll_region || tty->TS_set_scroll_region_1));
08a24c47 2899
7e59217d 2900 device->line_ins_del_ok
fca177d4
KL
2901 = (((tty->TS_ins_line || tty->TS_ins_multi_lines)
2902 && (tty->TS_del_line || tty->TS_del_multi_lines))
7e59217d 2903 || (device->scroll_region_ok
fca177d4 2904 && tty->TS_fwd_scroll && tty->TS_rev_scroll));
28d440ab 2905
7e59217d 2906 device->char_ins_del_ok
fca177d4
KL
2907 = ((tty->TS_ins_char || tty->TS_insert_mode
2908 || tty->TS_pad_inserted_char || tty->TS_ins_multi_chars)
2909 && (tty->TS_del_char || tty->TS_del_multi_chars));
8a56675d 2910
7e59217d 2911 device->fast_clear_end_of_line = tty->TS_clr_line != 0;
08a24c47 2912
0b0d3e0b 2913 init_baud_rate (fileno (tty->input));
20a558dc 2914
daf01701
KL
2915#ifdef AIXHFT
2916 /* The HFT system on AIX doesn't optimize for scrolling, so it's
2917 really ugly at times. */
7e59217d
KL
2918 device->line_ins_del_ok = 0;
2919 device->char_ins_del_ok = 0;
daf01701
KL
2920#endif
2921
0a125897
KL
2922 /* Don't do this. I think termcap may still need the buffer. */
2923 /* xfree (buffer); */
28d440ab 2924
0a125897
KL
2925 /* Init system terminal modes (RAW or CBREAK, etc.). */
2926 init_sys_modes (tty);
daf01701 2927
7e59217d 2928 return device;
7b00d185 2929#endif /* not WINDOWSNT */
08a24c47
JB
2930}
2931
a4c6993d 2932/* Auxiliary error-handling function for init_tty.
7e59217d 2933 Free BUFFER and delete DEVICE, then call error or fatal
da8e1115
KL
2934 with str1 or str2, respectively, according to MUST_SUCCEED. */
2935
3224dac1 2936static void
7e59217d 2937maybe_fatal (must_succeed, buffer, device, str1, str2, arg1, arg2)
3224dac1
KL
2938 int must_succeed;
2939 char *buffer;
7e59217d 2940 struct device *device;
3224dac1
KL
2941 char *str1, *str2, *arg1, *arg2;
2942{
2943 if (buffer)
2944 xfree (buffer);
2945
7e59217d
KL
2946 if (device)
2947 delete_tty (device);
3224dac1
KL
2948
2949 if (must_succeed)
2950 fatal (str2, arg1, arg2);
2951 else
2952 error (str1, arg1, arg2);
2953
2954 abort ();
2955}
2956
08a24c47 2957/* VARARGS 1 */
dfcf069d 2958void
08a24c47 2959fatal (str, arg1, arg2)
4746118a 2960 char *str, *arg1, *arg2;
08a24c47
JB
2961{
2962 fprintf (stderr, "emacs: ");
2963 fprintf (stderr, str, arg1, arg2);
e12c1054 2964 fprintf (stderr, "\n");
08a24c47
JB
2965 fflush (stderr);
2966 exit (1);
2967}
07c57952 2968
819b8f00
KL
2969\f
2970
0a125897
KL
2971static int deleting_tty = 0;
2972
da8e1115
KL
2973
2974/* Delete the given terminal device, closing all frames on it. */
2975
fca177d4 2976void
7e59217d 2977delete_tty (struct device *device)
fca177d4 2978{
428a555e 2979 struct tty_display_info *tty;
fca177d4 2980 Lisp_Object tail, frame;
4d553a13 2981 char *tty_name;
7e59217d 2982 int last_device;
4d553a13 2983
0a125897
KL
2984 if (deleting_tty)
2985 /* We get a recursive call when we delete the last frame on this
7e59217d 2986 device. */
0a125897 2987 return;
fca177d4 2988
7e59217d 2989 if (device->type != output_termcap)
428a555e
KL
2990 abort ();
2991
7e59217d 2992 tty = device->display_info.tty;
428a555e 2993
7e59217d 2994 last_device = 1;
81be1a93
KL
2995 FOR_EACH_FRAME (tail, frame)
2996 {
2997 struct frame *f = XFRAME (frame);
2998 if (FRAME_LIVE_P (f) && (!FRAME_TERMCAP_P (f) || FRAME_TTY (f) != tty))
2999 {
7e59217d 3000 last_device = 0;
81be1a93
KL
3001 break;
3002 }
3003 }
7e59217d
KL
3004 if (last_device)
3005 error ("Attempt to delete the sole display device with live frames");
81be1a93 3006
fca177d4
KL
3007 if (tty == tty_list)
3008 tty_list = tty->next;
3009 else
3010 {
28d7d09f 3011 struct tty_display_info *p;
fca177d4
KL
3012 for (p = tty_list; p && p->next != tty; p = p->next)
3013 ;
3014
3015 if (! p)
3016 /* This should not happen. */
3017 abort ();
3018
0a125897
KL
3019 p->next = tty->next;
3020 tty->next = 0;
fca177d4
KL
3021 }
3022
81be1a93
KL
3023 deleting_tty = 1;
3024
04c3243c
KL
3025 FOR_EACH_FRAME (tail, frame)
3026 {
3027 struct frame *f = XFRAME (frame);
daf01701 3028 if (FRAME_TERMCAP_P (f) && FRAME_LIVE_P (f) && FRAME_TTY (f) == tty)
04c3243c
KL
3029 {
3030 Fdelete_frame (frame, Qt);
04c3243c
KL
3031 }
3032 }
daf01701 3033
7e59217d
KL
3034 /* reset_sys_modes needs a valid device, so this call needs to be
3035 before delete_device. */
04c3243c 3036 reset_sys_modes (tty);
fca177d4 3037
7e59217d 3038 delete_device (device);
3224dac1 3039
4d553a13 3040 tty_name = tty->name;
fca177d4
KL
3041 if (tty->type)
3042 xfree (tty->type);
daf01701 3043
fca177d4 3044 if (tty->input)
819b8f00
KL
3045 {
3046 delete_keyboard_wait_descriptor (fileno (tty->input));
3047 if (tty->input != stdin)
3048 fclose (tty->input);
3049 }
3050 if (tty->output && tty->output != stdout && tty->output != tty->input)
fca177d4
KL
3051 fclose (tty->output);
3052 if (tty->termscript)
3053 fclose (tty->termscript);
daf01701 3054
fca177d4 3055 if (tty->old_tty)
0a125897 3056 xfree (tty->old_tty);
fca177d4 3057
0a125897 3058 if (tty->Wcm)
daf01701
KL
3059 xfree (tty->Wcm);
3060
28d7d09f 3061 bzero (tty, sizeof (struct tty_display_info));
fca177d4 3062 xfree (tty);
0a125897 3063 deleting_tty = 0;
fca177d4
KL
3064}
3065
428a555e
KL
3066\f
3067
3068/* Initialize the tty-dependent part of frame F. The frame must
7e59217d 3069 already have its device initialized. */
da8e1115 3070
428a555e
KL
3071void
3072create_tty_output (struct frame *f)
3073{
e9cda827
KL
3074 struct tty_output *t;
3075
428a555e
KL
3076 if (! FRAME_TERMCAP_P (f))
3077 abort ();
3078
e9cda827 3079 t = xmalloc (sizeof (struct tty_output));
428a555e
KL
3080 bzero (t, sizeof (struct tty_output));
3081
7e59217d 3082 t->display_info = FRAME_DEVICE (f)->display_info.tty;
428a555e
KL
3083
3084 f->output_data.tty = t;
3085}
3086
3087/* Delete the tty-dependent part of frame F. */
da8e1115 3088
428a555e
KL
3089void
3090delete_tty_output (struct frame *f)
3091{
3092 if (! FRAME_TERMCAP_P (f))
3093 abort ();
3094
3095 xfree (f->output_data.tty);
3096}
3097
fca177d4 3098
819b8f00 3099\f
28d440ab 3100
28d7d09f 3101/* Mark the pointers in the tty_display_info objects.
819b8f00 3102 Called by the Fgarbage_collector. */
da8e1115 3103
fca177d4 3104void
819b8f00 3105mark_ttys ()
fca177d4 3106{
28d7d09f 3107 struct tty_display_info *tty;
0c72d684 3108
819b8f00 3109 for (tty = tty_list; tty; tty = tty->next)
fca177d4 3110 {
819b8f00
KL
3111 if (tty->top_frame)
3112 mark_object (tty->top_frame);
fca177d4
KL
3113 }
3114}
3115
428a555e
KL
3116\f
3117
7e59217d 3118/* Create a new device object and add it to the device list. */
da8e1115 3119
7e59217d
KL
3120struct device *
3121create_device (void)
428a555e 3122{
7e59217d 3123 struct device *device = (struct device *) xmalloc (sizeof (struct device));
428a555e 3124
7e59217d
KL
3125 bzero (device, sizeof (struct device));
3126 device->next_device = device_list;
3127 device_list = device;
b8299c66 3128
7e59217d 3129 device->id = next_device_id++;
b6660415 3130
7e59217d 3131 device->keyboard_coding =
b8299c66 3132 (struct coding_system *) xmalloc (sizeof (struct coding_system));
7e59217d 3133 device->terminal_coding =
b8299c66
KL
3134 (struct coding_system *) xmalloc (sizeof (struct coding_system));
3135
7e59217d
KL
3136 setup_coding_system (Qnil, device->keyboard_coding);
3137 setup_coding_system (Qnil, device->terminal_coding);
b8299c66 3138
7e59217d 3139 return device;
428a555e
KL
3140}
3141
7e59217d 3142/* Remove a device from the device list and free its memory. */
da8e1115 3143
428a555e 3144void
7e59217d 3145delete_device (struct device *device)
428a555e 3146{
7e59217d 3147 struct device **dp;
d448e982
KL
3148 Lisp_Object tail, frame;
3149
3150 /* Check for and close live frames that are still on this
7e59217d 3151 device. */
d448e982
KL
3152 FOR_EACH_FRAME (tail, frame)
3153 {
3154 struct frame *f = XFRAME (frame);
7e59217d 3155 if (FRAME_LIVE_P (f) && f->device == device)
d448e982
KL
3156 {
3157 Fdelete_frame (frame, Qt);
3158 }
3159 }
3160
7e59217d 3161 for (dp = &device_list; *dp != device; dp = &(*dp)->next_device)
428a555e
KL
3162 if (! *dp)
3163 abort ();
7e59217d
KL
3164 *dp = device->next_device;
3165
3166 if (device->keyboard_coding)
3167 xfree (device->keyboard_coding);
3168 if (device->terminal_coding)
3169 xfree (device->terminal_coding);
3170 if (device->name)
3171 xfree (device->name);
b6660415 3172
bedb9c0e 3173#ifdef MULTI_KBOARD
7e59217d
KL
3174 if (device->kboard && --device->kboard->reference_count == 0)
3175 delete_kboard (device->kboard);
bedb9c0e
KL
3176#endif
3177
7e59217d
KL
3178 bzero (device, sizeof (struct device));
3179 xfree (device);
428a555e
KL
3180}
3181
b6660415 3182DEFUN ("delete-display", Fdelete_display, Sdelete_display, 0, 2, 0,
7e59217d
KL
3183 doc: /* Delete DEVICE by deleting all frames on it and closing the device.
3184DEVICE may be a display device id, a frame, or nil (meaning the
3185selected frame's display device).
b6660415
KL
3186
3187Normally, you may not delete a display if all other displays are suspended,
3188but if the second argument FORCE is non-nil, you may do so. */)
7e59217d
KL
3189 (device, force)
3190 Lisp_Object device, force;
b6660415 3191{
7e59217d 3192 struct device *d, *p;
b6660415 3193
7e59217d 3194 d = get_device (device, 0);
b6660415
KL
3195
3196 if (!d)
3197 return Qnil;
3198
7e59217d
KL
3199 p = device_list;
3200 while (p && (p == d || !DEVICE_ACTIVE_P (p)))
3201 p = p->next_device;
b6660415
KL
3202
3203 if (NILP (force) && !p)
7e59217d 3204 error ("Attempt to delete the sole active display device");
b6660415 3205
7e59217d
KL
3206 if (d->delete_device_hook)
3207 (*d->delete_device_hook) (d);
b6660415 3208 else
7e59217d 3209 delete_device (d);
b6660415
KL
3210
3211 return Qnil;
3212}
3213
3214DEFUN ("display-live-p", Fdisplay_live_p, Sdisplay_live_p, 1, 1, 0,
7e59217d
KL
3215 doc: /* Return non-nil if OBJECT is a device which has not been deleted.
3216Value is nil if OBJECT is not a live display device.
3217If object is a live display device, the return value indicates what
3218sort of output device it uses. See the documentation of `framep' for
3219possible return values.
b6660415 3220
7e59217d 3221Display devices are represented by their integer identifiers. */)
b6660415
KL
3222 (object)
3223 Lisp_Object object;
3224{
7e59217d 3225 struct device *d;
b6660415
KL
3226
3227 if (!INTEGERP (object))
3228 return Qnil;
3229
7e59217d 3230 d = get_device (object, 0);
b6660415
KL
3231
3232 if (!d)
3233 return Qnil;
3234
3235 switch (d->type)
3236 {
3237 case output_initial: /* The initial frame is like a termcap frame. */
3238 case output_termcap:
3239 return Qt;
3240 case output_x_window:
3241 return Qx;
3242 case output_w32:
3243 return Qw32;
3244 case output_msdos_raw:
3245 return Qpc;
3246 case output_mac:
3247 return Qmac;
3248 default:
3249 abort ();
3250 }
3251}
3252
3253DEFUN ("display-list", Fdisplay_list, Sdisplay_list, 0, 0, 0,
7e59217d
KL
3254 doc: /* Return a list of all display devices.
3255Display devices are represented by their integer identifiers. */)
b6660415
KL
3256 ()
3257{
7e59217d
KL
3258 Lisp_Object devices = Qnil;
3259 struct device *d;
b6660415 3260
7e59217d
KL
3261 for (d = device_list; d; d = d->next_device)
3262 devices = Fcons (make_number (d->id), devices);
b6660415 3263
7e59217d 3264 return devices;
b6660415
KL
3265}
3266
3267
0b0d3e0b
KL
3268\f
3269
3270DEFUN ("suspend-tty", Fsuspend_tty, Ssuspend_tty, 0, 1, 0,
3271 doc: /* Suspend the terminal device TTY.
b6660415 3272The terminal is restored to its default state, and Emacs ceases all
0b0d3e0b
KL
3273access to the terminal device. Frames that use the device are not
3274deleted, but input is not read from them and if they change, their
3275display is not updated.
3276
b6660415
KL
3277TTY may be a display id, a frame, or nil for the display device of the
3278currently selected frame.
0b0d3e0b
KL
3279
3280This function runs `suspend-tty-functions' after suspending the
b6660415
KL
3281device. The functions are run with one arg, the id of the suspended
3282display device.
0b0d3e0b
KL
3283
3284`suspend-tty' does nothing if it is called on an already suspended
3285device.
3286
3287A suspended terminal device may be resumed by calling `resume-tty' on
3288it. */)
3289 (tty)
3290 Lisp_Object tty;
3291{
7e59217d 3292 struct device *d = get_tty_device (tty);
0b0d3e0b
KL
3293 FILE *f;
3294
3295 if (!d)
3296 error ("Unknown tty device");
3297
3298 f = d->display_info.tty->input;
3299
3300 if (f)
3301 {
3302 reset_sys_modes (d->display_info.tty);
3303
3304 delete_keyboard_wait_descriptor (fileno (f));
3305
3306 fclose (f);
3307 if (f != d->display_info.tty->output)
3308 fclose (d->display_info.tty->output);
3309
3310 d->display_info.tty->input = 0;
3311 d->display_info.tty->output = 0;
3312
3313 if (FRAMEP (d->display_info.tty->top_frame))
3314 FRAME_SET_VISIBLE (XFRAME (d->display_info.tty->top_frame), 0);
3315
3316 /* Run `suspend-tty-functions'. */
3317 if (!NILP (Vrun_hooks))
3318 {
3319 Lisp_Object args[2];
3320 args[0] = intern ("suspend-tty-functions");
b6660415 3321 args[1] = make_number (d->id);
0b0d3e0b
KL
3322 Frun_hook_with_args (2, args);
3323 }
3324 }
3325
3326 return Qnil;
3327}
3328
3329
3330DEFUN ("resume-tty", Fresume_tty, Sresume_tty, 0, 1, 0,
3331 doc: /* Resume the previously suspended terminal device TTY.
b6660415
KL
3332The terminal is opened and reinitialized. Frames that are on the
3333suspended display are revived.
3334
3335It is an error to resume a display while another display is active on
3336the same device.
0b0d3e0b
KL
3337
3338This function runs `resume-tty-functions' after resuming the device.
b6660415
KL
3339The functions are run with one arg, the id of the resumed display
3340device.
0b0d3e0b
KL
3341
3342`resume-tty' does nothing if it is called on a device that is not
3343suspended.
3344
6d93dbff
KL
3345TTY may be a display device id, a frame, or nil for the display device
3346of the currently selected frame. */)
0b0d3e0b
KL
3347 (tty)
3348 Lisp_Object tty;
3349{
7e59217d 3350 struct device *d = get_tty_device (tty);
0b0d3e0b
KL
3351 int fd;
3352
3353 if (!d)
3354 error ("Unknown tty device");
3355
3356 if (!d->display_info.tty->input)
3357 {
7e59217d 3358 if (get_named_tty (d->display_info.tty->name))
b6660415
KL
3359 error ("Cannot resume display while another display is active on the same device");
3360
0b0d3e0b 3361 fd = emacs_open (d->display_info.tty->name, O_RDWR | O_NOCTTY, 0);
0b0d3e0b 3362
03a1d6bd
KL
3363 /* XXX What if open fails? */
3364
3365 dissociate_if_controlling_tty (fd);
3366
0b0d3e0b
KL
3367 d->display_info.tty->output = fdopen (fd, "w+");
3368 d->display_info.tty->input = d->display_info.tty->output;
3369
3370 add_keyboard_wait_descriptor (fd);
3371
3372 if (FRAMEP (d->display_info.tty->top_frame))
3373 FRAME_SET_VISIBLE (XFRAME (d->display_info.tty->top_frame), 1);
3374
3375 init_sys_modes (d->display_info.tty);
3376
3377 /* Run `suspend-tty-functions'. */
3378 if (!NILP (Vrun_hooks))
3379 {
3380 Lisp_Object args[2];
3381 args[0] = intern ("resume-tty-functions");
b6660415 3382 args[1] = make_number (d->id);
0b0d3e0b
KL
3383 Frun_hook_with_args (2, args);
3384 }
3385 }
3386
3387 return Qnil;
3388}
28d440ab 3389
819b8f00
KL
3390\f
3391void
3392syms_of_term ()
3393{
3394 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo,
3395 doc: /* Non-nil means the system uses terminfo rather than termcap.
3396This variable can be used by terminal emulator packages. */);
3397#ifdef TERMINFO
3398 system_uses_terminfo = 1;
3399#else
3400 system_uses_terminfo = 0;
3401#endif
3402
3403 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function,
3404 doc: /* Non-nil means call this function to ring the bell.
3405The function should accept no arguments. */);
3406 Vring_bell_function = Qnil;
3407
0b0d3e0b
KL
3408 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions,
3409 doc: /* Functions to be run after suspending a tty.
3410The functions are run with one argument, the name of the tty to be suspended.
3411See `suspend-tty'. */);
3412 Vsuspend_tty_functions = Qnil;
3413
3414
3415 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions,
3416 doc: /* Functions to be run after resuming a tty.
3417The functions are run with one argument, the name of the tty that was revived.
3418See `resume-tty'. */);
3419 Vresume_tty_functions = Qnil;
3420
819b8f00
KL
3421 defsubr (&Stty_display_color_p);
3422 defsubr (&Stty_display_color_cells);
072d84a6 3423 defsubr (&Stty_no_underline);
b6660415
KL
3424 defsubr (&Sdisplay_name);
3425 defsubr (&Sdisplay_tty_type);
4a933ef8 3426 defsubr (&Sdisplay_controlling_tty_p);
b6660415
KL
3427 defsubr (&Sdelete_display);
3428 defsubr (&Sdisplay_live_p);
3429 defsubr (&Sdisplay_list);
0b0d3e0b
KL
3430 defsubr (&Ssuspend_tty);
3431 defsubr (&Sresume_tty);
daf01701 3432
819b8f00 3433 Fprovide (intern ("multi-tty"), Qnil);
7b00d185 3434
819b8f00
KL
3435}
3436
3437
3438
ab5796a9
MB
3439/* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
3440 (do not change this comment) */