(display-time-mail-face): Replace :group `faces' with `mode-line-faces'.
[emacs.git] / src / term.c
blobe2c2fc39fc5ec6b0fa11a1fc2ddc13e28a3b8622
1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001,
3 2002, 2003, 2004, 2005 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., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, 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 /* Display space properties */
84 extern Lisp_Object Qspace, QCalign_to, QCwidth;
86 /* Function to use to ring the bell. */
88 Lisp_Object Vring_bell_function;
90 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */
92 static int visible_cursor;
94 /* Terminal characteristics that higher levels want to look at.
95 These are all extern'd in termchar.h */
97 int must_write_spaces; /* Nonzero means spaces in the text
98 must actually be output; can't just skip
99 over some columns to leave them blank. */
100 int min_padding_speed; /* Speed below which no padding necessary */
102 int line_ins_del_ok; /* Terminal can insert and delete lines */
103 int char_ins_del_ok; /* Terminal can insert and delete chars */
104 int scroll_region_ok; /* Terminal supports setting the
105 scroll window */
106 int scroll_region_cost; /* Cost of setting a scroll window,
107 measured in characters */
108 int memory_below_frame; /* Terminal remembers lines
109 scrolled off bottom */
110 int fast_clear_end_of_line; /* Terminal has a `ce' string */
112 /* Nonzero means no need to redraw the entire frame on resuming
113 a suspended Emacs. This is useful on terminals with multiple pages,
114 where one page is used for Emacs and another for all else. */
116 int no_redraw_on_reenter;
118 /* Hook functions that you can set to snap out the functions in this file.
119 These are all extern'd in termhooks.h */
121 void (*cursor_to_hook) P_ ((int, int));
122 void (*raw_cursor_to_hook) P_ ((int, int));
123 void (*clear_to_end_hook) P_ ((void));
124 void (*clear_frame_hook) P_ ((void));
125 void (*clear_end_of_line_hook) P_ ((int));
127 void (*ins_del_lines_hook) P_ ((int, int));
129 void (*delete_glyphs_hook) P_ ((int));
131 void (*ring_bell_hook) P_ ((void));
133 void (*reset_terminal_modes_hook) P_ ((void));
134 void (*set_terminal_modes_hook) P_ ((void));
135 void (*update_begin_hook) P_ ((struct frame *));
136 void (*update_end_hook) P_ ((struct frame *));
137 void (*set_terminal_window_hook) P_ ((int));
138 void (*insert_glyphs_hook) P_ ((struct glyph *, int));
139 void (*write_glyphs_hook) P_ ((struct glyph *, int));
140 void (*delete_glyphs_hook) P_ ((int));
142 int (*read_socket_hook) P_ ((int, int, struct input_event *));
144 void (*frame_up_to_date_hook) P_ ((struct frame *));
146 /* Return the current position of the mouse.
148 Set *f to the frame the mouse is in, or zero if the mouse is in no
149 Emacs frame. If it is set to zero, all the other arguments are
150 garbage.
152 If the motion started in a scroll bar, set *bar_window to the
153 scroll bar's window, *part to the part the mouse is currently over,
154 *x to the position of the mouse along the scroll bar, and *y to the
155 overall length of the scroll bar.
157 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
158 row of the character cell the mouse is over.
160 Set *time to the time the mouse was at the returned position.
162 This should clear mouse_moved until the next motion
163 event arrives. */
165 void (*mouse_position_hook) P_ ((FRAME_PTR *f, int insist,
166 Lisp_Object *bar_window,
167 enum scroll_bar_part *part,
168 Lisp_Object *x,
169 Lisp_Object *y,
170 unsigned long *time));
172 /* When reading from a minibuffer in a different frame, Emacs wants
173 to shift the highlight from the selected frame to the mini-buffer's
174 frame; under X, this means it lies about where the focus is.
175 This hook tells the window system code to re-decide where to put
176 the highlight. */
178 void (*frame_rehighlight_hook) P_ ((FRAME_PTR f));
180 /* If we're displaying frames using a window system that can stack
181 frames on top of each other, this hook allows you to bring a frame
182 to the front, or bury it behind all the other windows. If this
183 hook is zero, that means the device we're displaying on doesn't
184 support overlapping frames, so there's no need to raise or lower
185 anything.
187 If RAISE is non-zero, F is brought to the front, before all other
188 windows. If RAISE is zero, F is sent to the back, behind all other
189 windows. */
191 void (*frame_raise_lower_hook) P_ ((FRAME_PTR f, int raise));
193 /* Set the vertical scroll bar for WINDOW to have its upper left corner
194 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
195 indicate that we are displaying PORTION characters out of a total
196 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
197 have a scroll bar, create one for it. */
199 void (*set_vertical_scroll_bar_hook)
200 P_ ((struct window *window,
201 int portion, int whole, int position));
204 /* The following three hooks are used when we're doing a thorough
205 redisplay of the frame. We don't explicitly know which scroll bars
206 are going to be deleted, because keeping track of when windows go
207 away is a real pain - can you say set-window-configuration?
208 Instead, we just assert at the beginning of redisplay that *all*
209 scroll bars are to be removed, and then save scroll bars from the
210 fiery pit when we actually redisplay their window. */
212 /* Arrange for all scroll bars on FRAME to be removed at the next call
213 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
214 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
216 This should be applied to each frame each time its window tree is
217 redisplayed, even if it is not displaying scroll bars at the moment;
218 if the HAS_SCROLL_BARS flag has just been turned off, only calling
219 this and the judge_scroll_bars_hook will get rid of them.
221 If non-zero, this hook should be safe to apply to any frame,
222 whether or not it can support scroll bars, and whether or not it is
223 currently displaying them. */
225 void (*condemn_scroll_bars_hook) P_ ((FRAME_PTR frame));
227 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
228 Note that it's okay to redeem a scroll bar that is not condemned. */
230 void (*redeem_scroll_bar_hook) P_ ((struct window *window));
232 /* Remove all scroll bars on FRAME that haven't been saved since the
233 last call to `*condemn_scroll_bars_hook'.
235 This should be applied to each frame after each time its window
236 tree is redisplayed, even if it is not displaying scroll bars at the
237 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
238 calling this and condemn_scroll_bars_hook will get rid of them.
240 If non-zero, this hook should be safe to apply to any frame,
241 whether or not it can support scroll bars, and whether or not it is
242 currently displaying them. */
244 void (*judge_scroll_bars_hook) P_ ((FRAME_PTR FRAME));
246 /* Strings, numbers and flags taken from the termcap entry. */
248 char *TS_ins_line; /* "al" */
249 char *TS_ins_multi_lines; /* "AL" (one parameter, # lines to insert) */
250 char *TS_bell; /* "bl" */
251 char *TS_clr_to_bottom; /* "cd" */
252 char *TS_clr_line; /* "ce", clear to end of line */
253 char *TS_clr_frame; /* "cl" */
254 char *TS_set_scroll_region; /* "cs" (2 params, first line and last line) */
255 char *TS_set_scroll_region_1; /* "cS" (4 params: total lines,
256 lines above scroll region, lines below it,
257 total lines again) */
258 char *TS_del_char; /* "dc" */
259 char *TS_del_multi_chars; /* "DC" (one parameter, # chars to delete) */
260 char *TS_del_line; /* "dl" */
261 char *TS_del_multi_lines; /* "DL" (one parameter, # lines to delete) */
262 char *TS_delete_mode; /* "dm", enter character-delete mode */
263 char *TS_end_delete_mode; /* "ed", leave character-delete mode */
264 char *TS_end_insert_mode; /* "ei", leave character-insert mode */
265 char *TS_ins_char; /* "ic" */
266 char *TS_ins_multi_chars; /* "IC" (one parameter, # chars to insert) */
267 char *TS_insert_mode; /* "im", enter character-insert mode */
268 char *TS_pad_inserted_char; /* "ip". Just padding, no commands. */
269 char *TS_end_keypad_mode; /* "ke" */
270 char *TS_keypad_mode; /* "ks" */
271 char *TS_pad_char; /* "pc", char to use as padding */
272 char *TS_repeat; /* "rp" (2 params, # times to repeat
273 and character to be repeated) */
274 char *TS_end_standout_mode; /* "se" */
275 char *TS_fwd_scroll; /* "sf" */
276 char *TS_standout_mode; /* "so" */
277 char *TS_rev_scroll; /* "sr" */
278 char *TS_end_termcap_modes; /* "te" */
279 char *TS_termcap_modes; /* "ti" */
280 char *TS_visible_bell; /* "vb" */
281 char *TS_cursor_normal; /* "ve" */
282 char *TS_cursor_visible; /* "vs" */
283 char *TS_cursor_invisible; /* "vi" */
284 char *TS_set_window; /* "wi" (4 params, start and end of window,
285 each as vpos and hpos) */
287 /* Value of the "NC" (no_color_video) capability, or 0 if not
288 present. */
290 static int TN_no_color_video;
292 /* Meaning of bits in no_color_video. Each bit set means that the
293 corresponding attribute cannot be combined with colors. */
295 enum no_color_bit
297 NC_STANDOUT = 1 << 0,
298 NC_UNDERLINE = 1 << 1,
299 NC_REVERSE = 1 << 2,
300 NC_BLINK = 1 << 3,
301 NC_DIM = 1 << 4,
302 NC_BOLD = 1 << 5,
303 NC_INVIS = 1 << 6,
304 NC_PROTECT = 1 << 7,
305 NC_ALT_CHARSET = 1 << 8
308 /* "md" -- turn on bold (extra bright mode). */
310 char *TS_enter_bold_mode;
312 /* "mh" -- turn on half-bright mode. */
314 char *TS_enter_dim_mode;
316 /* "mb" -- enter blinking mode. */
318 char *TS_enter_blink_mode;
320 /* "mr" -- enter reverse video mode. */
322 char *TS_enter_reverse_mode;
324 /* "us"/"ue" -- start/end underlining. */
326 char *TS_exit_underline_mode, *TS_enter_underline_mode;
328 /* "as"/"ae" -- start/end alternate character set. Not really
329 supported, yet. */
331 char *TS_enter_alt_charset_mode, *TS_exit_alt_charset_mode;
333 /* "me" -- switch appearances off. */
335 char *TS_exit_attribute_mode;
337 /* "Co" -- number of colors. */
339 int TN_max_colors;
341 /* "pa" -- max. number of color pairs on screen. Not handled yet.
342 Could be a problem if not equal to TN_max_colors * TN_max_colors. */
344 int TN_max_pairs;
346 /* "op" -- SVr4 set default pair to its original value. */
348 char *TS_orig_pair;
350 /* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
351 1 param, the color index. */
353 char *TS_set_foreground, *TS_set_background;
355 int TF_hazeltine; /* termcap hz flag. */
356 int TF_insmode_motion; /* termcap mi flag: can move while in insert mode. */
357 int TF_standout_motion; /* termcap mi flag: can move while in standout mode. */
358 int TF_underscore; /* termcap ul flag: _ underlines if over-struck on
359 non-blank position. Must clear before writing _. */
360 int TF_teleray; /* termcap xt flag: many weird consequences.
361 For t1061. */
363 static int RPov; /* # chars to start a TS_repeat */
365 static int delete_in_insert_mode; /* delete mode == insert mode */
367 static int se_is_so; /* 1 if same string both enters and leaves
368 standout mode */
370 /* internal state */
372 /* The largest frame width in any call to calculate_costs. */
374 int max_frame_cols;
376 /* The largest frame height in any call to calculate_costs. */
378 int max_frame_lines;
380 static int costs_set; /* Nonzero if costs have been calculated. */
382 int insert_mode; /* Nonzero when in insert mode. */
383 int standout_mode; /* Nonzero when in standout mode. */
385 /* Size of window specified by higher levels.
386 This is the number of lines, from the top of frame downwards,
387 which can participate in insert-line/delete-line operations.
389 Effectively it excludes the bottom frame_lines - specified_window_size
390 lines from those operations. */
392 int specified_window;
394 /* Frame currently being redisplayed; 0 if not currently redisplaying.
395 (Direct output does not count). */
397 FRAME_PTR updating_frame;
399 /* Provided for lisp packages. */
401 static int system_uses_terminfo;
403 /* Flag used in tty_show/hide_cursor. */
405 static int tty_cursor_hidden;
407 char *tparam ();
409 extern char *tgetstr ();
412 #ifdef WINDOWSNT
413 /* We aren't X windows, but we aren't termcap either. This makes me
414 uncertain as to what value to use for frame.output_method. For
415 this file, we'll define FRAME_TERMCAP_P to be zero so that our
416 output hooks get called instead of the termcap functions. Probably
417 the best long-term solution is to define an output_windows_nt... */
419 #undef FRAME_TERMCAP_P
420 #define FRAME_TERMCAP_P(_f_) 0
421 #endif /* WINDOWSNT */
423 void
424 ring_bell ()
426 if (!NILP (Vring_bell_function))
428 Lisp_Object function;
430 /* Temporarily set the global variable to nil
431 so that if we get an error, it stays nil
432 and we don't call it over and over.
434 We don't specbind it, because that would carefully
435 restore the bad value if there's an error
436 and make the loop of errors happen anyway. */
438 function = Vring_bell_function;
439 Vring_bell_function = Qnil;
441 call0 (function);
443 Vring_bell_function = function;
445 else if (!FRAME_TERMCAP_P (XFRAME (selected_frame)))
446 (*ring_bell_hook) ();
447 else
448 OUTPUT (TS_visible_bell && visible_bell ? TS_visible_bell : TS_bell);
451 void
452 set_terminal_modes ()
454 if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
456 if (TS_termcap_modes)
457 OUTPUT (TS_termcap_modes);
458 else
460 /* Output enough newlines to scroll all the old screen contents
461 off the screen, so it won't be overwritten and lost. */
462 int i;
463 for (i = 0; i < FRAME_LINES (XFRAME (selected_frame)); i++)
464 putchar ('\n');
467 OUTPUT_IF (visible_cursor ? TS_cursor_visible : TS_cursor_normal);
468 OUTPUT_IF (TS_keypad_mode);
469 losecursor ();
471 else
472 (*set_terminal_modes_hook) ();
475 void
476 reset_terminal_modes ()
478 if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
480 turn_off_highlight ();
481 turn_off_insert ();
482 OUTPUT_IF (TS_end_keypad_mode);
483 OUTPUT_IF (TS_cursor_normal);
484 OUTPUT_IF (TS_end_termcap_modes);
485 OUTPUT_IF (TS_orig_pair);
486 /* Output raw CR so kernel can track the cursor hpos. */
487 cmputc ('\r');
489 else if (reset_terminal_modes_hook)
490 (*reset_terminal_modes_hook) ();
493 void
494 update_begin (f)
495 struct frame *f;
497 updating_frame = f;
498 if (!FRAME_TERMCAP_P (f))
499 update_begin_hook (f);
502 void
503 update_end (f)
504 struct frame *f;
506 if (FRAME_TERMCAP_P (f))
508 if (!XWINDOW (selected_window)->cursor_off_p)
509 tty_show_cursor ();
510 turn_off_insert ();
511 background_highlight ();
513 else
514 update_end_hook (f);
516 updating_frame = NULL;
519 void
520 set_terminal_window (size)
521 int size;
523 if (FRAME_TERMCAP_P (updating_frame))
525 specified_window = size ? size : FRAME_LINES (updating_frame);
526 if (scroll_region_ok)
527 set_scroll_region (0, specified_window);
529 else
530 set_terminal_window_hook (size);
533 void
534 set_scroll_region (start, stop)
535 int start, stop;
537 char *buf;
538 struct frame *sf = XFRAME (selected_frame);
540 if (TS_set_scroll_region)
541 buf = tparam (TS_set_scroll_region, 0, 0, start, stop - 1);
542 else if (TS_set_scroll_region_1)
543 buf = tparam (TS_set_scroll_region_1, 0, 0,
544 FRAME_LINES (sf), start,
545 FRAME_LINES (sf) - stop,
546 FRAME_LINES (sf));
547 else
548 buf = tparam (TS_set_window, 0, 0, start, 0, stop, FRAME_COLS (sf));
550 OUTPUT (buf);
551 xfree (buf);
552 losecursor ();
556 static void
557 turn_on_insert ()
559 if (!insert_mode)
560 OUTPUT (TS_insert_mode);
561 insert_mode = 1;
564 void
565 turn_off_insert ()
567 if (insert_mode)
568 OUTPUT (TS_end_insert_mode);
569 insert_mode = 0;
572 /* Handle highlighting. */
574 void
575 turn_off_highlight ()
577 if (standout_mode)
578 OUTPUT_IF (TS_end_standout_mode);
579 standout_mode = 0;
582 static void
583 turn_on_highlight ()
585 if (!standout_mode)
586 OUTPUT_IF (TS_standout_mode);
587 standout_mode = 1;
590 static void
591 toggle_highlight ()
593 if (standout_mode)
594 turn_off_highlight ();
595 else
596 turn_on_highlight ();
600 /* Make cursor invisible. */
602 static void
603 tty_hide_cursor ()
605 if (tty_cursor_hidden == 0)
607 tty_cursor_hidden = 1;
608 OUTPUT_IF (TS_cursor_invisible);
613 /* Ensure that cursor is visible. */
615 static void
616 tty_show_cursor ()
618 if (tty_cursor_hidden)
620 tty_cursor_hidden = 0;
621 OUTPUT_IF (TS_cursor_normal);
622 if (visible_cursor)
623 OUTPUT_IF (TS_cursor_visible);
628 /* Set standout mode to the state it should be in for
629 empty space inside windows. What this is,
630 depends on the user option inverse-video. */
632 void
633 background_highlight ()
635 if (inverse_video)
636 turn_on_highlight ();
637 else
638 turn_off_highlight ();
641 /* Set standout mode to the mode specified for the text to be output. */
643 static void
644 highlight_if_desired ()
646 if (inverse_video)
647 turn_on_highlight ();
648 else
649 turn_off_highlight ();
653 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
654 frame-relative coordinates. */
656 void
657 cursor_to (vpos, hpos)
658 int vpos, hpos;
660 struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame);
662 if (! FRAME_TERMCAP_P (f) && cursor_to_hook)
664 (*cursor_to_hook) (vpos, hpos);
665 return;
668 /* Detect the case where we are called from reset_sys_modes
669 and the costs have never been calculated. Do nothing. */
670 if (! costs_set)
671 return;
673 if (curY == vpos && curX == hpos)
674 return;
675 if (!TF_standout_motion)
676 background_highlight ();
677 if (!TF_insmode_motion)
678 turn_off_insert ();
679 cmgoto (vpos, hpos);
682 /* Similar but don't take any account of the wasted characters. */
684 void
685 raw_cursor_to (row, col)
686 int row, col;
688 struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame);
689 if (! FRAME_TERMCAP_P (f))
691 (*raw_cursor_to_hook) (row, col);
692 return;
694 if (curY == row && curX == col)
695 return;
696 if (!TF_standout_motion)
697 background_highlight ();
698 if (!TF_insmode_motion)
699 turn_off_insert ();
700 cmgoto (row, col);
703 /* Erase operations */
705 /* clear from cursor to end of frame */
706 void
707 clear_to_end ()
709 register int i;
711 if (clear_to_end_hook && ! FRAME_TERMCAP_P (updating_frame))
713 (*clear_to_end_hook) ();
714 return;
716 if (TS_clr_to_bottom)
718 background_highlight ();
719 OUTPUT (TS_clr_to_bottom);
721 else
723 for (i = curY; i < FRAME_LINES (XFRAME (selected_frame)); i++)
725 cursor_to (i, 0);
726 clear_end_of_line (FRAME_COLS (XFRAME (selected_frame)));
731 /* Clear entire frame */
733 void
734 clear_frame ()
736 struct frame *sf = XFRAME (selected_frame);
738 if (clear_frame_hook
739 && ! FRAME_TERMCAP_P ((updating_frame ? updating_frame : sf)))
741 (*clear_frame_hook) ();
742 return;
744 if (TS_clr_frame)
746 background_highlight ();
747 OUTPUT (TS_clr_frame);
748 cmat (0, 0);
750 else
752 cursor_to (0, 0);
753 clear_to_end ();
757 /* Clear from cursor to end of line.
758 Assume that the line is already clear starting at column first_unused_hpos.
760 Note that the cursor may be moved, on terminals lacking a `ce' string. */
762 void
763 clear_end_of_line (first_unused_hpos)
764 int first_unused_hpos;
766 register int i;
768 if (clear_end_of_line_hook
769 && ! FRAME_TERMCAP_P ((updating_frame
770 ? updating_frame
771 : XFRAME (selected_frame))))
773 (*clear_end_of_line_hook) (first_unused_hpos);
774 return;
777 /* Detect the case where we are called from reset_sys_modes
778 and the costs have never been calculated. Do nothing. */
779 if (! costs_set)
780 return;
782 if (curX >= first_unused_hpos)
783 return;
784 background_highlight ();
785 if (TS_clr_line)
787 OUTPUT1 (TS_clr_line);
789 else
790 { /* have to do it the hard way */
791 struct frame *sf = XFRAME (selected_frame);
792 turn_off_insert ();
794 /* Do not write in last row last col with Auto-wrap on. */
795 if (AutoWrap && curY == FRAME_LINES (sf) - 1
796 && first_unused_hpos == FRAME_COLS (sf))
797 first_unused_hpos--;
799 for (i = curX; i < first_unused_hpos; i++)
801 if (termscript)
802 fputc (' ', termscript);
803 putchar (' ');
805 cmplus (first_unused_hpos - curX);
809 /* Buffer to store the source and result of code conversion for terminal. */
810 static unsigned char *encode_terminal_buf;
811 /* Allocated size of the above buffer. */
812 static int encode_terminal_bufsize;
814 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
815 Set CODING->produced to the byte-length of the resulting byte
816 sequence, and return a pointer to that byte sequence. */
818 unsigned char *
819 encode_terminal_code (src, src_len, coding)
820 struct glyph *src;
821 int src_len;
822 struct coding_system *coding;
824 struct glyph *src_end = src + src_len;
825 register GLYPH g;
826 unsigned char *buf;
827 int nchars, nbytes, required;
828 register int tlen = GLYPH_TABLE_LENGTH;
829 register Lisp_Object *tbase = GLYPH_TABLE_BASE;
831 /* Allocate sufficient size of buffer to store all characters in
832 multibyte-form. But, it may be enlarged on demand if
833 Vglyph_table contains a string. */
834 required = MAX_MULTIBYTE_LENGTH * src_len;
835 if (encode_terminal_bufsize < required)
837 if (encode_terminal_bufsize == 0)
838 encode_terminal_buf = xmalloc (required);
839 else
840 encode_terminal_buf = xrealloc (encode_terminal_buf, required);
841 encode_terminal_bufsize = required;
844 buf = encode_terminal_buf;
845 nchars = 0;
846 while (src < src_end)
848 /* We must skip glyphs to be padded for a wide character. */
849 if (! CHAR_GLYPH_PADDING_P (*src))
851 g = GLYPH_FROM_CHAR_GLYPH (src[0]);
853 if (g < 0 || g >= tlen)
855 /* This glyph doesn't has an entry in Vglyph_table. */
856 if (CHAR_VALID_P (src->u.ch, 0))
857 buf += CHAR_STRING (src->u.ch, buf);
858 else
859 *buf++ = SPACEGLYPH;
860 nchars++;
862 else
864 /* This glyph has an entry in Vglyph_table,
865 so process any alias before testing for simpleness. */
866 GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
868 if (GLYPH_SIMPLE_P (tbase, tlen, g))
870 int c = FAST_GLYPH_CHAR (g);
872 if (CHAR_VALID_P (c, 0))
873 buf += CHAR_STRING (c, buf);
874 else
875 *buf++ = SPACEGLYPH;
876 nchars++;
878 else
880 /* We have a string in Vglyph_table. */
881 Lisp_Object string;
883 string = tbase[g];
884 if (! STRING_MULTIBYTE (string))
885 string = string_to_multibyte (string);
886 nbytes = buf - encode_terminal_buf;
887 if (encode_terminal_bufsize < nbytes + SBYTES (string))
889 encode_terminal_bufsize = nbytes + SBYTES (string);
890 encode_terminal_buf = xrealloc (encode_terminal_buf,
891 encode_terminal_bufsize);
892 buf = encode_terminal_buf + nbytes;
894 bcopy (SDATA (string), buf, SBYTES (string));
895 buf += SBYTES (string);
896 nchars += SCHARS (string);
900 src++;
903 nbytes = buf - encode_terminal_buf;
904 coding->src_multibyte = 1;
905 coding->dst_multibyte = 0;
906 if (SYMBOLP (coding->pre_write_conversion)
907 && ! NILP (Ffboundp (coding->pre_write_conversion)))
909 run_pre_write_conversin_on_c_str (&encode_terminal_buf,
910 &encode_terminal_bufsize,
911 nchars, nbytes, coding);
912 nchars = coding->produced_char;
913 nbytes = coding->produced;
915 required = nbytes + encoding_buffer_size (coding, nbytes);
916 if (encode_terminal_bufsize < required)
918 encode_terminal_bufsize = required;
919 encode_terminal_buf = xrealloc (encode_terminal_buf, required);
922 encode_coding (coding, encode_terminal_buf, encode_terminal_buf + nbytes,
923 nbytes, encode_terminal_bufsize - nbytes);
924 return encode_terminal_buf + nbytes;
927 void
928 write_glyphs (string, len)
929 register struct glyph *string;
930 register int len;
932 struct frame *sf = XFRAME (selected_frame);
933 struct frame *f = updating_frame ? updating_frame : sf;
934 unsigned char *conversion_buffer;
935 struct coding_system *coding;
937 if (write_glyphs_hook
938 && ! FRAME_TERMCAP_P (f))
940 (*write_glyphs_hook) (string, len);
941 return;
944 turn_off_insert ();
945 tty_hide_cursor ();
947 /* Don't dare write in last column of bottom line, if Auto-Wrap,
948 since that would scroll the whole frame on some terminals. */
950 if (AutoWrap
951 && curY + 1 == FRAME_LINES (sf)
952 && (curX + len) == FRAME_COLS (sf))
953 len --;
954 if (len <= 0)
955 return;
957 cmplus (len);
959 /* If terminal_coding does any conversion, use it, otherwise use
960 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
961 because it always return 1 if the member src_multibyte is 1. */
962 coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
963 ? &terminal_coding : &safe_terminal_coding);
964 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
965 the tail. */
966 coding->mode &= ~CODING_MODE_LAST_BLOCK;
968 while (len > 0)
970 /* Identify a run of glyphs with the same face. */
971 int face_id = string->face_id;
972 int n;
974 for (n = 1; n < len; ++n)
975 if (string[n].face_id != face_id)
976 break;
978 /* Turn appearance modes of the face of the run on. */
979 highlight_if_desired ();
980 turn_on_face (f, face_id);
982 if (n == len)
983 /* This is the last run. */
984 coding->mode |= CODING_MODE_LAST_BLOCK;
985 conversion_buffer = encode_terminal_code (string, n, coding);
986 if (coding->produced > 0)
988 fwrite (conversion_buffer, 1, coding->produced, stdout);
989 if (ferror (stdout))
990 clearerr (stdout);
991 if (termscript)
992 fwrite (conversion_buffer, 1, coding->produced, termscript);
994 len -= n;
995 string += n;
997 /* Turn appearance modes off. */
998 turn_off_face (f, face_id);
999 turn_off_highlight ();
1002 cmcheckmagic ();
1005 /* If start is zero, insert blanks instead of a string at start */
1007 void
1008 insert_glyphs (start, len)
1009 register struct glyph *start;
1010 register int len;
1012 char *buf;
1013 struct glyph *glyph = NULL;
1014 struct frame *f, *sf;
1015 unsigned char *conversion_buffer;
1016 unsigned char space[1];
1017 struct coding_system *coding;
1019 if (len <= 0)
1020 return;
1022 if (insert_glyphs_hook)
1024 (*insert_glyphs_hook) (start, len);
1025 return;
1028 sf = XFRAME (selected_frame);
1029 f = updating_frame ? updating_frame : sf;
1031 if (TS_ins_multi_chars)
1033 buf = tparam (TS_ins_multi_chars, 0, 0, len);
1034 OUTPUT1 (buf);
1035 xfree (buf);
1036 if (start)
1037 write_glyphs (start, len);
1038 return;
1041 turn_on_insert ();
1042 cmplus (len);
1044 if (! start)
1045 space[0] = SPACEGLYPH;
1047 /* If terminal_coding does any conversion, use it, otherwise use
1048 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
1049 because it always return 1 if the member src_multibyte is 1. */
1050 coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
1051 ? &terminal_coding : &safe_terminal_coding);
1052 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1053 the tail. */
1054 coding->mode &= ~CODING_MODE_LAST_BLOCK;
1056 while (len-- > 0)
1058 OUTPUT1_IF (TS_ins_char);
1059 if (!start)
1061 conversion_buffer = space;
1062 coding->produced = 1;
1064 else
1066 highlight_if_desired ();
1067 turn_on_face (f, start->face_id);
1068 glyph = start;
1069 ++start;
1070 /* We must open sufficient space for a character which
1071 occupies more than one column. */
1072 while (len && CHAR_GLYPH_PADDING_P (*start))
1074 OUTPUT1_IF (TS_ins_char);
1075 start++, len--;
1078 if (len <= 0)
1079 /* This is the last glyph. */
1080 coding->mode |= CODING_MODE_LAST_BLOCK;
1082 conversion_buffer = encode_terminal_code (glyph, 1, coding);
1085 if (coding->produced > 0)
1087 fwrite (conversion_buffer, 1, coding->produced, stdout);
1088 if (ferror (stdout))
1089 clearerr (stdout);
1090 if (termscript)
1091 fwrite (conversion_buffer, 1, coding->produced, termscript);
1094 OUTPUT1_IF (TS_pad_inserted_char);
1095 if (start)
1097 turn_off_face (f, glyph->face_id);
1098 turn_off_highlight ();
1102 cmcheckmagic ();
1105 void
1106 delete_glyphs (n)
1107 register int n;
1109 char *buf;
1110 register int i;
1112 if (delete_glyphs_hook && ! FRAME_TERMCAP_P (updating_frame))
1114 (*delete_glyphs_hook) (n);
1115 return;
1118 if (delete_in_insert_mode)
1120 turn_on_insert ();
1122 else
1124 turn_off_insert ();
1125 OUTPUT_IF (TS_delete_mode);
1128 if (TS_del_multi_chars)
1130 buf = tparam (TS_del_multi_chars, 0, 0, n);
1131 OUTPUT1 (buf);
1132 xfree (buf);
1134 else
1135 for (i = 0; i < n; i++)
1136 OUTPUT1 (TS_del_char);
1137 if (!delete_in_insert_mode)
1138 OUTPUT_IF (TS_end_delete_mode);
1141 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1143 void
1144 ins_del_lines (vpos, n)
1145 int vpos, n;
1147 char *multi = n > 0 ? TS_ins_multi_lines : TS_del_multi_lines;
1148 char *single = n > 0 ? TS_ins_line : TS_del_line;
1149 char *scroll = n > 0 ? TS_rev_scroll : TS_fwd_scroll;
1150 struct frame *sf;
1152 register int i = n > 0 ? n : -n;
1153 register char *buf;
1155 if (ins_del_lines_hook && ! FRAME_TERMCAP_P (updating_frame))
1157 (*ins_del_lines_hook) (vpos, n);
1158 return;
1161 sf = XFRAME (selected_frame);
1163 /* If the lines below the insertion are being pushed
1164 into the end of the window, this is the same as clearing;
1165 and we know the lines are already clear, since the matching
1166 deletion has already been done. So can ignore this. */
1167 /* If the lines below the deletion are blank lines coming
1168 out of the end of the window, don't bother,
1169 as there will be a matching inslines later that will flush them. */
1170 if (scroll_region_ok && vpos + i >= specified_window)
1171 return;
1172 if (!memory_below_frame && vpos + i >= FRAME_LINES (sf))
1173 return;
1175 if (multi)
1177 raw_cursor_to (vpos, 0);
1178 background_highlight ();
1179 buf = tparam (multi, 0, 0, i);
1180 OUTPUT (buf);
1181 xfree (buf);
1183 else if (single)
1185 raw_cursor_to (vpos, 0);
1186 background_highlight ();
1187 while (--i >= 0)
1188 OUTPUT (single);
1189 if (TF_teleray)
1190 curX = 0;
1192 else
1194 set_scroll_region (vpos, specified_window);
1195 if (n < 0)
1196 raw_cursor_to (specified_window - 1, 0);
1197 else
1198 raw_cursor_to (vpos, 0);
1199 background_highlight ();
1200 while (--i >= 0)
1201 OUTPUTL (scroll, specified_window - vpos);
1202 set_scroll_region (0, specified_window);
1205 if (!scroll_region_ok && memory_below_frame && n < 0)
1207 cursor_to (FRAME_LINES (sf) + n, 0);
1208 clear_to_end ();
1212 /* Compute cost of sending "str", in characters,
1213 not counting any line-dependent padding. */
1216 string_cost (str)
1217 char *str;
1219 cost = 0;
1220 if (str)
1221 tputs (str, 0, evalcost);
1222 return cost;
1225 /* Compute cost of sending "str", in characters,
1226 counting any line-dependent padding at one line. */
1228 static int
1229 string_cost_one_line (str)
1230 char *str;
1232 cost = 0;
1233 if (str)
1234 tputs (str, 1, evalcost);
1235 return cost;
1238 /* Compute per line amount of line-dependent padding,
1239 in tenths of characters. */
1242 per_line_cost (str)
1243 register char *str;
1245 cost = 0;
1246 if (str)
1247 tputs (str, 0, evalcost);
1248 cost = - cost;
1249 if (str)
1250 tputs (str, 10, evalcost);
1251 return cost;
1254 #ifndef old
1255 /* char_ins_del_cost[n] is cost of inserting N characters.
1256 char_ins_del_cost[-n] is cost of deleting N characters.
1257 The length of this vector is based on max_frame_cols. */
1259 int *char_ins_del_vector;
1261 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1262 #endif
1264 /* ARGSUSED */
1265 static void
1266 calculate_ins_del_char_costs (frame)
1267 FRAME_PTR frame;
1269 int ins_startup_cost, del_startup_cost;
1270 int ins_cost_per_char, del_cost_per_char;
1271 register int i;
1272 register int *p;
1274 if (TS_ins_multi_chars)
1276 ins_cost_per_char = 0;
1277 ins_startup_cost = string_cost_one_line (TS_ins_multi_chars);
1279 else if (TS_ins_char || TS_pad_inserted_char
1280 || (TS_insert_mode && TS_end_insert_mode))
1282 ins_startup_cost = (30 * (string_cost (TS_insert_mode)
1283 + string_cost (TS_end_insert_mode))) / 100;
1284 ins_cost_per_char = (string_cost_one_line (TS_ins_char)
1285 + string_cost_one_line (TS_pad_inserted_char));
1287 else
1289 ins_startup_cost = 9999;
1290 ins_cost_per_char = 0;
1293 if (TS_del_multi_chars)
1295 del_cost_per_char = 0;
1296 del_startup_cost = string_cost_one_line (TS_del_multi_chars);
1298 else if (TS_del_char)
1300 del_startup_cost = (string_cost (TS_delete_mode)
1301 + string_cost (TS_end_delete_mode));
1302 if (delete_in_insert_mode)
1303 del_startup_cost /= 2;
1304 del_cost_per_char = string_cost_one_line (TS_del_char);
1306 else
1308 del_startup_cost = 9999;
1309 del_cost_per_char = 0;
1312 /* Delete costs are at negative offsets */
1313 p = &char_ins_del_cost (frame)[0];
1314 for (i = FRAME_COLS (frame); --i >= 0;)
1315 *--p = (del_startup_cost += del_cost_per_char);
1317 /* Doing nothing is free */
1318 p = &char_ins_del_cost (frame)[0];
1319 *p++ = 0;
1321 /* Insert costs are at positive offsets */
1322 for (i = FRAME_COLS (frame); --i >= 0;)
1323 *p++ = (ins_startup_cost += ins_cost_per_char);
1326 void
1327 calculate_costs (frame)
1328 FRAME_PTR frame;
1330 register char *f = (TS_set_scroll_region
1331 ? TS_set_scroll_region
1332 : TS_set_scroll_region_1);
1334 FRAME_COST_BAUD_RATE (frame) = baud_rate;
1336 scroll_region_cost = string_cost (f);
1338 /* These variables are only used for terminal stuff. They are allocated
1339 once for the terminal frame of X-windows emacs, but not used afterwards.
1341 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1342 X turns off char_ins_del_ok. */
1344 max_frame_lines = max (max_frame_lines, FRAME_LINES (frame));
1345 max_frame_cols = max (max_frame_cols, FRAME_COLS (frame));
1347 costs_set = 1;
1349 if (char_ins_del_vector != 0)
1350 char_ins_del_vector
1351 = (int *) xrealloc (char_ins_del_vector,
1352 (sizeof (int)
1353 + 2 * max_frame_cols * sizeof (int)));
1354 else
1355 char_ins_del_vector
1356 = (int *) xmalloc (sizeof (int)
1357 + 2 * max_frame_cols * sizeof (int));
1359 bzero (char_ins_del_vector, (sizeof (int)
1360 + 2 * max_frame_cols * sizeof (int)));
1362 if (f && (!TS_ins_line && !TS_del_line))
1363 do_line_insertion_deletion_costs (frame,
1364 TS_rev_scroll, TS_ins_multi_lines,
1365 TS_fwd_scroll, TS_del_multi_lines,
1366 f, f, 1);
1367 else
1368 do_line_insertion_deletion_costs (frame,
1369 TS_ins_line, TS_ins_multi_lines,
1370 TS_del_line, TS_del_multi_lines,
1371 0, 0, 1);
1373 calculate_ins_del_char_costs (frame);
1375 /* Don't use TS_repeat if its padding is worse than sending the chars */
1376 if (TS_repeat && per_line_cost (TS_repeat) * baud_rate < 9000)
1377 RPov = string_cost (TS_repeat);
1378 else
1379 RPov = FRAME_COLS (frame) * 2;
1381 cmcostinit (); /* set up cursor motion costs */
1384 struct fkey_table {
1385 char *cap, *name;
1388 /* Termcap capability names that correspond directly to X keysyms.
1389 Some of these (marked "terminfo") aren't supplied by old-style
1390 (Berkeley) termcap entries. They're listed in X keysym order;
1391 except we put the keypad keys first, so that if they clash with
1392 other keys (as on the IBM PC keyboard) they get overridden.
1395 static struct fkey_table keys[] =
1397 {"kh", "home"}, /* termcap */
1398 {"kl", "left"}, /* termcap */
1399 {"ku", "up"}, /* termcap */
1400 {"kr", "right"}, /* termcap */
1401 {"kd", "down"}, /* termcap */
1402 {"%8", "prior"}, /* terminfo */
1403 {"%5", "next"}, /* terminfo */
1404 {"@7", "end"}, /* terminfo */
1405 {"@1", "begin"}, /* terminfo */
1406 {"*6", "select"}, /* terminfo */
1407 {"%9", "print"}, /* terminfo */
1408 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1410 * "insert" --- see below
1412 {"&8", "undo"}, /* terminfo */
1413 {"%0", "redo"}, /* terminfo */
1414 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1415 {"@0", "find"}, /* terminfo */
1416 {"@2", "cancel"}, /* terminfo */
1417 {"%1", "help"}, /* terminfo */
1419 * "break" goes here, but can't be reliably intercepted with termcap
1421 {"&4", "reset"}, /* terminfo --- actually `restart' */
1423 * "system" and "user" --- no termcaps
1425 {"kE", "clearline"}, /* terminfo */
1426 {"kA", "insertline"}, /* terminfo */
1427 {"kL", "deleteline"}, /* terminfo */
1428 {"kI", "insertchar"}, /* terminfo */
1429 {"kD", "deletechar"}, /* terminfo */
1430 {"kB", "backtab"}, /* terminfo */
1432 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1434 {"@8", "kp-enter"}, /* terminfo */
1436 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1437 * "kp-multiply", "kp-add", "kp-separator",
1438 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1439 * --- no termcaps for any of these.
1441 {"K4", "kp-1"}, /* terminfo */
1443 * "kp-2" --- no termcap
1445 {"K5", "kp-3"}, /* terminfo */
1447 * "kp-4" --- no termcap
1449 {"K2", "kp-5"}, /* terminfo */
1451 * "kp-6" --- no termcap
1453 {"K1", "kp-7"}, /* terminfo */
1455 * "kp-8" --- no termcap
1457 {"K3", "kp-9"}, /* terminfo */
1459 * "kp-equal" --- no termcap
1461 {"k1", "f1"},
1462 {"k2", "f2"},
1463 {"k3", "f3"},
1464 {"k4", "f4"},
1465 {"k5", "f5"},
1466 {"k6", "f6"},
1467 {"k7", "f7"},
1468 {"k8", "f8"},
1469 {"k9", "f9"},
1471 {"&0", "S-cancel"}, /*shifted cancel key*/
1472 {"&9", "S-begin"}, /*shifted begin key*/
1473 {"*0", "S-find"}, /*shifted find key*/
1474 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1475 {"*4", "S-delete"}, /*shifted delete-character key*/
1476 {"*7", "S-end"}, /*shifted end key*/
1477 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1478 {"#1", "S-help"}, /*shifted help key*/
1479 {"#2", "S-home"}, /*shifted home key*/
1480 {"#3", "S-insert"}, /*shifted insert-character key*/
1481 {"#4", "S-left"}, /*shifted left-arrow key*/
1482 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1483 {"%c", "S-next"}, /*shifted next key*/
1484 {"%e", "S-prior"}, /*shifted previous key*/
1485 {"%f", "S-print"}, /*shifted print key*/
1486 {"%g", "S-redo"}, /*shifted redo key*/
1487 {"%i", "S-right"}, /*shifted right-arrow key*/
1488 {"!3", "S-undo"} /*shifted undo key*/
1491 static char **term_get_fkeys_arg;
1492 static Lisp_Object term_get_fkeys_1 ();
1494 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1495 This function scans the termcap function key sequence entries, and
1496 adds entries to Vfunction_key_map for each function key it finds. */
1498 void
1499 term_get_fkeys (address)
1500 char **address;
1502 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1503 errors during the call. The only errors should be from Fdefine_key
1504 when given a key sequence containing an invalid prefix key. If the
1505 termcap defines function keys which use a prefix that is already bound
1506 to a command by the default bindings, we should silently ignore that
1507 function key specification, rather than giving the user an error and
1508 refusing to run at all on such a terminal. */
1510 extern Lisp_Object Fidentity ();
1511 term_get_fkeys_arg = address;
1512 internal_condition_case (term_get_fkeys_1, Qerror, Fidentity);
1515 static Lisp_Object
1516 term_get_fkeys_1 ()
1518 int i;
1520 char **address = term_get_fkeys_arg;
1522 /* This can happen if CANNOT_DUMP or with strange options. */
1523 if (!initialized)
1524 Vfunction_key_map = Fmake_sparse_keymap (Qnil);
1526 for (i = 0; i < (sizeof (keys)/sizeof (keys[0])); i++)
1528 char *sequence = tgetstr (keys[i].cap, address);
1529 if (sequence)
1530 Fdefine_key (Vfunction_key_map, build_string (sequence),
1531 Fmake_vector (make_number (1),
1532 intern (keys[i].name)));
1535 /* The uses of the "k0" capability are inconsistent; sometimes it
1536 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1537 We will attempt to politely accommodate both systems by testing for
1538 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1541 char *k_semi = tgetstr ("k;", address);
1542 char *k0 = tgetstr ("k0", address);
1543 char *k0_name = "f10";
1545 if (k_semi)
1547 if (k0)
1548 /* Define f0 first, so that f10 takes precedence in case the
1549 key sequences happens to be the same. */
1550 Fdefine_key (Vfunction_key_map, build_string (k0),
1551 Fmake_vector (make_number (1), intern ("f0")));
1552 Fdefine_key (Vfunction_key_map, build_string (k_semi),
1553 Fmake_vector (make_number (1), intern ("f10")));
1555 else if (k0)
1556 Fdefine_key (Vfunction_key_map, build_string (k0),
1557 Fmake_vector (make_number (1), intern (k0_name)));
1560 /* Set up cookies for numbered function keys above f10. */
1562 char fcap[3], fkey[4];
1564 fcap[0] = 'F'; fcap[2] = '\0';
1565 for (i = 11; i < 64; i++)
1567 if (i <= 19)
1568 fcap[1] = '1' + i - 11;
1569 else if (i <= 45)
1570 fcap[1] = 'A' + i - 20;
1571 else
1572 fcap[1] = 'a' + i - 46;
1575 char *sequence = tgetstr (fcap, address);
1576 if (sequence)
1578 sprintf (fkey, "f%d", i);
1579 Fdefine_key (Vfunction_key_map, build_string (sequence),
1580 Fmake_vector (make_number (1),
1581 intern (fkey)));
1588 * Various mappings to try and get a better fit.
1591 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1592 if (!tgetstr (cap1, address)) \
1594 char *sequence = tgetstr (cap2, address); \
1595 if (sequence) \
1596 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1597 Fmake_vector (make_number (1), \
1598 intern (sym))); \
1601 /* if there's no key_next keycap, map key_npage to `next' keysym */
1602 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1603 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1604 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1605 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1606 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1607 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1608 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1610 /* IBM has their own non-standard dialect of terminfo.
1611 If the standard name isn't found, try the IBM name. */
1612 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1613 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1614 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1615 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1616 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1617 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1618 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1619 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1620 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1621 #undef CONDITIONAL_REASSIGN
1624 return Qnil;
1628 /***********************************************************************
1629 Character Display Information
1630 ***********************************************************************/
1632 static void append_glyph P_ ((struct it *));
1633 static void produce_stretch_glyph P_ ((struct it *));
1636 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1637 terminal frames if IT->glyph_row != NULL. IT->c is the character
1638 for which to produce glyphs; IT->face_id contains the character's
1639 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1640 1. */
1642 static void
1643 append_glyph (it)
1644 struct it *it;
1646 struct glyph *glyph, *end;
1647 int i;
1649 xassert (it->glyph_row);
1650 glyph = (it->glyph_row->glyphs[it->area]
1651 + it->glyph_row->used[it->area]);
1652 end = it->glyph_row->glyphs[1 + it->area];
1654 for (i = 0;
1655 i < it->pixel_width && glyph < end;
1656 ++i)
1658 glyph->type = CHAR_GLYPH;
1659 glyph->pixel_width = 1;
1660 glyph->u.ch = it->c;
1661 glyph->face_id = it->face_id;
1662 glyph->padding_p = i > 0;
1663 glyph->charpos = CHARPOS (it->position);
1664 glyph->object = it->object;
1666 ++it->glyph_row->used[it->area];
1667 ++glyph;
1672 /* Produce glyphs for the display element described by IT. *IT
1673 specifies what we want to produce a glyph for (character, image, ...),
1674 and where in the glyph matrix we currently are (glyph row and hpos).
1675 produce_glyphs fills in output fields of *IT with information such as the
1676 pixel width and height of a character, and maybe output actual glyphs at
1677 the same time if IT->glyph_row is non-null. See the explanation of
1678 struct display_iterator in dispextern.h for an overview.
1680 produce_glyphs also stores the result of glyph width, ascent
1681 etc. computations in *IT.
1683 IT->glyph_row may be null, in which case produce_glyphs does not
1684 actually fill in the glyphs. This is used in the move_* functions
1685 in xdisp.c for text width and height computations.
1687 Callers usually don't call produce_glyphs directly;
1688 instead they use the macro PRODUCE_GLYPHS. */
1690 void
1691 produce_glyphs (it)
1692 struct it *it;
1694 /* If a hook is installed, let it do the work. */
1695 xassert (it->what == IT_CHARACTER
1696 || it->what == IT_COMPOSITION
1697 || it->what == IT_STRETCH);
1699 if (it->what == IT_STRETCH)
1701 produce_stretch_glyph (it);
1702 goto done;
1705 /* Nothing but characters are supported on terminal frames. For a
1706 composition sequence, it->c is the first character of the
1707 sequence. */
1708 xassert (it->what == IT_CHARACTER
1709 || it->what == IT_COMPOSITION);
1711 if (it->c >= 040 && it->c < 0177)
1713 it->pixel_width = it->nglyphs = 1;
1714 if (it->glyph_row)
1715 append_glyph (it);
1717 else if (it->c == '\n')
1718 it->pixel_width = it->nglyphs = 0;
1719 else if (it->c == '\t')
1721 int absolute_x = (it->current_x
1722 + it->continuation_lines_width);
1723 int next_tab_x
1724 = (((1 + absolute_x + it->tab_width - 1)
1725 / it->tab_width)
1726 * it->tab_width);
1727 int nspaces;
1729 /* If part of the TAB has been displayed on the previous line
1730 which is continued now, continuation_lines_width will have
1731 been incremented already by the part that fitted on the
1732 continued line. So, we will get the right number of spaces
1733 here. */
1734 nspaces = next_tab_x - absolute_x;
1736 if (it->glyph_row)
1738 int n = nspaces;
1740 it->c = ' ';
1741 it->pixel_width = it->len = 1;
1743 while (n--)
1744 append_glyph (it);
1746 it->c = '\t';
1749 it->pixel_width = nspaces;
1750 it->nglyphs = nspaces;
1752 else if (SINGLE_BYTE_CHAR_P (it->c))
1754 /* Coming here means that it->c is from display table, thus we
1755 must send the code as is to the terminal. Although there's
1756 no way to know how many columns it occupies on a screen, it
1757 is a good assumption that a single byte code has 1-column
1758 width. */
1759 it->pixel_width = it->nglyphs = 1;
1760 if (it->glyph_row)
1761 append_glyph (it);
1763 else
1765 /* A multi-byte character. The display width is fixed for all
1766 characters of the set. Some of the glyphs may have to be
1767 ignored because they are already displayed in a continued
1768 line. */
1769 int charset = CHAR_CHARSET (it->c);
1771 it->pixel_width = CHARSET_WIDTH (charset);
1772 it->nglyphs = it->pixel_width;
1774 if (it->glyph_row)
1775 append_glyph (it);
1778 done:
1779 /* Advance current_x by the pixel width as a convenience for
1780 the caller. */
1781 if (it->area == TEXT_AREA)
1782 it->current_x += it->pixel_width;
1783 it->ascent = it->max_ascent = it->phys_ascent = it->max_phys_ascent = 0;
1784 it->descent = it->max_descent = it->phys_descent = it->max_phys_descent = 1;
1788 /* Produce a stretch glyph for iterator IT. IT->object is the value
1789 of the glyph property displayed. The value must be a list
1790 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1791 being recognized:
1793 1. `:width WIDTH' specifies that the space should be WIDTH *
1794 canonical char width wide. WIDTH may be an integer or floating
1795 point number.
1797 2. `:align-to HPOS' specifies that the space should be wide enough
1798 to reach HPOS, a value in canonical character units. */
1800 static void
1801 produce_stretch_glyph (it)
1802 struct it *it;
1804 /* (space :width WIDTH ...) */
1805 Lisp_Object prop, plist;
1806 int width = 0, align_to = -1;
1807 int zero_width_ok_p = 0;
1808 double tem;
1810 /* List should start with `space'. */
1811 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
1812 plist = XCDR (it->object);
1814 /* Compute the width of the stretch. */
1815 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
1816 && calc_pixel_width_or_height (&tem, it, prop, 0, 1, 0))
1818 /* Absolute width `:width WIDTH' specified and valid. */
1819 zero_width_ok_p = 1;
1820 width = (int)(tem + 0.5);
1822 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
1823 && calc_pixel_width_or_height (&tem, it, prop, 0, 1, &align_to))
1825 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
1826 align_to = (align_to < 0
1828 : align_to - window_box_left_offset (it->w, TEXT_AREA));
1829 else if (align_to < 0)
1830 align_to = window_box_left_offset (it->w, TEXT_AREA);
1831 width = max (0, (int)(tem + 0.5) + align_to - it->current_x);
1832 zero_width_ok_p = 1;
1834 else
1835 /* Nothing specified -> width defaults to canonical char width. */
1836 width = FRAME_COLUMN_WIDTH (it->f);
1838 if (width <= 0 && (width < 0 || !zero_width_ok_p))
1839 width = 1;
1841 if (width > 0 && it->glyph_row)
1843 Lisp_Object o_object = it->object;
1844 Lisp_Object object = it->stack[it->sp - 1].string;
1845 int n = width;
1846 int c = it->c;
1848 if (!STRINGP (object))
1849 object = it->w->buffer;
1850 it->object = object;
1851 it->c = ' ';
1852 it->pixel_width = it->len = 1;
1853 while (n--)
1854 append_glyph (it);
1855 it->object = o_object;
1856 it->c = c;
1858 it->pixel_width = width;
1859 it->nglyphs = width;
1863 /* Get information about special display element WHAT in an
1864 environment described by IT. WHAT is one of IT_TRUNCATION or
1865 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1866 non-null glyph_row member. This function ensures that fields like
1867 face_id, c, len of IT are left untouched. */
1869 void
1870 produce_special_glyphs (it, what)
1871 struct it *it;
1872 enum display_element_type what;
1874 struct it temp_it;
1875 GLYPH glyph;
1877 temp_it = *it;
1878 temp_it.dp = NULL;
1879 temp_it.what = IT_CHARACTER;
1880 temp_it.len = 1;
1881 temp_it.object = make_number (0);
1882 bzero (&temp_it.current, sizeof temp_it.current);
1884 if (what == IT_CONTINUATION)
1886 /* Continuation glyph. */
1887 if (it->dp
1888 && INTEGERP (DISP_CONTINUE_GLYPH (it->dp))
1889 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it->dp))))
1891 glyph = XINT (DISP_CONTINUE_GLYPH (it->dp));
1892 glyph = spec_glyph_lookup_face (XWINDOW (it->window), glyph);
1894 else
1895 glyph = '\\';
1897 else if (what == IT_TRUNCATION)
1899 /* Truncation glyph. */
1900 if (it->dp
1901 && INTEGERP (DISP_TRUNC_GLYPH (it->dp))
1902 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it->dp))))
1904 glyph = XINT (DISP_TRUNC_GLYPH (it->dp));
1905 glyph = spec_glyph_lookup_face (XWINDOW (it->window), glyph);
1907 else
1908 glyph = '$';
1910 else
1911 abort ();
1913 temp_it.c = FAST_GLYPH_CHAR (glyph);
1914 temp_it.face_id = FAST_GLYPH_FACE (glyph);
1915 temp_it.len = CHAR_BYTES (temp_it.c);
1917 produce_glyphs (&temp_it);
1918 it->pixel_width = temp_it.pixel_width;
1919 it->nglyphs = temp_it.pixel_width;
1924 /***********************************************************************
1925 Faces
1926 ***********************************************************************/
1928 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1929 one of the enumerators from enum no_color_bit, or a bit set built
1930 from them. Some display attributes may not be used together with
1931 color; the termcap capability `NC' specifies which ones. */
1933 #define MAY_USE_WITH_COLORS_P(ATTR) \
1934 (TN_max_colors > 0 \
1935 ? (TN_no_color_video & (ATTR)) == 0 \
1936 : 1)
1938 /* Turn appearances of face FACE_ID on tty frame F on.
1939 FACE_ID is a realized face ID number, in the face cache. */
1941 static void
1942 turn_on_face (f, face_id)
1943 struct frame *f;
1944 int face_id;
1946 struct face *face = FACE_FROM_ID (f, face_id);
1947 long fg = face->foreground;
1948 long bg = face->background;
1950 /* Do this first because TS_end_standout_mode may be the same
1951 as TS_exit_attribute_mode, which turns all appearances off. */
1952 if (MAY_USE_WITH_COLORS_P (NC_REVERSE))
1954 if (TN_max_colors > 0)
1956 if (fg >= 0 && bg >= 0)
1958 /* If the terminal supports colors, we can set them
1959 below without using reverse video. The face's fg
1960 and bg colors are set as they should appear on
1961 the screen, i.e. they take the inverse-video'ness
1962 of the face already into account. */
1964 else if (inverse_video)
1966 if (fg == FACE_TTY_DEFAULT_FG_COLOR
1967 || bg == FACE_TTY_DEFAULT_BG_COLOR)
1968 toggle_highlight ();
1970 else
1972 if (fg == FACE_TTY_DEFAULT_BG_COLOR
1973 || bg == FACE_TTY_DEFAULT_FG_COLOR)
1974 toggle_highlight ();
1977 else
1979 /* If we can't display colors, use reverse video
1980 if the face specifies that. */
1981 if (inverse_video)
1983 if (fg == FACE_TTY_DEFAULT_FG_COLOR
1984 || bg == FACE_TTY_DEFAULT_BG_COLOR)
1985 toggle_highlight ();
1987 else
1989 if (fg == FACE_TTY_DEFAULT_BG_COLOR
1990 || bg == FACE_TTY_DEFAULT_FG_COLOR)
1991 toggle_highlight ();
1996 if (face->tty_bold_p)
1998 if (MAY_USE_WITH_COLORS_P (NC_BOLD))
1999 OUTPUT1_IF (TS_enter_bold_mode);
2001 else if (face->tty_dim_p)
2002 if (MAY_USE_WITH_COLORS_P (NC_DIM))
2003 OUTPUT1_IF (TS_enter_dim_mode);
2005 /* Alternate charset and blinking not yet used. */
2006 if (face->tty_alt_charset_p
2007 && MAY_USE_WITH_COLORS_P (NC_ALT_CHARSET))
2008 OUTPUT1_IF (TS_enter_alt_charset_mode);
2010 if (face->tty_blinking_p
2011 && MAY_USE_WITH_COLORS_P (NC_BLINK))
2012 OUTPUT1_IF (TS_enter_blink_mode);
2014 if (face->tty_underline_p && MAY_USE_WITH_COLORS_P (NC_UNDERLINE))
2015 OUTPUT1_IF (TS_enter_underline_mode);
2017 if (TN_max_colors > 0)
2019 char *ts, *p;
2021 ts = standout_mode ? TS_set_background : TS_set_foreground;
2022 if (fg >= 0 && ts)
2024 p = tparam (ts, NULL, 0, (int) fg);
2025 OUTPUT (p);
2026 xfree (p);
2029 ts = standout_mode ? TS_set_foreground : TS_set_background;
2030 if (bg >= 0 && ts)
2032 p = tparam (ts, NULL, 0, (int) bg);
2033 OUTPUT (p);
2034 xfree (p);
2040 /* Turn off appearances of face FACE_ID on tty frame F. */
2042 static void
2043 turn_off_face (f, face_id)
2044 struct frame *f;
2045 int face_id;
2047 struct face *face = FACE_FROM_ID (f, face_id);
2049 xassert (face != NULL);
2051 if (TS_exit_attribute_mode)
2053 /* Capability "me" will turn off appearance modes double-bright,
2054 half-bright, reverse-video, standout, underline. It may or
2055 may not turn off alt-char-mode. */
2056 if (face->tty_bold_p
2057 || face->tty_dim_p
2058 || face->tty_reverse_p
2059 || face->tty_alt_charset_p
2060 || face->tty_blinking_p
2061 || face->tty_underline_p)
2063 OUTPUT1_IF (TS_exit_attribute_mode);
2064 if (strcmp (TS_exit_attribute_mode, TS_end_standout_mode) == 0)
2065 standout_mode = 0;
2068 if (face->tty_alt_charset_p)
2069 OUTPUT_IF (TS_exit_alt_charset_mode);
2071 else
2073 /* If we don't have "me" we can only have those appearances
2074 that have exit sequences defined. */
2075 if (face->tty_alt_charset_p)
2076 OUTPUT_IF (TS_exit_alt_charset_mode);
2078 if (face->tty_underline_p)
2079 OUTPUT_IF (TS_exit_underline_mode);
2082 /* Switch back to default colors. */
2083 if (TN_max_colors > 0
2084 && ((face->foreground != FACE_TTY_DEFAULT_COLOR
2085 && face->foreground != FACE_TTY_DEFAULT_FG_COLOR)
2086 || (face->background != FACE_TTY_DEFAULT_COLOR
2087 && face->background != FACE_TTY_DEFAULT_BG_COLOR)))
2088 OUTPUT1_IF (TS_orig_pair);
2092 /* Return non-zero if the terminal on frame F supports all of the
2093 capabilities in CAPS simultaneously, with foreground and background
2094 colors FG and BG. */
2097 tty_capable_p (f, caps, fg, bg)
2098 struct frame *f;
2099 unsigned caps;
2100 unsigned long fg, bg;
2102 #define TTY_CAPABLE_P_TRY(cap, TS, NC_bit) \
2103 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(NC_bit))) \
2104 return 0;
2106 TTY_CAPABLE_P_TRY (TTY_CAP_INVERSE, TS_standout_mode, NC_REVERSE);
2107 TTY_CAPABLE_P_TRY (TTY_CAP_UNDERLINE, TS_enter_underline_mode, NC_UNDERLINE);
2108 TTY_CAPABLE_P_TRY (TTY_CAP_BOLD, TS_enter_bold_mode, NC_BOLD);
2109 TTY_CAPABLE_P_TRY (TTY_CAP_DIM, TS_enter_dim_mode, NC_DIM);
2110 TTY_CAPABLE_P_TRY (TTY_CAP_BLINK, TS_enter_blink_mode, NC_BLINK);
2111 TTY_CAPABLE_P_TRY (TTY_CAP_ALT_CHARSET, TS_enter_alt_charset_mode, NC_ALT_CHARSET);
2113 /* We can do it! */
2114 return 1;
2118 /* Return non-zero if the terminal is capable to display colors. */
2120 DEFUN ("tty-display-color-p", Ftty_display_color_p, Stty_display_color_p,
2121 0, 1, 0,
2122 doc: /* Return non-nil if TTY can display colors on DISPLAY. */)
2123 (display)
2124 Lisp_Object display;
2126 return TN_max_colors > 0 ? Qt : Qnil;
2129 /* Return the number of supported colors. */
2130 DEFUN ("tty-display-color-cells", Ftty_display_color_cells,
2131 Stty_display_color_cells, 0, 1, 0,
2132 doc: /* Return the number of colors supported by TTY on DISPLAY. */)
2133 (display)
2134 Lisp_Object display;
2136 return make_number (TN_max_colors);
2139 #ifndef WINDOWSNT
2141 /* Save or restore the default color-related capabilities of this
2142 terminal. */
2143 static void
2144 tty_default_color_capabilities (save)
2145 int save;
2147 static char
2148 *default_orig_pair, *default_set_foreground, *default_set_background;
2149 static int default_max_colors, default_max_pairs, default_no_color_video;
2151 if (save)
2153 if (default_orig_pair)
2154 xfree (default_orig_pair);
2155 default_orig_pair = TS_orig_pair ? xstrdup (TS_orig_pair) : NULL;
2157 if (default_set_foreground)
2158 xfree (default_set_foreground);
2159 default_set_foreground = TS_set_foreground ? xstrdup (TS_set_foreground)
2160 : NULL;
2162 if (default_set_background)
2163 xfree (default_set_background);
2164 default_set_background = TS_set_background ? xstrdup (TS_set_background)
2165 : NULL;
2167 default_max_colors = TN_max_colors;
2168 default_max_pairs = TN_max_pairs;
2169 default_no_color_video = TN_no_color_video;
2171 else
2173 TS_orig_pair = default_orig_pair;
2174 TS_set_foreground = default_set_foreground;
2175 TS_set_background = default_set_background;
2176 TN_max_colors = default_max_colors;
2177 TN_max_pairs = default_max_pairs;
2178 TN_no_color_video = default_no_color_video;
2182 /* Setup one of the standard tty color schemes according to MODE.
2183 MODE's value is generally the number of colors which we want to
2184 support; zero means set up for the default capabilities, the ones
2185 we saw at term_init time; -1 means turn off color support. */
2186 void
2187 tty_setup_colors (mode)
2188 int mode;
2190 /* Canonicalize all negative values of MODE. */
2191 if (mode < -1)
2192 mode = -1;
2194 switch (mode)
2196 case -1: /* no colors at all */
2197 TN_max_colors = 0;
2198 TN_max_pairs = 0;
2199 TN_no_color_video = 0;
2200 TS_set_foreground = TS_set_background = TS_orig_pair = NULL;
2201 break;
2202 case 0: /* default colors, if any */
2203 default:
2204 tty_default_color_capabilities (0);
2205 break;
2206 case 8: /* 8 standard ANSI colors */
2207 TS_orig_pair = "\033[0m";
2208 #ifdef TERMINFO
2209 TS_set_foreground = "\033[3%p1%dm";
2210 TS_set_background = "\033[4%p1%dm";
2211 #else
2212 TS_set_foreground = "\033[3%dm";
2213 TS_set_background = "\033[4%dm";
2214 #endif
2215 TN_max_colors = 8;
2216 TN_max_pairs = 64;
2217 TN_no_color_video = 0;
2218 break;
2222 void
2223 set_tty_color_mode (f, val)
2224 struct frame *f;
2225 Lisp_Object val;
2227 Lisp_Object color_mode_spec, current_mode_spec;
2228 Lisp_Object color_mode, current_mode;
2229 int mode, old_mode;
2230 extern Lisp_Object Qtty_color_mode;
2231 Lisp_Object tty_color_mode_alist;
2233 tty_color_mode_alist = Fintern_soft (build_string ("tty-color-mode-alist"),
2234 Qnil);
2236 if (INTEGERP (val))
2237 color_mode = val;
2238 else
2240 if (NILP (tty_color_mode_alist))
2241 color_mode_spec = Qnil;
2242 else
2243 color_mode_spec = Fassq (val, XSYMBOL (tty_color_mode_alist)->value);
2245 if (CONSP (color_mode_spec))
2246 color_mode = XCDR (color_mode_spec);
2247 else
2248 color_mode = Qnil;
2251 current_mode_spec = assq_no_quit (Qtty_color_mode, f->param_alist);
2253 if (CONSP (current_mode_spec))
2254 current_mode = XCDR (current_mode_spec);
2255 else
2256 current_mode = Qnil;
2257 if (INTEGERP (color_mode))
2258 mode = XINT (color_mode);
2259 else
2260 mode = 0; /* meaning default */
2261 if (INTEGERP (current_mode))
2262 old_mode = XINT (current_mode);
2263 else
2264 old_mode = 0;
2266 if (mode != old_mode)
2268 tty_setup_colors (mode);
2269 /* This recomputes all the faces given the new color
2270 definitions. */
2271 call0 (intern ("tty-set-up-initial-frame-faces"));
2272 redraw_frame (f);
2276 #endif /* !WINDOWSNT */
2279 /***********************************************************************
2280 Initialization
2281 ***********************************************************************/
2283 void
2284 term_init (terminal_type)
2285 char *terminal_type;
2287 char *area;
2288 char **address = &area;
2289 char *buffer = NULL;
2290 int buffer_size = 4096;
2291 register char *p;
2292 int status;
2293 struct frame *sf = XFRAME (selected_frame);
2295 encode_terminal_bufsize = 0;
2297 #ifdef WINDOWSNT
2298 initialize_w32_display ();
2300 Wcm_clear ();
2302 area = (char *) xmalloc (2044);
2304 FrameRows = FRAME_LINES (sf);
2305 FrameCols = FRAME_COLS (sf);
2306 specified_window = FRAME_LINES (sf);
2308 delete_in_insert_mode = 1;
2310 UseTabs = 0;
2311 scroll_region_ok = 0;
2313 /* Seems to insert lines when it's not supposed to, messing
2314 up the display. In doing a trace, it didn't seem to be
2315 called much, so I don't think we're losing anything by
2316 turning it off. */
2318 line_ins_del_ok = 0;
2319 char_ins_del_ok = 1;
2321 baud_rate = 19200;
2323 FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
2324 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
2325 TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */
2327 return;
2328 #else /* not WINDOWSNT */
2330 Wcm_clear ();
2332 buffer = (char *) xmalloc (buffer_size);
2333 status = tgetent (buffer, terminal_type);
2334 if (status < 0)
2336 #ifdef TERMINFO
2337 fatal ("Cannot open terminfo database file");
2338 #else
2339 fatal ("Cannot open termcap database file");
2340 #endif
2342 if (status == 0)
2344 #ifdef TERMINFO
2345 fatal ("Terminal type %s is not defined.\n\
2346 If that is not the actual type of terminal you have,\n\
2347 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2348 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2349 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2350 terminal_type);
2351 #else
2352 fatal ("Terminal type %s is not defined.\n\
2353 If that is not the actual type of terminal you have,\n\
2354 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2355 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2356 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2357 terminal_type);
2358 #endif
2361 #ifndef TERMINFO
2362 if (strlen (buffer) >= buffer_size)
2363 abort ();
2364 buffer_size = strlen (buffer);
2365 #endif
2366 area = (char *) xmalloc (buffer_size);
2368 TS_ins_line = tgetstr ("al", address);
2369 TS_ins_multi_lines = tgetstr ("AL", address);
2370 TS_bell = tgetstr ("bl", address);
2371 BackTab = tgetstr ("bt", address);
2372 TS_clr_to_bottom = tgetstr ("cd", address);
2373 TS_clr_line = tgetstr ("ce", address);
2374 TS_clr_frame = tgetstr ("cl", address);
2375 ColPosition = NULL; /* tgetstr ("ch", address); */
2376 AbsPosition = tgetstr ("cm", address);
2377 CR = tgetstr ("cr", address);
2378 TS_set_scroll_region = tgetstr ("cs", address);
2379 TS_set_scroll_region_1 = tgetstr ("cS", address);
2380 RowPosition = tgetstr ("cv", address);
2381 TS_del_char = tgetstr ("dc", address);
2382 TS_del_multi_chars = tgetstr ("DC", address);
2383 TS_del_line = tgetstr ("dl", address);
2384 TS_del_multi_lines = tgetstr ("DL", address);
2385 TS_delete_mode = tgetstr ("dm", address);
2386 TS_end_delete_mode = tgetstr ("ed", address);
2387 TS_end_insert_mode = tgetstr ("ei", address);
2388 Home = tgetstr ("ho", address);
2389 TS_ins_char = tgetstr ("ic", address);
2390 TS_ins_multi_chars = tgetstr ("IC", address);
2391 TS_insert_mode = tgetstr ("im", address);
2392 TS_pad_inserted_char = tgetstr ("ip", address);
2393 TS_end_keypad_mode = tgetstr ("ke", address);
2394 TS_keypad_mode = tgetstr ("ks", address);
2395 LastLine = tgetstr ("ll", address);
2396 Right = tgetstr ("nd", address);
2397 Down = tgetstr ("do", address);
2398 if (!Down)
2399 Down = tgetstr ("nl", address); /* Obsolete name for "do" */
2400 #ifdef VMS
2401 /* VMS puts a carriage return before each linefeed,
2402 so it is not safe to use linefeeds. */
2403 if (Down && Down[0] == '\n' && Down[1] == '\0')
2404 Down = 0;
2405 #endif /* VMS */
2406 if (tgetflag ("bs"))
2407 Left = "\b"; /* can't possibly be longer! */
2408 else /* (Actually, "bs" is obsolete...) */
2409 Left = tgetstr ("le", address);
2410 if (!Left)
2411 Left = tgetstr ("bc", address); /* Obsolete name for "le" */
2412 TS_pad_char = tgetstr ("pc", address);
2413 TS_repeat = tgetstr ("rp", address);
2414 TS_end_standout_mode = tgetstr ("se", address);
2415 TS_fwd_scroll = tgetstr ("sf", address);
2416 TS_standout_mode = tgetstr ("so", address);
2417 TS_rev_scroll = tgetstr ("sr", address);
2418 Wcm.cm_tab = tgetstr ("ta", address);
2419 TS_end_termcap_modes = tgetstr ("te", address);
2420 TS_termcap_modes = tgetstr ("ti", address);
2421 Up = tgetstr ("up", address);
2422 TS_visible_bell = tgetstr ("vb", address);
2423 TS_cursor_normal = tgetstr ("ve", address);
2424 TS_cursor_visible = tgetstr ("vs", address);
2425 TS_cursor_invisible = tgetstr ("vi", address);
2426 TS_set_window = tgetstr ("wi", address);
2428 TS_enter_underline_mode = tgetstr ("us", address);
2429 TS_exit_underline_mode = tgetstr ("ue", address);
2430 TS_enter_bold_mode = tgetstr ("md", address);
2431 TS_enter_dim_mode = tgetstr ("mh", address);
2432 TS_enter_blink_mode = tgetstr ("mb", address);
2433 TS_enter_reverse_mode = tgetstr ("mr", address);
2434 TS_enter_alt_charset_mode = tgetstr ("as", address);
2435 TS_exit_alt_charset_mode = tgetstr ("ae", address);
2436 TS_exit_attribute_mode = tgetstr ("me", address);
2438 MultiUp = tgetstr ("UP", address);
2439 MultiDown = tgetstr ("DO", address);
2440 MultiLeft = tgetstr ("LE", address);
2441 MultiRight = tgetstr ("RI", address);
2443 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2444 color because we can't switch back to the default foreground and
2445 background. */
2446 TS_orig_pair = tgetstr ("op", address);
2447 if (TS_orig_pair)
2449 TS_set_foreground = tgetstr ("AF", address);
2450 TS_set_background = tgetstr ("AB", address);
2451 if (!TS_set_foreground)
2453 /* SVr4. */
2454 TS_set_foreground = tgetstr ("Sf", address);
2455 TS_set_background = tgetstr ("Sb", address);
2458 TN_max_colors = tgetnum ("Co");
2459 TN_max_pairs = tgetnum ("pa");
2461 TN_no_color_video = tgetnum ("NC");
2462 if (TN_no_color_video == -1)
2463 TN_no_color_video = 0;
2466 tty_default_color_capabilities (1);
2468 MagicWrap = tgetflag ("xn");
2469 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2470 the former flag imply the latter. */
2471 AutoWrap = MagicWrap || tgetflag ("am");
2472 memory_below_frame = tgetflag ("db");
2473 TF_hazeltine = tgetflag ("hz");
2474 must_write_spaces = tgetflag ("in");
2475 meta_key = tgetflag ("km") || tgetflag ("MT");
2476 TF_insmode_motion = tgetflag ("mi");
2477 TF_standout_motion = tgetflag ("ms");
2478 TF_underscore = tgetflag ("ul");
2479 TF_teleray = tgetflag ("xt");
2481 term_get_fkeys (address);
2483 /* Get frame size from system, or else from termcap. */
2485 int height, width;
2486 get_frame_size (&width, &height);
2487 FRAME_COLS (sf) = width;
2488 FRAME_LINES (sf) = height;
2491 if (FRAME_COLS (sf) <= 0)
2492 SET_FRAME_COLS (sf, tgetnum ("co"));
2493 else
2494 /* Keep width and external_width consistent */
2495 SET_FRAME_COLS (sf, FRAME_COLS (sf));
2496 if (FRAME_LINES (sf) <= 0)
2497 FRAME_LINES (sf) = tgetnum ("li");
2499 if (FRAME_LINES (sf) < 3 || FRAME_COLS (sf) < 3)
2500 fatal ("Screen size %dx%d is too small",
2501 FRAME_LINES (sf), FRAME_COLS (sf));
2503 min_padding_speed = tgetnum ("pb");
2504 TabWidth = tgetnum ("tw");
2506 #ifdef VMS
2507 /* These capabilities commonly use ^J.
2508 I don't know why, but sending them on VMS does not work;
2509 it causes following spaces to be lost, sometimes.
2510 For now, the simplest fix is to avoid using these capabilities ever. */
2511 if (Down && Down[0] == '\n')
2512 Down = 0;
2513 #endif /* VMS */
2515 if (!TS_bell)
2516 TS_bell = "\07";
2518 if (!TS_fwd_scroll)
2519 TS_fwd_scroll = Down;
2521 PC = TS_pad_char ? *TS_pad_char : 0;
2523 if (TabWidth < 0)
2524 TabWidth = 8;
2526 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2527 and newer termcap doc does not seem to say there is a default.
2528 if (!Wcm.cm_tab)
2529 Wcm.cm_tab = "\t";
2532 /* We don't support standout modes that use `magic cookies', so
2533 turn off any that do. */
2534 if (TS_standout_mode && tgetnum ("sg") >= 0)
2536 TS_standout_mode = 0;
2537 TS_end_standout_mode = 0;
2539 if (TS_enter_underline_mode && tgetnum ("ug") >= 0)
2541 TS_enter_underline_mode = 0;
2542 TS_exit_underline_mode = 0;
2545 /* If there's no standout mode, try to use underlining instead. */
2546 if (TS_standout_mode == 0)
2548 TS_standout_mode = TS_enter_underline_mode;
2549 TS_end_standout_mode = TS_exit_underline_mode;
2552 /* If no `se' string, try using a `me' string instead.
2553 If that fails, we can't use standout mode at all. */
2554 if (TS_end_standout_mode == 0)
2556 char *s = tgetstr ("me", address);
2557 if (s != 0)
2558 TS_end_standout_mode = s;
2559 else
2560 TS_standout_mode = 0;
2563 if (TF_teleray)
2565 Wcm.cm_tab = 0;
2566 /* We can't support standout mode, because it uses magic cookies. */
2567 TS_standout_mode = 0;
2568 /* But that means we cannot rely on ^M to go to column zero! */
2569 CR = 0;
2570 /* LF can't be trusted either -- can alter hpos */
2571 /* if move at column 0 thru a line with TS_standout_mode */
2572 Down = 0;
2575 /* Special handling for certain terminal types known to need it */
2577 if (!strcmp (terminal_type, "supdup"))
2579 memory_below_frame = 1;
2580 Wcm.cm_losewrap = 1;
2582 if (!strncmp (terminal_type, "c10", 3)
2583 || !strcmp (terminal_type, "perq"))
2585 /* Supply a makeshift :wi string.
2586 This string is not valid in general since it works only
2587 for windows starting at the upper left corner;
2588 but that is all Emacs uses.
2590 This string works only if the frame is using
2591 the top of the video memory, because addressing is memory-relative.
2592 So first check the :ti string to see if that is true.
2594 It would be simpler if the :wi string could go in the termcap
2595 entry, but it can't because it is not fully valid.
2596 If it were in the termcap entry, it would confuse other programs. */
2597 if (!TS_set_window)
2599 p = TS_termcap_modes;
2600 while (*p && strcmp (p, "\033v "))
2601 p++;
2602 if (*p)
2603 TS_set_window = "\033v%C %C %C %C ";
2605 /* Termcap entry often fails to have :in: flag */
2606 must_write_spaces = 1;
2607 /* :ti string typically fails to have \E^G! in it */
2608 /* This limits scope of insert-char to one line. */
2609 strcpy (area, TS_termcap_modes);
2610 strcat (area, "\033\007!");
2611 TS_termcap_modes = area;
2612 area += strlen (area) + 1;
2613 p = AbsPosition;
2614 /* Change all %+ parameters to %C, to handle
2615 values above 96 correctly for the C100. */
2616 while (*p)
2618 if (p[0] == '%' && p[1] == '+')
2619 p[1] = 'C';
2620 p++;
2624 FrameRows = FRAME_LINES (sf);
2625 FrameCols = FRAME_COLS (sf);
2626 specified_window = FRAME_LINES (sf);
2628 if (Wcm_init () == -1) /* can't do cursor motion */
2629 #ifdef VMS
2630 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2631 It lacks the ability to position the cursor.\n\
2632 If that is not the actual type of terminal you have, use either the\n\
2633 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2634 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2635 terminal_type);
2636 #else /* not VMS */
2637 # ifdef TERMINFO
2638 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2639 It lacks the ability to position the cursor.\n\
2640 If that is not the actual type of terminal you have,\n\
2641 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2642 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2643 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2644 terminal_type);
2645 # else /* TERMCAP */
2646 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2647 It lacks the ability to position the cursor.\n\
2648 If that is not the actual type of terminal you have,\n\
2649 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2650 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2651 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2652 terminal_type);
2653 # endif /* TERMINFO */
2654 #endif /*VMS */
2655 if (FRAME_LINES (sf) <= 0
2656 || FRAME_COLS (sf) <= 0)
2657 fatal ("The frame size has not been specified");
2659 delete_in_insert_mode
2660 = TS_delete_mode && TS_insert_mode
2661 && !strcmp (TS_delete_mode, TS_insert_mode);
2663 se_is_so = (TS_standout_mode
2664 && TS_end_standout_mode
2665 && !strcmp (TS_standout_mode, TS_end_standout_mode));
2667 UseTabs = tabs_safe_p () && TabWidth == 8;
2669 scroll_region_ok
2670 = (Wcm.cm_abs
2671 && (TS_set_window || TS_set_scroll_region || TS_set_scroll_region_1));
2673 line_ins_del_ok = (((TS_ins_line || TS_ins_multi_lines)
2674 && (TS_del_line || TS_del_multi_lines))
2675 || (scroll_region_ok && TS_fwd_scroll && TS_rev_scroll));
2677 char_ins_del_ok = ((TS_ins_char || TS_insert_mode
2678 || TS_pad_inserted_char || TS_ins_multi_chars)
2679 && (TS_del_char || TS_del_multi_chars));
2681 fast_clear_end_of_line = TS_clr_line != 0;
2683 init_baud_rate ();
2684 if (read_socket_hook) /* Baudrate is somewhat */
2685 /* meaningless in this case */
2686 baud_rate = 9600;
2688 FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
2689 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
2690 #endif /* WINDOWSNT */
2692 xfree (buffer);
2695 /* VARARGS 1 */
2696 void
2697 fatal (str, arg1, arg2)
2698 char *str, *arg1, *arg2;
2700 fprintf (stderr, "emacs: ");
2701 fprintf (stderr, str, arg1, arg2);
2702 fprintf (stderr, "\n");
2703 fflush (stderr);
2704 exit (1);
2707 DEFUN ("tty-no-underline", Ftty_no_underline, Stty_no_underline, 0, 0, 0,
2708 doc: /* Declare that this terminal does not handle underlining.
2709 This is used to override the terminfo data, for certain terminals that
2710 do not really do underlining, but say that they do. */)
2713 TS_enter_underline_mode = 0;
2714 return Qnil;
2717 void
2718 syms_of_term ()
2720 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo,
2721 doc: /* Non-nil means the system uses terminfo rather than termcap.
2722 This variable can be used by terminal emulator packages. */);
2723 #ifdef TERMINFO
2724 system_uses_terminfo = 1;
2725 #else
2726 system_uses_terminfo = 0;
2727 #endif
2729 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function,
2730 doc: /* Non-nil means call this function to ring the bell.
2731 The function should accept no arguments. */);
2732 Vring_bell_function = Qnil;
2734 DEFVAR_BOOL ("visible-cursor", &visible_cursor,
2735 doc: /* Non-nil means to make the cursor very visible.
2736 This only has an effect when running in a text terminal.
2737 What means \"very visible\" is up to your terminal. It may make the cursor
2738 bigger, or it may make it blink, or it may do nothing at all. */);
2739 visible_cursor = 1;
2741 defsubr (&Stty_display_color_p);
2742 defsubr (&Stty_display_color_cells);
2743 defsubr (&Stty_no_underline);
2746 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
2747 (do not change this comment) */