comparison src/term.c @ 83716:a73440d2f146 merge-multi-tty-to-trunk

Merge multi-tty branch Revision: emacs@sv.gnu.org/emacs--devo--0--patch-866
author Miles Bader <miles@gnu.org>
date Wed, 29 Aug 2007 05:28:10 +0000
parents 2a69b973fae2
children ffb5395e8445
comparison
equal deleted inserted replaced
82950:ed8435ec5652 83716:a73440d2f146
23 23
24 #include <config.h> 24 #include <config.h>
25 #include <stdio.h> 25 #include <stdio.h>
26 #include <ctype.h> 26 #include <ctype.h>
27 #include <string.h> 27 #include <string.h>
28 #include <errno.h>
29 #include <sys/file.h>
30
28 #ifdef HAVE_UNISTD_H 31 #ifdef HAVE_UNISTD_H
29 #include <unistd.h> 32 #include <unistd.h>
30 #endif 33 #endif
31 34
35 #if HAVE_TERMIOS_H
36 #include <termios.h> /* For TIOCNOTTY. */
37 #endif
38
39 #include <signal.h>
40
41 #include "lisp.h"
32 #include "termchar.h" 42 #include "termchar.h"
33 #include "termopts.h" 43 #include "termopts.h"
34 #include "lisp.h"
35 #include "charset.h" 44 #include "charset.h"
36 #include "coding.h" 45 #include "coding.h"
37 #include "keyboard.h" 46 #include "keyboard.h"
38 #include "frame.h" 47 #include "frame.h"
39 #include "disptab.h" 48 #include "disptab.h"
40 #include "termhooks.h" 49 #include "termhooks.h"
41 #include "dispextern.h" 50 #include "dispextern.h"
42 #include "window.h" 51 #include "window.h"
43 #include "keymap.h" 52 #include "keymap.h"
44 #include "blockinput.h" 53 #include "blockinput.h"
54 #include "syssignal.h"
55 #include "systty.h"
45 #include "intervals.h" 56 #include "intervals.h"
46 57
47 /* For now, don't try to include termcap.h. On some systems, 58 /* For now, don't try to include termcap.h. On some systems,
48 configure finds a non-standard termcap.h that the main build 59 configure finds a non-standard termcap.h that the main build
49 won't find. */ 60 won't find. */
63 #endif 74 #endif
64 #ifdef MAC_OS 75 #ifdef MAC_OS
65 #include "macterm.h" 76 #include "macterm.h"
66 #endif 77 #endif
67 78
79 #ifndef O_RDWR
80 #define O_RDWR 2
81 #endif
82
83 #ifndef O_NOCTTY
84 #define O_NOCTTY 0
85 #endif
86
87 static void tty_set_scroll_region P_ ((struct frame *f, int start, int stop));
68 static void turn_on_face P_ ((struct frame *, int face_id)); 88 static void turn_on_face P_ ((struct frame *, int face_id));
69 static void turn_off_face P_ ((struct frame *, int face_id)); 89 static void turn_off_face P_ ((struct frame *, int face_id));
70 static void tty_show_cursor P_ ((void)); 90 static void tty_show_cursor P_ ((struct tty_display_info *));
71 static void tty_hide_cursor P_ ((void)); 91 static void tty_hide_cursor P_ ((struct tty_display_info *));
72 92 static void tty_background_highlight P_ ((struct tty_display_info *tty));
73 #define OUTPUT(a) \ 93 static void clear_tty_hooks P_ ((struct terminal *terminal));
74 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) - curY), cmputc) 94 static void set_tty_hooks P_ ((struct terminal *terminal));
75 #define OUTPUT1(a) tputs (a, 1, cmputc) 95 static void dissociate_if_controlling_tty P_ ((int fd));
76 #define OUTPUTL(a, lines) tputs (a, lines, cmputc) 96 static void delete_tty P_ ((struct terminal *));
77 97
78 #define OUTPUT_IF(a) \ 98 #define OUTPUT(tty, a) \
79 do { \ 99 emacs_tputs ((tty), a, \
80 if (a) \ 100 (int) (FRAME_LINES (XFRAME (selected_frame)) \
81 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) \ 101 - curY (tty)), \
82 - curY), cmputc); \ 102 cmputc)
83 } while (0) 103
84 104 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
85 #define OUTPUT1_IF(a) do { if (a) tputs (a, 1, cmputc); } while (0) 105 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
106
107 #define OUTPUT_IF(tty, a) \
108 do { \
109 if (a) \
110 emacs_tputs ((tty), a, \
111 (int) (FRAME_LINES (XFRAME (selected_frame)) \
112 - curY (tty) ), \
113 cmputc); \
114 } while (0)
115
116 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
117
118 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */
119
120 static int visible_cursor;
86 121
87 /* Display space properties */ 122 /* Display space properties */
88 123
89 extern Lisp_Object Qspace, QCalign_to, QCwidth; 124 extern Lisp_Object Qspace, QCalign_to, QCwidth;
90 125
91 /* Function to use to ring the bell. */ 126 /* Functions to call after suspending a tty. */
92 127 Lisp_Object Vsuspend_tty_functions;
93 Lisp_Object Vring_bell_function; 128
94 129 /* Functions to call after resuming a tty. */
95 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */ 130 Lisp_Object Vresume_tty_functions;
96 131
97 static int visible_cursor; 132 /* Chain of all tty device parameters. */
98 133 struct tty_display_info *tty_list;
99 /* Terminal characteristics that higher levels want to look at. 134
100 These are all extern'd in termchar.h */ 135 /* Nonzero means no need to redraw the entire frame on resuming a
101 136 suspended Emacs. This is useful on terminals with multiple
102 int must_write_spaces; /* Nonzero means spaces in the text 137 pages, where one page is used for Emacs and another for all
103 must actually be output; can't just skip 138 else. */
104 over some columns to leave them blank. */
105 int min_padding_speed; /* Speed below which no padding necessary */
106
107 int line_ins_del_ok; /* Terminal can insert and delete lines */
108 int char_ins_del_ok; /* Terminal can insert and delete chars */
109 int scroll_region_ok; /* Terminal supports setting the
110 scroll window */
111 int scroll_region_cost; /* Cost of setting a scroll window,
112 measured in characters */
113 int memory_below_frame; /* Terminal remembers lines
114 scrolled off bottom */
115 int fast_clear_end_of_line; /* Terminal has a `ce' string */
116
117 /* Nonzero means no need to redraw the entire frame on resuming
118 a suspended Emacs. This is useful on terminals with multiple pages,
119 where one page is used for Emacs and another for all else. */
120
121 int no_redraw_on_reenter; 139 int no_redraw_on_reenter;
122
123 /* Hook functions that you can set to snap out the functions in this file.
124 These are all extern'd in termhooks.h */
125
126 void (*cursor_to_hook) P_ ((int, int));
127 void (*raw_cursor_to_hook) P_ ((int, int));
128 void (*clear_to_end_hook) P_ ((void));
129 void (*clear_frame_hook) P_ ((void));
130 void (*clear_end_of_line_hook) P_ ((int));
131
132 void (*ins_del_lines_hook) P_ ((int, int));
133
134 void (*delete_glyphs_hook) P_ ((int));
135
136 void (*ring_bell_hook) P_ ((void));
137
138 void (*reset_terminal_modes_hook) P_ ((void));
139 void (*set_terminal_modes_hook) P_ ((void));
140 void (*update_begin_hook) P_ ((struct frame *));
141 void (*update_end_hook) P_ ((struct frame *));
142 void (*set_terminal_window_hook) P_ ((int));
143 void (*insert_glyphs_hook) P_ ((struct glyph *, int));
144 void (*write_glyphs_hook) P_ ((struct glyph *, int));
145 void (*delete_glyphs_hook) P_ ((int));
146
147 int (*read_socket_hook) P_ ((int, int, struct input_event *));
148
149 void (*frame_up_to_date_hook) P_ ((struct frame *));
150
151 void (*mouse_position_hook) P_ ((FRAME_PTR *f, int insist,
152 Lisp_Object *bar_window,
153 enum scroll_bar_part *part,
154 Lisp_Object *x,
155 Lisp_Object *y,
156 unsigned long *time));
157
158 /* When reading from a minibuffer in a different frame, Emacs wants
159 to shift the highlight from the selected frame to the mini-buffer's
160 frame; under X, this means it lies about where the focus is.
161 This hook tells the window system code to re-decide where to put
162 the highlight. */
163
164 void (*frame_rehighlight_hook) P_ ((FRAME_PTR f));
165
166 /* If we're displaying frames using a window system that can stack
167 frames on top of each other, this hook allows you to bring a frame
168 to the front, or bury it behind all the other windows. If this
169 hook is zero, that means the device we're displaying on doesn't
170 support overlapping frames, so there's no need to raise or lower
171 anything.
172
173 If RAISE is non-zero, F is brought to the front, before all other
174 windows. If RAISE is zero, F is sent to the back, behind all other
175 windows. */
176
177 void (*frame_raise_lower_hook) P_ ((FRAME_PTR f, int raise));
178
179 /* If the value of the frame parameter changed, whis hook is called.
180 For example, if going from fullscreen to not fullscreen this hook
181 may do something OS dependent, like extended window manager hints on X11. */
182 void (*fullscreen_hook) P_ ((struct frame *f));
183
184 /* Set the vertical scroll bar for WINDOW to have its upper left corner
185 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
186 indicate that we are displaying PORTION characters out of a total
187 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
188 have a scroll bar, create one for it. */
189
190 void (*set_vertical_scroll_bar_hook)
191 P_ ((struct window *window,
192 int portion, int whole, int position));
193
194
195 /* The following three hooks are used when we're doing a thorough
196 redisplay of the frame. We don't explicitly know which scroll bars
197 are going to be deleted, because keeping track of when windows go
198 away is a real pain - can you say set-window-configuration?
199 Instead, we just assert at the beginning of redisplay that *all*
200 scroll bars are to be removed, and then save scroll bars from the
201 fiery pit when we actually redisplay their window. */
202
203 /* Arrange for all scroll bars on FRAME to be removed at the next call
204 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
205 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
206
207 This should be applied to each frame each time its window tree is
208 redisplayed, even if it is not displaying scroll bars at the moment;
209 if the HAS_SCROLL_BARS flag has just been turned off, only calling
210 this and the judge_scroll_bars_hook will get rid of them.
211
212 If non-zero, this hook should be safe to apply to any frame,
213 whether or not it can support scroll bars, and whether or not it is
214 currently displaying them. */
215
216 void (*condemn_scroll_bars_hook) P_ ((FRAME_PTR frame));
217
218 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
219 Note that it's okay to redeem a scroll bar that is not condemned. */
220
221 void (*redeem_scroll_bar_hook) P_ ((struct window *window));
222
223 /* Remove all scroll bars on FRAME that haven't been saved since the
224 last call to `*condemn_scroll_bars_hook'.
225
226 This should be applied to each frame after each time its window
227 tree is redisplayed, even if it is not displaying scroll bars at the
228 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
229 calling this and condemn_scroll_bars_hook will get rid of them.
230
231 If non-zero, this hook should be safe to apply to any frame,
232 whether or not it can support scroll bars, and whether or not it is
233 currently displaying them. */
234
235 void (*judge_scroll_bars_hook) P_ ((FRAME_PTR FRAME));
236
237 /* Strings, numbers and flags taken from the termcap entry. */
238
239 char *TS_ins_line; /* "al" */
240 char *TS_ins_multi_lines; /* "AL" (one parameter, # lines to insert) */
241 char *TS_bell; /* "bl" */
242 char *TS_clr_to_bottom; /* "cd" */
243 char *TS_clr_line; /* "ce", clear to end of line */
244 char *TS_clr_frame; /* "cl" */
245 char *TS_set_scroll_region; /* "cs" (2 params, first line and last line) */
246 char *TS_set_scroll_region_1; /* "cS" (4 params: total lines,
247 lines above scroll region, lines below it,
248 total lines again) */
249 char *TS_del_char; /* "dc" */
250 char *TS_del_multi_chars; /* "DC" (one parameter, # chars to delete) */
251 char *TS_del_line; /* "dl" */
252 char *TS_del_multi_lines; /* "DL" (one parameter, # lines to delete) */
253 char *TS_delete_mode; /* "dm", enter character-delete mode */
254 char *TS_end_delete_mode; /* "ed", leave character-delete mode */
255 char *TS_end_insert_mode; /* "ei", leave character-insert mode */
256 char *TS_ins_char; /* "ic" */
257 char *TS_ins_multi_chars; /* "IC" (one parameter, # chars to insert) */
258 char *TS_insert_mode; /* "im", enter character-insert mode */
259 char *TS_pad_inserted_char; /* "ip". Just padding, no commands. */
260 char *TS_end_keypad_mode; /* "ke" */
261 char *TS_keypad_mode; /* "ks" */
262 char *TS_pad_char; /* "pc", char to use as padding */
263 char *TS_repeat; /* "rp" (2 params, # times to repeat
264 and character to be repeated) */
265 char *TS_end_standout_mode; /* "se" */
266 char *TS_fwd_scroll; /* "sf" */
267 char *TS_standout_mode; /* "so" */
268 char *TS_rev_scroll; /* "sr" */
269 char *TS_end_termcap_modes; /* "te" */
270 char *TS_termcap_modes; /* "ti" */
271 char *TS_visible_bell; /* "vb" */
272 char *TS_cursor_normal; /* "ve" */
273 char *TS_cursor_visible; /* "vs" */
274 char *TS_cursor_invisible; /* "vi" */
275 char *TS_set_window; /* "wi" (4 params, start and end of window,
276 each as vpos and hpos) */
277
278 /* Value of the "NC" (no_color_video) capability, or 0 if not
279 present. */
280
281 static int TN_no_color_video;
282 140
283 /* Meaning of bits in no_color_video. Each bit set means that the 141 /* Meaning of bits in no_color_video. Each bit set means that the
284 corresponding attribute cannot be combined with colors. */ 142 corresponding attribute cannot be combined with colors. */
285 143
286 enum no_color_bit 144 enum no_color_bit
294 NC_INVIS = 1 << 6, 152 NC_INVIS = 1 << 6,
295 NC_PROTECT = 1 << 7, 153 NC_PROTECT = 1 << 7,
296 NC_ALT_CHARSET = 1 << 8 154 NC_ALT_CHARSET = 1 << 8
297 }; 155 };
298 156
299 /* "md" -- turn on bold (extra bright mode). */
300
301 char *TS_enter_bold_mode;
302
303 /* "mh" -- turn on half-bright mode. */
304
305 char *TS_enter_dim_mode;
306
307 /* "mb" -- enter blinking mode. */
308
309 char *TS_enter_blink_mode;
310
311 /* "mr" -- enter reverse video mode. */
312
313 char *TS_enter_reverse_mode;
314
315 /* "us"/"ue" -- start/end underlining. */
316
317 char *TS_exit_underline_mode, *TS_enter_underline_mode;
318
319 /* "as"/"ae" -- start/end alternate character set. Not really
320 supported, yet. */
321
322 char *TS_enter_alt_charset_mode, *TS_exit_alt_charset_mode;
323
324 /* "me" -- switch appearances off. */
325
326 char *TS_exit_attribute_mode;
327
328 /* "Co" -- number of colors. */
329
330 int TN_max_colors;
331
332 /* "pa" -- max. number of color pairs on screen. Not handled yet.
333 Could be a problem if not equal to TN_max_colors * TN_max_colors. */
334
335 int TN_max_pairs;
336
337 /* "op" -- SVr4 set default pair to its original value. */
338
339 char *TS_orig_pair;
340
341 /* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
342 1 param, the color index. */
343
344 char *TS_set_foreground, *TS_set_background;
345
346 int TF_hazeltine; /* termcap hz flag. */
347 int TF_insmode_motion; /* termcap mi flag: can move while in insert mode. */
348 int TF_standout_motion; /* termcap mi flag: can move while in standout mode. */
349 int TF_underscore; /* termcap ul flag: _ underlines if over-struck on
350 non-blank position. Must clear before writing _. */
351 int TF_teleray; /* termcap xt flag: many weird consequences.
352 For t1061. */
353
354 static int RPov; /* # chars to start a TS_repeat */
355
356 static int delete_in_insert_mode; /* delete mode == insert mode */
357
358 static int se_is_so; /* 1 if same string both enters and leaves
359 standout mode */
360
361 /* internal state */ 157 /* internal state */
362 158
363 /* The largest frame width in any call to calculate_costs. */ 159 /* The largest frame width in any call to calculate_costs. */
364 160
365 int max_frame_cols; 161 int max_frame_cols;
366 162
367 /* The largest frame height in any call to calculate_costs. */ 163 /* The largest frame height in any call to calculate_costs. */
368 164
369 int max_frame_lines; 165 int max_frame_lines;
370 166
371 static int costs_set; /* Nonzero if costs have been calculated. */ 167 /* Non-zero if we have dropped our controlling tty and therefore
372 168 should not open a frame on stdout. */
373 int insert_mode; /* Nonzero when in insert mode. */ 169 static int no_controlling_tty;
374 int standout_mode; /* Nonzero when in standout mode. */
375
376 /* Size of window specified by higher levels.
377 This is the number of lines, from the top of frame downwards,
378 which can participate in insert-line/delete-line operations.
379
380 Effectively it excludes the bottom frame_lines - specified_window_size
381 lines from those operations. */
382
383 int specified_window;
384
385 /* Frame currently being redisplayed; 0 if not currently redisplaying.
386 (Direct output does not count). */
387
388 FRAME_PTR updating_frame;
389 170
390 /* Provided for lisp packages. */ 171 /* Provided for lisp packages. */
391 172
392 static int system_uses_terminfo; 173 static int system_uses_terminfo;
393
394 /* Flag used in tty_show/hide_cursor. */
395
396 static int tty_cursor_hidden;
397 174
398 char *tparam (); 175 char *tparam ();
399 176
400 extern char *tgetstr (); 177 extern char *tgetstr ();
401 178
418 #include <sys/fcntl.h> 195 #include <sys/fcntl.h>
419 #include "buffer.h" 196 #include "buffer.h"
420 197
421 /* Nonzero means mouse is enabled on Linux console. */ 198 /* Nonzero means mouse is enabled on Linux console. */
422 int term_gpm = 0; 199 int term_gpm = 0;
200
201 /* The id of the terminal device for which we have gpm support. */
202 int gpm_tty;
423 203
424 /* These variables describe the range of text currently shown in its 204 /* These variables describe the range of text currently shown in its
425 mouse-face, together with the window they apply to. As long as 205 mouse-face, together with the window they apply to. As long as
426 the mouse stays within this range, we need not redraw anything on 206 the mouse stays within this range, we need not redraw anything on
427 its account. Rows and columns are glyph matrix positions in 207 its account. Rows and columns are glyph matrix positions in
434 214
435 static int pos_x, pos_y; 215 static int pos_x, pos_y;
436 static int last_mouse_x, last_mouse_y; 216 static int last_mouse_x, last_mouse_y;
437 #endif /* HAVE_GPM */ 217 #endif /* HAVE_GPM */
438 218
219 /* Ring the bell on a tty. */
220
221 static void
222 tty_ring_bell (struct frame *f)
223 {
224 struct tty_display_info *tty = FRAME_TTY (f);
225
226 if (tty->output)
227 {
228 OUTPUT (tty, (tty->TS_visible_bell && visible_bell
229 ? tty->TS_visible_bell
230 : tty->TS_bell));
231 fflush (tty->output);
232 }
233 }
234
235 /* Set up termcap modes for Emacs. */
236
439 void 237 void
440 ring_bell () 238 tty_set_terminal_modes (struct terminal *terminal)
441 { 239 {
442 if (!NILP (Vring_bell_function)) 240 struct tty_display_info *tty = terminal->display_info.tty;
443 { 241
444 Lisp_Object function; 242 if (tty->output)
445 243 {
446 /* Temporarily set the global variable to nil 244 if (tty->TS_termcap_modes)
447 so that if we get an error, it stays nil 245 OUTPUT (tty, tty->TS_termcap_modes);
448 and we don't call it over and over. 246 else
449 247 {
450 We don't specbind it, because that would carefully 248 /* Output enough newlines to scroll all the old screen contents
451 restore the bad value if there's an error 249 off the screen, so it won't be overwritten and lost. */
452 and make the loop of errors happen anyway. */ 250 int i;
453 251 current_tty = tty;
454 function = Vring_bell_function; 252 for (i = 0; i < FRAME_LINES (XFRAME (selected_frame)); i++)
455 Vring_bell_function = Qnil; 253 cmputc ('\n');
456 254 }
457 call0 (function); 255
458 256 OUTPUT_IF (tty, tty->TS_termcap_modes);
459 Vring_bell_function = function; 257 OUTPUT_IF (tty, visible_cursor ? tty->TS_cursor_visible : tty->TS_cursor_normal);
460 } 258 OUTPUT_IF (tty, tty->TS_keypad_mode);
461 else if (!FRAME_TERMCAP_P (XFRAME (selected_frame))) 259 losecursor (tty);
462 (*ring_bell_hook) (); 260 fflush (tty->output);
261 }
262 }
263
264 /* Reset termcap modes before exiting Emacs. */
265
266 void
267 tty_reset_terminal_modes (struct terminal *terminal)
268 {
269 struct tty_display_info *tty = terminal->display_info.tty;
270
271 if (tty->output)
272 {
273 tty_turn_off_highlight (tty);
274 tty_turn_off_insert (tty);
275 OUTPUT_IF (tty, tty->TS_end_keypad_mode);
276 OUTPUT_IF (tty, tty->TS_cursor_normal);
277 OUTPUT_IF (tty, tty->TS_end_termcap_modes);
278 OUTPUT_IF (tty, tty->TS_orig_pair);
279 /* Output raw CR so kernel can track the cursor hpos. */
280 current_tty = tty;
281 cmputc ('\r');
282 fflush (tty->output);
283 }
284 }
285
286 /* Flag the end of a display update on a termcap terminal. */
287
288 static void
289 tty_update_end (struct frame *f)
290 {
291 struct tty_display_info *tty = FRAME_TTY (f);
292
293 if (!XWINDOW (selected_window)->cursor_off_p)
294 tty_show_cursor (tty);
295 tty_turn_off_insert (tty);
296 tty_background_highlight (tty);
297 }
298
299 /* The implementation of set_terminal_window for termcap frames. */
300
301 static void
302 tty_set_terminal_window (struct frame *f, int size)
303 {
304 struct tty_display_info *tty = FRAME_TTY (f);
305
306 tty->specified_window = size ? size : FRAME_LINES (f);
307 if (FRAME_SCROLL_REGION_OK (f))
308 tty_set_scroll_region (f, 0, tty->specified_window);
309 }
310
311 static void
312 tty_set_scroll_region (struct frame *f, int start, int stop)
313 {
314 char *buf;
315 struct tty_display_info *tty = FRAME_TTY (f);
316
317 if (tty->TS_set_scroll_region)
318 buf = tparam (tty->TS_set_scroll_region, 0, 0, start, stop - 1);
319 else if (tty->TS_set_scroll_region_1)
320 buf = tparam (tty->TS_set_scroll_region_1, 0, 0,
321 FRAME_LINES (f), start,
322 FRAME_LINES (f) - stop,
323 FRAME_LINES (f));
463 else 324 else
464 OUTPUT (TS_visible_bell && visible_bell ? TS_visible_bell : TS_bell); 325 buf = tparam (tty->TS_set_window, 0, 0, start, 0, stop, FRAME_COLS (f));
465 } 326
466 327 OUTPUT (tty, buf);
467 void
468 set_terminal_modes ()
469 {
470 if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
471 {
472 if (TS_termcap_modes)
473 OUTPUT (TS_termcap_modes);
474 else
475 {
476 /* Output enough newlines to scroll all the old screen contents
477 off the screen, so it won't be overwritten and lost. */
478 int i;
479 for (i = 0; i < FRAME_LINES (XFRAME (selected_frame)); i++)
480 putchar ('\n');
481 }
482
483 OUTPUT_IF (visible_cursor ? TS_cursor_visible : TS_cursor_normal);
484 OUTPUT_IF (TS_keypad_mode);
485 losecursor ();
486 }
487 else
488 (*set_terminal_modes_hook) ();
489 }
490
491 void
492 reset_terminal_modes ()
493 {
494 if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
495 {
496 turn_off_highlight ();
497 turn_off_insert ();
498 OUTPUT_IF (TS_end_keypad_mode);
499 OUTPUT_IF (TS_cursor_normal);
500 OUTPUT_IF (TS_end_termcap_modes);
501 OUTPUT_IF (TS_orig_pair);
502 /* Output raw CR so kernel can track the cursor hpos. */
503 cmputc ('\r');
504 }
505 else if (reset_terminal_modes_hook)
506 (*reset_terminal_modes_hook) ();
507 }
508
509 void
510 update_begin (f)
511 struct frame *f;
512 {
513 updating_frame = f;
514 if (!FRAME_TERMCAP_P (f))
515 update_begin_hook (f);
516 }
517
518 void
519 update_end (f)
520 struct frame *f;
521 {
522 if (FRAME_TERMCAP_P (f))
523 {
524 if (!XWINDOW (selected_window)->cursor_off_p)
525 tty_show_cursor ();
526 turn_off_insert ();
527 background_highlight ();
528 }
529 else
530 update_end_hook (f);
531
532 updating_frame = NULL;
533 }
534
535 void
536 set_terminal_window (size)
537 int size;
538 {
539 if (FRAME_TERMCAP_P (updating_frame))
540 {
541 specified_window = size ? size : FRAME_LINES (updating_frame);
542 if (scroll_region_ok)
543 set_scroll_region (0, specified_window);
544 }
545 else
546 set_terminal_window_hook (size);
547 }
548
549 void
550 set_scroll_region (start, stop)
551 int start, stop;
552 {
553 char *buf;
554 struct frame *sf = XFRAME (selected_frame);
555
556 if (TS_set_scroll_region)
557 buf = tparam (TS_set_scroll_region, 0, 0, start, stop - 1);
558 else if (TS_set_scroll_region_1)
559 buf = tparam (TS_set_scroll_region_1, 0, 0,
560 FRAME_LINES (sf), start,
561 FRAME_LINES (sf) - stop,
562 FRAME_LINES (sf));
563 else
564 buf = tparam (TS_set_window, 0, 0, start, 0, stop, FRAME_COLS (sf));
565
566 OUTPUT (buf);
567 xfree (buf); 328 xfree (buf);
568 losecursor (); 329 losecursor (tty);
569 } 330 }
570 331
571 332
572 static void 333 static void
573 turn_on_insert () 334 tty_turn_on_insert (struct tty_display_info *tty)
574 { 335 {
575 if (!insert_mode) 336 if (!tty->insert_mode)
576 OUTPUT (TS_insert_mode); 337 OUTPUT (tty, tty->TS_insert_mode);
577 insert_mode = 1; 338 tty->insert_mode = 1;
578 } 339 }
579 340
580 void 341 void
581 turn_off_insert () 342 tty_turn_off_insert (struct tty_display_info *tty)
582 { 343 {
583 if (insert_mode) 344 if (tty->insert_mode)
584 OUTPUT (TS_end_insert_mode); 345 OUTPUT (tty, tty->TS_end_insert_mode);
585 insert_mode = 0; 346 tty->insert_mode = 0;
586 } 347 }
587 348
588 /* Handle highlighting. */ 349 /* Handle highlighting. */
589 350
590 void 351 void
591 turn_off_highlight () 352 tty_turn_off_highlight (struct tty_display_info *tty)
592 { 353 {
593 if (standout_mode) 354 if (tty->standout_mode)
594 OUTPUT_IF (TS_end_standout_mode); 355 OUTPUT_IF (tty, tty->TS_end_standout_mode);
595 standout_mode = 0; 356 tty->standout_mode = 0;
596 } 357 }
597 358
598 static void 359 static void
599 turn_on_highlight () 360 tty_turn_on_highlight (struct tty_display_info *tty)
600 { 361 {
601 if (!standout_mode) 362 if (!tty->standout_mode)
602 OUTPUT_IF (TS_standout_mode); 363 OUTPUT_IF (tty, tty->TS_standout_mode);
603 standout_mode = 1; 364 tty->standout_mode = 1;
604 } 365 }
605 366
606 static void 367 static void
607 toggle_highlight () 368 tty_toggle_highlight (struct tty_display_info *tty)
608 { 369 {
609 if (standout_mode) 370 if (tty->standout_mode)
610 turn_off_highlight (); 371 tty_turn_off_highlight (tty);
611 else 372 else
612 turn_on_highlight (); 373 tty_turn_on_highlight (tty);
613 } 374 }
614 375
615 376
616 /* Make cursor invisible. */ 377 /* Make cursor invisible. */
617 378
618 static void 379 static void
619 tty_hide_cursor () 380 tty_hide_cursor (struct tty_display_info *tty)
620 { 381 {
621 if (tty_cursor_hidden == 0) 382 if (tty->cursor_hidden == 0)
622 { 383 {
623 tty_cursor_hidden = 1; 384 tty->cursor_hidden = 1;
624 OUTPUT_IF (TS_cursor_invisible); 385 OUTPUT_IF (tty, tty->TS_cursor_invisible);
625 } 386 }
626 } 387 }
627 388
628 389
629 /* Ensure that cursor is visible. */ 390 /* Ensure that cursor is visible. */
630 391
631 static void 392 static void
632 tty_show_cursor () 393 tty_show_cursor (struct tty_display_info *tty)
633 { 394 {
634 if (tty_cursor_hidden) 395 if (tty->cursor_hidden)
635 { 396 {
636 tty_cursor_hidden = 0; 397 tty->cursor_hidden = 0;
637 OUTPUT_IF (TS_cursor_normal); 398 OUTPUT_IF (tty, tty->TS_cursor_normal);
638 if (visible_cursor) 399 if (visible_cursor)
639 OUTPUT_IF (TS_cursor_visible); 400 OUTPUT_IF (tty, tty->TS_cursor_visible);
640 } 401 }
641 } 402 }
642 403
643 404
644 /* Set standout mode to the state it should be in for 405 /* Set standout mode to the state it should be in for
645 empty space inside windows. What this is, 406 empty space inside windows. What this is,
646 depends on the user option inverse-video. */ 407 depends on the user option inverse-video. */
647 408
648 void 409 static void
649 background_highlight () 410 tty_background_highlight (struct tty_display_info *tty)
650 { 411 {
651 if (inverse_video) 412 if (inverse_video)
652 turn_on_highlight (); 413 tty_turn_on_highlight (tty);
653 else 414 else
654 turn_off_highlight (); 415 tty_turn_off_highlight (tty);
655 } 416 }
656 417
657 /* Set standout mode to the mode specified for the text to be output. */ 418 /* Set standout mode to the mode specified for the text to be output. */
658 419
659 static void 420 static void
660 highlight_if_desired () 421 tty_highlight_if_desired (struct tty_display_info *tty)
661 { 422 {
662 if (inverse_video) 423 if (inverse_video)
663 turn_on_highlight (); 424 tty_turn_on_highlight (tty);
664 else 425 else
665 turn_off_highlight (); 426 tty_turn_off_highlight (tty);
666 } 427 }
667 428
668 429
669 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are 430 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
670 frame-relative coordinates. */ 431 frame-relative coordinates. */
671 432
672 void 433 static void
673 cursor_to (vpos, hpos) 434 tty_cursor_to (struct frame *f, int vpos, int hpos)
674 int vpos, hpos; 435 {
675 { 436 struct tty_display_info *tty = FRAME_TTY (f);
676 struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame);
677
678 if (! FRAME_TERMCAP_P (f) && cursor_to_hook)
679 {
680 (*cursor_to_hook) (vpos, hpos);
681 return;
682 }
683 437
684 /* Detect the case where we are called from reset_sys_modes 438 /* Detect the case where we are called from reset_sys_modes
685 and the costs have never been calculated. Do nothing. */ 439 and the costs have never been calculated. Do nothing. */
686 if (! costs_set) 440 if (! tty->costs_set)
687 return; 441 return;
688 442
689 if (curY == vpos && curX == hpos) 443 if (curY (tty) == vpos
444 && curX (tty) == hpos)
690 return; 445 return;
691 if (!TF_standout_motion) 446 if (!tty->TF_standout_motion)
692 background_highlight (); 447 tty_background_highlight (tty);
693 if (!TF_insmode_motion) 448 if (!tty->TF_insmode_motion)
694 turn_off_insert (); 449 tty_turn_off_insert (tty);
695 cmgoto (vpos, hpos); 450 cmgoto (tty, vpos, hpos);
696 } 451 }
697 452
698 /* Similar but don't take any account of the wasted characters. */ 453 /* Similar but don't take any account of the wasted characters. */
699 454
700 void 455 static void
701 raw_cursor_to (row, col) 456 tty_raw_cursor_to (struct frame *f, int row, int col)
702 int row, col; 457 {
703 { 458 struct tty_display_info *tty = FRAME_TTY (f);
704 struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame); 459
705 if (! FRAME_TERMCAP_P (f)) 460 if (curY (tty) == row
706 { 461 && curX (tty) == col)
707 (*raw_cursor_to_hook) (row, col);
708 return;
709 }
710 if (curY == row && curX == col)
711 return; 462 return;
712 if (!TF_standout_motion) 463 if (!tty->TF_standout_motion)
713 background_highlight (); 464 tty_background_highlight (tty);
714 if (!TF_insmode_motion) 465 if (!tty->TF_insmode_motion)
715 turn_off_insert (); 466 tty_turn_off_insert (tty);
716 cmgoto (row, col); 467 cmgoto (tty, row, col);
717 } 468 }
718 469
719 /* Erase operations */ 470 /* Erase operations */
720 471
721 /* clear from cursor to end of frame */ 472 /* Clear from cursor to end of frame on a termcap device. */
722 void 473
723 clear_to_end () 474 static void
475 tty_clear_to_end (struct frame *f)
724 { 476 {
725 register int i; 477 register int i;
726 478 struct tty_display_info *tty = FRAME_TTY (f);
727 if (clear_to_end_hook && ! FRAME_TERMCAP_P (updating_frame)) 479
728 { 480 if (tty->TS_clr_to_bottom)
729 (*clear_to_end_hook) (); 481 {
730 return; 482 tty_background_highlight (tty);
731 } 483 OUTPUT (tty, tty->TS_clr_to_bottom);
732 if (TS_clr_to_bottom)
733 {
734 background_highlight ();
735 OUTPUT (TS_clr_to_bottom);
736 } 484 }
737 else 485 else
738 { 486 {
739 for (i = curY; i < FRAME_LINES (XFRAME (selected_frame)); i++) 487 for (i = curY (tty); i < FRAME_LINES (f); i++)
740 { 488 {
741 cursor_to (i, 0); 489 cursor_to (f, i, 0);
742 clear_end_of_line (FRAME_COLS (XFRAME (selected_frame))); 490 clear_end_of_line (f, FRAME_COLS (f));
743 } 491 }
744 } 492 }
745 } 493 }
746 494
747 /* Clear entire frame */ 495 /* Clear an entire termcap frame. */
748 496
749 void 497 static void
750 clear_frame () 498 tty_clear_frame (struct frame *f)
751 { 499 {
752 struct frame *sf = XFRAME (selected_frame); 500 struct tty_display_info *tty = FRAME_TTY (f);
753 501
754 if (clear_frame_hook 502 if (tty->TS_clr_frame)
755 && ! FRAME_TERMCAP_P ((updating_frame ? updating_frame : sf))) 503 {
756 { 504 tty_background_highlight (tty);
757 (*clear_frame_hook) (); 505 OUTPUT (tty, tty->TS_clr_frame);
758 return; 506 cmat (tty, 0, 0);
759 }
760 if (TS_clr_frame)
761 {
762 background_highlight ();
763 OUTPUT (TS_clr_frame);
764 cmat (0, 0);
765 } 507 }
766 else 508 else
767 { 509 {
768 cursor_to (0, 0); 510 cursor_to (f, 0, 0);
769 clear_to_end (); 511 clear_to_end (f);
770 } 512 }
771 } 513 }
772 514
773 /* Clear from cursor to end of line. 515 /* An implementation of clear_end_of_line for termcap frames.
774 Assume that the line is already clear starting at column first_unused_hpos.
775 516
776 Note that the cursor may be moved, on terminals lacking a `ce' string. */ 517 Note that the cursor may be moved, on terminals lacking a `ce' string. */
777 518
778 void 519 static void
779 clear_end_of_line (first_unused_hpos) 520 tty_clear_end_of_line (struct frame *f, int first_unused_hpos)
780 int first_unused_hpos;
781 { 521 {
782 register int i; 522 register int i;
783 523 struct tty_display_info *tty = FRAME_TTY (f);
784 if (clear_end_of_line_hook
785 && ! FRAME_TERMCAP_P ((updating_frame
786 ? updating_frame
787 : XFRAME (selected_frame))))
788 {
789 (*clear_end_of_line_hook) (first_unused_hpos);
790 return;
791 }
792 524
793 /* Detect the case where we are called from reset_sys_modes 525 /* Detect the case where we are called from reset_sys_modes
794 and the costs have never been calculated. Do nothing. */ 526 and the costs have never been calculated. Do nothing. */
795 if (! costs_set) 527 if (! tty->costs_set)
796 return; 528 return;
797 529
798 if (curX >= first_unused_hpos) 530 if (curX (tty) >= first_unused_hpos)
799 return; 531 return;
800 background_highlight (); 532 tty_background_highlight (tty);
801 if (TS_clr_line) 533 if (tty->TS_clr_line)
802 { 534 {
803 OUTPUT1 (TS_clr_line); 535 OUTPUT1 (tty, tty->TS_clr_line);
804 } 536 }
805 else 537 else
806 { /* have to do it the hard way */ 538 { /* have to do it the hard way */
807 struct frame *sf = XFRAME (selected_frame); 539 tty_turn_off_insert (tty);
808 turn_off_insert ();
809 540
810 /* Do not write in last row last col with Auto-wrap on. */ 541 /* Do not write in last row last col with Auto-wrap on. */
811 if (AutoWrap && curY == FRAME_LINES (sf) - 1 542 if (AutoWrap (tty)
812 && first_unused_hpos == FRAME_COLS (sf)) 543 && curY (tty) == FrameRows (tty) - 1
544 && first_unused_hpos == FrameCols (tty))
813 first_unused_hpos--; 545 first_unused_hpos--;
814 546
815 for (i = curX; i < first_unused_hpos; i++) 547 for (i = curX (tty); i < first_unused_hpos; i++)
816 { 548 {
817 if (termscript) 549 if (tty->termscript)
818 fputc (' ', termscript); 550 fputc (' ', tty->termscript);
819 putchar (' '); 551 fputc (' ', tty->output);
820 } 552 }
821 cmplus (first_unused_hpos - curX); 553 cmplus (tty, first_unused_hpos - curX (tty));
822 } 554 }
823 } 555 }
824 556
825 /* Buffer to store the source and result of code conversion for terminal. */ 557 /* Buffer to store the source and result of code conversion for terminal. */
826 static unsigned char *encode_terminal_buf; 558 static unsigned char *encode_terminal_buf;
938 encode_coding (coding, encode_terminal_buf, encode_terminal_buf + nbytes, 670 encode_coding (coding, encode_terminal_buf, encode_terminal_buf + nbytes,
939 nbytes, encode_terminal_bufsize - nbytes); 671 nbytes, encode_terminal_bufsize - nbytes);
940 return encode_terminal_buf + nbytes; 672 return encode_terminal_buf + nbytes;
941 } 673 }
942 674
943 void 675
944 write_glyphs (string, len) 676 /* An implementation of write_glyphs for termcap frames. */
945 register struct glyph *string; 677
946 register int len; 678 static void
947 { 679 tty_write_glyphs (struct frame *f, struct glyph *string, int len)
948 struct frame *sf = XFRAME (selected_frame); 680 {
949 struct frame *f = updating_frame ? updating_frame : sf;
950 unsigned char *conversion_buffer; 681 unsigned char *conversion_buffer;
951 struct coding_system *coding; 682 struct coding_system *coding;
952 683
953 if (write_glyphs_hook 684 struct tty_display_info *tty = FRAME_TTY (f);
954 && ! FRAME_TERMCAP_P (f)) 685
955 { 686 tty_turn_off_insert (tty);
956 (*write_glyphs_hook) (string, len); 687 tty_hide_cursor (tty);
957 return;
958 }
959
960 turn_off_insert ();
961 tty_hide_cursor ();
962 688
963 /* Don't dare write in last column of bottom line, if Auto-Wrap, 689 /* Don't dare write in last column of bottom line, if Auto-Wrap,
964 since that would scroll the whole frame on some terminals. */ 690 since that would scroll the whole frame on some terminals. */
965 691
966 if (AutoWrap 692 if (AutoWrap (tty)
967 && curY + 1 == FRAME_LINES (sf) 693 && curY (tty) + 1 == FRAME_LINES (f)
968 && (curX + len) == FRAME_COLS (sf)) 694 && (curX (tty) + len) == FRAME_COLS (f))
969 len --; 695 len --;
970 if (len <= 0) 696 if (len <= 0)
971 return; 697 return;
972 698
973 cmplus (len); 699 cmplus (tty, len);
974 700
975 /* If terminal_coding does any conversion, use it, otherwise use 701 /* If terminal_coding does any conversion, use it, otherwise use
976 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here 702 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
977 because it always return 1 if the member src_multibyte is 1. */ 703 because it always return 1 if the member src_multibyte is 1. */
978 coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK 704 coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK
979 ? &terminal_coding : &safe_terminal_coding); 705 ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding);
980 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at 706 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
981 the tail. */ 707 the tail. */
982 coding->mode &= ~CODING_MODE_LAST_BLOCK; 708 coding->mode &= ~CODING_MODE_LAST_BLOCK;
983 709
984 while (len > 0) 710 while (len > 0)
990 for (n = 1; n < len; ++n) 716 for (n = 1; n < len; ++n)
991 if (string[n].face_id != face_id) 717 if (string[n].face_id != face_id)
992 break; 718 break;
993 719
994 /* Turn appearance modes of the face of the run on. */ 720 /* Turn appearance modes of the face of the run on. */
995 highlight_if_desired (); 721 tty_highlight_if_desired (tty);
996 turn_on_face (f, face_id); 722 turn_on_face (f, face_id);
997 723
998 if (n == len) 724 if (n == len)
999 /* This is the last run. */ 725 /* This is the last run. */
1000 coding->mode |= CODING_MODE_LAST_BLOCK; 726 coding->mode |= CODING_MODE_LAST_BLOCK;
1001 conversion_buffer = encode_terminal_code (string, n, coding); 727 conversion_buffer = encode_terminal_code (string, n, coding);
1002 if (coding->produced > 0) 728 if (coding->produced > 0)
1003 { 729 {
1004 BLOCK_INPUT; 730 BLOCK_INPUT;
1005 fwrite (conversion_buffer, 1, coding->produced, stdout); 731 fwrite (conversion_buffer, 1, coding->produced, tty->output);
1006 if (ferror (stdout)) 732 if (ferror (tty->output))
1007 clearerr (stdout); 733 clearerr (tty->output);
1008 if (termscript) 734 if (tty->termscript)
1009 fwrite (conversion_buffer, 1, coding->produced, termscript); 735 fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
1010 UNBLOCK_INPUT; 736 UNBLOCK_INPUT;
1011 } 737 }
1012 len -= n; 738 len -= n;
1013 string += n; 739 string += n;
1014 740
1015 /* Turn appearance modes off. */ 741 /* Turn appearance modes off. */
1016 turn_off_face (f, face_id); 742 turn_off_face (f, face_id);
1017 turn_off_highlight (); 743 tty_turn_off_highlight (tty);
1018 } 744 }
1019 745
1020 cmcheckmagic (); 746 cmcheckmagic (tty);
1021 } 747 }
1022 748
1023 void 749 static void
1024 write_glyphs_with_face (string, len, face_id) 750 tty_write_glyphs_with_face (f, string, len, face_id)
751 register struct frame *f;
1025 register struct glyph *string; 752 register struct glyph *string;
1026 register int len, face_id; 753 register int len, face_id;
1027 { 754 {
1028 struct frame *sf = XFRAME (selected_frame);
1029 struct frame *f = updating_frame ? updating_frame : sf;
1030 unsigned char *conversion_buffer; 755 unsigned char *conversion_buffer;
1031 struct coding_system *coding; 756 struct coding_system *coding;
1032 757
1033 turn_off_insert (); 758 struct tty_display_info *tty = FRAME_TTY (f);
1034 tty_hide_cursor (); 759
760 tty_turn_off_insert (tty);
761 tty_hide_cursor (tty);
1035 762
1036 /* Don't dare write in last column of bottom line, if Auto-Wrap, 763 /* Don't dare write in last column of bottom line, if Auto-Wrap,
1037 since that would scroll the whole frame on some terminals. */ 764 since that would scroll the whole frame on some terminals. */
1038 765
1039 if (AutoWrap 766 if (AutoWrap (tty)
1040 && curY + 1 == FRAME_LINES (sf) 767 && curY (tty) + 1 == FRAME_LINES (f)
1041 && (curX + len) == FRAME_COLS (sf)) 768 && (curX (tty) + len) == FRAME_COLS (f))
1042 len --; 769 len --;
1043 if (len <= 0) 770 if (len <= 0)
1044 return; 771 return;
1045 772
1046 cmplus (len); 773 cmplus (tty, len);
1047 774
1048 /* If terminal_coding does any conversion, use it, otherwise use 775 /* If terminal_coding does any conversion, use it, otherwise use
1049 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here 776 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
1050 because it always return 1 if the member src_multibyte is 1. */ 777 because it always return 1 if the member src_multibyte is 1. */
1051 coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK 778 coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK
1052 ? &terminal_coding : &safe_terminal_coding); 779 ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding);
1053 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at 780 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1054 the tail. */ 781 the tail. */
1055 coding->mode &= ~CODING_MODE_LAST_BLOCK; 782 coding->mode &= ~CODING_MODE_LAST_BLOCK;
1056 783
1057
1058 /* Turn appearance modes of the face. */ 784 /* Turn appearance modes of the face. */
1059 highlight_if_desired (); 785 tty_highlight_if_desired (tty);
1060 turn_on_face (f, face_id); 786 turn_on_face (f, face_id);
1061 787
1062 coding->mode |= CODING_MODE_LAST_BLOCK; 788 coding->mode |= CODING_MODE_LAST_BLOCK;
1063 conversion_buffer = encode_terminal_code (string, len, coding); 789 conversion_buffer = encode_terminal_code (string, len, coding);
1064 if (coding->produced > 0) 790 if (coding->produced > 0)
1065 { 791 {
1066 BLOCK_INPUT; 792 BLOCK_INPUT;
1067 fwrite (conversion_buffer, 1, coding->produced, stdout); 793 fwrite (conversion_buffer, 1, coding->produced, tty->output);
1068 if (ferror (stdout)) 794 if (ferror (tty->output))
1069 clearerr (stdout); 795 clearerr (tty->output);
1070 if (termscript) 796 if (tty->termscript)
1071 fwrite (conversion_buffer, 1, coding->produced, termscript); 797 fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
1072 UNBLOCK_INPUT; 798 UNBLOCK_INPUT;
1073 } 799 }
1074 800
1075 /* Turn appearance modes off. */ 801 /* Turn appearance modes off. */
1076 turn_off_face (f, face_id); 802 turn_off_face (f, face_id);
1077 turn_off_highlight (); 803 tty_turn_off_highlight (tty);
1078 804
1079 cmcheckmagic (); 805 cmcheckmagic (tty);
1080 } 806 }
1081 807
1082 /* If start is zero, insert blanks instead of a string at start */ 808
1083 809 /* An implementation of insert_glyphs for termcap frames. */
1084 void 810
1085 insert_glyphs (start, len) 811 static void
1086 register struct glyph *start; 812 tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
1087 register int len;
1088 { 813 {
1089 char *buf; 814 char *buf;
1090 struct glyph *glyph = NULL; 815 struct glyph *glyph = NULL;
1091 struct frame *f, *sf;
1092 unsigned char *conversion_buffer; 816 unsigned char *conversion_buffer;
1093 unsigned char space[1]; 817 unsigned char space[1];
1094 struct coding_system *coding; 818 struct coding_system *coding;
1095 819
1096 if (len <= 0) 820 struct tty_display_info *tty = FRAME_TTY (f);
1097 return; 821
1098 822 if (tty->TS_ins_multi_chars)
1099 if (insert_glyphs_hook) 823 {
1100 { 824 buf = tparam (tty->TS_ins_multi_chars, 0, 0, len);
1101 (*insert_glyphs_hook) (start, len); 825 OUTPUT1 (tty, buf);
1102 return;
1103 }
1104
1105 sf = XFRAME (selected_frame);
1106 f = updating_frame ? updating_frame : sf;
1107
1108 if (TS_ins_multi_chars)
1109 {
1110 buf = tparam (TS_ins_multi_chars, 0, 0, len);
1111 OUTPUT1 (buf);
1112 xfree (buf); 826 xfree (buf);
1113 if (start) 827 if (start)
1114 write_glyphs (start, len); 828 write_glyphs (f, start, len);
1115 return; 829 return;
1116 } 830 }
1117 831
1118 turn_on_insert (); 832 tty_turn_on_insert (tty);
1119 cmplus (len); 833 cmplus (tty, len);
1120 834
1121 if (! start) 835 if (! start)
1122 space[0] = SPACEGLYPH; 836 space[0] = SPACEGLYPH;
1123 837
1124 /* If terminal_coding does any conversion, use it, otherwise use 838 /* If terminal_coding does any conversion, use it, otherwise use
1125 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here 839 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
1126 because it always return 1 if the member src_multibyte is 1. */ 840 because it always return 1 if the member src_multibyte is 1. */
1127 coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK 841 coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK
1128 ? &terminal_coding : &safe_terminal_coding); 842 ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding);
1129 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at 843 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1130 the tail. */ 844 the tail. */
1131 coding->mode &= ~CODING_MODE_LAST_BLOCK; 845 coding->mode &= ~CODING_MODE_LAST_BLOCK;
1132 846
1133 while (len-- > 0) 847 while (len-- > 0)
1134 { 848 {
1135 OUTPUT1_IF (TS_ins_char); 849 OUTPUT1_IF (tty, tty->TS_ins_char);
1136 if (!start) 850 if (!start)
1137 { 851 {
1138 conversion_buffer = space; 852 conversion_buffer = space;
1139 coding->produced = 1; 853 coding->produced = 1;
1140 } 854 }
1141 else 855 else
1142 { 856 {
1143 highlight_if_desired (); 857 tty_highlight_if_desired (tty);
1144 turn_on_face (f, start->face_id); 858 turn_on_face (f, start->face_id);
1145 glyph = start; 859 glyph = start;
1146 ++start; 860 ++start;
1147 /* We must open sufficient space for a character which 861 /* We must open sufficient space for a character which
1148 occupies more than one column. */ 862 occupies more than one column. */
1149 while (len && CHAR_GLYPH_PADDING_P (*start)) 863 while (len && CHAR_GLYPH_PADDING_P (*start))
1150 { 864 {
1151 OUTPUT1_IF (TS_ins_char); 865 OUTPUT1_IF (tty, tty->TS_ins_char);
1152 start++, len--; 866 start++, len--;
1153 } 867 }
1154 868
1155 if (len <= 0) 869 if (len <= 0)
1156 /* This is the last glyph. */ 870 /* This is the last glyph. */
1157 coding->mode |= CODING_MODE_LAST_BLOCK; 871 coding->mode |= CODING_MODE_LAST_BLOCK;
1158 872
1159 conversion_buffer = encode_terminal_code (glyph, 1, coding); 873 conversion_buffer = encode_terminal_code (glyph, 1, coding);
1160 } 874 }
1161 875
1162 if (coding->produced > 0) 876 if (coding->produced > 0)
1163 { 877 {
1164 BLOCK_INPUT; 878 BLOCK_INPUT;
1165 fwrite (conversion_buffer, 1, coding->produced, stdout); 879 fwrite (conversion_buffer, 1, coding->produced, tty->output);
1166 if (ferror (stdout)) 880 if (ferror (tty->output))
1167 clearerr (stdout); 881 clearerr (tty->output);
1168 if (termscript) 882 if (tty->termscript)
1169 fwrite (conversion_buffer, 1, coding->produced, termscript); 883 fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
1170 UNBLOCK_INPUT; 884 UNBLOCK_INPUT;
1171 } 885 }
1172 886
1173 OUTPUT1_IF (TS_pad_inserted_char); 887 OUTPUT1_IF (tty, tty->TS_pad_inserted_char);
1174 if (start) 888 if (start)
1175 { 889 {
1176 turn_off_face (f, glyph->face_id); 890 turn_off_face (f, glyph->face_id);
1177 turn_off_highlight (); 891 tty_turn_off_highlight (tty);
1178 } 892 }
1179 } 893 }
1180 894
1181 cmcheckmagic (); 895 cmcheckmagic (tty);
1182 } 896 }
1183 897
1184 void 898 /* An implementation of delete_glyphs for termcap frames. */
1185 delete_glyphs (n) 899
1186 register int n; 900 static void
901 tty_delete_glyphs (struct frame *f, int n)
1187 { 902 {
1188 char *buf; 903 char *buf;
1189 register int i; 904 register int i;
1190 905
1191 if (delete_glyphs_hook && ! FRAME_TERMCAP_P (updating_frame)) 906 struct tty_display_info *tty = FRAME_TTY (f);
1192 { 907
1193 (*delete_glyphs_hook) (n); 908 if (tty->delete_in_insert_mode)
1194 return; 909 {
1195 } 910 tty_turn_on_insert (tty);
1196
1197 if (delete_in_insert_mode)
1198 {
1199 turn_on_insert ();
1200 } 911 }
1201 else 912 else
1202 { 913 {
1203 turn_off_insert (); 914 tty_turn_off_insert (tty);
1204 OUTPUT_IF (TS_delete_mode); 915 OUTPUT_IF (tty, tty->TS_delete_mode);
1205 } 916 }
1206 917
1207 if (TS_del_multi_chars) 918 if (tty->TS_del_multi_chars)
1208 { 919 {
1209 buf = tparam (TS_del_multi_chars, 0, 0, n); 920 buf = tparam (tty->TS_del_multi_chars, 0, 0, n);
1210 OUTPUT1 (buf); 921 OUTPUT1 (tty, buf);
1211 xfree (buf); 922 xfree (buf);
1212 } 923 }
1213 else 924 else
1214 for (i = 0; i < n; i++) 925 for (i = 0; i < n; i++)
1215 OUTPUT1 (TS_del_char); 926 OUTPUT1 (tty, tty->TS_del_char);
1216 if (!delete_in_insert_mode) 927 if (!tty->delete_in_insert_mode)
1217 OUTPUT_IF (TS_end_delete_mode); 928 OUTPUT_IF (tty, tty->TS_end_delete_mode);
1218 } 929 }
1219 930
1220 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */ 931 /* An implementation of ins_del_lines for termcap frames. */
1221 932
1222 void 933 static void
1223 ins_del_lines (vpos, n) 934 tty_ins_del_lines (struct frame *f, int vpos, int n)
1224 int vpos, n; 935 {
1225 { 936 struct tty_display_info *tty = FRAME_TTY (f);
1226 char *multi = n > 0 ? TS_ins_multi_lines : TS_del_multi_lines; 937 char *multi = n > 0 ? tty->TS_ins_multi_lines : tty->TS_del_multi_lines;
1227 char *single = n > 0 ? TS_ins_line : TS_del_line; 938 char *single = n > 0 ? tty->TS_ins_line : tty->TS_del_line;
1228 char *scroll = n > 0 ? TS_rev_scroll : TS_fwd_scroll; 939 char *scroll = n > 0 ? tty->TS_rev_scroll : tty->TS_fwd_scroll;
1229 struct frame *sf;
1230 940
1231 register int i = n > 0 ? n : -n; 941 register int i = n > 0 ? n : -n;
1232 register char *buf; 942 register char *buf;
1233
1234 if (ins_del_lines_hook && ! FRAME_TERMCAP_P (updating_frame))
1235 {
1236 (*ins_del_lines_hook) (vpos, n);
1237 return;
1238 }
1239
1240 sf = XFRAME (selected_frame);
1241 943
1242 /* If the lines below the insertion are being pushed 944 /* If the lines below the insertion are being pushed
1243 into the end of the window, this is the same as clearing; 945 into the end of the window, this is the same as clearing;
1244 and we know the lines are already clear, since the matching 946 and we know the lines are already clear, since the matching
1245 deletion has already been done. So can ignore this. */ 947 deletion has already been done. So can ignore this. */
1246 /* If the lines below the deletion are blank lines coming 948 /* If the lines below the deletion are blank lines coming
1247 out of the end of the window, don't bother, 949 out of the end of the window, don't bother,
1248 as there will be a matching inslines later that will flush them. */ 950 as there will be a matching inslines later that will flush them. */
1249 if (scroll_region_ok && vpos + i >= specified_window) 951 if (FRAME_SCROLL_REGION_OK (f)
952 && vpos + i >= tty->specified_window)
1250 return; 953 return;
1251 if (!memory_below_frame && vpos + i >= FRAME_LINES (sf)) 954 if (!FRAME_MEMORY_BELOW_FRAME (f)
955 && vpos + i >= FRAME_LINES (f))
1252 return; 956 return;
1253 957
1254 if (multi) 958 if (multi)
1255 { 959 {
1256 raw_cursor_to (vpos, 0); 960 raw_cursor_to (f, vpos, 0);
1257 background_highlight (); 961 tty_background_highlight (tty);
1258 buf = tparam (multi, 0, 0, i); 962 buf = tparam (multi, 0, 0, i);
1259 OUTPUT (buf); 963 OUTPUT (tty, buf);
1260 xfree (buf); 964 xfree (buf);
1261 } 965 }
1262 else if (single) 966 else if (single)
1263 { 967 {
1264 raw_cursor_to (vpos, 0); 968 raw_cursor_to (f, vpos, 0);
1265 background_highlight (); 969 tty_background_highlight (tty);
1266 while (--i >= 0) 970 while (--i >= 0)
1267 OUTPUT (single); 971 OUTPUT (tty, single);
1268 if (TF_teleray) 972 if (tty->TF_teleray)
1269 curX = 0; 973 curX (tty) = 0;
1270 } 974 }
1271 else 975 else
1272 { 976 {
1273 set_scroll_region (vpos, specified_window); 977 tty_set_scroll_region (f, vpos, tty->specified_window);
1274 if (n < 0) 978 if (n < 0)
1275 raw_cursor_to (specified_window - 1, 0); 979 raw_cursor_to (f, tty->specified_window - 1, 0);
1276 else 980 else
1277 raw_cursor_to (vpos, 0); 981 raw_cursor_to (f, vpos, 0);
1278 background_highlight (); 982 tty_background_highlight (tty);
1279 while (--i >= 0) 983 while (--i >= 0)
1280 OUTPUTL (scroll, specified_window - vpos); 984 OUTPUTL (tty, scroll, tty->specified_window - vpos);
1281 set_scroll_region (0, specified_window); 985 tty_set_scroll_region (f, 0, tty->specified_window);
1282 } 986 }
1283 987
1284 if (!scroll_region_ok && memory_below_frame && n < 0) 988 if (!FRAME_SCROLL_REGION_OK (f)
1285 { 989 && FRAME_MEMORY_BELOW_FRAME (f)
1286 cursor_to (FRAME_LINES (sf) + n, 0); 990 && n < 0)
1287 clear_to_end (); 991 {
992 cursor_to (f, FRAME_LINES (f) + n, 0);
993 clear_to_end (f);
1288 } 994 }
1289 } 995 }
1290 996
1291 /* Compute cost of sending "str", in characters, 997 /* Compute cost of sending "str", in characters,
1292 not counting any line-dependent padding. */ 998 not counting any line-dependent padding. */
1293 999
1294 int 1000 int
1295 string_cost (str) 1001 string_cost (char *str)
1296 char *str;
1297 { 1002 {
1298 cost = 0; 1003 cost = 0;
1299 if (str) 1004 if (str)
1300 tputs (str, 0, evalcost); 1005 tputs (str, 0, evalcost);
1301 return cost; 1006 return cost;
1303 1008
1304 /* Compute cost of sending "str", in characters, 1009 /* Compute cost of sending "str", in characters,
1305 counting any line-dependent padding at one line. */ 1010 counting any line-dependent padding at one line. */
1306 1011
1307 static int 1012 static int
1308 string_cost_one_line (str) 1013 string_cost_one_line (char *str)
1309 char *str;
1310 { 1014 {
1311 cost = 0; 1015 cost = 0;
1312 if (str) 1016 if (str)
1313 tputs (str, 1, evalcost); 1017 tputs (str, 1, evalcost);
1314 return cost; 1018 return cost;
1316 1020
1317 /* Compute per line amount of line-dependent padding, 1021 /* Compute per line amount of line-dependent padding,
1318 in tenths of characters. */ 1022 in tenths of characters. */
1319 1023
1320 int 1024 int
1321 per_line_cost (str) 1025 per_line_cost (char *str)
1322 register char *str;
1323 { 1026 {
1324 cost = 0; 1027 cost = 0;
1325 if (str) 1028 if (str)
1326 tputs (str, 0, evalcost); 1029 tputs (str, 0, evalcost);
1327 cost = - cost; 1030 cost = - cost;
1340 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))]) 1043 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1341 #endif 1044 #endif
1342 1045
1343 /* ARGSUSED */ 1046 /* ARGSUSED */
1344 static void 1047 static void
1345 calculate_ins_del_char_costs (frame) 1048 calculate_ins_del_char_costs (struct frame *f)
1346 FRAME_PTR frame; 1049 {
1347 { 1050 struct tty_display_info *tty = FRAME_TTY (f);
1348 int ins_startup_cost, del_startup_cost; 1051 int ins_startup_cost, del_startup_cost;
1349 int ins_cost_per_char, del_cost_per_char; 1052 int ins_cost_per_char, del_cost_per_char;
1350 register int i; 1053 register int i;
1351 register int *p; 1054 register int *p;
1352 1055
1353 if (TS_ins_multi_chars) 1056 if (tty->TS_ins_multi_chars)
1354 { 1057 {
1355 ins_cost_per_char = 0; 1058 ins_cost_per_char = 0;
1356 ins_startup_cost = string_cost_one_line (TS_ins_multi_chars); 1059 ins_startup_cost = string_cost_one_line (tty->TS_ins_multi_chars);
1357 } 1060 }
1358 else if (TS_ins_char || TS_pad_inserted_char 1061 else if (tty->TS_ins_char || tty->TS_pad_inserted_char
1359 || (TS_insert_mode && TS_end_insert_mode)) 1062 || (tty->TS_insert_mode && tty->TS_end_insert_mode))
1360 { 1063 {
1361 ins_startup_cost = (30 * (string_cost (TS_insert_mode) 1064 ins_startup_cost = (30 * (string_cost (tty->TS_insert_mode)
1362 + string_cost (TS_end_insert_mode))) / 100; 1065 + string_cost (tty->TS_end_insert_mode))) / 100;
1363 ins_cost_per_char = (string_cost_one_line (TS_ins_char) 1066 ins_cost_per_char = (string_cost_one_line (tty->TS_ins_char)
1364 + string_cost_one_line (TS_pad_inserted_char)); 1067 + string_cost_one_line (tty->TS_pad_inserted_char));
1365 } 1068 }
1366 else 1069 else
1367 { 1070 {
1368 ins_startup_cost = 9999; 1071 ins_startup_cost = 9999;
1369 ins_cost_per_char = 0; 1072 ins_cost_per_char = 0;
1370 } 1073 }
1371 1074
1372 if (TS_del_multi_chars) 1075 if (tty->TS_del_multi_chars)
1373 { 1076 {
1374 del_cost_per_char = 0; 1077 del_cost_per_char = 0;
1375 del_startup_cost = string_cost_one_line (TS_del_multi_chars); 1078 del_startup_cost = string_cost_one_line (tty->TS_del_multi_chars);
1376 } 1079 }
1377 else if (TS_del_char) 1080 else if (tty->TS_del_char)
1378 { 1081 {
1379 del_startup_cost = (string_cost (TS_delete_mode) 1082 del_startup_cost = (string_cost (tty->TS_delete_mode)
1380 + string_cost (TS_end_delete_mode)); 1083 + string_cost (tty->TS_end_delete_mode));
1381 if (delete_in_insert_mode) 1084 if (tty->delete_in_insert_mode)
1382 del_startup_cost /= 2; 1085 del_startup_cost /= 2;
1383 del_cost_per_char = string_cost_one_line (TS_del_char); 1086 del_cost_per_char = string_cost_one_line (tty->TS_del_char);
1384 } 1087 }
1385 else 1088 else
1386 { 1089 {
1387 del_startup_cost = 9999; 1090 del_startup_cost = 9999;
1388 del_cost_per_char = 0; 1091 del_cost_per_char = 0;
1389 } 1092 }
1390 1093
1391 /* Delete costs are at negative offsets */ 1094 /* Delete costs are at negative offsets */
1392 p = &char_ins_del_cost (frame)[0]; 1095 p = &char_ins_del_cost (f)[0];
1393 for (i = FRAME_COLS (frame); --i >= 0;) 1096 for (i = FRAME_COLS (f); --i >= 0;)
1394 *--p = (del_startup_cost += del_cost_per_char); 1097 *--p = (del_startup_cost += del_cost_per_char);
1395 1098
1396 /* Doing nothing is free */ 1099 /* Doing nothing is free */
1397 p = &char_ins_del_cost (frame)[0]; 1100 p = &char_ins_del_cost (f)[0];
1398 *p++ = 0; 1101 *p++ = 0;
1399 1102
1400 /* Insert costs are at positive offsets */ 1103 /* Insert costs are at positive offsets */
1401 for (i = FRAME_COLS (frame); --i >= 0;) 1104 for (i = FRAME_COLS (f); --i >= 0;)
1402 *p++ = (ins_startup_cost += ins_cost_per_char); 1105 *p++ = (ins_startup_cost += ins_cost_per_char);
1403 } 1106 }
1404 1107
1405 void 1108 void
1406 calculate_costs (frame) 1109 calculate_costs (struct frame *frame)
1407 FRAME_PTR frame; 1110 {
1408 {
1409 register char *f = (TS_set_scroll_region
1410 ? TS_set_scroll_region
1411 : TS_set_scroll_region_1);
1412
1413 FRAME_COST_BAUD_RATE (frame) = baud_rate; 1111 FRAME_COST_BAUD_RATE (frame) = baud_rate;
1414 1112
1415 scroll_region_cost = string_cost (f); 1113 if (FRAME_TERMCAP_P (frame))
1416 1114 {
1417 /* These variables are only used for terminal stuff. They are allocated 1115 struct tty_display_info *tty = FRAME_TTY (frame);
1418 once for the terminal frame of X-windows emacs, but not used afterwards. 1116 register char *f = (tty->TS_set_scroll_region
1419 1117 ? tty->TS_set_scroll_region
1420 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because 1118 : tty->TS_set_scroll_region_1);
1421 X turns off char_ins_del_ok. */ 1119
1422 1120 FRAME_SCROLL_REGION_COST (frame) = string_cost (f);
1423 max_frame_lines = max (max_frame_lines, FRAME_LINES (frame)); 1121
1424 max_frame_cols = max (max_frame_cols, FRAME_COLS (frame)); 1122 tty->costs_set = 1;
1425 1123
1426 costs_set = 1; 1124 /* These variables are only used for terminal stuff. They are
1427 1125 allocated once for the terminal frame of X-windows emacs, but not
1428 if (char_ins_del_vector != 0) 1126 used afterwards.
1429 char_ins_del_vector 1127
1430 = (int *) xrealloc (char_ins_del_vector, 1128 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1431 (sizeof (int) 1129 X turns off char_ins_del_ok. */
1432 + 2 * max_frame_cols * sizeof (int))); 1130
1433 else 1131 max_frame_lines = max (max_frame_lines, FRAME_LINES (frame));
1434 char_ins_del_vector 1132 max_frame_cols = max (max_frame_cols, FRAME_COLS (frame));
1435 = (int *) xmalloc (sizeof (int) 1133
1436 + 2 * max_frame_cols * sizeof (int)); 1134 if (char_ins_del_vector != 0)
1437 1135 char_ins_del_vector
1438 bzero (char_ins_del_vector, (sizeof (int) 1136 = (int *) xrealloc (char_ins_del_vector,
1439 + 2 * max_frame_cols * sizeof (int))); 1137 (sizeof (int)
1440 1138 + 2 * max_frame_cols * sizeof (int)));
1441 if (f && (!TS_ins_line && !TS_del_line)) 1139 else
1442 do_line_insertion_deletion_costs (frame, 1140 char_ins_del_vector
1443 TS_rev_scroll, TS_ins_multi_lines, 1141 = (int *) xmalloc (sizeof (int)
1444 TS_fwd_scroll, TS_del_multi_lines, 1142 + 2 * max_frame_cols * sizeof (int));
1445 f, f, 1); 1143
1446 else 1144 bzero (char_ins_del_vector, (sizeof (int)
1447 do_line_insertion_deletion_costs (frame, 1145 + 2 * max_frame_cols * sizeof (int)));
1448 TS_ins_line, TS_ins_multi_lines, 1146
1449 TS_del_line, TS_del_multi_lines, 1147
1450 0, 0, 1); 1148 if (f && (!tty->TS_ins_line && !tty->TS_del_line))
1451 1149 do_line_insertion_deletion_costs (frame,
1452 calculate_ins_del_char_costs (frame); 1150 tty->TS_rev_scroll, tty->TS_ins_multi_lines,
1453 1151 tty->TS_fwd_scroll, tty->TS_del_multi_lines,
1454 /* Don't use TS_repeat if its padding is worse than sending the chars */ 1152 f, f, 1);
1455 if (TS_repeat && per_line_cost (TS_repeat) * baud_rate < 9000) 1153 else
1456 RPov = string_cost (TS_repeat); 1154 do_line_insertion_deletion_costs (frame,
1457 else 1155 tty->TS_ins_line, tty->TS_ins_multi_lines,
1458 RPov = FRAME_COLS (frame) * 2; 1156 tty->TS_del_line, tty->TS_del_multi_lines,
1459 1157 0, 0, 1);
1460 cmcostinit (); /* set up cursor motion costs */ 1158
1159 calculate_ins_del_char_costs (frame);
1160
1161 /* Don't use TS_repeat if its padding is worse than sending the chars */
1162 if (tty->TS_repeat && per_line_cost (tty->TS_repeat) * baud_rate < 9000)
1163 tty->RPov = string_cost (tty->TS_repeat);
1164 else
1165 tty->RPov = FRAME_COLS (frame) * 2;
1166
1167 cmcostinit (FRAME_TTY (frame)); /* set up cursor motion costs */
1168 }
1461 } 1169 }
1462 1170
1463 struct fkey_table { 1171 struct fkey_table {
1464 char *cap, *name; 1172 char *cap, *name;
1465 }; 1173 };
1565 {"%g", "S-redo"}, /*shifted redo key*/ 1273 {"%g", "S-redo"}, /*shifted redo key*/
1566 {"%i", "S-right"}, /*shifted right-arrow key*/ 1274 {"%i", "S-right"}, /*shifted right-arrow key*/
1567 {"!3", "S-undo"} /*shifted undo key*/ 1275 {"!3", "S-undo"} /*shifted undo key*/
1568 }; 1276 };
1569 1277
1570 static char **term_get_fkeys_arg; 1278 static char **term_get_fkeys_address;
1279 static KBOARD *term_get_fkeys_kboard;
1571 static Lisp_Object term_get_fkeys_1 (); 1280 static Lisp_Object term_get_fkeys_1 ();
1572 1281
1573 /* Find the escape codes sent by the function keys for Vfunction_key_map. 1282 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1574 This function scans the termcap function key sequence entries, and 1283 This function scans the termcap function key sequence entries, and
1575 adds entries to Vfunction_key_map for each function key it finds. */ 1284 adds entries to Vfunction_key_map for each function key it finds. */
1576 1285
1577 void 1286 static void
1578 term_get_fkeys (address) 1287 term_get_fkeys (address, kboard)
1579 char **address; 1288 char **address;
1289 KBOARD *kboard;
1580 { 1290 {
1581 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp 1291 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1582 errors during the call. The only errors should be from Fdefine_key 1292 errors during the call. The only errors should be from Fdefine_key
1583 when given a key sequence containing an invalid prefix key. If the 1293 when given a key sequence containing an invalid prefix key. If the
1584 termcap defines function keys which use a prefix that is already bound 1294 termcap defines function keys which use a prefix that is already bound
1585 to a command by the default bindings, we should silently ignore that 1295 to a command by the default bindings, we should silently ignore that
1586 function key specification, rather than giving the user an error and 1296 function key specification, rather than giving the user an error and
1587 refusing to run at all on such a terminal. */ 1297 refusing to run at all on such a terminal. */
1588 1298
1589 extern Lisp_Object Fidentity (); 1299 extern Lisp_Object Fidentity ();
1590 term_get_fkeys_arg = address; 1300 term_get_fkeys_address = address;
1301 term_get_fkeys_kboard = kboard;
1591 internal_condition_case (term_get_fkeys_1, Qerror, Fidentity); 1302 internal_condition_case (term_get_fkeys_1, Qerror, Fidentity);
1592 } 1303 }
1593 1304
1594 static Lisp_Object 1305 static Lisp_Object
1595 term_get_fkeys_1 () 1306 term_get_fkeys_1 ()
1596 { 1307 {
1597 int i; 1308 int i;
1598 1309
1599 char **address = term_get_fkeys_arg; 1310 char **address = term_get_fkeys_address;
1600 1311 KBOARD *kboard = term_get_fkeys_kboard;
1312
1601 /* This can happen if CANNOT_DUMP or with strange options. */ 1313 /* This can happen if CANNOT_DUMP or with strange options. */
1602 if (!initialized) 1314 if (!initialized)
1603 Vfunction_key_map = Fmake_sparse_keymap (Qnil); 1315 kboard->Vlocal_function_key_map = Fmake_sparse_keymap (Qnil);
1604 1316
1605 for (i = 0; i < (sizeof (keys)/sizeof (keys[0])); i++) 1317 for (i = 0; i < (sizeof (keys)/sizeof (keys[0])); i++)
1606 { 1318 {
1607 char *sequence = tgetstr (keys[i].cap, address); 1319 char *sequence = tgetstr (keys[i].cap, address);
1608 if (sequence) 1320 if (sequence)
1609 Fdefine_key (Vfunction_key_map, build_string (sequence), 1321 Fdefine_key (kboard->Vlocal_function_key_map, build_string (sequence),
1610 Fmake_vector (make_number (1), 1322 Fmake_vector (make_number (1),
1611 intern (keys[i].name))); 1323 intern (keys[i].name)));
1612 } 1324 }
1613 1325
1614 /* The uses of the "k0" capability are inconsistent; sometimes it 1326 /* The uses of the "k0" capability are inconsistent; sometimes it
1624 if (k_semi) 1336 if (k_semi)
1625 { 1337 {
1626 if (k0) 1338 if (k0)
1627 /* Define f0 first, so that f10 takes precedence in case the 1339 /* Define f0 first, so that f10 takes precedence in case the
1628 key sequences happens to be the same. */ 1340 key sequences happens to be the same. */
1629 Fdefine_key (Vfunction_key_map, build_string (k0), 1341 Fdefine_key (kboard->Vlocal_function_key_map, build_string (k0),
1630 Fmake_vector (make_number (1), intern ("f0"))); 1342 Fmake_vector (make_number (1), intern ("f0")));
1631 Fdefine_key (Vfunction_key_map, build_string (k_semi), 1343 Fdefine_key (kboard->Vlocal_function_key_map, build_string (k_semi),
1632 Fmake_vector (make_number (1), intern ("f10"))); 1344 Fmake_vector (make_number (1), intern ("f10")));
1633 } 1345 }
1634 else if (k0) 1346 else if (k0)
1635 Fdefine_key (Vfunction_key_map, build_string (k0), 1347 Fdefine_key (kboard->Vlocal_function_key_map, build_string (k0),
1636 Fmake_vector (make_number (1), intern (k0_name))); 1348 Fmake_vector (make_number (1), intern (k0_name)));
1637 } 1349 }
1638 1350
1639 /* Set up cookies for numbered function keys above f10. */ 1351 /* Set up cookies for numbered function keys above f10. */
1640 { 1352 {
1653 { 1365 {
1654 char *sequence = tgetstr (fcap, address); 1366 char *sequence = tgetstr (fcap, address);
1655 if (sequence) 1367 if (sequence)
1656 { 1368 {
1657 sprintf (fkey, "f%d", i); 1369 sprintf (fkey, "f%d", i);
1658 Fdefine_key (Vfunction_key_map, build_string (sequence), 1370 Fdefine_key (kboard->Vlocal_function_key_map, build_string (sequence),
1659 Fmake_vector (make_number (1), 1371 Fmake_vector (make_number (1),
1660 intern (fkey))); 1372 intern (fkey)));
1661 } 1373 }
1662 } 1374 }
1663 } 1375 }
1669 { 1381 {
1670 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \ 1382 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1671 if (!tgetstr (cap1, address)) \ 1383 if (!tgetstr (cap1, address)) \
1672 { \ 1384 { \
1673 char *sequence = tgetstr (cap2, address); \ 1385 char *sequence = tgetstr (cap2, address); \
1674 if (sequence) \ 1386 if (sequence) \
1675 Fdefine_key (Vfunction_key_map, build_string (sequence), \ 1387 Fdefine_key (kboard->Vlocal_function_key_map, build_string (sequence), \
1676 Fmake_vector (make_number (1), \ 1388 Fmake_vector (make_number (1), \
1677 intern (sym))); \ 1389 intern (sym))); \
1678 } 1390 }
1679 1391
1680 /* if there's no key_next keycap, map key_npage to `next' keysym */ 1392 /* if there's no key_next keycap, map key_npage to `next' keysym */
1681 CONDITIONAL_REASSIGN ("%5", "kN", "next"); 1393 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1682 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */ 1394 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
2028 /* Value is non-zero if attribute ATTR may be used. ATTR should be 1740 /* Value is non-zero if attribute ATTR may be used. ATTR should be
2029 one of the enumerators from enum no_color_bit, or a bit set built 1741 one of the enumerators from enum no_color_bit, or a bit set built
2030 from them. Some display attributes may not be used together with 1742 from them. Some display attributes may not be used together with
2031 color; the termcap capability `NC' specifies which ones. */ 1743 color; the termcap capability `NC' specifies which ones. */
2032 1744
2033 #define MAY_USE_WITH_COLORS_P(ATTR) \ 1745 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
2034 (TN_max_colors > 0 \ 1746 (tty->TN_max_colors > 0 \
2035 ? (TN_no_color_video & (ATTR)) == 0 \ 1747 ? (tty->TN_no_color_video & (ATTR)) == 0 \
2036 : 1) 1748 : 1)
2037 1749
2038 /* Turn appearances of face FACE_ID on tty frame F on. 1750 /* Turn appearances of face FACE_ID on tty frame F on.
2039 FACE_ID is a realized face ID number, in the face cache. */ 1751 FACE_ID is a realized face ID number, in the face cache. */
2040 1752
2041 static void 1753 static void
2044 int face_id; 1756 int face_id;
2045 { 1757 {
2046 struct face *face = FACE_FROM_ID (f, face_id); 1758 struct face *face = FACE_FROM_ID (f, face_id);
2047 long fg = face->foreground; 1759 long fg = face->foreground;
2048 long bg = face->background; 1760 long bg = face->background;
1761 struct tty_display_info *tty = FRAME_TTY (f);
2049 1762
2050 /* Do this first because TS_end_standout_mode may be the same 1763 /* Do this first because TS_end_standout_mode may be the same
2051 as TS_exit_attribute_mode, which turns all appearances off. */ 1764 as TS_exit_attribute_mode, which turns all appearances off. */
2052 if (MAY_USE_WITH_COLORS_P (NC_REVERSE)) 1765 if (MAY_USE_WITH_COLORS_P (tty, NC_REVERSE))
2053 { 1766 {
2054 if (TN_max_colors > 0) 1767 if (tty->TN_max_colors > 0)
2055 { 1768 {
2056 if (fg >= 0 && bg >= 0) 1769 if (fg >= 0 && bg >= 0)
2057 { 1770 {
2058 /* If the terminal supports colors, we can set them 1771 /* If the terminal supports colors, we can set them
2059 below without using reverse video. The face's fg 1772 below without using reverse video. The face's fg
2063 } 1776 }
2064 else if (inverse_video) 1777 else if (inverse_video)
2065 { 1778 {
2066 if (fg == FACE_TTY_DEFAULT_FG_COLOR 1779 if (fg == FACE_TTY_DEFAULT_FG_COLOR
2067 || bg == FACE_TTY_DEFAULT_BG_COLOR) 1780 || bg == FACE_TTY_DEFAULT_BG_COLOR)
2068 toggle_highlight (); 1781 tty_toggle_highlight (tty);
2069 } 1782 }
2070 else 1783 else
2071 { 1784 {
2072 if (fg == FACE_TTY_DEFAULT_BG_COLOR 1785 if (fg == FACE_TTY_DEFAULT_BG_COLOR
2073 || bg == FACE_TTY_DEFAULT_FG_COLOR) 1786 || bg == FACE_TTY_DEFAULT_FG_COLOR)
2074 toggle_highlight (); 1787 tty_toggle_highlight (tty);
2075 } 1788 }
2076 } 1789 }
2077 else 1790 else
2078 { 1791 {
2079 /* If we can't display colors, use reverse video 1792 /* If we can't display colors, use reverse video
2080 if the face specifies that. */ 1793 if the face specifies that. */
2081 if (inverse_video) 1794 if (inverse_video)
2082 { 1795 {
2083 if (fg == FACE_TTY_DEFAULT_FG_COLOR 1796 if (fg == FACE_TTY_DEFAULT_FG_COLOR
2084 || bg == FACE_TTY_DEFAULT_BG_COLOR) 1797 || bg == FACE_TTY_DEFAULT_BG_COLOR)
2085 toggle_highlight (); 1798 tty_toggle_highlight (tty);
2086 } 1799 }
2087 else 1800 else
2088 { 1801 {
2089 if (fg == FACE_TTY_DEFAULT_BG_COLOR 1802 if (fg == FACE_TTY_DEFAULT_BG_COLOR
2090 || bg == FACE_TTY_DEFAULT_FG_COLOR) 1803 || bg == FACE_TTY_DEFAULT_FG_COLOR)
2091 toggle_highlight (); 1804 tty_toggle_highlight (tty);
2092 } 1805 }
2093 } 1806 }
2094 } 1807 }
2095 1808
2096 if (face->tty_bold_p) 1809 if (face->tty_bold_p)
2097 { 1810 {
2098 if (MAY_USE_WITH_COLORS_P (NC_BOLD)) 1811 if (MAY_USE_WITH_COLORS_P (tty, NC_BOLD))
2099 OUTPUT1_IF (TS_enter_bold_mode); 1812 OUTPUT1_IF (tty, tty->TS_enter_bold_mode);
2100 } 1813 }
2101 else if (face->tty_dim_p) 1814 else if (face->tty_dim_p)
2102 if (MAY_USE_WITH_COLORS_P (NC_DIM)) 1815 if (MAY_USE_WITH_COLORS_P (tty, NC_DIM))
2103 OUTPUT1_IF (TS_enter_dim_mode); 1816 OUTPUT1_IF (tty, tty->TS_enter_dim_mode);
2104 1817
2105 /* Alternate charset and blinking not yet used. */ 1818 /* Alternate charset and blinking not yet used. */
2106 if (face->tty_alt_charset_p 1819 if (face->tty_alt_charset_p
2107 && MAY_USE_WITH_COLORS_P (NC_ALT_CHARSET)) 1820 && MAY_USE_WITH_COLORS_P (tty, NC_ALT_CHARSET))
2108 OUTPUT1_IF (TS_enter_alt_charset_mode); 1821 OUTPUT1_IF (tty, tty->TS_enter_alt_charset_mode);
2109 1822
2110 if (face->tty_blinking_p 1823 if (face->tty_blinking_p
2111 && MAY_USE_WITH_COLORS_P (NC_BLINK)) 1824 && MAY_USE_WITH_COLORS_P (tty, NC_BLINK))
2112 OUTPUT1_IF (TS_enter_blink_mode); 1825 OUTPUT1_IF (tty, tty->TS_enter_blink_mode);
2113 1826
2114 if (face->tty_underline_p && MAY_USE_WITH_COLORS_P (NC_UNDERLINE)) 1827 if (face->tty_underline_p && MAY_USE_WITH_COLORS_P (tty, NC_UNDERLINE))
2115 OUTPUT1_IF (TS_enter_underline_mode); 1828 OUTPUT1_IF (tty, tty->TS_enter_underline_mode);
2116 1829
2117 if (TN_max_colors > 0) 1830 if (tty->TN_max_colors > 0)
2118 { 1831 {
2119 char *ts, *p; 1832 char *ts, *p;
2120 1833
2121 ts = standout_mode ? TS_set_background : TS_set_foreground; 1834 ts = tty->standout_mode ? tty->TS_set_background : tty->TS_set_foreground;
2122 if (fg >= 0 && ts) 1835 if (fg >= 0 && ts)
2123 { 1836 {
2124 p = tparam (ts, NULL, 0, (int) fg); 1837 p = tparam (ts, NULL, 0, (int) fg);
2125 OUTPUT (p); 1838 OUTPUT (tty, p);
2126 xfree (p); 1839 xfree (p);
2127 } 1840 }
2128 1841
2129 ts = standout_mode ? TS_set_foreground : TS_set_background; 1842 ts = tty->standout_mode ? tty->TS_set_foreground : tty->TS_set_background;
2130 if (bg >= 0 && ts) 1843 if (bg >= 0 && ts)
2131 { 1844 {
2132 p = tparam (ts, NULL, 0, (int) bg); 1845 p = tparam (ts, NULL, 0, (int) bg);
2133 OUTPUT (p); 1846 OUTPUT (tty, p);
2134 xfree (p); 1847 xfree (p);
2135 } 1848 }
2136 } 1849 }
2137 } 1850 }
2138 1851
2143 turn_off_face (f, face_id) 1856 turn_off_face (f, face_id)
2144 struct frame *f; 1857 struct frame *f;
2145 int face_id; 1858 int face_id;
2146 { 1859 {
2147 struct face *face = FACE_FROM_ID (f, face_id); 1860 struct face *face = FACE_FROM_ID (f, face_id);
1861 struct tty_display_info *tty = FRAME_TTY (f);
2148 1862
2149 xassert (face != NULL); 1863 xassert (face != NULL);
2150 1864
2151 if (TS_exit_attribute_mode) 1865 if (tty->TS_exit_attribute_mode)
2152 { 1866 {
2153 /* Capability "me" will turn off appearance modes double-bright, 1867 /* Capability "me" will turn off appearance modes double-bright,
2154 half-bright, reverse-video, standout, underline. It may or 1868 half-bright, reverse-video, standout, underline. It may or
2155 may not turn off alt-char-mode. */ 1869 may not turn off alt-char-mode. */
2156 if (face->tty_bold_p 1870 if (face->tty_bold_p
2158 || face->tty_reverse_p 1872 || face->tty_reverse_p
2159 || face->tty_alt_charset_p 1873 || face->tty_alt_charset_p
2160 || face->tty_blinking_p 1874 || face->tty_blinking_p
2161 || face->tty_underline_p) 1875 || face->tty_underline_p)
2162 { 1876 {
2163 OUTPUT1_IF (TS_exit_attribute_mode); 1877 OUTPUT1_IF (tty, tty->TS_exit_attribute_mode);
2164 if (strcmp (TS_exit_attribute_mode, TS_end_standout_mode) == 0) 1878 if (strcmp (tty->TS_exit_attribute_mode, tty->TS_end_standout_mode) == 0)
2165 standout_mode = 0; 1879 tty->standout_mode = 0;
2166 } 1880 }
2167 1881
2168 if (face->tty_alt_charset_p) 1882 if (face->tty_alt_charset_p)
2169 OUTPUT_IF (TS_exit_alt_charset_mode); 1883 OUTPUT_IF (tty, tty->TS_exit_alt_charset_mode);
2170 } 1884 }
2171 else 1885 else
2172 { 1886 {
2173 /* If we don't have "me" we can only have those appearances 1887 /* If we don't have "me" we can only have those appearances
2174 that have exit sequences defined. */ 1888 that have exit sequences defined. */
2175 if (face->tty_alt_charset_p) 1889 if (face->tty_alt_charset_p)
2176 OUTPUT_IF (TS_exit_alt_charset_mode); 1890 OUTPUT_IF (tty, tty->TS_exit_alt_charset_mode);
2177 1891
2178 if (face->tty_underline_p) 1892 if (face->tty_underline_p)
2179 OUTPUT_IF (TS_exit_underline_mode); 1893 OUTPUT_IF (tty, tty->TS_exit_underline_mode);
2180 } 1894 }
2181 1895
2182 /* Switch back to default colors. */ 1896 /* Switch back to default colors. */
2183 if (TN_max_colors > 0 1897 if (tty->TN_max_colors > 0
2184 && ((face->foreground != FACE_TTY_DEFAULT_COLOR 1898 && ((face->foreground != FACE_TTY_DEFAULT_COLOR
2185 && face->foreground != FACE_TTY_DEFAULT_FG_COLOR) 1899 && face->foreground != FACE_TTY_DEFAULT_FG_COLOR)
2186 || (face->background != FACE_TTY_DEFAULT_COLOR 1900 || (face->background != FACE_TTY_DEFAULT_COLOR
2187 && face->background != FACE_TTY_DEFAULT_BG_COLOR))) 1901 && face->background != FACE_TTY_DEFAULT_BG_COLOR)))
2188 OUTPUT1_IF (TS_orig_pair); 1902 OUTPUT1_IF (tty, tty->TS_orig_pair);
2189 } 1903 }
2190 1904
2191 1905
2192 /* Return non-zero if the terminal on frame F supports all of the 1906 /* Return non-zero if the terminal on frame F supports all of the
2193 capabilities in CAPS simultaneously, with foreground and background 1907 capabilities in CAPS simultaneously, with foreground and background
2194 colors FG and BG. */ 1908 colors FG and BG. */
2195 1909
2196 int 1910 int
2197 tty_capable_p (f, caps, fg, bg) 1911 tty_capable_p (tty, caps, fg, bg)
2198 struct frame *f; 1912 struct tty_display_info *tty;
2199 unsigned caps; 1913 unsigned caps;
2200 unsigned long fg, bg; 1914 unsigned long fg, bg;
2201 { 1915 {
2202 #define TTY_CAPABLE_P_TRY(cap, TS, NC_bit) \ 1916 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
2203 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(NC_bit))) \ 1917 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
2204 return 0; 1918 return 0;
2205 1919
2206 TTY_CAPABLE_P_TRY (TTY_CAP_INVERSE, TS_standout_mode, NC_REVERSE); 1920 TTY_CAPABLE_P_TRY (tty, TTY_CAP_INVERSE, tty->TS_standout_mode, NC_REVERSE);
2207 TTY_CAPABLE_P_TRY (TTY_CAP_UNDERLINE, TS_enter_underline_mode, NC_UNDERLINE); 1921 TTY_CAPABLE_P_TRY (tty, TTY_CAP_UNDERLINE, tty->TS_enter_underline_mode, NC_UNDERLINE);
2208 TTY_CAPABLE_P_TRY (TTY_CAP_BOLD, TS_enter_bold_mode, NC_BOLD); 1922 TTY_CAPABLE_P_TRY (tty, TTY_CAP_BOLD, tty->TS_enter_bold_mode, NC_BOLD);
2209 TTY_CAPABLE_P_TRY (TTY_CAP_DIM, TS_enter_dim_mode, NC_DIM); 1923 TTY_CAPABLE_P_TRY (tty, TTY_CAP_DIM, tty->TS_enter_dim_mode, NC_DIM);
2210 TTY_CAPABLE_P_TRY (TTY_CAP_BLINK, TS_enter_blink_mode, NC_BLINK); 1924 TTY_CAPABLE_P_TRY (tty, TTY_CAP_BLINK, tty->TS_enter_blink_mode, NC_BLINK);
2211 TTY_CAPABLE_P_TRY (TTY_CAP_ALT_CHARSET, TS_enter_alt_charset_mode, NC_ALT_CHARSET); 1925 TTY_CAPABLE_P_TRY (tty, TTY_CAP_ALT_CHARSET, tty->TS_enter_alt_charset_mode, NC_ALT_CHARSET);
2212 1926
2213 /* We can do it! */ 1927 /* We can do it! */
2214 return 1; 1928 return 1;
2215 } 1929 }
2216 1930
2217
2218 /* Return non-zero if the terminal is capable to display colors. */ 1931 /* Return non-zero if the terminal is capable to display colors. */
2219 1932
2220 DEFUN ("tty-display-color-p", Ftty_display_color_p, Stty_display_color_p, 1933 DEFUN ("tty-display-color-p", Ftty_display_color_p, Stty_display_color_p,
2221 0, 1, 0, 1934 0, 1, 0,
2222 doc: /* Return non-nil if TTY can display colors on DISPLAY. */) 1935 doc: /* Return non-nil if the tty device TERMINAL can display colors.
2223 (display) 1936
2224 Lisp_Object display; 1937 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2225 { 1938 frame's terminal). This function always returns nil if TERMINAL
2226 return TN_max_colors > 0 ? Qt : Qnil; 1939 is not on a tty device. */)
1940 (terminal)
1941 Lisp_Object terminal;
1942 {
1943 struct terminal *t = get_tty_terminal (terminal, 0);
1944 if (!t)
1945 return Qnil;
1946 else
1947 return t->display_info.tty->TN_max_colors > 0 ? Qt : Qnil;
2227 } 1948 }
2228 1949
2229 /* Return the number of supported colors. */ 1950 /* Return the number of supported colors. */
2230 DEFUN ("tty-display-color-cells", Ftty_display_color_cells, 1951 DEFUN ("tty-display-color-cells", Ftty_display_color_cells,
2231 Stty_display_color_cells, 0, 1, 0, 1952 Stty_display_color_cells, 0, 1, 0,
2232 doc: /* Return the number of colors supported by TTY on DISPLAY. */) 1953 doc: /* Return the number of colors supported by the tty device TERMINAL.
2233 (display) 1954
2234 Lisp_Object display; 1955 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2235 { 1956 frame's terminal). This function always returns 0 if TERMINAL
2236 return make_number (TN_max_colors); 1957 is not on a tty device. */)
1958 (terminal)
1959 Lisp_Object terminal;
1960 {
1961 struct terminal *t = get_tty_terminal (terminal, 0);
1962 if (!t)
1963 return make_number (0);
1964 else
1965 return make_number (t->display_info.tty->TN_max_colors);
2237 } 1966 }
2238 1967
2239 #ifndef WINDOWSNT 1968 #ifndef WINDOWSNT
2240 1969
2241 /* Declare here rather than in the function, as in the rest of Emacs, 1970 /* Declare here rather than in the function, as in the rest of Emacs,
2249 static char *default_set_background; 1978 static char *default_set_background;
2250 1979
2251 /* Save or restore the default color-related capabilities of this 1980 /* Save or restore the default color-related capabilities of this
2252 terminal. */ 1981 terminal. */
2253 static void 1982 static void
2254 tty_default_color_capabilities (save) 1983 tty_default_color_capabilities (struct tty_display_info *tty, int save)
2255 int save;
2256 { 1984 {
2257 1985
2258 if (save) 1986 if (save)
2259 { 1987 {
2260 if (default_orig_pair) 1988 if (default_orig_pair)
2261 xfree (default_orig_pair); 1989 xfree (default_orig_pair);
2262 default_orig_pair = TS_orig_pair ? xstrdup (TS_orig_pair) : NULL; 1990 default_orig_pair = tty->TS_orig_pair ? xstrdup (tty->TS_orig_pair) : NULL;
2263 1991
2264 if (default_set_foreground) 1992 if (default_set_foreground)
2265 xfree (default_set_foreground); 1993 xfree (default_set_foreground);
2266 default_set_foreground = TS_set_foreground ? xstrdup (TS_set_foreground) 1994 default_set_foreground = tty->TS_set_foreground ? xstrdup (tty->TS_set_foreground)
2267 : NULL; 1995 : NULL;
2268 1996
2269 if (default_set_background) 1997 if (default_set_background)
2270 xfree (default_set_background); 1998 xfree (default_set_background);
2271 default_set_background = TS_set_background ? xstrdup (TS_set_background) 1999 default_set_background = tty->TS_set_background ? xstrdup (tty->TS_set_background)
2272 : NULL; 2000 : NULL;
2273 2001
2274 default_max_colors = TN_max_colors; 2002 default_max_colors = tty->TN_max_colors;
2275 default_max_pairs = TN_max_pairs; 2003 default_max_pairs = tty->TN_max_pairs;
2276 default_no_color_video = TN_no_color_video; 2004 default_no_color_video = tty->TN_no_color_video;
2277 } 2005 }
2278 else 2006 else
2279 { 2007 {
2280 TS_orig_pair = default_orig_pair; 2008 tty->TS_orig_pair = default_orig_pair;
2281 TS_set_foreground = default_set_foreground; 2009 tty->TS_set_foreground = default_set_foreground;
2282 TS_set_background = default_set_background; 2010 tty->TS_set_background = default_set_background;
2283 TN_max_colors = default_max_colors; 2011 tty->TN_max_colors = default_max_colors;
2284 TN_max_pairs = default_max_pairs; 2012 tty->TN_max_pairs = default_max_pairs;
2285 TN_no_color_video = default_no_color_video; 2013 tty->TN_no_color_video = default_no_color_video;
2286 } 2014 }
2287 } 2015 }
2288 2016
2289 /* Setup one of the standard tty color schemes according to MODE. 2017 /* Setup one of the standard tty color schemes according to MODE.
2290 MODE's value is generally the number of colors which we want to 2018 MODE's value is generally the number of colors which we want to
2291 support; zero means set up for the default capabilities, the ones 2019 support; zero means set up for the default capabilities, the ones
2292 we saw at term_init time; -1 means turn off color support. */ 2020 we saw at init_tty time; -1 means turn off color support. */
2293 void 2021 static void
2294 tty_setup_colors (mode) 2022 tty_setup_colors (struct tty_display_info *tty, int mode)
2295 int mode;
2296 { 2023 {
2297 /* Canonicalize all negative values of MODE. */ 2024 /* Canonicalize all negative values of MODE. */
2298 if (mode < -1) 2025 if (mode < -1)
2299 mode = -1; 2026 mode = -1;
2300 2027
2301 switch (mode) 2028 switch (mode)
2302 { 2029 {
2303 case -1: /* no colors at all */ 2030 case -1: /* no colors at all */
2304 TN_max_colors = 0; 2031 tty->TN_max_colors = 0;
2305 TN_max_pairs = 0; 2032 tty->TN_max_pairs = 0;
2306 TN_no_color_video = 0; 2033 tty->TN_no_color_video = 0;
2307 TS_set_foreground = TS_set_background = TS_orig_pair = NULL; 2034 tty->TS_set_foreground = tty->TS_set_background = tty->TS_orig_pair = NULL;
2308 break; 2035 break;
2309 case 0: /* default colors, if any */ 2036 case 0: /* default colors, if any */
2310 default: 2037 default:
2311 tty_default_color_capabilities (0); 2038 tty_default_color_capabilities (tty, 0);
2312 break; 2039 break;
2313 case 8: /* 8 standard ANSI colors */ 2040 case 8: /* 8 standard ANSI colors */
2314 TS_orig_pair = "\033[0m"; 2041 tty->TS_orig_pair = "\033[0m";
2315 #ifdef TERMINFO 2042 #ifdef TERMINFO
2316 TS_set_foreground = "\033[3%p1%dm"; 2043 tty->TS_set_foreground = "\033[3%p1%dm";
2317 TS_set_background = "\033[4%p1%dm"; 2044 tty->TS_set_background = "\033[4%p1%dm";
2318 #else 2045 #else
2319 TS_set_foreground = "\033[3%dm"; 2046 tty->TS_set_foreground = "\033[3%dm";
2320 TS_set_background = "\033[4%dm"; 2047 tty->TS_set_background = "\033[4%dm";
2321 #endif 2048 #endif
2322 TN_max_colors = 8; 2049 tty->TN_max_colors = 8;
2323 TN_max_pairs = 64; 2050 tty->TN_max_pairs = 64;
2324 TN_no_color_video = 0; 2051 tty->TN_no_color_video = 0;
2325 break; 2052 break;
2326 } 2053 }
2327 } 2054 }
2328 2055
2329 void 2056 void
2370 else 2097 else
2371 old_mode = 0; 2098 old_mode = 0;
2372 2099
2373 if (mode != old_mode) 2100 if (mode != old_mode)
2374 { 2101 {
2375 tty_setup_colors (mode); 2102 tty_setup_colors (FRAME_TTY (f), mode);
2376 /* This recomputes all the faces given the new color 2103 /* This recomputes all the faces given the new color
2377 definitions. */ 2104 definitions. */
2378 call0 (intern ("tty-set-up-initial-frame-faces")); 2105 call0 (intern ("tty-set-up-initial-frame-faces"));
2379 redraw_frame (f); 2106 redraw_frame (f);
2380 } 2107 }
2381 } 2108 }
2382 2109
2383 #endif /* !WINDOWSNT */ 2110 #endif /* !WINDOWSNT */
2111
2112
2113
2114 /* Return the tty display object specified by TERMINAL. */
2115
2116 struct terminal *
2117 get_tty_terminal (Lisp_Object terminal, int throw)
2118 {
2119 struct terminal *t = get_terminal (terminal, throw);
2120
2121 if (t && t->type == output_initial)
2122 return NULL;
2123
2124 if (t && t->type != output_termcap)
2125 {
2126 if (throw)
2127 error ("Device %d is not a termcap terminal device", t->id);
2128 else
2129 return NULL;
2130 }
2131
2132 return t;
2133 }
2134
2135 /* Return an active termcap device that uses the tty device with the
2136 given name.
2137
2138 This function ignores suspended devices.
2139
2140 Returns NULL if the named terminal device is not opened. */
2141
2142 struct terminal *
2143 get_named_tty (name)
2144 char *name;
2145 {
2146 struct terminal *t;
2147
2148 if (!name)
2149 abort ();
2150
2151 for (t = terminal_list; t; t = t->next_terminal)
2152 {
2153 if (t->type == output_termcap
2154 && !strcmp (t->display_info.tty->name, name)
2155 && TERMINAL_ACTIVE_P (t))
2156 return t;
2157 }
2158
2159 return 0;
2160 }
2161
2162
2163 DEFUN ("tty-type", Ftty_type, Stty_type, 0, 1, 0,
2164 doc: /* Return the type of the tty device that TERMINAL uses.
2165 Returns nil if TERMINAL is not on a tty device.
2166
2167 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2168 frame's terminal). */)
2169 (terminal)
2170 Lisp_Object terminal;
2171 {
2172 struct terminal *t = get_terminal (terminal, 1);
2173
2174 if (t->type != output_termcap)
2175 return Qnil;
2176
2177 if (t->display_info.tty->type)
2178 return build_string (t->display_info.tty->type);
2179 else
2180 return Qnil;
2181 }
2182
2183 DEFUN ("controlling-tty-p", Fcontrolling_tty_p, Scontrolling_tty_p, 0, 1, 0,
2184 doc: /* Return non-nil if TERMINAL is on the controlling tty of the Emacs process.
2185
2186 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2187 frame's terminal). This function always returns nil if TERMINAL
2188 is not on a tty device. */)
2189 (terminal)
2190 Lisp_Object terminal;
2191 {
2192 struct terminal *t = get_terminal (terminal, 1);
2193
2194 if (t->type != output_termcap || strcmp (t->display_info.tty->name, "/dev/tty"))
2195 return Qnil;
2196 else
2197 return Qt;
2198 }
2199
2200 DEFUN ("tty-no-underline", Ftty_no_underline, Stty_no_underline, 0, 1, 0,
2201 doc: /* Declare that the tty used by TERMINAL does not handle underlining.
2202 This is used to override the terminfo data, for certain terminals that
2203 do not really do underlining, but say that they do. This function has
2204 no effect if used on a non-tty terminal.
2205
2206 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2207 frame's terminal). This function always returns nil if TERMINAL
2208 is not on a tty device. */)
2209 (terminal)
2210 Lisp_Object terminal;
2211 {
2212 struct terminal *t = get_terminal (terminal, 1);
2213
2214 if (t->type == output_termcap)
2215 t->display_info.tty->TS_enter_underline_mode = 0;
2216 return Qnil;
2217 }
2218
2219
2220
2221 DEFUN ("suspend-tty", Fsuspend_tty, Ssuspend_tty, 0, 1, 0,
2222 doc: /* Suspend the terminal device TTY.
2223
2224 The device is restored to its default state, and Emacs ceases all
2225 access to the tty device. Frames that use the device are not deleted,
2226 but input is not read from them and if they change, their display is
2227 not updated.
2228
2229 TTY may be a terminal id, a frame, or nil for the terminal device of
2230 the currently selected frame.
2231
2232 This function runs `suspend-tty-functions' after suspending the
2233 device. The functions are run with one arg, the id of the suspended
2234 terminal device.
2235
2236 `suspend-tty' does nothing if it is called on a device that is already
2237 suspended.
2238
2239 A suspended tty may be resumed by calling `resume-tty' on it. */)
2240 (tty)
2241 Lisp_Object tty;
2242 {
2243 struct terminal *t = get_tty_terminal (tty, 1);
2244 FILE *f;
2245
2246 if (!t)
2247 error ("Unknown tty device");
2248
2249 f = t->display_info.tty->input;
2250
2251 if (f)
2252 {
2253 reset_sys_modes (t->display_info.tty);
2254
2255 delete_keyboard_wait_descriptor (fileno (f));
2256
2257 fclose (f);
2258 if (f != t->display_info.tty->output)
2259 fclose (t->display_info.tty->output);
2260
2261 t->display_info.tty->input = 0;
2262 t->display_info.tty->output = 0;
2263
2264 if (FRAMEP (t->display_info.tty->top_frame))
2265 FRAME_SET_VISIBLE (XFRAME (t->display_info.tty->top_frame), 0);
2266
2267 /* Run `suspend-tty-functions'. */
2268 if (!NILP (Vrun_hooks))
2269 {
2270 Lisp_Object args[2];
2271 args[0] = intern ("suspend-tty-functions");
2272 args[1] = make_number (t->id);
2273 Frun_hook_with_args (2, args);
2274 }
2275 }
2276
2277 /* Clear display hooks to prevent further output. */
2278 clear_tty_hooks (t);
2279
2280 return Qnil;
2281 }
2282
2283 DEFUN ("resume-tty", Fresume_tty, Sresume_tty, 0, 1, 0,
2284 doc: /* Resume the previously suspended terminal device TTY.
2285 The terminal is opened and reinitialized. Frames that are on the
2286 suspended terminal are revived.
2287
2288 It is an error to resume a terminal while another terminal is active
2289 on the same device.
2290
2291 This function runs `resume-tty-functions' after resuming the terminal.
2292 The functions are run with one arg, the id of the resumed terminal
2293 device.
2294
2295 `resume-tty' does nothing if it is called on a device that is not
2296 suspended.
2297
2298 TTY may be a terminal id, a frame, or nil for the terminal device of
2299 the currently selected frame. */)
2300 (tty)
2301 Lisp_Object tty;
2302 {
2303 struct terminal *t = get_tty_terminal (tty, 1);
2304 int fd;
2305
2306 if (!t)
2307 error ("Unknown tty device");
2308
2309 if (!t->display_info.tty->input)
2310 {
2311 if (get_named_tty (t->display_info.tty->name))
2312 error ("Cannot resume display while another display is active on the same device");
2313
2314 fd = emacs_open (t->display_info.tty->name, O_RDWR | O_NOCTTY, 0);
2315
2316 if (fd == -1)
2317 error ("Can not reopen tty device %s: %s", t->display_info.tty->name, strerror (errno));
2318
2319 if (strcmp (t->display_info.tty->name, "/dev/tty"))
2320 dissociate_if_controlling_tty (fd);
2321
2322 t->display_info.tty->output = fdopen (fd, "w+");
2323 t->display_info.tty->input = t->display_info.tty->output;
2324
2325 add_keyboard_wait_descriptor (fd);
2326
2327 if (FRAMEP (t->display_info.tty->top_frame))
2328 FRAME_SET_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1);
2329
2330 init_sys_modes (t->display_info.tty);
2331
2332 /* Run `suspend-tty-functions'. */
2333 if (!NILP (Vrun_hooks))
2334 {
2335 Lisp_Object args[2];
2336 args[0] = intern ("resume-tty-functions");
2337 args[1] = make_number (t->id);
2338 Frun_hook_with_args (2, args);
2339 }
2340 }
2341
2342 set_tty_hooks (t);
2343
2344 return Qnil;
2345 }
2384 2346
2385 2347
2386 /*********************************************************************** 2348 /***********************************************************************
2387 Mouse 2349 Mouse
2388 ***********************************************************************/ 2350 ***********************************************************************/
2407 { 2369 {
2408 struct window *w = XWINDOW (Qmouse_face_window); 2370 struct window *w = XWINDOW (Qmouse_face_window);
2409 int save_x, save_y; 2371 int save_x, save_y;
2410 int i; 2372 int i;
2411 2373
2374 struct frame *f = XFRAME (w->frame);
2375 struct tty_display_info *tty = FRAME_TTY (f);
2376
2412 if (/* If window is in the process of being destroyed, don't bother 2377 if (/* If window is in the process of being destroyed, don't bother
2413 to do anything. */ 2378 to do anything. */
2414 w->current_matrix != NULL 2379 w->current_matrix != NULL
2415 /* Recognize when we are called to operate on rows that don't exist 2380 /* Recognize when we are called to operate on rows that don't exist
2416 anymore. This can happen when a window is split. */ 2381 anymore. This can happen when a window is split. */
2419 /* write_glyphs writes at cursor position, so we need to 2384 /* write_glyphs writes at cursor position, so we need to
2420 temporarily move cursor coordinates to the beginning of 2385 temporarily move cursor coordinates to the beginning of
2421 the highlight region. */ 2386 the highlight region. */
2422 2387
2423 /* Save current cursor co-ordinates */ 2388 /* Save current cursor co-ordinates */
2424 save_y = curY; 2389 save_y = curY (tty);
2425 save_x = curX; 2390 save_x = curX (tty);
2426 2391
2427 /* Note that mouse_face_beg_row etc. are window relative. */ 2392 /* Note that mouse_face_beg_row etc. are window relative. */
2428 for (i = mouse_face_beg_row; i <= mouse_face_end_row; i++) 2393 for (i = mouse_face_beg_row; i <= mouse_face_end_row; i++)
2429 { 2394 {
2430 int start_hpos, end_hpos, nglyphs; 2395 int start_hpos, end_hpos, nglyphs;
2462 2427
2463 pos_y = row->y + WINDOW_TOP_EDGE_Y (w); 2428 pos_y = row->y + WINDOW_TOP_EDGE_Y (w);
2464 pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos 2429 pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos
2465 + WINDOW_LEFT_EDGE_X (w); 2430 + WINDOW_LEFT_EDGE_X (w);
2466 2431
2467 cursor_to (pos_y, pos_x); 2432 cursor_to (f, pos_y, pos_x);
2468 2433
2469 if (draw == DRAW_MOUSE_FACE) 2434 if (draw == DRAW_MOUSE_FACE)
2470 { 2435 {
2471 write_glyphs_with_face (row->glyphs[TEXT_AREA] + start_hpos, 2436 tty_write_glyphs_with_face (f, row->glyphs[TEXT_AREA] + start_hpos,
2472 nglyphs, mouse_face_face_id); 2437 nglyphs, mouse_face_face_id);
2473 } 2438 }
2474 else /* draw == DRAW_NORMAL_TEXT */ 2439 else /* draw == DRAW_NORMAL_TEXT */
2475 write_glyphs (row->glyphs[TEXT_AREA] + start_hpos, nglyphs); 2440 write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
2476 } 2441 }
2477 cursor_to (save_y, save_x); 2442 cursor_to (f, save_y, save_x);
2478 } 2443 }
2479 } 2444 }
2480 2445
2481 static void 2446 static void
2482 term_clear_mouse_face () 2447 term_clear_mouse_face ()
2922 result->arg = Qnil; 2887 result->arg = Qnil;
2923 return Qnil; 2888 return Qnil;
2924 } 2889 }
2925 2890
2926 int 2891 int
2927 handle_one_term_event (Gpm_Event *event, struct input_event* hold_quit) 2892 handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event, struct input_event* hold_quit)
2928 { 2893 {
2929 struct frame *f = SELECTED_FRAME (); 2894 struct frame *f = XFRAME (tty->top_frame);
2930 int fd; 2895 int fd;
2931 struct input_event ie; 2896 struct input_event ie;
2932 int do_help = 0; 2897 int do_help = 0;
2933 int count = 0; 2898 int count = 0;
2934 2899
3000 DEFUN ("term-open-connection", Fterm_open_connection, Sterm_open_connection, 2965 DEFUN ("term-open-connection", Fterm_open_connection, Sterm_open_connection,
3001 0, 0, 0, 2966 0, 0, 0,
3002 doc: /* Open a connection to Gpm. */) 2967 doc: /* Open a connection to Gpm. */)
3003 () 2968 ()
3004 { 2969 {
2970 struct tty_display_info *tty = FRAME_TTY (SELECTED_FRAME ());
3005 Gpm_Connect connection; 2971 Gpm_Connect connection;
3006 2972
3007 connection.eventMask = ~0; 2973 connection.eventMask = ~0;
3008 connection.defaultMask = ~GPM_HARD; 2974 connection.defaultMask = ~GPM_HARD;
3009 connection.maxMod = ~0; 2975 connection.maxMod = ~0;
3010 connection.minMod = 0; 2976 connection.minMod = 0;
3011 gpm_zerobased = 1; 2977 gpm_zerobased = 1;
3012 2978
3013 if (Gpm_Open (&connection, 0) < 0) 2979 /* We only support GPM on the controlling tty. */
2980 if (term_gpm || tty->terminal->id > 1
2981 || Gpm_Open (&connection, 0) < 0)
3014 return Qnil; 2982 return Qnil;
3015 else 2983 else
3016 { 2984 {
3017 term_gpm = 1; 2985 term_gpm = 1;
3018 reset_sys_modes (); 2986 gpm_tty = tty->terminal->id;
3019 init_sys_modes (); 2987 reset_sys_modes (tty);
2988 init_sys_modes (tty);
3020 add_gpm_wait_descriptor (gpm_fd); 2989 add_gpm_wait_descriptor (gpm_fd);
3021 return Qt; 2990 return Qt;
3022 } 2991 }
3023 } 2992 }
3024 2993
3037 3006
3038 /*********************************************************************** 3007 /***********************************************************************
3039 Initialization 3008 Initialization
3040 ***********************************************************************/ 3009 ***********************************************************************/
3041 3010
3011 /* Initialize the tty-dependent part of frame F. The frame must
3012 already have its device initialized. */
3013
3042 void 3014 void
3043 term_init (terminal_type) 3015 create_tty_output (struct frame *f)
3044 char *terminal_type; 3016 {
3045 { 3017 struct tty_output *t;
3046 char *area; 3018
3019 if (! FRAME_TERMCAP_P (f))
3020 abort ();
3021
3022 t = xmalloc (sizeof (struct tty_output));
3023 bzero (t, sizeof (struct tty_output));
3024
3025 t->display_info = FRAME_TERMINAL (f)->display_info.tty;
3026
3027 f->output_data.tty = t;
3028 }
3029
3030 /* Delete the tty-dependent part of frame F. */
3031
3032 static void
3033 delete_tty_output (struct frame *f)
3034 {
3035 if (! FRAME_TERMCAP_P (f))
3036 abort ();
3037
3038 xfree (f->output_data.tty);
3039 }
3040
3041
3042
3043 static void
3044 clear_tty_hooks (struct terminal *terminal)
3045 {
3046 terminal->rif = 0;
3047 terminal->cursor_to_hook = 0;
3048 terminal->raw_cursor_to_hook = 0;
3049 terminal->clear_to_end_hook = 0;
3050 terminal->clear_frame_hook = 0;
3051 terminal->clear_end_of_line_hook = 0;
3052 terminal->ins_del_lines_hook = 0;
3053 terminal->insert_glyphs_hook = 0;
3054 terminal->write_glyphs_hook = 0;
3055 terminal->delete_glyphs_hook = 0;
3056 terminal->ring_bell_hook = 0;
3057 terminal->reset_terminal_modes_hook = 0;
3058 terminal->set_terminal_modes_hook = 0;
3059 terminal->update_begin_hook = 0;
3060 terminal->update_end_hook = 0;
3061 terminal->set_terminal_window_hook = 0;
3062 terminal->mouse_position_hook = 0;
3063 terminal->frame_rehighlight_hook = 0;
3064 terminal->frame_raise_lower_hook = 0;
3065 terminal->fullscreen_hook = 0;
3066 terminal->set_vertical_scroll_bar_hook = 0;
3067 terminal->condemn_scroll_bars_hook = 0;
3068 terminal->redeem_scroll_bar_hook = 0;
3069 terminal->judge_scroll_bars_hook = 0;
3070 terminal->read_socket_hook = 0;
3071 terminal->frame_up_to_date_hook = 0;
3072
3073 /* Leave these two set, or suspended frames are not deleted
3074 correctly. */
3075 terminal->delete_frame_hook = &delete_tty_output;
3076 terminal->delete_terminal_hook = &delete_tty;
3077 }
3078
3079 static void
3080 set_tty_hooks (struct terminal *terminal)
3081 {
3082 terminal->rif = 0; /* ttys don't support window-based redisplay. */
3083
3084 terminal->cursor_to_hook = &tty_cursor_to;
3085 terminal->raw_cursor_to_hook = &tty_raw_cursor_to;
3086
3087 terminal->clear_to_end_hook = &tty_clear_to_end;
3088 terminal->clear_frame_hook = &tty_clear_frame;
3089 terminal->clear_end_of_line_hook = &tty_clear_end_of_line;
3090
3091 terminal->ins_del_lines_hook = &tty_ins_del_lines;
3092
3093 terminal->insert_glyphs_hook = &tty_insert_glyphs;
3094 terminal->write_glyphs_hook = &tty_write_glyphs;
3095 terminal->delete_glyphs_hook = &tty_delete_glyphs;
3096
3097 terminal->ring_bell_hook = &tty_ring_bell;
3098
3099 terminal->reset_terminal_modes_hook = &tty_reset_terminal_modes;
3100 terminal->set_terminal_modes_hook = &tty_set_terminal_modes;
3101 terminal->update_begin_hook = 0; /* Not needed. */
3102 terminal->update_end_hook = &tty_update_end;
3103 terminal->set_terminal_window_hook = &tty_set_terminal_window;
3104
3105 terminal->mouse_position_hook = 0; /* Not needed. */
3106 terminal->frame_rehighlight_hook = 0; /* Not needed. */
3107 terminal->frame_raise_lower_hook = 0; /* Not needed. */
3108
3109 terminal->set_vertical_scroll_bar_hook = 0; /* Not needed. */
3110 terminal->condemn_scroll_bars_hook = 0; /* Not needed. */
3111 terminal->redeem_scroll_bar_hook = 0; /* Not needed. */
3112 terminal->judge_scroll_bars_hook = 0; /* Not needed. */
3113
3114 terminal->read_socket_hook = &tty_read_avail_input; /* keyboard.c */
3115 terminal->frame_up_to_date_hook = 0; /* Not needed. */
3116
3117 terminal->delete_frame_hook = &delete_tty_output;
3118 terminal->delete_terminal_hook = &delete_tty;
3119 }
3120
3121 /* Drop the controlling terminal if fd is the same device. */
3122 static void
3123 dissociate_if_controlling_tty (int fd)
3124 {
3125 #ifndef WINDOWSNT
3126 int pgid;
3127 EMACS_GET_TTY_PGRP (fd, &pgid); /* If tcgetpgrp succeeds, fd is the ctty. */
3128 if (pgid != -1)
3129 {
3130 #if defined (USG) && !defined (BSD_PGRPS)
3131 setpgrp ();
3132 no_controlling_tty = 1;
3133 #else
3134 #ifdef TIOCNOTTY /* Try BSD ioctls. */
3135 sigblock (sigmask (SIGTTOU));
3136 fd = emacs_open ("/dev/tty", O_RDWR, 0);
3137 if (fd != -1 && ioctl (fd, TIOCNOTTY, 0) != -1)
3138 {
3139 no_controlling_tty = 1;
3140 }
3141 if (fd != -1)
3142 emacs_close (fd);
3143 sigunblock (sigmask (SIGTTOU));
3144 #else
3145 /* Unknown system. */
3146 croak ();
3147 #endif /* ! TIOCNOTTY */
3148 #endif /* ! USG */
3149 }
3150 #endif
3151 }
3152
3153 static void maybe_fatal();
3154
3155 /* Create a termcap display on the tty device with the given name and
3156 type.
3157
3158 If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
3159 Otherwise NAME should be a path to the tty device file,
3160 e.g. "/dev/pts/7".
3161
3162 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
3163
3164 If MUST_SUCCEED is true, then all errors are fatal. */
3165
3166 struct terminal *
3167 init_tty (char *name, char *terminal_type, int must_succeed)
3168 {
3169 char *area = NULL;
3047 char **address = &area; 3170 char **address = &area;
3048 char *buffer = NULL; 3171 char *buffer = NULL;
3049 int buffer_size = 4096; 3172 int buffer_size = 4096;
3050 register char *p; 3173 register char *p = NULL;
3051 int status; 3174 int status;
3052 struct frame *sf = XFRAME (selected_frame); 3175 struct tty_display_info *tty = NULL;
3176 struct terminal *terminal = NULL;
3177 int ctty = 0; /* 1 if asked to open controlling tty. */
3178
3179 if (!terminal_type)
3180 maybe_fatal (must_succeed, 0, 0,
3181 "Unknown terminal type",
3182 "Unknown terminal type");
3183
3184 #ifndef WINDOWSNT
3185 if (name == NULL)
3186 name = "/dev/tty";
3187 if (!strcmp (name, "/dev/tty"))
3188 ctty = 1;
3189
3190 /* If we already have a terminal on the given device, use that. If
3191 all such terminals are suspended, create a new one instead. */
3192 /* XXX Perhaps this should be made explicit by having init_tty
3193 always create a new terminal and separating terminal and frame
3194 creation on Lisp level. */
3195 terminal = get_named_tty (name);
3196 if (terminal)
3197 return terminal;
3198 #endif
3199
3200 terminal = create_terminal ();
3201 tty = (struct tty_display_info *) xmalloc (sizeof (struct tty_display_info));
3202 bzero (tty, sizeof (struct tty_display_info));
3203 tty->next = tty_list;
3204 tty_list = tty;
3205
3206 terminal->type = output_termcap;
3207 terminal->display_info.tty = tty;
3208 tty->terminal = terminal;
3209
3210 tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm));
3211 Wcm_clear (tty);
3212
3213 #ifndef WINDOWSNT
3214 set_tty_hooks (terminal);
3215
3216 {
3217 int fd;
3218 FILE *file;
3219
3220 #ifdef O_IGNORE_CTTY
3221 if (!ctty)
3222 /* Open the terminal device. Don't recognize it as our
3223 controlling terminal, and don't make it the controlling tty
3224 if we don't have one at the moment. */
3225 fd = emacs_open (name, O_RDWR | O_IGNORE_CTTY | O_NOCTTY, 0);
3226 else
3227 #else
3228 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
3229 defined on Hurd. On other systems, we need to explicitly
3230 dissociate ourselves from the controlling tty when we want to
3231 open a frame on the same terminal. */
3232 fd = emacs_open (name, O_RDWR | O_NOCTTY, 0);
3233 #endif /* O_IGNORE_CTTY */
3234
3235 if (fd < 0)
3236 maybe_fatal (must_succeed, buffer, terminal,
3237 "Could not open file: %s",
3238 "Could not open file: %s",
3239 name);
3240 if (!isatty (fd))
3241 {
3242 close (fd);
3243 maybe_fatal (must_succeed, buffer, terminal,
3244 "Not a tty device: %s",
3245 "Not a tty device: %s",
3246 name);
3247 }
3248
3249 #ifndef O_IGNORE_CTTY
3250 if (!ctty)
3251 dissociate_if_controlling_tty (fd);
3252 #endif
3253
3254 file = fdopen (fd, "w+");
3255 tty->name = xstrdup (name);
3256 terminal->name = xstrdup (name);
3257 tty->input = file;
3258 tty->output = file;
3259 }
3260
3261 tty->type = xstrdup (terminal_type);
3262
3263 add_keyboard_wait_descriptor (fileno (tty->input));
3264
3265 #endif
3053 3266
3054 encode_terminal_bufsize = 0; 3267 encode_terminal_bufsize = 0;
3055 3268
3056 #ifdef HAVE_GPM 3269 #ifdef HAVE_GPM
3057 mouse_position_hook = term_mouse_position; 3270 terminal->mouse_position_hook = term_mouse_position;
3058 Qmouse_face_window = Qnil; 3271 Qmouse_face_window = Qnil;
3059 #endif 3272 #endif
3060 3273
3061 #ifdef WINDOWSNT 3274 #ifdef WINDOWSNT
3062 initialize_w32_display (); 3275 initialize_w32_display ();
3063 3276
3064 Wcm_clear (); 3277 /* XXX Can this be non-null? */
3065 3278 if (name)
3066 area = (char *) xmalloc (2044); 3279 {
3067 3280 tty->name = xstrdup (name);
3068 FrameRows = FRAME_LINES (sf); 3281 terminal->name = xstrdup (name);
3069 FrameCols = FRAME_COLS (sf); 3282 }
3070 specified_window = FRAME_LINES (sf); 3283 tty->type = xstrdup (terminal_type);
3071 3284
3072 delete_in_insert_mode = 1; 3285 /* XXX not sure if this line is correct. If it is not set then we
3073 3286 crash in update_display_1. */
3074 UseTabs = 0; 3287 tty->output = stdout;
3075 scroll_region_ok = 0; 3288
3076 3289 Wcm_clear (tty);
3077 /* Seems to insert lines when it's not supposed to, messing 3290
3078 up the display. In doing a trace, it didn't seem to be 3291 area = (char *) xmalloc (2044); /* XXX this seems unused. */
3079 called much, so I don't think we're losing anything by 3292
3080 turning it off. */ 3293 {
3081 3294 struct frame *f = XFRAME (selected_frame);
3082 line_ins_del_ok = 0; 3295
3083 char_ins_del_ok = 1; 3296 FrameRows (tty) = FRAME_LINES (f); /* XXX */
3297 FrameCols (tty) = FRAME_COLS (f); /* XXX */
3298 tty->specified_window = FRAME_LINES (f); /* XXX */
3299
3300 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; /* XXX */
3301 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; /* XXX */
3302 }
3303 tty->delete_in_insert_mode = 1;
3304
3305 UseTabs (tty) = 0;
3306 terminal->scroll_region_ok = 0;
3307
3308 /* Seems to insert lines when it's not supposed to, messing up the
3309 display. In doing a trace, it didn't seem to be called much, so I
3310 don't think we're losing anything by turning it off. */
3311 terminal->line_ins_del_ok = 0;
3312 terminal->char_ins_del_ok = 1;
3084 3313
3085 baud_rate = 19200; 3314 baud_rate = 19200;
3086 3315
3087 FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0; 3316 tty->TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */
3088 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none; 3317
3089 TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */ 3318 return terminal;
3090
3091 return;
3092 #else /* not WINDOWSNT */ 3319 #else /* not WINDOWSNT */
3093 3320
3094 Wcm_clear (); 3321 Wcm_clear (tty);
3095 3322
3096 buffer = (char *) xmalloc (buffer_size); 3323 buffer = (char *) xmalloc (buffer_size);
3324
3325 /* On some systems, tgetent tries to access the controlling
3326 terminal. */
3327 sigblock (sigmask (SIGTTOU));
3097 status = tgetent (buffer, terminal_type); 3328 status = tgetent (buffer, terminal_type);
3329 sigunblock (sigmask (SIGTTOU));
3330
3098 if (status < 0) 3331 if (status < 0)
3099 { 3332 {
3100 #ifdef TERMINFO 3333 #ifdef TERMINFO
3101 fatal ("Cannot open terminfo database file"); 3334 maybe_fatal (must_succeed, buffer, terminal,
3335 "Cannot open terminfo database file",
3336 "Cannot open terminfo database file");
3102 #else 3337 #else
3103 fatal ("Cannot open termcap database file"); 3338 maybe_fatal (must_succeed, buffer, terminal,
3339 "Cannot open termcap database file",
3340 "Cannot open termcap database file");
3104 #endif 3341 #endif
3105 } 3342 }
3106 if (status == 0) 3343 if (status == 0)
3107 { 3344 {
3108 #ifdef TERMINFO 3345 #ifdef TERMINFO
3109 fatal ("Terminal type %s is not defined.\n\ 3346 maybe_fatal (must_succeed, buffer, terminal,
3347 "Terminal type %s is not defined",
3348 "Terminal type %s is not defined.\n\
3110 If that is not the actual type of terminal you have,\n\ 3349 If that is not the actual type of terminal you have,\n\
3111 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ 3350 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3112 `setenv TERM ...') to specify the correct type. It may be necessary\n\ 3351 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3113 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.", 3352 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3114 terminal_type); 3353 terminal_type);
3115 #else 3354 #else
3116 fatal ("Terminal type %s is not defined.\n\ 3355 maybe_fatal (must_succeed, buffer, terminal,
3356 "Terminal type %s is not defined",
3357 "Terminal type %s is not defined.\n\
3117 If that is not the actual type of terminal you have,\n\ 3358 If that is not the actual type of terminal you have,\n\
3118 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ 3359 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3119 `setenv TERM ...') to specify the correct type. It may be necessary\n\ 3360 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3120 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", 3361 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3121 terminal_type); 3362 terminal_type);
3122 #endif 3363 #endif
3123 } 3364 }
3124 3365
3125 #ifndef TERMINFO 3366 #ifndef TERMINFO
3126 if (strlen (buffer) >= buffer_size) 3367 if (strlen (buffer) >= buffer_size)
3127 abort (); 3368 abort ();
3128 buffer_size = strlen (buffer); 3369 buffer_size = strlen (buffer);
3129 #endif 3370 #endif
3130 area = (char *) xmalloc (buffer_size); 3371 area = (char *) xmalloc (buffer_size);
3131 3372
3132 TS_ins_line = tgetstr ("al", address); 3373 tty->TS_ins_line = tgetstr ("al", address);
3133 TS_ins_multi_lines = tgetstr ("AL", address); 3374 tty->TS_ins_multi_lines = tgetstr ("AL", address);
3134 TS_bell = tgetstr ("bl", address); 3375 tty->TS_bell = tgetstr ("bl", address);
3135 BackTab = tgetstr ("bt", address); 3376 BackTab (tty) = tgetstr ("bt", address);
3136 TS_clr_to_bottom = tgetstr ("cd", address); 3377 tty->TS_clr_to_bottom = tgetstr ("cd", address);
3137 TS_clr_line = tgetstr ("ce", address); 3378 tty->TS_clr_line = tgetstr ("ce", address);
3138 TS_clr_frame = tgetstr ("cl", address); 3379 tty->TS_clr_frame = tgetstr ("cl", address);
3139 ColPosition = NULL; /* tgetstr ("ch", address); */ 3380 ColPosition (tty) = NULL; /* tgetstr ("ch", address); */
3140 AbsPosition = tgetstr ("cm", address); 3381 AbsPosition (tty) = tgetstr ("cm", address);
3141 CR = tgetstr ("cr", address); 3382 CR (tty) = tgetstr ("cr", address);
3142 TS_set_scroll_region = tgetstr ("cs", address); 3383 tty->TS_set_scroll_region = tgetstr ("cs", address);
3143 TS_set_scroll_region_1 = tgetstr ("cS", address); 3384 tty->TS_set_scroll_region_1 = tgetstr ("cS", address);
3144 RowPosition = tgetstr ("cv", address); 3385 RowPosition (tty) = tgetstr ("cv", address);
3145 TS_del_char = tgetstr ("dc", address); 3386 tty->TS_del_char = tgetstr ("dc", address);
3146 TS_del_multi_chars = tgetstr ("DC", address); 3387 tty->TS_del_multi_chars = tgetstr ("DC", address);
3147 TS_del_line = tgetstr ("dl", address); 3388 tty->TS_del_line = tgetstr ("dl", address);
3148 TS_del_multi_lines = tgetstr ("DL", address); 3389 tty->TS_del_multi_lines = tgetstr ("DL", address);
3149 TS_delete_mode = tgetstr ("dm", address); 3390 tty->TS_delete_mode = tgetstr ("dm", address);
3150 TS_end_delete_mode = tgetstr ("ed", address); 3391 tty->TS_end_delete_mode = tgetstr ("ed", address);
3151 TS_end_insert_mode = tgetstr ("ei", address); 3392 tty->TS_end_insert_mode = tgetstr ("ei", address);
3152 Home = tgetstr ("ho", address); 3393 Home (tty) = tgetstr ("ho", address);
3153 TS_ins_char = tgetstr ("ic", address); 3394 tty->TS_ins_char = tgetstr ("ic", address);
3154 TS_ins_multi_chars = tgetstr ("IC", address); 3395 tty->TS_ins_multi_chars = tgetstr ("IC", address);
3155 TS_insert_mode = tgetstr ("im", address); 3396 tty->TS_insert_mode = tgetstr ("im", address);
3156 TS_pad_inserted_char = tgetstr ("ip", address); 3397 tty->TS_pad_inserted_char = tgetstr ("ip", address);
3157 TS_end_keypad_mode = tgetstr ("ke", address); 3398 tty->TS_end_keypad_mode = tgetstr ("ke", address);
3158 TS_keypad_mode = tgetstr ("ks", address); 3399 tty->TS_keypad_mode = tgetstr ("ks", address);
3159 LastLine = tgetstr ("ll", address); 3400 LastLine (tty) = tgetstr ("ll", address);
3160 Right = tgetstr ("nd", address); 3401 Right (tty) = tgetstr ("nd", address);
3161 Down = tgetstr ("do", address); 3402 Down (tty) = tgetstr ("do", address);
3162 if (!Down) 3403 if (!Down (tty))
3163 Down = tgetstr ("nl", address); /* Obsolete name for "do" */ 3404 Down (tty) = tgetstr ("nl", address); /* Obsolete name for "do" */
3164 #ifdef VMS 3405 #ifdef VMS
3165 /* VMS puts a carriage return before each linefeed, 3406 /* VMS puts a carriage return before each linefeed,
3166 so it is not safe to use linefeeds. */ 3407 so it is not safe to use linefeeds. */
3167 if (Down && Down[0] == '\n' && Down[1] == '\0') 3408 if (Down (tty) && Down (tty)[0] == '\n' && Down (tty)[1] == '\0')
3168 Down = 0; 3409 Down (tty) = 0;
3169 #endif /* VMS */ 3410 #endif /* VMS */
3170 if (tgetflag ("bs")) 3411 if (tgetflag ("bs"))
3171 Left = "\b"; /* can't possibly be longer! */ 3412 Left (tty) = "\b"; /* can't possibly be longer! */
3172 else /* (Actually, "bs" is obsolete...) */ 3413 else /* (Actually, "bs" is obsolete...) */
3173 Left = tgetstr ("le", address); 3414 Left (tty) = tgetstr ("le", address);
3174 if (!Left) 3415 if (!Left (tty))
3175 Left = tgetstr ("bc", address); /* Obsolete name for "le" */ 3416 Left (tty) = tgetstr ("bc", address); /* Obsolete name for "le" */
3176 TS_pad_char = tgetstr ("pc", address); 3417 tty->TS_pad_char = tgetstr ("pc", address);
3177 TS_repeat = tgetstr ("rp", address); 3418 tty->TS_repeat = tgetstr ("rp", address);
3178 TS_end_standout_mode = tgetstr ("se", address); 3419 tty->TS_end_standout_mode = tgetstr ("se", address);
3179 TS_fwd_scroll = tgetstr ("sf", address); 3420 tty->TS_fwd_scroll = tgetstr ("sf", address);
3180 TS_standout_mode = tgetstr ("so", address); 3421 tty->TS_standout_mode = tgetstr ("so", address);
3181 TS_rev_scroll = tgetstr ("sr", address); 3422 tty->TS_rev_scroll = tgetstr ("sr", address);
3182 Wcm.cm_tab = tgetstr ("ta", address); 3423 tty->Wcm->cm_tab = tgetstr ("ta", address);
3183 TS_end_termcap_modes = tgetstr ("te", address); 3424 tty->TS_end_termcap_modes = tgetstr ("te", address);
3184 TS_termcap_modes = tgetstr ("ti", address); 3425 tty->TS_termcap_modes = tgetstr ("ti", address);
3185 Up = tgetstr ("up", address); 3426 Up (tty) = tgetstr ("up", address);
3186 TS_visible_bell = tgetstr ("vb", address); 3427 tty->TS_visible_bell = tgetstr ("vb", address);
3187 TS_cursor_normal = tgetstr ("ve", address); 3428 tty->TS_cursor_normal = tgetstr ("ve", address);
3188 TS_cursor_visible = tgetstr ("vs", address); 3429 tty->TS_cursor_visible = tgetstr ("vs", address);
3189 TS_cursor_invisible = tgetstr ("vi", address); 3430 tty->TS_cursor_invisible = tgetstr ("vi", address);
3190 TS_set_window = tgetstr ("wi", address); 3431 tty->TS_set_window = tgetstr ("wi", address);
3191 3432
3192 TS_enter_underline_mode = tgetstr ("us", address); 3433 tty->TS_enter_underline_mode = tgetstr ("us", address);
3193 TS_exit_underline_mode = tgetstr ("ue", address); 3434 tty->TS_exit_underline_mode = tgetstr ("ue", address);
3194 TS_enter_bold_mode = tgetstr ("md", address); 3435 tty->TS_enter_bold_mode = tgetstr ("md", address);
3195 TS_enter_dim_mode = tgetstr ("mh", address); 3436 tty->TS_enter_dim_mode = tgetstr ("mh", address);
3196 TS_enter_blink_mode = tgetstr ("mb", address); 3437 tty->TS_enter_blink_mode = tgetstr ("mb", address);
3197 TS_enter_reverse_mode = tgetstr ("mr", address); 3438 tty->TS_enter_reverse_mode = tgetstr ("mr", address);
3198 TS_enter_alt_charset_mode = tgetstr ("as", address); 3439 tty->TS_enter_alt_charset_mode = tgetstr ("as", address);
3199 TS_exit_alt_charset_mode = tgetstr ("ae", address); 3440 tty->TS_exit_alt_charset_mode = tgetstr ("ae", address);
3200 TS_exit_attribute_mode = tgetstr ("me", address); 3441 tty->TS_exit_attribute_mode = tgetstr ("me", address);
3201 3442
3202 MultiUp = tgetstr ("UP", address); 3443 MultiUp (tty) = tgetstr ("UP", address);
3203 MultiDown = tgetstr ("DO", address); 3444 MultiDown (tty) = tgetstr ("DO", address);
3204 MultiLeft = tgetstr ("LE", address); 3445 MultiLeft (tty) = tgetstr ("LE", address);
3205 MultiRight = tgetstr ("RI", address); 3446 MultiRight (tty) = tgetstr ("RI", address);
3206 3447
3207 /* SVr4/ANSI color suppert. If "op" isn't available, don't support 3448 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
3208 color because we can't switch back to the default foreground and 3449 color because we can't switch back to the default foreground and
3209 background. */ 3450 background. */
3210 TS_orig_pair = tgetstr ("op", address); 3451 tty->TS_orig_pair = tgetstr ("op", address);
3211 if (TS_orig_pair) 3452 if (tty->TS_orig_pair)
3212 { 3453 {
3213 TS_set_foreground = tgetstr ("AF", address); 3454 tty->TS_set_foreground = tgetstr ("AF", address);
3214 TS_set_background = tgetstr ("AB", address); 3455 tty->TS_set_background = tgetstr ("AB", address);
3215 if (!TS_set_foreground) 3456 if (!tty->TS_set_foreground)
3216 { 3457 {
3217 /* SVr4. */ 3458 /* SVr4. */
3218 TS_set_foreground = tgetstr ("Sf", address); 3459 tty->TS_set_foreground = tgetstr ("Sf", address);
3219 TS_set_background = tgetstr ("Sb", address); 3460 tty->TS_set_background = tgetstr ("Sb", address);
3220 } 3461 }
3221 3462
3222 TN_max_colors = tgetnum ("Co"); 3463 tty->TN_max_colors = tgetnum ("Co");
3223 TN_max_pairs = tgetnum ("pa"); 3464 tty->TN_max_pairs = tgetnum ("pa");
3224 3465
3225 TN_no_color_video = tgetnum ("NC"); 3466 tty->TN_no_color_video = tgetnum ("NC");
3226 if (TN_no_color_video == -1) 3467 if (tty->TN_no_color_video == -1)
3227 TN_no_color_video = 0; 3468 tty->TN_no_color_video = 0;
3228 } 3469 }
3229 3470
3230 tty_default_color_capabilities (1); 3471 tty_default_color_capabilities (tty, 1);
3231 3472
3232 MagicWrap = tgetflag ("xn"); 3473 MagicWrap (tty) = tgetflag ("xn");
3233 /* Since we make MagicWrap terminals look like AutoWrap, we need to have 3474 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3234 the former flag imply the latter. */ 3475 the former flag imply the latter. */
3235 AutoWrap = MagicWrap || tgetflag ("am"); 3476 AutoWrap (tty) = MagicWrap (tty) || tgetflag ("am");
3236 memory_below_frame = tgetflag ("db"); 3477 terminal->memory_below_frame = tgetflag ("db");
3237 TF_hazeltine = tgetflag ("hz"); 3478 tty->TF_hazeltine = tgetflag ("hz");
3238 must_write_spaces = tgetflag ("in"); 3479 terminal->must_write_spaces = tgetflag ("in");
3239 meta_key = tgetflag ("km") || tgetflag ("MT"); 3480 tty->meta_key = tgetflag ("km") || tgetflag ("MT");
3240 TF_insmode_motion = tgetflag ("mi"); 3481 tty->TF_insmode_motion = tgetflag ("mi");
3241 TF_standout_motion = tgetflag ("ms"); 3482 tty->TF_standout_motion = tgetflag ("ms");
3242 TF_underscore = tgetflag ("ul"); 3483 tty->TF_underscore = tgetflag ("ul");
3243 TF_teleray = tgetflag ("xt"); 3484 tty->TF_teleray = tgetflag ("xt");
3244 3485
3245 term_get_fkeys (address); 3486 #ifdef MULTI_KBOARD
3487 terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
3488 init_kboard (terminal->kboard);
3489 terminal->kboard->next_kboard = all_kboards;
3490 all_kboards = terminal->kboard;
3491 terminal->kboard->reference_count++;
3492 /* Don't let the initial kboard remain current longer than necessary.
3493 That would cause problems if a file loaded on startup tries to
3494 prompt in the mini-buffer. */
3495 if (current_kboard == initial_kboard)
3496 current_kboard = terminal->kboard;
3497 term_get_fkeys (address, terminal->kboard);
3498 #endif
3246 3499
3247 /* Get frame size from system, or else from termcap. */ 3500 /* Get frame size from system, or else from termcap. */
3248 { 3501 {
3249 int height, width; 3502 int height, width;
3250 get_frame_size (&width, &height); 3503 get_tty_size (fileno (tty->input), &width, &height);
3251 FRAME_COLS (sf) = width; 3504 FrameCols (tty) = width;
3252 FRAME_LINES (sf) = height; 3505 FrameRows (tty) = height;
3253 } 3506 }
3254 3507
3255 if (FRAME_COLS (sf) <= 0) 3508 if (FrameCols (tty) <= 0)
3256 SET_FRAME_COLS (sf, tgetnum ("co")); 3509 FrameCols (tty) = tgetnum ("co");
3257 else 3510 if (FrameRows (tty) <= 0)
3258 /* Keep width and external_width consistent */ 3511 FrameRows (tty) = tgetnum ("li");
3259 SET_FRAME_COLS (sf, FRAME_COLS (sf)); 3512
3260 if (FRAME_LINES (sf) <= 0) 3513 if (FrameRows (tty) < 3 || FrameCols (tty) < 3)
3261 FRAME_LINES (sf) = tgetnum ("li"); 3514 maybe_fatal (must_succeed, NULL, terminal,
3262 3515 "Screen size %dx%d is too small"
3263 if (FRAME_LINES (sf) < 3 || FRAME_COLS (sf) < 3) 3516 "Screen size %dx%d is too small",
3264 fatal ("Screen size %dx%d is too small", 3517 FrameCols (tty), FrameRows (tty));
3265 FRAME_LINES (sf), FRAME_COLS (sf)); 3518
3266 3519 #if 0 /* This is not used anywhere. */
3267 min_padding_speed = tgetnum ("pb"); 3520 tty->terminal->min_padding_speed = tgetnum ("pb");
3268 TabWidth = tgetnum ("tw"); 3521 #endif
3522
3523 TabWidth (tty) = tgetnum ("tw");
3269 3524
3270 #ifdef VMS 3525 #ifdef VMS
3271 /* These capabilities commonly use ^J. 3526 /* These capabilities commonly use ^J.
3272 I don't know why, but sending them on VMS does not work; 3527 I don't know why, but sending them on VMS does not work;
3273 it causes following spaces to be lost, sometimes. 3528 it causes following spaces to be lost, sometimes.
3274 For now, the simplest fix is to avoid using these capabilities ever. */ 3529 For now, the simplest fix is to avoid using these capabilities ever. */
3275 if (Down && Down[0] == '\n') 3530 if (Down (tty) && Down (tty)[0] == '\n')
3276 Down = 0; 3531 Down (tty) = 0;
3277 #endif /* VMS */ 3532 #endif /* VMS */
3278 3533
3279 if (!TS_bell) 3534 if (!tty->TS_bell)
3280 TS_bell = "\07"; 3535 tty->TS_bell = "\07";
3281 3536
3282 if (!TS_fwd_scroll) 3537 if (!tty->TS_fwd_scroll)
3283 TS_fwd_scroll = Down; 3538 tty->TS_fwd_scroll = Down (tty);
3284 3539
3285 PC = TS_pad_char ? *TS_pad_char : 0; 3540 PC = tty->TS_pad_char ? *tty->TS_pad_char : 0;
3286 3541
3287 if (TabWidth < 0) 3542 if (TabWidth (tty) < 0)
3288 TabWidth = 8; 3543 TabWidth (tty) = 8;
3289 3544
3290 /* Turned off since /etc/termcap seems to have :ta= for most terminals 3545 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3291 and newer termcap doc does not seem to say there is a default. 3546 and newer termcap doc does not seem to say there is a default.
3292 if (!Wcm.cm_tab) 3547 if (!tty->Wcm->cm_tab)
3293 Wcm.cm_tab = "\t"; 3548 tty->Wcm->cm_tab = "\t";
3294 */ 3549 */
3295 3550
3296 /* We don't support standout modes that use `magic cookies', so 3551 /* We don't support standout modes that use `magic cookies', so
3297 turn off any that do. */ 3552 turn off any that do. */
3298 if (TS_standout_mode && tgetnum ("sg") >= 0) 3553 if (tty->TS_standout_mode && tgetnum ("sg") >= 0)
3299 { 3554 {
3300 TS_standout_mode = 0; 3555 tty->TS_standout_mode = 0;
3301 TS_end_standout_mode = 0; 3556 tty->TS_end_standout_mode = 0;
3302 } 3557 }
3303 if (TS_enter_underline_mode && tgetnum ("ug") >= 0) 3558 if (tty->TS_enter_underline_mode && tgetnum ("ug") >= 0)
3304 { 3559 {
3305 TS_enter_underline_mode = 0; 3560 tty->TS_enter_underline_mode = 0;
3306 TS_exit_underline_mode = 0; 3561 tty->TS_exit_underline_mode = 0;
3307 } 3562 }
3308 3563
3309 /* If there's no standout mode, try to use underlining instead. */ 3564 /* If there's no standout mode, try to use underlining instead. */
3310 if (TS_standout_mode == 0) 3565 if (tty->TS_standout_mode == 0)
3311 { 3566 {
3312 TS_standout_mode = TS_enter_underline_mode; 3567 tty->TS_standout_mode = tty->TS_enter_underline_mode;
3313 TS_end_standout_mode = TS_exit_underline_mode; 3568 tty->TS_end_standout_mode = tty->TS_exit_underline_mode;
3314 } 3569 }
3315 3570
3316 /* If no `se' string, try using a `me' string instead. 3571 /* If no `se' string, try using a `me' string instead.
3317 If that fails, we can't use standout mode at all. */ 3572 If that fails, we can't use standout mode at all. */
3318 if (TS_end_standout_mode == 0) 3573 if (tty->TS_end_standout_mode == 0)
3319 { 3574 {
3320 char *s = tgetstr ("me", address); 3575 char *s = tgetstr ("me", address);
3321 if (s != 0) 3576 if (s != 0)
3322 TS_end_standout_mode = s; 3577 tty->TS_end_standout_mode = s;
3323 else 3578 else
3324 TS_standout_mode = 0; 3579 tty->TS_standout_mode = 0;
3325 } 3580 }
3326 3581
3327 if (TF_teleray) 3582 if (tty->TF_teleray)
3328 { 3583 {
3329 Wcm.cm_tab = 0; 3584 tty->Wcm->cm_tab = 0;
3330 /* We can't support standout mode, because it uses magic cookies. */ 3585 /* We can't support standout mode, because it uses magic cookies. */
3331 TS_standout_mode = 0; 3586 tty->TS_standout_mode = 0;
3332 /* But that means we cannot rely on ^M to go to column zero! */ 3587 /* But that means we cannot rely on ^M to go to column zero! */
3333 CR = 0; 3588 CR (tty) = 0;
3334 /* LF can't be trusted either -- can alter hpos */ 3589 /* LF can't be trusted either -- can alter hpos */
3335 /* if move at column 0 thru a line with TS_standout_mode */ 3590 /* if move at column 0 thru a line with TS_standout_mode */
3336 Down = 0; 3591 Down (tty) = 0;
3337 } 3592 }
3338 3593
3339 /* Special handling for certain terminal types known to need it */ 3594 /* Special handling for certain terminal types known to need it */
3340 3595
3341 if (!strcmp (terminal_type, "supdup")) 3596 if (!strcmp (terminal_type, "supdup"))
3342 { 3597 {
3343 memory_below_frame = 1; 3598 terminal->memory_below_frame = 1;
3344 Wcm.cm_losewrap = 1; 3599 tty->Wcm->cm_losewrap = 1;
3345 } 3600 }
3346 if (!strncmp (terminal_type, "c10", 3) 3601 if (!strncmp (terminal_type, "c10", 3)
3347 || !strcmp (terminal_type, "perq")) 3602 || !strcmp (terminal_type, "perq"))
3348 { 3603 {
3349 /* Supply a makeshift :wi string. 3604 /* Supply a makeshift :wi string.
3356 So first check the :ti string to see if that is true. 3611 So first check the :ti string to see if that is true.
3357 3612
3358 It would be simpler if the :wi string could go in the termcap 3613 It would be simpler if the :wi string could go in the termcap
3359 entry, but it can't because it is not fully valid. 3614 entry, but it can't because it is not fully valid.
3360 If it were in the termcap entry, it would confuse other programs. */ 3615 If it were in the termcap entry, it would confuse other programs. */
3361 if (!TS_set_window) 3616 if (!tty->TS_set_window)
3362 { 3617 {
3363 p = TS_termcap_modes; 3618 p = tty->TS_termcap_modes;
3364 while (*p && strcmp (p, "\033v ")) 3619 while (*p && strcmp (p, "\033v "))
3365 p++; 3620 p++;
3366 if (*p) 3621 if (*p)
3367 TS_set_window = "\033v%C %C %C %C "; 3622 tty->TS_set_window = "\033v%C %C %C %C ";
3368 } 3623 }
3369 /* Termcap entry often fails to have :in: flag */ 3624 /* Termcap entry often fails to have :in: flag */
3370 must_write_spaces = 1; 3625 terminal->must_write_spaces = 1;
3371 /* :ti string typically fails to have \E^G! in it */ 3626 /* :ti string typically fails to have \E^G! in it */
3372 /* This limits scope of insert-char to one line. */ 3627 /* This limits scope of insert-char to one line. */
3373 strcpy (area, TS_termcap_modes); 3628 strcpy (area, tty->TS_termcap_modes);
3374 strcat (area, "\033\007!"); 3629 strcat (area, "\033\007!");
3375 TS_termcap_modes = area; 3630 tty->TS_termcap_modes = area;
3376 area += strlen (area) + 1; 3631 area += strlen (area) + 1;
3377 p = AbsPosition; 3632 p = AbsPosition (tty);
3378 /* Change all %+ parameters to %C, to handle 3633 /* Change all %+ parameters to %C, to handle
3379 values above 96 correctly for the C100. */ 3634 values above 96 correctly for the C100. */
3380 while (*p) 3635 while (*p)
3381 { 3636 {
3382 if (p[0] == '%' && p[1] == '+') 3637 if (p[0] == '%' && p[1] == '+')
3383 p[1] = 'C'; 3638 p[1] = 'C';
3384 p++; 3639 p++;
3385 } 3640 }
3386 } 3641 }
3387 3642
3388 FrameRows = FRAME_LINES (sf); 3643 tty->specified_window = FrameRows (tty);
3389 FrameCols = FRAME_COLS (sf); 3644
3390 specified_window = FRAME_LINES (sf); 3645 if (Wcm_init (tty) == -1) /* can't do cursor motion */
3391 3646 {
3392 if (Wcm_init () == -1) /* can't do cursor motion */ 3647 maybe_fatal (must_succeed, NULL, terminal,
3648 "Terminal type \"%s\" is not powerful enough to run Emacs",
3393 #ifdef VMS 3649 #ifdef VMS
3394 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\ 3650 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3395 It lacks the ability to position the cursor.\n\ 3651 It lacks the ability to position the cursor.\n\
3396 If that is not the actual type of terminal you have, use either the\n\ 3652 If that is not the actual type of terminal you have, use either the\n\
3397 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\ 3653 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
3398 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.", 3654 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
3399 terminal_type);
3400 #else /* not VMS */ 3655 #else /* not VMS */
3401 # ifdef TERMINFO 3656 # ifdef TERMINFO
3402 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\ 3657 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3403 It lacks the ability to position the cursor.\n\ 3658 It lacks the ability to position the cursor.\n\
3404 If that is not the actual type of terminal you have,\n\ 3659 If that is not the actual type of terminal you have,\n\
3405 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ 3660 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3406 `setenv TERM ...') to specify the correct type. It may be necessary\n\ 3661 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3407 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.", 3662 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3408 terminal_type);
3409 # else /* TERMCAP */ 3663 # else /* TERMCAP */
3410 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\ 3664 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3411 It lacks the ability to position the cursor.\n\ 3665 It lacks the ability to position the cursor.\n\
3412 If that is not the actual type of terminal you have,\n\ 3666 If that is not the actual type of terminal you have,\n\
3413 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ 3667 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3414 `setenv TERM ...') to specify the correct type. It may be necessary\n\ 3668 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3415 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", 3669 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3416 terminal_type);
3417 # endif /* TERMINFO */ 3670 # endif /* TERMINFO */
3418 #endif /*VMS */ 3671 #endif /*VMS */
3419 if (FRAME_LINES (sf) <= 0 3672 terminal_type);
3420 || FRAME_COLS (sf) <= 0) 3673 }
3421 fatal ("The frame size has not been specified"); 3674
3422 3675 if (FrameRows (tty) <= 0 || FrameCols (tty) <= 0)
3423 delete_in_insert_mode 3676 maybe_fatal (must_succeed, NULL, terminal,
3424 = TS_delete_mode && TS_insert_mode 3677 "Could not determine the frame size",
3425 && !strcmp (TS_delete_mode, TS_insert_mode); 3678 "Could not determine the frame size");
3426 3679
3427 se_is_so = (TS_standout_mode 3680 tty->delete_in_insert_mode
3428 && TS_end_standout_mode 3681 = tty->TS_delete_mode && tty->TS_insert_mode
3429 && !strcmp (TS_standout_mode, TS_end_standout_mode)); 3682 && !strcmp (tty->TS_delete_mode, tty->TS_insert_mode);
3430 3683
3431 UseTabs = tabs_safe_p () && TabWidth == 8; 3684 tty->se_is_so = (tty->TS_standout_mode
3432 3685 && tty->TS_end_standout_mode
3433 scroll_region_ok 3686 && !strcmp (tty->TS_standout_mode, tty->TS_end_standout_mode));
3434 = (Wcm.cm_abs 3687
3435 && (TS_set_window || TS_set_scroll_region || TS_set_scroll_region_1)); 3688 UseTabs (tty) = tabs_safe_p (fileno (tty->input)) && TabWidth (tty) == 8;
3436 3689
3437 line_ins_del_ok = (((TS_ins_line || TS_ins_multi_lines) 3690 terminal->scroll_region_ok
3438 && (TS_del_line || TS_del_multi_lines)) 3691 = (tty->Wcm->cm_abs
3439 || (scroll_region_ok && TS_fwd_scroll && TS_rev_scroll)); 3692 && (tty->TS_set_window || tty->TS_set_scroll_region || tty->TS_set_scroll_region_1));
3440 3693
3441 char_ins_del_ok = ((TS_ins_char || TS_insert_mode 3694 terminal->line_ins_del_ok
3442 || TS_pad_inserted_char || TS_ins_multi_chars) 3695 = (((tty->TS_ins_line || tty->TS_ins_multi_lines)
3443 && (TS_del_char || TS_del_multi_chars)); 3696 && (tty->TS_del_line || tty->TS_del_multi_lines))
3444 3697 || (terminal->scroll_region_ok
3445 fast_clear_end_of_line = TS_clr_line != 0; 3698 && tty->TS_fwd_scroll && tty->TS_rev_scroll));
3446 3699
3447 init_baud_rate (); 3700 terminal->char_ins_del_ok
3448 if (read_socket_hook) /* Baudrate is somewhat */ 3701 = ((tty->TS_ins_char || tty->TS_insert_mode
3449 /* meaningless in this case */ 3702 || tty->TS_pad_inserted_char || tty->TS_ins_multi_chars)
3450 baud_rate = 9600; 3703 && (tty->TS_del_char || tty->TS_del_multi_chars));
3451 3704
3452 FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0; 3705 terminal->fast_clear_end_of_line = tty->TS_clr_line != 0;
3453 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none; 3706
3454 #endif /* WINDOWSNT */ 3707 init_baud_rate (fileno (tty->input));
3455 3708
3456 xfree (buffer); 3709 #ifdef AIXHFT
3710 /* The HFT system on AIX doesn't optimize for scrolling, so it's
3711 really ugly at times. */
3712 terminal->line_ins_del_ok = 0;
3713 terminal->char_ins_del_ok = 0;
3714 #endif
3715
3716 /* Don't do this. I think termcap may still need the buffer. */
3717 /* xfree (buffer); */
3718
3719 /* Init system terminal modes (RAW or CBREAK, etc.). */
3720 init_sys_modes (tty);
3721
3722 return terminal;
3723 #endif /* not WINDOWSNT */
3724 }
3725
3726 /* Auxiliary error-handling function for init_tty.
3727 Free BUFFER and delete TERMINAL, then call error or fatal
3728 with str1 or str2, respectively, according to MUST_SUCCEED. */
3729
3730 static void
3731 maybe_fatal (must_succeed, buffer, terminal, str1, str2, arg1, arg2)
3732 int must_succeed;
3733 char *buffer;
3734 struct terminal *terminal;
3735 char *str1, *str2, *arg1, *arg2;
3736 {
3737 if (buffer)
3738 xfree (buffer);
3739
3740 if (terminal)
3741 delete_tty (terminal);
3742
3743 if (must_succeed)
3744 fatal (str2, arg1, arg2);
3745 else
3746 error (str1, arg1, arg2);
3747
3748 abort ();
3457 } 3749 }
3458 3750
3459 /* VARARGS 1 */ 3751 /* VARARGS 1 */
3460 void 3752 void
3461 fatal (str, arg1, arg2) 3753 fatal (str, arg1, arg2)
3466 fprintf (stderr, "\n"); 3758 fprintf (stderr, "\n");
3467 fflush (stderr); 3759 fflush (stderr);
3468 exit (1); 3760 exit (1);
3469 } 3761 }
3470 3762
3471 DEFUN ("tty-no-underline", Ftty_no_underline, Stty_no_underline, 0, 0, 0, 3763
3472 doc: /* Declare that this terminal does not handle underlining. 3764
3473 This is used to override the terminfo data, for certain terminals that 3765 /* Delete the given tty terminal, closing all frames on it. */
3474 do not really do underlining, but say that they do. */) 3766
3475 () 3767 static void
3476 { 3768 delete_tty (struct terminal *terminal)
3477 TS_enter_underline_mode = 0; 3769 {
3478 return Qnil; 3770 struct tty_display_info *tty;
3479 } 3771 Lisp_Object tail, frame;
3772 int last_terminal;
3773
3774 /* Protect against recursive calls. Fdelete_frame in
3775 delete_terminal calls us back when it deletes our last frame. */
3776 if (terminal->deleted)
3777 return;
3778
3779 if (terminal->type != output_termcap)
3780 abort ();
3781
3782 tty = terminal->display_info.tty;
3783
3784 last_terminal = 1;
3785 FOR_EACH_FRAME (tail, frame)
3786 {
3787 struct frame *f = XFRAME (frame);
3788 if (FRAME_LIVE_P (f) && (!FRAME_TERMCAP_P (f) || FRAME_TTY (f) != tty))
3789 {
3790 last_terminal = 0;
3791 break;
3792 }
3793 }
3794 if (last_terminal)
3795 error ("Attempt to delete the sole terminal device with live frames");
3796
3797 if (tty == tty_list)
3798 tty_list = tty->next;
3799 else
3800 {
3801 struct tty_display_info *p;
3802 for (p = tty_list; p && p->next != tty; p = p->next)
3803 ;
3804
3805 if (! p)
3806 /* This should not happen. */
3807 abort ();
3808
3809 p->next = tty->next;
3810 tty->next = 0;
3811 }
3812
3813 /* reset_sys_modes needs a valid device, so this call needs to be
3814 before delete_terminal. */
3815 reset_sys_modes (tty);
3816
3817 delete_terminal (terminal);
3818
3819 if (tty->name)
3820 xfree (tty->name);
3821
3822 if (tty->type)
3823 xfree (tty->type);
3824
3825 if (tty->input)
3826 {
3827 delete_keyboard_wait_descriptor (fileno (tty->input));
3828 if (tty->input != stdin)
3829 fclose (tty->input);
3830 }
3831 if (tty->output && tty->output != stdout && tty->output != tty->input)
3832 fclose (tty->output);
3833 if (tty->termscript)
3834 fclose (tty->termscript);
3835
3836 if (tty->old_tty)
3837 xfree (tty->old_tty);
3838
3839 if (tty->Wcm)
3840 xfree (tty->Wcm);
3841
3842 bzero (tty, sizeof (struct tty_display_info));
3843 xfree (tty);
3844 }
3845
3846
3847
3848 /* Mark the pointers in the tty_display_info objects.
3849 Called by the Fgarbage_collector. */
3850
3851 void
3852 mark_ttys (void)
3853 {
3854 struct tty_display_info *tty;
3855
3856 for (tty = tty_list; tty; tty = tty->next)
3857 {
3858 if (tty->top_frame)
3859 mark_object (tty->top_frame);
3860 }
3861 }
3862
3863
3480 3864
3481 void 3865 void
3482 syms_of_term () 3866 syms_of_term ()
3483 { 3867 {
3484 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo, 3868 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo,
3488 system_uses_terminfo = 1; 3872 system_uses_terminfo = 1;
3489 #else 3873 #else
3490 system_uses_terminfo = 0; 3874 system_uses_terminfo = 0;
3491 #endif 3875 #endif
3492 3876
3493 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function, 3877 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions,
3494 doc: /* Non-nil means call this function to ring the bell. 3878 doc: /* Functions to be run after suspending a tty.
3495 The function should accept no arguments. */); 3879 The functions are run with one argument, the terminal id to be suspended.
3496 Vring_bell_function = Qnil; 3880 See `suspend-tty'. */);
3881 Vsuspend_tty_functions = Qnil;
3882
3883
3884 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions,
3885 doc: /* Functions to be run after resuming a tty.
3886 The functions are run with one argument, the terminal id that was revived.
3887 See `resume-tty'. */);
3888 Vresume_tty_functions = Qnil;
3497 3889
3498 DEFVAR_BOOL ("visible-cursor", &visible_cursor, 3890 DEFVAR_BOOL ("visible-cursor", &visible_cursor,
3499 doc: /* Non-nil means to make the cursor very visible. 3891 doc: /* Non-nil means to make the cursor very visible.
3500 This only has an effect when running in a text terminal. 3892 This only has an effect when running in a text terminal.
3501 What means \"very visible\" is up to your terminal. It may make the cursor 3893 What means \"very visible\" is up to your terminal. It may make the cursor
3503 visible_cursor = 1; 3895 visible_cursor = 1;
3504 3896
3505 defsubr (&Stty_display_color_p); 3897 defsubr (&Stty_display_color_p);
3506 defsubr (&Stty_display_color_cells); 3898 defsubr (&Stty_display_color_cells);
3507 defsubr (&Stty_no_underline); 3899 defsubr (&Stty_no_underline);
3900 defsubr (&Stty_type);
3901 defsubr (&Scontrolling_tty_p);
3902 defsubr (&Ssuspend_tty);
3903 defsubr (&Sresume_tty);
3508 #ifdef HAVE_GPM 3904 #ifdef HAVE_GPM
3509 defsubr (&Sterm_open_connection); 3905 defsubr (&Sterm_open_connection);
3510 defsubr (&Sterm_close_connection); 3906 defsubr (&Sterm_close_connection);
3511 3907
3512 staticpro (&Qmouse_face_window); 3908 staticpro (&Qmouse_face_window);
3513 #endif /* HAVE_GPM */ 3909 #endif /* HAVE_GPM */
3514 3910 }
3515 fullscreen_hook = NULL; 3911
3516 } 3912
3517 3913
3518 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193 3914 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
3519 (do not change this comment) */ 3915 (do not change this comment) */