253
|
1 /* terminal control module for terminals described by TERMCAP
|
25002
|
2 Copyright (C) 1985, 86, 87, 93, 94, 95, 98
|
|
3 Free Software Foundation, Inc.
|
253
|
4
|
|
5 This file is part of GNU Emacs.
|
|
6
|
|
7 GNU Emacs is free software; you can redistribute it and/or modify
|
|
8 it under the terms of the GNU General Public License as published by
|
621
|
9 the Free Software Foundation; either version 2, or (at your option)
|
253
|
10 any later version.
|
|
11
|
|
12 GNU Emacs is distributed in the hope that it will be useful,
|
|
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15 GNU General Public License for more details.
|
|
16
|
|
17 You should have received a copy of the GNU General Public License
|
|
18 along with GNU Emacs; see the file COPYING. If not, write to
|
14186
|
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
20 Boston, MA 02111-1307, USA. */
|
253
|
21
|
25002
|
22 /* New redisplay, TTY faces by Gerd Moellmann <gerd@acm.org>. */
|
|
23
|
253
|
24
|
7900
|
25 #include <config.h>
|
253
|
26 #include <stdio.h>
|
|
27 #include <ctype.h>
|
25002
|
28 #include <string.h>
|
253
|
29 #include "termchar.h"
|
|
30 #include "termopts.h"
|
|
31 #include "lisp.h"
|
17046
|
32 #include "charset.h"
|
|
33 #include "coding.h"
|
31102
|
34 #include "keyboard.h"
|
765
|
35 #include "frame.h"
|
253
|
36 #include "disptab.h"
|
|
37 #include "termhooks.h"
|
21514
|
38 #include "dispextern.h"
|
25002
|
39 #include "window.h"
|
|
40
|
33672
|
41 /* For now, don't try to include termcap.h. On some systems,
|
|
42 configure finds a non-standard termcap.h that the main build
|
|
43 won't find. */
|
|
44
|
|
45 #if defined HAVE_TERMCAP_H && 0
|
25727
|
46 #include <termcap.h>
|
29929
|
47 #else
|
|
48 extern void tputs P_ ((const char *, int, int (*)(int)));
|
|
49 extern int tgetent P_ ((char *, const char *));
|
|
50 extern int tgetflag P_ ((char *id));
|
|
51 extern int tgetnum P_ ((char *id));
|
25727
|
52 #endif
|
|
53
|
21827
87c7f4bd99da
Include cm.h after dispextern.h to avoid name conflicts
Geoff Voelker <voelker@cs.washington.edu>
diff
changeset
|
54 #include "cm.h"
|
21514
|
55 #ifdef HAVE_X_WINDOWS
|
|
56 #include "xterm.h"
|
|
57 #endif
|
32752
|
58 #ifdef macintosh
|
|
59 #include "macterm.h"
|
|
60 #endif
|
8898
|
61
|
25002
|
62 static void turn_on_face P_ ((struct frame *, int face_id));
|
|
63 static void turn_off_face P_ ((struct frame *, int face_id));
|
|
64 static void tty_show_cursor P_ ((void));
|
|
65 static void tty_hide_cursor P_ ((void));
|
|
66
|
253
|
67 #define max(a, b) ((a) > (b) ? (a) : (b))
|
|
68 #define min(a, b) ((a) < (b) ? (a) : (b))
|
|
69
|
25675
|
70 #define OUTPUT(a) \
|
|
71 tputs (a, (int) (FRAME_HEIGHT (XFRAME (selected_frame)) - curY), cmputc)
|
253
|
72 #define OUTPUT1(a) tputs (a, 1, cmputc)
|
|
73 #define OUTPUTL(a, lines) tputs (a, lines, cmputc)
|
25002
|
74
|
25727
|
75 #define OUTPUT_IF(a) \
|
|
76 do { \
|
|
77 if (a) \
|
|
78 tputs (a, (int) (FRAME_HEIGHT (XFRAME (selected_frame)) \
|
|
79 - curY), cmputc); \
|
|
80 } while (0)
|
25002
|
81
|
25727
|
82 #define OUTPUT1_IF(a) do { if (a) tputs (a, 1, cmputc); } while (0)
|
253
|
83
|
15974
|
84 /* Function to use to ring the bell. */
|
25002
|
85
|
15974
|
86 Lisp_Object Vring_bell_function;
|
|
87
|
3591
|
88 /* Terminal characteristics that higher levels want to look at.
|
253
|
89 These are all extern'd in termchar.h */
|
|
90
|
|
91 int must_write_spaces; /* Nonzero means spaces in the text
|
|
92 must actually be output; can't just skip
|
|
93 over some columns to leave them blank. */
|
|
94 int min_padding_speed; /* Speed below which no padding necessary */
|
|
95
|
|
96 int line_ins_del_ok; /* Terminal can insert and delete lines */
|
|
97 int char_ins_del_ok; /* Terminal can insert and delete chars */
|
|
98 int scroll_region_ok; /* Terminal supports setting the
|
|
99 scroll window */
|
10261
|
100 int scroll_region_cost; /* Cost of setting a scroll window,
|
|
101 measured in characters */
|
765
|
102 int memory_below_frame; /* Terminal remembers lines
|
253
|
103 scrolled off bottom */
|
|
104 int fast_clear_end_of_line; /* Terminal has a `ce' string */
|
|
105
|
765
|
106 /* Nonzero means no need to redraw the entire frame on resuming
|
253
|
107 a suspended Emacs. This is useful on terminals with multiple pages,
|
|
108 where one page is used for Emacs and another for all else. */
|
25002
|
109
|
253
|
110 int no_redraw_on_reenter;
|
|
111
|
|
112 /* Hook functions that you can set to snap out the functions in this file.
|
|
113 These are all extern'd in termhooks.h */
|
|
114
|
21514
|
115 void (*cursor_to_hook) P_ ((int, int));
|
|
116 void (*raw_cursor_to_hook) P_ ((int, int));
|
|
117 void (*clear_to_end_hook) P_ ((void));
|
|
118 void (*clear_frame_hook) P_ ((void));
|
|
119 void (*clear_end_of_line_hook) P_ ((int));
|
253
|
120
|
21514
|
121 void (*ins_del_lines_hook) P_ ((int, int));
|
253
|
122
|
25002
|
123 void (*change_line_highlight_hook) P_ ((int, int, int, int));
|
21514
|
124 void (*reassert_line_highlight_hook) P_ ((int, int));
|
253
|
125
|
21514
|
126 void (*delete_glyphs_hook) P_ ((int));
|
253
|
127
|
21514
|
128 void (*ring_bell_hook) P_ ((void));
|
253
|
129
|
21514
|
130 void (*reset_terminal_modes_hook) P_ ((void));
|
|
131 void (*set_terminal_modes_hook) P_ ((void));
|
|
132 void (*update_begin_hook) P_ ((struct frame *));
|
|
133 void (*update_end_hook) P_ ((struct frame *));
|
|
134 void (*set_terminal_window_hook) P_ ((int));
|
25002
|
135 void (*insert_glyphs_hook) P_ ((struct glyph *, int));
|
|
136 void (*write_glyphs_hook) P_ ((struct glyph *, int));
|
|
137 void (*delete_glyphs_hook) P_ ((int));
|
253
|
138
|
21514
|
139 int (*read_socket_hook) P_ ((int, struct input_event *, int, int));
|
253
|
140
|
21514
|
141 void (*frame_up_to_date_hook) P_ ((struct frame *));
|
6652
|
142
|
1717
|
143 /* Return the current position of the mouse.
|
1781
|
144
|
|
145 Set *f to the frame the mouse is in, or zero if the mouse is in no
|
|
146 Emacs frame. If it is set to zero, all the other arguments are
|
|
147 garbage.
|
|
148
|
1994
|
149 If the motion started in a scroll bar, set *bar_window to the
|
|
150 scroll bar's window, *part to the part the mouse is currently over,
|
|
151 *x to the position of the mouse along the scroll bar, and *y to the
|
|
152 overall length of the scroll bar.
|
1781
|
153
|
|
154 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
|
|
155 row of the character cell the mouse is over.
|
|
156
|
|
157 Set *time to the time the mouse was at the returned position.
|
|
158
|
|
159 This should clear mouse_moved until the next motion
|
|
160 event arrives. */
|
21514
|
161 void (*mouse_position_hook) P_ ((FRAME_PTR *f, int insist,
|
1781
|
162 Lisp_Object *bar_window,
|
1994
|
163 enum scroll_bar_part *part,
|
1717
|
164 Lisp_Object *x,
|
|
165 Lisp_Object *y,
|
21514
|
166 unsigned long *time));
|
253
|
167
|
765
|
168 /* When reading from a minibuffer in a different frame, Emacs wants
|
25002
|
169 to shift the highlight from the selected frame to the mini-buffer's
|
765
|
170 frame; under X, this means it lies about where the focus is.
|
339
|
171 This hook tells the window system code to re-decide where to put
|
|
172 the highlight. */
|
21514
|
173 void (*frame_rehighlight_hook) P_ ((FRAME_PTR f));
|
339
|
174
|
1821
|
175 /* If we're displaying frames using a window system that can stack
|
|
176 frames on top of each other, this hook allows you to bring a frame
|
|
177 to the front, or bury it behind all the other windows. If this
|
|
178 hook is zero, that means the device we're displaying on doesn't
|
|
179 support overlapping frames, so there's no need to raise or lower
|
|
180 anything.
|
|
181
|
|
182 If RAISE is non-zero, F is brought to the front, before all other
|
|
183 windows. If RAISE is zero, F is sent to the back, behind all other
|
|
184 windows. */
|
21514
|
185 void (*frame_raise_lower_hook) P_ ((FRAME_PTR f, int raise));
|
1821
|
186
|
1994
|
187 /* Set the vertical scroll bar for WINDOW to have its upper left corner
|
1781
|
188 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
|
|
189 indicate that we are displaying PORTION characters out of a total
|
|
190 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
|
1994
|
191 have a scroll bar, create one for it. */
|
25002
|
192
|
1994
|
193 void (*set_vertical_scroll_bar_hook)
|
21514
|
194 P_ ((struct window *window,
|
|
195 int portion, int whole, int position));
|
1717
|
196
|
1781
|
197
|
1717
|
198 /* The following three hooks are used when we're doing a thorough
|
1994
|
199 redisplay of the frame. We don't explicitly know which scroll bars
|
1717
|
200 are going to be deleted, because keeping track of when windows go
|
|
201 away is a real pain - can you say set-window-configuration?
|
|
202 Instead, we just assert at the beginning of redisplay that *all*
|
1994
|
203 scroll bars are to be removed, and then save scroll bars from the
|
14036
|
204 fiery pit when we actually redisplay their window. */
|
1717
|
205
|
1994
|
206 /* Arrange for all scroll bars on FRAME to be removed at the next call
|
|
207 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
|
25002
|
208 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
|
1781
|
209
|
|
210 This should be applied to each frame each time its window tree is
|
1994
|
211 redisplayed, even if it is not displaying scroll bars at the moment;
|
|
212 if the HAS_SCROLL_BARS flag has just been turned off, only calling
|
|
213 this and the judge_scroll_bars_hook will get rid of them.
|
1717
|
214
|
1781
|
215 If non-zero, this hook should be safe to apply to any frame,
|
1994
|
216 whether or not it can support scroll bars, and whether or not it is
|
1781
|
217 currently displaying them. */
|
21514
|
218 void (*condemn_scroll_bars_hook) P_ ((FRAME_PTR frame));
|
1781
|
219
|
1994
|
220 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
|
|
221 Note that it's okay to redeem a scroll bar that is not condemned. */
|
21514
|
222 void (*redeem_scroll_bar_hook) P_ ((struct window *window));
|
1717
|
223
|
1994
|
224 /* Remove all scroll bars on FRAME that haven't been saved since the
|
|
225 last call to `*condemn_scroll_bars_hook'.
|
1781
|
226
|
|
227 This should be applied to each frame after each time its window
|
1994
|
228 tree is redisplayed, even if it is not displaying scroll bars at the
|
|
229 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
|
|
230 calling this and condemn_scroll_bars_hook will get rid of them.
|
1781
|
231
|
|
232 If non-zero, this hook should be safe to apply to any frame,
|
1994
|
233 whether or not it can support scroll bars, and whether or not it is
|
1781
|
234 currently displaying them. */
|
21514
|
235 void (*judge_scroll_bars_hook) P_ ((FRAME_PTR FRAME));
|
1717
|
236
|
25002
|
237 /* Hook to call in estimate_mode_line_height, if any. */
|
|
238
|
|
239 int (* estimate_mode_line_height_hook) P_ ((struct frame *f, enum face_id));
|
|
240
|
1717
|
241
|
253
|
242 /* Strings, numbers and flags taken from the termcap entry. */
|
|
243
|
17046
|
244 char *TS_ins_line; /* "al" */
|
253
|
245 char *TS_ins_multi_lines; /* "AL" (one parameter, # lines to insert) */
|
|
246 char *TS_bell; /* "bl" */
|
|
247 char *TS_clr_to_bottom; /* "cd" */
|
|
248 char *TS_clr_line; /* "ce", clear to end of line */
|
765
|
249 char *TS_clr_frame; /* "cl" */
|
253
|
250 char *TS_set_scroll_region; /* "cs" (2 params, first line and last line) */
|
|
251 char *TS_set_scroll_region_1; /* "cS" (4 params: total lines,
|
|
252 lines above scroll region, lines below it,
|
|
253 total lines again) */
|
|
254 char *TS_del_char; /* "dc" */
|
|
255 char *TS_del_multi_chars; /* "DC" (one parameter, # chars to delete) */
|
|
256 char *TS_del_line; /* "dl" */
|
|
257 char *TS_del_multi_lines; /* "DL" (one parameter, # lines to delete) */
|
|
258 char *TS_delete_mode; /* "dm", enter character-delete mode */
|
|
259 char *TS_end_delete_mode; /* "ed", leave character-delete mode */
|
|
260 char *TS_end_insert_mode; /* "ei", leave character-insert mode */
|
|
261 char *TS_ins_char; /* "ic" */
|
|
262 char *TS_ins_multi_chars; /* "IC" (one parameter, # chars to insert) */
|
|
263 char *TS_insert_mode; /* "im", enter character-insert mode */
|
|
264 char *TS_pad_inserted_char; /* "ip". Just padding, no commands. */
|
|
265 char *TS_end_keypad_mode; /* "ke" */
|
|
266 char *TS_keypad_mode; /* "ks" */
|
|
267 char *TS_pad_char; /* "pc", char to use as padding */
|
|
268 char *TS_repeat; /* "rp" (2 params, # times to repeat
|
|
269 and character to be repeated) */
|
|
270 char *TS_end_standout_mode; /* "se" */
|
|
271 char *TS_fwd_scroll; /* "sf" */
|
|
272 char *TS_standout_mode; /* "so" */
|
|
273 char *TS_rev_scroll; /* "sr" */
|
|
274 char *TS_end_termcap_modes; /* "te" */
|
|
275 char *TS_termcap_modes; /* "ti" */
|
|
276 char *TS_visible_bell; /* "vb" */
|
25002
|
277 char *TS_cursor_normal; /* "ve" */
|
|
278 char *TS_cursor_visible; /* "vs" */
|
|
279 char *TS_cursor_invisible; /* "vi" */
|
253
|
280 char *TS_set_window; /* "wi" (4 params, start and end of window,
|
|
281 each as vpos and hpos) */
|
|
282
|
28465
|
283 /* Value of the "NC" (no_color_video) capability, or 0 if not
|
|
284 present. */
|
|
285
|
|
286 static int TN_no_color_video;
|
|
287
|
|
288 /* Meaning of bits in no_color_video. Each bit set means that the
|
|
289 corresponding attribute cannot be combined with colors. */
|
|
290
|
|
291 enum no_color_bit
|
|
292 {
|
|
293 NC_STANDOUT = 1 << 0,
|
|
294 NC_UNDERLINE = 1 << 1,
|
|
295 NC_REVERSE = 1 << 2,
|
|
296 NC_BLINK = 1 << 3,
|
|
297 NC_DIM = 1 << 4,
|
|
298 NC_BOLD = 1 << 5,
|
|
299 NC_INVIS = 1 << 6,
|
|
300 NC_PROTECT = 1 << 7,
|
|
301 NC_ALT_CHARSET = 1 << 8
|
|
302 };
|
|
303
|
25002
|
304 /* "md" -- turn on bold (extra bright mode). */
|
|
305
|
|
306 char *TS_enter_bold_mode;
|
|
307
|
|
308 /* "mh" -- turn on half-bright mode. */
|
|
309
|
|
310 char *TS_enter_dim_mode;
|
|
311
|
|
312 /* "mb" -- enter blinking mode. */
|
|
313
|
|
314 char *TS_enter_blink_mode;
|
|
315
|
|
316 /* "mr" -- enter reverse video mode. */
|
|
317
|
|
318 char *TS_enter_reverse_mode;
|
|
319
|
|
320 /* "us"/"ue" -- start/end underlining. */
|
|
321
|
|
322 char *TS_exit_underline_mode, *TS_enter_underline_mode;
|
|
323
|
|
324 /* "ug" -- number of blanks left by underline. */
|
|
325
|
|
326 int TN_magic_cookie_glitch_ul;
|
|
327
|
|
328 /* "as"/"ae" -- start/end alternate character set. Not really
|
|
329 supported, yet. */
|
|
330
|
|
331 char *TS_enter_alt_charset_mode, *TS_exit_alt_charset_mode;
|
|
332
|
|
333 /* "me" -- switch appearances off. */
|
|
334
|
|
335 char *TS_exit_attribute_mode;
|
|
336
|
|
337 /* "Co" -- number of colors. */
|
|
338
|
|
339 int TN_max_colors;
|
|
340
|
|
341 /* "pa" -- max. number of color pairs on screen. Not handled yet.
|
|
342 Could be a problem if not equal to TN_max_colors * TN_max_colors. */
|
|
343
|
|
344 int TN_max_pairs;
|
|
345
|
|
346 /* "op" -- SVr4 set default pair to its original value. */
|
|
347
|
|
348 char *TS_orig_pair;
|
|
349
|
|
350 /* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
|
|
351 1 param, the color index. */
|
|
352
|
|
353 char *TS_set_foreground, *TS_set_background;
|
|
354
|
253
|
355 int TF_hazeltine; /* termcap hz flag. */
|
|
356 int TF_insmode_motion; /* termcap mi flag: can move while in insert mode. */
|
|
357 int TF_standout_motion; /* termcap mi flag: can move while in standout mode. */
|
25002
|
358 int TF_underscore; /* termcap ul flag: _ underlines if over-struck on
|
|
359 non-blank position. Must clear before writing _. */
|
253
|
360 int TF_teleray; /* termcap xt flag: many weird consequences.
|
|
361 For t1061. */
|
|
362
|
|
363 int TF_xs; /* Nonzero for "xs". If set together with
|
|
364 TN_standout_width == 0, it means don't bother
|
|
365 to write any end-standout cookies. */
|
|
366
|
|
367 int TN_standout_width; /* termcap sg number: width occupied by standout
|
|
368 markers */
|
|
369
|
|
370 static int RPov; /* # chars to start a TS_repeat */
|
|
371
|
|
372 static int delete_in_insert_mode; /* delete mode == insert mode */
|
|
373
|
|
374 static int se_is_so; /* 1 if same string both enters and leaves
|
|
375 standout mode */
|
|
376
|
|
377 /* internal state */
|
|
378
|
10771
|
379 /* The largest frame width in any call to calculate_costs. */
|
25002
|
380
|
10771
|
381 int max_frame_width;
|
25002
|
382
|
10771
|
383 /* The largest frame height in any call to calculate_costs. */
|
25002
|
384
|
10771
|
385 int max_frame_height;
|
|
386
|
253
|
387 /* Number of chars of space used for standout marker at beginning of line,
|
|
388 or'd with 0100. Zero if no standout marker at all.
|
10771
|
389 The length of these vectors is max_frame_height.
|
253
|
390
|
|
391 Used IFF TN_standout_width >= 0. */
|
|
392
|
|
393 static char *chars_wasted;
|
|
394 static char *copybuf;
|
|
395
|
|
396 /* nonzero means supposed to write text in standout mode. */
|
25002
|
397
|
253
|
398 int standout_requested;
|
|
399
|
|
400 int insert_mode; /* Nonzero when in insert mode. */
|
|
401 int standout_mode; /* Nonzero when in standout mode. */
|
|
402
|
|
403 /* Size of window specified by higher levels.
|
765
|
404 This is the number of lines, from the top of frame downwards,
|
253
|
405 which can participate in insert-line/delete-line operations.
|
|
406
|
765
|
407 Effectively it excludes the bottom frame_height - specified_window_size
|
253
|
408 lines from those operations. */
|
|
409
|
|
410 int specified_window;
|
|
411
|
765
|
412 /* Frame currently being redisplayed; 0 if not currently redisplaying.
|
253
|
413 (Direct output does not count). */
|
|
414
|
765
|
415 FRAME_PTR updating_frame;
|
253
|
416
|
6752
|
417 /* Provided for lisp packages. */
|
25002
|
418
|
6752
|
419 static int system_uses_terminfo;
|
|
420
|
253
|
421 char *tparam ();
|
8612
|
422
|
|
423 extern char *tgetstr ();
|
253
|
424
|
9797
|
425
|
35448
|
426 #ifdef WINDOWSNT
|
|
427 /* We aren't X windows, but we aren't termcap either. This makes me
|
|
428 uncertain as to what value to use for frame.output_method. For
|
|
429 this file, we'll define FRAME_TERMCAP_P to be zero so that our
|
|
430 output hooks get called instead of the termcap functions. Probably
|
|
431 the best long-term solution is to define an output_windows_nt... */
|
|
432
|
|
433 #undef FRAME_TERMCAP_P
|
|
434 #define FRAME_TERMCAP_P(_f_) 0
|
|
435 #endif /* WINDOWSNT */
|
|
436
|
21514
|
437 void
|
253
|
438 ring_bell ()
|
|
439 {
|
15974
|
440 if (! NILP (Vring_bell_function))
|
|
441 {
|
|
442 Lisp_Object function;
|
|
443
|
|
444 /* Temporarily set the global variable to nil
|
|
445 so that if we get an error, it stays nil
|
|
446 and we don't call it over and over.
|
|
447
|
|
448 We don't specbind it, because that would carefully
|
|
449 restore the bad value if there's an error
|
|
450 and make the loop of errors happen anyway. */
|
|
451 function = Vring_bell_function;
|
|
452 Vring_bell_function = Qnil;
|
|
453
|
|
454 call0 (function);
|
|
455
|
|
456 Vring_bell_function = function;
|
|
457 return;
|
|
458 }
|
|
459
|
25675
|
460 if (! FRAME_TERMCAP_P (XFRAME (selected_frame)))
|
253
|
461 {
|
|
462 (*ring_bell_hook) ();
|
|
463 return;
|
|
464 }
|
|
465 OUTPUT (TS_visible_bell && visible_bell ? TS_visible_bell : TS_bell);
|
|
466 }
|
|
467
|
21514
|
468 void
|
253
|
469 set_terminal_modes ()
|
|
470 {
|
25675
|
471 if (! FRAME_TERMCAP_P (XFRAME (selected_frame)))
|
253
|
472 {
|
|
473 (*set_terminal_modes_hook) ();
|
|
474 return;
|
|
475 }
|
|
476 OUTPUT_IF (TS_termcap_modes);
|
25002
|
477 OUTPUT_IF (TS_cursor_visible);
|
253
|
478 OUTPUT_IF (TS_keypad_mode);
|
|
479 losecursor ();
|
|
480 }
|
|
481
|
21514
|
482 void
|
253
|
483 reset_terminal_modes ()
|
|
484 {
|
25675
|
485 if (! FRAME_TERMCAP_P (XFRAME (selected_frame)))
|
253
|
486 {
|
21624
|
487 if (reset_terminal_modes_hook)
|
|
488 (*reset_terminal_modes_hook) ();
|
253
|
489 return;
|
|
490 }
|
|
491 if (TN_standout_width < 0)
|
|
492 turn_off_highlight ();
|
|
493 turn_off_insert ();
|
|
494 OUTPUT_IF (TS_end_keypad_mode);
|
25002
|
495 OUTPUT_IF (TS_cursor_normal);
|
253
|
496 OUTPUT_IF (TS_end_termcap_modes);
|
25002
|
497 OUTPUT_IF (TS_orig_pair);
|
253
|
498 /* Output raw CR so kernel can track the cursor hpos. */
|
|
499 /* But on magic-cookie terminals this can erase an end-standout marker and
|
765
|
500 cause the rest of the frame to be in standout, so move down first. */
|
253
|
501 if (TN_standout_width >= 0)
|
|
502 cmputc ('\n');
|
|
503 cmputc ('\r');
|
|
504 }
|
|
505
|
21514
|
506 void
|
765
|
507 update_begin (f)
|
|
508 FRAME_PTR f;
|
253
|
509 {
|
765
|
510 updating_frame = f;
|
969
|
511 if (! FRAME_TERMCAP_P (updating_frame))
|
765
|
512 (*update_begin_hook) (f);
|
25002
|
513 else
|
|
514 tty_hide_cursor ();
|
253
|
515 }
|
|
516
|
21514
|
517 void
|
765
|
518 update_end (f)
|
|
519 FRAME_PTR f;
|
253
|
520 {
|
35091
|
521 if (! FRAME_TERMCAP_P (f))
|
253
|
522 {
|
7649
|
523 (*update_end_hook) (f);
|
5648
|
524 updating_frame = 0;
|
253
|
525 return;
|
|
526 }
|
25002
|
527
|
|
528 if (!XWINDOW (selected_window)->cursor_off_p)
|
|
529 tty_show_cursor ();
|
|
530
|
253
|
531 turn_off_insert ();
|
|
532 background_highlight ();
|
|
533 standout_requested = 0;
|
765
|
534 updating_frame = 0;
|
253
|
535 }
|
|
536
|
21514
|
537 void
|
253
|
538 set_terminal_window (size)
|
|
539 int size;
|
|
540 {
|
969
|
541 if (! FRAME_TERMCAP_P (updating_frame))
|
253
|
542 {
|
|
543 (*set_terminal_window_hook) (size);
|
|
544 return;
|
|
545 }
|
25675
|
546 specified_window = size ? size : FRAME_HEIGHT (XFRAME (selected_frame));
|
253
|
547 if (!scroll_region_ok)
|
|
548 return;
|
|
549 set_scroll_region (0, specified_window);
|
|
550 }
|
|
551
|
21514
|
552 void
|
253
|
553 set_scroll_region (start, stop)
|
|
554 int start, stop;
|
|
555 {
|
|
556 char *buf;
|
25675
|
557 struct frame *sf = XFRAME (selected_frame);
|
|
558
|
253
|
559 if (TS_set_scroll_region)
|
|
560 {
|
|
561 buf = tparam (TS_set_scroll_region, 0, 0, start, stop - 1);
|
|
562 }
|
|
563 else if (TS_set_scroll_region_1)
|
|
564 {
|
|
565 buf = tparam (TS_set_scroll_region_1, 0, 0,
|
25675
|
566 FRAME_HEIGHT (sf), start,
|
|
567 FRAME_HEIGHT (sf) - stop,
|
|
568 FRAME_HEIGHT (sf));
|
253
|
569 }
|
|
570 else
|
|
571 {
|
25675
|
572 buf = tparam (TS_set_window, 0, 0, start, 0, stop, FRAME_WIDTH (sf));
|
253
|
573 }
|
|
574 OUTPUT (buf);
|
2439
|
575 xfree (buf);
|
253
|
576 losecursor ();
|
|
577 }
|
|
578
|
21514
|
579 void
|
253
|
580 turn_on_insert ()
|
|
581 {
|
|
582 if (!insert_mode)
|
|
583 OUTPUT (TS_insert_mode);
|
|
584 insert_mode = 1;
|
|
585 }
|
|
586
|
21514
|
587 void
|
253
|
588 turn_off_insert ()
|
|
589 {
|
|
590 if (insert_mode)
|
|
591 OUTPUT (TS_end_insert_mode);
|
|
592 insert_mode = 0;
|
|
593 }
|
|
594
|
|
595 /* Handle highlighting when TN_standout_width (termcap sg) is not specified.
|
|
596 In these terminals, output is affected by the value of standout
|
|
597 mode when the output is written.
|
|
598
|
|
599 These functions are called on all terminals, but do nothing
|
|
600 on terminals whose standout mode does not work that way. */
|
|
601
|
21514
|
602 void
|
253
|
603 turn_off_highlight ()
|
|
604 {
|
|
605 if (TN_standout_width < 0)
|
|
606 {
|
|
607 if (standout_mode)
|
|
608 OUTPUT_IF (TS_end_standout_mode);
|
|
609 standout_mode = 0;
|
|
610 }
|
|
611 }
|
|
612
|
21514
|
613 void
|
253
|
614 turn_on_highlight ()
|
|
615 {
|
|
616 if (TN_standout_width < 0)
|
|
617 {
|
|
618 if (!standout_mode)
|
|
619 OUTPUT_IF (TS_standout_mode);
|
|
620 standout_mode = 1;
|
|
621 }
|
|
622 }
|
|
623
|
25002
|
624
|
|
625 /* Make cursor invisible. */
|
|
626
|
|
627 static void
|
|
628 tty_hide_cursor ()
|
|
629 {
|
|
630 OUTPUT_IF (TS_cursor_invisible);
|
|
631 }
|
|
632
|
|
633
|
|
634 /* Ensure that cursor is visible. */
|
|
635
|
|
636 static void
|
|
637 tty_show_cursor ()
|
|
638 {
|
|
639 OUTPUT_IF (TS_cursor_normal);
|
|
640 OUTPUT_IF (TS_cursor_visible);
|
|
641 }
|
|
642
|
|
643
|
253
|
644 /* Set standout mode to the state it should be in for
|
|
645 empty space inside windows. What this is,
|
|
646 depends on the user option inverse-video. */
|
|
647
|
21514
|
648 void
|
253
|
649 background_highlight ()
|
|
650 {
|
|
651 if (TN_standout_width >= 0)
|
|
652 return;
|
|
653 if (inverse_video)
|
|
654 turn_on_highlight ();
|
|
655 else
|
|
656 turn_off_highlight ();
|
|
657 }
|
|
658
|
|
659 /* Set standout mode to the mode specified for the text to be output. */
|
|
660
|
21514
|
661 static void
|
253
|
662 highlight_if_desired ()
|
|
663 {
|
|
664 if (TN_standout_width >= 0)
|
|
665 return;
|
|
666 if (!inverse_video == !standout_requested)
|
|
667 turn_off_highlight ();
|
|
668 else
|
|
669 turn_on_highlight ();
|
|
670 }
|
|
671
|
|
672 /* Handle standout mode for terminals in which TN_standout_width >= 0.
|
|
673 On these terminals, standout is controlled by markers that
|
765
|
674 live inside the terminal's memory. TN_standout_width is the width
|
253
|
675 that the marker occupies in memory. Standout runs from the marker
|
|
676 to the end of the line on some terminals, or to the next
|
|
677 turn-off-standout marker (TS_end_standout_mode) string
|
|
678 on other terminals. */
|
|
679
|
|
680 /* Write a standout marker or end-standout marker at the front of the line
|
|
681 at vertical position vpos. */
|
|
682
|
21514
|
683 void
|
253
|
684 write_standout_marker (flag, vpos)
|
|
685 int flag, vpos;
|
|
686 {
|
|
687 if (flag || (TS_end_standout_mode && !TF_teleray && !se_is_so
|
|
688 && !(TF_xs && TN_standout_width == 0)))
|
|
689 {
|
|
690 cmgoto (vpos, 0);
|
|
691 cmplus (TN_standout_width);
|
|
692 OUTPUT (flag ? TS_standout_mode : TS_end_standout_mode);
|
|
693 chars_wasted[curY] = TN_standout_width | 0100;
|
|
694 }
|
|
695 }
|
|
696
|
|
697 /* External interface to control of standout mode.
|
|
698 Call this when about to modify line at position VPOS
|
|
699 and not change whether it is highlighted. */
|
|
700
|
21514
|
701 void
|
253
|
702 reassert_line_highlight (highlight, vpos)
|
|
703 int highlight;
|
|
704 int vpos;
|
|
705 {
|
25675
|
706 struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame);
|
|
707 if (! FRAME_TERMCAP_P (f))
|
253
|
708 {
|
|
709 (*reassert_line_highlight_hook) (highlight, vpos);
|
|
710 return;
|
|
711 }
|
|
712 if (TN_standout_width < 0)
|
|
713 /* Handle terminals where standout takes affect at output time */
|
|
714 standout_requested = highlight;
|
25002
|
715 else if (chars_wasted && chars_wasted[vpos] == 0)
|
253
|
716 /* For terminals with standout markers, write one on this line
|
|
717 if there isn't one already. */
|
33006
|
718 write_standout_marker (inverse_video ? !highlight : highlight, vpos);
|
253
|
719 }
|
|
720
|
|
721 /* Call this when about to modify line at position VPOS
|
|
722 and change whether it is highlighted. */
|
|
723
|
21514
|
724 void
|
25002
|
725 change_line_highlight (new_highlight, vpos, y, first_unused_hpos)
|
|
726 int new_highlight, vpos, y, first_unused_hpos;
|
253
|
727 {
|
|
728 standout_requested = new_highlight;
|
969
|
729 if (! FRAME_TERMCAP_P (updating_frame))
|
253
|
730 {
|
25002
|
731 (*change_line_highlight_hook) (new_highlight, vpos, y, first_unused_hpos);
|
253
|
732 return;
|
|
733 }
|
|
734
|
|
735 cursor_to (vpos, 0);
|
|
736
|
|
737 if (TN_standout_width < 0)
|
|
738 background_highlight ();
|
|
739 /* If line starts with a marker, delete the marker */
|
|
740 else if (TS_clr_line && chars_wasted[curY])
|
|
741 {
|
|
742 turn_off_insert ();
|
|
743 /* On Teleray, make sure to erase the SO marker. */
|
|
744 if (TF_teleray)
|
|
745 {
|
25675
|
746 cmgoto (curY - 1, FRAME_WIDTH (XFRAME (selected_frame)) - 4);
|
253
|
747 OUTPUT ("\033S");
|
|
748 curY++; /* ESC S moves to next line where the TS_standout_mode was */
|
|
749 curX = 0;
|
|
750 }
|
|
751 else
|
|
752 cmgoto (curY, 0); /* reposition to kill standout marker */
|
|
753 }
|
|
754 clear_end_of_line_raw (first_unused_hpos);
|
|
755 reassert_line_highlight (new_highlight, curY);
|
|
756 }
|
|
757
|
|
758
|
25002
|
759 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
|
|
760 frame-relative coordinates. */
|
253
|
761
|
21514
|
762 void
|
25002
|
763 cursor_to (vpos, hpos)
|
|
764 int vpos, hpos;
|
253
|
765 {
|
25675
|
766 struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame);
|
|
767
|
|
768 if (! FRAME_TERMCAP_P (f) && cursor_to_hook)
|
253
|
769 {
|
25002
|
770 (*cursor_to_hook) (vpos, hpos);
|
253
|
771 return;
|
|
772 }
|
|
773
|
12071
|
774 /* Detect the case where we are called from reset_sys_modes
|
|
775 and the costs have never been calculated. Do nothing. */
|
|
776 if (chars_wasted == 0)
|
|
777 return;
|
|
778
|
25002
|
779 hpos += chars_wasted[vpos] & 077;
|
|
780 if (curY == vpos && curX == hpos)
|
253
|
781 return;
|
|
782 if (!TF_standout_motion)
|
|
783 background_highlight ();
|
|
784 if (!TF_insmode_motion)
|
|
785 turn_off_insert ();
|
25002
|
786 cmgoto (vpos, hpos);
|
253
|
787 }
|
|
788
|
|
789 /* Similar but don't take any account of the wasted characters. */
|
|
790
|
21514
|
791 void
|
253
|
792 raw_cursor_to (row, col)
|
621
|
793 int row, col;
|
253
|
794 {
|
25675
|
795 struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame);
|
|
796 if (! FRAME_TERMCAP_P (f))
|
253
|
797 {
|
|
798 (*raw_cursor_to_hook) (row, col);
|
|
799 return;
|
|
800 }
|
|
801 if (curY == row && curX == col)
|
|
802 return;
|
|
803 if (!TF_standout_motion)
|
|
804 background_highlight ();
|
|
805 if (!TF_insmode_motion)
|
|
806 turn_off_insert ();
|
|
807 cmgoto (row, col);
|
|
808 }
|
|
809
|
|
810 /* Erase operations */
|
|
811
|
765
|
812 /* clear from cursor to end of frame */
|
21514
|
813 void
|
253
|
814 clear_to_end ()
|
|
815 {
|
|
816 register int i;
|
|
817
|
8806
|
818 if (clear_to_end_hook && ! FRAME_TERMCAP_P (updating_frame))
|
253
|
819 {
|
|
820 (*clear_to_end_hook) ();
|
|
821 return;
|
|
822 }
|
|
823 if (TS_clr_to_bottom)
|
|
824 {
|
|
825 background_highlight ();
|
|
826 OUTPUT (TS_clr_to_bottom);
|
25675
|
827 bzero (chars_wasted + curY,
|
|
828 FRAME_HEIGHT (XFRAME (selected_frame)) - curY);
|
253
|
829 }
|
|
830 else
|
|
831 {
|
25675
|
832 for (i = curY; i < FRAME_HEIGHT (XFRAME (selected_frame)); i++)
|
253
|
833 {
|
|
834 cursor_to (i, 0);
|
25675
|
835 clear_end_of_line_raw (FRAME_WIDTH (XFRAME (selected_frame)));
|
253
|
836 }
|
|
837 }
|
|
838 }
|
|
839
|
765
|
840 /* Clear entire frame */
|
253
|
841
|
21514
|
842 void
|
765
|
843 clear_frame ()
|
253
|
844 {
|
25675
|
845 struct frame *sf = XFRAME (selected_frame);
|
|
846
|
765
|
847 if (clear_frame_hook
|
25675
|
848 && ! FRAME_TERMCAP_P ((updating_frame ? updating_frame : sf)))
|
253
|
849 {
|
765
|
850 (*clear_frame_hook) ();
|
253
|
851 return;
|
|
852 }
|
765
|
853 if (TS_clr_frame)
|
253
|
854 {
|
|
855 background_highlight ();
|
765
|
856 OUTPUT (TS_clr_frame);
|
25675
|
857 bzero (chars_wasted, FRAME_HEIGHT (sf));
|
253
|
858 cmat (0, 0);
|
|
859 }
|
|
860 else
|
|
861 {
|
|
862 cursor_to (0, 0);
|
|
863 clear_to_end ();
|
|
864 }
|
|
865 }
|
|
866
|
|
867 /* Clear to end of line, but do not clear any standout marker.
|
|
868 Assumes that the cursor is positioned at a character of real text,
|
|
869 which implies it cannot be before a standout marker
|
|
870 unless the marker has zero width.
|
|
871
|
|
872 Note that the cursor may be moved. */
|
|
873
|
21514
|
874 void
|
253
|
875 clear_end_of_line (first_unused_hpos)
|
|
876 int first_unused_hpos;
|
|
877 {
|
25675
|
878 if (FRAME_TERMCAP_P (XFRAME (selected_frame))
|
12071
|
879 && chars_wasted != 0
|
253
|
880 && TN_standout_width == 0 && curX == 0 && chars_wasted[curY] != 0)
|
25002
|
881 write_glyphs (&space_glyph, 1);
|
253
|
882 clear_end_of_line_raw (first_unused_hpos);
|
|
883 }
|
|
884
|
|
885 /* Clear from cursor to end of line.
|
|
886 Assume that the line is already clear starting at column first_unused_hpos.
|
|
887 If the cursor is at a standout marker, erase the marker.
|
|
888
|
|
889 Note that the cursor may be moved, on terminals lacking a `ce' string. */
|
|
890
|
21514
|
891 void
|
253
|
892 clear_end_of_line_raw (first_unused_hpos)
|
|
893 int first_unused_hpos;
|
|
894 {
|
|
895 register int i;
|
|
896
|
|
897 if (clear_end_of_line_hook
|
969
|
898 && ! FRAME_TERMCAP_P ((updating_frame
|
765
|
899 ? updating_frame
|
25675
|
900 : XFRAME (selected_frame))))
|
253
|
901 {
|
|
902 (*clear_end_of_line_hook) (first_unused_hpos);
|
|
903 return;
|
|
904 }
|
|
905
|
12071
|
906 /* Detect the case where we are called from reset_sys_modes
|
|
907 and the costs have never been calculated. Do nothing. */
|
|
908 if (chars_wasted == 0)
|
|
909 return;
|
|
910
|
253
|
911 first_unused_hpos += chars_wasted[curY] & 077;
|
|
912 if (curX >= first_unused_hpos)
|
|
913 return;
|
|
914 /* Notice if we are erasing a magic cookie */
|
|
915 if (curX == 0)
|
|
916 chars_wasted[curY] = 0;
|
|
917 background_highlight ();
|
|
918 if (TS_clr_line)
|
|
919 {
|
|
920 OUTPUT1 (TS_clr_line);
|
|
921 }
|
|
922 else
|
|
923 { /* have to do it the hard way */
|
25675
|
924 struct frame *sf = XFRAME (selected_frame);
|
253
|
925 turn_off_insert ();
|
|
926
|
25002
|
927 /* Do not write in last row last col with Auto-wrap on. */
|
25675
|
928 if (AutoWrap && curY == FRAME_HEIGHT (sf) - 1
|
|
929 && first_unused_hpos == FRAME_WIDTH (sf))
|
253
|
930 first_unused_hpos--;
|
|
931
|
|
932 for (i = curX; i < first_unused_hpos; i++)
|
|
933 {
|
|
934 if (termscript)
|
|
935 fputc (' ', termscript);
|
|
936 putchar (' ');
|
|
937 }
|
|
938 cmplus (first_unused_hpos - curX);
|
|
939 }
|
|
940 }
|
|
941
|
17046
|
942 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
|
|
943 store them at DST. Do not write more than DST_LEN bytes. That may
|
|
944 require stopping before all SRC_LEN input glyphs have been
|
|
945 converted.
|
|
946
|
|
947 We store the number of glyphs actually converted in *CONSUMED. The
|
|
948 return value is the number of bytes store in DST. */
|
|
949
|
|
950 int
|
|
951 encode_terminal_code (src, dst, src_len, dst_len, consumed)
|
25002
|
952 struct glyph *src;
|
17046
|
953 int src_len;
|
|
954 unsigned char *dst;
|
|
955 int dst_len, *consumed;
|
|
956 {
|
25002
|
957 struct glyph *src_start = src, *src_end = src + src_len;
|
17046
|
958 unsigned char *dst_start = dst, *dst_end = dst + dst_len;
|
17180
|
959 register GLYPH g;
|
26871
|
960 unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *buf;
|
20711
|
961 int len;
|
17046
|
962 register int tlen = GLYPH_TABLE_LENGTH;
|
|
963 register Lisp_Object *tbase = GLYPH_TABLE_BASE;
|
24263
|
964 int result;
|
20711
|
965 struct coding_system *coding;
|
|
966
|
29448
|
967 /* If terminal_coding does any conversion, use it, otherwise use
|
|
968 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
|
|
969 because it always return 1 if the member src_multibyte is 1. */
|
|
970 coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
|
20711
|
971 ? &terminal_coding
|
|
972 : &safe_terminal_coding);
|
17046
|
973
|
|
974 while (src < src_end)
|
|
975 {
|
|
976 /* We must skip glyphs to be padded for a wide character. */
|
25002
|
977 if (! CHAR_GLYPH_PADDING_P (*src))
|
17046
|
978 {
|
26999
|
979 g = GLYPH_FROM_CHAR_GLYPH (src[0]);
|
|
980
|
|
981 if (g < 0 || g >= tlen)
|
17046
|
982 {
|
26999
|
983 /* This glyph doesn't has an entry in Vglyph_table. */
|
|
984 if (! CHAR_VALID_P (src->u.ch, 0))
|
|
985 {
|
|
986 len = 1;
|
|
987 buf = " ";
|
29097
|
988 coding->src_multibyte = 0;
|
26999
|
989 }
|
|
990 else
|
|
991 {
|
|
992 len = CHAR_STRING (src->u.ch, workbuf);
|
|
993 buf = workbuf;
|
29097
|
994 coding->src_multibyte = 1;
|
26999
|
995 }
|
26871
|
996 }
|
17046
|
997 else
|
19035
|
998 {
|
26999
|
999 /* This glyph has an entry in Vglyph_table,
|
|
1000 so process any alias before testing for simpleness. */
|
|
1001 GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
|
|
1002
|
|
1003 if (GLYPH_SIMPLE_P (tbase, tlen, g))
|
|
1004 {
|
27128
|
1005 /* We set the multi-byte form of a character in G
|
|
1006 (that should be an ASCII character) at
|
|
1007 WORKBUF. */
|
|
1008 workbuf[0] = FAST_GLYPH_CHAR (g);
|
|
1009 len = 1;
|
26999
|
1010 buf = workbuf;
|
29097
|
1011 coding->src_multibyte = 0;
|
26999
|
1012 }
|
|
1013 else
|
|
1014 {
|
|
1015 /* We have a string in Vglyph_table. */
|
|
1016 len = GLYPH_LENGTH (tbase, g);
|
|
1017 buf = GLYPH_STRING (tbase, g);
|
29097
|
1018 coding->src_multibyte = STRING_MULTIBYTE (tbase[g]);
|
26999
|
1019 }
|
19035
|
1020 }
|
17046
|
1021
|
24263
|
1022 result = encode_coding (coding, buf, dst, len, dst_end - dst);
|
23338
|
1023 len -= coding->consumed;
|
20711
|
1024 dst += coding->produced;
|
24263
|
1025 if (result == CODING_FINISH_INSUFFICIENT_DST
|
|
1026 || (result == CODING_FINISH_INSUFFICIENT_SRC
|
|
1027 && len > dst_end - dst))
|
|
1028 /* The remaining output buffer is too short. We must
|
|
1029 break the loop here without increasing SRC so that the
|
|
1030 next call of this function starts from the same glyph. */
|
|
1031 break;
|
|
1032
|
23338
|
1033 if (len > 0)
|
|
1034 {
|
24263
|
1035 /* This is the case that a code of the range 0200..0237
|
|
1036 exists in buf. We must just write out such a code. */
|
|
1037 buf += coding->consumed;
|
|
1038 while (len--)
|
|
1039 *dst++ = *buf++;
|
23338
|
1040 }
|
17046
|
1041 }
|
|
1042 src++;
|
|
1043 }
|
25002
|
1044
|
17046
|
1045 *consumed = src - src_start;
|
|
1046 return (dst - dst_start);
|
|
1047 }
|
|
1048
|
253
|
1049
|
21514
|
1050 void
|
253
|
1051 write_glyphs (string, len)
|
25002
|
1052 register struct glyph *string;
|
253
|
1053 register int len;
|
|
1054 {
|
17046
|
1055 int produced, consumed;
|
25675
|
1056 struct frame *sf = XFRAME (selected_frame);
|
|
1057 struct frame *f = updating_frame ? updating_frame : sf;
|
30836
|
1058 unsigned char conversion_buffer[1024];
|
|
1059 int conversion_buffer_size = sizeof conversion_buffer;
|
253
|
1060
|
|
1061 if (write_glyphs_hook
|
25002
|
1062 && ! FRAME_TERMCAP_P (f))
|
253
|
1063 {
|
|
1064 (*write_glyphs_hook) (string, len);
|
|
1065 return;
|
|
1066 }
|
|
1067
|
|
1068 turn_off_insert ();
|
|
1069
|
25002
|
1070 /* Don't dare write in last column of bottom line, if Auto-Wrap,
|
765
|
1071 since that would scroll the whole frame on some terminals. */
|
253
|
1072
|
|
1073 if (AutoWrap
|
25675
|
1074 && curY + 1 == FRAME_HEIGHT (sf)
|
|
1075 && (curX + len - (chars_wasted[curY] & 077) == FRAME_WIDTH (sf)))
|
253
|
1076 len --;
|
17046
|
1077 if (len <= 0)
|
|
1078 return;
|
253
|
1079
|
|
1080 cmplus (len);
|
25002
|
1081
|
20711
|
1082 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
|
|
1083 the tail. */
|
|
1084 terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
|
25002
|
1085
|
17046
|
1086 while (len > 0)
|
253
|
1087 {
|
25002
|
1088 /* Identify a run of glyphs with the same face. */
|
26999
|
1089 int face_id = string->face_id;
|
25002
|
1090 int n;
|
|
1091
|
|
1092 for (n = 1; n < len; ++n)
|
26999
|
1093 if (string[n].face_id != face_id)
|
25002
|
1094 break;
|
|
1095
|
|
1096 /* Turn appearance modes of the face of the run on. */
|
30821
|
1097 highlight_if_desired ();
|
25002
|
1098 turn_on_face (f, face_id);
|
|
1099
|
|
1100 while (n > 0)
|
253
|
1101 {
|
30836
|
1102 /* We use a fixed size (1024 bytes) of conversion buffer.
|
|
1103 Usually it is sufficient, but if not, we just repeat the
|
|
1104 loop. */
|
25002
|
1105 produced = encode_terminal_code (string, conversion_buffer,
|
|
1106 n, conversion_buffer_size,
|
|
1107 &consumed);
|
|
1108 if (produced > 0)
|
|
1109 {
|
|
1110 fwrite (conversion_buffer, 1, produced, stdout);
|
|
1111 if (ferror (stdout))
|
|
1112 clearerr (stdout);
|
|
1113 if (termscript)
|
|
1114 fwrite (conversion_buffer, 1, produced, termscript);
|
|
1115 }
|
|
1116 len -= consumed;
|
|
1117 n -= consumed;
|
|
1118 string += consumed;
|
253
|
1119 }
|
25002
|
1120
|
|
1121 /* Turn appearance modes off. */
|
|
1122 turn_off_face (f, face_id);
|
30848
|
1123 turn_off_highlight ();
|
17046
|
1124 }
|
25002
|
1125
|
17046
|
1126 /* We may have to output some codes to terminate the writing. */
|
20223
|
1127 if (CODING_REQUIRE_FLUSHING (&terminal_coding))
|
17046
|
1128 {
|
20711
|
1129 terminal_coding.mode |= CODING_MODE_LAST_BLOCK;
|
23066
|
1130 encode_coding (&terminal_coding, "", conversion_buffer,
|
20711
|
1131 0, conversion_buffer_size);
|
|
1132 if (terminal_coding.produced > 0)
|
19277
|
1133 {
|
20711
|
1134 fwrite (conversion_buffer, 1, terminal_coding.produced, stdout);
|
19277
|
1135 if (ferror (stdout))
|
|
1136 clearerr (stdout);
|
|
1137 if (termscript)
|
20711
|
1138 fwrite (conversion_buffer, 1, terminal_coding.produced,
|
|
1139 termscript);
|
19277
|
1140 }
|
253
|
1141 }
|
25002
|
1142
|
10439
|
1143 cmcheckmagic ();
|
253
|
1144 }
|
|
1145
|
|
1146 /* If start is zero, insert blanks instead of a string at start */
|
|
1147
|
21514
|
1148 void
|
253
|
1149 insert_glyphs (start, len)
|
25002
|
1150 register struct glyph *start;
|
253
|
1151 register int len;
|
|
1152 {
|
|
1153 char *buf;
|
31829
|
1154 struct glyph *glyph = NULL;
|
25675
|
1155 struct frame *f, *sf;
|
253
|
1156
|
17046
|
1157 if (len <= 0)
|
|
1158 return;
|
|
1159
|
25002
|
1160 if (insert_glyphs_hook)
|
253
|
1161 {
|
|
1162 (*insert_glyphs_hook) (start, len);
|
|
1163 return;
|
|
1164 }
|
25002
|
1165
|
25675
|
1166 sf = XFRAME (selected_frame);
|
|
1167 f = updating_frame ? updating_frame : sf;
|
253
|
1168
|
|
1169 if (TS_ins_multi_chars)
|
|
1170 {
|
|
1171 buf = tparam (TS_ins_multi_chars, 0, 0, len);
|
|
1172 OUTPUT1 (buf);
|
2439
|
1173 xfree (buf);
|
253
|
1174 if (start)
|
|
1175 write_glyphs (start, len);
|
|
1176 return;
|
|
1177 }
|
|
1178
|
|
1179 turn_on_insert ();
|
|
1180 cmplus (len);
|
20711
|
1181 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
|
|
1182 terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
|
17191
|
1183 while (len-- > 0)
|
253
|
1184 {
|
17046
|
1185 int produced, consumed;
|
30836
|
1186 unsigned char conversion_buffer[1024];
|
|
1187 int conversion_buffer_size = sizeof conversion_buffer;
|
17046
|
1188
|
253
|
1189 OUTPUT1_IF (TS_ins_char);
|
|
1190 if (!start)
|
26999
|
1191 {
|
|
1192 conversion_buffer[0] = SPACEGLYPH;
|
|
1193 produced = 1;
|
|
1194 }
|
253
|
1195 else
|
17046
|
1196 {
|
30848
|
1197 highlight_if_desired ();
|
26999
|
1198 turn_on_face (f, start->face_id);
|
27085
|
1199 glyph = start;
|
25002
|
1200 ++start;
|
17046
|
1201 /* We must open sufficient space for a character which
|
|
1202 occupies more than one column. */
|
25002
|
1203 while (len && CHAR_GLYPH_PADDING_P (*start))
|
17046
|
1204 {
|
|
1205 OUTPUT1_IF (TS_ins_char);
|
|
1206 start++, len--;
|
|
1207 }
|
26999
|
1208
|
|
1209 if (len <= 0)
|
|
1210 /* This is the last glyph. */
|
|
1211 terminal_coding.mode |= CODING_MODE_LAST_BLOCK;
|
|
1212
|
30836
|
1213 /* The size of conversion buffer (1024 bytes) is surely
|
|
1214 sufficient for just one glyph. */
|
27085
|
1215 produced = encode_terminal_code (glyph, conversion_buffer, 1,
|
26999
|
1216 conversion_buffer_size, &consumed);
|
17046
|
1217 }
|
253
|
1218
|
17046
|
1219 if (produced > 0)
|
253
|
1220 {
|
17046
|
1221 fwrite (conversion_buffer, 1, produced, stdout);
|
253
|
1222 if (ferror (stdout))
|
|
1223 clearerr (stdout);
|
|
1224 if (termscript)
|
17046
|
1225 fwrite (conversion_buffer, 1, produced, termscript);
|
253
|
1226 }
|
|
1227
|
10439
|
1228 OUTPUT1_IF (TS_pad_inserted_char);
|
26999
|
1229 if (start)
|
30848
|
1230 {
|
|
1231 turn_off_face (f, glyph->face_id);
|
|
1232 turn_off_highlight ();
|
|
1233 }
|
10439
|
1234 }
|
25002
|
1235
|
10439
|
1236 cmcheckmagic ();
|
253
|
1237 }
|
|
1238
|
21514
|
1239 void
|
253
|
1240 delete_glyphs (n)
|
|
1241 register int n;
|
|
1242 {
|
|
1243 char *buf;
|
|
1244 register int i;
|
|
1245
|
969
|
1246 if (delete_glyphs_hook && ! FRAME_TERMCAP_P (updating_frame))
|
253
|
1247 {
|
|
1248 (*delete_glyphs_hook) (n);
|
|
1249 return;
|
|
1250 }
|
|
1251
|
|
1252 if (delete_in_insert_mode)
|
|
1253 {
|
|
1254 turn_on_insert ();
|
|
1255 }
|
|
1256 else
|
|
1257 {
|
|
1258 turn_off_insert ();
|
|
1259 OUTPUT_IF (TS_delete_mode);
|
|
1260 }
|
|
1261
|
|
1262 if (TS_del_multi_chars)
|
|
1263 {
|
|
1264 buf = tparam (TS_del_multi_chars, 0, 0, n);
|
|
1265 OUTPUT1 (buf);
|
2439
|
1266 xfree (buf);
|
253
|
1267 }
|
|
1268 else
|
|
1269 for (i = 0; i < n; i++)
|
|
1270 OUTPUT1 (TS_del_char);
|
|
1271 if (!delete_in_insert_mode)
|
|
1272 OUTPUT_IF (TS_end_delete_mode);
|
|
1273 }
|
|
1274
|
|
1275 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
|
|
1276
|
21514
|
1277 void
|
253
|
1278 ins_del_lines (vpos, n)
|
|
1279 int vpos, n;
|
|
1280 {
|
|
1281 char *multi = n > 0 ? TS_ins_multi_lines : TS_del_multi_lines;
|
|
1282 char *single = n > 0 ? TS_ins_line : TS_del_line;
|
|
1283 char *scroll = n > 0 ? TS_rev_scroll : TS_fwd_scroll;
|
25675
|
1284 struct frame *sf;
|
253
|
1285
|
|
1286 register int i = n > 0 ? n : -n;
|
|
1287 register char *buf;
|
|
1288
|
969
|
1289 if (ins_del_lines_hook && ! FRAME_TERMCAP_P (updating_frame))
|
253
|
1290 {
|
|
1291 (*ins_del_lines_hook) (vpos, n);
|
|
1292 return;
|
|
1293 }
|
|
1294
|
25675
|
1295 sf = XFRAME (selected_frame);
|
|
1296
|
253
|
1297 /* If the lines below the insertion are being pushed
|
|
1298 into the end of the window, this is the same as clearing;
|
|
1299 and we know the lines are already clear, since the matching
|
|
1300 deletion has already been done. So can ignore this. */
|
|
1301 /* If the lines below the deletion are blank lines coming
|
|
1302 out of the end of the window, don't bother,
|
|
1303 as there will be a matching inslines later that will flush them. */
|
|
1304 if (scroll_region_ok && vpos + i >= specified_window)
|
|
1305 return;
|
25675
|
1306 if (!memory_below_frame && vpos + i >= FRAME_HEIGHT (sf))
|
253
|
1307 return;
|
|
1308
|
|
1309 if (multi)
|
|
1310 {
|
|
1311 raw_cursor_to (vpos, 0);
|
|
1312 background_highlight ();
|
|
1313 buf = tparam (multi, 0, 0, i);
|
|
1314 OUTPUT (buf);
|
2439
|
1315 xfree (buf);
|
253
|
1316 }
|
|
1317 else if (single)
|
|
1318 {
|
|
1319 raw_cursor_to (vpos, 0);
|
|
1320 background_highlight ();
|
|
1321 while (--i >= 0)
|
|
1322 OUTPUT (single);
|
|
1323 if (TF_teleray)
|
|
1324 curX = 0;
|
|
1325 }
|
|
1326 else
|
|
1327 {
|
|
1328 set_scroll_region (vpos, specified_window);
|
|
1329 if (n < 0)
|
|
1330 raw_cursor_to (specified_window - 1, 0);
|
|
1331 else
|
|
1332 raw_cursor_to (vpos, 0);
|
|
1333 background_highlight ();
|
|
1334 while (--i >= 0)
|
|
1335 OUTPUTL (scroll, specified_window - vpos);
|
|
1336 set_scroll_region (0, specified_window);
|
|
1337 }
|
|
1338
|
|
1339 if (TN_standout_width >= 0)
|
|
1340 {
|
21514
|
1341 register int lower_limit
|
253
|
1342 = (scroll_region_ok
|
|
1343 ? specified_window
|
25675
|
1344 : FRAME_HEIGHT (sf));
|
253
|
1345
|
|
1346 if (n < 0)
|
|
1347 {
|
|
1348 bcopy (&chars_wasted[vpos - n], &chars_wasted[vpos],
|
|
1349 lower_limit - vpos + n);
|
|
1350 bzero (&chars_wasted[lower_limit + n], - n);
|
|
1351 }
|
|
1352 else
|
|
1353 {
|
|
1354 bcopy (&chars_wasted[vpos], ©buf[vpos], lower_limit - vpos - n);
|
|
1355 bcopy (©buf[vpos], &chars_wasted[vpos + n],
|
|
1356 lower_limit - vpos - n);
|
|
1357 bzero (&chars_wasted[vpos], n);
|
|
1358 }
|
|
1359 }
|
765
|
1360 if (!scroll_region_ok && memory_below_frame && n < 0)
|
253
|
1361 {
|
25675
|
1362 cursor_to (FRAME_HEIGHT (sf) + n, 0);
|
253
|
1363 clear_to_end ();
|
|
1364 }
|
|
1365 }
|
|
1366
|
|
1367 /* Compute cost of sending "str", in characters,
|
|
1368 not counting any line-dependent padding. */
|
|
1369
|
|
1370 int
|
|
1371 string_cost (str)
|
|
1372 char *str;
|
|
1373 {
|
|
1374 cost = 0;
|
|
1375 if (str)
|
|
1376 tputs (str, 0, evalcost);
|
|
1377 return cost;
|
|
1378 }
|
|
1379
|
|
1380 /* Compute cost of sending "str", in characters,
|
|
1381 counting any line-dependent padding at one line. */
|
|
1382
|
|
1383 static int
|
|
1384 string_cost_one_line (str)
|
|
1385 char *str;
|
|
1386 {
|
|
1387 cost = 0;
|
|
1388 if (str)
|
|
1389 tputs (str, 1, evalcost);
|
|
1390 return cost;
|
|
1391 }
|
|
1392
|
|
1393 /* Compute per line amount of line-dependent padding,
|
|
1394 in tenths of characters. */
|
|
1395
|
|
1396 int
|
|
1397 per_line_cost (str)
|
|
1398 register char *str;
|
|
1399 {
|
|
1400 cost = 0;
|
|
1401 if (str)
|
|
1402 tputs (str, 0, evalcost);
|
|
1403 cost = - cost;
|
|
1404 if (str)
|
|
1405 tputs (str, 10, evalcost);
|
|
1406 return cost;
|
|
1407 }
|
|
1408
|
|
1409 #ifndef old
|
|
1410 /* char_ins_del_cost[n] is cost of inserting N characters.
|
10771
|
1411 char_ins_del_cost[-n] is cost of deleting N characters.
|
|
1412 The length of this vector is based on max_frame_width. */
|
253
|
1413
|
|
1414 int *char_ins_del_vector;
|
|
1415
|
765
|
1416 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH ((f))])
|
253
|
1417 #endif
|
|
1418
|
|
1419 /* ARGSUSED */
|
|
1420 static void
|
765
|
1421 calculate_ins_del_char_costs (frame)
|
|
1422 FRAME_PTR frame;
|
253
|
1423 {
|
|
1424 int ins_startup_cost, del_startup_cost;
|
|
1425 int ins_cost_per_char, del_cost_per_char;
|
|
1426 register int i;
|
|
1427 register int *p;
|
|
1428
|
|
1429 if (TS_ins_multi_chars)
|
|
1430 {
|
|
1431 ins_cost_per_char = 0;
|
|
1432 ins_startup_cost = string_cost_one_line (TS_ins_multi_chars);
|
|
1433 }
|
|
1434 else if (TS_ins_char || TS_pad_inserted_char
|
|
1435 || (TS_insert_mode && TS_end_insert_mode))
|
|
1436 {
|
|
1437 ins_startup_cost = (30 * (string_cost (TS_insert_mode)
|
|
1438 + string_cost (TS_end_insert_mode))) / 100;
|
|
1439 ins_cost_per_char = (string_cost_one_line (TS_ins_char)
|
|
1440 + string_cost_one_line (TS_pad_inserted_char));
|
|
1441 }
|
|
1442 else
|
|
1443 {
|
|
1444 ins_startup_cost = 9999;
|
|
1445 ins_cost_per_char = 0;
|
|
1446 }
|
|
1447
|
|
1448 if (TS_del_multi_chars)
|
|
1449 {
|
|
1450 del_cost_per_char = 0;
|
|
1451 del_startup_cost = string_cost_one_line (TS_del_multi_chars);
|
|
1452 }
|
|
1453 else if (TS_del_char)
|
|
1454 {
|
|
1455 del_startup_cost = (string_cost (TS_delete_mode)
|
|
1456 + string_cost (TS_end_delete_mode));
|
|
1457 if (delete_in_insert_mode)
|
|
1458 del_startup_cost /= 2;
|
|
1459 del_cost_per_char = string_cost_one_line (TS_del_char);
|
|
1460 }
|
|
1461 else
|
|
1462 {
|
|
1463 del_startup_cost = 9999;
|
|
1464 del_cost_per_char = 0;
|
|
1465 }
|
|
1466
|
|
1467 /* Delete costs are at negative offsets */
|
765
|
1468 p = &char_ins_del_cost (frame)[0];
|
14980
|
1469 for (i = FRAME_WIDTH (frame); --i >= 0;)
|
253
|
1470 *--p = (del_startup_cost += del_cost_per_char);
|
|
1471
|
|
1472 /* Doing nothing is free */
|
765
|
1473 p = &char_ins_del_cost (frame)[0];
|
253
|
1474 *p++ = 0;
|
|
1475
|
|
1476 /* Insert costs are at positive offsets */
|
765
|
1477 for (i = FRAME_WIDTH (frame); --i >= 0;)
|
253
|
1478 *p++ = (ins_startup_cost += ins_cost_per_char);
|
|
1479 }
|
|
1480
|
21514
|
1481 void
|
765
|
1482 calculate_costs (frame)
|
|
1483 FRAME_PTR frame;
|
253
|
1484 {
|
10121
|
1485 register char *f = (TS_set_scroll_region
|
|
1486 ? TS_set_scroll_region
|
|
1487 : TS_set_scroll_region_1);
|
253
|
1488
|
10121
|
1489 FRAME_COST_BAUD_RATE (frame) = baud_rate;
|
253
|
1490
|
10261
|
1491 scroll_region_cost = string_cost (f);
|
253
|
1492
|
|
1493 /* These variables are only used for terminal stuff. They are allocated
|
765
|
1494 once for the terminal frame of X-windows emacs, but not used afterwards.
|
253
|
1495
|
|
1496 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
|
|
1497 X turns off char_ins_del_ok.
|
|
1498
|
|
1499 chars_wasted and copybuf are only used here in term.c in cases where
|
|
1500 the term hook isn't called. */
|
|
1501
|
10771
|
1502 max_frame_height = max (max_frame_height, FRAME_HEIGHT (frame));
|
|
1503 max_frame_width = max (max_frame_width, FRAME_WIDTH (frame));
|
|
1504
|
253
|
1505 if (chars_wasted != 0)
|
10771
|
1506 chars_wasted = (char *) xrealloc (chars_wasted, max_frame_height);
|
253
|
1507 else
|
10771
|
1508 chars_wasted = (char *) xmalloc (max_frame_height);
|
253
|
1509
|
|
1510 if (copybuf != 0)
|
10771
|
1511 copybuf = (char *) xrealloc (copybuf, max_frame_height);
|
253
|
1512 else
|
10771
|
1513 copybuf = (char *) xmalloc (max_frame_height);
|
253
|
1514
|
|
1515 if (char_ins_del_vector != 0)
|
|
1516 char_ins_del_vector
|
|
1517 = (int *) xrealloc (char_ins_del_vector,
|
|
1518 (sizeof (int)
|
10771
|
1519 + 2 * max_frame_width * sizeof (int)));
|
253
|
1520 else
|
|
1521 char_ins_del_vector
|
|
1522 = (int *) xmalloc (sizeof (int)
|
10771
|
1523 + 2 * max_frame_width * sizeof (int));
|
253
|
1524
|
10771
|
1525 bzero (chars_wasted, max_frame_height);
|
|
1526 bzero (copybuf, max_frame_height);
|
253
|
1527 bzero (char_ins_del_vector, (sizeof (int)
|
10771
|
1528 + 2 * max_frame_width * sizeof (int)));
|
253
|
1529
|
765
|
1530 if (f && (!TS_ins_line && !TS_del_line))
|
|
1531 do_line_insertion_deletion_costs (frame,
|
253
|
1532 TS_rev_scroll, TS_ins_multi_lines,
|
|
1533 TS_fwd_scroll, TS_del_multi_lines,
|
765
|
1534 f, f, 1);
|
253
|
1535 else
|
765
|
1536 do_line_insertion_deletion_costs (frame,
|
253
|
1537 TS_ins_line, TS_ins_multi_lines,
|
|
1538 TS_del_line, TS_del_multi_lines,
|
|
1539 0, 0, 1);
|
|
1540
|
765
|
1541 calculate_ins_del_char_costs (frame);
|
253
|
1542
|
|
1543 /* Don't use TS_repeat if its padding is worse than sending the chars */
|
|
1544 if (TS_repeat && per_line_cost (TS_repeat) * baud_rate < 9000)
|
|
1545 RPov = string_cost (TS_repeat);
|
|
1546 else
|
765
|
1547 RPov = FRAME_WIDTH (frame) * 2;
|
253
|
1548
|
|
1549 cmcostinit (); /* set up cursor motion costs */
|
|
1550 }
|
|
1551
|
1015
|
1552 struct fkey_table {
|
|
1553 char *cap, *name;
|
|
1554 };
|
|
1555
|
2137
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1556 /* Termcap capability names that correspond directly to X keysyms.
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1557 Some of these (marked "terminfo") aren't supplied by old-style
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1558 (Berkeley) termcap entries. They're listed in X keysym order;
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1559 except we put the keypad keys first, so that if they clash with
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1560 other keys (as on the IBM PC keyboard) they get overridden.
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1561 */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1562
|
25002
|
1563 static struct fkey_table keys[] =
|
|
1564 {
|
2137
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1565 "kh", "home", /* termcap */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1566 "kl", "left", /* termcap */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1567 "ku", "up", /* termcap */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1568 "kr", "right", /* termcap */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1569 "kd", "down", /* termcap */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1570 "%8", "prior", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1571 "%5", "next", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1572 "@7", "end", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1573 "@1", "begin", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1574 "*6", "select", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1575 "%9", "print", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1576 "@4", "execute", /* terminfo --- actually the `command' key */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1577 /*
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1578 * "insert" --- see below
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1579 */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1580 "&8", "undo", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1581 "%0", "redo", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1582 "%7", "menu", /* terminfo --- actually the `options' key */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1583 "@0", "find", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1584 "@2", "cancel", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1585 "%1", "help", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1586 /*
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1587 * "break" goes here, but can't be reliably intercepted with termcap
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1588 */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1589 "&4", "reset", /* terminfo --- actually `restart' */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1590 /*
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1591 * "system" and "user" --- no termcaps
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1592 */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1593 "kE", "clearline", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1594 "kA", "insertline", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1595 "kL", "deleteline", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1596 "kI", "insertchar", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1597 "kD", "deletechar", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1598 "kB", "backtab", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1599 /*
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1600 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1601 */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1602 "@8", "kp-enter", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1603 /*
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1604 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1605 * "kp-multiply", "kp-add", "kp-separator",
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1606 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1607 * --- no termcaps for any of these.
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1608 */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1609 "K4", "kp-1", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1610 /*
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1611 * "kp-2" --- no termcap
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1612 */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1613 "K5", "kp-3", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1614 /*
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1615 * "kp-4" --- no termcap
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1616 */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1617 "K2", "kp-5", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1618 /*
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1619 * "kp-6" --- no termcap
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1620 */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1621 "K1", "kp-7", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1622 /*
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1623 * "kp-8" --- no termcap
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1624 */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1625 "K3", "kp-9", /* terminfo */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1626 /*
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1627 * "kp-equal" --- no termcap
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1628 */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1629 "k1", "f1",
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1630 "k2", "f2",
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1631 "k3", "f3",
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1632 "k4", "f4",
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1633 "k5", "f5",
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1634 "k6", "f6",
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1635 "k7", "f7",
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1636 "k8", "f8",
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1637 "k9", "f9",
|
1015
|
1638 };
|
|
1639
|
6248
|
1640 static char **term_get_fkeys_arg;
|
|
1641 static Lisp_Object term_get_fkeys_1 ();
|
4543
929e4c850e76
(term_get_fkeys_define_1, term_get_fkeys_define): New functions.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1642
|
2137
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1643 /* Find the escape codes sent by the function keys for Vfunction_key_map.
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1644 This function scans the termcap function key sequence entries, and
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1645 adds entries to Vfunction_key_map for each function key it finds. */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1646
|
533
|
1647 void
|
|
1648 term_get_fkeys (address)
|
|
1649 char **address;
|
|
1650 {
|
6248
|
1651 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
|
|
1652 errors during the call. The only errors should be from Fdefine_key
|
|
1653 when given a key sequence containing an invalid prefix key. If the
|
|
1654 termcap defines function keys which use a prefix that is already bound
|
|
1655 to a command by the default bindings, we should silently ignore that
|
|
1656 function key specification, rather than giving the user an error and
|
|
1657 refusing to run at all on such a terminal. */
|
|
1658
|
|
1659 extern Lisp_Object Fidentity ();
|
|
1660 term_get_fkeys_arg = address;
|
|
1661 internal_condition_case (term_get_fkeys_1, Qerror, Fidentity);
|
|
1662 }
|
|
1663
|
|
1664 static Lisp_Object
|
|
1665 term_get_fkeys_1 ()
|
|
1666 {
|
533
|
1667 int i;
|
|
1668
|
6250
a08cca81d0bd
(term_get_fkeys_1): Use term_get_fkeys_arg, not term_get_fkeys_address.
Roland McGrath <roland@gnu.org>
diff
changeset
|
1669 char **address = term_get_fkeys_arg;
|
6249
365e7cbd7292
(term_get_fkeys_1): New local var ADDRESS, init to term_get_fkeys_address.
Roland McGrath <roland@gnu.org>
diff
changeset
|
1670
|
3359
|
1671 /* This can happen if CANNOT_DUMP or with strange options. */
|
|
1672 if (!initialized)
|
|
1673 Vfunction_key_map = Fmake_sparse_keymap (Qnil);
|
|
1674
|
533
|
1675 for (i = 0; i < (sizeof (keys)/sizeof (keys[0])); i++)
|
|
1676 {
|
|
1677 char *sequence = tgetstr (keys[i].cap, address);
|
|
1678 if (sequence)
|
6248
|
1679 Fdefine_key (Vfunction_key_map, build_string (sequence),
|
|
1680 Fmake_vector (make_number (1),
|
|
1681 intern (keys[i].name)));
|
533
|
1682 }
|
1015
|
1683
|
|
1684 /* The uses of the "k0" capability are inconsistent; sometimes it
|
|
1685 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
|
3591
|
1686 We will attempt to politely accommodate both systems by testing for
|
1015
|
1687 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
|
|
1688 */
|
|
1689 {
|
|
1690 char *k_semi = tgetstr ("k;", address);
|
|
1691 char *k0 = tgetstr ("k0", address);
|
|
1692 char *k0_name = "f10";
|
|
1693
|
|
1694 if (k_semi)
|
|
1695 {
|
6248
|
1696 Fdefine_key (Vfunction_key_map, build_string (k_semi),
|
|
1697 Fmake_vector (make_number (1), intern ("f10")));
|
1015
|
1698 k0_name = "f0";
|
|
1699 }
|
|
1700
|
|
1701 if (k0)
|
6248
|
1702 Fdefine_key (Vfunction_key_map, build_string (k0),
|
|
1703 Fmake_vector (make_number (1), intern (k0_name)));
|
1015
|
1704 }
|
2137
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1705
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1706 /* Set up cookies for numbered function keys above f10. */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1707 {
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1708 char fcap[3], fkey[4];
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1709
|
3489
|
1710 fcap[0] = 'F'; fcap[2] = '\0';
|
2137
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1711 for (i = 11; i < 64; i++)
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1712 {
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1713 if (i <= 19)
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1714 fcap[1] = '1' + i - 11;
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1715 else if (i <= 45)
|
10481
|
1716 fcap[1] = 'A' + i - 20;
|
2137
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1717 else
|
10481
|
1718 fcap[1] = 'a' + i - 46;
|
2137
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1719
|
3489
|
1720 {
|
|
1721 char *sequence = tgetstr (fcap, address);
|
|
1722 if (sequence)
|
|
1723 {
|
4543
929e4c850e76
(term_get_fkeys_define_1, term_get_fkeys_define): New functions.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
1724 sprintf (fkey, "f%d", i);
|
6248
|
1725 Fdefine_key (Vfunction_key_map, build_string (sequence),
|
|
1726 Fmake_vector (make_number (1),
|
|
1727 intern (fkey)));
|
3489
|
1728 }
|
|
1729 }
|
2137
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1730 }
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1731 }
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1732
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1733 /*
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1734 * Various mappings to try and get a better fit.
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1735 */
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1736 {
|
3489
|
1737 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
|
|
1738 if (!tgetstr (cap1, address)) \
|
|
1739 { \
|
|
1740 char *sequence = tgetstr (cap2, address); \
|
|
1741 if (sequence) \
|
6248
|
1742 Fdefine_key (Vfunction_key_map, build_string (sequence), \
|
|
1743 Fmake_vector (make_number (1), \
|
|
1744 intern (sym))); \
|
3489
|
1745 }
|
2137
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1746
|
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1747 /* if there's no key_next keycap, map key_npage to `next' keysym */
|
2243
|
1748 CONDITIONAL_REASSIGN ("%5", "kN", "next");
|
2137
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1749 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
|
3706
|
1750 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
|
2137
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1751 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
|
2243
|
1752 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
|
19385
|
1753 /* if there's no key_end keycap, map key_ll to 'end' keysym */
|
|
1754 CONDITIONAL_REASSIGN ("@7", "kH", "end");
|
9524
|
1755
|
|
1756 /* IBM has their own non-standard dialect of terminfo.
|
|
1757 If the standard name isn't found, try the IBM name. */
|
|
1758 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
|
|
1759 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
|
|
1760 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
|
|
1761 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
|
|
1762 CONDITIONAL_REASSIGN ("@7", "kw", "end");
|
|
1763 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
|
|
1764 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
|
|
1765 CONDITIONAL_REASSIGN ("%1", "kq", "help");
|
|
1766 CONDITIONAL_REASSIGN ("*6", "kU", "select");
|
2224
|
1767 #undef CONDITIONAL_REASSIGN
|
2137
8e4d2d1e7c66
Added lots more cookies to fkey_table[], and code to do even more.
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
1768 }
|
25002
|
1769
|
|
1770 return Qnil;
|
533
|
1771 }
|
|
1772
|
|
1773
|
25002
|
1774 /***********************************************************************
|
|
1775 Character Display Information
|
|
1776 ***********************************************************************/
|
|
1777
|
|
1778 static void append_glyph P_ ((struct it *));
|
|
1779
|
|
1780
|
|
1781 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
|
|
1782 terminal frames if IT->glyph_row != NULL. IT->c is the character
|
|
1783 for which to produce glyphs; IT->face_id contains the character's
|
|
1784 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
|
|
1785 1. */
|
|
1786
|
|
1787 static void
|
|
1788 append_glyph (it)
|
|
1789 struct it *it;
|
|
1790 {
|
|
1791 struct glyph *glyph, *end;
|
|
1792 int i;
|
|
1793
|
|
1794 xassert (it->glyph_row);
|
|
1795 glyph = (it->glyph_row->glyphs[it->area]
|
|
1796 + it->glyph_row->used[it->area]);
|
|
1797 end = it->glyph_row->glyphs[1 + it->area];
|
|
1798
|
|
1799 for (i = 0;
|
|
1800 i < it->pixel_width && glyph < end;
|
|
1801 ++i)
|
|
1802 {
|
|
1803 glyph->type = CHAR_GLYPH;
|
29462
|
1804 glyph->pixel_width = 1;
|
26999
|
1805 glyph->u.ch = it->c;
|
|
1806 glyph->face_id = it->face_id;
|
|
1807 glyph->padding_p = i > 0;
|
25002
|
1808 glyph->charpos = CHARPOS (it->position);
|
|
1809 glyph->object = it->object;
|
|
1810
|
|
1811 ++it->glyph_row->used[it->area];
|
|
1812 ++glyph;
|
|
1813 }
|
|
1814 }
|
|
1815
|
|
1816
|
|
1817 /* Produce glyphs for the display element described by IT. The
|
|
1818 function fills output fields of IT with pixel information like the
|
|
1819 pixel width and height of a character, and maybe produces glyphs at
|
|
1820 the same time if IT->glyph_row is non-null. See the explanation of
|
|
1821 struct display_iterator in dispextern.h for an overview. */
|
|
1822
|
|
1823 void
|
|
1824 produce_glyphs (it)
|
|
1825 struct it *it;
|
|
1826 {
|
|
1827 /* If a hook is installed, let it do the work. */
|
|
1828 xassert (it->what == IT_CHARACTER
|
26871
|
1829 || it->what == IT_COMPOSITION
|
25002
|
1830 || it->what == IT_IMAGE
|
|
1831 || it->what == IT_STRETCH);
|
|
1832
|
26871
|
1833 /* Nothing but characters are supported on terminal frames. For a
|
|
1834 composition sequence, it->c is the first character of the
|
|
1835 sequence. */
|
|
1836 xassert (it->what == IT_CHARACTER
|
|
1837 || it->what == IT_COMPOSITION);
|
25002
|
1838
|
|
1839 if (it->c >= 040 && it->c < 0177)
|
|
1840 {
|
|
1841 it->pixel_width = it->nglyphs = 1;
|
|
1842 if (it->glyph_row)
|
|
1843 append_glyph (it);
|
|
1844 }
|
|
1845 else if (it->c == '\n')
|
|
1846 it->pixel_width = it->nglyphs = 0;
|
|
1847 else if (it->c == '\t')
|
|
1848 {
|
28685
|
1849 int absolute_x = (it->current_x
|
25002
|
1850 + it->continuation_lines_width);
|
|
1851 int next_tab_x
|
|
1852 = (((1 + absolute_x + it->tab_width - 1)
|
|
1853 / it->tab_width)
|
|
1854 * it->tab_width);
|
|
1855 int nspaces;
|
|
1856
|
|
1857 /* If part of the TAB has been displayed on the previous line
|
|
1858 which is continued now, continuation_lines_width will have
|
|
1859 been incremented already by the part that fitted on the
|
|
1860 continued line. So, we will get the right number of spaces
|
|
1861 here. */
|
|
1862 nspaces = next_tab_x - absolute_x;
|
|
1863
|
|
1864 if (it->glyph_row)
|
|
1865 {
|
|
1866 int n = nspaces;
|
|
1867
|
|
1868 it->c = ' ';
|
|
1869 it->pixel_width = it->len = 1;
|
|
1870
|
|
1871 while (n--)
|
|
1872 append_glyph (it);
|
|
1873
|
|
1874 it->c = '\t';
|
|
1875 }
|
|
1876
|
|
1877 it->pixel_width = nspaces;
|
|
1878 it->nglyphs = nspaces;
|
|
1879 }
|
29262
|
1880 else if (SINGLE_BYTE_CHAR_P (it->c))
|
|
1881 {
|
29263
|
1882 /* Coming here means that it->c is from display table, thus we
|
29262
|
1883 must send the code as is to the terminal. Although there's
|
|
1884 no way to know how many columns it occupies on a screen, it
|
|
1885 is a good assumption that a single byte code has 1-column
|
|
1886 width. */
|
|
1887 it->pixel_width = it->nglyphs = 1;
|
|
1888 if (it->glyph_row)
|
|
1889 append_glyph (it);
|
|
1890 }
|
25002
|
1891 else
|
|
1892 {
|
26871
|
1893 /* A multi-byte character. The display width is fixed for all
|
|
1894 characters of the set. Some of the glyphs may have to be
|
|
1895 ignored because they are already displayed in a continued
|
|
1896 line. */
|
25002
|
1897 int charset = CHAR_CHARSET (it->c);
|
|
1898
|
26871
|
1899 it->pixel_width = CHARSET_WIDTH (charset);
|
25002
|
1900 it->nglyphs = it->pixel_width;
|
|
1901
|
|
1902 if (it->glyph_row)
|
|
1903 append_glyph (it);
|
|
1904 }
|
|
1905
|
|
1906 /* Advance current_x by the pixel width as a convenience for
|
|
1907 the caller. */
|
|
1908 if (it->area == TEXT_AREA)
|
|
1909 it->current_x += it->pixel_width;
|
25187
|
1910 it->ascent = it->max_ascent = it->phys_ascent = it->max_phys_ascent = 0;
|
|
1911 it->descent = it->max_descent = it->phys_descent = it->max_phys_descent = 1;
|
25002
|
1912 }
|
|
1913
|
|
1914
|
|
1915 /* Get information about special display element WHAT in an
|
|
1916 environment described by IT. WHAT is one of IT_TRUNCATION or
|
|
1917 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
|
|
1918 non-null glyph_row member. This function ensures that fields like
|
|
1919 face_id, c, len of IT are left untouched. */
|
|
1920
|
|
1921 void
|
|
1922 produce_special_glyphs (it, what)
|
|
1923 struct it *it;
|
|
1924 enum display_element_type what;
|
|
1925 {
|
|
1926 struct it temp_it;
|
|
1927
|
|
1928 temp_it = *it;
|
|
1929 temp_it.dp = NULL;
|
|
1930 temp_it.what = IT_CHARACTER;
|
|
1931 temp_it.len = 1;
|
28507
b6f06a755c7d
make_number/XINT/XUINT conversions; EQ/== fixes; ==Qnil -> NILP
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
1932 temp_it.object = make_number (0);
|
25002
|
1933 bzero (&temp_it.current, sizeof temp_it.current);
|
|
1934
|
|
1935 if (what == IT_CONTINUATION)
|
|
1936 {
|
|
1937 /* Continuation glyph. */
|
|
1938 if (it->dp
|
|
1939 && INTEGERP (DISP_CONTINUE_GLYPH (it->dp))
|
|
1940 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it->dp))))
|
|
1941 {
|
|
1942 temp_it.c = FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it->dp)));
|
29019
|
1943 temp_it.len = CHAR_BYTES (temp_it.c);
|
25002
|
1944 }
|
|
1945 else
|
|
1946 temp_it.c = '\\';
|
|
1947
|
|
1948 produce_glyphs (&temp_it);
|
|
1949 it->pixel_width = temp_it.pixel_width;
|
|
1950 it->nglyphs = temp_it.pixel_width;
|
|
1951 }
|
|
1952 else if (what == IT_TRUNCATION)
|
|
1953 {
|
|
1954 /* Truncation glyph. */
|
|
1955 if (it->dp
|
|
1956 && INTEGERP (DISP_TRUNC_GLYPH (it->dp))
|
|
1957 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it->dp))))
|
|
1958 {
|
|
1959 temp_it.c = FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it->dp)));
|
29019
|
1960 temp_it.len = CHAR_BYTES (temp_it.c);
|
25002
|
1961 }
|
|
1962 else
|
|
1963 temp_it.c = '$';
|
|
1964
|
|
1965 produce_glyphs (&temp_it);
|
|
1966 it->pixel_width = temp_it.pixel_width;
|
|
1967 it->nglyphs = temp_it.pixel_width;
|
|
1968 }
|
|
1969 else
|
|
1970 abort ();
|
|
1971 }
|
|
1972
|
|
1973
|
|
1974 /* Return an estimation of the pixel height of mode or top lines on
|
|
1975 frame F. FACE_ID specifies what line's height to estimate. */
|
|
1976
|
|
1977 int
|
|
1978 estimate_mode_line_height (f, face_id)
|
|
1979 struct frame *f;
|
|
1980 enum face_id face_id;
|
|
1981 {
|
|
1982 if (estimate_mode_line_height_hook)
|
|
1983 return estimate_mode_line_height_hook (f, face_id);
|
|
1984 else
|
|
1985 return 1;
|
|
1986 }
|
|
1987
|
|
1988
|
|
1989
|
|
1990 /***********************************************************************
|
|
1991 Faces
|
|
1992 ***********************************************************************/
|
|
1993
|
28465
|
1994 /* Value is non-zero if attribute ATTR may be used. ATTR should be
|
|
1995 one of the enumerators from enum no_color_bit, or a bit set built
|
|
1996 from them. Some display attributes may not be used together with
|
|
1997 color; the termcap capability `NC' specifies which ones. */
|
|
1998
|
|
1999 #define MAY_USE_WITH_COLORS_P(ATTR) \
|
|
2000 (TN_max_colors > 0 \
|
|
2001 ? (TN_no_color_video & (ATTR)) == 0 \
|
|
2002 : 1)
|
25002
|
2003
|
|
2004 /* Turn appearances of face FACE_ID on tty frame F on. */
|
|
2005
|
|
2006 static void
|
|
2007 turn_on_face (f, face_id)
|
|
2008 struct frame *f;
|
|
2009 int face_id;
|
|
2010 {
|
|
2011 struct face *face = FACE_FROM_ID (f, face_id);
|
|
2012
|
|
2013 xassert (face != NULL);
|
|
2014
|
|
2015 if (face->tty_bold_p)
|
28465
|
2016 {
|
|
2017 if (MAY_USE_WITH_COLORS_P (NC_BOLD))
|
|
2018 OUTPUT1_IF (TS_enter_bold_mode);
|
|
2019 }
|
25002
|
2020 else if (face->tty_dim_p)
|
28465
|
2021 if (MAY_USE_WITH_COLORS_P (NC_DIM))
|
|
2022 OUTPUT1_IF (TS_enter_dim_mode);
|
25002
|
2023
|
|
2024 /* Alternate charset and blinking not yet used. */
|
28465
|
2025 if (face->tty_alt_charset_p
|
|
2026 && MAY_USE_WITH_COLORS_P (NC_ALT_CHARSET))
|
25002
|
2027 OUTPUT1_IF (TS_enter_alt_charset_mode);
|
|
2028
|
28465
|
2029 if (face->tty_blinking_p
|
|
2030 && MAY_USE_WITH_COLORS_P (NC_BLINK))
|
25002
|
2031 OUTPUT1_IF (TS_enter_blink_mode);
|
|
2032
|
|
2033 if (face->tty_underline_p
|
|
2034 /* Don't underline if that's difficult. */
|
28465
|
2035 && TN_magic_cookie_glitch_ul <= 0
|
|
2036 && MAY_USE_WITH_COLORS_P (NC_UNDERLINE))
|
25002
|
2037 OUTPUT1_IF (TS_enter_underline_mode);
|
|
2038
|
28465
|
2039 if (MAY_USE_WITH_COLORS_P (NC_REVERSE))
|
|
2040 if (face->tty_reverse_p
|
|
2041 || face->foreground == FACE_TTY_DEFAULT_BG_COLOR
|
|
2042 || face->background == FACE_TTY_DEFAULT_FG_COLOR)
|
|
2043 OUTPUT1_IF (TS_enter_reverse_mode);
|
25002
|
2044
|
|
2045 if (TN_max_colors > 0)
|
|
2046 {
|
|
2047 char *p;
|
|
2048
|
|
2049 if (face->foreground != FACE_TTY_DEFAULT_COLOR
|
26902
|
2050 && face->foreground != FACE_TTY_DEFAULT_FG_COLOR
|
|
2051 && face->foreground != FACE_TTY_DEFAULT_BG_COLOR
|
25002
|
2052 && TS_set_foreground)
|
|
2053 {
|
|
2054 p = tparam (TS_set_foreground, NULL, 0, (int) face->foreground);
|
|
2055 OUTPUT (p);
|
|
2056 xfree (p);
|
|
2057 }
|
|
2058
|
|
2059 if (face->background != FACE_TTY_DEFAULT_COLOR
|
26902
|
2060 && face->background != FACE_TTY_DEFAULT_BG_COLOR
|
|
2061 && face->background != FACE_TTY_DEFAULT_FG_COLOR
|
25002
|
2062 && TS_set_background)
|
|
2063 {
|
|
2064 p = tparam (TS_set_background, NULL, 0, (int) face->background);
|
|
2065 OUTPUT (p);
|
|
2066 xfree (p);
|
|
2067 }
|
|
2068 }
|
|
2069 }
|
|
2070
|
|
2071
|
|
2072 /* Turn off appearances of face FACE_ID on tty frame F. */
|
|
2073
|
|
2074 static void
|
|
2075 turn_off_face (f, face_id)
|
|
2076 struct frame *f;
|
|
2077 int face_id;
|
|
2078 {
|
|
2079 struct face *face = FACE_FROM_ID (f, face_id);
|
|
2080
|
|
2081 xassert (face != NULL);
|
|
2082
|
|
2083 if (TS_exit_attribute_mode)
|
|
2084 {
|
|
2085 /* Capability "me" will turn off appearance modes double-bright,
|
|
2086 half-bright, reverse-video, standout, underline. It may or
|
|
2087 may not turn off alt-char-mode. */
|
|
2088 if (face->tty_bold_p
|
|
2089 || face->tty_dim_p
|
|
2090 || face->tty_reverse_p
|
|
2091 || face->tty_alt_charset_p
|
|
2092 || face->tty_blinking_p
|
|
2093 || face->tty_underline_p)
|
30848
|
2094 {
|
|
2095 OUTPUT1_IF (TS_exit_attribute_mode);
|
|
2096 if (strcmp (TS_exit_attribute_mode, TS_end_standout_mode) == 0)
|
|
2097 standout_mode = 0;
|
|
2098 }
|
25002
|
2099
|
|
2100 if (face->tty_alt_charset_p)
|
|
2101 OUTPUT_IF (TS_exit_alt_charset_mode);
|
|
2102 }
|
|
2103 else
|
|
2104 {
|
|
2105 /* If we don't have "me" we can only have those appearances
|
|
2106 that have exit sequences defined. */
|
|
2107 if (face->tty_alt_charset_p)
|
|
2108 OUTPUT_IF (TS_exit_alt_charset_mode);
|
|
2109
|
|
2110 if (face->tty_underline_p
|
|
2111 /* We don't underline if that's difficult. */
|
|
2112 && TN_magic_cookie_glitch_ul <= 0)
|
|
2113 OUTPUT_IF (TS_exit_underline_mode);
|
|
2114 }
|
|
2115
|
|
2116 /* Switch back to default colors. */
|
|
2117 if (TN_max_colors > 0
|
26902
|
2118 && ((face->foreground != FACE_TTY_DEFAULT_COLOR
|
|
2119 && face->foreground != FACE_TTY_DEFAULT_FG_COLOR)
|
|
2120 || (face->background != FACE_TTY_DEFAULT_COLOR
|
|
2121 && face->background != FACE_TTY_DEFAULT_BG_COLOR)))
|
25002
|
2122 OUTPUT1_IF (TS_orig_pair);
|
|
2123 }
|
|
2124
|
|
2125
|
|
2126 /* Return non-zero if the terminal is capable to display colors. */
|
|
2127
|
|
2128 DEFUN ("tty-display-color-p", Ftty_display_color_p, Stty_display_color_p,
|
27087
|
2129 0, 1, 0,
|
|
2130 "Return non-nil if TTY can display colors on FRAME.")
|
|
2131 (frame)
|
|
2132 Lisp_Object frame;
|
25002
|
2133 {
|
|
2134 return TN_max_colors > 0 ? Qt : Qnil;
|
|
2135 }
|
|
2136
|
|
2137
|
|
2138
|
|
2139
|
|
2140 /***********************************************************************
|
|
2141 Initialization
|
|
2142 ***********************************************************************/
|
|
2143
|
21514
|
2144 void
|
253
|
2145 term_init (terminal_type)
|
|
2146 char *terminal_type;
|
|
2147 {
|
|
2148 char *area;
|
|
2149 char **address = &area;
|
|
2150 char buffer[2044];
|
|
2151 register char *p;
|
|
2152 int status;
|
25675
|
2153 struct frame *sf = XFRAME (selected_frame);
|
253
|
2154
|
9797
|
2155 #ifdef WINDOWSNT
|
16885
|
2156 initialize_w32_display ();
|
9797
|
2157
|
|
2158 Wcm_clear ();
|
|
2159
|
24431
|
2160 area = (char *) xmalloc (2044);
|
9797
|
2161
|
|
2162 if (area == 0)
|
|
2163 abort ();
|
|
2164
|
25675
|
2165 FrameRows = FRAME_HEIGHT (sf);
|
|
2166 FrameCols = FRAME_WIDTH (sf);
|
|
2167 specified_window = FRAME_HEIGHT (sf);
|
9797
|
2168
|
|
2169 delete_in_insert_mode = 1;
|
|
2170
|
|
2171 UseTabs = 0;
|
|
2172 scroll_region_ok = 0;
|
|
2173
|
|
2174 /* Seems to insert lines when it's not supposed to, messing
|
|
2175 up the display. In doing a trace, it didn't seem to be
|
|
2176 called much, so I don't think we're losing anything by
|
|
2177 turning it off. */
|
|
2178
|
|
2179 line_ins_del_ok = 0;
|
|
2180 char_ins_del_ok = 1;
|
|
2181
|
|
2182 baud_rate = 19200;
|
|
2183
|
25675
|
2184 FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
|
|
2185 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
|
27519
|
2186 TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */
|
9797
|
2187
|
|
2188 return;
|
21827
87c7f4bd99da
Include cm.h after dispextern.h to avoid name conflicts
Geoff Voelker <voelker@cs.washington.edu>
diff
changeset
|
2189 #else /* not WINDOWSNT */
|
9797
|
2190
|
253
|
2191 Wcm_clear ();
|
|
2192
|
|
2193 status = tgetent (buffer, terminal_type);
|
|
2194 if (status < 0)
|
10824
|
2195 {
|
|
2196 #ifdef TERMINFO
|
16894
|
2197 fatal ("Cannot open terminfo database file");
|
10824
|
2198 #else
|
16894
|
2199 fatal ("Cannot open termcap database file");
|
10824
|
2200 #endif
|
|
2201 }
|
253
|
2202 if (status == 0)
|
10824
|
2203 {
|
|
2204 #ifdef TERMINFO
|
|
2205 fatal ("Terminal type %s is not defined.\n\
|
|
2206 If that is not the actual type of terminal you have,\n\
|
|
2207 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
|
|
2208 `setenv TERM ...') to specify the correct type. It may be necessary\n\
|
16894
|
2209 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
|
10824
|
2210 terminal_type);
|
|
2211 #else
|
|
2212 fatal ("Terminal type %s is not defined.\n\
|
4499
|
2213 If that is not the actual type of terminal you have,\n\
|
|
2214 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
|
|
2215 `setenv TERM ...') to specify the correct type. It may be necessary\n\
|
16894
|
2216 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
|
10824
|
2217 terminal_type);
|
|
2218 #endif
|
|
2219 }
|
253
|
2220 #ifdef TERMINFO
|
24431
|
2221 area = (char *) xmalloc (2044);
|
253
|
2222 #else
|
24431
|
2223 area = (char *) xmalloc (strlen (buffer));
|
253
|
2224 #endif /* not TERMINFO */
|
|
2225 if (area == 0)
|
|
2226 abort ();
|
|
2227
|
|
2228 TS_ins_line = tgetstr ("al", address);
|
|
2229 TS_ins_multi_lines = tgetstr ("AL", address);
|
|
2230 TS_bell = tgetstr ("bl", address);
|
|
2231 BackTab = tgetstr ("bt", address);
|
|
2232 TS_clr_to_bottom = tgetstr ("cd", address);
|
|
2233 TS_clr_line = tgetstr ("ce", address);
|
765
|
2234 TS_clr_frame = tgetstr ("cl", address);
|
28685
|
2235 ColPosition = NULL; /* tgetstr ("ch", address); */
|
253
|
2236 AbsPosition = tgetstr ("cm", address);
|
|
2237 CR = tgetstr ("cr", address);
|
|
2238 TS_set_scroll_region = tgetstr ("cs", address);
|
|
2239 TS_set_scroll_region_1 = tgetstr ("cS", address);
|
|
2240 RowPosition = tgetstr ("cv", address);
|
|
2241 TS_del_char = tgetstr ("dc", address);
|
|
2242 TS_del_multi_chars = tgetstr ("DC", address);
|
|
2243 TS_del_line = tgetstr ("dl", address);
|
|
2244 TS_del_multi_lines = tgetstr ("DL", address);
|
|
2245 TS_delete_mode = tgetstr ("dm", address);
|
|
2246 TS_end_delete_mode = tgetstr ("ed", address);
|
|
2247 TS_end_insert_mode = tgetstr ("ei", address);
|
|
2248 Home = tgetstr ("ho", address);
|
|
2249 TS_ins_char = tgetstr ("ic", address);
|
|
2250 TS_ins_multi_chars = tgetstr ("IC", address);
|
|
2251 TS_insert_mode = tgetstr ("im", address);
|
|
2252 TS_pad_inserted_char = tgetstr ("ip", address);
|
|
2253 TS_end_keypad_mode = tgetstr ("ke", address);
|
|
2254 TS_keypad_mode = tgetstr ("ks", address);
|
|
2255 LastLine = tgetstr ("ll", address);
|
|
2256 Right = tgetstr ("nd", address);
|
|
2257 Down = tgetstr ("do", address);
|
|
2258 if (!Down)
|
|
2259 Down = tgetstr ("nl", address); /* Obsolete name for "do" */
|
|
2260 #ifdef VMS
|
|
2261 /* VMS puts a carriage return before each linefeed,
|
|
2262 so it is not safe to use linefeeds. */
|
|
2263 if (Down && Down[0] == '\n' && Down[1] == '\0')
|
|
2264 Down = 0;
|
|
2265 #endif /* VMS */
|
|
2266 if (tgetflag ("bs"))
|
|
2267 Left = "\b"; /* can't possibly be longer! */
|
|
2268 else /* (Actually, "bs" is obsolete...) */
|
|
2269 Left = tgetstr ("le", address);
|
|
2270 if (!Left)
|
|
2271 Left = tgetstr ("bc", address); /* Obsolete name for "le" */
|
|
2272 TS_pad_char = tgetstr ("pc", address);
|
|
2273 TS_repeat = tgetstr ("rp", address);
|
|
2274 TS_end_standout_mode = tgetstr ("se", address);
|
|
2275 TS_fwd_scroll = tgetstr ("sf", address);
|
|
2276 TS_standout_mode = tgetstr ("so", address);
|
|
2277 TS_rev_scroll = tgetstr ("sr", address);
|
|
2278 Wcm.cm_tab = tgetstr ("ta", address);
|
|
2279 TS_end_termcap_modes = tgetstr ("te", address);
|
|
2280 TS_termcap_modes = tgetstr ("ti", address);
|
|
2281 Up = tgetstr ("up", address);
|
|
2282 TS_visible_bell = tgetstr ("vb", address);
|
25002
|
2283 TS_cursor_normal = tgetstr ("ve", address);
|
|
2284 TS_cursor_visible = tgetstr ("vs", address);
|
|
2285 TS_cursor_invisible = tgetstr ("vi", address);
|
253
|
2286 TS_set_window = tgetstr ("wi", address);
|
25002
|
2287
|
|
2288 TS_enter_underline_mode = tgetstr ("us", address);
|
|
2289 TS_exit_underline_mode = tgetstr ("ue", address);
|
|
2290 TN_magic_cookie_glitch_ul = tgetnum ("ug");
|
|
2291 TS_enter_bold_mode = tgetstr ("md", address);
|
|
2292 TS_enter_dim_mode = tgetstr ("mh", address);
|
|
2293 TS_enter_blink_mode = tgetstr ("mb", address);
|
|
2294 TS_enter_reverse_mode = tgetstr ("mr", address);
|
|
2295 TS_enter_alt_charset_mode = tgetstr ("as", address);
|
|
2296 TS_exit_alt_charset_mode = tgetstr ("ae", address);
|
|
2297 TS_exit_attribute_mode = tgetstr ("me", address);
|
|
2298
|
253
|
2299 MultiUp = tgetstr ("UP", address);
|
|
2300 MultiDown = tgetstr ("DO", address);
|
|
2301 MultiLeft = tgetstr ("LE", address);
|
|
2302 MultiRight = tgetstr ("RI", address);
|
|
2303
|
26425
|
2304 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
|
|
2305 color because we can't switch back to the default foreground and
|
|
2306 background. */
|
25002
|
2307 TS_orig_pair = tgetstr ("op", address);
|
26425
|
2308 if (TS_orig_pair)
|
25002
|
2309 {
|
26425
|
2310 TS_set_foreground = tgetstr ("AF", address);
|
|
2311 TS_set_background = tgetstr ("AB", address);
|
|
2312 if (!TS_set_foreground)
|
|
2313 {
|
|
2314 /* SVr4. */
|
|
2315 TS_set_foreground = tgetstr ("Sf", address);
|
|
2316 TS_set_background = tgetstr ("Sb", address);
|
|
2317 }
|
28465
|
2318
|
26425
|
2319 TN_max_colors = tgetnum ("Co");
|
|
2320 TN_max_pairs = tgetnum ("pa");
|
28465
|
2321
|
|
2322 TN_no_color_video = tgetnum ("NC");
|
|
2323 if (TN_no_color_video == -1)
|
|
2324 TN_no_color_video = 0;
|
25002
|
2325 }
|
|
2326
|
11530
|
2327 MagicWrap = tgetflag ("xn");
|
|
2328 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
|
|
2329 the former flag imply the latter. */
|
|
2330 AutoWrap = MagicWrap || tgetflag ("am");
|
765
|
2331 memory_below_frame = tgetflag ("db");
|
253
|
2332 TF_hazeltine = tgetflag ("hz");
|
|
2333 must_write_spaces = tgetflag ("in");
|
|
2334 meta_key = tgetflag ("km") || tgetflag ("MT");
|
|
2335 TF_insmode_motion = tgetflag ("mi");
|
|
2336 TF_standout_motion = tgetflag ("ms");
|
|
2337 TF_underscore = tgetflag ("ul");
|
|
2338 TF_xs = tgetflag ("xs");
|
|
2339 TF_teleray = tgetflag ("xt");
|
|
2340
|
533
|
2341 term_get_fkeys (address);
|
|
2342
|
765
|
2343 /* Get frame size from system, or else from termcap. */
|
16093
|
2344 {
|
|
2345 int height, width;
|
|
2346 get_frame_size (&width, &height);
|
25675
|
2347 FRAME_WIDTH (sf) = width;
|
|
2348 FRAME_HEIGHT (sf) = height;
|
16093
|
2349 }
|
|
2350
|
25675
|
2351 if (FRAME_WIDTH (sf) <= 0)
|
|
2352 SET_FRAME_WIDTH (sf, tgetnum ("co"));
|
16260
|
2353 else
|
|
2354 /* Keep width and external_width consistent */
|
25675
|
2355 SET_FRAME_WIDTH (sf, FRAME_WIDTH (sf));
|
|
2356 if (FRAME_HEIGHT (sf) <= 0)
|
|
2357 FRAME_HEIGHT (sf) = tgetnum ("li");
|
16260
|
2358
|
25675
|
2359 if (FRAME_HEIGHT (sf) < 3 || FRAME_WIDTH (sf) < 3)
|
16894
|
2360 fatal ("Screen size %dx%d is too small",
|
25675
|
2361 FRAME_HEIGHT (sf), FRAME_WIDTH (sf));
|
10332
|
2362
|
253
|
2363 min_padding_speed = tgetnum ("pb");
|
|
2364 TN_standout_width = tgetnum ("sg");
|
|
2365 TabWidth = tgetnum ("tw");
|
|
2366
|
|
2367 #ifdef VMS
|
|
2368 /* These capabilities commonly use ^J.
|
|
2369 I don't know why, but sending them on VMS does not work;
|
|
2370 it causes following spaces to be lost, sometimes.
|
|
2371 For now, the simplest fix is to avoid using these capabilities ever. */
|
|
2372 if (Down && Down[0] == '\n')
|
|
2373 Down = 0;
|
|
2374 #endif /* VMS */
|
|
2375
|
|
2376 if (!TS_bell)
|
|
2377 TS_bell = "\07";
|
|
2378
|
|
2379 if (!TS_fwd_scroll)
|
|
2380 TS_fwd_scroll = Down;
|
|
2381
|
|
2382 PC = TS_pad_char ? *TS_pad_char : 0;
|
|
2383
|
|
2384 if (TabWidth < 0)
|
|
2385 TabWidth = 8;
|
|
2386
|
|
2387 /* Turned off since /etc/termcap seems to have :ta= for most terminals
|
|
2388 and newer termcap doc does not seem to say there is a default.
|
|
2389 if (!Wcm.cm_tab)
|
|
2390 Wcm.cm_tab = "\t";
|
|
2391 */
|
|
2392
|
|
2393 if (TS_standout_mode == 0)
|
|
2394 {
|
|
2395 TN_standout_width = tgetnum ("ug");
|
|
2396 TS_end_standout_mode = tgetstr ("ue", address);
|
|
2397 TS_standout_mode = tgetstr ("us", address);
|
|
2398 }
|
|
2399
|
5933
|
2400 /* If no `se' string, try using a `me' string instead.
|
|
2401 If that fails, we can't use standout mode at all. */
|
|
2402 if (TS_end_standout_mode == 0)
|
|
2403 {
|
8612
|
2404 char *s = tgetstr ("me", address);
|
5933
|
2405 if (s != 0)
|
|
2406 TS_end_standout_mode = s;
|
|
2407 else
|
|
2408 TS_standout_mode = 0;
|
|
2409 }
|
|
2410
|
253
|
2411 if (TF_teleray)
|
|
2412 {
|
|
2413 Wcm.cm_tab = 0;
|
|
2414 /* Teleray: most programs want a space in front of TS_standout_mode,
|
|
2415 but Emacs can do without it (and give one extra column). */
|
|
2416 TS_standout_mode = "\033RD";
|
|
2417 TN_standout_width = 1;
|
|
2418 /* But that means we cannot rely on ^M to go to column zero! */
|
|
2419 CR = 0;
|
|
2420 /* LF can't be trusted either -- can alter hpos */
|
|
2421 /* if move at column 0 thru a line with TS_standout_mode */
|
|
2422 Down = 0;
|
|
2423 }
|
|
2424
|
|
2425 /* Special handling for certain terminal types known to need it */
|
|
2426
|
|
2427 if (!strcmp (terminal_type, "supdup"))
|
|
2428 {
|
765
|
2429 memory_below_frame = 1;
|
253
|
2430 Wcm.cm_losewrap = 1;
|
|
2431 }
|
|
2432 if (!strncmp (terminal_type, "c10", 3)
|
|
2433 || !strcmp (terminal_type, "perq"))
|
|
2434 {
|
|
2435 /* Supply a makeshift :wi string.
|
|
2436 This string is not valid in general since it works only
|
|
2437 for windows starting at the upper left corner;
|
|
2438 but that is all Emacs uses.
|
|
2439
|
765
|
2440 This string works only if the frame is using
|
253
|
2441 the top of the video memory, because addressing is memory-relative.
|
|
2442 So first check the :ti string to see if that is true.
|
|
2443
|
|
2444 It would be simpler if the :wi string could go in the termcap
|
|
2445 entry, but it can't because it is not fully valid.
|
|
2446 If it were in the termcap entry, it would confuse other programs. */
|
|
2447 if (!TS_set_window)
|
|
2448 {
|
|
2449 p = TS_termcap_modes;
|
|
2450 while (*p && strcmp (p, "\033v "))
|
|
2451 p++;
|
|
2452 if (*p)
|
|
2453 TS_set_window = "\033v%C %C %C %C ";
|
|
2454 }
|
|
2455 /* Termcap entry often fails to have :in: flag */
|
|
2456 must_write_spaces = 1;
|
|
2457 /* :ti string typically fails to have \E^G! in it */
|
|
2458 /* This limits scope of insert-char to one line. */
|
|
2459 strcpy (area, TS_termcap_modes);
|
|
2460 strcat (area, "\033\007!");
|
|
2461 TS_termcap_modes = area;
|
|
2462 area += strlen (area) + 1;
|
|
2463 p = AbsPosition;
|
|
2464 /* Change all %+ parameters to %C, to handle
|
|
2465 values above 96 correctly for the C100. */
|
|
2466 while (*p)
|
|
2467 {
|
|
2468 if (p[0] == '%' && p[1] == '+')
|
|
2469 p[1] = 'C';
|
|
2470 p++;
|
|
2471 }
|
|
2472 }
|
|
2473
|
25675
|
2474 FrameRows = FRAME_HEIGHT (sf);
|
|
2475 FrameCols = FRAME_WIDTH (sf);
|
|
2476 specified_window = FRAME_HEIGHT (sf);
|
253
|
2477
|
|
2478 if (Wcm_init () == -1) /* can't do cursor motion */
|
|
2479 #ifdef VMS
|
|
2480 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
|
|
2481 It lacks the ability to position the cursor.\n\
|
|
2482 If that is not the actual type of terminal you have, use either the\n\
|
|
2483 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
|
16894
|
2484 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
|
253
|
2485 terminal_type);
|
12412
|
2486 #else /* not VMS */
|
|
2487 # ifdef TERMINFO
|
|
2488 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
|
|
2489 It lacks the ability to position the cursor.\n\
|
|
2490 If that is not the actual type of terminal you have,\n\
|
|
2491 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
|
|
2492 `setenv TERM ...') to specify the correct type. It may be necessary\n\
|
16894
|
2493 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
|
12412
|
2494 terminal_type);
|
|
2495 # else /* TERMCAP */
|
253
|
2496 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
|
|
2497 It lacks the ability to position the cursor.\n\
|
|
2498 If that is not the actual type of terminal you have,\n\
|
4499
|
2499 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
|
|
2500 `setenv TERM ...') to specify the correct type. It may be necessary\n\
|
16894
|
2501 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
|
253
|
2502 terminal_type);
|
12412
|
2503 # endif /* TERMINFO */
|
|
2504 #endif /*VMS */
|
25675
|
2505 if (FRAME_HEIGHT (sf) <= 0
|
|
2506 || FRAME_WIDTH (sf) <= 0)
|
16894
|
2507 fatal ("The frame size has not been specified");
|
253
|
2508
|
|
2509 delete_in_insert_mode
|
|
2510 = TS_delete_mode && TS_insert_mode
|
|
2511 && !strcmp (TS_delete_mode, TS_insert_mode);
|
|
2512
|
|
2513 se_is_so = (TS_standout_mode
|
|
2514 && TS_end_standout_mode
|
|
2515 && !strcmp (TS_standout_mode, TS_end_standout_mode));
|
|
2516
|
|
2517 /* Remove width of standout marker from usable width of line */
|
|
2518 if (TN_standout_width > 0)
|
25675
|
2519 SET_FRAME_WIDTH (sf, FRAME_WIDTH (sf) - TN_standout_width);
|
253
|
2520
|
|
2521 UseTabs = tabs_safe_p () && TabWidth == 8;
|
|
2522
|
|
2523 scroll_region_ok
|
|
2524 = (Wcm.cm_abs
|
|
2525 && (TS_set_window || TS_set_scroll_region || TS_set_scroll_region_1));
|
|
2526
|
|
2527 line_ins_del_ok = (((TS_ins_line || TS_ins_multi_lines)
|
|
2528 && (TS_del_line || TS_del_multi_lines))
|
|
2529 || (scroll_region_ok && TS_fwd_scroll && TS_rev_scroll));
|
|
2530
|
|
2531 char_ins_del_ok = ((TS_ins_char || TS_insert_mode
|
|
2532 || TS_pad_inserted_char || TS_ins_multi_chars)
|
|
2533 && (TS_del_char || TS_del_multi_chars));
|
|
2534
|
|
2535 fast_clear_end_of_line = TS_clr_line != 0;
|
|
2536
|
|
2537 init_baud_rate ();
|
|
2538 if (read_socket_hook) /* Baudrate is somewhat */
|
|
2539 /* meaningless in this case */
|
|
2540 baud_rate = 9600;
|
1717
|
2541
|
25675
|
2542 FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
|
|
2543 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
|
21827
87c7f4bd99da
Include cm.h after dispextern.h to avoid name conflicts
Geoff Voelker <voelker@cs.washington.edu>
diff
changeset
|
2544 #endif /* WINDOWSNT */
|
253
|
2545 }
|
|
2546
|
|
2547 /* VARARGS 1 */
|
21514
|
2548 void
|
253
|
2549 fatal (str, arg1, arg2)
|
621
|
2550 char *str, *arg1, *arg2;
|
253
|
2551 {
|
|
2552 fprintf (stderr, "emacs: ");
|
|
2553 fprintf (stderr, str, arg1, arg2);
|
16894
|
2554 fprintf (stderr, "\n");
|
253
|
2555 fflush (stderr);
|
|
2556 exit (1);
|
|
2557 }
|
6752
|
2558
|
21514
|
2559 void
|
6752
|
2560 syms_of_term ()
|
|
2561 {
|
|
2562 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo,
|
|
2563 "Non-nil means the system uses terminfo rather than termcap.\n\
|
|
2564 This variable can be used by terminal emulator packages.");
|
|
2565 #ifdef TERMINFO
|
|
2566 system_uses_terminfo = 1;
|
|
2567 #else
|
|
2568 system_uses_terminfo = 0;
|
|
2569 #endif
|
15974
|
2570
|
|
2571 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function,
|
|
2572 "Non-nil means call this function to ring the bell.\n\
|
|
2573 The function should accept no arguments.");
|
|
2574 Vring_bell_function = Qnil;
|
25002
|
2575
|
|
2576 defsubr (&Stty_display_color_p);
|
6752
|
2577 }
|
25002
|
2578
|