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