(Info-unescape-quotes, Info-split-parameter-string)
[emacs.git] / src / term.c
blob5c25c7419dce216dd0a27f604d5fb2ffff71d8dc
1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 86, 87, 93, 94, 95, 98, 2000, 2001, 2002
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
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
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
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.
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
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
24 #include <config.h>
25 #include <stdio.h>
26 #include <ctype.h>
27 #include <string.h>
29 #include "termchar.h"
30 #include "termopts.h"
31 #include "lisp.h"
32 #include "charset.h"
33 #include "coding.h"
34 #include "keyboard.h"
35 #include "frame.h"
36 #include "disptab.h"
37 #include "termhooks.h"
38 #include "dispextern.h"
39 #include "window.h"
40 #include "keymap.h"
42 /* For now, don't try to include termcap.h. On some systems,
43 configure finds a non-standard termcap.h that the main build
44 won't find. */
46 #if defined HAVE_TERMCAP_H && 0
47 #include <termcap.h>
48 #else
49 extern void tputs P_ ((const char *, int, int (*)(int)));
50 extern int tgetent P_ ((char *, const char *));
51 extern int tgetflag P_ ((char *id));
52 extern int tgetnum P_ ((char *id));
53 #endif
55 #include "cm.h"
56 #ifdef HAVE_X_WINDOWS
57 #include "xterm.h"
58 #endif
59 #ifdef MAC_OS
60 #include "macterm.h"
61 #endif
63 static void turn_on_face P_ ((struct frame *, int face_id));
64 static void turn_off_face P_ ((struct frame *, int face_id));
65 static void tty_show_cursor P_ ((void));
66 static void tty_hide_cursor P_ ((void));
68 #define OUTPUT(a) \
69 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) - curY), cmputc)
70 #define OUTPUT1(a) tputs (a, 1, cmputc)
71 #define OUTPUTL(a, lines) tputs (a, lines, cmputc)
73 #define OUTPUT_IF(a) \
74 do { \
75 if (a) \
76 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) \
77 - curY), cmputc); \
78 } while (0)
80 #define OUTPUT1_IF(a) do { if (a) tputs (a, 1, cmputc); } while (0)
82 /* Function to use to ring the bell. */
84 Lisp_Object Vring_bell_function;
86 /* Terminal characteristics that higher levels want to look at.
87 These are all extern'd in termchar.h */
89 int must_write_spaces; /* Nonzero means spaces in the text
90 must actually be output; can't just skip
91 over some columns to leave them blank. */
92 int min_padding_speed; /* Speed below which no padding necessary */
94 int line_ins_del_ok; /* Terminal can insert and delete lines */
95 int char_ins_del_ok; /* Terminal can insert and delete chars */
96 int scroll_region_ok; /* Terminal supports setting the
97 scroll window */
98 int scroll_region_cost; /* Cost of setting a scroll window,
99 measured in characters */
100 int memory_below_frame; /* Terminal remembers lines
101 scrolled off bottom */
102 int fast_clear_end_of_line; /* Terminal has a `ce' string */
104 /* Nonzero means no need to redraw the entire frame on resuming
105 a suspended Emacs. This is useful on terminals with multiple pages,
106 where one page is used for Emacs and another for all else. */
108 int no_redraw_on_reenter;
110 /* Hook functions that you can set to snap out the functions in this file.
111 These are all extern'd in termhooks.h */
113 void (*cursor_to_hook) P_ ((int, int));
114 void (*raw_cursor_to_hook) P_ ((int, int));
115 void (*clear_to_end_hook) P_ ((void));
116 void (*clear_frame_hook) P_ ((void));
117 void (*clear_end_of_line_hook) P_ ((int));
119 void (*ins_del_lines_hook) P_ ((int, int));
121 void (*delete_glyphs_hook) P_ ((int));
123 void (*ring_bell_hook) P_ ((void));
125 void (*reset_terminal_modes_hook) P_ ((void));
126 void (*set_terminal_modes_hook) P_ ((void));
127 void (*update_begin_hook) P_ ((struct frame *));
128 void (*update_end_hook) P_ ((struct frame *));
129 void (*set_terminal_window_hook) P_ ((int));
130 void (*insert_glyphs_hook) P_ ((struct glyph *, int));
131 void (*write_glyphs_hook) P_ ((struct glyph *, int));
132 void (*delete_glyphs_hook) P_ ((int));
134 int (*read_socket_hook) P_ ((int, struct input_event *, int, int));
136 void (*frame_up_to_date_hook) P_ ((struct frame *));
138 /* Return the current position of the mouse.
140 Set *f to the frame the mouse is in, or zero if the mouse is in no
141 Emacs frame. If it is set to zero, all the other arguments are
142 garbage.
144 If the motion started in a scroll bar, set *bar_window to the
145 scroll bar's window, *part to the part the mouse is currently over,
146 *x to the position of the mouse along the scroll bar, and *y to the
147 overall length of the scroll bar.
149 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
150 row of the character cell the mouse is over.
152 Set *time to the time the mouse was at the returned position.
154 This should clear mouse_moved until the next motion
155 event arrives. */
157 void (*mouse_position_hook) P_ ((FRAME_PTR *f, int insist,
158 Lisp_Object *bar_window,
159 enum scroll_bar_part *part,
160 Lisp_Object *x,
161 Lisp_Object *y,
162 unsigned long *time));
164 /* When reading from a minibuffer in a different frame, Emacs wants
165 to shift the highlight from the selected frame to the mini-buffer's
166 frame; under X, this means it lies about where the focus is.
167 This hook tells the window system code to re-decide where to put
168 the highlight. */
170 void (*frame_rehighlight_hook) P_ ((FRAME_PTR f));
172 /* If we're displaying frames using a window system that can stack
173 frames on top of each other, this hook allows you to bring a frame
174 to the front, or bury it behind all the other windows. If this
175 hook is zero, that means the device we're displaying on doesn't
176 support overlapping frames, so there's no need to raise or lower
177 anything.
179 If RAISE is non-zero, F is brought to the front, before all other
180 windows. If RAISE is zero, F is sent to the back, behind all other
181 windows. */
183 void (*frame_raise_lower_hook) P_ ((FRAME_PTR f, int raise));
185 /* Set the vertical scroll bar for WINDOW to have its upper left corner
186 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
187 indicate that we are displaying PORTION characters out of a total
188 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
189 have a scroll bar, create one for it. */
191 void (*set_vertical_scroll_bar_hook)
192 P_ ((struct window *window,
193 int portion, int whole, int position));
196 /* The following three hooks are used when we're doing a thorough
197 redisplay of the frame. We don't explicitly know which scroll bars
198 are going to be deleted, because keeping track of when windows go
199 away is a real pain - can you say set-window-configuration?
200 Instead, we just assert at the beginning of redisplay that *all*
201 scroll bars are to be removed, and then save scroll bars from the
202 fiery pit when we actually redisplay their window. */
204 /* Arrange for all scroll bars on FRAME to be removed at the next call
205 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
206 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
208 This should be applied to each frame each time its window tree is
209 redisplayed, even if it is not displaying scroll bars at the moment;
210 if the HAS_SCROLL_BARS flag has just been turned off, only calling
211 this and the judge_scroll_bars_hook will get rid of them.
213 If non-zero, this hook should be safe to apply to any frame,
214 whether or not it can support scroll bars, and whether or not it is
215 currently displaying them. */
217 void (*condemn_scroll_bars_hook) P_ ((FRAME_PTR frame));
219 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
220 Note that it's okay to redeem a scroll bar that is not condemned. */
222 void (*redeem_scroll_bar_hook) P_ ((struct window *window));
224 /* Remove all scroll bars on FRAME that haven't been saved since the
225 last call to `*condemn_scroll_bars_hook'.
227 This should be applied to each frame after each time its window
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.
232 If non-zero, this hook should be safe to apply to any frame,
233 whether or not it can support scroll bars, and whether or not it is
234 currently displaying them. */
236 void (*judge_scroll_bars_hook) P_ ((FRAME_PTR FRAME));
238 /* Strings, numbers and flags taken from the termcap entry. */
240 char *TS_ins_line; /* "al" */
241 char *TS_ins_multi_lines; /* "AL" (one parameter, # lines to insert) */
242 char *TS_bell; /* "bl" */
243 char *TS_clr_to_bottom; /* "cd" */
244 char *TS_clr_line; /* "ce", clear to end of line */
245 char *TS_clr_frame; /* "cl" */
246 char *TS_set_scroll_region; /* "cs" (2 params, first line and last line) */
247 char *TS_set_scroll_region_1; /* "cS" (4 params: total lines,
248 lines above scroll region, lines below it,
249 total lines again) */
250 char *TS_del_char; /* "dc" */
251 char *TS_del_multi_chars; /* "DC" (one parameter, # chars to delete) */
252 char *TS_del_line; /* "dl" */
253 char *TS_del_multi_lines; /* "DL" (one parameter, # lines to delete) */
254 char *TS_delete_mode; /* "dm", enter character-delete mode */
255 char *TS_end_delete_mode; /* "ed", leave character-delete mode */
256 char *TS_end_insert_mode; /* "ei", leave character-insert mode */
257 char *TS_ins_char; /* "ic" */
258 char *TS_ins_multi_chars; /* "IC" (one parameter, # chars to insert) */
259 char *TS_insert_mode; /* "im", enter character-insert mode */
260 char *TS_pad_inserted_char; /* "ip". Just padding, no commands. */
261 char *TS_end_keypad_mode; /* "ke" */
262 char *TS_keypad_mode; /* "ks" */
263 char *TS_pad_char; /* "pc", char to use as padding */
264 char *TS_repeat; /* "rp" (2 params, # times to repeat
265 and character to be repeated) */
266 char *TS_end_standout_mode; /* "se" */
267 char *TS_fwd_scroll; /* "sf" */
268 char *TS_standout_mode; /* "so" */
269 char *TS_rev_scroll; /* "sr" */
270 char *TS_end_termcap_modes; /* "te" */
271 char *TS_termcap_modes; /* "ti" */
272 char *TS_visible_bell; /* "vb" */
273 char *TS_cursor_normal; /* "ve" */
274 char *TS_cursor_visible; /* "vs" */
275 char *TS_cursor_invisible; /* "vi" */
276 char *TS_set_window; /* "wi" (4 params, start and end of window,
277 each as vpos and hpos) */
279 /* Value of the "NC" (no_color_video) capability, or 0 if not
280 present. */
282 static int TN_no_color_video;
284 /* Meaning of bits in no_color_video. Each bit set means that the
285 corresponding attribute cannot be combined with colors. */
287 enum no_color_bit
289 NC_STANDOUT = 1 << 0,
290 NC_UNDERLINE = 1 << 1,
291 NC_REVERSE = 1 << 2,
292 NC_BLINK = 1 << 3,
293 NC_DIM = 1 << 4,
294 NC_BOLD = 1 << 5,
295 NC_INVIS = 1 << 6,
296 NC_PROTECT = 1 << 7,
297 NC_ALT_CHARSET = 1 << 8
300 /* "md" -- turn on bold (extra bright mode). */
302 char *TS_enter_bold_mode;
304 /* "mh" -- turn on half-bright mode. */
306 char *TS_enter_dim_mode;
308 /* "mb" -- enter blinking mode. */
310 char *TS_enter_blink_mode;
312 /* "mr" -- enter reverse video mode. */
314 char *TS_enter_reverse_mode;
316 /* "us"/"ue" -- start/end underlining. */
318 char *TS_exit_underline_mode, *TS_enter_underline_mode;
320 /* "as"/"ae" -- start/end alternate character set. Not really
321 supported, yet. */
323 char *TS_enter_alt_charset_mode, *TS_exit_alt_charset_mode;
325 /* "me" -- switch appearances off. */
327 char *TS_exit_attribute_mode;
329 /* "Co" -- number of colors. */
331 int TN_max_colors;
333 /* "pa" -- max. number of color pairs on screen. Not handled yet.
334 Could be a problem if not equal to TN_max_colors * TN_max_colors. */
336 int TN_max_pairs;
338 /* "op" -- SVr4 set default pair to its original value. */
340 char *TS_orig_pair;
342 /* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
343 1 param, the color index. */
345 char *TS_set_foreground, *TS_set_background;
347 int TF_hazeltine; /* termcap hz flag. */
348 int TF_insmode_motion; /* termcap mi flag: can move while in insert mode. */
349 int TF_standout_motion; /* termcap mi flag: can move while in standout mode. */
350 int TF_underscore; /* termcap ul flag: _ underlines if over-struck on
351 non-blank position. Must clear before writing _. */
352 int TF_teleray; /* termcap xt flag: many weird consequences.
353 For t1061. */
355 static int RPov; /* # chars to start a TS_repeat */
357 static int delete_in_insert_mode; /* delete mode == insert mode */
359 static int se_is_so; /* 1 if same string both enters and leaves
360 standout mode */
362 /* internal state */
364 /* The largest frame width in any call to calculate_costs. */
366 int max_frame_cols;
368 /* The largest frame height in any call to calculate_costs. */
370 int max_frame_lines;
372 static int costs_set; /* Nonzero if costs have been calculated. */
374 int insert_mode; /* Nonzero when in insert mode. */
375 int standout_mode; /* Nonzero when in standout mode. */
377 /* Size of window specified by higher levels.
378 This is the number of lines, from the top of frame downwards,
379 which can participate in insert-line/delete-line operations.
381 Effectively it excludes the bottom frame_lines - specified_window_size
382 lines from those operations. */
384 int specified_window;
386 /* Frame currently being redisplayed; 0 if not currently redisplaying.
387 (Direct output does not count). */
389 FRAME_PTR updating_frame;
391 /* Provided for lisp packages. */
393 static int system_uses_terminfo;
395 /* Flag used in tty_show/hide_cursor. */
397 static int tty_cursor_hidden;
399 char *tparam ();
401 extern char *tgetstr ();
404 #ifdef WINDOWSNT
405 /* We aren't X windows, but we aren't termcap either. This makes me
406 uncertain as to what value to use for frame.output_method. For
407 this file, we'll define FRAME_TERMCAP_P to be zero so that our
408 output hooks get called instead of the termcap functions. Probably
409 the best long-term solution is to define an output_windows_nt... */
411 #undef FRAME_TERMCAP_P
412 #define FRAME_TERMCAP_P(_f_) 0
413 #endif /* WINDOWSNT */
415 void
416 ring_bell ()
418 if (!NILP (Vring_bell_function))
420 Lisp_Object function;
422 /* Temporarily set the global variable to nil
423 so that if we get an error, it stays nil
424 and we don't call it over and over.
426 We don't specbind it, because that would carefully
427 restore the bad value if there's an error
428 and make the loop of errors happen anyway. */
430 function = Vring_bell_function;
431 Vring_bell_function = Qnil;
433 call0 (function);
435 Vring_bell_function = function;
437 else if (!FRAME_TERMCAP_P (XFRAME (selected_frame)))
438 (*ring_bell_hook) ();
439 else
440 OUTPUT (TS_visible_bell && visible_bell ? TS_visible_bell : TS_bell);
443 void
444 set_terminal_modes ()
446 if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
448 OUTPUT_IF (TS_termcap_modes);
449 OUTPUT_IF (TS_cursor_visible);
450 OUTPUT_IF (TS_keypad_mode);
451 losecursor ();
453 else
454 (*set_terminal_modes_hook) ();
457 void
458 reset_terminal_modes ()
460 if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
462 turn_off_highlight ();
463 turn_off_insert ();
464 OUTPUT_IF (TS_end_keypad_mode);
465 OUTPUT_IF (TS_cursor_normal);
466 OUTPUT_IF (TS_end_termcap_modes);
467 OUTPUT_IF (TS_orig_pair);
468 /* Output raw CR so kernel can track the cursor hpos. */
469 cmputc ('\r');
471 else if (reset_terminal_modes_hook)
472 (*reset_terminal_modes_hook) ();
475 void
476 update_begin (f)
477 struct frame *f;
479 updating_frame = f;
480 if (!FRAME_TERMCAP_P (f))
481 update_begin_hook (f);
484 void
485 update_end (f)
486 struct frame *f;
488 if (FRAME_TERMCAP_P (f))
490 if (!XWINDOW (selected_window)->cursor_off_p)
491 tty_show_cursor ();
492 turn_off_insert ();
493 background_highlight ();
495 else
496 update_end_hook (f);
498 updating_frame = NULL;
501 void
502 set_terminal_window (size)
503 int size;
505 if (FRAME_TERMCAP_P (updating_frame))
507 specified_window = size ? size : FRAME_LINES (updating_frame);
508 if (scroll_region_ok)
509 set_scroll_region (0, specified_window);
511 else
512 set_terminal_window_hook (size);
515 void
516 set_scroll_region (start, stop)
517 int start, stop;
519 char *buf;
520 struct frame *sf = XFRAME (selected_frame);
522 if (TS_set_scroll_region)
523 buf = tparam (TS_set_scroll_region, 0, 0, start, stop - 1);
524 else if (TS_set_scroll_region_1)
525 buf = tparam (TS_set_scroll_region_1, 0, 0,
526 FRAME_LINES (sf), start,
527 FRAME_LINES (sf) - stop,
528 FRAME_LINES (sf));
529 else
530 buf = tparam (TS_set_window, 0, 0, start, 0, stop, FRAME_COLS (sf));
532 OUTPUT (buf);
533 xfree (buf);
534 losecursor ();
538 static void
539 turn_on_insert ()
541 if (!insert_mode)
542 OUTPUT (TS_insert_mode);
543 insert_mode = 1;
546 void
547 turn_off_insert ()
549 if (insert_mode)
550 OUTPUT (TS_end_insert_mode);
551 insert_mode = 0;
554 /* Handle highlighting. */
556 void
557 turn_off_highlight ()
559 if (standout_mode)
560 OUTPUT_IF (TS_end_standout_mode);
561 standout_mode = 0;
564 static void
565 turn_on_highlight ()
567 if (!standout_mode)
568 OUTPUT_IF (TS_standout_mode);
569 standout_mode = 1;
572 static void
573 toggle_highlight ()
575 if (standout_mode)
576 turn_off_highlight ();
577 else
578 turn_on_highlight ();
582 /* Make cursor invisible. */
584 static void
585 tty_hide_cursor ()
587 if (tty_cursor_hidden == 0)
589 tty_cursor_hidden = 1;
590 OUTPUT_IF (TS_cursor_invisible);
595 /* Ensure that cursor is visible. */
597 static void
598 tty_show_cursor ()
600 if (tty_cursor_hidden)
602 tty_cursor_hidden = 0;
603 OUTPUT_IF (TS_cursor_normal);
604 OUTPUT_IF (TS_cursor_visible);
609 /* Set standout mode to the state it should be in for
610 empty space inside windows. What this is,
611 depends on the user option inverse-video. */
613 void
614 background_highlight ()
616 if (inverse_video)
617 turn_on_highlight ();
618 else
619 turn_off_highlight ();
622 /* Set standout mode to the mode specified for the text to be output. */
624 static void
625 highlight_if_desired ()
627 if (inverse_video)
628 turn_on_highlight ();
629 else
630 turn_off_highlight ();
634 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
635 frame-relative coordinates. */
637 void
638 cursor_to (vpos, hpos)
639 int vpos, hpos;
641 struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame);
643 if (! FRAME_TERMCAP_P (f) && cursor_to_hook)
645 (*cursor_to_hook) (vpos, hpos);
646 return;
649 /* Detect the case where we are called from reset_sys_modes
650 and the costs have never been calculated. Do nothing. */
651 if (! costs_set)
652 return;
654 if (curY == vpos && curX == hpos)
655 return;
656 if (!TF_standout_motion)
657 background_highlight ();
658 if (!TF_insmode_motion)
659 turn_off_insert ();
660 cmgoto (vpos, hpos);
663 /* Similar but don't take any account of the wasted characters. */
665 void
666 raw_cursor_to (row, col)
667 int row, col;
669 struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame);
670 if (! FRAME_TERMCAP_P (f))
672 (*raw_cursor_to_hook) (row, col);
673 return;
675 if (curY == row && curX == col)
676 return;
677 if (!TF_standout_motion)
678 background_highlight ();
679 if (!TF_insmode_motion)
680 turn_off_insert ();
681 cmgoto (row, col);
684 /* Erase operations */
686 /* clear from cursor to end of frame */
687 void
688 clear_to_end ()
690 register int i;
692 if (clear_to_end_hook && ! FRAME_TERMCAP_P (updating_frame))
694 (*clear_to_end_hook) ();
695 return;
697 if (TS_clr_to_bottom)
699 background_highlight ();
700 OUTPUT (TS_clr_to_bottom);
702 else
704 for (i = curY; i < FRAME_LINES (XFRAME (selected_frame)); i++)
706 cursor_to (i, 0);
707 clear_end_of_line (FRAME_COLS (XFRAME (selected_frame)));
712 /* Clear entire frame */
714 void
715 clear_frame ()
717 struct frame *sf = XFRAME (selected_frame);
719 if (clear_frame_hook
720 && ! FRAME_TERMCAP_P ((updating_frame ? updating_frame : sf)))
722 (*clear_frame_hook) ();
723 return;
725 if (TS_clr_frame)
727 background_highlight ();
728 OUTPUT (TS_clr_frame);
729 cmat (0, 0);
731 else
733 cursor_to (0, 0);
734 clear_to_end ();
738 /* Clear from cursor to end of line.
739 Assume that the line is already clear starting at column first_unused_hpos.
741 Note that the cursor may be moved, on terminals lacking a `ce' string. */
743 void
744 clear_end_of_line (first_unused_hpos)
745 int first_unused_hpos;
747 register int i;
749 if (clear_end_of_line_hook
750 && ! FRAME_TERMCAP_P ((updating_frame
751 ? updating_frame
752 : XFRAME (selected_frame))))
754 (*clear_end_of_line_hook) (first_unused_hpos);
755 return;
758 /* Detect the case where we are called from reset_sys_modes
759 and the costs have never been calculated. Do nothing. */
760 if (! costs_set)
761 return;
763 if (curX >= first_unused_hpos)
764 return;
765 background_highlight ();
766 if (TS_clr_line)
768 OUTPUT1 (TS_clr_line);
770 else
771 { /* have to do it the hard way */
772 struct frame *sf = XFRAME (selected_frame);
773 turn_off_insert ();
775 /* Do not write in last row last col with Auto-wrap on. */
776 if (AutoWrap && curY == FRAME_LINES (sf) - 1
777 && first_unused_hpos == FRAME_COLS (sf))
778 first_unused_hpos--;
780 for (i = curX; i < first_unused_hpos; i++)
782 if (termscript)
783 fputc (' ', termscript);
784 putchar (' ');
786 cmplus (first_unused_hpos - curX);
790 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
791 store them at DST. Do not write more than DST_LEN bytes. That may
792 require stopping before all SRC_LEN input glyphs have been
793 converted.
795 We store the number of glyphs actually converted in *CONSUMED. The
796 return value is the number of bytes store in DST. */
799 encode_terminal_code (src, dst, src_len, dst_len, consumed)
800 struct glyph *src;
801 int src_len;
802 unsigned char *dst;
803 int dst_len, *consumed;
805 struct glyph *src_start = src, *src_end = src + src_len;
806 unsigned char *dst_start = dst, *dst_end = dst + dst_len;
807 register GLYPH g;
808 unsigned char workbuf[MAX_MULTIBYTE_LENGTH];
809 const unsigned char *buf;
810 int len;
811 register int tlen = GLYPH_TABLE_LENGTH;
812 register Lisp_Object *tbase = GLYPH_TABLE_BASE;
813 int result;
814 struct coding_system *coding;
816 /* If terminal_coding does any conversion, use it, otherwise use
817 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
818 because it always return 1 if the member src_multibyte is 1. */
819 coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
820 ? &terminal_coding
821 : &safe_terminal_coding);
823 while (src < src_end)
825 /* We must skip glyphs to be padded for a wide character. */
826 if (! CHAR_GLYPH_PADDING_P (*src))
828 g = GLYPH_FROM_CHAR_GLYPH (src[0]);
830 if (g < 0 || g >= tlen)
832 /* This glyph doesn't has an entry in Vglyph_table. */
833 if (! CHAR_VALID_P (src->u.ch, 0))
835 len = 1;
836 buf = " ";
837 coding->src_multibyte = 0;
839 else
841 len = CHAR_STRING (src->u.ch, workbuf);
842 buf = workbuf;
843 coding->src_multibyte = 1;
846 else
848 /* This glyph has an entry in Vglyph_table,
849 so process any alias before testing for simpleness. */
850 GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
852 if (GLYPH_SIMPLE_P (tbase, tlen, g))
854 /* We set the multi-byte form of a character in G
855 (that should be an ASCII character) at
856 WORKBUF. */
857 workbuf[0] = FAST_GLYPH_CHAR (g);
858 len = 1;
859 buf = workbuf;
860 coding->src_multibyte = 0;
862 else
864 /* We have a string in Vglyph_table. */
865 len = GLYPH_LENGTH (tbase, g);
866 buf = GLYPH_STRING (tbase, g);
867 coding->src_multibyte = STRING_MULTIBYTE (tbase[g]);
871 result = encode_coding (coding, buf, dst, len, dst_end - dst);
872 len -= coding->consumed;
873 dst += coding->produced;
874 if (result == CODING_FINISH_INSUFFICIENT_DST
875 || (result == CODING_FINISH_INSUFFICIENT_SRC
876 && len > dst_end - dst))
877 /* The remaining output buffer is too short. We must
878 break the loop here without increasing SRC so that the
879 next call of this function starts from the same glyph. */
880 break;
882 if (len > 0)
884 /* This is the case that a code of the range 0200..0237
885 exists in buf. We must just write out such a code. */
886 buf += coding->consumed;
887 while (len--)
888 *dst++ = *buf++;
891 src++;
894 *consumed = src - src_start;
895 return (dst - dst_start);
899 void
900 write_glyphs (string, len)
901 register struct glyph *string;
902 register int len;
904 int produced, consumed;
905 struct frame *sf = XFRAME (selected_frame);
906 struct frame *f = updating_frame ? updating_frame : sf;
907 unsigned char conversion_buffer[1024];
908 int conversion_buffer_size = sizeof conversion_buffer;
910 if (write_glyphs_hook
911 && ! FRAME_TERMCAP_P (f))
913 (*write_glyphs_hook) (string, len);
914 return;
917 turn_off_insert ();
918 tty_hide_cursor ();
920 /* Don't dare write in last column of bottom line, if Auto-Wrap,
921 since that would scroll the whole frame on some terminals. */
923 if (AutoWrap
924 && curY + 1 == FRAME_LINES (sf)
925 && (curX + len) == FRAME_COLS (sf))
926 len --;
927 if (len <= 0)
928 return;
930 cmplus (len);
932 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
933 the tail. */
934 terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
936 while (len > 0)
938 /* Identify a run of glyphs with the same face. */
939 int face_id = string->face_id;
940 int n;
942 for (n = 1; n < len; ++n)
943 if (string[n].face_id != face_id)
944 break;
946 /* Turn appearance modes of the face of the run on. */
947 highlight_if_desired ();
948 turn_on_face (f, face_id);
950 while (n > 0)
952 /* We use a fixed size (1024 bytes) of conversion buffer.
953 Usually it is sufficient, but if not, we just repeat the
954 loop. */
955 produced = encode_terminal_code (string, conversion_buffer,
956 n, conversion_buffer_size,
957 &consumed);
958 if (produced > 0)
960 fwrite (conversion_buffer, 1, produced, stdout);
961 if (ferror (stdout))
962 clearerr (stdout);
963 if (termscript)
964 fwrite (conversion_buffer, 1, produced, termscript);
966 len -= consumed;
967 n -= consumed;
968 string += consumed;
971 /* Turn appearance modes off. */
972 turn_off_face (f, face_id);
973 turn_off_highlight ();
976 /* We may have to output some codes to terminate the writing. */
977 if (CODING_REQUIRE_FLUSHING (&terminal_coding))
979 terminal_coding.mode |= CODING_MODE_LAST_BLOCK;
980 encode_coding (&terminal_coding, "", conversion_buffer,
981 0, conversion_buffer_size);
982 if (terminal_coding.produced > 0)
984 fwrite (conversion_buffer, 1, terminal_coding.produced, stdout);
985 if (ferror (stdout))
986 clearerr (stdout);
987 if (termscript)
988 fwrite (conversion_buffer, 1, terminal_coding.produced,
989 termscript);
993 cmcheckmagic ();
996 /* If start is zero, insert blanks instead of a string at start */
998 void
999 insert_glyphs (start, len)
1000 register struct glyph *start;
1001 register int len;
1003 char *buf;
1004 struct glyph *glyph = NULL;
1005 struct frame *f, *sf;
1007 if (len <= 0)
1008 return;
1010 if (insert_glyphs_hook)
1012 (*insert_glyphs_hook) (start, len);
1013 return;
1016 sf = XFRAME (selected_frame);
1017 f = updating_frame ? updating_frame : sf;
1019 if (TS_ins_multi_chars)
1021 buf = tparam (TS_ins_multi_chars, 0, 0, len);
1022 OUTPUT1 (buf);
1023 xfree (buf);
1024 if (start)
1025 write_glyphs (start, len);
1026 return;
1029 turn_on_insert ();
1030 cmplus (len);
1031 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
1032 terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
1033 while (len-- > 0)
1035 int produced, consumed;
1036 unsigned char conversion_buffer[1024];
1037 int conversion_buffer_size = sizeof conversion_buffer;
1039 OUTPUT1_IF (TS_ins_char);
1040 if (!start)
1042 conversion_buffer[0] = SPACEGLYPH;
1043 produced = 1;
1045 else
1047 highlight_if_desired ();
1048 turn_on_face (f, start->face_id);
1049 glyph = start;
1050 ++start;
1051 /* We must open sufficient space for a character which
1052 occupies more than one column. */
1053 while (len && CHAR_GLYPH_PADDING_P (*start))
1055 OUTPUT1_IF (TS_ins_char);
1056 start++, len--;
1059 if (len <= 0)
1060 /* This is the last glyph. */
1061 terminal_coding.mode |= CODING_MODE_LAST_BLOCK;
1063 /* The size of conversion buffer (1024 bytes) is surely
1064 sufficient for just one glyph. */
1065 produced = encode_terminal_code (glyph, conversion_buffer, 1,
1066 conversion_buffer_size, &consumed);
1069 if (produced > 0)
1071 fwrite (conversion_buffer, 1, produced, stdout);
1072 if (ferror (stdout))
1073 clearerr (stdout);
1074 if (termscript)
1075 fwrite (conversion_buffer, 1, produced, termscript);
1078 OUTPUT1_IF (TS_pad_inserted_char);
1079 if (start)
1081 turn_off_face (f, glyph->face_id);
1082 turn_off_highlight ();
1086 cmcheckmagic ();
1089 void
1090 delete_glyphs (n)
1091 register int n;
1093 char *buf;
1094 register int i;
1096 if (delete_glyphs_hook && ! FRAME_TERMCAP_P (updating_frame))
1098 (*delete_glyphs_hook) (n);
1099 return;
1102 if (delete_in_insert_mode)
1104 turn_on_insert ();
1106 else
1108 turn_off_insert ();
1109 OUTPUT_IF (TS_delete_mode);
1112 if (TS_del_multi_chars)
1114 buf = tparam (TS_del_multi_chars, 0, 0, n);
1115 OUTPUT1 (buf);
1116 xfree (buf);
1118 else
1119 for (i = 0; i < n; i++)
1120 OUTPUT1 (TS_del_char);
1121 if (!delete_in_insert_mode)
1122 OUTPUT_IF (TS_end_delete_mode);
1125 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1127 void
1128 ins_del_lines (vpos, n)
1129 int vpos, n;
1131 char *multi = n > 0 ? TS_ins_multi_lines : TS_del_multi_lines;
1132 char *single = n > 0 ? TS_ins_line : TS_del_line;
1133 char *scroll = n > 0 ? TS_rev_scroll : TS_fwd_scroll;
1134 struct frame *sf;
1136 register int i = n > 0 ? n : -n;
1137 register char *buf;
1139 if (ins_del_lines_hook && ! FRAME_TERMCAP_P (updating_frame))
1141 (*ins_del_lines_hook) (vpos, n);
1142 return;
1145 sf = XFRAME (selected_frame);
1147 /* If the lines below the insertion are being pushed
1148 into the end of the window, this is the same as clearing;
1149 and we know the lines are already clear, since the matching
1150 deletion has already been done. So can ignore this. */
1151 /* If the lines below the deletion are blank lines coming
1152 out of the end of the window, don't bother,
1153 as there will be a matching inslines later that will flush them. */
1154 if (scroll_region_ok && vpos + i >= specified_window)
1155 return;
1156 if (!memory_below_frame && vpos + i >= FRAME_LINES (sf))
1157 return;
1159 if (multi)
1161 raw_cursor_to (vpos, 0);
1162 background_highlight ();
1163 buf = tparam (multi, 0, 0, i);
1164 OUTPUT (buf);
1165 xfree (buf);
1167 else if (single)
1169 raw_cursor_to (vpos, 0);
1170 background_highlight ();
1171 while (--i >= 0)
1172 OUTPUT (single);
1173 if (TF_teleray)
1174 curX = 0;
1176 else
1178 set_scroll_region (vpos, specified_window);
1179 if (n < 0)
1180 raw_cursor_to (specified_window - 1, 0);
1181 else
1182 raw_cursor_to (vpos, 0);
1183 background_highlight ();
1184 while (--i >= 0)
1185 OUTPUTL (scroll, specified_window - vpos);
1186 set_scroll_region (0, specified_window);
1189 if (!scroll_region_ok && memory_below_frame && n < 0)
1191 cursor_to (FRAME_LINES (sf) + n, 0);
1192 clear_to_end ();
1196 /* Compute cost of sending "str", in characters,
1197 not counting any line-dependent padding. */
1200 string_cost (str)
1201 char *str;
1203 cost = 0;
1204 if (str)
1205 tputs (str, 0, evalcost);
1206 return cost;
1209 /* Compute cost of sending "str", in characters,
1210 counting any line-dependent padding at one line. */
1212 static int
1213 string_cost_one_line (str)
1214 char *str;
1216 cost = 0;
1217 if (str)
1218 tputs (str, 1, evalcost);
1219 return cost;
1222 /* Compute per line amount of line-dependent padding,
1223 in tenths of characters. */
1226 per_line_cost (str)
1227 register char *str;
1229 cost = 0;
1230 if (str)
1231 tputs (str, 0, evalcost);
1232 cost = - cost;
1233 if (str)
1234 tputs (str, 10, evalcost);
1235 return cost;
1238 #ifndef old
1239 /* char_ins_del_cost[n] is cost of inserting N characters.
1240 char_ins_del_cost[-n] is cost of deleting N characters.
1241 The length of this vector is based on max_frame_cols. */
1243 int *char_ins_del_vector;
1245 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1246 #endif
1248 /* ARGSUSED */
1249 static void
1250 calculate_ins_del_char_costs (frame)
1251 FRAME_PTR frame;
1253 int ins_startup_cost, del_startup_cost;
1254 int ins_cost_per_char, del_cost_per_char;
1255 register int i;
1256 register int *p;
1258 if (TS_ins_multi_chars)
1260 ins_cost_per_char = 0;
1261 ins_startup_cost = string_cost_one_line (TS_ins_multi_chars);
1263 else if (TS_ins_char || TS_pad_inserted_char
1264 || (TS_insert_mode && TS_end_insert_mode))
1266 ins_startup_cost = (30 * (string_cost (TS_insert_mode)
1267 + string_cost (TS_end_insert_mode))) / 100;
1268 ins_cost_per_char = (string_cost_one_line (TS_ins_char)
1269 + string_cost_one_line (TS_pad_inserted_char));
1271 else
1273 ins_startup_cost = 9999;
1274 ins_cost_per_char = 0;
1277 if (TS_del_multi_chars)
1279 del_cost_per_char = 0;
1280 del_startup_cost = string_cost_one_line (TS_del_multi_chars);
1282 else if (TS_del_char)
1284 del_startup_cost = (string_cost (TS_delete_mode)
1285 + string_cost (TS_end_delete_mode));
1286 if (delete_in_insert_mode)
1287 del_startup_cost /= 2;
1288 del_cost_per_char = string_cost_one_line (TS_del_char);
1290 else
1292 del_startup_cost = 9999;
1293 del_cost_per_char = 0;
1296 /* Delete costs are at negative offsets */
1297 p = &char_ins_del_cost (frame)[0];
1298 for (i = FRAME_COLS (frame); --i >= 0;)
1299 *--p = (del_startup_cost += del_cost_per_char);
1301 /* Doing nothing is free */
1302 p = &char_ins_del_cost (frame)[0];
1303 *p++ = 0;
1305 /* Insert costs are at positive offsets */
1306 for (i = FRAME_COLS (frame); --i >= 0;)
1307 *p++ = (ins_startup_cost += ins_cost_per_char);
1310 void
1311 calculate_costs (frame)
1312 FRAME_PTR frame;
1314 register char *f = (TS_set_scroll_region
1315 ? TS_set_scroll_region
1316 : TS_set_scroll_region_1);
1318 FRAME_COST_BAUD_RATE (frame) = baud_rate;
1320 scroll_region_cost = string_cost (f);
1322 /* These variables are only used for terminal stuff. They are allocated
1323 once for the terminal frame of X-windows emacs, but not used afterwards.
1325 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1326 X turns off char_ins_del_ok. */
1328 max_frame_lines = max (max_frame_lines, FRAME_LINES (frame));
1329 max_frame_cols = max (max_frame_cols, FRAME_COLS (frame));
1331 costs_set = 1;
1333 if (char_ins_del_vector != 0)
1334 char_ins_del_vector
1335 = (int *) xrealloc (char_ins_del_vector,
1336 (sizeof (int)
1337 + 2 * max_frame_cols * sizeof (int)));
1338 else
1339 char_ins_del_vector
1340 = (int *) xmalloc (sizeof (int)
1341 + 2 * max_frame_cols * sizeof (int));
1343 bzero (char_ins_del_vector, (sizeof (int)
1344 + 2 * max_frame_cols * sizeof (int)));
1346 if (f && (!TS_ins_line && !TS_del_line))
1347 do_line_insertion_deletion_costs (frame,
1348 TS_rev_scroll, TS_ins_multi_lines,
1349 TS_fwd_scroll, TS_del_multi_lines,
1350 f, f, 1);
1351 else
1352 do_line_insertion_deletion_costs (frame,
1353 TS_ins_line, TS_ins_multi_lines,
1354 TS_del_line, TS_del_multi_lines,
1355 0, 0, 1);
1357 calculate_ins_del_char_costs (frame);
1359 /* Don't use TS_repeat if its padding is worse than sending the chars */
1360 if (TS_repeat && per_line_cost (TS_repeat) * baud_rate < 9000)
1361 RPov = string_cost (TS_repeat);
1362 else
1363 RPov = FRAME_COLS (frame) * 2;
1365 cmcostinit (); /* set up cursor motion costs */
1368 struct fkey_table {
1369 char *cap, *name;
1372 /* Termcap capability names that correspond directly to X keysyms.
1373 Some of these (marked "terminfo") aren't supplied by old-style
1374 (Berkeley) termcap entries. They're listed in X keysym order;
1375 except we put the keypad keys first, so that if they clash with
1376 other keys (as on the IBM PC keyboard) they get overridden.
1379 static struct fkey_table keys[] =
1381 {"kh", "home"}, /* termcap */
1382 {"kl", "left"}, /* termcap */
1383 {"ku", "up"}, /* termcap */
1384 {"kr", "right"}, /* termcap */
1385 {"kd", "down"}, /* termcap */
1386 {"%8", "prior"}, /* terminfo */
1387 {"%5", "next"}, /* terminfo */
1388 {"@7", "end"}, /* terminfo */
1389 {"@1", "begin"}, /* terminfo */
1390 {"*6", "select"}, /* terminfo */
1391 {"%9", "print"}, /* terminfo */
1392 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1394 * "insert" --- see below
1396 {"&8", "undo"}, /* terminfo */
1397 {"%0", "redo"}, /* terminfo */
1398 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1399 {"@0", "find"}, /* terminfo */
1400 {"@2", "cancel"}, /* terminfo */
1401 {"%1", "help"}, /* terminfo */
1403 * "break" goes here, but can't be reliably intercepted with termcap
1405 {"&4", "reset"}, /* terminfo --- actually `restart' */
1407 * "system" and "user" --- no termcaps
1409 {"kE", "clearline"}, /* terminfo */
1410 {"kA", "insertline"}, /* terminfo */
1411 {"kL", "deleteline"}, /* terminfo */
1412 {"kI", "insertchar"}, /* terminfo */
1413 {"kD", "deletechar"}, /* terminfo */
1414 {"kB", "backtab"}, /* terminfo */
1416 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1418 {"@8", "kp-enter"}, /* terminfo */
1420 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1421 * "kp-multiply", "kp-add", "kp-separator",
1422 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1423 * --- no termcaps for any of these.
1425 {"K4", "kp-1"}, /* terminfo */
1427 * "kp-2" --- no termcap
1429 {"K5", "kp-3"}, /* terminfo */
1431 * "kp-4" --- no termcap
1433 {"K2", "kp-5"}, /* terminfo */
1435 * "kp-6" --- no termcap
1437 {"K1", "kp-7"}, /* terminfo */
1439 * "kp-8" --- no termcap
1441 {"K3", "kp-9"}, /* terminfo */
1443 * "kp-equal" --- no termcap
1445 {"k1", "f1"},
1446 {"k2", "f2"},
1447 {"k3", "f3"},
1448 {"k4", "f4"},
1449 {"k5", "f5"},
1450 {"k6", "f6"},
1451 {"k7", "f7"},
1452 {"k8", "f8"},
1453 {"k9", "f9"}
1456 static char **term_get_fkeys_arg;
1457 static Lisp_Object term_get_fkeys_1 ();
1459 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1460 This function scans the termcap function key sequence entries, and
1461 adds entries to Vfunction_key_map for each function key it finds. */
1463 void
1464 term_get_fkeys (address)
1465 char **address;
1467 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1468 errors during the call. The only errors should be from Fdefine_key
1469 when given a key sequence containing an invalid prefix key. If the
1470 termcap defines function keys which use a prefix that is already bound
1471 to a command by the default bindings, we should silently ignore that
1472 function key specification, rather than giving the user an error and
1473 refusing to run at all on such a terminal. */
1475 extern Lisp_Object Fidentity ();
1476 term_get_fkeys_arg = address;
1477 internal_condition_case (term_get_fkeys_1, Qerror, Fidentity);
1480 static Lisp_Object
1481 term_get_fkeys_1 ()
1483 int i;
1485 char **address = term_get_fkeys_arg;
1487 /* This can happen if CANNOT_DUMP or with strange options. */
1488 if (!initialized)
1489 Vfunction_key_map = Fmake_sparse_keymap (Qnil);
1491 for (i = 0; i < (sizeof (keys)/sizeof (keys[0])); i++)
1493 char *sequence = tgetstr (keys[i].cap, address);
1494 if (sequence)
1495 Fdefine_key (Vfunction_key_map, build_string (sequence),
1496 Fmake_vector (make_number (1),
1497 intern (keys[i].name)));
1500 /* The uses of the "k0" capability are inconsistent; sometimes it
1501 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1502 We will attempt to politely accommodate both systems by testing for
1503 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1506 char *k_semi = tgetstr ("k;", address);
1507 char *k0 = tgetstr ("k0", address);
1508 char *k0_name = "f10";
1510 if (k_semi)
1512 if (k0)
1513 /* Define f0 first, so that f10 takes precedence in case the
1514 key sequences happens to be the same. */
1515 Fdefine_key (Vfunction_key_map, build_string (k0),
1516 Fmake_vector (make_number (1), intern ("f0")));
1517 Fdefine_key (Vfunction_key_map, build_string (k_semi),
1518 Fmake_vector (make_number (1), intern ("f10")));
1520 else if (k0)
1521 Fdefine_key (Vfunction_key_map, build_string (k0),
1522 Fmake_vector (make_number (1), intern (k0_name)));
1525 /* Set up cookies for numbered function keys above f10. */
1527 char fcap[3], fkey[4];
1529 fcap[0] = 'F'; fcap[2] = '\0';
1530 for (i = 11; i < 64; i++)
1532 if (i <= 19)
1533 fcap[1] = '1' + i - 11;
1534 else if (i <= 45)
1535 fcap[1] = 'A' + i - 20;
1536 else
1537 fcap[1] = 'a' + i - 46;
1540 char *sequence = tgetstr (fcap, address);
1541 if (sequence)
1543 sprintf (fkey, "f%d", i);
1544 Fdefine_key (Vfunction_key_map, build_string (sequence),
1545 Fmake_vector (make_number (1),
1546 intern (fkey)));
1553 * Various mappings to try and get a better fit.
1556 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1557 if (!tgetstr (cap1, address)) \
1559 char *sequence = tgetstr (cap2, address); \
1560 if (sequence) \
1561 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1562 Fmake_vector (make_number (1), \
1563 intern (sym))); \
1566 /* if there's no key_next keycap, map key_npage to `next' keysym */
1567 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1568 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1569 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1570 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1571 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1572 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1573 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1575 /* IBM has their own non-standard dialect of terminfo.
1576 If the standard name isn't found, try the IBM name. */
1577 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1578 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1579 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1580 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1581 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1582 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1583 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1584 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1585 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1586 #undef CONDITIONAL_REASSIGN
1589 return Qnil;
1593 /***********************************************************************
1594 Character Display Information
1595 ***********************************************************************/
1597 static void append_glyph P_ ((struct it *));
1600 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1601 terminal frames if IT->glyph_row != NULL. IT->c is the character
1602 for which to produce glyphs; IT->face_id contains the character's
1603 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1604 1. */
1606 static void
1607 append_glyph (it)
1608 struct it *it;
1610 struct glyph *glyph, *end;
1611 int i;
1613 xassert (it->glyph_row);
1614 glyph = (it->glyph_row->glyphs[it->area]
1615 + it->glyph_row->used[it->area]);
1616 end = it->glyph_row->glyphs[1 + it->area];
1618 for (i = 0;
1619 i < it->pixel_width && glyph < end;
1620 ++i)
1622 glyph->type = CHAR_GLYPH;
1623 glyph->pixel_width = 1;
1624 glyph->u.ch = it->c;
1625 glyph->face_id = it->face_id;
1626 glyph->padding_p = i > 0;
1627 glyph->charpos = CHARPOS (it->position);
1628 glyph->object = it->object;
1630 ++it->glyph_row->used[it->area];
1631 ++glyph;
1636 /* Produce glyphs for the display element described by IT. *IT
1637 specifies what we want to produce a glyph for (character, image, ...),
1638 and where in the glyph matrix we currently are (glyph row and hpos).
1639 produce_glyphs fills in output fields of *IT with information such as the
1640 pixel width and height of a character, and maybe output actual glyphs at
1641 the same time if IT->glyph_row is non-null. See the explanation of
1642 struct display_iterator in dispextern.h for an overview.
1644 produce_glyphs also stores the result of glyph width, ascent
1645 etc. computations in *IT.
1647 IT->glyph_row may be null, in which case produce_glyphs does not
1648 actually fill in the glyphs. This is used in the move_* functions
1649 in xdisp.c for text width and height computations.
1651 Callers usually don't call produce_glyphs directly;
1652 instead they use the macro PRODUCE_GLYPHS. */
1654 void
1655 produce_glyphs (it)
1656 struct it *it;
1658 /* If a hook is installed, let it do the work. */
1659 xassert (it->what == IT_CHARACTER
1660 || it->what == IT_COMPOSITION
1661 || it->what == IT_IMAGE
1662 || it->what == IT_STRETCH);
1664 /* Nothing but characters are supported on terminal frames. For a
1665 composition sequence, it->c is the first character of the
1666 sequence. */
1667 xassert (it->what == IT_CHARACTER
1668 || it->what == IT_COMPOSITION);
1670 if (it->c >= 040 && it->c < 0177)
1672 it->pixel_width = it->nglyphs = 1;
1673 if (it->glyph_row)
1674 append_glyph (it);
1676 else if (it->c == '\n')
1677 it->pixel_width = it->nglyphs = 0;
1678 else if (it->c == '\t')
1680 int absolute_x = (it->current_x
1681 + it->continuation_lines_width);
1682 int next_tab_x
1683 = (((1 + absolute_x + it->tab_width - 1)
1684 / it->tab_width)
1685 * it->tab_width);
1686 int nspaces;
1688 /* If part of the TAB has been displayed on the previous line
1689 which is continued now, continuation_lines_width will have
1690 been incremented already by the part that fitted on the
1691 continued line. So, we will get the right number of spaces
1692 here. */
1693 nspaces = next_tab_x - absolute_x;
1695 if (it->glyph_row)
1697 int n = nspaces;
1699 it->c = ' ';
1700 it->pixel_width = it->len = 1;
1702 while (n--)
1703 append_glyph (it);
1705 it->c = '\t';
1708 it->pixel_width = nspaces;
1709 it->nglyphs = nspaces;
1711 else if (SINGLE_BYTE_CHAR_P (it->c))
1713 /* Coming here means that it->c is from display table, thus we
1714 must send the code as is to the terminal. Although there's
1715 no way to know how many columns it occupies on a screen, it
1716 is a good assumption that a single byte code has 1-column
1717 width. */
1718 it->pixel_width = it->nglyphs = 1;
1719 if (it->glyph_row)
1720 append_glyph (it);
1722 else
1724 /* A multi-byte character. The display width is fixed for all
1725 characters of the set. Some of the glyphs may have to be
1726 ignored because they are already displayed in a continued
1727 line. */
1728 int charset = CHAR_CHARSET (it->c);
1730 it->pixel_width = CHARSET_WIDTH (charset);
1731 it->nglyphs = it->pixel_width;
1733 if (it->glyph_row)
1734 append_glyph (it);
1737 /* Advance current_x by the pixel width as a convenience for
1738 the caller. */
1739 if (it->area == TEXT_AREA)
1740 it->current_x += it->pixel_width;
1741 it->ascent = it->max_ascent = it->phys_ascent = it->max_phys_ascent = 0;
1742 it->descent = it->max_descent = it->phys_descent = it->max_phys_descent = 1;
1746 /* Get information about special display element WHAT in an
1747 environment described by IT. WHAT is one of IT_TRUNCATION or
1748 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1749 non-null glyph_row member. This function ensures that fields like
1750 face_id, c, len of IT are left untouched. */
1752 void
1753 produce_special_glyphs (it, what)
1754 struct it *it;
1755 enum display_element_type what;
1757 struct it temp_it;
1759 temp_it = *it;
1760 temp_it.dp = NULL;
1761 temp_it.what = IT_CHARACTER;
1762 temp_it.len = 1;
1763 temp_it.object = make_number (0);
1764 bzero (&temp_it.current, sizeof temp_it.current);
1766 if (what == IT_CONTINUATION)
1768 /* Continuation glyph. */
1769 if (it->dp
1770 && INTEGERP (DISP_CONTINUE_GLYPH (it->dp))
1771 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it->dp))))
1773 temp_it.c = FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it->dp)));
1774 temp_it.len = CHAR_BYTES (temp_it.c);
1776 else
1777 temp_it.c = '\\';
1779 produce_glyphs (&temp_it);
1780 it->pixel_width = temp_it.pixel_width;
1781 it->nglyphs = temp_it.pixel_width;
1783 else if (what == IT_TRUNCATION)
1785 /* Truncation glyph. */
1786 if (it->dp
1787 && INTEGERP (DISP_TRUNC_GLYPH (it->dp))
1788 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it->dp))))
1790 temp_it.c = FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it->dp)));
1791 temp_it.len = CHAR_BYTES (temp_it.c);
1793 else
1794 temp_it.c = '$';
1796 produce_glyphs (&temp_it);
1797 it->pixel_width = temp_it.pixel_width;
1798 it->nglyphs = temp_it.pixel_width;
1800 else
1801 abort ();
1806 /***********************************************************************
1807 Faces
1808 ***********************************************************************/
1810 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1811 one of the enumerators from enum no_color_bit, or a bit set built
1812 from them. Some display attributes may not be used together with
1813 color; the termcap capability `NC' specifies which ones. */
1815 #define MAY_USE_WITH_COLORS_P(ATTR) \
1816 (TN_max_colors > 0 \
1817 ? (TN_no_color_video & (ATTR)) == 0 \
1818 : 1)
1820 /* Turn appearances of face FACE_ID on tty frame F on. */
1822 static void
1823 turn_on_face (f, face_id)
1824 struct frame *f;
1825 int face_id;
1827 struct face *face = FACE_FROM_ID (f, face_id);
1828 long fg = face->foreground;
1829 long bg = face->background;
1831 /* Do this first because TS_end_standout_mode may be the same
1832 as TS_exit_attribute_mode, which turns all appearances off. */
1833 if (MAY_USE_WITH_COLORS_P (NC_REVERSE))
1835 if (TN_max_colors > 0)
1837 if (fg >= 0 && bg >= 0)
1839 /* If the terminal supports colors, we can set them
1840 below without using reverse video. The face's fg
1841 and bg colors are set as they should appear on
1842 the screen, i.e. they take the inverse-video'ness
1843 of the face already into account. */
1845 else if (inverse_video)
1847 if (fg == FACE_TTY_DEFAULT_FG_COLOR
1848 || bg == FACE_TTY_DEFAULT_BG_COLOR)
1849 toggle_highlight ();
1851 else
1853 if (fg == FACE_TTY_DEFAULT_BG_COLOR
1854 || bg == FACE_TTY_DEFAULT_FG_COLOR)
1855 toggle_highlight ();
1858 else
1860 /* If we can't display colors, use reverse video
1861 if the face specifies that. */
1862 if (inverse_video)
1864 if (fg == FACE_TTY_DEFAULT_FG_COLOR
1865 || bg == FACE_TTY_DEFAULT_BG_COLOR)
1866 toggle_highlight ();
1868 else
1870 if (fg == FACE_TTY_DEFAULT_BG_COLOR
1871 || bg == FACE_TTY_DEFAULT_FG_COLOR)
1872 toggle_highlight ();
1877 if (face->tty_bold_p)
1879 if (MAY_USE_WITH_COLORS_P (NC_BOLD))
1880 OUTPUT1_IF (TS_enter_bold_mode);
1882 else if (face->tty_dim_p)
1883 if (MAY_USE_WITH_COLORS_P (NC_DIM))
1884 OUTPUT1_IF (TS_enter_dim_mode);
1886 /* Alternate charset and blinking not yet used. */
1887 if (face->tty_alt_charset_p
1888 && MAY_USE_WITH_COLORS_P (NC_ALT_CHARSET))
1889 OUTPUT1_IF (TS_enter_alt_charset_mode);
1891 if (face->tty_blinking_p
1892 && MAY_USE_WITH_COLORS_P (NC_BLINK))
1893 OUTPUT1_IF (TS_enter_blink_mode);
1895 if (face->tty_underline_p && MAY_USE_WITH_COLORS_P (NC_UNDERLINE))
1896 OUTPUT1_IF (TS_enter_underline_mode);
1898 if (TN_max_colors > 0)
1900 char *p;
1902 if (fg >= 0 && TS_set_foreground)
1904 p = tparam (TS_set_foreground, NULL, 0, (int) fg);
1905 OUTPUT (p);
1906 xfree (p);
1909 if (bg >= 0 && TS_set_background)
1911 p = tparam (TS_set_background, NULL, 0, (int) bg);
1912 OUTPUT (p);
1913 xfree (p);
1919 /* Turn off appearances of face FACE_ID on tty frame F. */
1921 static void
1922 turn_off_face (f, face_id)
1923 struct frame *f;
1924 int face_id;
1926 struct face *face = FACE_FROM_ID (f, face_id);
1928 xassert (face != NULL);
1930 if (TS_exit_attribute_mode)
1932 /* Capability "me" will turn off appearance modes double-bright,
1933 half-bright, reverse-video, standout, underline. It may or
1934 may not turn off alt-char-mode. */
1935 if (face->tty_bold_p
1936 || face->tty_dim_p
1937 || face->tty_reverse_p
1938 || face->tty_alt_charset_p
1939 || face->tty_blinking_p
1940 || face->tty_underline_p)
1942 OUTPUT1_IF (TS_exit_attribute_mode);
1943 if (strcmp (TS_exit_attribute_mode, TS_end_standout_mode) == 0)
1944 standout_mode = 0;
1947 if (face->tty_alt_charset_p)
1948 OUTPUT_IF (TS_exit_alt_charset_mode);
1950 else
1952 /* If we don't have "me" we can only have those appearances
1953 that have exit sequences defined. */
1954 if (face->tty_alt_charset_p)
1955 OUTPUT_IF (TS_exit_alt_charset_mode);
1957 if (face->tty_underline_p)
1958 OUTPUT_IF (TS_exit_underline_mode);
1961 /* Switch back to default colors. */
1962 if (TN_max_colors > 0
1963 && ((face->foreground != FACE_TTY_DEFAULT_COLOR
1964 && face->foreground != FACE_TTY_DEFAULT_FG_COLOR)
1965 || (face->background != FACE_TTY_DEFAULT_COLOR
1966 && face->background != FACE_TTY_DEFAULT_BG_COLOR)))
1967 OUTPUT1_IF (TS_orig_pair);
1971 /* Return non-zero if the terminal on frame F supports all of the
1972 capabilities in CAPS simultaneously, with foreground and background
1973 colors FG and BG. */
1976 tty_capable_p (f, caps, fg, bg)
1977 struct frame *f;
1978 unsigned caps;
1979 unsigned long fg, bg;
1981 #define TTY_CAPABLE_P_TRY(cap, TS, NC_bit) \
1982 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(NC_bit))) \
1983 return 0;
1985 TTY_CAPABLE_P_TRY (TTY_CAP_INVERSE, TS_standout_mode, NC_REVERSE);
1986 TTY_CAPABLE_P_TRY (TTY_CAP_UNDERLINE, TS_enter_underline_mode, NC_UNDERLINE);
1987 TTY_CAPABLE_P_TRY (TTY_CAP_BOLD, TS_enter_bold_mode, NC_BOLD);
1988 TTY_CAPABLE_P_TRY (TTY_CAP_DIM, TS_enter_dim_mode, NC_DIM);
1989 TTY_CAPABLE_P_TRY (TTY_CAP_BLINK, TS_enter_blink_mode, NC_BLINK);
1990 TTY_CAPABLE_P_TRY (TTY_CAP_ALT_CHARSET, TS_enter_alt_charset_mode, NC_ALT_CHARSET);
1992 /* We can do it! */
1993 return 1;
1997 /* Return non-zero if the terminal is capable to display colors. */
1999 DEFUN ("tty-display-color-p", Ftty_display_color_p, Stty_display_color_p,
2000 0, 1, 0,
2001 doc: /* Return non-nil if TTY can display colors on DISPLAY. */)
2002 (display)
2003 Lisp_Object display;
2005 return TN_max_colors > 0 ? Qt : Qnil;
2008 /* Return the number of supported colors. */
2009 DEFUN ("tty-display-color-cells", Ftty_display_color_cells,
2010 Stty_display_color_cells, 0, 1, 0,
2011 doc: /* Return the number of colors supported by TTY on DISPLAY. */)
2012 (display)
2013 Lisp_Object display;
2015 return make_number (TN_max_colors);
2018 #ifndef WINDOWSNT
2020 /* Save or restore the default color-related capabilities of this
2021 terminal. */
2022 static void
2023 tty_default_color_capabilities (save)
2024 int save;
2026 static char
2027 *default_orig_pair, *default_set_foreground, *default_set_background;
2028 static int default_max_colors, default_max_pairs, default_no_color_video;
2030 if (save)
2032 if (default_orig_pair)
2033 xfree (default_orig_pair);
2034 default_orig_pair = TS_orig_pair ? xstrdup (TS_orig_pair) : NULL;
2036 if (default_set_foreground)
2037 xfree (default_set_foreground);
2038 default_set_foreground = TS_set_foreground ? xstrdup (TS_set_foreground)
2039 : NULL;
2041 if (default_set_background)
2042 xfree (default_set_background);
2043 default_set_background = TS_set_background ? xstrdup (TS_set_background)
2044 : NULL;
2046 default_max_colors = TN_max_colors;
2047 default_max_pairs = TN_max_pairs;
2048 default_no_color_video = TN_no_color_video;
2050 else
2052 TS_orig_pair = default_orig_pair;
2053 TS_set_foreground = default_set_foreground;
2054 TS_set_background = default_set_background;
2055 TN_max_colors = default_max_colors;
2056 TN_max_pairs = default_max_pairs;
2057 TN_no_color_video = default_no_color_video;
2061 /* Setup one of the standard tty color schemes according to MODE.
2062 MODE's value is generally the number of colors which we want to
2063 support; zero means set up for the default capabilities, the ones
2064 we saw at term_init time; -1 means turn off color support. */
2065 void
2066 tty_setup_colors (mode)
2067 int mode;
2069 /* Canonicalize all negative values of MODE. */
2070 if (mode < -1)
2071 mode = -1;
2073 switch (mode)
2075 case -1: /* no colors at all */
2076 TN_max_colors = 0;
2077 TN_max_pairs = 0;
2078 TN_no_color_video = 0;
2079 TS_set_foreground = TS_set_background = TS_orig_pair = NULL;
2080 break;
2081 case 0: /* default colors, if any */
2082 default:
2083 tty_default_color_capabilities (0);
2084 break;
2085 case 8: /* 8 standard ANSI colors */
2086 TS_orig_pair = "\033[0m";
2087 #ifdef TERMINFO
2088 TS_set_foreground = "\033[3%p1%dm";
2089 TS_set_background = "\033[4%p1%dm";
2090 #else
2091 TS_set_foreground = "\033[3%dm";
2092 TS_set_background = "\033[4%dm";
2093 #endif
2094 TN_max_colors = 8;
2095 TN_max_pairs = 64;
2096 TN_no_color_video = 0;
2097 break;
2101 void
2102 set_tty_color_mode (f, val)
2103 struct frame *f;
2104 Lisp_Object val;
2106 Lisp_Object color_mode_spec, current_mode_spec;
2107 Lisp_Object color_mode, current_mode;
2108 int mode, old_mode;
2109 extern Lisp_Object Qtty_color_mode;
2110 Lisp_Object tty_color_mode_alist;
2112 tty_color_mode_alist = Fintern_soft (build_string ("tty-color-mode-alist"),
2113 Qnil);
2115 if (INTEGERP (val))
2116 color_mode = val;
2117 else
2119 if (NILP (tty_color_mode_alist))
2120 color_mode_spec = Qnil;
2121 else
2122 color_mode_spec = Fassq (val, XSYMBOL (tty_color_mode_alist)->value);
2124 if (CONSP (color_mode_spec))
2125 color_mode = XCDR (color_mode_spec);
2126 else
2127 color_mode = Qnil;
2130 current_mode_spec = assq_no_quit (Qtty_color_mode, f->param_alist);
2132 if (CONSP (current_mode_spec))
2133 current_mode = XCDR (current_mode_spec);
2134 else
2135 current_mode = Qnil;
2136 if (INTEGERP (color_mode))
2137 mode = XINT (color_mode);
2138 else
2139 mode = 0; /* meaning default */
2140 if (INTEGERP (current_mode))
2141 old_mode = XINT (current_mode);
2142 else
2143 old_mode = 0;
2145 if (mode != old_mode)
2147 tty_setup_colors (mode);
2148 /* This recomputes all the faces given the new color
2149 definitions. */
2150 call0 (intern ("tty-set-up-initial-frame-faces"));
2151 redraw_frame (f);
2155 #endif /* !WINDOWSNT */
2158 /***********************************************************************
2159 Initialization
2160 ***********************************************************************/
2162 void
2163 term_init (terminal_type)
2164 char *terminal_type;
2166 char *area;
2167 char **address = &area;
2168 char *buffer = NULL;
2169 int buffer_size = 4096;
2170 register char *p;
2171 int status;
2172 struct frame *sf = XFRAME (selected_frame);
2174 #ifdef WINDOWSNT
2175 initialize_w32_display ();
2177 Wcm_clear ();
2179 area = (char *) xmalloc (2044);
2181 FrameRows = FRAME_LINES (sf);
2182 FrameCols = FRAME_COLS (sf);
2183 specified_window = FRAME_LINES (sf);
2185 delete_in_insert_mode = 1;
2187 UseTabs = 0;
2188 scroll_region_ok = 0;
2190 /* Seems to insert lines when it's not supposed to, messing
2191 up the display. In doing a trace, it didn't seem to be
2192 called much, so I don't think we're losing anything by
2193 turning it off. */
2195 line_ins_del_ok = 0;
2196 char_ins_del_ok = 1;
2198 baud_rate = 19200;
2200 FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
2201 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
2202 TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */
2204 return;
2205 #else /* not WINDOWSNT */
2207 Wcm_clear ();
2209 buffer = (char *) xmalloc (buffer_size);
2210 status = tgetent (buffer, terminal_type);
2211 if (status < 0)
2213 #ifdef TERMINFO
2214 fatal ("Cannot open terminfo database file");
2215 #else
2216 fatal ("Cannot open termcap database file");
2217 #endif
2219 if (status == 0)
2221 #ifdef TERMINFO
2222 fatal ("Terminal type %s is not defined.\n\
2223 If that is not the actual type of terminal you have,\n\
2224 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2225 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2226 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2227 terminal_type);
2228 #else
2229 fatal ("Terminal type %s is not defined.\n\
2230 If that is not the actual type of terminal you have,\n\
2231 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2232 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2233 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2234 terminal_type);
2235 #endif
2238 #ifndef TERMINFO
2239 if (strlen (buffer) >= buffer_size)
2240 abort ();
2241 buffer_size = strlen (buffer);
2242 #endif
2243 area = (char *) xmalloc (buffer_size);
2245 TS_ins_line = tgetstr ("al", address);
2246 TS_ins_multi_lines = tgetstr ("AL", address);
2247 TS_bell = tgetstr ("bl", address);
2248 BackTab = tgetstr ("bt", address);
2249 TS_clr_to_bottom = tgetstr ("cd", address);
2250 TS_clr_line = tgetstr ("ce", address);
2251 TS_clr_frame = tgetstr ("cl", address);
2252 ColPosition = NULL; /* tgetstr ("ch", address); */
2253 AbsPosition = tgetstr ("cm", address);
2254 CR = tgetstr ("cr", address);
2255 TS_set_scroll_region = tgetstr ("cs", address);
2256 TS_set_scroll_region_1 = tgetstr ("cS", address);
2257 RowPosition = tgetstr ("cv", address);
2258 TS_del_char = tgetstr ("dc", address);
2259 TS_del_multi_chars = tgetstr ("DC", address);
2260 TS_del_line = tgetstr ("dl", address);
2261 TS_del_multi_lines = tgetstr ("DL", address);
2262 TS_delete_mode = tgetstr ("dm", address);
2263 TS_end_delete_mode = tgetstr ("ed", address);
2264 TS_end_insert_mode = tgetstr ("ei", address);
2265 Home = tgetstr ("ho", address);
2266 TS_ins_char = tgetstr ("ic", address);
2267 TS_ins_multi_chars = tgetstr ("IC", address);
2268 TS_insert_mode = tgetstr ("im", address);
2269 TS_pad_inserted_char = tgetstr ("ip", address);
2270 TS_end_keypad_mode = tgetstr ("ke", address);
2271 TS_keypad_mode = tgetstr ("ks", address);
2272 LastLine = tgetstr ("ll", address);
2273 Right = tgetstr ("nd", address);
2274 Down = tgetstr ("do", address);
2275 if (!Down)
2276 Down = tgetstr ("nl", address); /* Obsolete name for "do" */
2277 #ifdef VMS
2278 /* VMS puts a carriage return before each linefeed,
2279 so it is not safe to use linefeeds. */
2280 if (Down && Down[0] == '\n' && Down[1] == '\0')
2281 Down = 0;
2282 #endif /* VMS */
2283 if (tgetflag ("bs"))
2284 Left = "\b"; /* can't possibly be longer! */
2285 else /* (Actually, "bs" is obsolete...) */
2286 Left = tgetstr ("le", address);
2287 if (!Left)
2288 Left = tgetstr ("bc", address); /* Obsolete name for "le" */
2289 TS_pad_char = tgetstr ("pc", address);
2290 TS_repeat = tgetstr ("rp", address);
2291 TS_end_standout_mode = tgetstr ("se", address);
2292 TS_fwd_scroll = tgetstr ("sf", address);
2293 TS_standout_mode = tgetstr ("so", address);
2294 TS_rev_scroll = tgetstr ("sr", address);
2295 Wcm.cm_tab = tgetstr ("ta", address);
2296 TS_end_termcap_modes = tgetstr ("te", address);
2297 TS_termcap_modes = tgetstr ("ti", address);
2298 Up = tgetstr ("up", address);
2299 TS_visible_bell = tgetstr ("vb", address);
2300 TS_cursor_normal = tgetstr ("ve", address);
2301 TS_cursor_visible = tgetstr ("vs", address);
2302 TS_cursor_invisible = tgetstr ("vi", address);
2303 TS_set_window = tgetstr ("wi", address);
2305 TS_enter_underline_mode = tgetstr ("us", address);
2306 TS_exit_underline_mode = tgetstr ("ue", address);
2307 TS_enter_bold_mode = tgetstr ("md", address);
2308 TS_enter_dim_mode = tgetstr ("mh", address);
2309 TS_enter_blink_mode = tgetstr ("mb", address);
2310 TS_enter_reverse_mode = tgetstr ("mr", address);
2311 TS_enter_alt_charset_mode = tgetstr ("as", address);
2312 TS_exit_alt_charset_mode = tgetstr ("ae", address);
2313 TS_exit_attribute_mode = tgetstr ("me", address);
2315 MultiUp = tgetstr ("UP", address);
2316 MultiDown = tgetstr ("DO", address);
2317 MultiLeft = tgetstr ("LE", address);
2318 MultiRight = tgetstr ("RI", address);
2320 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2321 color because we can't switch back to the default foreground and
2322 background. */
2323 TS_orig_pair = tgetstr ("op", address);
2324 if (TS_orig_pair)
2326 TS_set_foreground = tgetstr ("AF", address);
2327 TS_set_background = tgetstr ("AB", address);
2328 if (!TS_set_foreground)
2330 /* SVr4. */
2331 TS_set_foreground = tgetstr ("Sf", address);
2332 TS_set_background = tgetstr ("Sb", address);
2335 TN_max_colors = tgetnum ("Co");
2336 TN_max_pairs = tgetnum ("pa");
2338 TN_no_color_video = tgetnum ("NC");
2339 if (TN_no_color_video == -1)
2340 TN_no_color_video = 0;
2343 tty_default_color_capabilities (1);
2345 MagicWrap = tgetflag ("xn");
2346 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2347 the former flag imply the latter. */
2348 AutoWrap = MagicWrap || tgetflag ("am");
2349 memory_below_frame = tgetflag ("db");
2350 TF_hazeltine = tgetflag ("hz");
2351 must_write_spaces = tgetflag ("in");
2352 meta_key = tgetflag ("km") || tgetflag ("MT");
2353 TF_insmode_motion = tgetflag ("mi");
2354 TF_standout_motion = tgetflag ("ms");
2355 TF_underscore = tgetflag ("ul");
2356 TF_teleray = tgetflag ("xt");
2358 term_get_fkeys (address);
2360 /* Get frame size from system, or else from termcap. */
2362 int height, width;
2363 get_frame_size (&width, &height);
2364 FRAME_COLS (sf) = width;
2365 FRAME_LINES (sf) = height;
2368 if (FRAME_COLS (sf) <= 0)
2369 SET_FRAME_COLS (sf, tgetnum ("co"));
2370 else
2371 /* Keep width and external_width consistent */
2372 SET_FRAME_COLS (sf, FRAME_COLS (sf));
2373 if (FRAME_LINES (sf) <= 0)
2374 FRAME_LINES (sf) = tgetnum ("li");
2376 if (FRAME_LINES (sf) < 3 || FRAME_COLS (sf) < 3)
2377 fatal ("Screen size %dx%d is too small",
2378 FRAME_LINES (sf), FRAME_COLS (sf));
2380 min_padding_speed = tgetnum ("pb");
2381 TabWidth = tgetnum ("tw");
2383 #ifdef VMS
2384 /* These capabilities commonly use ^J.
2385 I don't know why, but sending them on VMS does not work;
2386 it causes following spaces to be lost, sometimes.
2387 For now, the simplest fix is to avoid using these capabilities ever. */
2388 if (Down && Down[0] == '\n')
2389 Down = 0;
2390 #endif /* VMS */
2392 if (!TS_bell)
2393 TS_bell = "\07";
2395 if (!TS_fwd_scroll)
2396 TS_fwd_scroll = Down;
2398 PC = TS_pad_char ? *TS_pad_char : 0;
2400 if (TabWidth < 0)
2401 TabWidth = 8;
2403 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2404 and newer termcap doc does not seem to say there is a default.
2405 if (!Wcm.cm_tab)
2406 Wcm.cm_tab = "\t";
2409 /* We don't support standout modes that use `magic cookies', so
2410 turn off any that do. */
2411 if (TS_standout_mode && tgetnum ("sg") >= 0)
2413 TS_standout_mode = 0;
2414 TS_end_standout_mode = 0;
2416 if (TS_enter_underline_mode && tgetnum ("ug") >= 0)
2418 TS_enter_underline_mode = 0;
2419 TS_exit_underline_mode = 0;
2422 /* If there's no standout mode, try to use underlining instead. */
2423 if (TS_standout_mode == 0)
2425 TS_standout_mode = TS_enter_underline_mode;
2426 TS_end_standout_mode = TS_exit_underline_mode;
2429 /* If no `se' string, try using a `me' string instead.
2430 If that fails, we can't use standout mode at all. */
2431 if (TS_end_standout_mode == 0)
2433 char *s = tgetstr ("me", address);
2434 if (s != 0)
2435 TS_end_standout_mode = s;
2436 else
2437 TS_standout_mode = 0;
2440 if (TF_teleray)
2442 Wcm.cm_tab = 0;
2443 /* We can't support standout mode, because it uses magic cookies. */
2444 TS_standout_mode = 0;
2445 /* But that means we cannot rely on ^M to go to column zero! */
2446 CR = 0;
2447 /* LF can't be trusted either -- can alter hpos */
2448 /* if move at column 0 thru a line with TS_standout_mode */
2449 Down = 0;
2452 /* Special handling for certain terminal types known to need it */
2454 if (!strcmp (terminal_type, "supdup"))
2456 memory_below_frame = 1;
2457 Wcm.cm_losewrap = 1;
2459 if (!strncmp (terminal_type, "c10", 3)
2460 || !strcmp (terminal_type, "perq"))
2462 /* Supply a makeshift :wi string.
2463 This string is not valid in general since it works only
2464 for windows starting at the upper left corner;
2465 but that is all Emacs uses.
2467 This string works only if the frame is using
2468 the top of the video memory, because addressing is memory-relative.
2469 So first check the :ti string to see if that is true.
2471 It would be simpler if the :wi string could go in the termcap
2472 entry, but it can't because it is not fully valid.
2473 If it were in the termcap entry, it would confuse other programs. */
2474 if (!TS_set_window)
2476 p = TS_termcap_modes;
2477 while (*p && strcmp (p, "\033v "))
2478 p++;
2479 if (*p)
2480 TS_set_window = "\033v%C %C %C %C ";
2482 /* Termcap entry often fails to have :in: flag */
2483 must_write_spaces = 1;
2484 /* :ti string typically fails to have \E^G! in it */
2485 /* This limits scope of insert-char to one line. */
2486 strcpy (area, TS_termcap_modes);
2487 strcat (area, "\033\007!");
2488 TS_termcap_modes = area;
2489 area += strlen (area) + 1;
2490 p = AbsPosition;
2491 /* Change all %+ parameters to %C, to handle
2492 values above 96 correctly for the C100. */
2493 while (*p)
2495 if (p[0] == '%' && p[1] == '+')
2496 p[1] = 'C';
2497 p++;
2501 FrameRows = FRAME_LINES (sf);
2502 FrameCols = FRAME_COLS (sf);
2503 specified_window = FRAME_LINES (sf);
2505 if (Wcm_init () == -1) /* can't do cursor motion */
2506 #ifdef VMS
2507 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2508 It lacks the ability to position the cursor.\n\
2509 If that is not the actual type of terminal you have, use either the\n\
2510 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2511 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2512 terminal_type);
2513 #else /* not VMS */
2514 # ifdef TERMINFO
2515 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2516 It lacks the ability to position the cursor.\n\
2517 If that is not the actual type of terminal you have,\n\
2518 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2519 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2520 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2521 terminal_type);
2522 # else /* TERMCAP */
2523 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2524 It lacks the ability to position the cursor.\n\
2525 If that is not the actual type of terminal you have,\n\
2526 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2527 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2528 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2529 terminal_type);
2530 # endif /* TERMINFO */
2531 #endif /*VMS */
2532 if (FRAME_LINES (sf) <= 0
2533 || FRAME_COLS (sf) <= 0)
2534 fatal ("The frame size has not been specified");
2536 delete_in_insert_mode
2537 = TS_delete_mode && TS_insert_mode
2538 && !strcmp (TS_delete_mode, TS_insert_mode);
2540 se_is_so = (TS_standout_mode
2541 && TS_end_standout_mode
2542 && !strcmp (TS_standout_mode, TS_end_standout_mode));
2544 UseTabs = tabs_safe_p () && TabWidth == 8;
2546 scroll_region_ok
2547 = (Wcm.cm_abs
2548 && (TS_set_window || TS_set_scroll_region || TS_set_scroll_region_1));
2550 line_ins_del_ok = (((TS_ins_line || TS_ins_multi_lines)
2551 && (TS_del_line || TS_del_multi_lines))
2552 || (scroll_region_ok && TS_fwd_scroll && TS_rev_scroll));
2554 char_ins_del_ok = ((TS_ins_char || TS_insert_mode
2555 || TS_pad_inserted_char || TS_ins_multi_chars)
2556 && (TS_del_char || TS_del_multi_chars));
2558 fast_clear_end_of_line = TS_clr_line != 0;
2560 init_baud_rate ();
2561 if (read_socket_hook) /* Baudrate is somewhat */
2562 /* meaningless in this case */
2563 baud_rate = 9600;
2565 FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
2566 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
2567 #endif /* WINDOWSNT */
2569 xfree (buffer);
2572 /* VARARGS 1 */
2573 void
2574 fatal (str, arg1, arg2)
2575 char *str, *arg1, *arg2;
2577 fprintf (stderr, "emacs: ");
2578 fprintf (stderr, str, arg1, arg2);
2579 fprintf (stderr, "\n");
2580 fflush (stderr);
2581 exit (1);
2584 void
2585 syms_of_term ()
2587 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo,
2588 doc: /* Non-nil means the system uses terminfo rather than termcap.
2589 This variable can be used by terminal emulator packages. */);
2590 #ifdef TERMINFO
2591 system_uses_terminfo = 1;
2592 #else
2593 system_uses_terminfo = 0;
2594 #endif
2596 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function,
2597 doc: /* Non-nil means call this function to ring the bell.
2598 The function should accept no arguments. */);
2599 Vring_bell_function = Qnil;
2601 defsubr (&Stty_display_color_p);
2602 defsubr (&Stty_display_color_cells);
2605 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
2606 (do not change this comment) */