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)
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>. */
32 #include "systty.h" /* For emacs_tty in termchar.h */
40 #include "termhooks.h"
41 #include "dispextern.h"
45 /* For now, don't try to include termcap.h. On some systems,
46 configure finds a non-standard termcap.h that the main build
49 #if defined HAVE_TERMCAP_H && 0
52 extern void tputs
P_ ((const char *, int, int (*)(int)));
53 extern int tgetent
P_ ((char *, const char *));
54 extern int tgetflag
P_ ((char *id
));
55 extern int tgetnum
P_ ((char *id
));
70 static void turn_on_face
P_ ((struct frame
*, int face_id
));
71 static void turn_off_face
P_ ((struct frame
*, int face_id
));
72 static void tty_show_cursor
P_ ((void));
73 static void tty_hide_cursor
P_ ((void));
75 #define OUTPUT(tty, a) \
76 emacs_tputs ((tty), a, \
77 (int) (FRAME_LINES (XFRAME (selected_frame)) \
81 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
82 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
84 #define OUTPUT_IF(tty, a) \
87 emacs_tputs ((tty), a, \
88 (int) (FRAME_LINES (XFRAME (selected_frame)) \
93 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
95 /* Function to use to ring the bell. */
97 Lisp_Object Vring_bell_function
;
99 /* Terminal characteristics that higher levels want to look at. */
101 struct tty_output
*tty_list
;
103 /* Nonzero means no need to redraw the entire frame on resuming
104 a suspended Emacs. This is useful on terminals with multiple pages,
105 where one page is used for Emacs and another for all else. */
106 int no_redraw_on_reenter
;
108 /* Hook functions that you can set to snap out the functions in this file.
109 These are all extern'd in termhooks.h */
111 void (*cursor_to_hook
) P_ ((int, int));
112 void (*raw_cursor_to_hook
) P_ ((int, int));
113 void (*clear_to_end_hook
) P_ ((void));
114 void (*clear_frame_hook
) P_ ((void));
115 void (*clear_end_of_line_hook
) P_ ((int));
117 void (*ins_del_lines_hook
) P_ ((int, int));
119 void (*delete_glyphs_hook
) P_ ((int));
121 void (*ring_bell_hook
) P_ ((void));
123 void (*reset_terminal_modes_hook
) P_ ((void));
124 void (*set_terminal_modes_hook
) P_ ((void));
125 void (*update_begin_hook
) P_ ((struct frame
*));
126 void (*update_end_hook
) P_ ((struct frame
*));
127 void (*set_terminal_window_hook
) P_ ((int));
128 void (*insert_glyphs_hook
) P_ ((struct glyph
*, int));
129 void (*write_glyphs_hook
) P_ ((struct glyph
*, int));
130 void (*delete_glyphs_hook
) P_ ((int));
132 int (*read_socket_hook
) P_ ((struct input_event
*, int, int));
134 void (*frame_up_to_date_hook
) P_ ((struct frame
*));
136 /* Return the current position of the mouse.
138 Set *f to the frame the mouse is in, or zero if the mouse is in no
139 Emacs frame. If it is set to zero, all the other arguments are
142 If the motion started in a scroll bar, set *bar_window to the
143 scroll bar's window, *part to the part the mouse is currently over,
144 *x to the position of the mouse along the scroll bar, and *y to the
145 overall length of the scroll bar.
147 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
148 row of the character cell the mouse is over.
150 Set *time to the time the mouse was at the returned position.
152 This should clear mouse_moved until the next motion
155 void (*mouse_position_hook
) P_ ((FRAME_PTR
*f
, int insist
,
156 Lisp_Object
*bar_window
,
157 enum scroll_bar_part
*part
,
160 unsigned long *time
));
162 /* When reading from a minibuffer in a different frame, Emacs wants
163 to shift the highlight from the selected frame to the mini-buffer's
164 frame; under X, this means it lies about where the focus is.
165 This hook tells the window system code to re-decide where to put
168 void (*frame_rehighlight_hook
) P_ ((FRAME_PTR f
));
170 /* If we're displaying frames using a window system that can stack
171 frames on top of each other, this hook allows you to bring a frame
172 to the front, or bury it behind all the other windows. If this
173 hook is zero, that means the device we're displaying on doesn't
174 support overlapping frames, so there's no need to raise or lower
177 If RAISE is non-zero, F is brought to the front, before all other
178 windows. If RAISE is zero, F is sent to the back, behind all other
181 void (*frame_raise_lower_hook
) P_ ((FRAME_PTR f
, int raise
));
183 /* Set the vertical scroll bar for WINDOW to have its upper left corner
184 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
185 indicate that we are displaying PORTION characters out of a total
186 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
187 have a scroll bar, create one for it. */
189 void (*set_vertical_scroll_bar_hook
)
190 P_ ((struct window
*window
,
191 int portion
, int whole
, int position
));
194 /* The following three hooks are used when we're doing a thorough
195 redisplay of the frame. We don't explicitly know which scroll bars
196 are going to be deleted, because keeping track of when windows go
197 away is a real pain - can you say set-window-configuration?
198 Instead, we just assert at the beginning of redisplay that *all*
199 scroll bars are to be removed, and then save scroll bars from the
200 fiery pit when we actually redisplay their window. */
202 /* Arrange for all scroll bars on FRAME to be removed at the next call
203 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
204 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
206 This should be applied to each frame each time its window tree is
207 redisplayed, even if it is not displaying scroll bars at the moment;
208 if the HAS_SCROLL_BARS flag has just been turned off, only calling
209 this and the judge_scroll_bars_hook will get rid of them.
211 If non-zero, this hook should be safe to apply to any frame,
212 whether or not it can support scroll bars, and whether or not it is
213 currently displaying them. */
215 void (*condemn_scroll_bars_hook
) P_ ((FRAME_PTR frame
));
217 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
218 Note that it's okay to redeem a scroll bar that is not condemned. */
220 void (*redeem_scroll_bar_hook
) P_ ((struct window
*window
));
222 /* Remove all scroll bars on FRAME that haven't been saved since the
223 last call to `*condemn_scroll_bars_hook'.
225 This should be applied to each frame after each time its window
226 tree is redisplayed, even if it is not displaying scroll bars at the
227 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
228 calling this and condemn_scroll_bars_hook will get rid of them.
230 If non-zero, this hook should be safe to apply to any frame,
231 whether or not it can support scroll bars, and whether or not it is
232 currently displaying them. */
234 void (*judge_scroll_bars_hook
) P_ ((FRAME_PTR FRAME
));
236 /* Strings, numbers and flags taken from the termcap entry. */
238 char *TS_ins_line
; /* "al" */
239 char *TS_ins_multi_lines
; /* "AL" (one parameter, # lines to insert) */
240 char *TS_bell
; /* "bl" */
241 char *TS_clr_to_bottom
; /* "cd" */
242 char *TS_clr_line
; /* "ce", clear to end of line */
243 char *TS_clr_frame
; /* "cl" */
244 char *TS_set_scroll_region
; /* "cs" (2 params, first line and last line) */
245 char *TS_set_scroll_region_1
; /* "cS" (4 params: total lines,
246 lines above scroll region, lines below it,
247 total lines again) */
248 char *TS_del_char
; /* "dc" */
249 char *TS_del_multi_chars
; /* "DC" (one parameter, # chars to delete) */
250 char *TS_del_line
; /* "dl" */
251 char *TS_del_multi_lines
; /* "DL" (one parameter, # lines to delete) */
252 char *TS_delete_mode
; /* "dm", enter character-delete mode */
253 char *TS_end_delete_mode
; /* "ed", leave character-delete mode */
254 char *TS_end_insert_mode
; /* "ei", leave character-insert mode */
255 char *TS_ins_char
; /* "ic" */
256 char *TS_ins_multi_chars
; /* "IC" (one parameter, # chars to insert) */
257 char *TS_insert_mode
; /* "im", enter character-insert mode */
258 char *TS_pad_inserted_char
; /* "ip". Just padding, no commands. */
259 char *TS_end_keypad_mode
; /* "ke" */
260 char *TS_keypad_mode
; /* "ks" */
261 char *TS_pad_char
; /* "pc", char to use as padding */
262 char *TS_repeat
; /* "rp" (2 params, # times to repeat
263 and character to be repeated) */
264 char *TS_end_standout_mode
; /* "se" */
265 char *TS_fwd_scroll
; /* "sf" */
266 char *TS_standout_mode
; /* "so" */
267 char *TS_rev_scroll
; /* "sr" */
268 char *TS_end_termcap_modes
; /* "te" */
269 char *TS_termcap_modes
; /* "ti" */
270 char *TS_visible_bell
; /* "vb" */
271 char *TS_cursor_normal
; /* "ve" */
272 char *TS_cursor_visible
; /* "vs" */
273 char *TS_cursor_invisible
; /* "vi" */
274 char *TS_set_window
; /* "wi" (4 params, start and end of window,
275 each as vpos and hpos) */
277 /* Value of the "NC" (no_color_video) capability, or 0 if not
280 static int TN_no_color_video
;
282 /* Meaning of bits in no_color_video. Each bit set means that the
283 corresponding attribute cannot be combined with colors. */
287 NC_STANDOUT
= 1 << 0,
288 NC_UNDERLINE
= 1 << 1,
295 NC_ALT_CHARSET
= 1 << 8
298 /* "md" -- turn on bold (extra bright mode). */
300 char *TS_enter_bold_mode
;
302 /* "mh" -- turn on half-bright mode. */
304 char *TS_enter_dim_mode
;
306 /* "mb" -- enter blinking mode. */
308 char *TS_enter_blink_mode
;
310 /* "mr" -- enter reverse video mode. */
312 char *TS_enter_reverse_mode
;
314 /* "us"/"ue" -- start/end underlining. */
316 char *TS_exit_underline_mode
, *TS_enter_underline_mode
;
318 /* "as"/"ae" -- start/end alternate character set. Not really
321 char *TS_enter_alt_charset_mode
, *TS_exit_alt_charset_mode
;
323 /* "me" -- switch appearances off. */
325 char *TS_exit_attribute_mode
;
327 /* "Co" -- number of colors. */
331 /* "pa" -- max. number of color pairs on screen. Not handled yet.
332 Could be a problem if not equal to TN_max_colors * TN_max_colors. */
336 /* "op" -- SVr4 set default pair to its original value. */
340 /* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
341 1 param, the color index. */
343 char *TS_set_foreground
, *TS_set_background
;
345 int TF_hazeltine
; /* termcap hz flag. */
346 int TF_insmode_motion
; /* termcap mi flag: can move while in insert mode. */
347 int TF_standout_motion
; /* termcap mi flag: can move while in standout mode. */
348 int TF_underscore
; /* termcap ul flag: _ underlines if over-struck on
349 non-blank position. Must clear before writing _. */
350 int TF_teleray
; /* termcap xt flag: many weird consequences.
353 static int RPov
; /* # chars to start a TS_repeat */
355 static int delete_in_insert_mode
; /* delete mode == insert mode */
357 static int se_is_so
; /* 1 if same string both enters and leaves
362 /* The largest frame width in any call to calculate_costs. */
366 /* The largest frame height in any call to calculate_costs. */
370 static int costs_set
; /* Nonzero if costs have been calculated. */
372 int insert_mode
; /* Nonzero when in insert mode. */
373 int standout_mode
; /* Nonzero when in standout mode. */
375 /* Size of window specified by higher levels.
376 This is the number of lines, from the top of frame downwards,
377 which can participate in insert-line/delete-line operations.
379 Effectively it excludes the bottom frame_lines - specified_window_size
380 lines from those operations. */
382 int specified_window
;
384 /* Frame currently being redisplayed; 0 if not currently redisplaying.
385 (Direct output does not count). */
387 FRAME_PTR updating_frame
;
389 /* Provided for lisp packages. */
391 static int system_uses_terminfo
;
393 /* Flag used in tty_show/hide_cursor. */
395 static int tty_cursor_hidden
;
399 extern char *tgetstr ();
403 /* We aren't X windows, but we aren't termcap either. This makes me
404 uncertain as to what value to use for frame.output_method. For
405 this file, we'll define FRAME_TERMCAP_P to be zero so that our
406 output hooks get called instead of the termcap functions. Probably
407 the best long-term solution is to define an output_windows_nt... */
409 #undef FRAME_TERMCAP_P
410 #define FRAME_TERMCAP_P(_f_) 0
411 #endif /* WINDOWSNT */
416 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
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
;
435 Vring_bell_function
= function
;
437 else if (!FRAME_TERMCAP_P (f
))
438 (*ring_bell_hook
) ();
440 struct tty_output
*tty
= FRAME_TTY (f
);
441 OUTPUT (tty
, TS_visible_bell
&& visible_bell
? TS_visible_bell
: TS_bell
);
446 set_terminal_modes ()
448 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
449 if (FRAME_TERMCAP_P (f
))
451 struct tty_output
*tty
= FRAME_TTY (f
);
452 OUTPUT_IF (tty
, TS_termcap_modes
);
453 OUTPUT_IF (tty
, TS_cursor_visible
);
454 OUTPUT_IF (tty
, TS_keypad_mode
);
458 (*set_terminal_modes_hook
) ();
462 reset_terminal_modes ()
464 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
465 if (FRAME_TERMCAP_P (f
))
467 struct tty_output
*tty
= FRAME_TTY (f
);
468 turn_off_highlight ();
470 OUTPUT_IF (tty
, TS_end_keypad_mode
);
471 OUTPUT_IF (tty
, TS_cursor_normal
);
472 OUTPUT_IF (tty
, TS_end_termcap_modes
);
473 OUTPUT_IF (tty
, TS_orig_pair
);
474 /* Output raw CR so kernel can track the cursor hpos. */
478 else if (reset_terminal_modes_hook
)
479 (*reset_terminal_modes_hook
) ();
487 if (!FRAME_TERMCAP_P (f
))
488 update_begin_hook (f
);
495 if (FRAME_TERMCAP_P (f
))
497 if (!XWINDOW (selected_window
)->cursor_off_p
)
500 background_highlight ();
505 updating_frame
= NULL
;
509 set_terminal_window (size
)
512 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
513 if (FRAME_TERMCAP_P (f
))
515 struct tty_output
*tty
= FRAME_TTY (f
);
516 specified_window
= size
? size
: FRAME_LINES (f
);
517 if (TTY_SCROLL_REGION_OK (tty
))
518 set_scroll_region (0, specified_window
);
521 set_terminal_window_hook (size
);
525 set_scroll_region (start
, stop
)
529 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
530 struct tty_output
*tty
= FRAME_TTY (f
);
532 if (TS_set_scroll_region
)
533 buf
= tparam (TS_set_scroll_region
, 0, 0, start
, stop
- 1);
534 else if (TS_set_scroll_region_1
)
535 buf
= tparam (TS_set_scroll_region_1
, 0, 0,
536 FRAME_LINES (f
), start
,
537 FRAME_LINES (f
) - stop
,
540 buf
= tparam (TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
551 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
552 struct tty_output
*tty
= FRAME_TTY (f
);
554 OUTPUT (tty
, TS_insert_mode
);
561 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
562 struct tty_output
*tty
= FRAME_TTY (f
);
564 OUTPUT (tty
, TS_end_insert_mode
);
568 /* Handle highlighting. */
571 turn_off_highlight ()
573 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
574 struct tty_output
*tty
= FRAME_TTY (f
);
576 OUTPUT_IF (tty
, TS_end_standout_mode
);
583 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
584 struct tty_output
*tty
= FRAME_TTY (f
);
586 OUTPUT_IF (tty
, TS_standout_mode
);
594 turn_off_highlight ();
596 turn_on_highlight ();
600 /* Make cursor invisible. */
605 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
606 struct tty_output
*tty
= FRAME_TTY (f
);
607 if (tty_cursor_hidden
== 0)
609 tty_cursor_hidden
= 1;
610 OUTPUT_IF (tty
, TS_cursor_invisible
);
615 /* Ensure that cursor is visible. */
620 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
621 struct tty_output
*tty
= FRAME_TTY (f
);
623 if (tty_cursor_hidden
)
625 tty_cursor_hidden
= 0;
626 OUTPUT_IF (tty
, TS_cursor_normal
);
627 OUTPUT_IF (tty
, TS_cursor_visible
);
632 /* Set standout mode to the state it should be in for
633 empty space inside windows. What this is,
634 depends on the user option inverse-video. */
637 background_highlight ()
640 turn_on_highlight ();
642 turn_off_highlight ();
645 /* Set standout mode to the mode specified for the text to be output. */
648 highlight_if_desired ()
651 turn_on_highlight ();
653 turn_off_highlight ();
657 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
658 frame-relative coordinates. */
661 cursor_to (vpos
, hpos
)
664 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
666 if (! FRAME_TERMCAP_P (f
) && cursor_to_hook
)
668 (*cursor_to_hook
) (vpos
, hpos
);
672 struct tty_output
*tty
= FRAME_TTY (f
);
674 /* Detect the case where we are called from reset_sys_modes
675 and the costs have never been calculated. Do nothing. */
679 if (curY (tty
) == vpos
680 && curX (tty
) == hpos
)
682 if (!TF_standout_motion
)
683 background_highlight ();
684 if (!TF_insmode_motion
)
686 cmgoto (tty
, vpos
, hpos
);
689 /* Similar but don't take any account of the wasted characters. */
692 raw_cursor_to (row
, col
)
695 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
696 if (! FRAME_TERMCAP_P (f
))
698 (*raw_cursor_to_hook
) (row
, col
);
701 struct tty_output
*tty
= FRAME_TTY (f
);
702 if (curY (tty
) == row
703 && curX (tty
) == col
)
705 if (!TF_standout_motion
)
706 background_highlight ();
707 if (!TF_insmode_motion
)
709 cmgoto (tty
, row
, col
);
712 /* Erase operations */
714 /* clear from cursor to end of frame */
720 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
722 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (f
))
724 (*clear_to_end_hook
) ();
727 struct tty_output
*tty
= FRAME_TTY (f
);
728 if (TS_clr_to_bottom
)
730 background_highlight ();
731 OUTPUT (tty
, TS_clr_to_bottom
);
735 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
738 clear_end_of_line (FRAME_COLS (f
));
743 /* Clear entire frame */
748 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
750 if (clear_frame_hook
&& ! FRAME_TERMCAP_P (f
))
752 (*clear_frame_hook
) ();
755 struct tty_output
*tty
= FRAME_TTY (f
);
758 background_highlight ();
759 OUTPUT (tty
, TS_clr_frame
);
769 /* Clear from cursor to end of line.
770 Assume that the line is already clear starting at column first_unused_hpos.
772 Note that the cursor may be moved, on terminals lacking a `ce' string. */
775 clear_end_of_line (first_unused_hpos
)
776 int first_unused_hpos
;
780 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
782 if (clear_end_of_line_hook
783 && ! FRAME_TERMCAP_P (f
))
785 (*clear_end_of_line_hook
) (first_unused_hpos
);
789 struct tty_output
*tty
= FRAME_TTY (f
);
791 /* Detect the case where we are called from reset_sys_modes
792 and the costs have never been calculated. Do nothing. */
796 if (curX (tty
) >= first_unused_hpos
)
798 background_highlight ();
801 OUTPUT1 (tty
, TS_clr_line
);
804 { /* have to do it the hard way */
807 /* Do not write in last row last col with Auto-wrap on. */
809 && curY (tty
) == FRAME_LINES (f
) - 1
810 && first_unused_hpos
== FRAME_COLS (f
))
813 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
815 if (TTY_TERMSCRIPT (tty
))
816 fputc (' ', TTY_TERMSCRIPT (tty
));
817 fputc (' ', TTY_OUTPUT (tty
));
819 cmplus (tty
, first_unused_hpos
- curX (tty
));
823 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
824 store them at DST. Do not write more than DST_LEN bytes. That may
825 require stopping before all SRC_LEN input glyphs have been
828 We store the number of glyphs actually converted in *CONSUMED. The
829 return value is the number of bytes store in DST. */
832 encode_terminal_code (src
, dst
, src_len
, dst_len
, consumed
)
836 int dst_len
, *consumed
;
838 struct glyph
*src_start
= src
, *src_end
= src
+ src_len
;
839 unsigned char *dst_start
= dst
, *dst_end
= dst
+ dst_len
;
841 unsigned char workbuf
[MAX_MULTIBYTE_LENGTH
];
842 const unsigned char *buf
;
844 register int tlen
= GLYPH_TABLE_LENGTH
;
845 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
847 struct coding_system
*coding
;
849 /* If terminal_coding does any conversion, use it, otherwise use
850 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
851 because it always return 1 if the member src_multibyte is 1. */
852 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
854 : &safe_terminal_coding
);
856 while (src
< src_end
)
858 /* We must skip glyphs to be padded for a wide character. */
859 if (! CHAR_GLYPH_PADDING_P (*src
))
861 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
863 if (g
< 0 || g
>= tlen
)
865 /* This glyph doesn't has an entry in Vglyph_table. */
866 if (! CHAR_VALID_P (src
->u
.ch
, 0))
870 coding
->src_multibyte
= 0;
874 len
= CHAR_STRING (src
->u
.ch
, workbuf
);
876 coding
->src_multibyte
= 1;
881 /* This glyph has an entry in Vglyph_table,
882 so process any alias before testing for simpleness. */
883 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
885 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
887 /* We set the multi-byte form of a character in G
888 (that should be an ASCII character) at
890 workbuf
[0] = FAST_GLYPH_CHAR (g
);
893 coding
->src_multibyte
= 0;
897 /* We have a string in Vglyph_table. */
898 len
= GLYPH_LENGTH (tbase
, g
);
899 buf
= GLYPH_STRING (tbase
, g
);
900 coding
->src_multibyte
= STRING_MULTIBYTE (tbase
[g
]);
904 result
= encode_coding (coding
, buf
, dst
, len
, dst_end
- dst
);
905 len
-= coding
->consumed
;
906 dst
+= coding
->produced
;
907 if (result
== CODING_FINISH_INSUFFICIENT_DST
908 || (result
== CODING_FINISH_INSUFFICIENT_SRC
909 && len
> dst_end
- dst
))
910 /* The remaining output buffer is too short. We must
911 break the loop here without increasing SRC so that the
912 next call of this function starts from the same glyph. */
917 /* This is the case that a code of the range 0200..0237
918 exists in buf. We must just write out such a code. */
919 buf
+= coding
->consumed
;
927 *consumed
= src
- src_start
;
928 return (dst
- dst_start
);
933 write_glyphs (string
, len
)
934 register struct glyph
*string
;
937 int produced
, consumed
;
938 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
939 unsigned char conversion_buffer
[1024];
940 int conversion_buffer_size
= sizeof conversion_buffer
;
942 if (write_glyphs_hook
943 && ! FRAME_TERMCAP_P (f
))
945 (*write_glyphs_hook
) (string
, len
);
949 struct tty_output
*tty
= FRAME_TTY (f
);
954 /* Don't dare write in last column of bottom line, if Auto-Wrap,
955 since that would scroll the whole frame on some terminals. */
958 && curY (tty
) + 1 == FRAME_LINES (f
)
959 && (curX (tty
) + len
) == FRAME_COLS (f
))
966 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
968 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
972 /* Identify a run of glyphs with the same face. */
973 int face_id
= string
->face_id
;
976 for (n
= 1; n
< len
; ++n
)
977 if (string
[n
].face_id
!= face_id
)
980 /* Turn appearance modes of the face of the run on. */
981 highlight_if_desired ();
982 turn_on_face (f
, face_id
);
986 /* We use a fixed size (1024 bytes) of conversion buffer.
987 Usually it is sufficient, but if not, we just repeat the
989 produced
= encode_terminal_code (string
, conversion_buffer
,
990 n
, conversion_buffer_size
,
994 fwrite (conversion_buffer
, 1, produced
,
996 if (ferror (TTY_OUTPUT (tty
)))
997 clearerr (TTY_OUTPUT (tty
));
998 if (TTY_TERMSCRIPT (tty
))
999 fwrite (conversion_buffer
, 1, produced
,
1000 TTY_TERMSCRIPT (tty
));
1007 /* Turn appearance modes off. */
1008 turn_off_face (f
, face_id
);
1009 turn_off_highlight ();
1012 /* We may have to output some codes to terminate the writing. */
1013 if (CODING_REQUIRE_FLUSHING (&terminal_coding
))
1015 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
1016 encode_coding (&terminal_coding
, "", conversion_buffer
,
1017 0, conversion_buffer_size
);
1018 if (terminal_coding
.produced
> 0)
1020 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
1022 if (ferror (TTY_OUTPUT (tty
)))
1023 clearerr (TTY_OUTPUT (tty
));
1024 if (TTY_TERMSCRIPT (tty
))
1025 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
1026 TTY_TERMSCRIPT (tty
));
1033 /* If start is zero, insert blanks instead of a string at start */
1036 insert_glyphs (start
, len
)
1037 register struct glyph
*start
;
1041 struct glyph
*glyph
= NULL
;
1042 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
1047 if (insert_glyphs_hook
&& ! FRAME_TERMCAP_P (f
))
1049 (*insert_glyphs_hook
) (start
, len
);
1053 struct tty_output
*tty
= FRAME_TTY (f
);
1055 if (TS_ins_multi_chars
)
1057 buf
= tparam (TS_ins_multi_chars
, 0, 0, len
);
1061 write_glyphs (start
, len
);
1067 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
1068 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
1071 int produced
, consumed
;
1072 unsigned char conversion_buffer
[1024];
1073 int conversion_buffer_size
= sizeof conversion_buffer
;
1075 OUTPUT1_IF (tty
, TS_ins_char
);
1078 conversion_buffer
[0] = SPACEGLYPH
;
1083 highlight_if_desired ();
1084 turn_on_face (f
, start
->face_id
);
1087 /* We must open sufficient space for a character which
1088 occupies more than one column. */
1089 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
1091 OUTPUT1_IF (tty
, TS_ins_char
);
1096 /* This is the last glyph. */
1097 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
1099 /* The size of conversion buffer (1024 bytes) is surely
1100 sufficient for just one glyph. */
1101 produced
= encode_terminal_code (glyph
, conversion_buffer
, 1,
1102 conversion_buffer_size
, &consumed
);
1107 fwrite (conversion_buffer
, 1, produced
,
1109 if (ferror (TTY_OUTPUT (tty
)))
1110 clearerr (TTY_OUTPUT (tty
));
1111 if (TTY_TERMSCRIPT (tty
))
1112 fwrite (conversion_buffer
, 1, produced
,
1113 TTY_TERMSCRIPT (tty
));
1116 OUTPUT1_IF (tty
, TS_pad_inserted_char
);
1119 turn_off_face (f
, glyph
->face_id
);
1120 turn_off_highlight ();
1133 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
1134 struct tty_output
*tty
= FRAME_TTY (f
);
1136 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (f
))
1138 (*delete_glyphs_hook
) (n
);
1143 if (delete_in_insert_mode
)
1150 OUTPUT_IF (tty
, TS_delete_mode
);
1153 if (TS_del_multi_chars
)
1155 buf
= tparam (TS_del_multi_chars
, 0, 0, n
);
1160 for (i
= 0; i
< n
; i
++)
1161 OUTPUT1 (tty
, TS_del_char
);
1162 if (!delete_in_insert_mode
)
1163 OUTPUT_IF (tty
, TS_end_delete_mode
);
1166 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1169 ins_del_lines (vpos
, n
)
1172 char *multi
= n
> 0 ? TS_ins_multi_lines
: TS_del_multi_lines
;
1173 char *single
= n
> 0 ? TS_ins_line
: TS_del_line
;
1174 char *scroll
= n
> 0 ? TS_rev_scroll
: TS_fwd_scroll
;
1175 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
1177 register int i
= n
> 0 ? n
: -n
;
1180 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (f
))
1182 (*ins_del_lines_hook
) (vpos
, n
);
1186 struct tty_output
*tty
= FRAME_TTY (f
);
1188 /* If the lines below the insertion are being pushed
1189 into the end of the window, this is the same as clearing;
1190 and we know the lines are already clear, since the matching
1191 deletion has already been done. So can ignore this. */
1192 /* If the lines below the deletion are blank lines coming
1193 out of the end of the window, don't bother,
1194 as there will be a matching inslines later that will flush them. */
1195 if (TTY_SCROLL_REGION_OK (tty
)
1196 && vpos
+ i
>= specified_window
)
1198 if (!TTY_MEMORY_BELOW_FRAME (tty
)
1199 && vpos
+ i
>= FRAME_LINES (f
))
1204 raw_cursor_to (vpos
, 0);
1205 background_highlight ();
1206 buf
= tparam (multi
, 0, 0, i
);
1212 raw_cursor_to (vpos
, 0);
1213 background_highlight ();
1215 OUTPUT (tty
, single
);
1221 set_scroll_region (vpos
, specified_window
);
1223 raw_cursor_to (specified_window
- 1, 0);
1225 raw_cursor_to (vpos
, 0);
1226 background_highlight ();
1228 OUTPUTL (tty
, scroll
, specified_window
- vpos
);
1229 set_scroll_region (0, specified_window
);
1232 if (!TTY_SCROLL_REGION_OK (tty
)
1233 && TTY_MEMORY_BELOW_FRAME (tty
)
1236 cursor_to (FRAME_LINES (f
) + n
, 0);
1241 /* Compute cost of sending "str", in characters,
1242 not counting any line-dependent padding. */
1250 tputs (str
, 0, evalcost
);
1254 /* Compute cost of sending "str", in characters,
1255 counting any line-dependent padding at one line. */
1258 string_cost_one_line (str
)
1263 tputs (str
, 1, evalcost
);
1267 /* Compute per line amount of line-dependent padding,
1268 in tenths of characters. */
1276 tputs (str
, 0, evalcost
);
1279 tputs (str
, 10, evalcost
);
1284 /* char_ins_del_cost[n] is cost of inserting N characters.
1285 char_ins_del_cost[-n] is cost of deleting N characters.
1286 The length of this vector is based on max_frame_cols. */
1288 int *char_ins_del_vector
;
1290 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1295 calculate_ins_del_char_costs (frame
)
1298 int ins_startup_cost
, del_startup_cost
;
1299 int ins_cost_per_char
, del_cost_per_char
;
1303 if (TS_ins_multi_chars
)
1305 ins_cost_per_char
= 0;
1306 ins_startup_cost
= string_cost_one_line (TS_ins_multi_chars
);
1308 else if (TS_ins_char
|| TS_pad_inserted_char
1309 || (TS_insert_mode
&& TS_end_insert_mode
))
1311 ins_startup_cost
= (30 * (string_cost (TS_insert_mode
)
1312 + string_cost (TS_end_insert_mode
))) / 100;
1313 ins_cost_per_char
= (string_cost_one_line (TS_ins_char
)
1314 + string_cost_one_line (TS_pad_inserted_char
));
1318 ins_startup_cost
= 9999;
1319 ins_cost_per_char
= 0;
1322 if (TS_del_multi_chars
)
1324 del_cost_per_char
= 0;
1325 del_startup_cost
= string_cost_one_line (TS_del_multi_chars
);
1327 else if (TS_del_char
)
1329 del_startup_cost
= (string_cost (TS_delete_mode
)
1330 + string_cost (TS_end_delete_mode
));
1331 if (delete_in_insert_mode
)
1332 del_startup_cost
/= 2;
1333 del_cost_per_char
= string_cost_one_line (TS_del_char
);
1337 del_startup_cost
= 9999;
1338 del_cost_per_char
= 0;
1341 /* Delete costs are at negative offsets */
1342 p
= &char_ins_del_cost (frame
)[0];
1343 for (i
= FRAME_COLS (frame
); --i
>= 0;)
1344 *--p
= (del_startup_cost
+= del_cost_per_char
);
1346 /* Doing nothing is free */
1347 p
= &char_ins_del_cost (frame
)[0];
1350 /* Insert costs are at positive offsets */
1351 for (i
= FRAME_COLS (frame
); --i
>= 0;)
1352 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1356 calculate_costs (frame
)
1359 register char *f
= (TS_set_scroll_region
1360 ? TS_set_scroll_region
1361 : TS_set_scroll_region_1
);
1363 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1365 if (FRAME_TERMCAP_P (frame
))
1366 TTY_SCROLL_REGION_COST (frame
->output_data
.tty
) = string_cost (f
);
1368 /* These variables are only used for terminal stuff. They are allocated
1369 once for the terminal frame of X-windows emacs, but not used afterwards.
1371 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1372 X turns off char_ins_del_ok. */
1374 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1375 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1379 if (char_ins_del_vector
!= 0)
1381 = (int *) xrealloc (char_ins_del_vector
,
1383 + 2 * max_frame_cols
* sizeof (int)));
1386 = (int *) xmalloc (sizeof (int)
1387 + 2 * max_frame_cols
* sizeof (int));
1389 bzero (char_ins_del_vector
, (sizeof (int)
1390 + 2 * max_frame_cols
* sizeof (int)));
1392 if (f
&& (!TS_ins_line
&& !TS_del_line
))
1393 do_line_insertion_deletion_costs (frame
,
1394 TS_rev_scroll
, TS_ins_multi_lines
,
1395 TS_fwd_scroll
, TS_del_multi_lines
,
1398 do_line_insertion_deletion_costs (frame
,
1399 TS_ins_line
, TS_ins_multi_lines
,
1400 TS_del_line
, TS_del_multi_lines
,
1403 calculate_ins_del_char_costs (frame
);
1405 /* Don't use TS_repeat if its padding is worse than sending the chars */
1406 if (TS_repeat
&& per_line_cost (TS_repeat
) * baud_rate
< 9000)
1407 RPov
= string_cost (TS_repeat
);
1409 RPov
= FRAME_COLS (frame
) * 2;
1411 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1418 /* Termcap capability names that correspond directly to X keysyms.
1419 Some of these (marked "terminfo") aren't supplied by old-style
1420 (Berkeley) termcap entries. They're listed in X keysym order;
1421 except we put the keypad keys first, so that if they clash with
1422 other keys (as on the IBM PC keyboard) they get overridden.
1425 static struct fkey_table keys
[] =
1427 {"kh", "home"}, /* termcap */
1428 {"kl", "left"}, /* termcap */
1429 {"ku", "up"}, /* termcap */
1430 {"kr", "right"}, /* termcap */
1431 {"kd", "down"}, /* termcap */
1432 {"%8", "prior"}, /* terminfo */
1433 {"%5", "next"}, /* terminfo */
1434 {"@7", "end"}, /* terminfo */
1435 {"@1", "begin"}, /* terminfo */
1436 {"*6", "select"}, /* terminfo */
1437 {"%9", "print"}, /* terminfo */
1438 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1440 * "insert" --- see below
1442 {"&8", "undo"}, /* terminfo */
1443 {"%0", "redo"}, /* terminfo */
1444 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1445 {"@0", "find"}, /* terminfo */
1446 {"@2", "cancel"}, /* terminfo */
1447 {"%1", "help"}, /* terminfo */
1449 * "break" goes here, but can't be reliably intercepted with termcap
1451 {"&4", "reset"}, /* terminfo --- actually `restart' */
1453 * "system" and "user" --- no termcaps
1455 {"kE", "clearline"}, /* terminfo */
1456 {"kA", "insertline"}, /* terminfo */
1457 {"kL", "deleteline"}, /* terminfo */
1458 {"kI", "insertchar"}, /* terminfo */
1459 {"kD", "deletechar"}, /* terminfo */
1460 {"kB", "backtab"}, /* terminfo */
1462 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1464 {"@8", "kp-enter"}, /* terminfo */
1466 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1467 * "kp-multiply", "kp-add", "kp-separator",
1468 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1469 * --- no termcaps for any of these.
1471 {"K4", "kp-1"}, /* terminfo */
1473 * "kp-2" --- no termcap
1475 {"K5", "kp-3"}, /* terminfo */
1477 * "kp-4" --- no termcap
1479 {"K2", "kp-5"}, /* terminfo */
1481 * "kp-6" --- no termcap
1483 {"K1", "kp-7"}, /* terminfo */
1485 * "kp-8" --- no termcap
1487 {"K3", "kp-9"}, /* terminfo */
1489 * "kp-equal" --- no termcap
1502 static char **term_get_fkeys_arg
;
1503 static Lisp_Object
term_get_fkeys_1 ();
1505 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1506 This function scans the termcap function key sequence entries, and
1507 adds entries to Vfunction_key_map for each function key it finds. */
1510 term_get_fkeys (address
)
1513 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1514 errors during the call. The only errors should be from Fdefine_key
1515 when given a key sequence containing an invalid prefix key. If the
1516 termcap defines function keys which use a prefix that is already bound
1517 to a command by the default bindings, we should silently ignore that
1518 function key specification, rather than giving the user an error and
1519 refusing to run at all on such a terminal. */
1521 extern Lisp_Object
Fidentity ();
1522 term_get_fkeys_arg
= address
;
1523 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1531 char **address
= term_get_fkeys_arg
;
1533 /* This can happen if CANNOT_DUMP or with strange options. */
1535 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1537 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1539 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1541 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1542 Fmake_vector (make_number (1),
1543 intern (keys
[i
].name
)));
1546 /* The uses of the "k0" capability are inconsistent; sometimes it
1547 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1548 We will attempt to politely accommodate both systems by testing for
1549 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1552 char *k_semi
= tgetstr ("k;", address
);
1553 char *k0
= tgetstr ("k0", address
);
1554 char *k0_name
= "f10";
1559 /* Define f0 first, so that f10 takes precedence in case the
1560 key sequences happens to be the same. */
1561 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1562 Fmake_vector (make_number (1), intern ("f0")));
1563 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1564 Fmake_vector (make_number (1), intern ("f10")));
1567 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1568 Fmake_vector (make_number (1), intern (k0_name
)));
1571 /* Set up cookies for numbered function keys above f10. */
1573 char fcap
[3], fkey
[4];
1575 fcap
[0] = 'F'; fcap
[2] = '\0';
1576 for (i
= 11; i
< 64; i
++)
1579 fcap
[1] = '1' + i
- 11;
1581 fcap
[1] = 'A' + i
- 20;
1583 fcap
[1] = 'a' + i
- 46;
1586 char *sequence
= tgetstr (fcap
, address
);
1589 sprintf (fkey
, "f%d", i
);
1590 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1591 Fmake_vector (make_number (1),
1599 * Various mappings to try and get a better fit.
1602 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1603 if (!tgetstr (cap1, address)) \
1605 char *sequence = tgetstr (cap2, address); \
1607 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1608 Fmake_vector (make_number (1), \
1612 /* if there's no key_next keycap, map key_npage to `next' keysym */
1613 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1614 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1615 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1616 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1617 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1618 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1619 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1621 /* IBM has their own non-standard dialect of terminfo.
1622 If the standard name isn't found, try the IBM name. */
1623 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1624 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1625 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1626 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1627 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1628 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1629 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1630 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1631 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1632 #undef CONDITIONAL_REASSIGN
1639 /***********************************************************************
1640 Character Display Information
1641 ***********************************************************************/
1643 static void append_glyph
P_ ((struct it
*));
1646 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1647 terminal frames if IT->glyph_row != NULL. IT->c is the character
1648 for which to produce glyphs; IT->face_id contains the character's
1649 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1656 struct glyph
*glyph
, *end
;
1659 xassert (it
->glyph_row
);
1660 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1661 + it
->glyph_row
->used
[it
->area
]);
1662 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1665 i
< it
->pixel_width
&& glyph
< end
;
1668 glyph
->type
= CHAR_GLYPH
;
1669 glyph
->pixel_width
= 1;
1670 glyph
->u
.ch
= it
->c
;
1671 glyph
->face_id
= it
->face_id
;
1672 glyph
->padding_p
= i
> 0;
1673 glyph
->charpos
= CHARPOS (it
->position
);
1674 glyph
->object
= it
->object
;
1676 ++it
->glyph_row
->used
[it
->area
];
1682 /* Produce glyphs for the display element described by IT. *IT
1683 specifies what we want to produce a glyph for (character, image, ...),
1684 and where in the glyph matrix we currently are (glyph row and hpos).
1685 produce_glyphs fills in output fields of *IT with information such as the
1686 pixel width and height of a character, and maybe output actual glyphs at
1687 the same time if IT->glyph_row is non-null. See the explanation of
1688 struct display_iterator in dispextern.h for an overview.
1690 produce_glyphs also stores the result of glyph width, ascent
1691 etc. computations in *IT.
1693 IT->glyph_row may be null, in which case produce_glyphs does not
1694 actually fill in the glyphs. This is used in the move_* functions
1695 in xdisp.c for text width and height computations.
1697 Callers usually don't call produce_glyphs directly;
1698 instead they use the macro PRODUCE_GLYPHS. */
1704 /* If a hook is installed, let it do the work. */
1705 xassert (it
->what
== IT_CHARACTER
1706 || it
->what
== IT_COMPOSITION
1707 || it
->what
== IT_IMAGE
1708 || it
->what
== IT_STRETCH
);
1710 /* Nothing but characters are supported on terminal frames. For a
1711 composition sequence, it->c is the first character of the
1713 xassert (it
->what
== IT_CHARACTER
1714 || it
->what
== IT_COMPOSITION
);
1716 if (it
->c
>= 040 && it
->c
< 0177)
1718 it
->pixel_width
= it
->nglyphs
= 1;
1722 else if (it
->c
== '\n')
1723 it
->pixel_width
= it
->nglyphs
= 0;
1724 else if (it
->c
== '\t')
1726 int absolute_x
= (it
->current_x
1727 + it
->continuation_lines_width
);
1729 = (((1 + absolute_x
+ it
->tab_width
- 1)
1734 /* If part of the TAB has been displayed on the previous line
1735 which is continued now, continuation_lines_width will have
1736 been incremented already by the part that fitted on the
1737 continued line. So, we will get the right number of spaces
1739 nspaces
= next_tab_x
- absolute_x
;
1746 it
->pixel_width
= it
->len
= 1;
1754 it
->pixel_width
= nspaces
;
1755 it
->nglyphs
= nspaces
;
1757 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1759 /* Coming here means that it->c is from display table, thus we
1760 must send the code as is to the terminal. Although there's
1761 no way to know how many columns it occupies on a screen, it
1762 is a good assumption that a single byte code has 1-column
1764 it
->pixel_width
= it
->nglyphs
= 1;
1770 /* A multi-byte character. The display width is fixed for all
1771 characters of the set. Some of the glyphs may have to be
1772 ignored because they are already displayed in a continued
1774 int charset
= CHAR_CHARSET (it
->c
);
1776 it
->pixel_width
= CHARSET_WIDTH (charset
);
1777 it
->nglyphs
= it
->pixel_width
;
1783 /* Advance current_x by the pixel width as a convenience for
1785 if (it
->area
== TEXT_AREA
)
1786 it
->current_x
+= it
->pixel_width
;
1787 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1788 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1792 /* Get information about special display element WHAT in an
1793 environment described by IT. WHAT is one of IT_TRUNCATION or
1794 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1795 non-null glyph_row member. This function ensures that fields like
1796 face_id, c, len of IT are left untouched. */
1799 produce_special_glyphs (it
, what
)
1801 enum display_element_type what
;
1807 temp_it
.what
= IT_CHARACTER
;
1809 temp_it
.object
= make_number (0);
1810 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1812 if (what
== IT_CONTINUATION
)
1814 /* Continuation glyph. */
1816 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1817 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1819 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it
->dp
)));
1820 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1825 produce_glyphs (&temp_it
);
1826 it
->pixel_width
= temp_it
.pixel_width
;
1827 it
->nglyphs
= temp_it
.pixel_width
;
1829 else if (what
== IT_TRUNCATION
)
1831 /* Truncation glyph. */
1833 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1834 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1836 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it
->dp
)));
1837 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1842 produce_glyphs (&temp_it
);
1843 it
->pixel_width
= temp_it
.pixel_width
;
1844 it
->nglyphs
= temp_it
.pixel_width
;
1852 /***********************************************************************
1854 ***********************************************************************/
1856 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1857 one of the enumerators from enum no_color_bit, or a bit set built
1858 from them. Some display attributes may not be used together with
1859 color; the termcap capability `NC' specifies which ones. */
1861 #define MAY_USE_WITH_COLORS_P(ATTR) \
1862 (TN_max_colors > 0 \
1863 ? (TN_no_color_video & (ATTR)) == 0 \
1866 /* Turn appearances of face FACE_ID on tty frame F on. */
1869 turn_on_face (f
, face_id
)
1873 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1874 long fg
= face
->foreground
;
1875 long bg
= face
->background
;
1876 struct tty_output
*tty
= FRAME_TTY (f
);
1878 /* Do this first because TS_end_standout_mode may be the same
1879 as TS_exit_attribute_mode, which turns all appearances off. */
1880 if (MAY_USE_WITH_COLORS_P (NC_REVERSE
))
1882 if (TN_max_colors
> 0)
1884 if (fg
>= 0 && bg
>= 0)
1886 /* If the terminal supports colors, we can set them
1887 below without using reverse video. The face's fg
1888 and bg colors are set as they should appear on
1889 the screen, i.e. they take the inverse-video'ness
1890 of the face already into account. */
1892 else if (inverse_video
)
1894 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1895 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1896 toggle_highlight ();
1900 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1901 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1902 toggle_highlight ();
1907 /* If we can't display colors, use reverse video
1908 if the face specifies that. */
1911 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1912 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1913 toggle_highlight ();
1917 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1918 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1919 toggle_highlight ();
1924 if (face
->tty_bold_p
)
1926 if (MAY_USE_WITH_COLORS_P (NC_BOLD
))
1927 OUTPUT1_IF (tty
, TS_enter_bold_mode
);
1929 else if (face
->tty_dim_p
)
1930 if (MAY_USE_WITH_COLORS_P (NC_DIM
))
1931 OUTPUT1_IF (tty
, TS_enter_dim_mode
);
1933 /* Alternate charset and blinking not yet used. */
1934 if (face
->tty_alt_charset_p
1935 && MAY_USE_WITH_COLORS_P (NC_ALT_CHARSET
))
1936 OUTPUT1_IF (tty
, TS_enter_alt_charset_mode
);
1938 if (face
->tty_blinking_p
1939 && MAY_USE_WITH_COLORS_P (NC_BLINK
))
1940 OUTPUT1_IF (tty
, TS_enter_blink_mode
);
1942 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (NC_UNDERLINE
))
1943 OUTPUT1_IF (tty
, TS_enter_underline_mode
);
1945 if (TN_max_colors
> 0)
1949 if (fg
>= 0 && TS_set_foreground
)
1951 p
= tparam (TS_set_foreground
, NULL
, 0, (int) fg
);
1956 if (bg
>= 0 && TS_set_background
)
1958 p
= tparam (TS_set_background
, NULL
, 0, (int) bg
);
1966 /* Turn off appearances of face FACE_ID on tty frame F. */
1969 turn_off_face (f
, face_id
)
1973 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1974 struct tty_output
*tty
= FRAME_TTY (f
);
1976 xassert (face
!= NULL
);
1978 if (TS_exit_attribute_mode
)
1980 /* Capability "me" will turn off appearance modes double-bright,
1981 half-bright, reverse-video, standout, underline. It may or
1982 may not turn off alt-char-mode. */
1983 if (face
->tty_bold_p
1985 || face
->tty_reverse_p
1986 || face
->tty_alt_charset_p
1987 || face
->tty_blinking_p
1988 || face
->tty_underline_p
)
1990 OUTPUT1_IF (tty
, TS_exit_attribute_mode
);
1991 if (strcmp (TS_exit_attribute_mode
, TS_end_standout_mode
) == 0)
1995 if (face
->tty_alt_charset_p
)
1996 OUTPUT_IF (tty
, TS_exit_alt_charset_mode
);
2000 /* If we don't have "me" we can only have those appearances
2001 that have exit sequences defined. */
2002 if (face
->tty_alt_charset_p
)
2003 OUTPUT_IF (tty
, TS_exit_alt_charset_mode
);
2005 if (face
->tty_underline_p
)
2006 OUTPUT_IF (tty
, TS_exit_underline_mode
);
2009 /* Switch back to default colors. */
2010 if (TN_max_colors
> 0
2011 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2012 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2013 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2014 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2015 OUTPUT1_IF (tty
, TS_orig_pair
);
2019 /* Return non-zero if the terminal on frame F supports all of the
2020 capabilities in CAPS simultaneously, with foreground and background
2021 colors FG and BG. */
2024 tty_capable_p (f
, caps
, fg
, bg
)
2027 unsigned long fg
, bg
;
2029 #define TTY_CAPABLE_P_TRY(cap, TS, NC_bit) \
2030 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(NC_bit))) \
2033 TTY_CAPABLE_P_TRY (TTY_CAP_INVERSE
, TS_standout_mode
, NC_REVERSE
);
2034 TTY_CAPABLE_P_TRY (TTY_CAP_UNDERLINE
, TS_enter_underline_mode
, NC_UNDERLINE
);
2035 TTY_CAPABLE_P_TRY (TTY_CAP_BOLD
, TS_enter_bold_mode
, NC_BOLD
);
2036 TTY_CAPABLE_P_TRY (TTY_CAP_DIM
, TS_enter_dim_mode
, NC_DIM
);
2037 TTY_CAPABLE_P_TRY (TTY_CAP_BLINK
, TS_enter_blink_mode
, NC_BLINK
);
2038 TTY_CAPABLE_P_TRY (TTY_CAP_ALT_CHARSET
, TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
2045 /* Return non-zero if the terminal is capable to display colors. */
2047 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2049 doc
: /* Return non-nil if TTY can display colors on DISPLAY. */)
2051 Lisp_Object display
;
2053 return TN_max_colors
> 0 ? Qt
: Qnil
;
2056 /* Return the number of supported colors. */
2057 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2058 Stty_display_color_cells
, 0, 1, 0,
2059 doc
: /* Return the number of colors supported by TTY on DISPLAY. */)
2061 Lisp_Object display
;
2063 return make_number (TN_max_colors
);
2068 /* Save or restore the default color-related capabilities of this
2071 tty_default_color_capabilities (save
)
2075 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
2076 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
2080 if (default_orig_pair
)
2081 xfree (default_orig_pair
);
2082 default_orig_pair
= TS_orig_pair
? xstrdup (TS_orig_pair
) : NULL
;
2084 if (default_set_foreground
)
2085 xfree (default_set_foreground
);
2086 default_set_foreground
= TS_set_foreground
? xstrdup (TS_set_foreground
)
2089 if (default_set_background
)
2090 xfree (default_set_background
);
2091 default_set_background
= TS_set_background
? xstrdup (TS_set_background
)
2094 default_max_colors
= TN_max_colors
;
2095 default_max_pairs
= TN_max_pairs
;
2096 default_no_color_video
= TN_no_color_video
;
2100 TS_orig_pair
= default_orig_pair
;
2101 TS_set_foreground
= default_set_foreground
;
2102 TS_set_background
= default_set_background
;
2103 TN_max_colors
= default_max_colors
;
2104 TN_max_pairs
= default_max_pairs
;
2105 TN_no_color_video
= default_no_color_video
;
2109 /* Setup one of the standard tty color schemes according to MODE.
2110 MODE's value is generally the number of colors which we want to
2111 support; zero means set up for the default capabilities, the ones
2112 we saw at term_init time; -1 means turn off color support. */
2114 tty_setup_colors (mode
)
2117 /* Canonicalize all negative values of MODE. */
2123 case -1: /* no colors at all */
2126 TN_no_color_video
= 0;
2127 TS_set_foreground
= TS_set_background
= TS_orig_pair
= NULL
;
2129 case 0: /* default colors, if any */
2131 tty_default_color_capabilities (0);
2133 case 8: /* 8 standard ANSI colors */
2134 TS_orig_pair
= "\033[0m";
2136 TS_set_foreground
= "\033[3%p1%dm";
2137 TS_set_background
= "\033[4%p1%dm";
2139 TS_set_foreground
= "\033[3%dm";
2140 TS_set_background
= "\033[4%dm";
2144 TN_no_color_video
= 0;
2150 set_tty_color_mode (f
, val
)
2154 Lisp_Object color_mode_spec
, current_mode_spec
;
2155 Lisp_Object color_mode
, current_mode
;
2157 extern Lisp_Object Qtty_color_mode
;
2158 Lisp_Object tty_color_mode_alist
;
2160 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2167 if (NILP (tty_color_mode_alist
))
2168 color_mode_spec
= Qnil
;
2170 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2172 if (CONSP (color_mode_spec
))
2173 color_mode
= XCDR (color_mode_spec
);
2178 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2180 if (CONSP (current_mode_spec
))
2181 current_mode
= XCDR (current_mode_spec
);
2183 current_mode
= Qnil
;
2184 if (INTEGERP (color_mode
))
2185 mode
= XINT (color_mode
);
2187 mode
= 0; /* meaning default */
2188 if (INTEGERP (current_mode
))
2189 old_mode
= XINT (current_mode
);
2193 if (mode
!= old_mode
)
2195 tty_setup_colors (mode
);
2196 /* This recomputes all the faces given the new color
2198 call0 (intern ("tty-set-up-initial-frame-faces"));
2203 #endif /* !WINDOWSNT */
2208 get_named_tty (name
)
2211 struct tty_output
*tty
= tty_list
;
2214 if ((tty
->name
== 0 && name
== 0)
2215 || (name
&& tty
->name
&& !strcmp (tty
->name
, name
)))
2224 /***********************************************************************
2226 ***********************************************************************/
2229 term_dummy_init (void)
2231 if (initialized
|| tty_list
)
2232 error ("tty already initialized");
2234 tty_list
= xmalloc (sizeof (struct tty_output
));
2235 bzero (tty_list
, sizeof (struct tty_output
));
2236 TTY_NAME (tty_list
) = 0;
2237 TTY_INPUT (tty_list
) = stdin
;
2238 TTY_OUTPUT (tty_list
) = stdout
;
2244 term_init (name
, terminal_type
)
2246 char *terminal_type
;
2249 char **address
= &area
;
2250 char *buffer
= NULL
;
2251 int buffer_size
= 4096;
2254 struct frame
*sf
= XFRAME (selected_frame
);
2256 struct tty_output
*tty
;
2258 tty
= get_named_tty (name
);
2261 /* Return the previously initialized terminal, except if it is the dummy
2262 terminal created for the initial frame. */
2269 error ("Unknown terminal type");
2271 tty
= (struct tty_output
*) xmalloc (sizeof (struct tty_output
));
2272 bzero (tty
, sizeof (struct tty_output
));
2273 tty
->next
= tty_list
;
2279 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
2285 fd
= emacs_open (name
, O_RDWR
, 0);
2288 tty_list
= tty
->next
;
2290 error ("could not open file: %s", name
);
2292 f
= fdopen (fd
, "w+");
2293 TTY_NAME (tty
) = xstrdup (name
);
2294 TTY_INPUT (tty
) = f
;
2295 TTY_OUTPUT (tty
) = f
;
2300 TTY_INPUT (tty
) = stdin
;
2301 TTY_OUTPUT (tty
) = stdout
;
2304 init_sys_modes (tty
);
2307 initialize_w32_display ();
2311 area
= (char *) xmalloc (2044);
2313 FrameRows
= FRAME_LINES (sf
);
2314 FrameCols
= FRAME_COLS (sf
);
2315 specified_window
= FRAME_LINES (sf
);
2317 delete_in_insert_mode
= 1;
2320 TTY_SCROLL_REGION_OK (tty
) = 0;
2322 /* Seems to insert lines when it's not supposed to, messing
2323 up the display. In doing a trace, it didn't seem to be
2324 called much, so I don't think we're losing anything by
2326 TTY_LINE_INS_DEL_OK (tty
) = 0;
2328 TTY_CHAR_INS_DEL_OK (tty
) = 1;
2332 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
2333 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
2334 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2337 #else /* not WINDOWSNT */
2341 TTY_TYPE (tty
) = xstrdup (terminal_type
);
2343 buffer
= (char *) xmalloc (buffer_size
);
2344 status
= tgetent (buffer
, terminal_type
);
2348 fatal ("Cannot open terminfo database file");
2350 fatal ("Cannot open termcap database file");
2356 fatal ("Terminal type %s is not defined.\n\
2357 If that is not the actual type of terminal you have,\n\
2358 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2359 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2360 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2363 fatal ("Terminal type %s is not defined.\n\
2364 If that is not the actual type of terminal you have,\n\
2365 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2366 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2367 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2373 if (strlen (buffer
) >= buffer_size
)
2375 buffer_size
= strlen (buffer
);
2377 area
= (char *) xmalloc (buffer_size
);
2379 TS_ins_line
= tgetstr ("al", address
);
2380 TS_ins_multi_lines
= tgetstr ("AL", address
);
2381 TS_bell
= tgetstr ("bl", address
);
2382 BackTab (tty
) = tgetstr ("bt", address
);
2383 TS_clr_to_bottom
= tgetstr ("cd", address
);
2384 TS_clr_line
= tgetstr ("ce", address
);
2385 TS_clr_frame
= tgetstr ("cl", address
);
2386 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
2387 AbsPosition (tty
) = tgetstr ("cm", address
);
2388 CR (tty
) = tgetstr ("cr", address
);
2389 TS_set_scroll_region
= tgetstr ("cs", address
);
2390 TS_set_scroll_region_1
= tgetstr ("cS", address
);
2391 RowPosition (tty
) = tgetstr ("cv", address
);
2392 TS_del_char
= tgetstr ("dc", address
);
2393 TS_del_multi_chars
= tgetstr ("DC", address
);
2394 TS_del_line
= tgetstr ("dl", address
);
2395 TS_del_multi_lines
= tgetstr ("DL", address
);
2396 TS_delete_mode
= tgetstr ("dm", address
);
2397 TS_end_delete_mode
= tgetstr ("ed", address
);
2398 TS_end_insert_mode
= tgetstr ("ei", address
);
2399 Home (tty
) = tgetstr ("ho", address
);
2400 TS_ins_char
= tgetstr ("ic", address
);
2401 TS_ins_multi_chars
= tgetstr ("IC", address
);
2402 TS_insert_mode
= tgetstr ("im", address
);
2403 TS_pad_inserted_char
= tgetstr ("ip", address
);
2404 TS_end_keypad_mode
= tgetstr ("ke", address
);
2405 TS_keypad_mode
= tgetstr ("ks", address
);
2406 LastLine (tty
) = tgetstr ("ll", address
);
2407 Right (tty
) = tgetstr ("nd", address
);
2408 Down (tty
) = tgetstr ("do", address
);
2410 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
2412 /* VMS puts a carriage return before each linefeed,
2413 so it is not safe to use linefeeds. */
2414 if (Down (tty
) && Down (tty
)[0] == '\n' && Down (tty
)[1] == '\0')
2417 if (tgetflag ("bs"))
2418 Left (tty
) = "\b"; /* can't possibly be longer! */
2419 else /* (Actually, "bs" is obsolete...) */
2420 Left (tty
) = tgetstr ("le", address
);
2422 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
2423 TS_pad_char
= tgetstr ("pc", address
);
2424 TS_repeat
= tgetstr ("rp", address
);
2425 TS_end_standout_mode
= tgetstr ("se", address
);
2426 TS_fwd_scroll
= tgetstr ("sf", address
);
2427 TS_standout_mode
= tgetstr ("so", address
);
2428 TS_rev_scroll
= tgetstr ("sr", address
);
2429 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
2430 TS_end_termcap_modes
= tgetstr ("te", address
);
2431 TS_termcap_modes
= tgetstr ("ti", address
);
2432 Up (tty
) = tgetstr ("up", address
);
2433 TS_visible_bell
= tgetstr ("vb", address
);
2434 TS_cursor_normal
= tgetstr ("ve", address
);
2435 TS_cursor_visible
= tgetstr ("vs", address
);
2436 TS_cursor_invisible
= tgetstr ("vi", address
);
2437 TS_set_window
= tgetstr ("wi", address
);
2439 TS_enter_underline_mode
= tgetstr ("us", address
);
2440 TS_exit_underline_mode
= tgetstr ("ue", address
);
2441 TS_enter_bold_mode
= tgetstr ("md", address
);
2442 TS_enter_dim_mode
= tgetstr ("mh", address
);
2443 TS_enter_blink_mode
= tgetstr ("mb", address
);
2444 TS_enter_reverse_mode
= tgetstr ("mr", address
);
2445 TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2446 TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2447 TS_exit_attribute_mode
= tgetstr ("me", address
);
2449 MultiUp (tty
) = tgetstr ("UP", address
);
2450 MultiDown (tty
) = tgetstr ("DO", address
);
2451 MultiLeft (tty
) = tgetstr ("LE", address
);
2452 MultiRight (tty
) = tgetstr ("RI", address
);
2454 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2455 color because we can't switch back to the default foreground and
2457 TS_orig_pair
= tgetstr ("op", address
);
2460 TS_set_foreground
= tgetstr ("AF", address
);
2461 TS_set_background
= tgetstr ("AB", address
);
2462 if (!TS_set_foreground
)
2465 TS_set_foreground
= tgetstr ("Sf", address
);
2466 TS_set_background
= tgetstr ("Sb", address
);
2469 TN_max_colors
= tgetnum ("Co");
2470 TN_max_pairs
= tgetnum ("pa");
2472 TN_no_color_video
= tgetnum ("NC");
2473 if (TN_no_color_video
== -1)
2474 TN_no_color_video
= 0;
2477 tty_default_color_capabilities (1);
2479 MagicWrap (tty
) = tgetflag ("xn");
2480 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2481 the former flag imply the latter. */
2482 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
2483 TTY_MEMORY_BELOW_FRAME (tty
) = tgetflag ("db");
2484 TF_hazeltine
= tgetflag ("hz");
2485 TTY_MUST_WRITE_SPACES (tty
) = tgetflag ("in");
2486 meta_key
= tgetflag ("km") || tgetflag ("MT");
2487 TF_insmode_motion
= tgetflag ("mi");
2488 TF_standout_motion
= tgetflag ("ms");
2489 TF_underscore
= tgetflag ("ul");
2490 TF_teleray
= tgetflag ("xt");
2492 term_get_fkeys (address
);
2494 /* Get frame size from system, or else from termcap. */
2497 get_tty_size (tty
, &width
, &height
);
2498 FRAME_COLS (sf
) = width
;
2499 FRAME_LINES (sf
) = height
;
2502 if (FRAME_COLS (sf
) <= 0)
2503 SET_FRAME_COLS (sf
, tgetnum ("co"));
2505 /* Keep width and external_width consistent */
2506 SET_FRAME_COLS (sf
, FRAME_COLS (sf
));
2507 if (FRAME_LINES (sf
) <= 0)
2508 FRAME_LINES (sf
) = tgetnum ("li");
2510 if (FRAME_LINES (sf
) < 3 || FRAME_COLS (sf
) < 3)
2511 fatal ("Screen size %dx%d is too small",
2512 FRAME_LINES (sf
), FRAME_COLS (sf
));
2514 #if 0 /* This is not used anywhere. */
2515 TTY_MIN_PADDING_SPEED (tty
) = tgetnum ("pb");
2518 TabWidth (tty
) = tgetnum ("tw");
2521 /* These capabilities commonly use ^J.
2522 I don't know why, but sending them on VMS does not work;
2523 it causes following spaces to be lost, sometimes.
2524 For now, the simplest fix is to avoid using these capabilities ever. */
2525 if (Down (tty
) && Down (tty
)[0] == '\n')
2533 TS_fwd_scroll
= Down (tty
);
2535 PC
= TS_pad_char
? *TS_pad_char
: 0;
2537 if (TabWidth (tty
) < 0)
2540 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2541 and newer termcap doc does not seem to say there is a default.
2542 if (!tty->Wcm->cm_tab)
2543 tty->Wcm->cm_tab = "\t";
2546 /* We don't support standout modes that use `magic cookies', so
2547 turn off any that do. */
2548 if (TS_standout_mode
&& tgetnum ("sg") >= 0)
2550 TS_standout_mode
= 0;
2551 TS_end_standout_mode
= 0;
2553 if (TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
2555 TS_enter_underline_mode
= 0;
2556 TS_exit_underline_mode
= 0;
2559 /* If there's no standout mode, try to use underlining instead. */
2560 if (TS_standout_mode
== 0)
2562 TS_standout_mode
= TS_enter_underline_mode
;
2563 TS_end_standout_mode
= TS_exit_underline_mode
;
2566 /* If no `se' string, try using a `me' string instead.
2567 If that fails, we can't use standout mode at all. */
2568 if (TS_end_standout_mode
== 0)
2570 char *s
= tgetstr ("me", address
);
2572 TS_end_standout_mode
= s
;
2574 TS_standout_mode
= 0;
2579 tty
->Wcm
->cm_tab
= 0;
2580 /* We can't support standout mode, because it uses magic cookies. */
2581 TS_standout_mode
= 0;
2582 /* But that means we cannot rely on ^M to go to column zero! */
2584 /* LF can't be trusted either -- can alter hpos */
2585 /* if move at column 0 thru a line with TS_standout_mode */
2589 /* Special handling for certain terminal types known to need it */
2591 if (!strcmp (terminal_type
, "supdup"))
2593 TTY_MEMORY_BELOW_FRAME (tty
) = 1;
2594 tty
->Wcm
->cm_losewrap
= 1;
2596 if (!strncmp (terminal_type
, "c10", 3)
2597 || !strcmp (terminal_type
, "perq"))
2599 /* Supply a makeshift :wi string.
2600 This string is not valid in general since it works only
2601 for windows starting at the upper left corner;
2602 but that is all Emacs uses.
2604 This string works only if the frame is using
2605 the top of the video memory, because addressing is memory-relative.
2606 So first check the :ti string to see if that is true.
2608 It would be simpler if the :wi string could go in the termcap
2609 entry, but it can't because it is not fully valid.
2610 If it were in the termcap entry, it would confuse other programs. */
2613 p
= TS_termcap_modes
;
2614 while (*p
&& strcmp (p
, "\033v "))
2617 TS_set_window
= "\033v%C %C %C %C ";
2619 /* Termcap entry often fails to have :in: flag */
2620 TTY_MUST_WRITE_SPACES (tty
) = 1;
2621 /* :ti string typically fails to have \E^G! in it */
2622 /* This limits scope of insert-char to one line. */
2623 strcpy (area
, TS_termcap_modes
);
2624 strcat (area
, "\033\007!");
2625 TS_termcap_modes
= area
;
2626 area
+= strlen (area
) + 1;
2627 p
= AbsPosition (tty
);
2628 /* Change all %+ parameters to %C, to handle
2629 values above 96 correctly for the C100. */
2632 if (p
[0] == '%' && p
[1] == '+')
2638 FrameRows (tty
) = FRAME_LINES (sf
);
2639 FrameCols (tty
) = FRAME_COLS (sf
);
2640 specified_window
= FRAME_LINES (sf
);
2642 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
2644 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2645 It lacks the ability to position the cursor.\n\
2646 If that is not the actual type of terminal you have, use either the\n\
2647 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2648 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2652 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2653 It lacks the ability to position the cursor.\n\
2654 If that is not the actual type of terminal you have,\n\
2655 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2656 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2657 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2659 # else /* TERMCAP */
2660 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2661 It lacks the ability to position the cursor.\n\
2662 If that is not the actual type of terminal you have,\n\
2663 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2664 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2665 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2667 # endif /* TERMINFO */
2669 if (FRAME_LINES (sf
) <= 0
2670 || FRAME_COLS (sf
) <= 0)
2671 fatal ("The frame size has not been specified");
2673 delete_in_insert_mode
2674 = TS_delete_mode
&& TS_insert_mode
2675 && !strcmp (TS_delete_mode
, TS_insert_mode
);
2677 se_is_so
= (TS_standout_mode
2678 && TS_end_standout_mode
2679 && !strcmp (TS_standout_mode
, TS_end_standout_mode
));
2681 UseTabs (tty
) = tabs_safe_p (tty
) && TabWidth (tty
) == 8;
2683 TTY_SCROLL_REGION_OK (tty
)
2685 && (TS_set_window
|| TS_set_scroll_region
|| TS_set_scroll_region_1
));
2687 TTY_LINE_INS_DEL_OK (tty
)
2688 = (((TS_ins_line
|| TS_ins_multi_lines
)
2689 && (TS_del_line
|| TS_del_multi_lines
))
2690 || (TTY_SCROLL_REGION_OK (tty
)
2691 && TS_fwd_scroll
&& TS_rev_scroll
));
2693 TTY_CHAR_INS_DEL_OK (tty
)
2694 = ((TS_ins_char
|| TS_insert_mode
2695 || TS_pad_inserted_char
|| TS_ins_multi_chars
)
2696 && (TS_del_char
|| TS_del_multi_chars
));
2698 TTY_FAST_CLEAR_END_OF_LINE (tty
) = TS_clr_line
!= 0;
2701 if (read_socket_hook
) /* Baudrate is somewhat
2702 meaningless in this case */
2705 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
2706 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
2707 #endif /* WINDOWSNT */
2716 fatal (str
, arg1
, arg2
)
2717 char *str
, *arg1
, *arg2
;
2719 fprintf (stderr
, "emacs: ");
2720 fprintf (stderr
, str
, arg1
, arg2
);
2721 fprintf (stderr
, "\n");
2729 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
2730 doc
: /* Non-nil means the system uses terminfo rather than termcap.
2731 This variable can be used by terminal emulator packages. */);
2733 system_uses_terminfo
= 1;
2735 system_uses_terminfo
= 0;
2738 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
2739 doc
: /* Non-nil means call this function to ring the bell.
2740 The function should accept no arguments. */);
2741 Vring_bell_function
= Qnil
;
2743 defsubr (&Stty_display_color_p
);
2744 defsubr (&Stty_display_color_cells
);
2746 Fprovide (intern ("multi-tty"), Qnil
);
2756 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
2757 (do not change this comment) */