1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
33 #include "character.h"
36 #include "composite.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
));
66 static void turn_on_face
P_ ((struct frame
*, int face_id
));
67 static void turn_off_face
P_ ((struct frame
*, int face_id
));
68 static void tty_show_cursor
P_ ((void));
69 static void tty_hide_cursor
P_ ((void));
72 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) - curY), cmputc)
73 #define OUTPUT1(a) tputs (a, 1, cmputc)
74 #define OUTPUTL(a, lines) tputs (a, lines, cmputc)
76 #define OUTPUT_IF(a) \
79 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) \
83 #define OUTPUT1_IF(a) do { if (a) tputs (a, 1, cmputc); } while (0)
85 /* Display space properties */
87 extern Lisp_Object Qspace
, QCalign_to
, QCwidth
;
89 /* Function to use to ring the bell. */
91 Lisp_Object Vring_bell_function
;
93 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */
95 static int visible_cursor
;
97 /* Terminal characteristics that higher levels want to look at.
98 These are all extern'd in termchar.h */
100 int must_write_spaces
; /* Nonzero means spaces in the text
101 must actually be output; can't just skip
102 over some columns to leave them blank. */
103 int min_padding_speed
; /* Speed below which no padding necessary */
105 int line_ins_del_ok
; /* Terminal can insert and delete lines */
106 int char_ins_del_ok
; /* Terminal can insert and delete chars */
107 int scroll_region_ok
; /* Terminal supports setting the
109 int scroll_region_cost
; /* Cost of setting a scroll window,
110 measured in characters */
111 int memory_below_frame
; /* Terminal remembers lines
112 scrolled off bottom */
113 int fast_clear_end_of_line
; /* Terminal has a `ce' string */
115 /* Nonzero means no need to redraw the entire frame on resuming
116 a suspended Emacs. This is useful on terminals with multiple pages,
117 where one page is used for Emacs and another for all else. */
119 int no_redraw_on_reenter
;
121 /* Hook functions that you can set to snap out the functions in this file.
122 These are all extern'd in termhooks.h */
124 void (*cursor_to_hook
) P_ ((int, int));
125 void (*raw_cursor_to_hook
) P_ ((int, int));
126 void (*clear_to_end_hook
) P_ ((void));
127 void (*clear_frame_hook
) P_ ((void));
128 void (*clear_end_of_line_hook
) P_ ((int));
130 void (*ins_del_lines_hook
) P_ ((int, int));
132 void (*delete_glyphs_hook
) P_ ((int));
134 void (*ring_bell_hook
) P_ ((void));
136 void (*reset_terminal_modes_hook
) P_ ((void));
137 void (*set_terminal_modes_hook
) P_ ((void));
138 void (*update_begin_hook
) P_ ((struct frame
*));
139 void (*update_end_hook
) P_ ((struct frame
*));
140 void (*set_terminal_window_hook
) P_ ((int));
141 void (*insert_glyphs_hook
) P_ ((struct glyph
*, int));
142 void (*write_glyphs_hook
) P_ ((struct glyph
*, int));
143 void (*delete_glyphs_hook
) P_ ((int));
145 int (*read_socket_hook
) P_ ((int, int, struct input_event
*));
147 void (*frame_up_to_date_hook
) P_ ((struct frame
*));
149 /* Return the current position of the mouse.
151 Set *f to the frame the mouse is in, or zero if the mouse is in no
152 Emacs frame. If it is set to zero, all the other arguments are
155 If the motion started in a scroll bar, set *bar_window to the
156 scroll bar's window, *part to the part the mouse is currently over,
157 *x to the position of the mouse along the scroll bar, and *y to the
158 overall length of the scroll bar.
160 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
161 row of the character cell the mouse is over.
163 Set *time to the time the mouse was at the returned position.
165 This should clear mouse_moved until the next motion
168 void (*mouse_position_hook
) P_ ((FRAME_PTR
*f
, int insist
,
169 Lisp_Object
*bar_window
,
170 enum scroll_bar_part
*part
,
173 unsigned long *time
));
175 /* When reading from a minibuffer in a different frame, Emacs wants
176 to shift the highlight from the selected frame to the mini-buffer's
177 frame; under X, this means it lies about where the focus is.
178 This hook tells the window system code to re-decide where to put
181 void (*frame_rehighlight_hook
) P_ ((FRAME_PTR f
));
183 /* If we're displaying frames using a window system that can stack
184 frames on top of each other, this hook allows you to bring a frame
185 to the front, or bury it behind all the other windows. If this
186 hook is zero, that means the device we're displaying on doesn't
187 support overlapping frames, so there's no need to raise or lower
190 If RAISE is non-zero, F is brought to the front, before all other
191 windows. If RAISE is zero, F is sent to the back, behind all other
194 void (*frame_raise_lower_hook
) P_ ((FRAME_PTR f
, int raise
));
196 /* If the value of the frame parameter changed, whis hook is called.
197 For example, if going from fullscreen to not fullscreen this hook
198 may do something OS dependent, like extended window manager hints on X11. */
199 void (*fullscreen_hook
) P_ ((struct frame
*f
));
201 /* Set the vertical scroll bar for WINDOW to have its upper left corner
202 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
203 indicate that we are displaying PORTION characters out of a total
204 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
205 have a scroll bar, create one for it. */
207 void (*set_vertical_scroll_bar_hook
)
208 P_ ((struct window
*window
,
209 int portion
, int whole
, int position
));
212 /* The following three hooks are used when we're doing a thorough
213 redisplay of the frame. We don't explicitly know which scroll bars
214 are going to be deleted, because keeping track of when windows go
215 away is a real pain - can you say set-window-configuration?
216 Instead, we just assert at the beginning of redisplay that *all*
217 scroll bars are to be removed, and then save scroll bars from the
218 fiery pit when we actually redisplay their window. */
220 /* Arrange for all scroll bars on FRAME to be removed at the next call
221 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
222 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
224 This should be applied to each frame each time its window tree is
225 redisplayed, even if it is not displaying scroll bars at the moment;
226 if the HAS_SCROLL_BARS flag has just been turned off, only calling
227 this and the judge_scroll_bars_hook will get rid of them.
229 If non-zero, this hook should be safe to apply to any frame,
230 whether or not it can support scroll bars, and whether or not it is
231 currently displaying them. */
233 void (*condemn_scroll_bars_hook
) P_ ((FRAME_PTR frame
));
235 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
236 Note that it's okay to redeem a scroll bar that is not condemned. */
238 void (*redeem_scroll_bar_hook
) P_ ((struct window
*window
));
240 /* Remove all scroll bars on FRAME that haven't been saved since the
241 last call to `*condemn_scroll_bars_hook'.
243 This should be applied to each frame after each time its window
244 tree is redisplayed, even if it is not displaying scroll bars at the
245 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
246 calling this and condemn_scroll_bars_hook will get rid of them.
248 If non-zero, this hook should be safe to apply to any frame,
249 whether or not it can support scroll bars, and whether or not it is
250 currently displaying them. */
252 void (*judge_scroll_bars_hook
) P_ ((FRAME_PTR FRAME
));
254 /* Strings, numbers and flags taken from the termcap entry. */
256 char *TS_ins_line
; /* "al" */
257 char *TS_ins_multi_lines
; /* "AL" (one parameter, # lines to insert) */
258 char *TS_bell
; /* "bl" */
259 char *TS_clr_to_bottom
; /* "cd" */
260 char *TS_clr_line
; /* "ce", clear to end of line */
261 char *TS_clr_frame
; /* "cl" */
262 char *TS_set_scroll_region
; /* "cs" (2 params, first line and last line) */
263 char *TS_set_scroll_region_1
; /* "cS" (4 params: total lines,
264 lines above scroll region, lines below it,
265 total lines again) */
266 char *TS_del_char
; /* "dc" */
267 char *TS_del_multi_chars
; /* "DC" (one parameter, # chars to delete) */
268 char *TS_del_line
; /* "dl" */
269 char *TS_del_multi_lines
; /* "DL" (one parameter, # lines to delete) */
270 char *TS_delete_mode
; /* "dm", enter character-delete mode */
271 char *TS_end_delete_mode
; /* "ed", leave character-delete mode */
272 char *TS_end_insert_mode
; /* "ei", leave character-insert mode */
273 char *TS_ins_char
; /* "ic" */
274 char *TS_ins_multi_chars
; /* "IC" (one parameter, # chars to insert) */
275 char *TS_insert_mode
; /* "im", enter character-insert mode */
276 char *TS_pad_inserted_char
; /* "ip". Just padding, no commands. */
277 char *TS_end_keypad_mode
; /* "ke" */
278 char *TS_keypad_mode
; /* "ks" */
279 char *TS_pad_char
; /* "pc", char to use as padding */
280 char *TS_repeat
; /* "rp" (2 params, # times to repeat
281 and character to be repeated) */
282 char *TS_end_standout_mode
; /* "se" */
283 char *TS_fwd_scroll
; /* "sf" */
284 char *TS_standout_mode
; /* "so" */
285 char *TS_rev_scroll
; /* "sr" */
286 char *TS_end_termcap_modes
; /* "te" */
287 char *TS_termcap_modes
; /* "ti" */
288 char *TS_visible_bell
; /* "vb" */
289 char *TS_cursor_normal
; /* "ve" */
290 char *TS_cursor_visible
; /* "vs" */
291 char *TS_cursor_invisible
; /* "vi" */
292 char *TS_set_window
; /* "wi" (4 params, start and end of window,
293 each as vpos and hpos) */
295 /* Value of the "NC" (no_color_video) capability, or 0 if not
298 static int TN_no_color_video
;
300 /* Meaning of bits in no_color_video. Each bit set means that the
301 corresponding attribute cannot be combined with colors. */
305 NC_STANDOUT
= 1 << 0,
306 NC_UNDERLINE
= 1 << 1,
313 NC_ALT_CHARSET
= 1 << 8
316 /* "md" -- turn on bold (extra bright mode). */
318 char *TS_enter_bold_mode
;
320 /* "mh" -- turn on half-bright mode. */
322 char *TS_enter_dim_mode
;
324 /* "mb" -- enter blinking mode. */
326 char *TS_enter_blink_mode
;
328 /* "mr" -- enter reverse video mode. */
330 char *TS_enter_reverse_mode
;
332 /* "us"/"ue" -- start/end underlining. */
334 char *TS_exit_underline_mode
, *TS_enter_underline_mode
;
336 /* "as"/"ae" -- start/end alternate character set. Not really
339 char *TS_enter_alt_charset_mode
, *TS_exit_alt_charset_mode
;
341 /* "me" -- switch appearances off. */
343 char *TS_exit_attribute_mode
;
345 /* "Co" -- number of colors. */
349 /* "pa" -- max. number of color pairs on screen. Not handled yet.
350 Could be a problem if not equal to TN_max_colors * TN_max_colors. */
354 /* "op" -- SVr4 set default pair to its original value. */
358 /* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
359 1 param, the color index. */
361 char *TS_set_foreground
, *TS_set_background
;
363 int TF_hazeltine
; /* termcap hz flag. */
364 int TF_insmode_motion
; /* termcap mi flag: can move while in insert mode. */
365 int TF_standout_motion
; /* termcap mi flag: can move while in standout mode. */
366 int TF_underscore
; /* termcap ul flag: _ underlines if over-struck on
367 non-blank position. Must clear before writing _. */
368 int TF_teleray
; /* termcap xt flag: many weird consequences.
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. */
388 static int costs_set
; /* 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_lines - 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 if (TS_termcap_modes
)
465 OUTPUT (TS_termcap_modes
);
468 /* Output enough newlines to scroll all the old screen contents
469 off the screen, so it won't be overwritten and lost. */
471 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
475 OUTPUT_IF (visible_cursor
? TS_cursor_visible
: TS_cursor_normal
);
476 OUTPUT_IF (TS_keypad_mode
);
480 (*set_terminal_modes_hook
) ();
484 reset_terminal_modes ()
486 if (FRAME_TERMCAP_P (XFRAME (selected_frame
)))
488 turn_off_highlight ();
490 OUTPUT_IF (TS_end_keypad_mode
);
491 OUTPUT_IF (TS_cursor_normal
);
492 OUTPUT_IF (TS_end_termcap_modes
);
493 OUTPUT_IF (TS_orig_pair
);
494 /* Output raw CR so kernel can track the cursor hpos. */
497 else if (reset_terminal_modes_hook
)
498 (*reset_terminal_modes_hook
) ();
506 if (!FRAME_TERMCAP_P (f
))
507 update_begin_hook (f
);
514 if (FRAME_TERMCAP_P (f
))
516 if (!XWINDOW (selected_window
)->cursor_off_p
)
519 background_highlight ();
524 updating_frame
= NULL
;
528 set_terminal_window (size
)
531 if (FRAME_TERMCAP_P (updating_frame
))
533 specified_window
= size
? size
: FRAME_LINES (updating_frame
);
534 if (scroll_region_ok
)
535 set_scroll_region (0, specified_window
);
538 set_terminal_window_hook (size
);
542 set_scroll_region (start
, stop
)
546 struct frame
*sf
= XFRAME (selected_frame
);
548 if (TS_set_scroll_region
)
549 buf
= tparam (TS_set_scroll_region
, 0, 0, start
, stop
- 1);
550 else if (TS_set_scroll_region_1
)
551 buf
= tparam (TS_set_scroll_region_1
, 0, 0,
552 FRAME_LINES (sf
), start
,
553 FRAME_LINES (sf
) - stop
,
556 buf
= tparam (TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (sf
));
568 OUTPUT (TS_insert_mode
);
576 OUTPUT (TS_end_insert_mode
);
580 /* Handle highlighting. */
583 turn_off_highlight ()
586 OUTPUT_IF (TS_end_standout_mode
);
594 OUTPUT_IF (TS_standout_mode
);
602 turn_off_highlight ();
604 turn_on_highlight ();
608 /* Make cursor invisible. */
613 if (tty_cursor_hidden
== 0)
615 tty_cursor_hidden
= 1;
616 OUTPUT_IF (TS_cursor_invisible
);
621 /* Ensure that cursor is visible. */
626 if (tty_cursor_hidden
)
628 tty_cursor_hidden
= 0;
629 OUTPUT_IF (TS_cursor_normal
);
631 OUTPUT_IF (TS_cursor_visible
);
636 /* Set standout mode to the state it should be in for
637 empty space inside windows. What this is,
638 depends on the user option inverse-video. */
641 background_highlight ()
644 turn_on_highlight ();
646 turn_off_highlight ();
649 /* Set standout mode to the mode specified for the text to be output. */
652 highlight_if_desired ()
655 turn_on_highlight ();
657 turn_off_highlight ();
661 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
662 frame-relative coordinates. */
665 cursor_to (vpos
, hpos
)
668 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
670 if (! FRAME_TERMCAP_P (f
) && cursor_to_hook
)
672 (*cursor_to_hook
) (vpos
, hpos
);
676 /* Detect the case where we are called from reset_sys_modes
677 and the costs have never been calculated. Do nothing. */
681 if (curY
== vpos
&& curX
== hpos
)
683 if (!TF_standout_motion
)
684 background_highlight ();
685 if (!TF_insmode_motion
)
690 /* Similar but don't take any account of the wasted characters. */
693 raw_cursor_to (row
, col
)
696 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
697 if (! FRAME_TERMCAP_P (f
))
699 (*raw_cursor_to_hook
) (row
, col
);
702 if (curY
== row
&& curX
== col
)
704 if (!TF_standout_motion
)
705 background_highlight ();
706 if (!TF_insmode_motion
)
711 /* Erase operations */
713 /* clear from cursor to end of frame */
719 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
721 (*clear_to_end_hook
) ();
724 if (TS_clr_to_bottom
)
726 background_highlight ();
727 OUTPUT (TS_clr_to_bottom
);
731 for (i
= curY
; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
734 clear_end_of_line (FRAME_COLS (XFRAME (selected_frame
)));
739 /* Clear entire frame */
744 struct frame
*sf
= XFRAME (selected_frame
);
747 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: sf
)))
749 (*clear_frame_hook
) ();
754 background_highlight ();
755 OUTPUT (TS_clr_frame
);
765 /* Clear from cursor to end of line.
766 Assume that the line is already clear starting at column first_unused_hpos.
768 Note that the cursor may be moved, on terminals lacking a `ce' string. */
771 clear_end_of_line (first_unused_hpos
)
772 int first_unused_hpos
;
776 if (clear_end_of_line_hook
777 && ! FRAME_TERMCAP_P ((updating_frame
779 : XFRAME (selected_frame
))))
781 (*clear_end_of_line_hook
) (first_unused_hpos
);
785 /* Detect the case where we are called from reset_sys_modes
786 and the costs have never been calculated. Do nothing. */
790 if (curX
>= first_unused_hpos
)
792 background_highlight ();
795 OUTPUT1 (TS_clr_line
);
798 { /* have to do it the hard way */
799 struct frame
*sf
= XFRAME (selected_frame
);
802 /* Do not write in last row last col with Auto-wrap on. */
803 if (AutoWrap
&& curY
== FRAME_LINES (sf
) - 1
804 && first_unused_hpos
== FRAME_COLS (sf
))
807 for (i
= curX
; i
< first_unused_hpos
; i
++)
810 fputc (' ', termscript
);
813 cmplus (first_unused_hpos
- curX
);
817 /* Buffers to store the source and result of code conversion for terminal. */
818 static unsigned char *encode_terminal_src
;
819 static unsigned char *encode_terminal_dst
;
820 /* Allocated sizes of the above buffers. */
821 static int encode_terminal_src_size
;
822 static int encode_terminal_dst_size
;
824 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
825 Set CODING->produced to the byte-length of the resulting byte
826 sequence, and return a pointer to that byte sequence. */
829 encode_terminal_code (src
, src_len
, coding
)
832 struct coding_system
*coding
;
834 struct glyph
*src_end
= src
+ src_len
;
837 int nchars
, nbytes
, required
;
838 register int tlen
= GLYPH_TABLE_LENGTH
;
839 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
840 Lisp_Object charset_list
;
842 /* Allocate sufficient size of buffer to store all characters in
843 multibyte-form. But, it may be enlarged on demand if
844 Vglyph_table contains a string or a composite glyph is
846 required
= MAX_MULTIBYTE_LENGTH
* src_len
;
847 if (encode_terminal_src_size
< required
)
849 if (encode_terminal_src_size
== 0)
850 encode_terminal_src
= xmalloc (required
);
852 encode_terminal_src
= xrealloc (encode_terminal_src
, required
);
853 encode_terminal_src_size
= required
;
856 charset_list
= coding_charset_list (coding
);
858 buf
= encode_terminal_src
;
860 while (src
< src_end
)
862 if (src
->type
== COMPOSITE_GLYPH
)
864 struct composition
*cmp
= composition_table
[src
->u
.cmp_id
];
867 nbytes
= buf
- encode_terminal_src
;
868 required
= MAX_MULTIBYTE_LENGTH
* cmp
->glyph_len
;
870 if (encode_terminal_src_size
< nbytes
+ required
)
872 encode_terminal_src_size
= nbytes
+ required
;
873 encode_terminal_src
= xrealloc (encode_terminal_src
,
874 encode_terminal_src_size
);
875 buf
= encode_terminal_src
+ nbytes
;
878 for (i
= 0; i
< cmp
->glyph_len
; i
++)
880 int c
= COMPOSITION_GLYPH (cmp
, i
);
882 if (! char_charset (c
, charset_list
, NULL
))
884 buf
+= CHAR_STRING (c
, buf
);
889 /* The first character of the composition is not encodable. */
894 /* We must skip glyphs to be padded for a wide character. */
895 else if (! CHAR_GLYPH_PADDING_P (*src
))
901 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
903 if (g
< 0 || g
>= tlen
)
905 /* This glyph doesn't has an entry in Vglyph_table. */
910 /* This glyph has an entry in Vglyph_table,
911 so process any alias before testing for simpleness. */
912 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
914 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
915 /* We set the multi-byte form of a character in G
916 (that should be an ASCII character) at WORKBUF. */
917 c
= FAST_GLYPH_CHAR (g
);
919 /* We have a string in Vglyph_table. */
925 nbytes
= buf
- encode_terminal_src
;
926 if (encode_terminal_src_size
< nbytes
+ MAX_MULTIBYTE_LENGTH
)
928 encode_terminal_src_size
= nbytes
+ MAX_MULTIBYTE_LENGTH
;
929 encode_terminal_src
= xrealloc (encode_terminal_src
,
930 encode_terminal_src_size
);
931 buf
= encode_terminal_src
+ nbytes
;
933 if (char_charset (c
, charset_list
, NULL
))
935 /* Store the multibyte form of C at BUF. */
936 buf
+= CHAR_STRING (c
, buf
);
941 /* C is not encodable. */
944 while (src
+ 1 < src_end
&& CHAR_GLYPH_PADDING_P (src
[1]))
954 unsigned char *p
= SDATA (string
), *pend
= p
+ SBYTES (string
);
956 if (! STRING_MULTIBYTE (string
))
957 string
= string_to_multibyte (string
);
958 nbytes
= buf
- encode_terminal_src
;
959 if (encode_terminal_src_size
< nbytes
+ SBYTES (string
))
961 encode_terminal_src_size
= nbytes
+ SBYTES (string
);
962 encode_terminal_src
= xrealloc (encode_terminal_src
,
963 encode_terminal_src_size
);
964 buf
= encode_terminal_src
+ nbytes
;
966 bcopy (SDATA (string
), buf
, SBYTES (string
));
967 buf
+= SBYTES (string
);
968 nchars
+= SCHARS (string
);
976 coding
->produced
= 0;
980 nbytes
= buf
- encode_terminal_src
;
981 coding
->source
= encode_terminal_src
;
982 if (encode_terminal_dst_size
== 0)
984 encode_terminal_dst_size
= encode_terminal_src_size
;
985 encode_terminal_dst
= xmalloc (encode_terminal_dst_size
);
987 coding
->destination
= encode_terminal_dst
;
988 coding
->dst_bytes
= encode_terminal_dst_size
;
989 encode_coding_object (coding
, Qnil
, 0, 0, nchars
, nbytes
, Qnil
);
990 /* coding->destination may have been reallocated. */
991 encode_terminal_dst
= coding
->destination
;
992 encode_terminal_dst_size
= coding
->dst_bytes
;
994 return (encode_terminal_dst
);
999 write_glyphs (string
, len
)
1000 register struct glyph
*string
;
1003 int produced
, consumed
;
1004 struct frame
*sf
= XFRAME (selected_frame
);
1005 struct frame
*f
= updating_frame
? updating_frame
: sf
;
1006 unsigned char *conversion_buffer
;
1007 struct coding_system
*coding
;
1009 if (write_glyphs_hook
1010 && ! FRAME_TERMCAP_P (f
))
1012 (*write_glyphs_hook
) (string
, len
);
1019 /* Don't dare write in last column of bottom line, if Auto-Wrap,
1020 since that would scroll the whole frame on some terminals. */
1023 && curY
+ 1 == FRAME_LINES (sf
)
1024 && (curX
+ len
) == FRAME_COLS (sf
))
1031 /* If terminal_coding does any conversion, use it, otherwise use
1032 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
1033 because it always return 1 if the member src_multibyte is 1. */
1034 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
1035 ? &terminal_coding
: &safe_terminal_coding
);
1036 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1038 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
1042 /* Identify a run of glyphs with the same face. */
1043 int face_id
= string
->face_id
;
1046 for (n
= 1; n
< len
; ++n
)
1047 if (string
[n
].face_id
!= face_id
)
1050 /* Turn appearance modes of the face of the run on. */
1051 highlight_if_desired ();
1052 turn_on_face (f
, face_id
);
1055 /* This is the last run. */
1056 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
1057 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
1058 if (coding
->produced
> 0)
1060 fwrite (conversion_buffer
, 1, coding
->produced
, stdout
);
1061 if (ferror (stdout
))
1064 fwrite (conversion_buffer
, 1, coding
->produced
, termscript
);
1069 /* Turn appearance modes off. */
1070 turn_off_face (f
, face_id
);
1071 turn_off_highlight ();
1077 /* If start is zero, insert blanks instead of a string at start */
1080 insert_glyphs (start
, len
)
1081 register struct glyph
*start
;
1085 struct glyph
*glyph
= NULL
;
1086 struct frame
*f
, *sf
;
1087 unsigned char *conversion_buffer
;
1088 unsigned char space
[1];
1089 struct coding_system
*coding
;
1094 if (insert_glyphs_hook
)
1096 (*insert_glyphs_hook
) (start
, len
);
1100 sf
= XFRAME (selected_frame
);
1101 f
= updating_frame
? updating_frame
: sf
;
1103 if (TS_ins_multi_chars
)
1105 buf
= tparam (TS_ins_multi_chars
, 0, 0, len
);
1109 write_glyphs (start
, len
);
1117 space
[0] = SPACEGLYPH
;
1119 /* If terminal_coding does any conversion, use it, otherwise use
1120 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
1121 because it always return 1 if the member src_multibyte is 1. */
1122 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
1123 ? &terminal_coding
: &safe_terminal_coding
);
1124 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1126 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
1130 OUTPUT1_IF (TS_ins_char
);
1133 conversion_buffer
= space
;
1134 coding
->produced
= 1;
1138 highlight_if_desired ();
1139 turn_on_face (f
, start
->face_id
);
1142 /* We must open sufficient space for a character which
1143 occupies more than one column. */
1144 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
1146 OUTPUT1_IF (TS_ins_char
);
1151 /* This is the last glyph. */
1152 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
1154 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
1157 if (coding
->produced
> 0)
1159 fwrite (conversion_buffer
, 1, coding
->produced
, stdout
);
1160 if (ferror (stdout
))
1163 fwrite (conversion_buffer
, 1, coding
->produced
, termscript
);
1166 OUTPUT1_IF (TS_pad_inserted_char
);
1169 turn_off_face (f
, glyph
->face_id
);
1170 turn_off_highlight ();
1184 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1186 (*delete_glyphs_hook
) (n
);
1190 if (delete_in_insert_mode
)
1197 OUTPUT_IF (TS_delete_mode
);
1200 if (TS_del_multi_chars
)
1202 buf
= tparam (TS_del_multi_chars
, 0, 0, n
);
1207 for (i
= 0; i
< n
; i
++)
1208 OUTPUT1 (TS_del_char
);
1209 if (!delete_in_insert_mode
)
1210 OUTPUT_IF (TS_end_delete_mode
);
1213 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1216 ins_del_lines (vpos
, n
)
1219 char *multi
= n
> 0 ? TS_ins_multi_lines
: TS_del_multi_lines
;
1220 char *single
= n
> 0 ? TS_ins_line
: TS_del_line
;
1221 char *scroll
= n
> 0 ? TS_rev_scroll
: TS_fwd_scroll
;
1224 register int i
= n
> 0 ? n
: -n
;
1227 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1229 (*ins_del_lines_hook
) (vpos
, n
);
1233 sf
= XFRAME (selected_frame
);
1235 /* If the lines below the insertion are being pushed
1236 into the end of the window, this is the same as clearing;
1237 and we know the lines are already clear, since the matching
1238 deletion has already been done. So can ignore this. */
1239 /* If the lines below the deletion are blank lines coming
1240 out of the end of the window, don't bother,
1241 as there will be a matching inslines later that will flush them. */
1242 if (scroll_region_ok
&& vpos
+ i
>= specified_window
)
1244 if (!memory_below_frame
&& vpos
+ i
>= FRAME_LINES (sf
))
1249 raw_cursor_to (vpos
, 0);
1250 background_highlight ();
1251 buf
= tparam (multi
, 0, 0, i
);
1257 raw_cursor_to (vpos
, 0);
1258 background_highlight ();
1266 set_scroll_region (vpos
, specified_window
);
1268 raw_cursor_to (specified_window
- 1, 0);
1270 raw_cursor_to (vpos
, 0);
1271 background_highlight ();
1273 OUTPUTL (scroll
, specified_window
- vpos
);
1274 set_scroll_region (0, specified_window
);
1277 if (!scroll_region_ok
&& memory_below_frame
&& n
< 0)
1279 cursor_to (FRAME_LINES (sf
) + n
, 0);
1284 /* Compute cost of sending "str", in characters,
1285 not counting any line-dependent padding. */
1293 tputs (str
, 0, evalcost
);
1297 /* Compute cost of sending "str", in characters,
1298 counting any line-dependent padding at one line. */
1301 string_cost_one_line (str
)
1306 tputs (str
, 1, evalcost
);
1310 /* Compute per line amount of line-dependent padding,
1311 in tenths of characters. */
1319 tputs (str
, 0, evalcost
);
1322 tputs (str
, 10, evalcost
);
1327 /* char_ins_del_cost[n] is cost of inserting N characters.
1328 char_ins_del_cost[-n] is cost of deleting N characters.
1329 The length of this vector is based on max_frame_cols. */
1331 int *char_ins_del_vector
;
1333 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1338 calculate_ins_del_char_costs (frame
)
1341 int ins_startup_cost
, del_startup_cost
;
1342 int ins_cost_per_char
, del_cost_per_char
;
1346 if (TS_ins_multi_chars
)
1348 ins_cost_per_char
= 0;
1349 ins_startup_cost
= string_cost_one_line (TS_ins_multi_chars
);
1351 else if (TS_ins_char
|| TS_pad_inserted_char
1352 || (TS_insert_mode
&& TS_end_insert_mode
))
1354 ins_startup_cost
= (30 * (string_cost (TS_insert_mode
)
1355 + string_cost (TS_end_insert_mode
))) / 100;
1356 ins_cost_per_char
= (string_cost_one_line (TS_ins_char
)
1357 + string_cost_one_line (TS_pad_inserted_char
));
1361 ins_startup_cost
= 9999;
1362 ins_cost_per_char
= 0;
1365 if (TS_del_multi_chars
)
1367 del_cost_per_char
= 0;
1368 del_startup_cost
= string_cost_one_line (TS_del_multi_chars
);
1370 else if (TS_del_char
)
1372 del_startup_cost
= (string_cost (TS_delete_mode
)
1373 + string_cost (TS_end_delete_mode
));
1374 if (delete_in_insert_mode
)
1375 del_startup_cost
/= 2;
1376 del_cost_per_char
= string_cost_one_line (TS_del_char
);
1380 del_startup_cost
= 9999;
1381 del_cost_per_char
= 0;
1384 /* Delete costs are at negative offsets */
1385 p
= &char_ins_del_cost (frame
)[0];
1386 for (i
= FRAME_COLS (frame
); --i
>= 0;)
1387 *--p
= (del_startup_cost
+= del_cost_per_char
);
1389 /* Doing nothing is free */
1390 p
= &char_ins_del_cost (frame
)[0];
1393 /* Insert costs are at positive offsets */
1394 for (i
= FRAME_COLS (frame
); --i
>= 0;)
1395 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1399 calculate_costs (frame
)
1402 register char *f
= (TS_set_scroll_region
1403 ? TS_set_scroll_region
1404 : TS_set_scroll_region_1
);
1406 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1408 scroll_region_cost
= string_cost (f
);
1410 /* These variables are only used for terminal stuff. They are allocated
1411 once for the terminal frame of X-windows emacs, but not used afterwards.
1413 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1414 X turns off char_ins_del_ok. */
1416 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1417 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1421 if (char_ins_del_vector
!= 0)
1423 = (int *) xrealloc (char_ins_del_vector
,
1425 + 2 * max_frame_cols
* sizeof (int)));
1428 = (int *) xmalloc (sizeof (int)
1429 + 2 * max_frame_cols
* sizeof (int));
1431 bzero (char_ins_del_vector
, (sizeof (int)
1432 + 2 * max_frame_cols
* sizeof (int)));
1434 if (f
&& (!TS_ins_line
&& !TS_del_line
))
1435 do_line_insertion_deletion_costs (frame
,
1436 TS_rev_scroll
, TS_ins_multi_lines
,
1437 TS_fwd_scroll
, TS_del_multi_lines
,
1440 do_line_insertion_deletion_costs (frame
,
1441 TS_ins_line
, TS_ins_multi_lines
,
1442 TS_del_line
, TS_del_multi_lines
,
1445 calculate_ins_del_char_costs (frame
);
1447 /* Don't use TS_repeat if its padding is worse than sending the chars */
1448 if (TS_repeat
&& per_line_cost (TS_repeat
) * baud_rate
< 9000)
1449 RPov
= string_cost (TS_repeat
);
1451 RPov
= FRAME_COLS (frame
) * 2;
1453 cmcostinit (); /* set up cursor motion costs */
1460 /* Termcap capability names that correspond directly to X keysyms.
1461 Some of these (marked "terminfo") aren't supplied by old-style
1462 (Berkeley) termcap entries. They're listed in X keysym order;
1463 except we put the keypad keys first, so that if they clash with
1464 other keys (as on the IBM PC keyboard) they get overridden.
1467 static struct fkey_table keys
[] =
1469 {"kh", "home"}, /* termcap */
1470 {"kl", "left"}, /* termcap */
1471 {"ku", "up"}, /* termcap */
1472 {"kr", "right"}, /* termcap */
1473 {"kd", "down"}, /* termcap */
1474 {"%8", "prior"}, /* terminfo */
1475 {"%5", "next"}, /* terminfo */
1476 {"@7", "end"}, /* terminfo */
1477 {"@1", "begin"}, /* terminfo */
1478 {"*6", "select"}, /* terminfo */
1479 {"%9", "print"}, /* terminfo */
1480 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1482 * "insert" --- see below
1484 {"&8", "undo"}, /* terminfo */
1485 {"%0", "redo"}, /* terminfo */
1486 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1487 {"@0", "find"}, /* terminfo */
1488 {"@2", "cancel"}, /* terminfo */
1489 {"%1", "help"}, /* terminfo */
1491 * "break" goes here, but can't be reliably intercepted with termcap
1493 {"&4", "reset"}, /* terminfo --- actually `restart' */
1495 * "system" and "user" --- no termcaps
1497 {"kE", "clearline"}, /* terminfo */
1498 {"kA", "insertline"}, /* terminfo */
1499 {"kL", "deleteline"}, /* terminfo */
1500 {"kI", "insertchar"}, /* terminfo */
1501 {"kD", "deletechar"}, /* terminfo */
1502 {"kB", "backtab"}, /* terminfo */
1504 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1506 {"@8", "kp-enter"}, /* terminfo */
1508 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1509 * "kp-multiply", "kp-add", "kp-separator",
1510 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1511 * --- no termcaps for any of these.
1513 {"K4", "kp-1"}, /* terminfo */
1515 * "kp-2" --- no termcap
1517 {"K5", "kp-3"}, /* terminfo */
1519 * "kp-4" --- no termcap
1521 {"K2", "kp-5"}, /* terminfo */
1523 * "kp-6" --- no termcap
1525 {"K1", "kp-7"}, /* terminfo */
1527 * "kp-8" --- no termcap
1529 {"K3", "kp-9"}, /* terminfo */
1531 * "kp-equal" --- no termcap
1543 {"&0", "S-cancel"}, /*shifted cancel key*/
1544 {"&9", "S-begin"}, /*shifted begin key*/
1545 {"*0", "S-find"}, /*shifted find key*/
1546 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1547 {"*4", "S-delete"}, /*shifted delete-character key*/
1548 {"*7", "S-end"}, /*shifted end key*/
1549 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1550 {"#1", "S-help"}, /*shifted help key*/
1551 {"#2", "S-home"}, /*shifted home key*/
1552 {"#3", "S-insert"}, /*shifted insert-character key*/
1553 {"#4", "S-left"}, /*shifted left-arrow key*/
1554 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1555 {"%c", "S-next"}, /*shifted next key*/
1556 {"%e", "S-prior"}, /*shifted previous key*/
1557 {"%f", "S-print"}, /*shifted print key*/
1558 {"%g", "S-redo"}, /*shifted redo key*/
1559 {"%i", "S-right"}, /*shifted right-arrow key*/
1560 {"!3", "S-undo"} /*shifted undo key*/
1563 static char **term_get_fkeys_arg
;
1564 static Lisp_Object
term_get_fkeys_1 ();
1566 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1567 This function scans the termcap function key sequence entries, and
1568 adds entries to Vfunction_key_map for each function key it finds. */
1571 term_get_fkeys (address
)
1574 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1575 errors during the call. The only errors should be from Fdefine_key
1576 when given a key sequence containing an invalid prefix key. If the
1577 termcap defines function keys which use a prefix that is already bound
1578 to a command by the default bindings, we should silently ignore that
1579 function key specification, rather than giving the user an error and
1580 refusing to run at all on such a terminal. */
1582 extern Lisp_Object
Fidentity ();
1583 term_get_fkeys_arg
= address
;
1584 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1592 char **address
= term_get_fkeys_arg
;
1594 /* This can happen if CANNOT_DUMP or with strange options. */
1596 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1598 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1600 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1602 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1603 Fmake_vector (make_number (1),
1604 intern (keys
[i
].name
)));
1607 /* The uses of the "k0" capability are inconsistent; sometimes it
1608 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1609 We will attempt to politely accommodate both systems by testing for
1610 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1613 char *k_semi
= tgetstr ("k;", address
);
1614 char *k0
= tgetstr ("k0", address
);
1615 char *k0_name
= "f10";
1620 /* Define f0 first, so that f10 takes precedence in case the
1621 key sequences happens to be the same. */
1622 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1623 Fmake_vector (make_number (1), intern ("f0")));
1624 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1625 Fmake_vector (make_number (1), intern ("f10")));
1628 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1629 Fmake_vector (make_number (1), intern (k0_name
)));
1632 /* Set up cookies for numbered function keys above f10. */
1634 char fcap
[3], fkey
[4];
1636 fcap
[0] = 'F'; fcap
[2] = '\0';
1637 for (i
= 11; i
< 64; i
++)
1640 fcap
[1] = '1' + i
- 11;
1642 fcap
[1] = 'A' + i
- 20;
1644 fcap
[1] = 'a' + i
- 46;
1647 char *sequence
= tgetstr (fcap
, address
);
1650 sprintf (fkey
, "f%d", i
);
1651 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1652 Fmake_vector (make_number (1),
1660 * Various mappings to try and get a better fit.
1663 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1664 if (!tgetstr (cap1, address)) \
1666 char *sequence = tgetstr (cap2, address); \
1668 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1669 Fmake_vector (make_number (1), \
1673 /* if there's no key_next keycap, map key_npage to `next' keysym */
1674 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1675 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1676 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1677 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1678 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1679 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1680 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1682 /* IBM has their own non-standard dialect of terminfo.
1683 If the standard name isn't found, try the IBM name. */
1684 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1685 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1686 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1687 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1688 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1689 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1690 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1691 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1692 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1693 #undef CONDITIONAL_REASSIGN
1700 /***********************************************************************
1701 Character Display Information
1702 ***********************************************************************/
1704 /* Avoid name clash with functions defined in xterm.c */
1706 #define append_glyph append_glyph_term
1707 #define produce_stretch_glyph produce_stretch_glyph_term
1708 #define append_composite_glyph append_composite_glyph_term
1709 #define produce_composite_glyph produce_composite_glyph_term
1712 static void append_glyph
P_ ((struct it
*));
1713 static void produce_stretch_glyph
P_ ((struct it
*));
1714 static void append_composite_glyph
P_ ((struct it
*));
1715 static void produce_composite_glyph
P_ ((struct it
*));
1717 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1718 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1719 the character for which to produce glyphs; IT->face_id contains the
1720 character's face. Padding glyphs are appended if IT->c has a
1721 IT->pixel_width > 1. */
1727 struct glyph
*glyph
, *end
;
1730 xassert (it
->glyph_row
);
1731 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1732 + it
->glyph_row
->used
[it
->area
]);
1733 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1736 i
< it
->pixel_width
&& glyph
< end
;
1739 glyph
->type
= CHAR_GLYPH
;
1740 glyph
->pixel_width
= 1;
1741 glyph
->u
.ch
= it
->char_to_display
;
1742 glyph
->face_id
= it
->face_id
;
1743 glyph
->padding_p
= i
> 0;
1744 glyph
->charpos
= CHARPOS (it
->position
);
1745 glyph
->object
= it
->object
;
1747 ++it
->glyph_row
->used
[it
->area
];
1753 /* Produce glyphs for the display element described by IT. *IT
1754 specifies what we want to produce a glyph for (character, image, ...),
1755 and where in the glyph matrix we currently are (glyph row and hpos).
1756 produce_glyphs fills in output fields of *IT with information such as the
1757 pixel width and height of a character, and maybe output actual glyphs at
1758 the same time if IT->glyph_row is non-null. See the explanation of
1759 struct display_iterator in dispextern.h for an overview.
1761 produce_glyphs also stores the result of glyph width, ascent
1762 etc. computations in *IT.
1764 IT->glyph_row may be null, in which case produce_glyphs does not
1765 actually fill in the glyphs. This is used in the move_* functions
1766 in xdisp.c for text width and height computations.
1768 Callers usually don't call produce_glyphs directly;
1769 instead they use the macro PRODUCE_GLYPHS. */
1775 /* If a hook is installed, let it do the work. */
1777 /* Nothing but characters are supported on terminal frames. */
1778 xassert (it
->what
== IT_CHARACTER
1779 || it
->what
== IT_COMPOSITION
1780 || it
->what
== IT_STRETCH
);
1782 if (it
->what
== IT_STRETCH
)
1784 produce_stretch_glyph (it
);
1788 if (it
->what
== IT_COMPOSITION
)
1790 produce_composite_glyph (it
);
1794 /* Maybe translate single-byte characters to multibyte. */
1795 it
->char_to_display
= it
->c
;
1797 if (it
->c
>= 040 && it
->c
< 0177)
1799 it
->pixel_width
= it
->nglyphs
= 1;
1803 else if (it
->c
== '\n')
1804 it
->pixel_width
= it
->nglyphs
= 0;
1805 else if (it
->c
== '\t')
1807 int absolute_x
= (it
->current_x
1808 + it
->continuation_lines_width
);
1810 = (((1 + absolute_x
+ it
->tab_width
- 1)
1815 /* If part of the TAB has been displayed on the previous line
1816 which is continued now, continuation_lines_width will have
1817 been incremented already by the part that fitted on the
1818 continued line. So, we will get the right number of spaces
1820 nspaces
= next_tab_x
- absolute_x
;
1826 it
->char_to_display
= ' ';
1827 it
->pixel_width
= it
->len
= 1;
1833 it
->pixel_width
= nspaces
;
1834 it
->nglyphs
= nspaces
;
1836 else if (CHAR_BYTE8_P (it
->c
))
1838 if (unibyte_display_via_language_environment
1841 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1842 it
->pixel_width
= CHAR_WIDTH (it
->char_to_display
);
1843 it
->nglyphs
= it
->pixel_width
;
1849 /* Coming here means that it->c is from display table, thus
1850 we must send the raw 8-bit byte as is to the terminal.
1851 Although there's no way to know how many columns it
1852 occupies on a screen, it is a good assumption that a
1853 single byte code has 1-column width. */
1854 it
->pixel_width
= it
->nglyphs
= 1;
1861 it
->pixel_width
= CHAR_WIDTH (it
->c
);
1862 it
->nglyphs
= it
->pixel_width
;
1869 /* Advance current_x by the pixel width as a convenience for
1871 if (it
->area
== TEXT_AREA
)
1872 it
->current_x
+= it
->pixel_width
;
1873 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1874 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1878 /* Produce a stretch glyph for iterator IT. IT->object is the value
1879 of the glyph property displayed. The value must be a list
1880 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1883 1. `:width WIDTH' specifies that the space should be WIDTH *
1884 canonical char width wide. WIDTH may be an integer or floating
1887 2. `:align-to HPOS' specifies that the space should be wide enough
1888 to reach HPOS, a value in canonical character units. */
1891 produce_stretch_glyph (it
)
1894 /* (space :width WIDTH ...) */
1895 Lisp_Object prop
, plist
;
1896 int width
= 0, align_to
= -1;
1897 int zero_width_ok_p
= 0;
1900 /* List should start with `space'. */
1901 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1902 plist
= XCDR (it
->object
);
1904 /* Compute the width of the stretch. */
1905 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1906 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1908 /* Absolute width `:width WIDTH' specified and valid. */
1909 zero_width_ok_p
= 1;
1910 width
= (int)(tem
+ 0.5);
1912 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1913 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1915 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1916 align_to
= (align_to
< 0
1918 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1919 else if (align_to
< 0)
1920 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1921 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1922 zero_width_ok_p
= 1;
1925 /* Nothing specified -> width defaults to canonical char width. */
1926 width
= FRAME_COLUMN_WIDTH (it
->f
);
1928 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1931 if (width
> 0 && it
->glyph_row
)
1933 Lisp_Object o_object
= it
->object
;
1934 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1937 if (!STRINGP (object
))
1938 object
= it
->w
->buffer
;
1939 it
->object
= object
;
1940 it
->char_to_display
= ' ';
1941 it
->pixel_width
= it
->len
= 1;
1944 it
->object
= o_object
;
1946 it
->pixel_width
= width
;
1947 it
->nglyphs
= width
;
1951 /* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
1952 Called from produce_composite_glyph for terminal frames if
1953 IT->glyph_row != NULL. IT->face_id contains the character's
1957 append_composite_glyph (it
)
1960 struct glyph
*glyph
;
1962 xassert (it
->glyph_row
);
1963 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1964 if (glyph
< it
->glyph_row
->glyphs
[1 + it
->area
])
1966 glyph
->type
= COMPOSITE_GLYPH
;
1967 glyph
->pixel_width
= it
->pixel_width
;
1968 glyph
->u
.cmp_id
= it
->cmp_id
;
1969 glyph
->face_id
= it
->face_id
;
1970 glyph
->padding_p
= 0;
1971 glyph
->charpos
= CHARPOS (it
->position
);
1972 glyph
->object
= it
->object
;
1974 ++it
->glyph_row
->used
[it
->area
];
1980 /* Produce a composite glyph for iterator IT. IT->cmp_id is the ID of
1981 the composition. We simply produces components of the composition
1982 assuming that that the terminal has a capability to layout/render
1986 produce_composite_glyph (it
)
1989 struct composition
*cmp
= composition_table
[it
->cmp_id
];
1992 xassert (cmp
->glyph_len
> 0);
1993 c
= COMPOSITION_GLYPH (cmp
, 0);
1994 it
->pixel_width
= CHAR_WIDTH (it
->c
);
1998 append_composite_glyph (it
);
2002 /* Get information about special display element WHAT in an
2003 environment described by IT. WHAT is one of IT_TRUNCATION or
2004 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
2005 non-null glyph_row member. This function ensures that fields like
2006 face_id, c, len of IT are left untouched. */
2009 produce_special_glyphs (it
, what
)
2011 enum display_element_type what
;
2018 temp_it
.what
= IT_CHARACTER
;
2020 temp_it
.object
= make_number (0);
2021 bzero (&temp_it
.current
, sizeof temp_it
.current
);
2023 if (what
== IT_CONTINUATION
)
2025 /* Continuation glyph. */
2027 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
2028 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
2030 glyph
= XINT (DISP_CONTINUE_GLYPH (it
->dp
));
2031 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
2036 else if (what
== IT_TRUNCATION
)
2038 /* Truncation glyph. */
2040 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
2041 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
2043 glyph
= XINT (DISP_TRUNC_GLYPH (it
->dp
));
2044 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
2052 temp_it
.c
= FAST_GLYPH_CHAR (glyph
);
2053 temp_it
.face_id
= FAST_GLYPH_FACE (glyph
);
2054 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
2056 produce_glyphs (&temp_it
);
2057 it
->pixel_width
= temp_it
.pixel_width
;
2058 it
->nglyphs
= temp_it
.pixel_width
;
2063 /***********************************************************************
2065 ***********************************************************************/
2067 /* Value is non-zero if attribute ATTR may be used. ATTR should be
2068 one of the enumerators from enum no_color_bit, or a bit set built
2069 from them. Some display attributes may not be used together with
2070 color; the termcap capability `NC' specifies which ones. */
2072 #define MAY_USE_WITH_COLORS_P(ATTR) \
2073 (TN_max_colors > 0 \
2074 ? (TN_no_color_video & (ATTR)) == 0 \
2077 /* Turn appearances of face FACE_ID on tty frame F on.
2078 FACE_ID is a realized face ID number, in the face cache. */
2081 turn_on_face (f
, face_id
)
2085 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2086 long fg
= face
->foreground
;
2087 long bg
= face
->background
;
2089 /* Do this first because TS_end_standout_mode may be the same
2090 as TS_exit_attribute_mode, which turns all appearances off. */
2091 if (MAY_USE_WITH_COLORS_P (NC_REVERSE
))
2093 if (TN_max_colors
> 0)
2095 if (fg
>= 0 && bg
>= 0)
2097 /* If the terminal supports colors, we can set them
2098 below without using reverse video. The face's fg
2099 and bg colors are set as they should appear on
2100 the screen, i.e. they take the inverse-video'ness
2101 of the face already into account. */
2103 else if (inverse_video
)
2105 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
2106 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
2107 toggle_highlight ();
2111 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
2112 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
2113 toggle_highlight ();
2118 /* If we can't display colors, use reverse video
2119 if the face specifies that. */
2122 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
2123 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
2124 toggle_highlight ();
2128 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
2129 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
2130 toggle_highlight ();
2135 if (face
->tty_bold_p
)
2137 if (MAY_USE_WITH_COLORS_P (NC_BOLD
))
2138 OUTPUT1_IF (TS_enter_bold_mode
);
2140 else if (face
->tty_dim_p
)
2141 if (MAY_USE_WITH_COLORS_P (NC_DIM
))
2142 OUTPUT1_IF (TS_enter_dim_mode
);
2144 /* Alternate charset and blinking not yet used. */
2145 if (face
->tty_alt_charset_p
2146 && MAY_USE_WITH_COLORS_P (NC_ALT_CHARSET
))
2147 OUTPUT1_IF (TS_enter_alt_charset_mode
);
2149 if (face
->tty_blinking_p
2150 && MAY_USE_WITH_COLORS_P (NC_BLINK
))
2151 OUTPUT1_IF (TS_enter_blink_mode
);
2153 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (NC_UNDERLINE
))
2154 OUTPUT1_IF (TS_enter_underline_mode
);
2156 if (TN_max_colors
> 0)
2160 ts
= standout_mode
? TS_set_background
: TS_set_foreground
;
2163 p
= tparam (ts
, NULL
, 0, (int) fg
);
2168 ts
= standout_mode
? TS_set_foreground
: TS_set_background
;
2171 p
= tparam (ts
, NULL
, 0, (int) bg
);
2179 /* Turn off appearances of face FACE_ID on tty frame F. */
2182 turn_off_face (f
, face_id
)
2186 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2188 xassert (face
!= NULL
);
2190 if (TS_exit_attribute_mode
)
2192 /* Capability "me" will turn off appearance modes double-bright,
2193 half-bright, reverse-video, standout, underline. It may or
2194 may not turn off alt-char-mode. */
2195 if (face
->tty_bold_p
2197 || face
->tty_reverse_p
2198 || face
->tty_alt_charset_p
2199 || face
->tty_blinking_p
2200 || face
->tty_underline_p
)
2202 OUTPUT1_IF (TS_exit_attribute_mode
);
2203 if (strcmp (TS_exit_attribute_mode
, TS_end_standout_mode
) == 0)
2207 if (face
->tty_alt_charset_p
)
2208 OUTPUT_IF (TS_exit_alt_charset_mode
);
2212 /* If we don't have "me" we can only have those appearances
2213 that have exit sequences defined. */
2214 if (face
->tty_alt_charset_p
)
2215 OUTPUT_IF (TS_exit_alt_charset_mode
);
2217 if (face
->tty_underline_p
)
2218 OUTPUT_IF (TS_exit_underline_mode
);
2221 /* Switch back to default colors. */
2222 if (TN_max_colors
> 0
2223 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2224 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2225 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2226 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2227 OUTPUT1_IF (TS_orig_pair
);
2231 /* Return non-zero if the terminal on frame F supports all of the
2232 capabilities in CAPS simultaneously, with foreground and background
2233 colors FG and BG. */
2236 tty_capable_p (f
, caps
, fg
, bg
)
2239 unsigned long fg
, bg
;
2241 #define TTY_CAPABLE_P_TRY(cap, TS, NC_bit) \
2242 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(NC_bit))) \
2245 TTY_CAPABLE_P_TRY (TTY_CAP_INVERSE
, TS_standout_mode
, NC_REVERSE
);
2246 TTY_CAPABLE_P_TRY (TTY_CAP_UNDERLINE
, TS_enter_underline_mode
, NC_UNDERLINE
);
2247 TTY_CAPABLE_P_TRY (TTY_CAP_BOLD
, TS_enter_bold_mode
, NC_BOLD
);
2248 TTY_CAPABLE_P_TRY (TTY_CAP_DIM
, TS_enter_dim_mode
, NC_DIM
);
2249 TTY_CAPABLE_P_TRY (TTY_CAP_BLINK
, TS_enter_blink_mode
, NC_BLINK
);
2250 TTY_CAPABLE_P_TRY (TTY_CAP_ALT_CHARSET
, TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
2257 /* Return non-zero if the terminal is capable to display colors. */
2259 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2261 doc
: /* Return non-nil if TTY can display colors on DISPLAY. */)
2263 Lisp_Object display
;
2265 return TN_max_colors
> 0 ? Qt
: Qnil
;
2268 /* Return the number of supported colors. */
2269 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2270 Stty_display_color_cells
, 0, 1, 0,
2271 doc
: /* Return the number of colors supported by TTY on DISPLAY. */)
2273 Lisp_Object display
;
2275 return make_number (TN_max_colors
);
2280 /* Save or restore the default color-related capabilities of this
2283 tty_default_color_capabilities (save
)
2287 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
2288 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
2292 if (default_orig_pair
)
2293 xfree (default_orig_pair
);
2294 default_orig_pair
= TS_orig_pair
? xstrdup (TS_orig_pair
) : NULL
;
2296 if (default_set_foreground
)
2297 xfree (default_set_foreground
);
2298 default_set_foreground
= TS_set_foreground
? xstrdup (TS_set_foreground
)
2301 if (default_set_background
)
2302 xfree (default_set_background
);
2303 default_set_background
= TS_set_background
? xstrdup (TS_set_background
)
2306 default_max_colors
= TN_max_colors
;
2307 default_max_pairs
= TN_max_pairs
;
2308 default_no_color_video
= TN_no_color_video
;
2312 TS_orig_pair
= default_orig_pair
;
2313 TS_set_foreground
= default_set_foreground
;
2314 TS_set_background
= default_set_background
;
2315 TN_max_colors
= default_max_colors
;
2316 TN_max_pairs
= default_max_pairs
;
2317 TN_no_color_video
= default_no_color_video
;
2321 /* Setup one of the standard tty color schemes according to MODE.
2322 MODE's value is generally the number of colors which we want to
2323 support; zero means set up for the default capabilities, the ones
2324 we saw at term_init time; -1 means turn off color support. */
2326 tty_setup_colors (mode
)
2329 /* Canonicalize all negative values of MODE. */
2335 case -1: /* no colors at all */
2338 TN_no_color_video
= 0;
2339 TS_set_foreground
= TS_set_background
= TS_orig_pair
= NULL
;
2341 case 0: /* default colors, if any */
2343 tty_default_color_capabilities (0);
2345 case 8: /* 8 standard ANSI colors */
2346 TS_orig_pair
= "\033[0m";
2348 TS_set_foreground
= "\033[3%p1%dm";
2349 TS_set_background
= "\033[4%p1%dm";
2351 TS_set_foreground
= "\033[3%dm";
2352 TS_set_background
= "\033[4%dm";
2356 TN_no_color_video
= 0;
2362 set_tty_color_mode (f
, val
)
2366 Lisp_Object color_mode_spec
, current_mode_spec
;
2367 Lisp_Object color_mode
, current_mode
;
2369 extern Lisp_Object Qtty_color_mode
;
2370 Lisp_Object tty_color_mode_alist
;
2372 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2379 if (NILP (tty_color_mode_alist
))
2380 color_mode_spec
= Qnil
;
2382 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2384 if (CONSP (color_mode_spec
))
2385 color_mode
= XCDR (color_mode_spec
);
2390 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2392 if (CONSP (current_mode_spec
))
2393 current_mode
= XCDR (current_mode_spec
);
2395 current_mode
= Qnil
;
2396 if (INTEGERP (color_mode
))
2397 mode
= XINT (color_mode
);
2399 mode
= 0; /* meaning default */
2400 if (INTEGERP (current_mode
))
2401 old_mode
= XINT (current_mode
);
2405 if (mode
!= old_mode
)
2407 tty_setup_colors (mode
);
2408 /* This recomputes all the faces given the new color
2410 call0 (intern ("tty-set-up-initial-frame-faces"));
2415 #endif /* !WINDOWSNT */
2418 /***********************************************************************
2420 ***********************************************************************/
2423 term_init (terminal_type
)
2424 char *terminal_type
;
2427 char **address
= &area
;
2428 char *buffer
= NULL
;
2429 int buffer_size
= 4096;
2432 struct frame
*sf
= XFRAME (selected_frame
);
2434 encode_terminal_src_size
= 0;
2435 encode_terminal_dst_size
= 0;
2438 initialize_w32_display ();
2442 area
= (char *) xmalloc (2044);
2444 FrameRows
= FRAME_LINES (sf
);
2445 FrameCols
= FRAME_COLS (sf
);
2446 specified_window
= FRAME_LINES (sf
);
2448 delete_in_insert_mode
= 1;
2451 scroll_region_ok
= 0;
2453 /* Seems to insert lines when it's not supposed to, messing
2454 up the display. In doing a trace, it didn't seem to be
2455 called much, so I don't think we're losing anything by
2458 line_ins_del_ok
= 0;
2459 char_ins_del_ok
= 1;
2463 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
2464 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
2465 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2468 #else /* not WINDOWSNT */
2472 buffer
= (char *) xmalloc (buffer_size
);
2473 status
= tgetent (buffer
, terminal_type
);
2477 fatal ("Cannot open terminfo database file");
2479 fatal ("Cannot open termcap database file");
2485 fatal ("Terminal type %s is not defined.\n\
2486 If that is not the actual type of terminal you have,\n\
2487 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2488 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2489 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2492 fatal ("Terminal type %s is not defined.\n\
2493 If that is not the actual type of terminal you have,\n\
2494 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2495 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2496 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2502 if (strlen (buffer
) >= buffer_size
)
2504 buffer_size
= strlen (buffer
);
2506 area
= (char *) xmalloc (buffer_size
);
2508 TS_ins_line
= tgetstr ("al", address
);
2509 TS_ins_multi_lines
= tgetstr ("AL", address
);
2510 TS_bell
= tgetstr ("bl", address
);
2511 BackTab
= tgetstr ("bt", address
);
2512 TS_clr_to_bottom
= tgetstr ("cd", address
);
2513 TS_clr_line
= tgetstr ("ce", address
);
2514 TS_clr_frame
= tgetstr ("cl", address
);
2515 ColPosition
= NULL
; /* tgetstr ("ch", address); */
2516 AbsPosition
= tgetstr ("cm", address
);
2517 CR
= tgetstr ("cr", address
);
2518 TS_set_scroll_region
= tgetstr ("cs", address
);
2519 TS_set_scroll_region_1
= tgetstr ("cS", address
);
2520 RowPosition
= tgetstr ("cv", address
);
2521 TS_del_char
= tgetstr ("dc", address
);
2522 TS_del_multi_chars
= tgetstr ("DC", address
);
2523 TS_del_line
= tgetstr ("dl", address
);
2524 TS_del_multi_lines
= tgetstr ("DL", address
);
2525 TS_delete_mode
= tgetstr ("dm", address
);
2526 TS_end_delete_mode
= tgetstr ("ed", address
);
2527 TS_end_insert_mode
= tgetstr ("ei", address
);
2528 Home
= tgetstr ("ho", address
);
2529 TS_ins_char
= tgetstr ("ic", address
);
2530 TS_ins_multi_chars
= tgetstr ("IC", address
);
2531 TS_insert_mode
= tgetstr ("im", address
);
2532 TS_pad_inserted_char
= tgetstr ("ip", address
);
2533 TS_end_keypad_mode
= tgetstr ("ke", address
);
2534 TS_keypad_mode
= tgetstr ("ks", address
);
2535 LastLine
= tgetstr ("ll", address
);
2536 Right
= tgetstr ("nd", address
);
2537 Down
= tgetstr ("do", address
);
2539 Down
= tgetstr ("nl", address
); /* Obsolete name for "do" */
2541 /* VMS puts a carriage return before each linefeed,
2542 so it is not safe to use linefeeds. */
2543 if (Down
&& Down
[0] == '\n' && Down
[1] == '\0')
2546 if (tgetflag ("bs"))
2547 Left
= "\b"; /* can't possibly be longer! */
2548 else /* (Actually, "bs" is obsolete...) */
2549 Left
= tgetstr ("le", address
);
2551 Left
= tgetstr ("bc", address
); /* Obsolete name for "le" */
2552 TS_pad_char
= tgetstr ("pc", address
);
2553 TS_repeat
= tgetstr ("rp", address
);
2554 TS_end_standout_mode
= tgetstr ("se", address
);
2555 TS_fwd_scroll
= tgetstr ("sf", address
);
2556 TS_standout_mode
= tgetstr ("so", address
);
2557 TS_rev_scroll
= tgetstr ("sr", address
);
2558 Wcm
.cm_tab
= tgetstr ("ta", address
);
2559 TS_end_termcap_modes
= tgetstr ("te", address
);
2560 TS_termcap_modes
= tgetstr ("ti", address
);
2561 Up
= tgetstr ("up", address
);
2562 TS_visible_bell
= tgetstr ("vb", address
);
2563 TS_cursor_normal
= tgetstr ("ve", address
);
2564 TS_cursor_visible
= tgetstr ("vs", address
);
2565 TS_cursor_invisible
= tgetstr ("vi", address
);
2566 TS_set_window
= tgetstr ("wi", address
);
2568 TS_enter_underline_mode
= tgetstr ("us", address
);
2569 TS_exit_underline_mode
= tgetstr ("ue", address
);
2570 TS_enter_bold_mode
= tgetstr ("md", address
);
2571 TS_enter_dim_mode
= tgetstr ("mh", address
);
2572 TS_enter_blink_mode
= tgetstr ("mb", address
);
2573 TS_enter_reverse_mode
= tgetstr ("mr", address
);
2574 TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2575 TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2576 TS_exit_attribute_mode
= tgetstr ("me", address
);
2578 MultiUp
= tgetstr ("UP", address
);
2579 MultiDown
= tgetstr ("DO", address
);
2580 MultiLeft
= tgetstr ("LE", address
);
2581 MultiRight
= tgetstr ("RI", address
);
2583 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2584 color because we can't switch back to the default foreground and
2586 TS_orig_pair
= tgetstr ("op", address
);
2589 TS_set_foreground
= tgetstr ("AF", address
);
2590 TS_set_background
= tgetstr ("AB", address
);
2591 if (!TS_set_foreground
)
2594 TS_set_foreground
= tgetstr ("Sf", address
);
2595 TS_set_background
= tgetstr ("Sb", address
);
2598 TN_max_colors
= tgetnum ("Co");
2599 TN_max_pairs
= tgetnum ("pa");
2601 TN_no_color_video
= tgetnum ("NC");
2602 if (TN_no_color_video
== -1)
2603 TN_no_color_video
= 0;
2606 tty_default_color_capabilities (1);
2608 MagicWrap
= tgetflag ("xn");
2609 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2610 the former flag imply the latter. */
2611 AutoWrap
= MagicWrap
|| tgetflag ("am");
2612 memory_below_frame
= tgetflag ("db");
2613 TF_hazeltine
= tgetflag ("hz");
2614 must_write_spaces
= tgetflag ("in");
2615 meta_key
= tgetflag ("km") || tgetflag ("MT");
2616 TF_insmode_motion
= tgetflag ("mi");
2617 TF_standout_motion
= tgetflag ("ms");
2618 TF_underscore
= tgetflag ("ul");
2619 TF_teleray
= tgetflag ("xt");
2621 term_get_fkeys (address
);
2623 /* Get frame size from system, or else from termcap. */
2626 get_frame_size (&width
, &height
);
2627 FRAME_COLS (sf
) = width
;
2628 FRAME_LINES (sf
) = height
;
2631 if (FRAME_COLS (sf
) <= 0)
2632 SET_FRAME_COLS (sf
, tgetnum ("co"));
2634 /* Keep width and external_width consistent */
2635 SET_FRAME_COLS (sf
, FRAME_COLS (sf
));
2636 if (FRAME_LINES (sf
) <= 0)
2637 FRAME_LINES (sf
) = tgetnum ("li");
2639 if (FRAME_LINES (sf
) < 3 || FRAME_COLS (sf
) < 3)
2640 fatal ("Screen size %dx%d is too small",
2641 FRAME_LINES (sf
), FRAME_COLS (sf
));
2643 min_padding_speed
= tgetnum ("pb");
2644 TabWidth
= tgetnum ("tw");
2647 /* These capabilities commonly use ^J.
2648 I don't know why, but sending them on VMS does not work;
2649 it causes following spaces to be lost, sometimes.
2650 For now, the simplest fix is to avoid using these capabilities ever. */
2651 if (Down
&& Down
[0] == '\n')
2659 TS_fwd_scroll
= Down
;
2661 PC
= TS_pad_char
? *TS_pad_char
: 0;
2666 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2667 and newer termcap doc does not seem to say there is a default.
2672 /* We don't support standout modes that use `magic cookies', so
2673 turn off any that do. */
2674 if (TS_standout_mode
&& tgetnum ("sg") >= 0)
2676 TS_standout_mode
= 0;
2677 TS_end_standout_mode
= 0;
2679 if (TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
2681 TS_enter_underline_mode
= 0;
2682 TS_exit_underline_mode
= 0;
2685 /* If there's no standout mode, try to use underlining instead. */
2686 if (TS_standout_mode
== 0)
2688 TS_standout_mode
= TS_enter_underline_mode
;
2689 TS_end_standout_mode
= TS_exit_underline_mode
;
2692 /* If no `se' string, try using a `me' string instead.
2693 If that fails, we can't use standout mode at all. */
2694 if (TS_end_standout_mode
== 0)
2696 char *s
= tgetstr ("me", address
);
2698 TS_end_standout_mode
= s
;
2700 TS_standout_mode
= 0;
2706 /* We can't support standout mode, because it uses magic cookies. */
2707 TS_standout_mode
= 0;
2708 /* But that means we cannot rely on ^M to go to column zero! */
2710 /* LF can't be trusted either -- can alter hpos */
2711 /* if move at column 0 thru a line with TS_standout_mode */
2715 /* Special handling for certain terminal types known to need it */
2717 if (!strcmp (terminal_type
, "supdup"))
2719 memory_below_frame
= 1;
2720 Wcm
.cm_losewrap
= 1;
2722 if (!strncmp (terminal_type
, "c10", 3)
2723 || !strcmp (terminal_type
, "perq"))
2725 /* Supply a makeshift :wi string.
2726 This string is not valid in general since it works only
2727 for windows starting at the upper left corner;
2728 but that is all Emacs uses.
2730 This string works only if the frame is using
2731 the top of the video memory, because addressing is memory-relative.
2732 So first check the :ti string to see if that is true.
2734 It would be simpler if the :wi string could go in the termcap
2735 entry, but it can't because it is not fully valid.
2736 If it were in the termcap entry, it would confuse other programs. */
2739 p
= TS_termcap_modes
;
2740 while (*p
&& strcmp (p
, "\033v "))
2743 TS_set_window
= "\033v%C %C %C %C ";
2745 /* Termcap entry often fails to have :in: flag */
2746 must_write_spaces
= 1;
2747 /* :ti string typically fails to have \E^G! in it */
2748 /* This limits scope of insert-char to one line. */
2749 strcpy (area
, TS_termcap_modes
);
2750 strcat (area
, "\033\007!");
2751 TS_termcap_modes
= area
;
2752 area
+= strlen (area
) + 1;
2754 /* Change all %+ parameters to %C, to handle
2755 values above 96 correctly for the C100. */
2758 if (p
[0] == '%' && p
[1] == '+')
2764 FrameRows
= FRAME_LINES (sf
);
2765 FrameCols
= FRAME_COLS (sf
);
2766 specified_window
= FRAME_LINES (sf
);
2768 if (Wcm_init () == -1) /* can't do cursor motion */
2770 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2771 It lacks the ability to position the cursor.\n\
2772 If that is not the actual type of terminal you have, use either the\n\
2773 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2774 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2778 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2779 It lacks the ability to position the cursor.\n\
2780 If that is not the actual type of terminal you have,\n\
2781 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2782 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2783 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2785 # else /* TERMCAP */
2786 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2787 It lacks the ability to position the cursor.\n\
2788 If that is not the actual type of terminal you have,\n\
2789 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2790 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2791 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2793 # endif /* TERMINFO */
2795 if (FRAME_LINES (sf
) <= 0
2796 || FRAME_COLS (sf
) <= 0)
2797 fatal ("The frame size has not been specified");
2799 delete_in_insert_mode
2800 = TS_delete_mode
&& TS_insert_mode
2801 && !strcmp (TS_delete_mode
, TS_insert_mode
);
2803 se_is_so
= (TS_standout_mode
2804 && TS_end_standout_mode
2805 && !strcmp (TS_standout_mode
, TS_end_standout_mode
));
2807 UseTabs
= tabs_safe_p () && TabWidth
== 8;
2811 && (TS_set_window
|| TS_set_scroll_region
|| TS_set_scroll_region_1
));
2813 line_ins_del_ok
= (((TS_ins_line
|| TS_ins_multi_lines
)
2814 && (TS_del_line
|| TS_del_multi_lines
))
2815 || (scroll_region_ok
&& TS_fwd_scroll
&& TS_rev_scroll
));
2817 char_ins_del_ok
= ((TS_ins_char
|| TS_insert_mode
2818 || TS_pad_inserted_char
|| TS_ins_multi_chars
)
2819 && (TS_del_char
|| TS_del_multi_chars
));
2821 fast_clear_end_of_line
= TS_clr_line
!= 0;
2824 if (read_socket_hook
) /* Baudrate is somewhat */
2825 /* meaningless in this case */
2828 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
2829 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
2830 #endif /* WINDOWSNT */
2837 fatal (str
, arg1
, arg2
)
2838 char *str
, *arg1
, *arg2
;
2840 fprintf (stderr
, "emacs: ");
2841 fprintf (stderr
, str
, arg1
, arg2
);
2842 fprintf (stderr
, "\n");
2847 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 0, 0,
2848 doc
: /* Declare that this terminal does not handle underlining.
2849 This is used to override the terminfo data, for certain terminals that
2850 do not really do underlining, but say that they do. */)
2853 TS_enter_underline_mode
= 0;
2860 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
2861 doc
: /* Non-nil means the system uses terminfo rather than termcap.
2862 This variable can be used by terminal emulator packages. */);
2864 system_uses_terminfo
= 1;
2866 system_uses_terminfo
= 0;
2869 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
2870 doc
: /* Non-nil means call this function to ring the bell.
2871 The function should accept no arguments. */);
2872 Vring_bell_function
= Qnil
;
2874 DEFVAR_BOOL ("visible-cursor", &visible_cursor
,
2875 doc
: /* Non-nil means to make the cursor very visible.
2876 This only has an effect when running in a text terminal.
2877 What means \"very visible\" is up to your terminal. It may make the cursor
2878 bigger, or it may make it blink, or it may do nothing at all. */);
2881 defsubr (&Stty_display_color_p
);
2882 defsubr (&Stty_display_color_cells
);
2883 defsubr (&Stty_no_underline
);
2885 fullscreen_hook
= NULL
;
2888 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
2889 (do not change this comment) */