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