1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001,
3 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
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"
39 #include "termhooks.h"
40 #include "dispextern.h"
44 /* For now, don't try to include termcap.h. On some systems,
45 configure finds a non-standard termcap.h that the main build
48 #if defined HAVE_TERMCAP_H && 0
51 extern void tputs
P_ ((const char *, int, int (*)(int)));
52 extern int tgetent
P_ ((char *, const char *));
53 extern int tgetflag
P_ ((char *id
));
54 extern int tgetnum
P_ ((char *id
));
65 static void turn_on_face
P_ ((struct frame
*, int face_id
));
66 static void turn_off_face
P_ ((struct frame
*, int face_id
));
67 static void tty_show_cursor
P_ ((void));
68 static void tty_hide_cursor
P_ ((void));
71 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) - curY), cmputc)
72 #define OUTPUT1(a) tputs (a, 1, cmputc)
73 #define OUTPUTL(a, lines) tputs (a, lines, cmputc)
75 #define OUTPUT_IF(a) \
78 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) \
82 #define OUTPUT1_IF(a) do { if (a) tputs (a, 1, cmputc); } while (0)
84 /* Display space properties */
86 extern Lisp_Object Qspace
, QCalign_to
, QCwidth
;
88 /* Function to use to ring the bell. */
90 Lisp_Object Vring_bell_function
;
92 /* Terminal characteristics that higher levels want to look at.
93 These are all extern'd in termchar.h */
95 int must_write_spaces
; /* Nonzero means spaces in the text
96 must actually be output; can't just skip
97 over some columns to leave them blank. */
98 int min_padding_speed
; /* Speed below which no padding necessary */
100 int line_ins_del_ok
; /* Terminal can insert and delete lines */
101 int char_ins_del_ok
; /* Terminal can insert and delete chars */
102 int scroll_region_ok
; /* Terminal supports setting the
104 int scroll_region_cost
; /* Cost of setting a scroll window,
105 measured in characters */
106 int memory_below_frame
; /* Terminal remembers lines
107 scrolled off bottom */
108 int fast_clear_end_of_line
; /* Terminal has a `ce' string */
110 /* Nonzero means no need to redraw the entire frame on resuming
111 a suspended Emacs. This is useful on terminals with multiple pages,
112 where one page is used for Emacs and another for all else. */
114 int no_redraw_on_reenter
;
116 /* Hook functions that you can set to snap out the functions in this file.
117 These are all extern'd in termhooks.h */
119 void (*cursor_to_hook
) P_ ((int, int));
120 void (*raw_cursor_to_hook
) P_ ((int, int));
121 void (*clear_to_end_hook
) P_ ((void));
122 void (*clear_frame_hook
) P_ ((void));
123 void (*clear_end_of_line_hook
) P_ ((int));
125 void (*ins_del_lines_hook
) P_ ((int, int));
127 void (*delete_glyphs_hook
) P_ ((int));
129 void (*ring_bell_hook
) P_ ((void));
131 void (*reset_terminal_modes_hook
) P_ ((void));
132 void (*set_terminal_modes_hook
) P_ ((void));
133 void (*update_begin_hook
) P_ ((struct frame
*));
134 void (*update_end_hook
) P_ ((struct frame
*));
135 void (*set_terminal_window_hook
) P_ ((int));
136 void (*insert_glyphs_hook
) P_ ((struct glyph
*, int));
137 void (*write_glyphs_hook
) P_ ((struct glyph
*, int));
138 void (*delete_glyphs_hook
) P_ ((int));
140 int (*read_socket_hook
) P_ ((int, int, struct input_event
*));
142 void (*frame_up_to_date_hook
) P_ ((struct frame
*));
144 /* Return the current position of the mouse.
146 Set *f to the frame the mouse is in, or zero if the mouse is in no
147 Emacs frame. If it is set to zero, all the other arguments are
150 If the motion started in a scroll bar, set *bar_window to the
151 scroll bar's window, *part to the part the mouse is currently over,
152 *x to the position of the mouse along the scroll bar, and *y to the
153 overall length of the scroll bar.
155 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
156 row of the character cell the mouse is over.
158 Set *time to the time the mouse was at the returned position.
160 This should clear mouse_moved until the next motion
163 void (*mouse_position_hook
) P_ ((FRAME_PTR
*f
, int insist
,
164 Lisp_Object
*bar_window
,
165 enum scroll_bar_part
*part
,
168 unsigned long *time
));
170 /* When reading from a minibuffer in a different frame, Emacs wants
171 to shift the highlight from the selected frame to the mini-buffer's
172 frame; under X, this means it lies about where the focus is.
173 This hook tells the window system code to re-decide where to put
176 void (*frame_rehighlight_hook
) P_ ((FRAME_PTR f
));
178 /* If we're displaying frames using a window system that can stack
179 frames on top of each other, this hook allows you to bring a frame
180 to the front, or bury it behind all the other windows. If this
181 hook is zero, that means the device we're displaying on doesn't
182 support overlapping frames, so there's no need to raise or lower
185 If RAISE is non-zero, F is brought to the front, before all other
186 windows. If RAISE is zero, F is sent to the back, behind all other
189 void (*frame_raise_lower_hook
) P_ ((FRAME_PTR f
, int raise
));
191 /* Set the vertical scroll bar for WINDOW to have its upper left corner
192 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
193 indicate that we are displaying PORTION characters out of a total
194 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
195 have a scroll bar, create one for it. */
197 void (*set_vertical_scroll_bar_hook
)
198 P_ ((struct window
*window
,
199 int portion
, int whole
, int position
));
202 /* The following three hooks are used when we're doing a thorough
203 redisplay of the frame. We don't explicitly know which scroll bars
204 are going to be deleted, because keeping track of when windows go
205 away is a real pain - can you say set-window-configuration?
206 Instead, we just assert at the beginning of redisplay that *all*
207 scroll bars are to be removed, and then save scroll bars from the
208 fiery pit when we actually redisplay their window. */
210 /* Arrange for all scroll bars on FRAME to be removed at the next call
211 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
212 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
214 This should be applied to each frame each time its window tree is
215 redisplayed, even if it is not displaying scroll bars at the moment;
216 if the HAS_SCROLL_BARS flag has just been turned off, only calling
217 this and the judge_scroll_bars_hook will get rid of them.
219 If non-zero, this hook should be safe to apply to any frame,
220 whether or not it can support scroll bars, and whether or not it is
221 currently displaying them. */
223 void (*condemn_scroll_bars_hook
) P_ ((FRAME_PTR frame
));
225 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
226 Note that it's okay to redeem a scroll bar that is not condemned. */
228 void (*redeem_scroll_bar_hook
) P_ ((struct window
*window
));
230 /* Remove all scroll bars on FRAME that haven't been saved since the
231 last call to `*condemn_scroll_bars_hook'.
233 This should be applied to each frame after each time its window
234 tree is redisplayed, even if it is not displaying scroll bars at the
235 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
236 calling this and condemn_scroll_bars_hook will get rid of them.
238 If non-zero, this hook should be safe to apply to any frame,
239 whether or not it can support scroll bars, and whether or not it is
240 currently displaying them. */
242 void (*judge_scroll_bars_hook
) P_ ((FRAME_PTR FRAME
));
244 /* Strings, numbers and flags taken from the termcap entry. */
246 char *TS_ins_line
; /* "al" */
247 char *TS_ins_multi_lines
; /* "AL" (one parameter, # lines to insert) */
248 char *TS_bell
; /* "bl" */
249 char *TS_clr_to_bottom
; /* "cd" */
250 char *TS_clr_line
; /* "ce", clear to end of line */
251 char *TS_clr_frame
; /* "cl" */
252 char *TS_set_scroll_region
; /* "cs" (2 params, first line and last line) */
253 char *TS_set_scroll_region_1
; /* "cS" (4 params: total lines,
254 lines above scroll region, lines below it,
255 total lines again) */
256 char *TS_del_char
; /* "dc" */
257 char *TS_del_multi_chars
; /* "DC" (one parameter, # chars to delete) */
258 char *TS_del_line
; /* "dl" */
259 char *TS_del_multi_lines
; /* "DL" (one parameter, # lines to delete) */
260 char *TS_delete_mode
; /* "dm", enter character-delete mode */
261 char *TS_end_delete_mode
; /* "ed", leave character-delete mode */
262 char *TS_end_insert_mode
; /* "ei", leave character-insert mode */
263 char *TS_ins_char
; /* "ic" */
264 char *TS_ins_multi_chars
; /* "IC" (one parameter, # chars to insert) */
265 char *TS_insert_mode
; /* "im", enter character-insert mode */
266 char *TS_pad_inserted_char
; /* "ip". Just padding, no commands. */
267 char *TS_end_keypad_mode
; /* "ke" */
268 char *TS_keypad_mode
; /* "ks" */
269 char *TS_pad_char
; /* "pc", char to use as padding */
270 char *TS_repeat
; /* "rp" (2 params, # times to repeat
271 and character to be repeated) */
272 char *TS_end_standout_mode
; /* "se" */
273 char *TS_fwd_scroll
; /* "sf" */
274 char *TS_standout_mode
; /* "so" */
275 char *TS_rev_scroll
; /* "sr" */
276 char *TS_end_termcap_modes
; /* "te" */
277 char *TS_termcap_modes
; /* "ti" */
278 char *TS_visible_bell
; /* "vb" */
279 char *TS_cursor_normal
; /* "ve" */
280 char *TS_cursor_visible
; /* "vs" */
281 char *TS_cursor_invisible
; /* "vi" */
282 char *TS_set_window
; /* "wi" (4 params, start and end of window,
283 each as vpos and hpos) */
285 /* Value of the "NC" (no_color_video) capability, or 0 if not
288 static int TN_no_color_video
;
290 /* Meaning of bits in no_color_video. Each bit set means that the
291 corresponding attribute cannot be combined with colors. */
295 NC_STANDOUT
= 1 << 0,
296 NC_UNDERLINE
= 1 << 1,
303 NC_ALT_CHARSET
= 1 << 8
306 /* "md" -- turn on bold (extra bright mode). */
308 char *TS_enter_bold_mode
;
310 /* "mh" -- turn on half-bright mode. */
312 char *TS_enter_dim_mode
;
314 /* "mb" -- enter blinking mode. */
316 char *TS_enter_blink_mode
;
318 /* "mr" -- enter reverse video mode. */
320 char *TS_enter_reverse_mode
;
322 /* "us"/"ue" -- start/end underlining. */
324 char *TS_exit_underline_mode
, *TS_enter_underline_mode
;
326 /* "as"/"ae" -- start/end alternate character set. Not really
329 char *TS_enter_alt_charset_mode
, *TS_exit_alt_charset_mode
;
331 /* "me" -- switch appearances off. */
333 char *TS_exit_attribute_mode
;
335 /* "Co" -- number of colors. */
339 /* "pa" -- max. number of color pairs on screen. Not handled yet.
340 Could be a problem if not equal to TN_max_colors * TN_max_colors. */
344 /* "op" -- SVr4 set default pair to its original value. */
348 /* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
349 1 param, the color index. */
351 char *TS_set_foreground
, *TS_set_background
;
353 int TF_hazeltine
; /* termcap hz flag. */
354 int TF_insmode_motion
; /* termcap mi flag: can move while in insert mode. */
355 int TF_standout_motion
; /* termcap mi flag: can move while in standout mode. */
356 int TF_underscore
; /* termcap ul flag: _ underlines if over-struck on
357 non-blank position. Must clear before writing _. */
358 int TF_teleray
; /* termcap xt flag: many weird consequences.
361 static int RPov
; /* # chars to start a TS_repeat */
363 static int delete_in_insert_mode
; /* delete mode == insert mode */
365 static int se_is_so
; /* 1 if same string both enters and leaves
370 /* The largest frame width in any call to calculate_costs. */
374 /* The largest frame height in any call to calculate_costs. */
378 static int costs_set
; /* Nonzero if costs have been calculated. */
380 int insert_mode
; /* Nonzero when in insert mode. */
381 int standout_mode
; /* Nonzero when in standout mode. */
383 /* Size of window specified by higher levels.
384 This is the number of lines, from the top of frame downwards,
385 which can participate in insert-line/delete-line operations.
387 Effectively it excludes the bottom frame_lines - specified_window_size
388 lines from those operations. */
390 int specified_window
;
392 /* Frame currently being redisplayed; 0 if not currently redisplaying.
393 (Direct output does not count). */
395 FRAME_PTR updating_frame
;
397 /* Provided for lisp packages. */
399 static int system_uses_terminfo
;
401 /* Flag used in tty_show/hide_cursor. */
403 static int tty_cursor_hidden
;
407 extern char *tgetstr ();
411 /* We aren't X windows, but we aren't termcap either. This makes me
412 uncertain as to what value to use for frame.output_method. For
413 this file, we'll define FRAME_TERMCAP_P to be zero so that our
414 output hooks get called instead of the termcap functions. Probably
415 the best long-term solution is to define an output_windows_nt... */
417 #undef FRAME_TERMCAP_P
418 #define FRAME_TERMCAP_P(_f_) 0
419 #endif /* WINDOWSNT */
424 if (!NILP (Vring_bell_function
))
426 Lisp_Object function
;
428 /* Temporarily set the global variable to nil
429 so that if we get an error, it stays nil
430 and we don't call it over and over.
432 We don't specbind it, because that would carefully
433 restore the bad value if there's an error
434 and make the loop of errors happen anyway. */
436 function
= Vring_bell_function
;
437 Vring_bell_function
= Qnil
;
441 Vring_bell_function
= function
;
443 else if (!FRAME_TERMCAP_P (XFRAME (selected_frame
)))
444 (*ring_bell_hook
) ();
446 OUTPUT (TS_visible_bell
&& visible_bell
? TS_visible_bell
: TS_bell
);
450 set_terminal_modes ()
452 if (FRAME_TERMCAP_P (XFRAME (selected_frame
)))
454 if (TS_termcap_modes
)
455 OUTPUT (TS_termcap_modes
);
458 /* Output enough newlines to scroll all the old screen contents
459 off the screen, so it won't be overwritten and lost. */
461 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
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 turn_off_highlight ();
480 OUTPUT_IF (TS_end_keypad_mode
);
481 OUTPUT_IF (TS_cursor_normal
);
482 OUTPUT_IF (TS_end_termcap_modes
);
483 OUTPUT_IF (TS_orig_pair
);
484 /* Output raw CR so kernel can track the cursor hpos. */
487 else if (reset_terminal_modes_hook
)
488 (*reset_terminal_modes_hook
) ();
496 if (!FRAME_TERMCAP_P (f
))
497 update_begin_hook (f
);
504 if (FRAME_TERMCAP_P (f
))
506 if (!XWINDOW (selected_window
)->cursor_off_p
)
509 background_highlight ();
514 updating_frame
= NULL
;
518 set_terminal_window (size
)
521 if (FRAME_TERMCAP_P (updating_frame
))
523 specified_window
= size
? size
: FRAME_LINES (updating_frame
);
524 if (scroll_region_ok
)
525 set_scroll_region (0, specified_window
);
528 set_terminal_window_hook (size
);
532 set_scroll_region (start
, stop
)
536 struct frame
*sf
= XFRAME (selected_frame
);
538 if (TS_set_scroll_region
)
539 buf
= tparam (TS_set_scroll_region
, 0, 0, start
, stop
- 1);
540 else if (TS_set_scroll_region_1
)
541 buf
= tparam (TS_set_scroll_region_1
, 0, 0,
542 FRAME_LINES (sf
), start
,
543 FRAME_LINES (sf
) - stop
,
546 buf
= tparam (TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (sf
));
558 OUTPUT (TS_insert_mode
);
566 OUTPUT (TS_end_insert_mode
);
570 /* Handle highlighting. */
573 turn_off_highlight ()
576 OUTPUT_IF (TS_end_standout_mode
);
584 OUTPUT_IF (TS_standout_mode
);
592 turn_off_highlight ();
594 turn_on_highlight ();
598 /* Make cursor invisible. */
603 if (tty_cursor_hidden
== 0)
605 tty_cursor_hidden
= 1;
606 OUTPUT_IF (TS_cursor_invisible
);
611 /* Ensure that cursor is visible. */
616 if (tty_cursor_hidden
)
618 tty_cursor_hidden
= 0;
619 OUTPUT_IF (TS_cursor_normal
);
620 OUTPUT_IF (TS_cursor_visible
);
625 /* Set standout mode to the state it should be in for
626 empty space inside windows. What this is,
627 depends on the user option inverse-video. */
630 background_highlight ()
633 turn_on_highlight ();
635 turn_off_highlight ();
638 /* Set standout mode to the mode specified for the text to be output. */
641 highlight_if_desired ()
644 turn_on_highlight ();
646 turn_off_highlight ();
650 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
651 frame-relative coordinates. */
654 cursor_to (vpos
, hpos
)
657 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
659 if (! FRAME_TERMCAP_P (f
) && cursor_to_hook
)
661 (*cursor_to_hook
) (vpos
, hpos
);
665 /* Detect the case where we are called from reset_sys_modes
666 and the costs have never been calculated. Do nothing. */
670 if (curY
== vpos
&& curX
== hpos
)
672 if (!TF_standout_motion
)
673 background_highlight ();
674 if (!TF_insmode_motion
)
679 /* Similar but don't take any account of the wasted characters. */
682 raw_cursor_to (row
, col
)
685 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
686 if (! FRAME_TERMCAP_P (f
))
688 (*raw_cursor_to_hook
) (row
, col
);
691 if (curY
== row
&& curX
== col
)
693 if (!TF_standout_motion
)
694 background_highlight ();
695 if (!TF_insmode_motion
)
700 /* Erase operations */
702 /* clear from cursor to end of frame */
708 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
710 (*clear_to_end_hook
) ();
713 if (TS_clr_to_bottom
)
715 background_highlight ();
716 OUTPUT (TS_clr_to_bottom
);
720 for (i
= curY
; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
723 clear_end_of_line (FRAME_COLS (XFRAME (selected_frame
)));
728 /* Clear entire frame */
733 struct frame
*sf
= XFRAME (selected_frame
);
736 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: sf
)))
738 (*clear_frame_hook
) ();
743 background_highlight ();
744 OUTPUT (TS_clr_frame
);
754 /* Clear from cursor to end of line.
755 Assume that the line is already clear starting at column first_unused_hpos.
757 Note that the cursor may be moved, on terminals lacking a `ce' string. */
760 clear_end_of_line (first_unused_hpos
)
761 int first_unused_hpos
;
765 if (clear_end_of_line_hook
766 && ! FRAME_TERMCAP_P ((updating_frame
768 : XFRAME (selected_frame
))))
770 (*clear_end_of_line_hook
) (first_unused_hpos
);
774 /* Detect the case where we are called from reset_sys_modes
775 and the costs have never been calculated. Do nothing. */
779 if (curX
>= first_unused_hpos
)
781 background_highlight ();
784 OUTPUT1 (TS_clr_line
);
787 { /* have to do it the hard way */
788 struct frame
*sf
= XFRAME (selected_frame
);
791 /* Do not write in last row last col with Auto-wrap on. */
792 if (AutoWrap
&& curY
== FRAME_LINES (sf
) - 1
793 && first_unused_hpos
== FRAME_COLS (sf
))
796 for (i
= curX
; i
< first_unused_hpos
; i
++)
799 fputc (' ', termscript
);
802 cmplus (first_unused_hpos
- curX
);
806 /* Buffers to store the source and result of code conversion for terminal. */
807 static unsigned char *encode_terminal_src
;
808 static unsigned char *encode_terminal_dst
;
809 /* Allocated sizes of the above buffers. */
810 static int encode_terminal_src_size
;
811 static int encode_terminal_dst_size
;
813 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
814 Set CODING->produced to the byte-length of the resulting byte
815 sequence, and return a pointer to that byte sequence. */
818 encode_terminal_code (src
, src_len
, coding
)
821 struct coding_system
*coding
;
823 struct glyph
*src_end
= src
+ src_len
;
826 int nchars
, nbytes
, required
;
827 register int tlen
= GLYPH_TABLE_LENGTH
;
828 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
829 Lisp_Object charset_list
;
831 /* Allocate sufficient size of buffer to store all characters in
832 multibyte-form. But, it may be enlarged on demand if
833 Vglyph_table contains a string. */
834 required
= MAX_MULTIBYTE_LENGTH
* src_len
;
835 if (encode_terminal_src_size
< required
)
837 if (encode_terminal_src_size
== 0)
838 encode_terminal_src
= xmalloc (required
);
840 encode_terminal_src
= xrealloc (encode_terminal_src
, required
);
841 encode_terminal_src_size
= required
;
844 charset_list
= coding_charset_list (coding
);
846 buf
= encode_terminal_src
;
848 while (src
< src_end
)
850 /* We must skip glyphs to be padded for a wide character. */
851 if (! CHAR_GLYPH_PADDING_P (*src
))
857 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
859 if (g
< 0 || g
>= tlen
)
861 /* This glyph doesn't has an entry in Vglyph_table. */
866 /* This glyph has an entry in Vglyph_table,
867 so process any alias before testing for simpleness. */
868 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
870 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
871 /* We set the multi-byte form of a character in G
872 (that should be an ASCII character) at WORKBUF. */
873 c
= FAST_GLYPH_CHAR (g
);
875 /* We have a string in Vglyph_table. */
881 if (char_charset (c
, charset_list
, NULL
))
883 /* Store the multibyte form of C at BUF. */
884 buf
+= CHAR_STRING (c
, buf
);
889 /* C is not encodable. */
892 while (src
+ 1 < src_end
&& CHAR_GLYPH_PADDING_P (src
[1]))
902 unsigned char *p
= SDATA (string
), *pend
= p
+ SBYTES (string
);
904 if (! STRING_MULTIBYTE (string
))
905 string
= string_to_multibyte (string
);
906 nbytes
= buf
- encode_terminal_src
;
907 if (encode_terminal_src_size
< nbytes
+ SBYTES (string
))
909 encode_terminal_src_size
= nbytes
+ SBYTES (string
);
910 encode_terminal_src
= xrealloc (encode_terminal_src
,
911 encode_terminal_src_size
);
912 buf
= encode_terminal_src
+ nbytes
;
914 bcopy (SDATA (string
), buf
, SBYTES (string
));
915 buf
+= SBYTES (string
);
916 nchars
+= SCHARS (string
);
924 coding
->produced
= 0;
928 nbytes
= buf
- encode_terminal_src
;
929 coding
->source
= encode_terminal_src
;
930 if (encode_terminal_dst_size
== 0)
932 encode_terminal_dst_size
= encode_terminal_src_size
;
933 encode_terminal_dst
= xmalloc (encode_terminal_dst_size
);
935 coding
->destination
= encode_terminal_dst
;
936 coding
->dst_bytes
= encode_terminal_dst_size
;
937 encode_coding_object (coding
, Qnil
, 0, 0, nchars
, nbytes
, Qnil
);
938 /* coding->destination may have been reallocated. */
939 encode_terminal_dst
= coding
->destination
;
940 encode_terminal_dst_size
= coding
->dst_bytes
;
942 return (encode_terminal_dst
);
947 write_glyphs (string
, len
)
948 register struct glyph
*string
;
951 int produced
, consumed
;
952 struct frame
*sf
= XFRAME (selected_frame
);
953 struct frame
*f
= updating_frame
? updating_frame
: sf
;
954 unsigned char *conversion_buffer
;
955 struct coding_system
*coding
;
957 if (write_glyphs_hook
958 && ! FRAME_TERMCAP_P (f
))
960 (*write_glyphs_hook
) (string
, len
);
967 /* Don't dare write in last column of bottom line, if Auto-Wrap,
968 since that would scroll the whole frame on some terminals. */
971 && curY
+ 1 == FRAME_LINES (sf
)
972 && (curX
+ len
) == FRAME_COLS (sf
))
979 /* If terminal_coding does any conversion, use it, otherwise use
980 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
981 because it always return 1 if the member src_multibyte is 1. */
982 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
983 ? &terminal_coding
: &safe_terminal_coding
);
984 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
986 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
990 /* Identify a run of glyphs with the same face. */
991 int face_id
= string
->face_id
;
994 for (n
= 1; n
< len
; ++n
)
995 if (string
[n
].face_id
!= face_id
)
998 /* Turn appearance modes of the face of the run on. */
999 highlight_if_desired ();
1000 turn_on_face (f
, face_id
);
1003 /* This is the last run. */
1004 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
1005 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
1006 if (coding
->produced
> 0)
1008 fwrite (conversion_buffer
, 1, coding
->produced
, stdout
);
1009 if (ferror (stdout
))
1012 fwrite (conversion_buffer
, 1, coding
->produced
, termscript
);
1017 /* Turn appearance modes off. */
1018 turn_off_face (f
, face_id
);
1019 turn_off_highlight ();
1025 /* If start is zero, insert blanks instead of a string at start */
1028 insert_glyphs (start
, len
)
1029 register struct glyph
*start
;
1033 struct glyph
*glyph
= NULL
;
1034 struct frame
*f
, *sf
;
1035 unsigned char *conversion_buffer
;
1036 unsigned char space
[1];
1037 struct coding_system
*coding
;
1042 if (insert_glyphs_hook
)
1044 (*insert_glyphs_hook
) (start
, len
);
1048 sf
= XFRAME (selected_frame
);
1049 f
= updating_frame
? updating_frame
: sf
;
1051 if (TS_ins_multi_chars
)
1053 buf
= tparam (TS_ins_multi_chars
, 0, 0, len
);
1057 write_glyphs (start
, len
);
1065 space
[0] = SPACEGLYPH
;
1067 /* If terminal_coding does any conversion, use it, otherwise use
1068 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
1069 because it always return 1 if the member src_multibyte is 1. */
1070 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
1071 ? &terminal_coding
: &safe_terminal_coding
);
1072 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1074 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
1078 OUTPUT1_IF (TS_ins_char
);
1081 conversion_buffer
= space
;
1082 coding
->produced
= 1;
1086 highlight_if_desired ();
1087 turn_on_face (f
, start
->face_id
);
1090 /* We must open sufficient space for a character which
1091 occupies more than one column. */
1092 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
1094 OUTPUT1_IF (TS_ins_char
);
1099 /* This is the last glyph. */
1100 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
1102 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
1105 if (coding
->produced
> 0)
1107 fwrite (conversion_buffer
, 1, coding
->produced
, stdout
);
1108 if (ferror (stdout
))
1111 fwrite (conversion_buffer
, 1, coding
->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_LINES (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 (!scroll_region_ok
&& memory_below_frame
&& n
< 0)
1227 cursor_to (FRAME_LINES (sf
) + n
, 0);
1232 /* Compute cost of sending "str", in characters,
1233 not counting any line-dependent padding. */
1241 tputs (str
, 0, evalcost
);
1245 /* Compute cost of sending "str", in characters,
1246 counting any line-dependent padding at one line. */
1249 string_cost_one_line (str
)
1254 tputs (str
, 1, evalcost
);
1258 /* Compute per line amount of line-dependent padding,
1259 in tenths of characters. */
1267 tputs (str
, 0, evalcost
);
1270 tputs (str
, 10, evalcost
);
1275 /* char_ins_del_cost[n] is cost of inserting N characters.
1276 char_ins_del_cost[-n] is cost of deleting N characters.
1277 The length of this vector is based on max_frame_cols. */
1279 int *char_ins_del_vector
;
1281 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1286 calculate_ins_del_char_costs (frame
)
1289 int ins_startup_cost
, del_startup_cost
;
1290 int ins_cost_per_char
, del_cost_per_char
;
1294 if (TS_ins_multi_chars
)
1296 ins_cost_per_char
= 0;
1297 ins_startup_cost
= string_cost_one_line (TS_ins_multi_chars
);
1299 else if (TS_ins_char
|| TS_pad_inserted_char
1300 || (TS_insert_mode
&& TS_end_insert_mode
))
1302 ins_startup_cost
= (30 * (string_cost (TS_insert_mode
)
1303 + string_cost (TS_end_insert_mode
))) / 100;
1304 ins_cost_per_char
= (string_cost_one_line (TS_ins_char
)
1305 + string_cost_one_line (TS_pad_inserted_char
));
1309 ins_startup_cost
= 9999;
1310 ins_cost_per_char
= 0;
1313 if (TS_del_multi_chars
)
1315 del_cost_per_char
= 0;
1316 del_startup_cost
= string_cost_one_line (TS_del_multi_chars
);
1318 else if (TS_del_char
)
1320 del_startup_cost
= (string_cost (TS_delete_mode
)
1321 + string_cost (TS_end_delete_mode
));
1322 if (delete_in_insert_mode
)
1323 del_startup_cost
/= 2;
1324 del_cost_per_char
= string_cost_one_line (TS_del_char
);
1328 del_startup_cost
= 9999;
1329 del_cost_per_char
= 0;
1332 /* Delete costs are at negative offsets */
1333 p
= &char_ins_del_cost (frame
)[0];
1334 for (i
= FRAME_COLS (frame
); --i
>= 0;)
1335 *--p
= (del_startup_cost
+= del_cost_per_char
);
1337 /* Doing nothing is free */
1338 p
= &char_ins_del_cost (frame
)[0];
1341 /* Insert costs are at positive offsets */
1342 for (i
= FRAME_COLS (frame
); --i
>= 0;)
1343 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1347 calculate_costs (frame
)
1350 register char *f
= (TS_set_scroll_region
1351 ? TS_set_scroll_region
1352 : TS_set_scroll_region_1
);
1354 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1356 scroll_region_cost
= string_cost (f
);
1358 /* These variables are only used for terminal stuff. They are allocated
1359 once for the terminal frame of X-windows emacs, but not used afterwards.
1361 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1362 X turns off char_ins_del_ok. */
1364 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1365 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1369 if (char_ins_del_vector
!= 0)
1371 = (int *) xrealloc (char_ins_del_vector
,
1373 + 2 * max_frame_cols
* sizeof (int)));
1376 = (int *) xmalloc (sizeof (int)
1377 + 2 * max_frame_cols
* sizeof (int));
1379 bzero (char_ins_del_vector
, (sizeof (int)
1380 + 2 * max_frame_cols
* sizeof (int)));
1382 if (f
&& (!TS_ins_line
&& !TS_del_line
))
1383 do_line_insertion_deletion_costs (frame
,
1384 TS_rev_scroll
, TS_ins_multi_lines
,
1385 TS_fwd_scroll
, TS_del_multi_lines
,
1388 do_line_insertion_deletion_costs (frame
,
1389 TS_ins_line
, TS_ins_multi_lines
,
1390 TS_del_line
, TS_del_multi_lines
,
1393 calculate_ins_del_char_costs (frame
);
1395 /* Don't use TS_repeat if its padding is worse than sending the chars */
1396 if (TS_repeat
&& per_line_cost (TS_repeat
) * baud_rate
< 9000)
1397 RPov
= string_cost (TS_repeat
);
1399 RPov
= FRAME_COLS (frame
) * 2;
1401 cmcostinit (); /* set up cursor motion costs */
1408 /* Termcap capability names that correspond directly to X keysyms.
1409 Some of these (marked "terminfo") aren't supplied by old-style
1410 (Berkeley) termcap entries. They're listed in X keysym order;
1411 except we put the keypad keys first, so that if they clash with
1412 other keys (as on the IBM PC keyboard) they get overridden.
1415 static struct fkey_table keys
[] =
1417 {"kh", "home"}, /* termcap */
1418 {"kl", "left"}, /* termcap */
1419 {"ku", "up"}, /* termcap */
1420 {"kr", "right"}, /* termcap */
1421 {"kd", "down"}, /* termcap */
1422 {"%8", "prior"}, /* terminfo */
1423 {"%5", "next"}, /* terminfo */
1424 {"@7", "end"}, /* terminfo */
1425 {"@1", "begin"}, /* terminfo */
1426 {"*6", "select"}, /* terminfo */
1427 {"%9", "print"}, /* terminfo */
1428 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1430 * "insert" --- see below
1432 {"&8", "undo"}, /* terminfo */
1433 {"%0", "redo"}, /* terminfo */
1434 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1435 {"@0", "find"}, /* terminfo */
1436 {"@2", "cancel"}, /* terminfo */
1437 {"%1", "help"}, /* terminfo */
1439 * "break" goes here, but can't be reliably intercepted with termcap
1441 {"&4", "reset"}, /* terminfo --- actually `restart' */
1443 * "system" and "user" --- no termcaps
1445 {"kE", "clearline"}, /* terminfo */
1446 {"kA", "insertline"}, /* terminfo */
1447 {"kL", "deleteline"}, /* terminfo */
1448 {"kI", "insertchar"}, /* terminfo */
1449 {"kD", "deletechar"}, /* terminfo */
1450 {"kB", "backtab"}, /* terminfo */
1452 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1454 {"@8", "kp-enter"}, /* terminfo */
1456 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1457 * "kp-multiply", "kp-add", "kp-separator",
1458 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1459 * --- no termcaps for any of these.
1461 {"K4", "kp-1"}, /* terminfo */
1463 * "kp-2" --- no termcap
1465 {"K5", "kp-3"}, /* terminfo */
1467 * "kp-4" --- no termcap
1469 {"K2", "kp-5"}, /* terminfo */
1471 * "kp-6" --- no termcap
1473 {"K1", "kp-7"}, /* terminfo */
1475 * "kp-8" --- no termcap
1477 {"K3", "kp-9"}, /* terminfo */
1479 * "kp-equal" --- no termcap
1491 {"&0", "S-cancel"}, /*shifted cancel key*/
1492 {"&9", "S-begin"}, /*shifted begin key*/
1493 {"*0", "S-find"}, /*shifted find key*/
1494 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1495 {"*4", "S-delete"}, /*shifted delete-character key*/
1496 {"*7", "S-end"}, /*shifted end key*/
1497 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1498 {"#1", "S-help"}, /*shifted help key*/
1499 {"#2", "S-home"}, /*shifted home key*/
1500 {"#3", "S-insert"}, /*shifted insert-character key*/
1501 {"#4", "S-left"}, /*shifted left-arrow key*/
1502 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1503 {"%c", "S-next"}, /*shifted next key*/
1504 {"%e", "S-prior"}, /*shifted previous key*/
1505 {"%f", "S-print"}, /*shifted print key*/
1506 {"%g", "S-redo"}, /*shifted redo key*/
1507 {"%i", "S-right"}, /*shifted right-arrow key*/
1508 {"!3", "S-undo"} /*shifted undo key*/
1511 static char **term_get_fkeys_arg
;
1512 static Lisp_Object
term_get_fkeys_1 ();
1514 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1515 This function scans the termcap function key sequence entries, and
1516 adds entries to Vfunction_key_map for each function key it finds. */
1519 term_get_fkeys (address
)
1522 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1523 errors during the call. The only errors should be from Fdefine_key
1524 when given a key sequence containing an invalid prefix key. If the
1525 termcap defines function keys which use a prefix that is already bound
1526 to a command by the default bindings, we should silently ignore that
1527 function key specification, rather than giving the user an error and
1528 refusing to run at all on such a terminal. */
1530 extern Lisp_Object
Fidentity ();
1531 term_get_fkeys_arg
= address
;
1532 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1540 char **address
= term_get_fkeys_arg
;
1542 /* This can happen if CANNOT_DUMP or with strange options. */
1544 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1546 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1548 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1550 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1551 Fmake_vector (make_number (1),
1552 intern (keys
[i
].name
)));
1555 /* The uses of the "k0" capability are inconsistent; sometimes it
1556 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1557 We will attempt to politely accommodate both systems by testing for
1558 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1561 char *k_semi
= tgetstr ("k;", address
);
1562 char *k0
= tgetstr ("k0", address
);
1563 char *k0_name
= "f10";
1568 /* Define f0 first, so that f10 takes precedence in case the
1569 key sequences happens to be the same. */
1570 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1571 Fmake_vector (make_number (1), intern ("f0")));
1572 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1573 Fmake_vector (make_number (1), intern ("f10")));
1576 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1577 Fmake_vector (make_number (1), intern (k0_name
)));
1580 /* Set up cookies for numbered function keys above f10. */
1582 char fcap
[3], fkey
[4];
1584 fcap
[0] = 'F'; fcap
[2] = '\0';
1585 for (i
= 11; i
< 64; i
++)
1588 fcap
[1] = '1' + i
- 11;
1590 fcap
[1] = 'A' + i
- 20;
1592 fcap
[1] = 'a' + i
- 46;
1595 char *sequence
= tgetstr (fcap
, address
);
1598 sprintf (fkey
, "f%d", i
);
1599 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1600 Fmake_vector (make_number (1),
1608 * Various mappings to try and get a better fit.
1611 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1612 if (!tgetstr (cap1, address)) \
1614 char *sequence = tgetstr (cap2, address); \
1616 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1617 Fmake_vector (make_number (1), \
1621 /* if there's no key_next keycap, map key_npage to `next' keysym */
1622 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1623 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1624 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1625 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1626 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1627 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1628 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1630 /* IBM has their own non-standard dialect of terminfo.
1631 If the standard name isn't found, try the IBM name. */
1632 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1633 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1634 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1635 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1636 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1637 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1638 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1639 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1640 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1641 #undef CONDITIONAL_REASSIGN
1648 /***********************************************************************
1649 Character Display Information
1650 ***********************************************************************/
1652 static void append_glyph
P_ ((struct it
*));
1653 static void produce_stretch_glyph
P_ ((struct it
*));
1656 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1657 terminal frames if IT->glyph_row != NULL. IT->c is the character
1658 for which to produce glyphs; IT->face_id contains the character's
1659 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1666 struct glyph
*glyph
, *end
;
1669 xassert (it
->glyph_row
);
1670 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1671 + it
->glyph_row
->used
[it
->area
]);
1672 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1675 i
< it
->pixel_width
&& glyph
< end
;
1678 glyph
->type
= CHAR_GLYPH
;
1679 glyph
->pixel_width
= 1;
1680 glyph
->u
.ch
= it
->c
;
1681 glyph
->face_id
= it
->face_id
;
1682 glyph
->padding_p
= i
> 0;
1683 glyph
->charpos
= CHARPOS (it
->position
);
1684 glyph
->object
= it
->object
;
1686 ++it
->glyph_row
->used
[it
->area
];
1692 /* Produce glyphs for the display element described by IT. *IT
1693 specifies what we want to produce a glyph for (character, image, ...),
1694 and where in the glyph matrix we currently are (glyph row and hpos).
1695 produce_glyphs fills in output fields of *IT with information such as the
1696 pixel width and height of a character, and maybe output actual glyphs at
1697 the same time if IT->glyph_row is non-null. See the explanation of
1698 struct display_iterator in dispextern.h for an overview.
1700 produce_glyphs also stores the result of glyph width, ascent
1701 etc. computations in *IT.
1703 IT->glyph_row may be null, in which case produce_glyphs does not
1704 actually fill in the glyphs. This is used in the move_* functions
1705 in xdisp.c for text width and height computations.
1707 Callers usually don't call produce_glyphs directly;
1708 instead they use the macro PRODUCE_GLYPHS. */
1714 /* If a hook is installed, let it do the work. */
1715 xassert (it
->what
== IT_CHARACTER
1716 || it
->what
== IT_COMPOSITION
1717 || it
->what
== IT_STRETCH
);
1719 if (it
->what
== IT_STRETCH
)
1721 produce_stretch_glyph (it
);
1725 /* Nothing but characters are supported on terminal frames. For a
1726 composition sequence, it->c is the first character of the
1728 xassert (it
->what
== IT_CHARACTER
1729 || it
->what
== IT_COMPOSITION
);
1731 if (it
->c
>= 040 && it
->c
< 0177)
1733 it
->pixel_width
= it
->nglyphs
= 1;
1737 else if (it
->c
== '\n')
1738 it
->pixel_width
= it
->nglyphs
= 0;
1739 else if (it
->c
== '\t')
1741 int absolute_x
= (it
->current_x
1742 + it
->continuation_lines_width
);
1744 = (((1 + absolute_x
+ it
->tab_width
- 1)
1749 /* If part of the TAB has been displayed on the previous line
1750 which is continued now, continuation_lines_width will have
1751 been incremented already by the part that fitted on the
1752 continued line. So, we will get the right number of spaces
1754 nspaces
= next_tab_x
- absolute_x
;
1761 it
->pixel_width
= it
->len
= 1;
1769 it
->pixel_width
= nspaces
;
1770 it
->nglyphs
= nspaces
;
1772 else if (CHAR_BYTE8_P (it
->c
))
1774 /* We must send the raw 8-bit byte as is to the terminal.
1775 Although there's no way to know how many columns it occupies
1776 on a screen, it is a good assumption that a single byte code
1777 has 1-column width. */
1778 it
->pixel_width
= it
->nglyphs
= 1;
1784 it
->pixel_width
= CHAR_WIDTH (it
->c
);
1785 it
->nglyphs
= it
->pixel_width
;
1792 /* Advance current_x by the pixel width as a convenience for
1794 if (it
->area
== TEXT_AREA
)
1795 it
->current_x
+= it
->pixel_width
;
1796 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1797 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1801 /* Produce a stretch glyph for iterator IT. IT->object is the value
1802 of the glyph property displayed. The value must be a list
1803 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1806 1. `:width WIDTH' specifies that the space should be WIDTH *
1807 canonical char width wide. WIDTH may be an integer or floating
1810 2. `:align-to HPOS' specifies that the space should be wide enough
1811 to reach HPOS, a value in canonical character units. */
1814 produce_stretch_glyph (it
)
1817 /* (space :width WIDTH ...) */
1818 Lisp_Object prop
, plist
;
1819 int width
= 0, align_to
= -1;
1820 int zero_width_ok_p
= 0;
1823 /* List should start with `space'. */
1824 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1825 plist
= XCDR (it
->object
);
1827 /* Compute the width of the stretch. */
1828 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1829 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1831 /* Absolute width `:width WIDTH' specified and valid. */
1832 zero_width_ok_p
= 1;
1833 width
= (int)(tem
+ 0.5);
1835 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1836 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1838 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1839 align_to
= (align_to
< 0
1841 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1842 else if (align_to
< 0)
1843 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1844 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1845 zero_width_ok_p
= 1;
1848 /* Nothing specified -> width defaults to canonical char width. */
1849 width
= FRAME_COLUMN_WIDTH (it
->f
);
1851 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1854 if (width
> 0 && it
->glyph_row
)
1856 Lisp_Object o_object
= it
->object
;
1857 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1861 if (!STRINGP (object
))
1862 object
= it
->w
->buffer
;
1863 it
->object
= object
;
1865 it
->pixel_width
= it
->len
= 1;
1868 it
->object
= o_object
;
1871 it
->pixel_width
= width
;
1872 it
->nglyphs
= width
;
1876 /* Get information about special display element WHAT in an
1877 environment described by IT. WHAT is one of IT_TRUNCATION or
1878 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1879 non-null glyph_row member. This function ensures that fields like
1880 face_id, c, len of IT are left untouched. */
1883 produce_special_glyphs (it
, what
)
1885 enum display_element_type what
;
1892 temp_it
.what
= IT_CHARACTER
;
1894 temp_it
.object
= make_number (0);
1895 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1897 if (what
== IT_CONTINUATION
)
1899 /* Continuation glyph. */
1901 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1902 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1904 glyph
= XINT (DISP_CONTINUE_GLYPH (it
->dp
));
1905 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
1910 else if (what
== IT_TRUNCATION
)
1912 /* Truncation glyph. */
1914 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1915 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1917 glyph
= XINT (DISP_TRUNC_GLYPH (it
->dp
));
1918 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
1926 temp_it
.c
= FAST_GLYPH_CHAR (glyph
);
1927 temp_it
.face_id
= FAST_GLYPH_FACE (glyph
);
1928 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1930 produce_glyphs (&temp_it
);
1931 it
->pixel_width
= temp_it
.pixel_width
;
1932 it
->nglyphs
= temp_it
.pixel_width
;
1937 /***********************************************************************
1939 ***********************************************************************/
1941 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1942 one of the enumerators from enum no_color_bit, or a bit set built
1943 from them. Some display attributes may not be used together with
1944 color; the termcap capability `NC' specifies which ones. */
1946 #define MAY_USE_WITH_COLORS_P(ATTR) \
1947 (TN_max_colors > 0 \
1948 ? (TN_no_color_video & (ATTR)) == 0 \
1951 /* Turn appearances of face FACE_ID on tty frame F on.
1952 FACE_ID is a realized face ID number, in the face cache. */
1955 turn_on_face (f
, face_id
)
1959 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1960 long fg
= face
->foreground
;
1961 long bg
= face
->background
;
1963 /* Do this first because TS_end_standout_mode may be the same
1964 as TS_exit_attribute_mode, which turns all appearances off. */
1965 if (MAY_USE_WITH_COLORS_P (NC_REVERSE
))
1967 if (TN_max_colors
> 0)
1969 if (fg
>= 0 && bg
>= 0)
1971 /* If the terminal supports colors, we can set them
1972 below without using reverse video. The face's fg
1973 and bg colors are set as they should appear on
1974 the screen, i.e. they take the inverse-video'ness
1975 of the face already into account. */
1977 else if (inverse_video
)
1979 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1980 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1981 toggle_highlight ();
1985 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1986 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1987 toggle_highlight ();
1992 /* If we can't display colors, use reverse video
1993 if the face specifies that. */
1996 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1997 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1998 toggle_highlight ();
2002 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
2003 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
2004 toggle_highlight ();
2009 if (face
->tty_bold_p
)
2011 if (MAY_USE_WITH_COLORS_P (NC_BOLD
))
2012 OUTPUT1_IF (TS_enter_bold_mode
);
2014 else if (face
->tty_dim_p
)
2015 if (MAY_USE_WITH_COLORS_P (NC_DIM
))
2016 OUTPUT1_IF (TS_enter_dim_mode
);
2018 /* Alternate charset and blinking not yet used. */
2019 if (face
->tty_alt_charset_p
2020 && MAY_USE_WITH_COLORS_P (NC_ALT_CHARSET
))
2021 OUTPUT1_IF (TS_enter_alt_charset_mode
);
2023 if (face
->tty_blinking_p
2024 && MAY_USE_WITH_COLORS_P (NC_BLINK
))
2025 OUTPUT1_IF (TS_enter_blink_mode
);
2027 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (NC_UNDERLINE
))
2028 OUTPUT1_IF (TS_enter_underline_mode
);
2030 if (TN_max_colors
> 0)
2034 ts
= standout_mode
? TS_set_background
: TS_set_foreground
;
2037 p
= tparam (ts
, NULL
, 0, (int) fg
);
2042 ts
= standout_mode
? TS_set_foreground
: TS_set_background
;
2045 p
= tparam (ts
, NULL
, 0, (int) bg
);
2053 /* Turn off appearances of face FACE_ID on tty frame F. */
2056 turn_off_face (f
, face_id
)
2060 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2062 xassert (face
!= NULL
);
2064 if (TS_exit_attribute_mode
)
2066 /* Capability "me" will turn off appearance modes double-bright,
2067 half-bright, reverse-video, standout, underline. It may or
2068 may not turn off alt-char-mode. */
2069 if (face
->tty_bold_p
2071 || face
->tty_reverse_p
2072 || face
->tty_alt_charset_p
2073 || face
->tty_blinking_p
2074 || face
->tty_underline_p
)
2076 OUTPUT1_IF (TS_exit_attribute_mode
);
2077 if (strcmp (TS_exit_attribute_mode
, TS_end_standout_mode
) == 0)
2081 if (face
->tty_alt_charset_p
)
2082 OUTPUT_IF (TS_exit_alt_charset_mode
);
2086 /* If we don't have "me" we can only have those appearances
2087 that have exit sequences defined. */
2088 if (face
->tty_alt_charset_p
)
2089 OUTPUT_IF (TS_exit_alt_charset_mode
);
2091 if (face
->tty_underline_p
)
2092 OUTPUT_IF (TS_exit_underline_mode
);
2095 /* Switch back to default colors. */
2096 if (TN_max_colors
> 0
2097 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2098 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2099 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2100 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2101 OUTPUT1_IF (TS_orig_pair
);
2105 /* Return non-zero if the terminal on frame F supports all of the
2106 capabilities in CAPS simultaneously, with foreground and background
2107 colors FG and BG. */
2110 tty_capable_p (f
, caps
, fg
, bg
)
2113 unsigned long fg
, bg
;
2115 #define TTY_CAPABLE_P_TRY(cap, TS, NC_bit) \
2116 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(NC_bit))) \
2119 TTY_CAPABLE_P_TRY (TTY_CAP_INVERSE
, TS_standout_mode
, NC_REVERSE
);
2120 TTY_CAPABLE_P_TRY (TTY_CAP_UNDERLINE
, TS_enter_underline_mode
, NC_UNDERLINE
);
2121 TTY_CAPABLE_P_TRY (TTY_CAP_BOLD
, TS_enter_bold_mode
, NC_BOLD
);
2122 TTY_CAPABLE_P_TRY (TTY_CAP_DIM
, TS_enter_dim_mode
, NC_DIM
);
2123 TTY_CAPABLE_P_TRY (TTY_CAP_BLINK
, TS_enter_blink_mode
, NC_BLINK
);
2124 TTY_CAPABLE_P_TRY (TTY_CAP_ALT_CHARSET
, TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
2131 /* Return non-zero if the terminal is capable to display colors. */
2133 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2135 doc
: /* Return non-nil if TTY can display colors on DISPLAY. */)
2137 Lisp_Object display
;
2139 return TN_max_colors
> 0 ? Qt
: Qnil
;
2142 /* Return the number of supported colors. */
2143 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2144 Stty_display_color_cells
, 0, 1, 0,
2145 doc
: /* Return the number of colors supported by TTY on DISPLAY. */)
2147 Lisp_Object display
;
2149 return make_number (TN_max_colors
);
2154 /* Save or restore the default color-related capabilities of this
2157 tty_default_color_capabilities (save
)
2161 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
2162 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
2166 if (default_orig_pair
)
2167 xfree (default_orig_pair
);
2168 default_orig_pair
= TS_orig_pair
? xstrdup (TS_orig_pair
) : NULL
;
2170 if (default_set_foreground
)
2171 xfree (default_set_foreground
);
2172 default_set_foreground
= TS_set_foreground
? xstrdup (TS_set_foreground
)
2175 if (default_set_background
)
2176 xfree (default_set_background
);
2177 default_set_background
= TS_set_background
? xstrdup (TS_set_background
)
2180 default_max_colors
= TN_max_colors
;
2181 default_max_pairs
= TN_max_pairs
;
2182 default_no_color_video
= TN_no_color_video
;
2186 TS_orig_pair
= default_orig_pair
;
2187 TS_set_foreground
= default_set_foreground
;
2188 TS_set_background
= default_set_background
;
2189 TN_max_colors
= default_max_colors
;
2190 TN_max_pairs
= default_max_pairs
;
2191 TN_no_color_video
= default_no_color_video
;
2195 /* Setup one of the standard tty color schemes according to MODE.
2196 MODE's value is generally the number of colors which we want to
2197 support; zero means set up for the default capabilities, the ones
2198 we saw at term_init time; -1 means turn off color support. */
2200 tty_setup_colors (mode
)
2203 /* Canonicalize all negative values of MODE. */
2209 case -1: /* no colors at all */
2212 TN_no_color_video
= 0;
2213 TS_set_foreground
= TS_set_background
= TS_orig_pair
= NULL
;
2215 case 0: /* default colors, if any */
2217 tty_default_color_capabilities (0);
2219 case 8: /* 8 standard ANSI colors */
2220 TS_orig_pair
= "\033[0m";
2222 TS_set_foreground
= "\033[3%p1%dm";
2223 TS_set_background
= "\033[4%p1%dm";
2225 TS_set_foreground
= "\033[3%dm";
2226 TS_set_background
= "\033[4%dm";
2230 TN_no_color_video
= 0;
2236 set_tty_color_mode (f
, val
)
2240 Lisp_Object color_mode_spec
, current_mode_spec
;
2241 Lisp_Object color_mode
, current_mode
;
2243 extern Lisp_Object Qtty_color_mode
;
2244 Lisp_Object tty_color_mode_alist
;
2246 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2253 if (NILP (tty_color_mode_alist
))
2254 color_mode_spec
= Qnil
;
2256 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2258 if (CONSP (color_mode_spec
))
2259 color_mode
= XCDR (color_mode_spec
);
2264 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2266 if (CONSP (current_mode_spec
))
2267 current_mode
= XCDR (current_mode_spec
);
2269 current_mode
= Qnil
;
2270 if (INTEGERP (color_mode
))
2271 mode
= XINT (color_mode
);
2273 mode
= 0; /* meaning default */
2274 if (INTEGERP (current_mode
))
2275 old_mode
= XINT (current_mode
);
2279 if (mode
!= old_mode
)
2281 tty_setup_colors (mode
);
2282 /* This recomputes all the faces given the new color
2284 call0 (intern ("tty-set-up-initial-frame-faces"));
2289 #endif /* !WINDOWSNT */
2292 /***********************************************************************
2294 ***********************************************************************/
2297 term_init (terminal_type
)
2298 char *terminal_type
;
2301 char **address
= &area
;
2302 char *buffer
= NULL
;
2303 int buffer_size
= 4096;
2306 struct frame
*sf
= XFRAME (selected_frame
);
2308 encode_terminal_src_size
= 0;
2309 encode_terminal_dst_size
= 0;
2312 initialize_w32_display ();
2316 area
= (char *) xmalloc (2044);
2318 FrameRows
= FRAME_LINES (sf
);
2319 FrameCols
= FRAME_COLS (sf
);
2320 specified_window
= FRAME_LINES (sf
);
2322 delete_in_insert_mode
= 1;
2325 scroll_region_ok
= 0;
2327 /* Seems to insert lines when it's not supposed to, messing
2328 up the display. In doing a trace, it didn't seem to be
2329 called much, so I don't think we're losing anything by
2332 line_ins_del_ok
= 0;
2333 char_ins_del_ok
= 1;
2337 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
2338 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
2339 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2342 #else /* not WINDOWSNT */
2346 buffer
= (char *) xmalloc (buffer_size
);
2347 status
= tgetent (buffer
, terminal_type
);
2351 fatal ("Cannot open terminfo database file");
2353 fatal ("Cannot open termcap database file");
2359 fatal ("Terminal type %s is not defined.\n\
2360 If that is not the actual type of terminal you have,\n\
2361 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2362 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2363 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2366 fatal ("Terminal type %s is not defined.\n\
2367 If that is not the actual type of terminal you have,\n\
2368 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2369 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2370 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2376 if (strlen (buffer
) >= buffer_size
)
2378 buffer_size
= strlen (buffer
);
2380 area
= (char *) xmalloc (buffer_size
);
2382 TS_ins_line
= tgetstr ("al", address
);
2383 TS_ins_multi_lines
= tgetstr ("AL", address
);
2384 TS_bell
= tgetstr ("bl", address
);
2385 BackTab
= tgetstr ("bt", address
);
2386 TS_clr_to_bottom
= tgetstr ("cd", address
);
2387 TS_clr_line
= tgetstr ("ce", address
);
2388 TS_clr_frame
= tgetstr ("cl", address
);
2389 ColPosition
= NULL
; /* tgetstr ("ch", address); */
2390 AbsPosition
= tgetstr ("cm", address
);
2391 CR
= tgetstr ("cr", address
);
2392 TS_set_scroll_region
= tgetstr ("cs", address
);
2393 TS_set_scroll_region_1
= tgetstr ("cS", address
);
2394 RowPosition
= tgetstr ("cv", address
);
2395 TS_del_char
= tgetstr ("dc", address
);
2396 TS_del_multi_chars
= tgetstr ("DC", address
);
2397 TS_del_line
= tgetstr ("dl", address
);
2398 TS_del_multi_lines
= tgetstr ("DL", address
);
2399 TS_delete_mode
= tgetstr ("dm", address
);
2400 TS_end_delete_mode
= tgetstr ("ed", address
);
2401 TS_end_insert_mode
= tgetstr ("ei", address
);
2402 Home
= tgetstr ("ho", address
);
2403 TS_ins_char
= tgetstr ("ic", address
);
2404 TS_ins_multi_chars
= tgetstr ("IC", address
);
2405 TS_insert_mode
= tgetstr ("im", address
);
2406 TS_pad_inserted_char
= tgetstr ("ip", address
);
2407 TS_end_keypad_mode
= tgetstr ("ke", address
);
2408 TS_keypad_mode
= tgetstr ("ks", address
);
2409 LastLine
= tgetstr ("ll", address
);
2410 Right
= tgetstr ("nd", address
);
2411 Down
= tgetstr ("do", address
);
2413 Down
= tgetstr ("nl", address
); /* Obsolete name for "do" */
2415 /* VMS puts a carriage return before each linefeed,
2416 so it is not safe to use linefeeds. */
2417 if (Down
&& Down
[0] == '\n' && Down
[1] == '\0')
2420 if (tgetflag ("bs"))
2421 Left
= "\b"; /* can't possibly be longer! */
2422 else /* (Actually, "bs" is obsolete...) */
2423 Left
= tgetstr ("le", address
);
2425 Left
= tgetstr ("bc", address
); /* Obsolete name for "le" */
2426 TS_pad_char
= tgetstr ("pc", address
);
2427 TS_repeat
= tgetstr ("rp", address
);
2428 TS_end_standout_mode
= tgetstr ("se", address
);
2429 TS_fwd_scroll
= tgetstr ("sf", address
);
2430 TS_standout_mode
= tgetstr ("so", address
);
2431 TS_rev_scroll
= tgetstr ("sr", address
);
2432 Wcm
.cm_tab
= tgetstr ("ta", address
);
2433 TS_end_termcap_modes
= tgetstr ("te", address
);
2434 TS_termcap_modes
= tgetstr ("ti", address
);
2435 Up
= tgetstr ("up", address
);
2436 TS_visible_bell
= tgetstr ("vb", address
);
2437 TS_cursor_normal
= tgetstr ("ve", address
);
2438 TS_cursor_visible
= tgetstr ("vs", address
);
2439 TS_cursor_invisible
= tgetstr ("vi", address
);
2440 TS_set_window
= tgetstr ("wi", address
);
2442 TS_enter_underline_mode
= tgetstr ("us", address
);
2443 TS_exit_underline_mode
= tgetstr ("ue", address
);
2444 TS_enter_bold_mode
= tgetstr ("md", address
);
2445 TS_enter_dim_mode
= tgetstr ("mh", address
);
2446 TS_enter_blink_mode
= tgetstr ("mb", address
);
2447 TS_enter_reverse_mode
= tgetstr ("mr", address
);
2448 TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2449 TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2450 TS_exit_attribute_mode
= tgetstr ("me", address
);
2452 MultiUp
= tgetstr ("UP", address
);
2453 MultiDown
= tgetstr ("DO", address
);
2454 MultiLeft
= tgetstr ("LE", address
);
2455 MultiRight
= tgetstr ("RI", address
);
2457 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2458 color because we can't switch back to the default foreground and
2460 TS_orig_pair
= tgetstr ("op", address
);
2463 TS_set_foreground
= tgetstr ("AF", address
);
2464 TS_set_background
= tgetstr ("AB", address
);
2465 if (!TS_set_foreground
)
2468 TS_set_foreground
= tgetstr ("Sf", address
);
2469 TS_set_background
= tgetstr ("Sb", address
);
2472 TN_max_colors
= tgetnum ("Co");
2473 TN_max_pairs
= tgetnum ("pa");
2475 TN_no_color_video
= tgetnum ("NC");
2476 if (TN_no_color_video
== -1)
2477 TN_no_color_video
= 0;
2480 tty_default_color_capabilities (1);
2482 MagicWrap
= tgetflag ("xn");
2483 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2484 the former flag imply the latter. */
2485 AutoWrap
= MagicWrap
|| tgetflag ("am");
2486 memory_below_frame
= tgetflag ("db");
2487 TF_hazeltine
= tgetflag ("hz");
2488 must_write_spaces
= tgetflag ("in");
2489 meta_key
= tgetflag ("km") || tgetflag ("MT");
2490 TF_insmode_motion
= tgetflag ("mi");
2491 TF_standout_motion
= tgetflag ("ms");
2492 TF_underscore
= tgetflag ("ul");
2493 TF_teleray
= tgetflag ("xt");
2495 term_get_fkeys (address
);
2497 /* Get frame size from system, or else from termcap. */
2500 get_frame_size (&width
, &height
);
2501 FRAME_COLS (sf
) = width
;
2502 FRAME_LINES (sf
) = height
;
2505 if (FRAME_COLS (sf
) <= 0)
2506 SET_FRAME_COLS (sf
, tgetnum ("co"));
2508 /* Keep width and external_width consistent */
2509 SET_FRAME_COLS (sf
, FRAME_COLS (sf
));
2510 if (FRAME_LINES (sf
) <= 0)
2511 FRAME_LINES (sf
) = tgetnum ("li");
2513 if (FRAME_LINES (sf
) < 3 || FRAME_COLS (sf
) < 3)
2514 fatal ("Screen size %dx%d is too small",
2515 FRAME_LINES (sf
), FRAME_COLS (sf
));
2517 min_padding_speed
= tgetnum ("pb");
2518 TabWidth
= tgetnum ("tw");
2521 /* These capabilities commonly use ^J.
2522 I don't know why, but sending them on VMS does not work;
2523 it causes following spaces to be lost, sometimes.
2524 For now, the simplest fix is to avoid using these capabilities ever. */
2525 if (Down
&& Down
[0] == '\n')
2533 TS_fwd_scroll
= Down
;
2535 PC
= TS_pad_char
? *TS_pad_char
: 0;
2540 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2541 and newer termcap doc does not seem to say there is a default.
2546 /* We don't support standout modes that use `magic cookies', so
2547 turn off any that do. */
2548 if (TS_standout_mode
&& tgetnum ("sg") >= 0)
2550 TS_standout_mode
= 0;
2551 TS_end_standout_mode
= 0;
2553 if (TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
2555 TS_enter_underline_mode
= 0;
2556 TS_exit_underline_mode
= 0;
2559 /* If there's no standout mode, try to use underlining instead. */
2560 if (TS_standout_mode
== 0)
2562 TS_standout_mode
= TS_enter_underline_mode
;
2563 TS_end_standout_mode
= TS_exit_underline_mode
;
2566 /* If no `se' string, try using a `me' string instead.
2567 If that fails, we can't use standout mode at all. */
2568 if (TS_end_standout_mode
== 0)
2570 char *s
= tgetstr ("me", address
);
2572 TS_end_standout_mode
= s
;
2574 TS_standout_mode
= 0;
2580 /* We can't support standout mode, because it uses magic cookies. */
2581 TS_standout_mode
= 0;
2582 /* But that means we cannot rely on ^M to go to column zero! */
2584 /* LF can't be trusted either -- can alter hpos */
2585 /* if move at column 0 thru a line with TS_standout_mode */
2589 /* Special handling for certain terminal types known to need it */
2591 if (!strcmp (terminal_type
, "supdup"))
2593 memory_below_frame
= 1;
2594 Wcm
.cm_losewrap
= 1;
2596 if (!strncmp (terminal_type
, "c10", 3)
2597 || !strcmp (terminal_type
, "perq"))
2599 /* Supply a makeshift :wi string.
2600 This string is not valid in general since it works only
2601 for windows starting at the upper left corner;
2602 but that is all Emacs uses.
2604 This string works only if the frame is using
2605 the top of the video memory, because addressing is memory-relative.
2606 So first check the :ti string to see if that is true.
2608 It would be simpler if the :wi string could go in the termcap
2609 entry, but it can't because it is not fully valid.
2610 If it were in the termcap entry, it would confuse other programs. */
2613 p
= TS_termcap_modes
;
2614 while (*p
&& strcmp (p
, "\033v "))
2617 TS_set_window
= "\033v%C %C %C %C ";
2619 /* Termcap entry often fails to have :in: flag */
2620 must_write_spaces
= 1;
2621 /* :ti string typically fails to have \E^G! in it */
2622 /* This limits scope of insert-char to one line. */
2623 strcpy (area
, TS_termcap_modes
);
2624 strcat (area
, "\033\007!");
2625 TS_termcap_modes
= area
;
2626 area
+= strlen (area
) + 1;
2628 /* Change all %+ parameters to %C, to handle
2629 values above 96 correctly for the C100. */
2632 if (p
[0] == '%' && p
[1] == '+')
2638 FrameRows
= FRAME_LINES (sf
);
2639 FrameCols
= FRAME_COLS (sf
);
2640 specified_window
= FRAME_LINES (sf
);
2642 if (Wcm_init () == -1) /* can't do cursor motion */
2644 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2645 It lacks the ability to position the cursor.\n\
2646 If that is not the actual type of terminal you have, use either the\n\
2647 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2648 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2652 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2653 It lacks the ability to position the cursor.\n\
2654 If that is not the actual type of terminal you have,\n\
2655 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2656 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2657 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2659 # else /* TERMCAP */
2660 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2661 It lacks the ability to position the cursor.\n\
2662 If that is not the actual type of terminal you have,\n\
2663 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2664 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2665 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2667 # endif /* TERMINFO */
2669 if (FRAME_LINES (sf
) <= 0
2670 || FRAME_COLS (sf
) <= 0)
2671 fatal ("The frame size has not been specified");
2673 delete_in_insert_mode
2674 = TS_delete_mode
&& TS_insert_mode
2675 && !strcmp (TS_delete_mode
, TS_insert_mode
);
2677 se_is_so
= (TS_standout_mode
2678 && TS_end_standout_mode
2679 && !strcmp (TS_standout_mode
, TS_end_standout_mode
));
2681 UseTabs
= tabs_safe_p () && TabWidth
== 8;
2685 && (TS_set_window
|| TS_set_scroll_region
|| TS_set_scroll_region_1
));
2687 line_ins_del_ok
= (((TS_ins_line
|| TS_ins_multi_lines
)
2688 && (TS_del_line
|| TS_del_multi_lines
))
2689 || (scroll_region_ok
&& TS_fwd_scroll
&& TS_rev_scroll
));
2691 char_ins_del_ok
= ((TS_ins_char
|| TS_insert_mode
2692 || TS_pad_inserted_char
|| TS_ins_multi_chars
)
2693 && (TS_del_char
|| TS_del_multi_chars
));
2695 fast_clear_end_of_line
= TS_clr_line
!= 0;
2698 if (read_socket_hook
) /* Baudrate is somewhat */
2699 /* meaningless in this case */
2702 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
2703 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
2704 #endif /* WINDOWSNT */
2711 fatal (str
, arg1
, arg2
)
2712 char *str
, *arg1
, *arg2
;
2714 fprintf (stderr
, "emacs: ");
2715 fprintf (stderr
, str
, arg1
, arg2
);
2716 fprintf (stderr
, "\n");
2721 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 0, 0,
2722 doc
: /* Declare that this terminal does not handle underlining.
2723 This is used to override the terminfo data, for certain terminals that
2724 do not really do underlining, but say that they do. */)
2727 TS_enter_underline_mode
= 0;
2734 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
2735 doc
: /* Non-nil means the system uses terminfo rather than termcap.
2736 This variable can be used by terminal emulator packages. */);
2738 system_uses_terminfo
= 1;
2740 system_uses_terminfo
= 0;
2743 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
2744 doc
: /* Non-nil means call this function to ring the bell.
2745 The function should accept no arguments. */);
2746 Vring_bell_function
= Qnil
;
2748 defsubr (&Stty_display_color_p
);
2749 defsubr (&Stty_display_color_cells
);
2750 defsubr (&Stty_no_underline
);
2753 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
2754 (do not change this comment) */