Mercurial > emacs
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) */ |