(struct skp): New struct, to pass args through map_keymap.
[emacs.git] / src / term.c
blob68f522c506cbaae665ff20db31a8f440fbf68fda
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_HEIGHT (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_HEIGHT (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_width;
368 /* The largest frame height in any call to calculate_costs. */
370 int max_frame_height;
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_height - 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_HEIGHT (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_HEIGHT (sf), start,
527 FRAME_HEIGHT (sf) - stop,
528 FRAME_HEIGHT (sf));
529 else
530 buf = tparam (TS_set_window, 0, 0, start, 0, stop, FRAME_WIDTH (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_HEIGHT (XFRAME (selected_frame)); i++)
706 cursor_to (i, 0);
707 clear_end_of_line (FRAME_WIDTH (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_HEIGHT (sf) - 1
777 && first_unused_hpos == FRAME_WIDTH (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_HEIGHT (sf)
925 && (curX + len) == FRAME_WIDTH (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_HEIGHT (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_HEIGHT (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_width. */
1243 int *char_ins_del_vector;
1245 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH ((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_WIDTH (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_WIDTH (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_height = max (max_frame_height, FRAME_HEIGHT (frame));
1329 max_frame_width = max (max_frame_width, FRAME_WIDTH (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_width * sizeof (int)));
1338 else
1339 char_ins_del_vector
1340 = (int *) xmalloc (sizeof (int)
1341 + 2 * max_frame_width * sizeof (int));
1343 bzero (char_ins_del_vector, (sizeof (int)
1344 + 2 * max_frame_width * 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_WIDTH (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 switch (mode)
2071 case -1: /* no colors at all */
2072 TN_max_colors = 0;
2073 TN_max_pairs = 0;
2074 TN_no_color_video = 0;
2075 TS_set_foreground = TS_set_background = TS_orig_pair = NULL;
2076 break;
2077 case 0: /* default colors, if any */
2078 default:
2079 tty_default_color_capabilities (0);
2080 break;
2081 case 8: /* 8 standard ANSI colors */
2082 TS_orig_pair = "\033[0m";
2083 #ifdef TERMINFO
2084 TS_set_foreground = "\033[3%p1%dm";
2085 TS_set_background = "\033[4%p1%dm";
2086 #else
2087 TS_set_foreground = "\033[3%dm";
2088 TS_set_background = "\033[4%dm";
2089 #endif
2090 TN_max_colors = 8;
2091 TN_max_pairs = 64;
2092 TN_no_color_video = 0;
2093 break;
2097 void
2098 set_tty_color_mode (f, val)
2099 struct frame *f;
2100 Lisp_Object val;
2102 Lisp_Object color_mode_spec, current_mode_spec;
2103 Lisp_Object color_mode, current_mode;
2104 int mode, old_mode;
2105 extern Lisp_Object Qtty_color_mode;
2106 Lisp_Object tty_color_mode_alist;
2108 tty_color_mode_alist = Fintern_soft (build_string ("tty-color-mode-alist"),
2109 Qnil);
2111 if (NATNUMP (val))
2112 color_mode = val;
2113 else
2115 if (NILP (tty_color_mode_alist))
2116 color_mode_spec = Qnil;
2117 else
2118 color_mode_spec = Fassq (val, XSYMBOL (tty_color_mode_alist)->value);
2119 current_mode_spec = assq_no_quit (Qtty_color_mode, f->param_alist);
2121 if (CONSP (color_mode_spec))
2122 color_mode = XCDR (color_mode_spec);
2123 else
2124 color_mode = Qnil;
2126 if (CONSP (current_mode_spec))
2127 current_mode = XCDR (current_mode_spec);
2128 else
2129 current_mode = Qnil;
2130 if (NATNUMP (color_mode))
2131 mode = XINT (color_mode);
2132 else
2133 mode = 0; /* meaning default */
2134 if (NATNUMP (current_mode))
2135 old_mode = XINT (current_mode);
2136 else
2137 old_mode = 0;
2139 if (mode != old_mode)
2141 tty_setup_colors (mode);
2142 /* This recomputes all the faces given the new color
2143 definitions. */
2144 call0 (intern ("tty-set-up-initial-frame-faces"));
2145 redraw_frame (f);
2149 #endif /* !WINDOWSNT */
2152 /***********************************************************************
2153 Initialization
2154 ***********************************************************************/
2156 void
2157 term_init (terminal_type)
2158 char *terminal_type;
2160 char *area;
2161 char **address = &area;
2162 char buffer[2044];
2163 register char *p;
2164 int status;
2165 struct frame *sf = XFRAME (selected_frame);
2167 #ifdef WINDOWSNT
2168 initialize_w32_display ();
2170 Wcm_clear ();
2172 area = (char *) xmalloc (2044);
2174 if (area == 0)
2175 abort ();
2177 FrameRows = FRAME_HEIGHT (sf);
2178 FrameCols = FRAME_WIDTH (sf);
2179 specified_window = FRAME_HEIGHT (sf);
2181 delete_in_insert_mode = 1;
2183 UseTabs = 0;
2184 scroll_region_ok = 0;
2186 /* Seems to insert lines when it's not supposed to, messing
2187 up the display. In doing a trace, it didn't seem to be
2188 called much, so I don't think we're losing anything by
2189 turning it off. */
2191 line_ins_del_ok = 0;
2192 char_ins_del_ok = 1;
2194 baud_rate = 19200;
2196 FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
2197 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
2198 TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */
2200 return;
2201 #else /* not WINDOWSNT */
2203 Wcm_clear ();
2205 status = tgetent (buffer, terminal_type);
2206 if (status < 0)
2208 #ifdef TERMINFO
2209 fatal ("Cannot open terminfo database file");
2210 #else
2211 fatal ("Cannot open termcap database file");
2212 #endif
2214 if (status == 0)
2216 #ifdef TERMINFO
2217 fatal ("Terminal type %s is not defined.\n\
2218 If that is not the actual type of terminal you have,\n\
2219 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2220 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2221 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2222 terminal_type);
2223 #else
2224 fatal ("Terminal type %s is not defined.\n\
2225 If that is not the actual type of terminal you have,\n\
2226 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2227 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2228 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2229 terminal_type);
2230 #endif
2232 #ifdef TERMINFO
2233 area = (char *) xmalloc (2044);
2234 #else
2235 area = (char *) xmalloc (strlen (buffer));
2236 #endif /* not TERMINFO */
2237 if (area == 0)
2238 abort ();
2240 TS_ins_line = tgetstr ("al", address);
2241 TS_ins_multi_lines = tgetstr ("AL", address);
2242 TS_bell = tgetstr ("bl", address);
2243 BackTab = tgetstr ("bt", address);
2244 TS_clr_to_bottom = tgetstr ("cd", address);
2245 TS_clr_line = tgetstr ("ce", address);
2246 TS_clr_frame = tgetstr ("cl", address);
2247 ColPosition = NULL; /* tgetstr ("ch", address); */
2248 AbsPosition = tgetstr ("cm", address);
2249 CR = tgetstr ("cr", address);
2250 TS_set_scroll_region = tgetstr ("cs", address);
2251 TS_set_scroll_region_1 = tgetstr ("cS", address);
2252 RowPosition = tgetstr ("cv", address);
2253 TS_del_char = tgetstr ("dc", address);
2254 TS_del_multi_chars = tgetstr ("DC", address);
2255 TS_del_line = tgetstr ("dl", address);
2256 TS_del_multi_lines = tgetstr ("DL", address);
2257 TS_delete_mode = tgetstr ("dm", address);
2258 TS_end_delete_mode = tgetstr ("ed", address);
2259 TS_end_insert_mode = tgetstr ("ei", address);
2260 Home = tgetstr ("ho", address);
2261 TS_ins_char = tgetstr ("ic", address);
2262 TS_ins_multi_chars = tgetstr ("IC", address);
2263 TS_insert_mode = tgetstr ("im", address);
2264 TS_pad_inserted_char = tgetstr ("ip", address);
2265 TS_end_keypad_mode = tgetstr ("ke", address);
2266 TS_keypad_mode = tgetstr ("ks", address);
2267 LastLine = tgetstr ("ll", address);
2268 Right = tgetstr ("nd", address);
2269 Down = tgetstr ("do", address);
2270 if (!Down)
2271 Down = tgetstr ("nl", address); /* Obsolete name for "do" */
2272 #ifdef VMS
2273 /* VMS puts a carriage return before each linefeed,
2274 so it is not safe to use linefeeds. */
2275 if (Down && Down[0] == '\n' && Down[1] == '\0')
2276 Down = 0;
2277 #endif /* VMS */
2278 if (tgetflag ("bs"))
2279 Left = "\b"; /* can't possibly be longer! */
2280 else /* (Actually, "bs" is obsolete...) */
2281 Left = tgetstr ("le", address);
2282 if (!Left)
2283 Left = tgetstr ("bc", address); /* Obsolete name for "le" */
2284 TS_pad_char = tgetstr ("pc", address);
2285 TS_repeat = tgetstr ("rp", address);
2286 TS_end_standout_mode = tgetstr ("se", address);
2287 TS_fwd_scroll = tgetstr ("sf", address);
2288 TS_standout_mode = tgetstr ("so", address);
2289 TS_rev_scroll = tgetstr ("sr", address);
2290 Wcm.cm_tab = tgetstr ("ta", address);
2291 TS_end_termcap_modes = tgetstr ("te", address);
2292 TS_termcap_modes = tgetstr ("ti", address);
2293 Up = tgetstr ("up", address);
2294 TS_visible_bell = tgetstr ("vb", address);
2295 TS_cursor_normal = tgetstr ("ve", address);
2296 TS_cursor_visible = tgetstr ("vs", address);
2297 TS_cursor_invisible = tgetstr ("vi", address);
2298 TS_set_window = tgetstr ("wi", address);
2300 TS_enter_underline_mode = tgetstr ("us", address);
2301 TS_exit_underline_mode = tgetstr ("ue", address);
2302 TS_enter_bold_mode = tgetstr ("md", address);
2303 TS_enter_dim_mode = tgetstr ("mh", address);
2304 TS_enter_blink_mode = tgetstr ("mb", address);
2305 TS_enter_reverse_mode = tgetstr ("mr", address);
2306 TS_enter_alt_charset_mode = tgetstr ("as", address);
2307 TS_exit_alt_charset_mode = tgetstr ("ae", address);
2308 TS_exit_attribute_mode = tgetstr ("me", address);
2310 MultiUp = tgetstr ("UP", address);
2311 MultiDown = tgetstr ("DO", address);
2312 MultiLeft = tgetstr ("LE", address);
2313 MultiRight = tgetstr ("RI", address);
2315 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2316 color because we can't switch back to the default foreground and
2317 background. */
2318 TS_orig_pair = tgetstr ("op", address);
2319 if (TS_orig_pair)
2321 TS_set_foreground = tgetstr ("AF", address);
2322 TS_set_background = tgetstr ("AB", address);
2323 if (!TS_set_foreground)
2325 /* SVr4. */
2326 TS_set_foreground = tgetstr ("Sf", address);
2327 TS_set_background = tgetstr ("Sb", address);
2330 TN_max_colors = tgetnum ("Co");
2331 TN_max_pairs = tgetnum ("pa");
2333 TN_no_color_video = tgetnum ("NC");
2334 if (TN_no_color_video == -1)
2335 TN_no_color_video = 0;
2338 tty_default_color_capabilities (1);
2340 MagicWrap = tgetflag ("xn");
2341 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2342 the former flag imply the latter. */
2343 AutoWrap = MagicWrap || tgetflag ("am");
2344 memory_below_frame = tgetflag ("db");
2345 TF_hazeltine = tgetflag ("hz");
2346 must_write_spaces = tgetflag ("in");
2347 meta_key = tgetflag ("km") || tgetflag ("MT");
2348 TF_insmode_motion = tgetflag ("mi");
2349 TF_standout_motion = tgetflag ("ms");
2350 TF_underscore = tgetflag ("ul");
2351 TF_teleray = tgetflag ("xt");
2353 term_get_fkeys (address);
2355 /* Get frame size from system, or else from termcap. */
2357 int height, width;
2358 get_frame_size (&width, &height);
2359 FRAME_WIDTH (sf) = width;
2360 FRAME_HEIGHT (sf) = height;
2363 if (FRAME_WIDTH (sf) <= 0)
2364 SET_FRAME_WIDTH (sf, tgetnum ("co"));
2365 else
2366 /* Keep width and external_width consistent */
2367 SET_FRAME_WIDTH (sf, FRAME_WIDTH (sf));
2368 if (FRAME_HEIGHT (sf) <= 0)
2369 FRAME_HEIGHT (sf) = tgetnum ("li");
2371 if (FRAME_HEIGHT (sf) < 3 || FRAME_WIDTH (sf) < 3)
2372 fatal ("Screen size %dx%d is too small",
2373 FRAME_HEIGHT (sf), FRAME_WIDTH (sf));
2375 min_padding_speed = tgetnum ("pb");
2376 TabWidth = tgetnum ("tw");
2378 #ifdef VMS
2379 /* These capabilities commonly use ^J.
2380 I don't know why, but sending them on VMS does not work;
2381 it causes following spaces to be lost, sometimes.
2382 For now, the simplest fix is to avoid using these capabilities ever. */
2383 if (Down && Down[0] == '\n')
2384 Down = 0;
2385 #endif /* VMS */
2387 if (!TS_bell)
2388 TS_bell = "\07";
2390 if (!TS_fwd_scroll)
2391 TS_fwd_scroll = Down;
2393 PC = TS_pad_char ? *TS_pad_char : 0;
2395 if (TabWidth < 0)
2396 TabWidth = 8;
2398 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2399 and newer termcap doc does not seem to say there is a default.
2400 if (!Wcm.cm_tab)
2401 Wcm.cm_tab = "\t";
2404 /* We don't support standout modes that use `magic cookies', so
2405 turn off any that do. */
2406 if (TS_standout_mode && tgetnum ("sg") >= 0)
2408 TS_standout_mode = 0;
2409 TS_end_standout_mode = 0;
2411 if (TS_enter_underline_mode && tgetnum ("ug") >= 0)
2413 TS_enter_underline_mode = 0;
2414 TS_exit_underline_mode = 0;
2417 /* If there's no standout mode, try to use underlining instead. */
2418 if (TS_standout_mode == 0)
2420 TS_standout_mode = TS_enter_underline_mode;
2421 TS_end_standout_mode = TS_exit_underline_mode;
2424 /* If no `se' string, try using a `me' string instead.
2425 If that fails, we can't use standout mode at all. */
2426 if (TS_end_standout_mode == 0)
2428 char *s = tgetstr ("me", address);
2429 if (s != 0)
2430 TS_end_standout_mode = s;
2431 else
2432 TS_standout_mode = 0;
2435 if (TF_teleray)
2437 Wcm.cm_tab = 0;
2438 /* We can't support standout mode, because it uses magic cookies. */
2439 TS_standout_mode = 0;
2440 /* But that means we cannot rely on ^M to go to column zero! */
2441 CR = 0;
2442 /* LF can't be trusted either -- can alter hpos */
2443 /* if move at column 0 thru a line with TS_standout_mode */
2444 Down = 0;
2447 /* Special handling for certain terminal types known to need it */
2449 if (!strcmp (terminal_type, "supdup"))
2451 memory_below_frame = 1;
2452 Wcm.cm_losewrap = 1;
2454 if (!strncmp (terminal_type, "c10", 3)
2455 || !strcmp (terminal_type, "perq"))
2457 /* Supply a makeshift :wi string.
2458 This string is not valid in general since it works only
2459 for windows starting at the upper left corner;
2460 but that is all Emacs uses.
2462 This string works only if the frame is using
2463 the top of the video memory, because addressing is memory-relative.
2464 So first check the :ti string to see if that is true.
2466 It would be simpler if the :wi string could go in the termcap
2467 entry, but it can't because it is not fully valid.
2468 If it were in the termcap entry, it would confuse other programs. */
2469 if (!TS_set_window)
2471 p = TS_termcap_modes;
2472 while (*p && strcmp (p, "\033v "))
2473 p++;
2474 if (*p)
2475 TS_set_window = "\033v%C %C %C %C ";
2477 /* Termcap entry often fails to have :in: flag */
2478 must_write_spaces = 1;
2479 /* :ti string typically fails to have \E^G! in it */
2480 /* This limits scope of insert-char to one line. */
2481 strcpy (area, TS_termcap_modes);
2482 strcat (area, "\033\007!");
2483 TS_termcap_modes = area;
2484 area += strlen (area) + 1;
2485 p = AbsPosition;
2486 /* Change all %+ parameters to %C, to handle
2487 values above 96 correctly for the C100. */
2488 while (*p)
2490 if (p[0] == '%' && p[1] == '+')
2491 p[1] = 'C';
2492 p++;
2496 FrameRows = FRAME_HEIGHT (sf);
2497 FrameCols = FRAME_WIDTH (sf);
2498 specified_window = FRAME_HEIGHT (sf);
2500 if (Wcm_init () == -1) /* can't do cursor motion */
2501 #ifdef VMS
2502 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2503 It lacks the ability to position the cursor.\n\
2504 If that is not the actual type of terminal you have, use either the\n\
2505 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2506 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2507 terminal_type);
2508 #else /* not VMS */
2509 # ifdef TERMINFO
2510 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2511 It lacks the ability to position the cursor.\n\
2512 If that is not the actual type of terminal you have,\n\
2513 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2514 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2515 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2516 terminal_type);
2517 # else /* TERMCAP */
2518 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2519 It lacks the ability to position the cursor.\n\
2520 If that is not the actual type of terminal you have,\n\
2521 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2522 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2523 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2524 terminal_type);
2525 # endif /* TERMINFO */
2526 #endif /*VMS */
2527 if (FRAME_HEIGHT (sf) <= 0
2528 || FRAME_WIDTH (sf) <= 0)
2529 fatal ("The frame size has not been specified");
2531 delete_in_insert_mode
2532 = TS_delete_mode && TS_insert_mode
2533 && !strcmp (TS_delete_mode, TS_insert_mode);
2535 se_is_so = (TS_standout_mode
2536 && TS_end_standout_mode
2537 && !strcmp (TS_standout_mode, TS_end_standout_mode));
2539 UseTabs = tabs_safe_p () && TabWidth == 8;
2541 scroll_region_ok
2542 = (Wcm.cm_abs
2543 && (TS_set_window || TS_set_scroll_region || TS_set_scroll_region_1));
2545 line_ins_del_ok = (((TS_ins_line || TS_ins_multi_lines)
2546 && (TS_del_line || TS_del_multi_lines))
2547 || (scroll_region_ok && TS_fwd_scroll && TS_rev_scroll));
2549 char_ins_del_ok = ((TS_ins_char || TS_insert_mode
2550 || TS_pad_inserted_char || TS_ins_multi_chars)
2551 && (TS_del_char || TS_del_multi_chars));
2553 fast_clear_end_of_line = TS_clr_line != 0;
2555 init_baud_rate ();
2556 if (read_socket_hook) /* Baudrate is somewhat */
2557 /* meaningless in this case */
2558 baud_rate = 9600;
2560 FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
2561 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
2562 #endif /* WINDOWSNT */
2565 /* VARARGS 1 */
2566 void
2567 fatal (str, arg1, arg2)
2568 char *str, *arg1, *arg2;
2570 fprintf (stderr, "emacs: ");
2571 fprintf (stderr, str, arg1, arg2);
2572 fprintf (stderr, "\n");
2573 fflush (stderr);
2574 exit (1);
2577 void
2578 syms_of_term ()
2580 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo,
2581 doc: /* Non-nil means the system uses terminfo rather than termcap.
2582 This variable can be used by terminal emulator packages. */);
2583 #ifdef TERMINFO
2584 system_uses_terminfo = 1;
2585 #else
2586 system_uses_terminfo = 0;
2587 #endif
2589 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function,
2590 doc: /* Non-nil means call this function to ring the bell.
2591 The function should accept no arguments. */);
2592 Vring_bell_function = Qnil;
2594 defsubr (&Stty_display_color_p);
2595 defsubr (&Stty_display_color_cells);