1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 86, 87, 93, 94, 95, 98, 2000, 2001
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>. */
37 #include "termhooks.h"
38 #include "dispextern.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
46 #if defined HAVE_TERMCAP_H && 0
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
));
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));
69 tputs (a, (int) (FRAME_HEIGHT (XFRAME (selected_frame)) - curY), cmputc)
70 #define OUTPUT1(a) tputs (a, 1, cmputc)
71 #define OUTPUTL(a, lines) tputs (a, lines, cmputc)
73 #define OUTPUT_IF(a) \
76 tputs (a, (int) (FRAME_HEIGHT (XFRAME (selected_frame)) \
80 #define OUTPUT1_IF(a) do { if (a) tputs (a, 1, cmputc); } while (0)
82 /* Function to use to ring the bell. */
84 Lisp_Object Vring_bell_function
;
86 /* Terminal characteristics that higher levels want to look at.
87 These are all extern'd in termchar.h */
89 int must_write_spaces
; /* Nonzero means spaces in the text
90 must actually be output; can't just skip
91 over some columns to leave them blank. */
92 int min_padding_speed
; /* Speed below which no padding necessary */
94 int line_ins_del_ok
; /* Terminal can insert and delete lines */
95 int char_ins_del_ok
; /* Terminal can insert and delete chars */
96 int scroll_region_ok
; /* Terminal supports setting the
98 int scroll_region_cost
; /* Cost of setting a scroll window,
99 measured in characters */
100 int memory_below_frame
; /* Terminal remembers lines
101 scrolled off bottom */
102 int fast_clear_end_of_line
; /* Terminal has a `ce' string */
104 /* Nonzero means no need to redraw the entire frame on resuming
105 a suspended Emacs. This is useful on terminals with multiple pages,
106 where one page is used for Emacs and another for all else. */
108 int no_redraw_on_reenter
;
110 /* Hook functions that you can set to snap out the functions in this file.
111 These are all extern'd in termhooks.h */
113 void (*cursor_to_hook
) P_ ((int, int));
114 void (*raw_cursor_to_hook
) P_ ((int, int));
115 void (*clear_to_end_hook
) P_ ((void));
116 void (*clear_frame_hook
) P_ ((void));
117 void (*clear_end_of_line_hook
) P_ ((int));
119 void (*ins_del_lines_hook
) P_ ((int, int));
121 void (*delete_glyphs_hook
) P_ ((int));
123 void (*ring_bell_hook
) P_ ((void));
125 void (*reset_terminal_modes_hook
) P_ ((void));
126 void (*set_terminal_modes_hook
) P_ ((void));
127 void (*update_begin_hook
) P_ ((struct frame
*));
128 void (*update_end_hook
) P_ ((struct frame
*));
129 void (*set_terminal_window_hook
) P_ ((int));
130 void (*insert_glyphs_hook
) P_ ((struct glyph
*, int));
131 void (*write_glyphs_hook
) P_ ((struct glyph
*, int));
132 void (*delete_glyphs_hook
) P_ ((int));
134 int (*read_socket_hook
) P_ ((int, struct input_event
*, int, int));
136 void (*frame_up_to_date_hook
) P_ ((struct frame
*));
138 /* Return the current position of the mouse.
140 Set *f to the frame the mouse is in, or zero if the mouse is in no
141 Emacs frame. If it is set to zero, all the other arguments are
144 If the motion started in a scroll bar, set *bar_window to the
145 scroll bar's window, *part to the part the mouse is currently over,
146 *x to the position of the mouse along the scroll bar, and *y to the
147 overall length of the scroll bar.
149 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
150 row of the character cell the mouse is over.
152 Set *time to the time the mouse was at the returned position.
154 This should clear mouse_moved until the next motion
157 void (*mouse_position_hook
) P_ ((FRAME_PTR
*f
, int insist
,
158 Lisp_Object
*bar_window
,
159 enum scroll_bar_part
*part
,
162 unsigned long *time
));
164 /* When reading from a minibuffer in a different frame, Emacs wants
165 to shift the highlight from the selected frame to the mini-buffer's
166 frame; under X, this means it lies about where the focus is.
167 This hook tells the window system code to re-decide where to put
170 void (*frame_rehighlight_hook
) P_ ((FRAME_PTR f
));
172 /* If we're displaying frames using a window system that can stack
173 frames on top of each other, this hook allows you to bring a frame
174 to the front, or bury it behind all the other windows. If this
175 hook is zero, that means the device we're displaying on doesn't
176 support overlapping frames, so there's no need to raise or lower
179 If RAISE is non-zero, F is brought to the front, before all other
180 windows. If RAISE is zero, F is sent to the back, behind all other
183 void (*frame_raise_lower_hook
) P_ ((FRAME_PTR f
, int raise
));
185 /* Set the vertical scroll bar for WINDOW to have its upper left corner
186 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
187 indicate that we are displaying PORTION characters out of a total
188 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
189 have a scroll bar, create one for it. */
191 void (*set_vertical_scroll_bar_hook
)
192 P_ ((struct window
*window
,
193 int portion
, int whole
, int position
));
196 /* The following three hooks are used when we're doing a thorough
197 redisplay of the frame. We don't explicitly know which scroll bars
198 are going to be deleted, because keeping track of when windows go
199 away is a real pain - can you say set-window-configuration?
200 Instead, we just assert at the beginning of redisplay that *all*
201 scroll bars are to be removed, and then save scroll bars from the
202 fiery pit when we actually redisplay their window. */
204 /* Arrange for all scroll bars on FRAME to be removed at the next call
205 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
206 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
208 This should be applied to each frame each time its window tree is
209 redisplayed, even if it is not displaying scroll bars at the moment;
210 if the HAS_SCROLL_BARS flag has just been turned off, only calling
211 this and the judge_scroll_bars_hook will get rid of them.
213 If non-zero, this hook should be safe to apply to any frame,
214 whether or not it can support scroll bars, and whether or not it is
215 currently displaying them. */
217 void (*condemn_scroll_bars_hook
) P_ ((FRAME_PTR frame
));
219 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
220 Note that it's okay to redeem a scroll bar that is not condemned. */
222 void (*redeem_scroll_bar_hook
) P_ ((struct window
*window
));
224 /* Remove all scroll bars on FRAME that haven't been saved since the
225 last call to `*condemn_scroll_bars_hook'.
227 This should be applied to each frame after each time its window
228 tree is redisplayed, even if it is not displaying scroll bars at the
229 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
230 calling this and condemn_scroll_bars_hook will get rid of them.
232 If non-zero, this hook should be safe to apply to any frame,
233 whether or not it can support scroll bars, and whether or not it is
234 currently displaying them. */
236 void (*judge_scroll_bars_hook
) P_ ((FRAME_PTR FRAME
));
238 /* Hook to call in estimate_mode_line_height, if any. */
240 int (* estimate_mode_line_height_hook
) P_ ((struct frame
*f
, enum face_id
));
243 /* Strings, numbers and flags taken from the termcap entry. */
245 char *TS_ins_line
; /* "al" */
246 char *TS_ins_multi_lines
; /* "AL" (one parameter, # lines to insert) */
247 char *TS_bell
; /* "bl" */
248 char *TS_clr_to_bottom
; /* "cd" */
249 char *TS_clr_line
; /* "ce", clear to end of line */
250 char *TS_clr_frame
; /* "cl" */
251 char *TS_set_scroll_region
; /* "cs" (2 params, first line and last line) */
252 char *TS_set_scroll_region_1
; /* "cS" (4 params: total lines,
253 lines above scroll region, lines below it,
254 total lines again) */
255 char *TS_del_char
; /* "dc" */
256 char *TS_del_multi_chars
; /* "DC" (one parameter, # chars to delete) */
257 char *TS_del_line
; /* "dl" */
258 char *TS_del_multi_lines
; /* "DL" (one parameter, # lines to delete) */
259 char *TS_delete_mode
; /* "dm", enter character-delete mode */
260 char *TS_end_delete_mode
; /* "ed", leave character-delete mode */
261 char *TS_end_insert_mode
; /* "ei", leave character-insert mode */
262 char *TS_ins_char
; /* "ic" */
263 char *TS_ins_multi_chars
; /* "IC" (one parameter, # chars to insert) */
264 char *TS_insert_mode
; /* "im", enter character-insert mode */
265 char *TS_pad_inserted_char
; /* "ip". Just padding, no commands. */
266 char *TS_end_keypad_mode
; /* "ke" */
267 char *TS_keypad_mode
; /* "ks" */
268 char *TS_pad_char
; /* "pc", char to use as padding */
269 char *TS_repeat
; /* "rp" (2 params, # times to repeat
270 and character to be repeated) */
271 char *TS_end_standout_mode
; /* "se" */
272 char *TS_fwd_scroll
; /* "sf" */
273 char *TS_standout_mode
; /* "so" */
274 char *TS_rev_scroll
; /* "sr" */
275 char *TS_end_termcap_modes
; /* "te" */
276 char *TS_termcap_modes
; /* "ti" */
277 char *TS_visible_bell
; /* "vb" */
278 char *TS_cursor_normal
; /* "ve" */
279 char *TS_cursor_visible
; /* "vs" */
280 char *TS_cursor_invisible
; /* "vi" */
281 char *TS_set_window
; /* "wi" (4 params, start and end of window,
282 each as vpos and hpos) */
284 /* Value of the "NC" (no_color_video) capability, or 0 if not
287 static int TN_no_color_video
;
289 /* Meaning of bits in no_color_video. Each bit set means that the
290 corresponding attribute cannot be combined with colors. */
294 NC_STANDOUT
= 1 << 0,
295 NC_UNDERLINE
= 1 << 1,
302 NC_ALT_CHARSET
= 1 << 8
305 /* "md" -- turn on bold (extra bright mode). */
307 char *TS_enter_bold_mode
;
309 /* "mh" -- turn on half-bright mode. */
311 char *TS_enter_dim_mode
;
313 /* "mb" -- enter blinking mode. */
315 char *TS_enter_blink_mode
;
317 /* "mr" -- enter reverse video mode. */
319 char *TS_enter_reverse_mode
;
321 /* "us"/"ue" -- start/end underlining. */
323 char *TS_exit_underline_mode
, *TS_enter_underline_mode
;
325 /* "ug" -- number of blanks left by underline. */
327 int TN_magic_cookie_glitch_ul
;
329 /* "as"/"ae" -- start/end alternate character set. Not really
332 char *TS_enter_alt_charset_mode
, *TS_exit_alt_charset_mode
;
334 /* "me" -- switch appearances off. */
336 char *TS_exit_attribute_mode
;
338 /* "Co" -- number of colors. */
342 /* "pa" -- max. number of color pairs on screen. Not handled yet.
343 Could be a problem if not equal to TN_max_colors * TN_max_colors. */
347 /* "op" -- SVr4 set default pair to its original value. */
351 /* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
352 1 param, the color index. */
354 char *TS_set_foreground
, *TS_set_background
;
356 int TF_hazeltine
; /* termcap hz flag. */
357 int TF_insmode_motion
; /* termcap mi flag: can move while in insert mode. */
358 int TF_standout_motion
; /* termcap mi flag: can move while in standout mode. */
359 int TF_underscore
; /* termcap ul flag: _ underlines if over-struck on
360 non-blank position. Must clear before writing _. */
361 int TF_teleray
; /* termcap xt flag: many weird consequences.
364 int TF_xs
; /* Nonzero for "xs". If set together with
365 TN_standout_width == 0, it means don't bother
366 to write any end-standout cookies. */
368 int TN_standout_width
; /* termcap sg number: width occupied by standout
371 static int RPov
; /* # chars to start a TS_repeat */
373 static int delete_in_insert_mode
; /* delete mode == insert mode */
375 static int se_is_so
; /* 1 if same string both enters and leaves
380 /* The largest frame width in any call to calculate_costs. */
384 /* The largest frame height in any call to calculate_costs. */
386 int max_frame_height
;
388 int costs_set
= 0; /* Nonzero if costs have been calculated. */
390 int insert_mode
; /* Nonzero when in insert mode. */
391 int standout_mode
; /* Nonzero when in standout mode. */
393 /* Size of window specified by higher levels.
394 This is the number of lines, from the top of frame downwards,
395 which can participate in insert-line/delete-line operations.
397 Effectively it excludes the bottom frame_height - specified_window_size
398 lines from those operations. */
400 int specified_window
;
402 /* Frame currently being redisplayed; 0 if not currently redisplaying.
403 (Direct output does not count). */
405 FRAME_PTR updating_frame
;
407 /* Provided for lisp packages. */
409 static int system_uses_terminfo
;
411 /* Flag used in tty_show/hide_cursor. */
413 static int tty_cursor_hidden
;
417 extern char *tgetstr ();
421 /* We aren't X windows, but we aren't termcap either. This makes me
422 uncertain as to what value to use for frame.output_method. For
423 this file, we'll define FRAME_TERMCAP_P to be zero so that our
424 output hooks get called instead of the termcap functions. Probably
425 the best long-term solution is to define an output_windows_nt... */
427 #undef FRAME_TERMCAP_P
428 #define FRAME_TERMCAP_P(_f_) 0
429 #endif /* WINDOWSNT */
434 if (!NILP (Vring_bell_function
))
436 Lisp_Object function
;
438 /* Temporarily set the global variable to nil
439 so that if we get an error, it stays nil
440 and we don't call it over and over.
442 We don't specbind it, because that would carefully
443 restore the bad value if there's an error
444 and make the loop of errors happen anyway. */
446 function
= Vring_bell_function
;
447 Vring_bell_function
= Qnil
;
451 Vring_bell_function
= function
;
453 else if (!FRAME_TERMCAP_P (XFRAME (selected_frame
)))
454 (*ring_bell_hook
) ();
456 OUTPUT (TS_visible_bell
&& visible_bell
? TS_visible_bell
: TS_bell
);
460 set_terminal_modes ()
462 if (FRAME_TERMCAP_P (XFRAME (selected_frame
)))
464 OUTPUT_IF (TS_termcap_modes
);
465 OUTPUT_IF (TS_cursor_visible
);
466 OUTPUT_IF (TS_keypad_mode
);
470 (*set_terminal_modes_hook
) ();
474 reset_terminal_modes ()
476 if (FRAME_TERMCAP_P (XFRAME (selected_frame
)))
478 if (TN_standout_width
< 0)
479 turn_off_highlight ();
481 OUTPUT_IF (TS_end_keypad_mode
);
482 OUTPUT_IF (TS_cursor_normal
);
483 OUTPUT_IF (TS_end_termcap_modes
);
484 OUTPUT_IF (TS_orig_pair
);
485 /* Output raw CR so kernel can track the cursor hpos. */
486 /* But on magic-cookie terminals this can erase an end-standout
487 marker and cause the rest of the frame to be in standout, so
489 if (TN_standout_width
>= 0)
493 else if (reset_terminal_modes_hook
)
494 (*reset_terminal_modes_hook
) ();
502 if (!FRAME_TERMCAP_P (f
))
503 update_begin_hook (f
);
510 if (FRAME_TERMCAP_P (f
))
512 if (!XWINDOW (selected_window
)->cursor_off_p
)
515 background_highlight ();
520 updating_frame
= NULL
;
524 set_terminal_window (size
)
527 if (FRAME_TERMCAP_P (updating_frame
))
529 specified_window
= size
? size
: FRAME_HEIGHT (updating_frame
);
530 if (scroll_region_ok
)
531 set_scroll_region (0, specified_window
);
534 set_terminal_window_hook (size
);
538 set_scroll_region (start
, stop
)
542 struct frame
*sf
= XFRAME (selected_frame
);
544 if (TS_set_scroll_region
)
545 buf
= tparam (TS_set_scroll_region
, 0, 0, start
, stop
- 1);
546 else if (TS_set_scroll_region_1
)
547 buf
= tparam (TS_set_scroll_region_1
, 0, 0,
548 FRAME_HEIGHT (sf
), start
,
549 FRAME_HEIGHT (sf
) - stop
,
552 buf
= tparam (TS_set_window
, 0, 0, start
, 0, stop
, FRAME_WIDTH (sf
));
564 OUTPUT (TS_insert_mode
);
572 OUTPUT (TS_end_insert_mode
);
576 /* Handle highlighting when TN_standout_width (termcap sg) is not specified.
577 In these terminals, output is affected by the value of standout
578 mode when the output is written.
580 These functions are called on all terminals, but do nothing
581 on terminals whose standout mode does not work that way. */
584 turn_off_highlight ()
586 if (TN_standout_width
< 0)
589 OUTPUT_IF (TS_end_standout_mode
);
597 if (TN_standout_width
< 0)
600 OUTPUT_IF (TS_standout_mode
);
609 turn_off_highlight ();
611 turn_on_highlight ();
615 /* Make cursor invisible. */
620 if (tty_cursor_hidden
== 0)
622 tty_cursor_hidden
= 1;
623 OUTPUT_IF (TS_cursor_invisible
);
628 /* Ensure that cursor is visible. */
633 if (tty_cursor_hidden
)
635 tty_cursor_hidden
= 0;
636 OUTPUT_IF (TS_cursor_normal
);
637 OUTPUT_IF (TS_cursor_visible
);
642 /* Set standout mode to the state it should be in for
643 empty space inside windows. What this is,
644 depends on the user option inverse-video. */
647 background_highlight ()
649 if (TN_standout_width
>= 0)
652 turn_on_highlight ();
654 turn_off_highlight ();
657 /* Set standout mode to the mode specified for the text to be output. */
660 highlight_if_desired ()
662 if (TN_standout_width
>= 0)
665 turn_on_highlight ();
667 turn_off_highlight ();
671 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
672 frame-relative coordinates. */
675 cursor_to (vpos
, hpos
)
678 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
680 if (! FRAME_TERMCAP_P (f
) && cursor_to_hook
)
682 (*cursor_to_hook
) (vpos
, hpos
);
686 /* Detect the case where we are called from reset_sys_modes
687 and the costs have never been calculated. Do nothing. */
691 if (curY
== vpos
&& curX
== hpos
)
693 if (!TF_standout_motion
)
694 background_highlight ();
695 if (!TF_insmode_motion
)
700 /* Similar but don't take any account of the wasted characters. */
703 raw_cursor_to (row
, col
)
706 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
707 if (! FRAME_TERMCAP_P (f
))
709 (*raw_cursor_to_hook
) (row
, col
);
712 if (curY
== row
&& curX
== col
)
714 if (!TF_standout_motion
)
715 background_highlight ();
716 if (!TF_insmode_motion
)
721 /* Erase operations */
723 /* clear from cursor to end of frame */
729 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
731 (*clear_to_end_hook
) ();
734 if (TS_clr_to_bottom
)
736 background_highlight ();
737 OUTPUT (TS_clr_to_bottom
);
741 for (i
= curY
; i
< FRAME_HEIGHT (XFRAME (selected_frame
)); i
++)
744 clear_end_of_line (FRAME_WIDTH (XFRAME (selected_frame
)));
749 /* Clear entire frame */
754 struct frame
*sf
= XFRAME (selected_frame
);
757 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: sf
)))
759 (*clear_frame_hook
) ();
764 background_highlight ();
765 OUTPUT (TS_clr_frame
);
775 /* Clear from cursor to end of line.
776 Assume that the line is already clear starting at column first_unused_hpos.
778 Note that the cursor may be moved, on terminals lacking a `ce' string. */
781 clear_end_of_line (first_unused_hpos
)
782 int first_unused_hpos
;
786 if (clear_end_of_line_hook
787 && ! FRAME_TERMCAP_P ((updating_frame
789 : XFRAME (selected_frame
))))
791 (*clear_end_of_line_hook
) (first_unused_hpos
);
795 /* Detect the case where we are called from reset_sys_modes
796 and the costs have never been calculated. Do nothing. */
800 if (curX
>= first_unused_hpos
)
802 background_highlight ();
805 OUTPUT1 (TS_clr_line
);
808 { /* have to do it the hard way */
809 struct frame
*sf
= XFRAME (selected_frame
);
812 /* Do not write in last row last col with Auto-wrap on. */
813 if (AutoWrap
&& curY
== FRAME_HEIGHT (sf
) - 1
814 && first_unused_hpos
== FRAME_WIDTH (sf
))
817 for (i
= curX
; i
< first_unused_hpos
; i
++)
820 fputc (' ', termscript
);
823 cmplus (first_unused_hpos
- curX
);
827 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
828 store them at DST. Do not write more than DST_LEN bytes. That may
829 require stopping before all SRC_LEN input glyphs have been
832 We store the number of glyphs actually converted in *CONSUMED. The
833 return value is the number of bytes store in DST. */
836 encode_terminal_code (src
, dst
, src_len
, dst_len
, consumed
)
840 int dst_len
, *consumed
;
842 struct glyph
*src_start
= src
, *src_end
= src
+ src_len
;
843 unsigned char *dst_start
= dst
, *dst_end
= dst
+ dst_len
;
845 unsigned char workbuf
[MAX_MULTIBYTE_LENGTH
], *buf
;
847 register int tlen
= GLYPH_TABLE_LENGTH
;
848 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
850 struct coding_system
*coding
;
852 /* If terminal_coding does any conversion, use it, otherwise use
853 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
854 because it always return 1 if the member src_multibyte is 1. */
855 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
857 : &safe_terminal_coding
);
859 while (src
< src_end
)
861 /* We must skip glyphs to be padded for a wide character. */
862 if (! CHAR_GLYPH_PADDING_P (*src
))
864 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
866 if (g
< 0 || g
>= tlen
)
868 /* This glyph doesn't has an entry in Vglyph_table. */
869 if (! CHAR_VALID_P (src
->u
.ch
, 0))
873 coding
->src_multibyte
= 0;
877 len
= CHAR_STRING (src
->u
.ch
, workbuf
);
879 coding
->src_multibyte
= 1;
884 /* This glyph has an entry in Vglyph_table,
885 so process any alias before testing for simpleness. */
886 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
888 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
890 /* We set the multi-byte form of a character in G
891 (that should be an ASCII character) at
893 workbuf
[0] = FAST_GLYPH_CHAR (g
);
896 coding
->src_multibyte
= 0;
900 /* We have a string in Vglyph_table. */
901 len
= GLYPH_LENGTH (tbase
, g
);
902 buf
= GLYPH_STRING (tbase
, g
);
903 coding
->src_multibyte
= STRING_MULTIBYTE (tbase
[g
]);
907 result
= encode_coding (coding
, buf
, dst
, len
, dst_end
- dst
);
908 len
-= coding
->consumed
;
909 dst
+= coding
->produced
;
910 if (result
== CODING_FINISH_INSUFFICIENT_DST
911 || (result
== CODING_FINISH_INSUFFICIENT_SRC
912 && len
> dst_end
- dst
))
913 /* The remaining output buffer is too short. We must
914 break the loop here without increasing SRC so that the
915 next call of this function starts from the same glyph. */
920 /* This is the case that a code of the range 0200..0237
921 exists in buf. We must just write out such a code. */
922 buf
+= coding
->consumed
;
930 *consumed
= src
- src_start
;
931 return (dst
- dst_start
);
936 write_glyphs (string
, len
)
937 register struct glyph
*string
;
940 int produced
, consumed
;
941 struct frame
*sf
= XFRAME (selected_frame
);
942 struct frame
*f
= updating_frame
? updating_frame
: sf
;
943 unsigned char conversion_buffer
[1024];
944 int conversion_buffer_size
= sizeof conversion_buffer
;
946 if (write_glyphs_hook
947 && ! FRAME_TERMCAP_P (f
))
949 (*write_glyphs_hook
) (string
, len
);
956 /* Don't dare write in last column of bottom line, if Auto-Wrap,
957 since that would scroll the whole frame on some terminals. */
960 && curY
+ 1 == FRAME_HEIGHT (sf
)
961 && (curX
+ len
) == FRAME_WIDTH (sf
))
968 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
970 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
974 /* Identify a run of glyphs with the same face. */
975 int face_id
= string
->face_id
;
978 for (n
= 1; n
< len
; ++n
)
979 if (string
[n
].face_id
!= face_id
)
982 /* Turn appearance modes of the face of the run on. */
983 highlight_if_desired ();
984 turn_on_face (f
, face_id
);
988 /* We use a fixed size (1024 bytes) of conversion buffer.
989 Usually it is sufficient, but if not, we just repeat the
991 produced
= encode_terminal_code (string
, conversion_buffer
,
992 n
, conversion_buffer_size
,
996 fwrite (conversion_buffer
, 1, produced
, stdout
);
1000 fwrite (conversion_buffer
, 1, produced
, termscript
);
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
, stdout
);
1021 if (ferror (stdout
))
1024 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
1032 /* If start is zero, insert blanks instead of a string at start */
1035 insert_glyphs (start
, len
)
1036 register struct glyph
*start
;
1040 struct glyph
*glyph
= NULL
;
1041 struct frame
*f
, *sf
;
1046 if (insert_glyphs_hook
)
1048 (*insert_glyphs_hook
) (start
, len
);
1052 sf
= XFRAME (selected_frame
);
1053 f
= updating_frame
? updating_frame
: sf
;
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 (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 (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
, stdout
);
1108 if (ferror (stdout
))
1111 fwrite (conversion_buffer
, 1, produced
, termscript
);
1114 OUTPUT1_IF (TS_pad_inserted_char
);
1117 turn_off_face (f
, glyph
->face_id
);
1118 turn_off_highlight ();
1132 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1134 (*delete_glyphs_hook
) (n
);
1138 if (delete_in_insert_mode
)
1145 OUTPUT_IF (TS_delete_mode
);
1148 if (TS_del_multi_chars
)
1150 buf
= tparam (TS_del_multi_chars
, 0, 0, n
);
1155 for (i
= 0; i
< n
; i
++)
1156 OUTPUT1 (TS_del_char
);
1157 if (!delete_in_insert_mode
)
1158 OUTPUT_IF (TS_end_delete_mode
);
1161 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1164 ins_del_lines (vpos
, n
)
1167 char *multi
= n
> 0 ? TS_ins_multi_lines
: TS_del_multi_lines
;
1168 char *single
= n
> 0 ? TS_ins_line
: TS_del_line
;
1169 char *scroll
= n
> 0 ? TS_rev_scroll
: TS_fwd_scroll
;
1172 register int i
= n
> 0 ? n
: -n
;
1175 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1177 (*ins_del_lines_hook
) (vpos
, n
);
1181 sf
= XFRAME (selected_frame
);
1183 /* If the lines below the insertion are being pushed
1184 into the end of the window, this is the same as clearing;
1185 and we know the lines are already clear, since the matching
1186 deletion has already been done. So can ignore this. */
1187 /* If the lines below the deletion are blank lines coming
1188 out of the end of the window, don't bother,
1189 as there will be a matching inslines later that will flush them. */
1190 if (scroll_region_ok
&& vpos
+ i
>= specified_window
)
1192 if (!memory_below_frame
&& vpos
+ i
>= FRAME_HEIGHT (sf
))
1197 raw_cursor_to (vpos
, 0);
1198 background_highlight ();
1199 buf
= tparam (multi
, 0, 0, i
);
1205 raw_cursor_to (vpos
, 0);
1206 background_highlight ();
1214 set_scroll_region (vpos
, specified_window
);
1216 raw_cursor_to (specified_window
- 1, 0);
1218 raw_cursor_to (vpos
, 0);
1219 background_highlight ();
1221 OUTPUTL (scroll
, specified_window
- vpos
);
1222 set_scroll_region (0, specified_window
);
1225 if (TN_standout_width
>= 0)
1227 register int lower_limit
1230 : FRAME_HEIGHT (sf
));
1232 if (!scroll_region_ok
&& memory_below_frame
&& n
< 0)
1234 cursor_to (FRAME_HEIGHT (sf
) + n
, 0);
1239 /* Compute cost of sending "str", in characters,
1240 not counting any line-dependent padding. */
1248 tputs (str
, 0, evalcost
);
1252 /* Compute cost of sending "str", in characters,
1253 counting any line-dependent padding at one line. */
1256 string_cost_one_line (str
)
1261 tputs (str
, 1, evalcost
);
1265 /* Compute per line amount of line-dependent padding,
1266 in tenths of characters. */
1274 tputs (str
, 0, evalcost
);
1277 tputs (str
, 10, evalcost
);
1282 /* char_ins_del_cost[n] is cost of inserting N characters.
1283 char_ins_del_cost[-n] is cost of deleting N characters.
1284 The length of this vector is based on max_frame_width. */
1286 int *char_ins_del_vector
;
1288 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH ((f))])
1293 calculate_ins_del_char_costs (frame
)
1296 int ins_startup_cost
, del_startup_cost
;
1297 int ins_cost_per_char
, del_cost_per_char
;
1301 if (TS_ins_multi_chars
)
1303 ins_cost_per_char
= 0;
1304 ins_startup_cost
= string_cost_one_line (TS_ins_multi_chars
);
1306 else if (TS_ins_char
|| TS_pad_inserted_char
1307 || (TS_insert_mode
&& TS_end_insert_mode
))
1309 ins_startup_cost
= (30 * (string_cost (TS_insert_mode
)
1310 + string_cost (TS_end_insert_mode
))) / 100;
1311 ins_cost_per_char
= (string_cost_one_line (TS_ins_char
)
1312 + string_cost_one_line (TS_pad_inserted_char
));
1316 ins_startup_cost
= 9999;
1317 ins_cost_per_char
= 0;
1320 if (TS_del_multi_chars
)
1322 del_cost_per_char
= 0;
1323 del_startup_cost
= string_cost_one_line (TS_del_multi_chars
);
1325 else if (TS_del_char
)
1327 del_startup_cost
= (string_cost (TS_delete_mode
)
1328 + string_cost (TS_end_delete_mode
));
1329 if (delete_in_insert_mode
)
1330 del_startup_cost
/= 2;
1331 del_cost_per_char
= string_cost_one_line (TS_del_char
);
1335 del_startup_cost
= 9999;
1336 del_cost_per_char
= 0;
1339 /* Delete costs are at negative offsets */
1340 p
= &char_ins_del_cost (frame
)[0];
1341 for (i
= FRAME_WIDTH (frame
); --i
>= 0;)
1342 *--p
= (del_startup_cost
+= del_cost_per_char
);
1344 /* Doing nothing is free */
1345 p
= &char_ins_del_cost (frame
)[0];
1348 /* Insert costs are at positive offsets */
1349 for (i
= FRAME_WIDTH (frame
); --i
>= 0;)
1350 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1354 calculate_costs (frame
)
1357 register char *f
= (TS_set_scroll_region
1358 ? TS_set_scroll_region
1359 : TS_set_scroll_region_1
);
1361 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1363 scroll_region_cost
= string_cost (f
);
1365 /* These variables are only used for terminal stuff. They are allocated
1366 once for the terminal frame of X-windows emacs, but not used afterwards.
1368 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1369 X turns off char_ins_del_ok. */
1371 max_frame_height
= max (max_frame_height
, FRAME_HEIGHT (frame
));
1372 max_frame_width
= max (max_frame_width
, FRAME_WIDTH (frame
));
1376 if (char_ins_del_vector
!= 0)
1378 = (int *) xrealloc (char_ins_del_vector
,
1380 + 2 * max_frame_width
* sizeof (int)));
1383 = (int *) xmalloc (sizeof (int)
1384 + 2 * max_frame_width
* sizeof (int));
1386 bzero (char_ins_del_vector
, (sizeof (int)
1387 + 2 * max_frame_width
* sizeof (int)));
1389 if (f
&& (!TS_ins_line
&& !TS_del_line
))
1390 do_line_insertion_deletion_costs (frame
,
1391 TS_rev_scroll
, TS_ins_multi_lines
,
1392 TS_fwd_scroll
, TS_del_multi_lines
,
1395 do_line_insertion_deletion_costs (frame
,
1396 TS_ins_line
, TS_ins_multi_lines
,
1397 TS_del_line
, TS_del_multi_lines
,
1400 calculate_ins_del_char_costs (frame
);
1402 /* Don't use TS_repeat if its padding is worse than sending the chars */
1403 if (TS_repeat
&& per_line_cost (TS_repeat
) * baud_rate
< 9000)
1404 RPov
= string_cost (TS_repeat
);
1406 RPov
= FRAME_WIDTH (frame
) * 2;
1408 cmcostinit (); /* set up cursor motion costs */
1415 /* Termcap capability names that correspond directly to X keysyms.
1416 Some of these (marked "terminfo") aren't supplied by old-style
1417 (Berkeley) termcap entries. They're listed in X keysym order;
1418 except we put the keypad keys first, so that if they clash with
1419 other keys (as on the IBM PC keyboard) they get overridden.
1422 static struct fkey_table keys
[] =
1424 "kh", "home", /* termcap */
1425 "kl", "left", /* termcap */
1426 "ku", "up", /* termcap */
1427 "kr", "right", /* termcap */
1428 "kd", "down", /* termcap */
1429 "%8", "prior", /* terminfo */
1430 "%5", "next", /* terminfo */
1431 "@7", "end", /* terminfo */
1432 "@1", "begin", /* terminfo */
1433 "*6", "select", /* terminfo */
1434 "%9", "print", /* terminfo */
1435 "@4", "execute", /* terminfo --- actually the `command' key */
1437 * "insert" --- see below
1439 "&8", "undo", /* terminfo */
1440 "%0", "redo", /* terminfo */
1441 "%7", "menu", /* terminfo --- actually the `options' key */
1442 "@0", "find", /* terminfo */
1443 "@2", "cancel", /* terminfo */
1444 "%1", "help", /* terminfo */
1446 * "break" goes here, but can't be reliably intercepted with termcap
1448 "&4", "reset", /* terminfo --- actually `restart' */
1450 * "system" and "user" --- no termcaps
1452 "kE", "clearline", /* terminfo */
1453 "kA", "insertline", /* terminfo */
1454 "kL", "deleteline", /* terminfo */
1455 "kI", "insertchar", /* terminfo */
1456 "kD", "deletechar", /* terminfo */
1457 "kB", "backtab", /* terminfo */
1459 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1461 "@8", "kp-enter", /* terminfo */
1463 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1464 * "kp-multiply", "kp-add", "kp-separator",
1465 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1466 * --- no termcaps for any of these.
1468 "K4", "kp-1", /* terminfo */
1470 * "kp-2" --- no termcap
1472 "K5", "kp-3", /* terminfo */
1474 * "kp-4" --- no termcap
1476 "K2", "kp-5", /* terminfo */
1478 * "kp-6" --- no termcap
1480 "K1", "kp-7", /* terminfo */
1482 * "kp-8" --- no termcap
1484 "K3", "kp-9", /* terminfo */
1486 * "kp-equal" --- no termcap
1499 static char **term_get_fkeys_arg
;
1500 static Lisp_Object
term_get_fkeys_1 ();
1502 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1503 This function scans the termcap function key sequence entries, and
1504 adds entries to Vfunction_key_map for each function key it finds. */
1507 term_get_fkeys (address
)
1510 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1511 errors during the call. The only errors should be from Fdefine_key
1512 when given a key sequence containing an invalid prefix key. If the
1513 termcap defines function keys which use a prefix that is already bound
1514 to a command by the default bindings, we should silently ignore that
1515 function key specification, rather than giving the user an error and
1516 refusing to run at all on such a terminal. */
1518 extern Lisp_Object
Fidentity ();
1519 term_get_fkeys_arg
= address
;
1520 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1528 char **address
= term_get_fkeys_arg
;
1530 /* This can happen if CANNOT_DUMP or with strange options. */
1532 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1534 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1536 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1538 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1539 Fmake_vector (make_number (1),
1540 intern (keys
[i
].name
)));
1543 /* The uses of the "k0" capability are inconsistent; sometimes it
1544 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1545 We will attempt to politely accommodate both systems by testing for
1546 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1549 char *k_semi
= tgetstr ("k;", address
);
1550 char *k0
= tgetstr ("k0", address
);
1551 char *k0_name
= "f10";
1555 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1556 Fmake_vector (make_number (1), intern ("f10")));
1561 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1562 Fmake_vector (make_number (1), intern (k0_name
)));
1565 /* Set up cookies for numbered function keys above f10. */
1567 char fcap
[3], fkey
[4];
1569 fcap
[0] = 'F'; fcap
[2] = '\0';
1570 for (i
= 11; i
< 64; i
++)
1573 fcap
[1] = '1' + i
- 11;
1575 fcap
[1] = 'A' + i
- 20;
1577 fcap
[1] = 'a' + i
- 46;
1580 char *sequence
= tgetstr (fcap
, address
);
1583 sprintf (fkey
, "f%d", i
);
1584 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1585 Fmake_vector (make_number (1),
1593 * Various mappings to try and get a better fit.
1596 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1597 if (!tgetstr (cap1, address)) \
1599 char *sequence = tgetstr (cap2, address); \
1601 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1602 Fmake_vector (make_number (1), \
1606 /* if there's no key_next keycap, map key_npage to `next' keysym */
1607 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1608 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1609 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1610 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1611 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1612 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1613 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1615 /* IBM has their own non-standard dialect of terminfo.
1616 If the standard name isn't found, try the IBM name. */
1617 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1618 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1619 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1620 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1621 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1622 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1623 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1624 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1625 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1626 #undef CONDITIONAL_REASSIGN
1633 /***********************************************************************
1634 Character Display Information
1635 ***********************************************************************/
1637 static void append_glyph
P_ ((struct it
*));
1640 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1641 terminal frames if IT->glyph_row != NULL. IT->c is the character
1642 for which to produce glyphs; IT->face_id contains the character's
1643 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1650 struct glyph
*glyph
, *end
;
1653 xassert (it
->glyph_row
);
1654 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1655 + it
->glyph_row
->used
[it
->area
]);
1656 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1659 i
< it
->pixel_width
&& glyph
< end
;
1662 glyph
->type
= CHAR_GLYPH
;
1663 glyph
->pixel_width
= 1;
1664 glyph
->u
.ch
= it
->c
;
1665 glyph
->face_id
= it
->face_id
;
1666 glyph
->padding_p
= i
> 0;
1667 glyph
->charpos
= CHARPOS (it
->position
);
1668 glyph
->object
= it
->object
;
1670 ++it
->glyph_row
->used
[it
->area
];
1676 /* Produce glyphs for the display element described by IT. The
1677 function fills output fields of IT with pixel information like the
1678 pixel width and height of a character, and maybe produces glyphs at
1679 the same time if IT->glyph_row is non-null. See the explanation of
1680 struct display_iterator in dispextern.h for an overview. */
1686 /* If a hook is installed, let it do the work. */
1687 xassert (it
->what
== IT_CHARACTER
1688 || it
->what
== IT_COMPOSITION
1689 || it
->what
== IT_IMAGE
1690 || it
->what
== IT_STRETCH
);
1692 /* Nothing but characters are supported on terminal frames. For a
1693 composition sequence, it->c is the first character of the
1695 xassert (it
->what
== IT_CHARACTER
1696 || it
->what
== IT_COMPOSITION
);
1698 if (it
->c
>= 040 && it
->c
< 0177)
1700 it
->pixel_width
= it
->nglyphs
= 1;
1704 else if (it
->c
== '\n')
1705 it
->pixel_width
= it
->nglyphs
= 0;
1706 else if (it
->c
== '\t')
1708 int absolute_x
= (it
->current_x
1709 + it
->continuation_lines_width
);
1711 = (((1 + absolute_x
+ it
->tab_width
- 1)
1716 /* If part of the TAB has been displayed on the previous line
1717 which is continued now, continuation_lines_width will have
1718 been incremented already by the part that fitted on the
1719 continued line. So, we will get the right number of spaces
1721 nspaces
= next_tab_x
- absolute_x
;
1728 it
->pixel_width
= it
->len
= 1;
1736 it
->pixel_width
= nspaces
;
1737 it
->nglyphs
= nspaces
;
1739 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1741 /* Coming here means that it->c is from display table, thus we
1742 must send the code as is to the terminal. Although there's
1743 no way to know how many columns it occupies on a screen, it
1744 is a good assumption that a single byte code has 1-column
1746 it
->pixel_width
= it
->nglyphs
= 1;
1752 /* A multi-byte character. The display width is fixed for all
1753 characters of the set. Some of the glyphs may have to be
1754 ignored because they are already displayed in a continued
1756 int charset
= CHAR_CHARSET (it
->c
);
1758 it
->pixel_width
= CHARSET_WIDTH (charset
);
1759 it
->nglyphs
= it
->pixel_width
;
1765 /* Advance current_x by the pixel width as a convenience for
1767 if (it
->area
== TEXT_AREA
)
1768 it
->current_x
+= it
->pixel_width
;
1769 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1770 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1774 /* Get information about special display element WHAT in an
1775 environment described by IT. WHAT is one of IT_TRUNCATION or
1776 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1777 non-null glyph_row member. This function ensures that fields like
1778 face_id, c, len of IT are left untouched. */
1781 produce_special_glyphs (it
, what
)
1783 enum display_element_type what
;
1789 temp_it
.what
= IT_CHARACTER
;
1791 temp_it
.object
= make_number (0);
1792 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1794 if (what
== IT_CONTINUATION
)
1796 /* Continuation glyph. */
1798 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1799 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1801 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it
->dp
)));
1802 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1807 produce_glyphs (&temp_it
);
1808 it
->pixel_width
= temp_it
.pixel_width
;
1809 it
->nglyphs
= temp_it
.pixel_width
;
1811 else if (what
== IT_TRUNCATION
)
1813 /* Truncation glyph. */
1815 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1816 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1818 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it
->dp
)));
1819 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1824 produce_glyphs (&temp_it
);
1825 it
->pixel_width
= temp_it
.pixel_width
;
1826 it
->nglyphs
= temp_it
.pixel_width
;
1833 /* Return an estimation of the pixel height of mode or top lines on
1834 frame F. FACE_ID specifies what line's height to estimate. */
1837 estimate_mode_line_height (f
, face_id
)
1839 enum face_id face_id
;
1841 if (estimate_mode_line_height_hook
)
1842 return estimate_mode_line_height_hook (f
, face_id
);
1849 /***********************************************************************
1851 ***********************************************************************/
1853 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1854 one of the enumerators from enum no_color_bit, or a bit set built
1855 from them. Some display attributes may not be used together with
1856 color; the termcap capability `NC' specifies which ones. */
1858 #define MAY_USE_WITH_COLORS_P(ATTR) \
1859 (TN_max_colors > 0 \
1860 ? (TN_no_color_video & (ATTR)) == 0 \
1863 /* Turn appearances of face FACE_ID on tty frame F on. */
1866 turn_on_face (f
, face_id
)
1870 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1871 long fg
= face
->foreground
;
1872 long bg
= face
->background
;
1874 /* Do this first because TS_end_standout_mode may be the same
1875 as TS_exit_attribute_mode, which turns all appearances off. */
1876 if (MAY_USE_WITH_COLORS_P (NC_REVERSE
))
1878 if (TN_max_colors
> 0)
1880 if (fg
>= 0 && bg
>= 0)
1882 /* If the terminal supports colors, we can set them
1883 below without using reverse video. The face's fg
1884 and bg colors are set as they should appear on
1885 the screen, i.e. they take the inverse-video'ness
1886 of the face already into account. */
1888 else if (inverse_video
)
1890 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1891 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1892 toggle_highlight ();
1896 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1897 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1898 toggle_highlight ();
1903 /* If we can't display colors, use reverse video
1904 if the face specifies that. */
1907 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1908 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1909 toggle_highlight ();
1913 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1914 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1915 toggle_highlight ();
1920 if (face
->tty_bold_p
)
1922 if (MAY_USE_WITH_COLORS_P (NC_BOLD
))
1923 OUTPUT1_IF (TS_enter_bold_mode
);
1925 else if (face
->tty_dim_p
)
1926 if (MAY_USE_WITH_COLORS_P (NC_DIM
))
1927 OUTPUT1_IF (TS_enter_dim_mode
);
1929 /* Alternate charset and blinking not yet used. */
1930 if (face
->tty_alt_charset_p
1931 && MAY_USE_WITH_COLORS_P (NC_ALT_CHARSET
))
1932 OUTPUT1_IF (TS_enter_alt_charset_mode
);
1934 if (face
->tty_blinking_p
1935 && MAY_USE_WITH_COLORS_P (NC_BLINK
))
1936 OUTPUT1_IF (TS_enter_blink_mode
);
1938 if (face
->tty_underline_p
1939 /* Don't underline if that's difficult. */
1940 && TN_magic_cookie_glitch_ul
<= 0
1941 && MAY_USE_WITH_COLORS_P (NC_UNDERLINE
))
1942 OUTPUT1_IF (TS_enter_underline_mode
);
1944 if (TN_max_colors
> 0)
1948 if (fg
>= 0 && TS_set_foreground
)
1950 p
= tparam (TS_set_foreground
, NULL
, 0, (int) fg
);
1955 if (bg
>= 0 && TS_set_background
)
1957 p
= tparam (TS_set_background
, NULL
, 0, (int) bg
);
1965 /* Turn off appearances of face FACE_ID on tty frame F. */
1968 turn_off_face (f
, face_id
)
1972 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1974 xassert (face
!= NULL
);
1976 if (TS_exit_attribute_mode
)
1978 /* Capability "me" will turn off appearance modes double-bright,
1979 half-bright, reverse-video, standout, underline. It may or
1980 may not turn off alt-char-mode. */
1981 if (face
->tty_bold_p
1983 || face
->tty_reverse_p
1984 || face
->tty_alt_charset_p
1985 || face
->tty_blinking_p
1986 || face
->tty_underline_p
)
1988 OUTPUT1_IF (TS_exit_attribute_mode
);
1989 if (strcmp (TS_exit_attribute_mode
, TS_end_standout_mode
) == 0)
1993 if (face
->tty_alt_charset_p
)
1994 OUTPUT_IF (TS_exit_alt_charset_mode
);
1998 /* If we don't have "me" we can only have those appearances
1999 that have exit sequences defined. */
2000 if (face
->tty_alt_charset_p
)
2001 OUTPUT_IF (TS_exit_alt_charset_mode
);
2003 if (face
->tty_underline_p
2004 /* We don't underline if that's difficult. */
2005 && TN_magic_cookie_glitch_ul
<= 0)
2006 OUTPUT_IF (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 (TS_orig_pair
);
2019 /* Return non-zero if the terminal is capable to display colors. */
2021 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2023 doc
: /* Return non-nil if TTY can display colors on FRAME. */)
2027 return TN_max_colors
> 0 ? Qt
: Qnil
;
2033 /***********************************************************************
2035 ***********************************************************************/
2038 term_init (terminal_type
)
2039 char *terminal_type
;
2042 char **address
= &area
;
2046 struct frame
*sf
= XFRAME (selected_frame
);
2049 initialize_w32_display ();
2053 area
= (char *) xmalloc (2044);
2058 FrameRows
= FRAME_HEIGHT (sf
);
2059 FrameCols
= FRAME_WIDTH (sf
);
2060 specified_window
= FRAME_HEIGHT (sf
);
2062 delete_in_insert_mode
= 1;
2065 scroll_region_ok
= 0;
2067 /* Seems to insert lines when it's not supposed to, messing
2068 up the display. In doing a trace, it didn't seem to be
2069 called much, so I don't think we're losing anything by
2072 line_ins_del_ok
= 0;
2073 char_ins_del_ok
= 1;
2077 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
2078 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
2079 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2082 #else /* not WINDOWSNT */
2086 status
= tgetent (buffer
, terminal_type
);
2090 fatal ("Cannot open terminfo database file");
2092 fatal ("Cannot open termcap database file");
2098 fatal ("Terminal type %s is not defined.\n\
2099 If that is not the actual type of terminal you have,\n\
2100 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2101 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2102 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2105 fatal ("Terminal type %s is not defined.\n\
2106 If that is not the actual type of terminal you have,\n\
2107 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2108 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2109 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2114 area
= (char *) xmalloc (2044);
2116 area
= (char *) xmalloc (strlen (buffer
));
2117 #endif /* not TERMINFO */
2121 TS_ins_line
= tgetstr ("al", address
);
2122 TS_ins_multi_lines
= tgetstr ("AL", address
);
2123 TS_bell
= tgetstr ("bl", address
);
2124 BackTab
= tgetstr ("bt", address
);
2125 TS_clr_to_bottom
= tgetstr ("cd", address
);
2126 TS_clr_line
= tgetstr ("ce", address
);
2127 TS_clr_frame
= tgetstr ("cl", address
);
2128 ColPosition
= NULL
; /* tgetstr ("ch", address); */
2129 AbsPosition
= tgetstr ("cm", address
);
2130 CR
= tgetstr ("cr", address
);
2131 TS_set_scroll_region
= tgetstr ("cs", address
);
2132 TS_set_scroll_region_1
= tgetstr ("cS", address
);
2133 RowPosition
= tgetstr ("cv", address
);
2134 TS_del_char
= tgetstr ("dc", address
);
2135 TS_del_multi_chars
= tgetstr ("DC", address
);
2136 TS_del_line
= tgetstr ("dl", address
);
2137 TS_del_multi_lines
= tgetstr ("DL", address
);
2138 TS_delete_mode
= tgetstr ("dm", address
);
2139 TS_end_delete_mode
= tgetstr ("ed", address
);
2140 TS_end_insert_mode
= tgetstr ("ei", address
);
2141 Home
= tgetstr ("ho", address
);
2142 TS_ins_char
= tgetstr ("ic", address
);
2143 TS_ins_multi_chars
= tgetstr ("IC", address
);
2144 TS_insert_mode
= tgetstr ("im", address
);
2145 TS_pad_inserted_char
= tgetstr ("ip", address
);
2146 TS_end_keypad_mode
= tgetstr ("ke", address
);
2147 TS_keypad_mode
= tgetstr ("ks", address
);
2148 LastLine
= tgetstr ("ll", address
);
2149 Right
= tgetstr ("nd", address
);
2150 Down
= tgetstr ("do", address
);
2152 Down
= tgetstr ("nl", address
); /* Obsolete name for "do" */
2154 /* VMS puts a carriage return before each linefeed,
2155 so it is not safe to use linefeeds. */
2156 if (Down
&& Down
[0] == '\n' && Down
[1] == '\0')
2159 if (tgetflag ("bs"))
2160 Left
= "\b"; /* can't possibly be longer! */
2161 else /* (Actually, "bs" is obsolete...) */
2162 Left
= tgetstr ("le", address
);
2164 Left
= tgetstr ("bc", address
); /* Obsolete name for "le" */
2165 TS_pad_char
= tgetstr ("pc", address
);
2166 TS_repeat
= tgetstr ("rp", address
);
2167 TS_end_standout_mode
= tgetstr ("se", address
);
2168 TS_fwd_scroll
= tgetstr ("sf", address
);
2169 TS_standout_mode
= tgetstr ("so", address
);
2170 TS_rev_scroll
= tgetstr ("sr", address
);
2171 Wcm
.cm_tab
= tgetstr ("ta", address
);
2172 TS_end_termcap_modes
= tgetstr ("te", address
);
2173 TS_termcap_modes
= tgetstr ("ti", address
);
2174 Up
= tgetstr ("up", address
);
2175 TS_visible_bell
= tgetstr ("vb", address
);
2176 TS_cursor_normal
= tgetstr ("ve", address
);
2177 TS_cursor_visible
= tgetstr ("vs", address
);
2178 TS_cursor_invisible
= tgetstr ("vi", address
);
2179 TS_set_window
= tgetstr ("wi", address
);
2181 TS_enter_underline_mode
= tgetstr ("us", address
);
2182 TS_exit_underline_mode
= tgetstr ("ue", address
);
2183 TN_magic_cookie_glitch_ul
= tgetnum ("ug");
2184 TS_enter_bold_mode
= tgetstr ("md", address
);
2185 TS_enter_dim_mode
= tgetstr ("mh", address
);
2186 TS_enter_blink_mode
= tgetstr ("mb", address
);
2187 TS_enter_reverse_mode
= tgetstr ("mr", address
);
2188 TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2189 TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2190 TS_exit_attribute_mode
= tgetstr ("me", address
);
2192 MultiUp
= tgetstr ("UP", address
);
2193 MultiDown
= tgetstr ("DO", address
);
2194 MultiLeft
= tgetstr ("LE", address
);
2195 MultiRight
= tgetstr ("RI", address
);
2197 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2198 color because we can't switch back to the default foreground and
2200 TS_orig_pair
= tgetstr ("op", address
);
2203 TS_set_foreground
= tgetstr ("AF", address
);
2204 TS_set_background
= tgetstr ("AB", address
);
2205 if (!TS_set_foreground
)
2208 TS_set_foreground
= tgetstr ("Sf", address
);
2209 TS_set_background
= tgetstr ("Sb", address
);
2212 TN_max_colors
= tgetnum ("Co");
2213 TN_max_pairs
= tgetnum ("pa");
2215 TN_no_color_video
= tgetnum ("NC");
2216 if (TN_no_color_video
== -1)
2217 TN_no_color_video
= 0;
2220 MagicWrap
= tgetflag ("xn");
2221 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2222 the former flag imply the latter. */
2223 AutoWrap
= MagicWrap
|| tgetflag ("am");
2224 memory_below_frame
= tgetflag ("db");
2225 TF_hazeltine
= tgetflag ("hz");
2226 must_write_spaces
= tgetflag ("in");
2227 meta_key
= tgetflag ("km") || tgetflag ("MT");
2228 TF_insmode_motion
= tgetflag ("mi");
2229 TF_standout_motion
= tgetflag ("ms");
2230 TF_underscore
= tgetflag ("ul");
2231 TF_xs
= tgetflag ("xs");
2232 TF_teleray
= tgetflag ("xt");
2234 term_get_fkeys (address
);
2236 /* Get frame size from system, or else from termcap. */
2239 get_frame_size (&width
, &height
);
2240 FRAME_WIDTH (sf
) = width
;
2241 FRAME_HEIGHT (sf
) = height
;
2244 if (FRAME_WIDTH (sf
) <= 0)
2245 SET_FRAME_WIDTH (sf
, tgetnum ("co"));
2247 /* Keep width and external_width consistent */
2248 SET_FRAME_WIDTH (sf
, FRAME_WIDTH (sf
));
2249 if (FRAME_HEIGHT (sf
) <= 0)
2250 FRAME_HEIGHT (sf
) = tgetnum ("li");
2252 if (FRAME_HEIGHT (sf
) < 3 || FRAME_WIDTH (sf
) < 3)
2253 fatal ("Screen size %dx%d is too small",
2254 FRAME_HEIGHT (sf
), FRAME_WIDTH (sf
));
2256 min_padding_speed
= tgetnum ("pb");
2257 TN_standout_width
= tgetnum ("sg");
2258 TabWidth
= tgetnum ("tw");
2261 /* These capabilities commonly use ^J.
2262 I don't know why, but sending them on VMS does not work;
2263 it causes following spaces to be lost, sometimes.
2264 For now, the simplest fix is to avoid using these capabilities ever. */
2265 if (Down
&& Down
[0] == '\n')
2273 TS_fwd_scroll
= Down
;
2275 PC
= TS_pad_char
? *TS_pad_char
: 0;
2280 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2281 and newer termcap doc does not seem to say there is a default.
2286 if (TS_standout_mode
== 0)
2288 TN_standout_width
= tgetnum ("ug");
2289 TS_end_standout_mode
= tgetstr ("ue", address
);
2290 TS_standout_mode
= tgetstr ("us", address
);
2293 /* If no `se' string, try using a `me' string instead.
2294 If that fails, we can't use standout mode at all. */
2295 if (TS_end_standout_mode
== 0)
2297 char *s
= tgetstr ("me", address
);
2299 TS_end_standout_mode
= s
;
2301 TS_standout_mode
= 0;
2307 /* Teleray: most programs want a space in front of TS_standout_mode,
2308 but Emacs can do without it (and give one extra column). */
2309 TS_standout_mode
= "\033RD";
2310 TN_standout_width
= 1;
2311 /* But that means we cannot rely on ^M to go to column zero! */
2313 /* LF can't be trusted either -- can alter hpos */
2314 /* if move at column 0 thru a line with TS_standout_mode */
2318 /* Special handling for certain terminal types known to need it */
2320 if (!strcmp (terminal_type
, "supdup"))
2322 memory_below_frame
= 1;
2323 Wcm
.cm_losewrap
= 1;
2325 if (!strncmp (terminal_type
, "c10", 3)
2326 || !strcmp (terminal_type
, "perq"))
2328 /* Supply a makeshift :wi string.
2329 This string is not valid in general since it works only
2330 for windows starting at the upper left corner;
2331 but that is all Emacs uses.
2333 This string works only if the frame is using
2334 the top of the video memory, because addressing is memory-relative.
2335 So first check the :ti string to see if that is true.
2337 It would be simpler if the :wi string could go in the termcap
2338 entry, but it can't because it is not fully valid.
2339 If it were in the termcap entry, it would confuse other programs. */
2342 p
= TS_termcap_modes
;
2343 while (*p
&& strcmp (p
, "\033v "))
2346 TS_set_window
= "\033v%C %C %C %C ";
2348 /* Termcap entry often fails to have :in: flag */
2349 must_write_spaces
= 1;
2350 /* :ti string typically fails to have \E^G! in it */
2351 /* This limits scope of insert-char to one line. */
2352 strcpy (area
, TS_termcap_modes
);
2353 strcat (area
, "\033\007!");
2354 TS_termcap_modes
= area
;
2355 area
+= strlen (area
) + 1;
2357 /* Change all %+ parameters to %C, to handle
2358 values above 96 correctly for the C100. */
2361 if (p
[0] == '%' && p
[1] == '+')
2367 FrameRows
= FRAME_HEIGHT (sf
);
2368 FrameCols
= FRAME_WIDTH (sf
);
2369 specified_window
= FRAME_HEIGHT (sf
);
2371 if (Wcm_init () == -1) /* can't do cursor motion */
2373 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2374 It lacks the ability to position the cursor.\n\
2375 If that is not the actual type of terminal you have, use either the\n\
2376 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2377 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2381 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2382 It lacks the ability to position the cursor.\n\
2383 If that is not the actual type of terminal you have,\n\
2384 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2385 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2386 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2388 # else /* TERMCAP */
2389 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2390 It lacks the ability to position the cursor.\n\
2391 If that is not the actual type of terminal you have,\n\
2392 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2393 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2394 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2396 # endif /* TERMINFO */
2398 if (FRAME_HEIGHT (sf
) <= 0
2399 || FRAME_WIDTH (sf
) <= 0)
2400 fatal ("The frame size has not been specified");
2402 delete_in_insert_mode
2403 = TS_delete_mode
&& TS_insert_mode
2404 && !strcmp (TS_delete_mode
, TS_insert_mode
);
2406 se_is_so
= (TS_standout_mode
2407 && TS_end_standout_mode
2408 && !strcmp (TS_standout_mode
, TS_end_standout_mode
));
2410 /* Remove width of standout marker from usable width of line */
2411 if (TN_standout_width
> 0)
2412 SET_FRAME_WIDTH (sf
, FRAME_WIDTH (sf
) - TN_standout_width
);
2414 UseTabs
= tabs_safe_p () && TabWidth
== 8;
2418 && (TS_set_window
|| TS_set_scroll_region
|| TS_set_scroll_region_1
));
2420 line_ins_del_ok
= (((TS_ins_line
|| TS_ins_multi_lines
)
2421 && (TS_del_line
|| TS_del_multi_lines
))
2422 || (scroll_region_ok
&& TS_fwd_scroll
&& TS_rev_scroll
));
2424 char_ins_del_ok
= ((TS_ins_char
|| TS_insert_mode
2425 || TS_pad_inserted_char
|| TS_ins_multi_chars
)
2426 && (TS_del_char
|| TS_del_multi_chars
));
2428 fast_clear_end_of_line
= TS_clr_line
!= 0;
2431 if (read_socket_hook
) /* Baudrate is somewhat */
2432 /* meaningless in this case */
2435 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
2436 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
2437 #endif /* WINDOWSNT */
2442 fatal (str
, arg1
, arg2
)
2443 char *str
, *arg1
, *arg2
;
2445 fprintf (stderr
, "emacs: ");
2446 fprintf (stderr
, str
, arg1
, arg2
);
2447 fprintf (stderr
, "\n");
2455 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
2456 doc
: /* Non-nil means the system uses terminfo rather than termcap.
2457 This variable can be used by terminal emulator packages. */);
2459 system_uses_terminfo
= 1;
2461 system_uses_terminfo
= 0;
2464 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
2465 doc
: /* Non-nil means call this function to ring the bell.
2466 The function should accept no arguments. */);
2467 Vring_bell_function
= Qnil
;
2469 defsubr (&Stty_display_color_p
);