1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 86, 87, 93, 94, 95, 98, 2000, 2001, 2002
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
32 #include "systty.h" /* For emacs_tty in termchar.h */
40 #include "termhooks.h"
41 #include "dispextern.h"
45 /* For now, don't try to include termcap.h. On some systems,
46 configure finds a non-standard termcap.h that the main build
49 #if defined HAVE_TERMCAP_H && 0
52 extern void tputs
P_ ((const char *, int, int (*)(int)));
53 extern int tgetent
P_ ((char *, const char *));
54 extern int tgetflag
P_ ((char *id
));
55 extern int tgetnum
P_ ((char *id
));
70 static void turn_on_face
P_ ((struct frame
*, int face_id
));
71 static void turn_off_face
P_ ((struct frame
*, int face_id
));
72 static void tty_show_cursor
P_ ((struct tty_display_info
*));
73 static void tty_hide_cursor
P_ ((struct tty_display_info
*));
75 void delete_tty
P_ ((struct tty_display_info
*));
76 static void delete_tty_1
P_ ((struct tty_display_info
*));
79 #define OUTPUT(tty, a) \
80 emacs_tputs ((tty), a, \
81 (int) (FRAME_LINES (XFRAME (selected_frame)) \
85 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
86 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
88 #define OUTPUT_IF(tty, a) \
91 emacs_tputs ((tty), a, \
92 (int) (FRAME_LINES (XFRAME (selected_frame)) \
97 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
99 /* Function to use to ring the bell. */
101 Lisp_Object Vring_bell_function
;
103 /* Terminal characteristics that higher levels want to look at. */
105 struct tty_display_info
*tty_list
;
107 /* Nonzero means no need to redraw the entire frame on resuming a
108 suspended Emacs. This is useful on terminals with multiple
109 pages, where one page is used for Emacs and another for all
111 int no_redraw_on_reenter
;
113 Lisp_Object Qframe_tty_name
, Qframe_tty_type
;
115 /* Hook functions that you can set to snap out the functions in this file.
116 These are all extern'd in termhooks.h */
118 void (*cursor_to_hook
) P_ ((int, int));
119 void (*raw_cursor_to_hook
) P_ ((int, int));
120 void (*clear_to_end_hook
) P_ ((void));
121 void (*clear_frame_hook
) P_ ((void));
122 void (*clear_end_of_line_hook
) P_ ((int));
124 void (*ins_del_lines_hook
) P_ ((int, int));
126 void (*delete_glyphs_hook
) P_ ((int));
128 void (*ring_bell_hook
) P_ ((void));
130 void (*reset_terminal_modes_hook
) P_ ((void));
131 void (*set_terminal_modes_hook
) P_ ((void));
132 void (*update_begin_hook
) P_ ((struct frame
*));
133 void (*update_end_hook
) P_ ((struct frame
*));
134 void (*set_terminal_window_hook
) P_ ((int));
135 void (*insert_glyphs_hook
) P_ ((struct glyph
*, int));
136 void (*write_glyphs_hook
) P_ ((struct glyph
*, int));
137 void (*delete_glyphs_hook
) P_ ((int));
139 int (*read_socket_hook
) P_ ((struct input_event
*, int, int));
141 void (*frame_up_to_date_hook
) P_ ((struct frame
*));
143 /* Return the current position of the mouse.
145 Set *f to the frame the mouse is in, or zero if the mouse is in no
146 Emacs frame. If it is set to zero, all the other arguments are
149 If the motion started in a scroll bar, set *bar_window to the
150 scroll bar's window, *part to the part the mouse is currently over,
151 *x to the position of the mouse along the scroll bar, and *y to the
152 overall length of the scroll bar.
154 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
155 row of the character cell the mouse is over.
157 Set *time to the time the mouse was at the returned position.
159 This should clear mouse_moved until the next motion
162 void (*mouse_position_hook
) P_ ((FRAME_PTR
*f
, int insist
,
163 Lisp_Object
*bar_window
,
164 enum scroll_bar_part
*part
,
167 unsigned long *time
));
169 /* When reading from a minibuffer in a different frame, Emacs wants
170 to shift the highlight from the selected frame to the mini-buffer's
171 frame; under X, this means it lies about where the focus is.
172 This hook tells the window system code to re-decide where to put
175 void (*frame_rehighlight_hook
) P_ ((FRAME_PTR f
));
177 /* If we're displaying frames using a window system that can stack
178 frames on top of each other, this hook allows you to bring a frame
179 to the front, or bury it behind all the other windows. If this
180 hook is zero, that means the device we're displaying on doesn't
181 support overlapping frames, so there's no need to raise or lower
184 If RAISE is non-zero, F is brought to the front, before all other
185 windows. If RAISE is zero, F is sent to the back, behind all other
188 void (*frame_raise_lower_hook
) P_ ((FRAME_PTR f
, int raise
));
190 /* Set the vertical scroll bar for WINDOW to have its upper left corner
191 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
192 indicate that we are displaying PORTION characters out of a total
193 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
194 have a scroll bar, create one for it. */
196 void (*set_vertical_scroll_bar_hook
)
197 P_ ((struct window
*window
,
198 int portion
, int whole
, int position
));
201 /* The following three hooks are used when we're doing a thorough
202 redisplay of the frame. We don't explicitly know which scroll bars
203 are going to be deleted, because keeping track of when windows go
204 away is a real pain - can you say set-window-configuration?
205 Instead, we just assert at the beginning of redisplay that *all*
206 scroll bars are to be removed, and then save scroll bars from the
207 fiery pit when we actually redisplay their window. */
209 /* Arrange for all scroll bars on FRAME to be removed at the next call
210 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
211 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
213 This should be applied to each frame each time its window tree is
214 redisplayed, even if it is not displaying scroll bars at the moment;
215 if the HAS_SCROLL_BARS flag has just been turned off, only calling
216 this and the judge_scroll_bars_hook will get rid of them.
218 If non-zero, this hook should be safe to apply to any frame,
219 whether or not it can support scroll bars, and whether or not it is
220 currently displaying them. */
222 void (*condemn_scroll_bars_hook
) P_ ((FRAME_PTR frame
));
224 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
225 Note that it's okay to redeem a scroll bar that is not condemned. */
227 void (*redeem_scroll_bar_hook
) P_ ((struct window
*window
));
229 /* Remove all scroll bars on FRAME that haven't been saved since the
230 last call to `*condemn_scroll_bars_hook'.
232 This should be applied to each frame after each time its window
233 tree is redisplayed, even if it is not displaying scroll bars at the
234 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
235 calling this and condemn_scroll_bars_hook will get rid of them.
237 If non-zero, this hook should be safe to apply to any frame,
238 whether or not it can support scroll bars, and whether or not it is
239 currently displaying them. */
241 void (*judge_scroll_bars_hook
) P_ ((FRAME_PTR FRAME
));
244 /* Meaning of bits in no_color_video. Each bit set means that the
245 corresponding attribute cannot be combined with colors. */
249 NC_STANDOUT
= 1 << 0,
250 NC_UNDERLINE
= 1 << 1,
257 NC_ALT_CHARSET
= 1 << 8
262 /* The largest frame width in any call to calculate_costs. */
266 /* The largest frame height in any call to calculate_costs. */
270 /* A template for tty display methods, with common values
272 static struct display_method tty_display_method_template
;
274 /* Frame currently being redisplayed; 0 if not currently redisplaying.
275 (Direct output does not count). */
277 FRAME_PTR updating_frame
;
279 /* Provided for lisp packages. */
281 static int system_uses_terminfo
;
285 extern char *tgetstr ();
289 /* We aren't X windows, but we aren't termcap either. This makes me
290 uncertain as to what value to use for frame.output_method. For
291 this file, we'll define FRAME_TERMCAP_P to be zero so that our
292 output hooks get called instead of the termcap functions. Probably
293 the best long-term solution is to define an output_windows_nt... */
295 #undef FRAME_TERMCAP_P
296 #define FRAME_TERMCAP_P(_f_) 0
297 #endif /* WINDOWSNT */
302 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
304 if (!NILP (Vring_bell_function
))
306 Lisp_Object function
;
308 /* Temporarily set the global variable to nil
309 so that if we get an error, it stays nil
310 and we don't call it over and over.
312 We don't specbind it, because that would carefully
313 restore the bad value if there's an error
314 and make the loop of errors happen anyway. */
316 function
= Vring_bell_function
;
317 Vring_bell_function
= Qnil
;
321 Vring_bell_function
= function
;
323 else if (!FRAME_TERMCAP_P (f
))
324 (*ring_bell_hook
) ();
326 struct tty_display_info
*tty
= FRAME_TTY (f
);
327 OUTPUT (tty
, tty
->TS_visible_bell
&& visible_bell
? tty
->TS_visible_bell
: tty
->TS_bell
);
331 void tty_set_terminal_modes (struct tty_display_info
*tty
)
333 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
334 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
335 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
340 set_terminal_modes ()
342 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
343 if (FRAME_TERMCAP_P (f
))
344 tty_set_terminal_modes (FRAME_TTY (f
));
346 (*set_terminal_modes_hook
) ();
349 void tty_reset_terminal_modes (struct tty_display_info
*tty
)
351 turn_off_highlight (tty
);
352 turn_off_insert (tty
);
353 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
354 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
355 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
356 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
357 /* Output raw CR so kernel can track the cursor hpos. */
363 reset_terminal_modes ()
365 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
366 if (FRAME_TERMCAP_P (f
))
367 tty_reset_terminal_modes (FRAME_TTY (f
));
368 else if (reset_terminal_modes_hook
)
369 (*reset_terminal_modes_hook
) ();
377 if (!FRAME_TERMCAP_P (f
))
378 update_begin_hook (f
);
385 if (FRAME_TERMCAP_P (f
))
387 struct tty_display_info
*tty
= FRAME_TTY (f
);
388 if (!XWINDOW (selected_window
)->cursor_off_p
)
389 tty_show_cursor (tty
);
390 turn_off_insert (tty
);
391 background_highlight (tty
);
396 updating_frame
= NULL
;
400 set_terminal_window (size
)
403 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
404 if (FRAME_TERMCAP_P (f
))
406 struct tty_display_info
*tty
= FRAME_TTY (f
);
407 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
408 if (FRAME_SCROLL_REGION_OK (f
))
409 set_scroll_region (0, tty
->specified_window
);
412 set_terminal_window_hook (size
);
416 set_scroll_region (start
, stop
)
420 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
421 struct tty_display_info
*tty
= FRAME_TTY (f
);
423 if (tty
->TS_set_scroll_region
)
424 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
425 else if (tty
->TS_set_scroll_region_1
)
426 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
427 FRAME_LINES (f
), start
,
428 FRAME_LINES (f
) - stop
,
431 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
440 turn_on_insert (struct tty_display_info
*tty
)
442 if (!tty
->insert_mode
)
443 OUTPUT (tty
, tty
->TS_insert_mode
);
444 tty
->insert_mode
= 1;
448 turn_off_insert (struct tty_display_info
*tty
)
450 if (tty
->insert_mode
)
451 OUTPUT (tty
, tty
->TS_end_insert_mode
);
452 tty
->insert_mode
= 0;
455 /* Handle highlighting. */
458 turn_off_highlight (struct tty_display_info
*tty
)
460 if (tty
->standout_mode
)
461 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
462 tty
->standout_mode
= 0;
466 turn_on_highlight (struct tty_display_info
*tty
)
468 if (!tty
->standout_mode
)
469 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
470 tty
->standout_mode
= 1;
474 toggle_highlight (struct tty_display_info
*tty
)
476 if (tty
->standout_mode
)
477 turn_off_highlight (tty
);
479 turn_on_highlight (tty
);
483 /* Make cursor invisible. */
486 tty_hide_cursor (struct tty_display_info
*tty
)
488 if (tty
->cursor_hidden
== 0)
490 tty
->cursor_hidden
= 1;
491 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
496 /* Ensure that cursor is visible. */
499 tty_show_cursor (struct tty_display_info
*tty
)
501 if (tty
->cursor_hidden
)
503 tty
->cursor_hidden
= 0;
504 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
505 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
510 /* Set standout mode to the state it should be in for
511 empty space inside windows. What this is,
512 depends on the user option inverse-video. */
515 background_highlight (struct tty_display_info
*tty
)
518 turn_on_highlight (tty
);
520 turn_off_highlight (tty
);
523 /* Set standout mode to the mode specified for the text to be output. */
526 highlight_if_desired (struct tty_display_info
*tty
)
529 turn_on_highlight (tty
);
531 turn_off_highlight (tty
);
535 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
536 frame-relative coordinates. */
539 cursor_to (vpos
, hpos
)
542 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
543 struct tty_display_info
*tty
;
545 if (! FRAME_TERMCAP_P (f
) && cursor_to_hook
)
547 (*cursor_to_hook
) (vpos
, hpos
);
553 /* Detect the case where we are called from reset_sys_modes
554 and the costs have never been calculated. Do nothing. */
555 if (! tty
->costs_set
)
558 if (curY (tty
) == vpos
559 && curX (tty
) == hpos
)
561 if (!tty
->TF_standout_motion
)
562 background_highlight (tty
);
563 if (!tty
->TF_insmode_motion
)
564 turn_off_insert (tty
);
565 cmgoto (tty
, vpos
, hpos
);
568 /* Similar but don't take any account of the wasted characters. */
571 raw_cursor_to (row
, col
)
574 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
575 struct tty_display_info
*tty
;
576 if (! FRAME_TERMCAP_P (f
))
578 (*raw_cursor_to_hook
) (row
, col
);
582 if (curY (tty
) == row
583 && curX (tty
) == col
)
585 if (!tty
->TF_standout_motion
)
586 background_highlight (tty
);
587 if (!tty
->TF_insmode_motion
)
588 turn_off_insert (tty
);
589 cmgoto (tty
, row
, col
);
592 /* Erase operations */
594 /* clear from cursor to end of frame */
600 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
601 struct tty_display_info
*tty
;
603 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (f
))
605 (*clear_to_end_hook
) ();
609 if (tty
->TS_clr_to_bottom
)
611 background_highlight (tty
);
612 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
616 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
619 clear_end_of_line (FRAME_COLS (f
));
624 /* Clear entire frame */
629 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
630 struct tty_display_info
*tty
;
632 if (clear_frame_hook
&& ! FRAME_TERMCAP_P (f
))
634 (*clear_frame_hook
) ();
638 if (tty
->TS_clr_frame
)
640 background_highlight (tty
);
641 OUTPUT (tty
, tty
->TS_clr_frame
);
651 /* Clear from cursor to end of line.
652 Assume that the line is already clear starting at column first_unused_hpos.
654 Note that the cursor may be moved, on terminals lacking a `ce' string. */
657 clear_end_of_line (first_unused_hpos
)
658 int first_unused_hpos
;
660 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
661 struct tty_display_info
*tty
;
663 if (clear_end_of_line_hook
&& ! FRAME_TERMCAP_P (f
))
665 (*clear_end_of_line_hook
) (first_unused_hpos
);
669 tty_clear_end_of_line (FRAME_TTY (f
), first_unused_hpos
);
673 tty_clear_end_of_line (struct tty_display_info
*tty
, int first_unused_hpos
)
676 /* Detect the case where we are called from reset_sys_modes
677 and the costs have never been calculated. Do nothing. */
678 if (! tty
->costs_set
)
681 if (curX (tty
) >= first_unused_hpos
)
683 background_highlight (tty
);
684 if (tty
->TS_clr_line
)
686 OUTPUT1 (tty
, tty
->TS_clr_line
);
689 { /* have to do it the hard way */
690 turn_off_insert (tty
);
692 /* Do not write in last row last col with Auto-wrap on. */
694 && curY (tty
) == FrameRows (tty
) - 1
695 && first_unused_hpos
== FrameCols (tty
))
698 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
700 if (TTY_TERMSCRIPT (tty
))
701 fputc (' ', TTY_TERMSCRIPT (tty
));
702 fputc (' ', TTY_OUTPUT (tty
));
704 cmplus (tty
, first_unused_hpos
- curX (tty
));
708 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
709 store them at DST. Do not write more than DST_LEN bytes. That may
710 require stopping before all SRC_LEN input glyphs have been
713 We store the number of glyphs actually converted in *CONSUMED. The
714 return value is the number of bytes store in DST. */
717 encode_terminal_code (src
, dst
, src_len
, dst_len
, consumed
)
721 int dst_len
, *consumed
;
723 struct glyph
*src_start
= src
, *src_end
= src
+ src_len
;
724 unsigned char *dst_start
= dst
, *dst_end
= dst
+ dst_len
;
726 unsigned char workbuf
[MAX_MULTIBYTE_LENGTH
];
727 const unsigned char *buf
;
729 register int tlen
= GLYPH_TABLE_LENGTH
;
730 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
732 struct coding_system
*coding
;
734 /* If terminal_coding does any conversion, use it, otherwise use
735 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
736 because it always return 1 if the member src_multibyte is 1. */
737 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
739 : &safe_terminal_coding
);
741 while (src
< src_end
)
743 /* We must skip glyphs to be padded for a wide character. */
744 if (! CHAR_GLYPH_PADDING_P (*src
))
746 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
748 if (g
< 0 || g
>= tlen
)
750 /* This glyph doesn't has an entry in Vglyph_table. */
751 if (! CHAR_VALID_P (src
->u
.ch
, 0))
755 coding
->src_multibyte
= 0;
759 len
= CHAR_STRING (src
->u
.ch
, workbuf
);
761 coding
->src_multibyte
= 1;
766 /* This glyph has an entry in Vglyph_table,
767 so process any alias before testing for simpleness. */
768 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
770 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
772 /* We set the multi-byte form of a character in G
773 (that should be an ASCII character) at
775 workbuf
[0] = FAST_GLYPH_CHAR (g
);
778 coding
->src_multibyte
= 0;
782 /* We have a string in Vglyph_table. */
783 len
= GLYPH_LENGTH (tbase
, g
);
784 buf
= GLYPH_STRING (tbase
, g
);
785 coding
->src_multibyte
= STRING_MULTIBYTE (tbase
[g
]);
789 result
= encode_coding (coding
, buf
, dst
, len
, dst_end
- dst
);
790 len
-= coding
->consumed
;
791 dst
+= coding
->produced
;
792 if (result
== CODING_FINISH_INSUFFICIENT_DST
793 || (result
== CODING_FINISH_INSUFFICIENT_SRC
794 && len
> dst_end
- dst
))
795 /* The remaining output buffer is too short. We must
796 break the loop here without increasing SRC so that the
797 next call of this function starts from the same glyph. */
802 /* This is the case that a code of the range 0200..0237
803 exists in buf. We must just write out such a code. */
804 buf
+= coding
->consumed
;
812 *consumed
= src
- src_start
;
813 return (dst
- dst_start
);
818 write_glyphs (string
, len
)
819 register struct glyph
*string
;
822 int produced
, consumed
;
823 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
824 struct tty_display_info
*tty
;
825 unsigned char conversion_buffer
[1024];
826 int conversion_buffer_size
= sizeof conversion_buffer
;
828 if (write_glyphs_hook
&& ! FRAME_TERMCAP_P (f
))
830 (*write_glyphs_hook
) (string
, len
);
836 turn_off_insert (tty
);
837 tty_hide_cursor (tty
);
839 /* Don't dare write in last column of bottom line, if Auto-Wrap,
840 since that would scroll the whole frame on some terminals. */
843 && curY (tty
) + 1 == FRAME_LINES (f
)
844 && (curX (tty
) + len
) == FRAME_COLS (f
))
851 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
853 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
857 /* Identify a run of glyphs with the same face. */
858 int face_id
= string
->face_id
;
861 for (n
= 1; n
< len
; ++n
)
862 if (string
[n
].face_id
!= face_id
)
865 /* Turn appearance modes of the face of the run on. */
866 highlight_if_desired (tty
);
867 turn_on_face (f
, face_id
);
871 /* We use a fixed size (1024 bytes) of conversion buffer.
872 Usually it is sufficient, but if not, we just repeat the
874 produced
= encode_terminal_code (string
, conversion_buffer
,
875 n
, conversion_buffer_size
,
879 fwrite (conversion_buffer
, 1, produced
,
881 if (ferror (TTY_OUTPUT (tty
)))
882 clearerr (TTY_OUTPUT (tty
));
883 if (TTY_TERMSCRIPT (tty
))
884 fwrite (conversion_buffer
, 1, produced
,
885 TTY_TERMSCRIPT (tty
));
892 /* Turn appearance modes off. */
893 turn_off_face (f
, face_id
);
894 turn_off_highlight (tty
);
897 /* We may have to output some codes to terminate the writing. */
898 if (CODING_REQUIRE_FLUSHING (&terminal_coding
))
900 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
901 encode_coding (&terminal_coding
, "", conversion_buffer
,
902 0, conversion_buffer_size
);
903 if (terminal_coding
.produced
> 0)
905 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
907 if (ferror (TTY_OUTPUT (tty
)))
908 clearerr (TTY_OUTPUT (tty
));
909 if (TTY_TERMSCRIPT (tty
))
910 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
911 TTY_TERMSCRIPT (tty
));
918 /* If start is zero, insert blanks instead of a string at start */
921 insert_glyphs (start
, len
)
922 register struct glyph
*start
;
926 struct glyph
*glyph
= NULL
;
928 struct tty_display_info
*tty
;
933 f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
935 if (insert_glyphs_hook
&& ! FRAME_TERMCAP_P (f
))
937 (*insert_glyphs_hook
) (start
, len
);
943 if (tty
->TS_ins_multi_chars
)
945 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
949 write_glyphs (start
, len
);
953 turn_on_insert (tty
);
955 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
956 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
959 int produced
, consumed
;
960 unsigned char conversion_buffer
[1024];
961 int conversion_buffer_size
= sizeof conversion_buffer
;
963 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
966 conversion_buffer
[0] = SPACEGLYPH
;
971 highlight_if_desired (tty
);
972 turn_on_face (f
, start
->face_id
);
975 /* We must open sufficient space for a character which
976 occupies more than one column. */
977 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
979 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
984 /* This is the last glyph. */
985 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
987 /* The size of conversion buffer (1024 bytes) is surely
988 sufficient for just one glyph. */
989 produced
= encode_terminal_code (glyph
, conversion_buffer
, 1,
990 conversion_buffer_size
, &consumed
);
995 fwrite (conversion_buffer
, 1, produced
,
997 if (ferror (TTY_OUTPUT (tty
)))
998 clearerr (TTY_OUTPUT (tty
));
999 if (TTY_TERMSCRIPT (tty
))
1000 fwrite (conversion_buffer
, 1, produced
,
1001 TTY_TERMSCRIPT (tty
));
1004 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
1007 turn_off_face (f
, glyph
->face_id
);
1008 turn_off_highlight (tty
);
1021 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
1022 struct tty_display_info
*tty
= FRAME_TTY (f
);
1024 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (f
))
1026 (*delete_glyphs_hook
) (n
);
1031 if (tty
->delete_in_insert_mode
)
1033 turn_on_insert (tty
);
1037 turn_off_insert (tty
);
1038 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
1041 if (tty
->TS_del_multi_chars
)
1043 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
1048 for (i
= 0; i
< n
; i
++)
1049 OUTPUT1 (tty
, tty
->TS_del_char
);
1050 if (!tty
->delete_in_insert_mode
)
1051 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
1054 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1057 ins_del_lines (vpos
, n
)
1060 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
1061 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (f
))
1063 (*ins_del_lines_hook
) (vpos
, n
);
1068 struct tty_display_info
*tty
= FRAME_TTY (f
);
1069 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
1070 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
1071 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
1073 register int i
= n
> 0 ? n
: -n
;
1076 /* If the lines below the insertion are being pushed
1077 into the end of the window, this is the same as clearing;
1078 and we know the lines are already clear, since the matching
1079 deletion has already been done. So can ignore this. */
1080 /* If the lines below the deletion are blank lines coming
1081 out of the end of the window, don't bother,
1082 as there will be a matching inslines later that will flush them. */
1083 if (FRAME_SCROLL_REGION_OK (f
)
1084 && vpos
+ i
>= tty
->specified_window
)
1086 if (!FRAME_MEMORY_BELOW_FRAME (f
)
1087 && vpos
+ i
>= FRAME_LINES (f
))
1092 raw_cursor_to (vpos
, 0);
1093 background_highlight (tty
);
1094 buf
= tparam (multi
, 0, 0, i
);
1100 raw_cursor_to (vpos
, 0);
1101 background_highlight (tty
);
1103 OUTPUT (tty
, single
);
1104 if (tty
->TF_teleray
)
1109 set_scroll_region (vpos
, tty
->specified_window
);
1111 raw_cursor_to (tty
->specified_window
- 1, 0);
1113 raw_cursor_to (vpos
, 0);
1114 background_highlight (tty
);
1116 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1117 set_scroll_region (0, tty
->specified_window
);
1120 if (!FRAME_SCROLL_REGION_OK (f
)
1121 && FRAME_MEMORY_BELOW_FRAME (f
)
1124 cursor_to (FRAME_LINES (f
) + n
, 0);
1130 /* Compute cost of sending "str", in characters,
1131 not counting any line-dependent padding. */
1139 tputs (str
, 0, evalcost
);
1143 /* Compute cost of sending "str", in characters,
1144 counting any line-dependent padding at one line. */
1147 string_cost_one_line (str
)
1152 tputs (str
, 1, evalcost
);
1156 /* Compute per line amount of line-dependent padding,
1157 in tenths of characters. */
1165 tputs (str
, 0, evalcost
);
1168 tputs (str
, 10, evalcost
);
1173 /* char_ins_del_cost[n] is cost of inserting N characters.
1174 char_ins_del_cost[-n] is cost of deleting N characters.
1175 The length of this vector is based on max_frame_cols. */
1177 int *char_ins_del_vector
;
1179 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1184 calculate_ins_del_char_costs (f
)
1187 struct tty_display_info
*tty
= FRAME_TTY (f
);
1188 int ins_startup_cost
, del_startup_cost
;
1189 int ins_cost_per_char
, del_cost_per_char
;
1193 if (tty
->TS_ins_multi_chars
)
1195 ins_cost_per_char
= 0;
1196 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1198 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1199 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1201 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1202 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1203 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1204 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1208 ins_startup_cost
= 9999;
1209 ins_cost_per_char
= 0;
1212 if (tty
->TS_del_multi_chars
)
1214 del_cost_per_char
= 0;
1215 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1217 else if (tty
->TS_del_char
)
1219 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1220 + string_cost (tty
->TS_end_delete_mode
));
1221 if (tty
->delete_in_insert_mode
)
1222 del_startup_cost
/= 2;
1223 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1227 del_startup_cost
= 9999;
1228 del_cost_per_char
= 0;
1231 /* Delete costs are at negative offsets */
1232 p
= &char_ins_del_cost (f
)[0];
1233 for (i
= FRAME_COLS (f
); --i
>= 0;)
1234 *--p
= (del_startup_cost
+= del_cost_per_char
);
1236 /* Doing nothing is free */
1237 p
= &char_ins_del_cost (f
)[0];
1240 /* Insert costs are at positive offsets */
1241 for (i
= FRAME_COLS (f
); --i
>= 0;)
1242 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1246 calculate_costs (frame
)
1249 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1251 if (FRAME_TERMCAP_P (frame
))
1253 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1254 register char *f
= (tty
->TS_set_scroll_region
1255 ? tty
->TS_set_scroll_region
1256 : tty
->TS_set_scroll_region_1
);
1258 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1262 /* These variables are only used for terminal stuff. They are
1263 allocated once for the terminal frame of X-windows emacs, but not
1266 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1267 X turns off char_ins_del_ok. */
1269 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1270 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1272 if (char_ins_del_vector
!= 0)
1274 = (int *) xrealloc (char_ins_del_vector
,
1276 + 2 * max_frame_cols
* sizeof (int)));
1279 = (int *) xmalloc (sizeof (int)
1280 + 2 * max_frame_cols
* sizeof (int));
1282 bzero (char_ins_del_vector
, (sizeof (int)
1283 + 2 * max_frame_cols
* sizeof (int)));
1286 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1287 do_line_insertion_deletion_costs (frame
,
1288 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1289 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1292 do_line_insertion_deletion_costs (frame
,
1293 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1294 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1297 calculate_ins_del_char_costs (frame
);
1299 /* Don't use TS_repeat if its padding is worse than sending the chars */
1300 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1301 tty
->RPov
= string_cost (tty
->TS_repeat
);
1303 tty
->RPov
= FRAME_COLS (frame
) * 2;
1305 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1313 /* Termcap capability names that correspond directly to X keysyms.
1314 Some of these (marked "terminfo") aren't supplied by old-style
1315 (Berkeley) termcap entries. They're listed in X keysym order;
1316 except we put the keypad keys first, so that if they clash with
1317 other keys (as on the IBM PC keyboard) they get overridden.
1320 static struct fkey_table keys
[] =
1322 {"kh", "home"}, /* termcap */
1323 {"kl", "left"}, /* termcap */
1324 {"ku", "up"}, /* termcap */
1325 {"kr", "right"}, /* termcap */
1326 {"kd", "down"}, /* termcap */
1327 {"%8", "prior"}, /* terminfo */
1328 {"%5", "next"}, /* terminfo */
1329 {"@7", "end"}, /* terminfo */
1330 {"@1", "begin"}, /* terminfo */
1331 {"*6", "select"}, /* terminfo */
1332 {"%9", "print"}, /* terminfo */
1333 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1335 * "insert" --- see below
1337 {"&8", "undo"}, /* terminfo */
1338 {"%0", "redo"}, /* terminfo */
1339 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1340 {"@0", "find"}, /* terminfo */
1341 {"@2", "cancel"}, /* terminfo */
1342 {"%1", "help"}, /* terminfo */
1344 * "break" goes here, but can't be reliably intercepted with termcap
1346 {"&4", "reset"}, /* terminfo --- actually `restart' */
1348 * "system" and "user" --- no termcaps
1350 {"kE", "clearline"}, /* terminfo */
1351 {"kA", "insertline"}, /* terminfo */
1352 {"kL", "deleteline"}, /* terminfo */
1353 {"kI", "insertchar"}, /* terminfo */
1354 {"kD", "deletechar"}, /* terminfo */
1355 {"kB", "backtab"}, /* terminfo */
1357 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1359 {"@8", "kp-enter"}, /* terminfo */
1361 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1362 * "kp-multiply", "kp-add", "kp-separator",
1363 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1364 * --- no termcaps for any of these.
1366 {"K4", "kp-1"}, /* terminfo */
1368 * "kp-2" --- no termcap
1370 {"K5", "kp-3"}, /* terminfo */
1372 * "kp-4" --- no termcap
1374 {"K2", "kp-5"}, /* terminfo */
1376 * "kp-6" --- no termcap
1378 {"K1", "kp-7"}, /* terminfo */
1380 * "kp-8" --- no termcap
1382 {"K3", "kp-9"}, /* terminfo */
1384 * "kp-equal" --- no termcap
1397 static char **term_get_fkeys_arg
;
1398 static Lisp_Object
term_get_fkeys_1 ();
1400 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1401 This function scans the termcap function key sequence entries, and
1402 adds entries to Vfunction_key_map for each function key it finds. */
1405 term_get_fkeys (address
)
1408 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1409 errors during the call. The only errors should be from Fdefine_key
1410 when given a key sequence containing an invalid prefix key. If the
1411 termcap defines function keys which use a prefix that is already bound
1412 to a command by the default bindings, we should silently ignore that
1413 function key specification, rather than giving the user an error and
1414 refusing to run at all on such a terminal. */
1416 extern Lisp_Object
Fidentity ();
1417 term_get_fkeys_arg
= address
;
1418 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1426 char **address
= term_get_fkeys_arg
;
1428 /* This can happen if CANNOT_DUMP or with strange options. */
1430 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1432 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1434 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1436 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1437 Fmake_vector (make_number (1),
1438 intern (keys
[i
].name
)));
1441 /* The uses of the "k0" capability are inconsistent; sometimes it
1442 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1443 We will attempt to politely accommodate both systems by testing for
1444 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1447 char *k_semi
= tgetstr ("k;", address
);
1448 char *k0
= tgetstr ("k0", address
);
1449 char *k0_name
= "f10";
1454 /* Define f0 first, so that f10 takes precedence in case the
1455 key sequences happens to be the same. */
1456 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1457 Fmake_vector (make_number (1), intern ("f0")));
1458 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1459 Fmake_vector (make_number (1), intern ("f10")));
1462 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1463 Fmake_vector (make_number (1), intern (k0_name
)));
1466 /* Set up cookies for numbered function keys above f10. */
1468 char fcap
[3], fkey
[4];
1470 fcap
[0] = 'F'; fcap
[2] = '\0';
1471 for (i
= 11; i
< 64; i
++)
1474 fcap
[1] = '1' + i
- 11;
1476 fcap
[1] = 'A' + i
- 20;
1478 fcap
[1] = 'a' + i
- 46;
1481 char *sequence
= tgetstr (fcap
, address
);
1484 sprintf (fkey
, "f%d", i
);
1485 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1486 Fmake_vector (make_number (1),
1494 * Various mappings to try and get a better fit.
1497 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1498 if (!tgetstr (cap1, address)) \
1500 char *sequence = tgetstr (cap2, address); \
1502 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1503 Fmake_vector (make_number (1), \
1507 /* if there's no key_next keycap, map key_npage to `next' keysym */
1508 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1509 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1510 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1511 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1512 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1513 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1514 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1516 /* IBM has their own non-standard dialect of terminfo.
1517 If the standard name isn't found, try the IBM name. */
1518 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1519 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1520 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1521 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1522 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1523 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1524 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1525 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1526 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1527 #undef CONDITIONAL_REASSIGN
1534 /***********************************************************************
1535 Character Display Information
1536 ***********************************************************************/
1538 static void append_glyph
P_ ((struct it
*));
1541 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1542 terminal frames if IT->glyph_row != NULL. IT->c is the character
1543 for which to produce glyphs; IT->face_id contains the character's
1544 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1551 struct glyph
*glyph
, *end
;
1554 xassert (it
->glyph_row
);
1555 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1556 + it
->glyph_row
->used
[it
->area
]);
1557 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1560 i
< it
->pixel_width
&& glyph
< end
;
1563 glyph
->type
= CHAR_GLYPH
;
1564 glyph
->pixel_width
= 1;
1565 glyph
->u
.ch
= it
->c
;
1566 glyph
->face_id
= it
->face_id
;
1567 glyph
->padding_p
= i
> 0;
1568 glyph
->charpos
= CHARPOS (it
->position
);
1569 glyph
->object
= it
->object
;
1571 ++it
->glyph_row
->used
[it
->area
];
1577 /* Produce glyphs for the display element described by IT. *IT
1578 specifies what we want to produce a glyph for (character, image, ...),
1579 and where in the glyph matrix we currently are (glyph row and hpos).
1580 produce_glyphs fills in output fields of *IT with information such as the
1581 pixel width and height of a character, and maybe output actual glyphs at
1582 the same time if IT->glyph_row is non-null. See the explanation of
1583 struct display_iterator in dispextern.h for an overview.
1585 produce_glyphs also stores the result of glyph width, ascent
1586 etc. computations in *IT.
1588 IT->glyph_row may be null, in which case produce_glyphs does not
1589 actually fill in the glyphs. This is used in the move_* functions
1590 in xdisp.c for text width and height computations.
1592 Callers usually don't call produce_glyphs directly;
1593 instead they use the macro PRODUCE_GLYPHS. */
1599 /* If a hook is installed, let it do the work. */
1600 xassert (it
->what
== IT_CHARACTER
1601 || it
->what
== IT_COMPOSITION
1602 || it
->what
== IT_IMAGE
1603 || it
->what
== IT_STRETCH
);
1605 /* Nothing but characters are supported on terminal frames. For a
1606 composition sequence, it->c is the first character of the
1608 xassert (it
->what
== IT_CHARACTER
1609 || it
->what
== IT_COMPOSITION
);
1611 if (it
->c
>= 040 && it
->c
< 0177)
1613 it
->pixel_width
= it
->nglyphs
= 1;
1617 else if (it
->c
== '\n')
1618 it
->pixel_width
= it
->nglyphs
= 0;
1619 else if (it
->c
== '\t')
1621 int absolute_x
= (it
->current_x
1622 + it
->continuation_lines_width
);
1624 = (((1 + absolute_x
+ it
->tab_width
- 1)
1629 /* If part of the TAB has been displayed on the previous line
1630 which is continued now, continuation_lines_width will have
1631 been incremented already by the part that fitted on the
1632 continued line. So, we will get the right number of spaces
1634 nspaces
= next_tab_x
- absolute_x
;
1641 it
->pixel_width
= it
->len
= 1;
1649 it
->pixel_width
= nspaces
;
1650 it
->nglyphs
= nspaces
;
1652 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1654 /* Coming here means that it->c is from display table, thus we
1655 must send the code as is to the terminal. Although there's
1656 no way to know how many columns it occupies on a screen, it
1657 is a good assumption that a single byte code has 1-column
1659 it
->pixel_width
= it
->nglyphs
= 1;
1665 /* A multi-byte character. The display width is fixed for all
1666 characters of the set. Some of the glyphs may have to be
1667 ignored because they are already displayed in a continued
1669 int charset
= CHAR_CHARSET (it
->c
);
1671 it
->pixel_width
= CHARSET_WIDTH (charset
);
1672 it
->nglyphs
= it
->pixel_width
;
1678 /* Advance current_x by the pixel width as a convenience for
1680 if (it
->area
== TEXT_AREA
)
1681 it
->current_x
+= it
->pixel_width
;
1682 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1683 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1687 /* Get information about special display element WHAT in an
1688 environment described by IT. WHAT is one of IT_TRUNCATION or
1689 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1690 non-null glyph_row member. This function ensures that fields like
1691 face_id, c, len of IT are left untouched. */
1694 produce_special_glyphs (it
, what
)
1696 enum display_element_type what
;
1702 temp_it
.what
= IT_CHARACTER
;
1704 temp_it
.object
= make_number (0);
1705 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1707 if (what
== IT_CONTINUATION
)
1709 /* Continuation glyph. */
1711 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1712 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1714 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it
->dp
)));
1715 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1720 produce_glyphs (&temp_it
);
1721 it
->pixel_width
= temp_it
.pixel_width
;
1722 it
->nglyphs
= temp_it
.pixel_width
;
1724 else if (what
== IT_TRUNCATION
)
1726 /* Truncation glyph. */
1728 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1729 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1731 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it
->dp
)));
1732 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1737 produce_glyphs (&temp_it
);
1738 it
->pixel_width
= temp_it
.pixel_width
;
1739 it
->nglyphs
= temp_it
.pixel_width
;
1747 /***********************************************************************
1749 ***********************************************************************/
1751 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1752 one of the enumerators from enum no_color_bit, or a bit set built
1753 from them. Some display attributes may not be used together with
1754 color; the termcap capability `NC' specifies which ones. */
1756 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1757 (tty->TN_max_colors > 0 \
1758 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1761 /* Turn appearances of face FACE_ID on tty frame F on. */
1764 turn_on_face (f
, face_id
)
1768 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1769 long fg
= face
->foreground
;
1770 long bg
= face
->background
;
1771 struct tty_display_info
*tty
= FRAME_TTY (f
);
1773 /* Do this first because TS_end_standout_mode may be the same
1774 as TS_exit_attribute_mode, which turns all appearances off. */
1775 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1777 if (tty
->TN_max_colors
> 0)
1779 if (fg
>= 0 && bg
>= 0)
1781 /* If the terminal supports colors, we can set them
1782 below without using reverse video. The face's fg
1783 and bg colors are set as they should appear on
1784 the screen, i.e. they take the inverse-video'ness
1785 of the face already into account. */
1787 else if (inverse_video
)
1789 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1790 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1791 toggle_highlight (tty
);
1795 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1796 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1797 toggle_highlight (tty
);
1802 /* If we can't display colors, use reverse video
1803 if the face specifies that. */
1806 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1807 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1808 toggle_highlight (tty
);
1812 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1813 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1814 toggle_highlight (tty
);
1819 if (face
->tty_bold_p
)
1821 if (MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1822 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1824 else if (face
->tty_dim_p
)
1825 if (MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1826 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1828 /* Alternate charset and blinking not yet used. */
1829 if (face
->tty_alt_charset_p
1830 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1831 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1833 if (face
->tty_blinking_p
1834 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1835 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1837 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1838 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1840 if (tty
->TN_max_colors
> 0)
1844 if (fg
>= 0 && tty
->TS_set_foreground
)
1846 p
= tparam (tty
->TS_set_foreground
, NULL
, 0, (int) fg
);
1851 if (bg
>= 0 && tty
->TS_set_background
)
1853 p
= tparam (tty
->TS_set_background
, NULL
, 0, (int) bg
);
1861 /* Turn off appearances of face FACE_ID on tty frame F. */
1864 turn_off_face (f
, face_id
)
1868 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1869 struct tty_display_info
*tty
= FRAME_TTY (f
);
1871 xassert (face
!= NULL
);
1873 if (tty
->TS_exit_attribute_mode
)
1875 /* Capability "me" will turn off appearance modes double-bright,
1876 half-bright, reverse-video, standout, underline. It may or
1877 may not turn off alt-char-mode. */
1878 if (face
->tty_bold_p
1880 || face
->tty_reverse_p
1881 || face
->tty_alt_charset_p
1882 || face
->tty_blinking_p
1883 || face
->tty_underline_p
)
1885 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
1886 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
1887 tty
->standout_mode
= 0;
1890 if (face
->tty_alt_charset_p
)
1891 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1895 /* If we don't have "me" we can only have those appearances
1896 that have exit sequences defined. */
1897 if (face
->tty_alt_charset_p
)
1898 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1900 if (face
->tty_underline_p
)
1901 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
1904 /* Switch back to default colors. */
1905 if (tty
->TN_max_colors
> 0
1906 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
1907 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
1908 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
1909 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
1910 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
1914 /* Return non-zero if the terminal on frame F supports all of the
1915 capabilities in CAPS simultaneously, with foreground and background
1916 colors FG and BG. */
1919 tty_capable_p (tty
, caps
, fg
, bg
)
1920 struct tty_display_info
*tty
;
1922 unsigned long fg
, bg
;
1924 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
1925 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
1928 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
1929 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
1930 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
1931 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
1932 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
1933 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
1940 /* Return non-zero if the terminal is capable to display colors. */
1942 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
1944 doc
: /* Return non-nil if TTY can display colors on DISPLAY. */)
1946 Lisp_Object display
;
1948 struct tty_display_info
*tty
= FRAME_TTY (SELECTED_FRAME ());
1949 return tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
1952 /* Return the number of supported colors. */
1953 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
1954 Stty_display_color_cells
, 0, 1, 0,
1955 doc
: /* Return the number of colors supported by TTY on DISPLAY. */)
1957 Lisp_Object display
;
1959 struct tty_display_info
*tty
= FRAME_TTY (SELECTED_FRAME ());
1960 return make_number (tty
->TN_max_colors
);
1965 /* Save or restore the default color-related capabilities of this
1968 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
1971 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
1972 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
1976 if (default_orig_pair
)
1977 xfree (default_orig_pair
);
1978 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
1980 if (default_set_foreground
)
1981 xfree (default_set_foreground
);
1982 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
1985 if (default_set_background
)
1986 xfree (default_set_background
);
1987 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
1990 default_max_colors
= tty
->TN_max_colors
;
1991 default_max_pairs
= tty
->TN_max_pairs
;
1992 default_no_color_video
= tty
->TN_no_color_video
;
1996 tty
->TS_orig_pair
= default_orig_pair
;
1997 tty
->TS_set_foreground
= default_set_foreground
;
1998 tty
->TS_set_background
= default_set_background
;
1999 tty
->TN_max_colors
= default_max_colors
;
2000 tty
->TN_max_pairs
= default_max_pairs
;
2001 tty
->TN_no_color_video
= default_no_color_video
;
2005 /* Setup one of the standard tty color schemes according to MODE.
2006 MODE's value is generally the number of colors which we want to
2007 support; zero means set up for the default capabilities, the ones
2008 we saw at term_init time; -1 means turn off color support. */
2010 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2012 /* Canonicalize all negative values of MODE. */
2018 case -1: /* no colors at all */
2019 tty
->TN_max_colors
= 0;
2020 tty
->TN_max_pairs
= 0;
2021 tty
->TN_no_color_video
= 0;
2022 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2024 case 0: /* default colors, if any */
2026 tty_default_color_capabilities (tty
, 0);
2028 case 8: /* 8 standard ANSI colors */
2029 tty
->TS_orig_pair
= "\033[0m";
2031 tty
->TS_set_foreground
= "\033[3%p1%dm";
2032 tty
->TS_set_background
= "\033[4%p1%dm";
2034 tty
->TS_set_foreground
= "\033[3%dm";
2035 tty
->TS_set_background
= "\033[4%dm";
2037 tty
->TN_max_colors
= 8;
2038 tty
->TN_max_pairs
= 64;
2039 tty
->TN_no_color_video
= 0;
2045 set_tty_color_mode (f
, val
)
2049 Lisp_Object color_mode_spec
, current_mode_spec
;
2050 Lisp_Object color_mode
, current_mode
;
2052 extern Lisp_Object Qtty_color_mode
;
2053 Lisp_Object tty_color_mode_alist
;
2055 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2062 if (NILP (tty_color_mode_alist
))
2063 color_mode_spec
= Qnil
;
2065 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2067 if (CONSP (color_mode_spec
))
2068 color_mode
= XCDR (color_mode_spec
);
2073 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2075 if (CONSP (current_mode_spec
))
2076 current_mode
= XCDR (current_mode_spec
);
2078 current_mode
= Qnil
;
2079 if (INTEGERP (color_mode
))
2080 mode
= XINT (color_mode
);
2082 mode
= 0; /* meaning default */
2083 if (INTEGERP (current_mode
))
2084 old_mode
= XINT (current_mode
);
2088 if (mode
!= old_mode
)
2090 tty_setup_colors (FRAME_TTY (f
), mode
);
2091 /* This recomputes all the faces given the new color
2093 call0 (intern ("tty-set-up-initial-frame-faces"));
2098 #endif /* !WINDOWSNT */
2102 struct tty_display_info
*
2103 get_named_tty (name
)
2106 struct tty_display_info
*tty
= tty_list
;
2109 if ((tty
->name
== 0 && name
== 0)
2110 || (name
&& tty
->name
&& !strcmp (tty
->name
, name
)))
2120 DEFUN ("frame-tty-name", Fframe_tty_name
, Sframe_tty_name
, 0, 1, 0,
2121 doc
: /* Return the name of the TTY device that FRAME is displayed on. */)
2129 f
= XFRAME (selected_frame
);
2133 CHECK_LIVE_FRAME (frame
);
2137 if (f
->output_method
!= output_termcap
)
2138 wrong_type_argument (Qframe_tty_name
, frame
);
2140 if (FRAME_TTY (f
)->name
)
2141 return build_string (FRAME_TTY (f
)->name
);
2146 DEFUN ("frame-tty-type", Fframe_tty_type
, Sframe_tty_type
, 0, 1, 0,
2147 doc
: /* Return the type of the TTY device that FRAME is displayed on. */)
2155 f
= XFRAME (selected_frame
);
2159 CHECK_LIVE_FRAME (frame
);
2163 if (f
->output_method
!= output_termcap
)
2164 wrong_type_argument (Qframe_tty_type
, frame
);
2166 if (FRAME_TTY (f
)->type
)
2167 return build_string (FRAME_TTY (f
)->type
);
2173 /***********************************************************************
2175 ***********************************************************************/
2177 struct tty_display_info
*
2178 term_dummy_init (void)
2180 if (initialized
|| tty_list
)
2181 error ("tty already initialized");
2183 tty_list
= xmalloc (sizeof (struct tty_display_info
));
2184 bzero (tty_list
, sizeof (struct tty_display_info
));
2186 tty_list
->input
= stdin
;
2187 tty_list
->output
= stdout
;
2188 tty_list
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
2189 tty_list
->display_method
= (struct display_method
*) xmalloc (sizeof (struct display_method
));
2190 tty_list
->kboard
= initial_kboard
;
2195 struct tty_display_info
*
2196 term_init (Lisp_Object frame
, char *name
, char *terminal_type
)
2199 char **address
= &area
;
2200 char *buffer
= NULL
;
2201 int buffer_size
= 4096;
2204 struct frame
*f
= XFRAME (frame
);
2205 struct tty_display_info
*tty
;
2207 tty
= get_named_tty (name
);
2210 /* Return the previously initialized terminal, except if it is
2211 the dummy terminal created for the initial frame. */
2215 /* Free up temporary structures. */
2218 if (tty
->display_method
)
2219 xfree (tty
->display_method
);
2220 if (tty
->kboard
!= initial_kboard
)
2226 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
2227 bzero (tty
, sizeof (struct tty_display_info
));
2228 tty
->next
= tty_list
;
2232 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
2235 /* Each termcap frame has its own display method. */
2236 tty
->display_method
= (struct display_method
*) xmalloc (sizeof (struct display_method
));
2237 bzero (tty
->display_method
, sizeof (struct display_method
));
2239 /* Initialize the common members in the new display method with our
2240 predefined template. */
2241 *tty
->display_method
= tty_display_method_template
;
2242 f
->display_method
= tty
->display_method
;
2244 /* Make sure the frame is live; if an error happens, it must be
2246 f
->output_method
= output_termcap
;
2247 if (! f
->output_data
.tty
)
2249 f
->output_data
.tty
->display_info
= tty
;
2254 fd
= emacs_open (name
, O_RDWR
, 0);
2258 error ("Could not open file: %s", name
);
2260 file
= fdopen (fd
, "w+");
2261 tty
->name
= xstrdup (name
);
2269 tty
->output
= stdout
;
2272 tty
->type
= xstrdup (terminal_type
);
2274 add_keyboard_wait_descriptor (fileno (tty
->input
));
2277 initialize_w32_display ();
2281 area
= (char *) xmalloc (2044);
2283 FrameRows (tty
) = FRAME_LINES (f
);
2284 FrameCols (tty
) = FRAME_COLS (f
);
2285 tty
->specified_window
= FRAME_LINES (f
);
2287 tty
->display_method
->delete_in_insert_mode
= 1;
2290 FRAME_SCROLL_REGION_OK (f
) = 0;
2292 /* Seems to insert lines when it's not supposed to, messing
2293 up the display. In doing a trace, it didn't seem to be
2294 called much, so I don't think we're losing anything by
2296 FRAME_LINE_INS_DEL_OK (f
) = 0;
2297 FRAME_CHAR_INS_DEL_OK (f
) = 1;
2301 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
2302 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
2303 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2306 #else /* not WINDOWSNT */
2310 buffer
= (char *) xmalloc (buffer_size
);
2311 status
= tgetent (buffer
, terminal_type
);
2319 error ("Cannot open terminfo database file");
2322 fatal ("Cannot open terminfo database file");
2328 error ("Cannot open termcap database file");
2331 fatal ("Cannot open termcap database file");
2341 error ("Terminal type %s is not defined", terminal_type
);
2344 fatal ("Terminal type %s is not defined.\n\
2345 If that is not the actual type of terminal you have,\n\
2346 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2347 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2348 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2355 error ("Terminal type %s is not defined", terminal_type
);
2358 fatal ("Terminal type %s is not defined.\n\
2359 If that is not the actual type of terminal you have,\n\
2360 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2361 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2362 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2368 if (strlen (buffer
) >= buffer_size
)
2370 buffer_size
= strlen (buffer
);
2372 area
= (char *) xmalloc (buffer_size
);
2374 tty
->TS_ins_line
= tgetstr ("al", address
);
2375 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
2376 tty
->TS_bell
= tgetstr ("bl", address
);
2377 BackTab (tty
) = tgetstr ("bt", address
);
2378 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
2379 tty
->TS_clr_line
= tgetstr ("ce", address
);
2380 tty
->TS_clr_frame
= tgetstr ("cl", address
);
2381 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
2382 AbsPosition (tty
) = tgetstr ("cm", address
);
2383 CR (tty
) = tgetstr ("cr", address
);
2384 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
2385 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
2386 RowPosition (tty
) = tgetstr ("cv", address
);
2387 tty
->TS_del_char
= tgetstr ("dc", address
);
2388 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
2389 tty
->TS_del_line
= tgetstr ("dl", address
);
2390 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
2391 tty
->TS_delete_mode
= tgetstr ("dm", address
);
2392 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
2393 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
2394 Home (tty
) = tgetstr ("ho", address
);
2395 tty
->TS_ins_char
= tgetstr ("ic", address
);
2396 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
2397 tty
->TS_insert_mode
= tgetstr ("im", address
);
2398 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
2399 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
2400 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
2401 LastLine (tty
) = tgetstr ("ll", address
);
2402 Right (tty
) = tgetstr ("nd", address
);
2403 Down (tty
) = tgetstr ("do", address
);
2405 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
2407 /* VMS puts a carriage return before each linefeed,
2408 so it is not safe to use linefeeds. */
2409 if (Down (tty
) && Down (tty
)[0] == '\n' && Down (tty
)[1] == '\0')
2412 if (tgetflag ("bs"))
2413 Left (tty
) = "\b"; /* can't possibly be longer! */
2414 else /* (Actually, "bs" is obsolete...) */
2415 Left (tty
) = tgetstr ("le", address
);
2417 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
2418 tty
->TS_pad_char
= tgetstr ("pc", address
);
2419 tty
->TS_repeat
= tgetstr ("rp", address
);
2420 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
2421 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
2422 tty
->TS_standout_mode
= tgetstr ("so", address
);
2423 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
2424 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
2425 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
2426 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
2427 Up (tty
) = tgetstr ("up", address
);
2428 tty
->TS_visible_bell
= tgetstr ("vb", address
);
2429 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
2430 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
2431 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
2432 tty
->TS_set_window
= tgetstr ("wi", address
);
2434 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
2435 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
2436 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
2437 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
2438 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
2439 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
2440 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2441 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2442 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
2444 MultiUp (tty
) = tgetstr ("UP", address
);
2445 MultiDown (tty
) = tgetstr ("DO", address
);
2446 MultiLeft (tty
) = tgetstr ("LE", address
);
2447 MultiRight (tty
) = tgetstr ("RI", address
);
2449 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2450 color because we can't switch back to the default foreground and
2452 tty
->TS_orig_pair
= tgetstr ("op", address
);
2453 if (tty
->TS_orig_pair
)
2455 tty
->TS_set_foreground
= tgetstr ("AF", address
);
2456 tty
->TS_set_background
= tgetstr ("AB", address
);
2457 if (!tty
->TS_set_foreground
)
2460 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
2461 tty
->TS_set_background
= tgetstr ("Sb", address
);
2464 tty
->TN_max_colors
= tgetnum ("Co");
2465 tty
->TN_max_pairs
= tgetnum ("pa");
2467 tty
->TN_no_color_video
= tgetnum ("NC");
2468 if (tty
->TN_no_color_video
== -1)
2469 tty
->TN_no_color_video
= 0;
2472 tty_default_color_capabilities (tty
, 1);
2474 MagicWrap (tty
) = tgetflag ("xn");
2475 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2476 the former flag imply the latter. */
2477 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
2478 FRAME_MEMORY_BELOW_FRAME (f
) = tgetflag ("db");
2479 tty
->TF_hazeltine
= tgetflag ("hz");
2480 FRAME_MUST_WRITE_SPACES (f
) = tgetflag ("in");
2481 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
2482 tty
->TF_insmode_motion
= tgetflag ("mi");
2483 tty
->TF_standout_motion
= tgetflag ("ms");
2484 tty
->TF_underscore
= tgetflag ("ul");
2485 tty
->TF_teleray
= tgetflag ("xt");
2487 term_get_fkeys (address
);
2489 /* Get frame size from system, or else from termcap. */
2492 get_tty_size (fileno (TTY_INPUT (tty
)), &width
, &height
);
2493 FrameCols (tty
) = width
;
2494 FrameRows (tty
) = height
;
2497 if (FrameCols (tty
) <= 0)
2498 FrameCols (tty
) = tgetnum ("co");
2499 if (FrameRows (tty
) <= 0)
2500 FrameRows (tty
) = tgetnum ("li");
2502 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
2507 error ("Screen size %dx%d is too small",
2508 FrameCols (tty
), FrameRows (tty
));
2512 fatal ("Screen size %dx%d is too small",
2513 FrameCols (tty
), FrameRows (tty
));
2517 #if 0 /* This is not used anywhere. */
2518 tty
->display_method
->min_padding_speed
= tgetnum ("pb");
2521 TabWidth (tty
) = tgetnum ("tw");
2524 /* These capabilities commonly use ^J.
2525 I don't know why, but sending them on VMS does not work;
2526 it causes following spaces to be lost, sometimes.
2527 For now, the simplest fix is to avoid using these capabilities ever. */
2528 if (Down (tty
) && Down (tty
)[0] == '\n')
2533 tty
->TS_bell
= "\07";
2535 if (!tty
->TS_fwd_scroll
)
2536 tty
->TS_fwd_scroll
= Down (tty
);
2538 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
2540 if (TabWidth (tty
) < 0)
2543 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2544 and newer termcap doc does not seem to say there is a default.
2545 if (!tty->Wcm->cm_tab)
2546 tty->Wcm->cm_tab = "\t";
2549 /* We don't support standout modes that use `magic cookies', so
2550 turn off any that do. */
2551 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
2553 tty
->TS_standout_mode
= 0;
2554 tty
->TS_end_standout_mode
= 0;
2556 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
2558 tty
->TS_enter_underline_mode
= 0;
2559 tty
->TS_exit_underline_mode
= 0;
2562 /* If there's no standout mode, try to use underlining instead. */
2563 if (tty
->TS_standout_mode
== 0)
2565 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
2566 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
2569 /* If no `se' string, try using a `me' string instead.
2570 If that fails, we can't use standout mode at all. */
2571 if (tty
->TS_end_standout_mode
== 0)
2573 char *s
= tgetstr ("me", address
);
2575 tty
->TS_end_standout_mode
= s
;
2577 tty
->TS_standout_mode
= 0;
2580 if (tty
->TF_teleray
)
2582 tty
->Wcm
->cm_tab
= 0;
2583 /* We can't support standout mode, because it uses magic cookies. */
2584 tty
->TS_standout_mode
= 0;
2585 /* But that means we cannot rely on ^M to go to column zero! */
2587 /* LF can't be trusted either -- can alter hpos */
2588 /* if move at column 0 thru a line with TS_standout_mode */
2592 /* Special handling for certain terminal types known to need it */
2594 if (!strcmp (terminal_type
, "supdup"))
2596 FRAME_MEMORY_BELOW_FRAME (f
) = 1;
2597 tty
->Wcm
->cm_losewrap
= 1;
2599 if (!strncmp (terminal_type
, "c10", 3)
2600 || !strcmp (terminal_type
, "perq"))
2602 /* Supply a makeshift :wi string.
2603 This string is not valid in general since it works only
2604 for windows starting at the upper left corner;
2605 but that is all Emacs uses.
2607 This string works only if the frame is using
2608 the top of the video memory, because addressing is memory-relative.
2609 So first check the :ti string to see if that is true.
2611 It would be simpler if the :wi string could go in the termcap
2612 entry, but it can't because it is not fully valid.
2613 If it were in the termcap entry, it would confuse other programs. */
2614 if (!tty
->TS_set_window
)
2616 p
= tty
->TS_termcap_modes
;
2617 while (*p
&& strcmp (p
, "\033v "))
2620 tty
->TS_set_window
= "\033v%C %C %C %C ";
2622 /* Termcap entry often fails to have :in: flag */
2623 FRAME_MUST_WRITE_SPACES (f
) = 1;
2624 /* :ti string typically fails to have \E^G! in it */
2625 /* This limits scope of insert-char to one line. */
2626 strcpy (area
, tty
->TS_termcap_modes
);
2627 strcat (area
, "\033\007!");
2628 tty
->TS_termcap_modes
= area
;
2629 area
+= strlen (area
) + 1;
2630 p
= AbsPosition (tty
);
2631 /* Change all %+ parameters to %C, to handle
2632 values above 96 correctly for the C100. */
2635 if (p
[0] == '%' && p
[1] == '+')
2641 tty
->specified_window
= FrameRows (tty
);
2643 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
2647 error ("Terminal type \"%s\" is not powerful enough to run Emacs",
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, use either the\n\
2655 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2656 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
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 TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2667 # else /* TERMCAP */
2668 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2669 It lacks the ability to position the cursor.\n\
2670 If that is not the actual type of terminal you have,\n\
2671 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2672 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2673 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2675 # endif /* TERMINFO */
2679 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
2684 error ("The frame size has not been specified");
2687 fatal ("The frame size has not been specified");
2690 tty
->delete_in_insert_mode
2691 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
2692 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
2694 tty
->se_is_so
= (tty
->TS_standout_mode
2695 && tty
->TS_end_standout_mode
2696 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
2698 UseTabs (tty
) = tabs_safe_p (fileno (TTY_INPUT (tty
))) && TabWidth (tty
) == 8;
2700 FRAME_SCROLL_REGION_OK (f
)
2702 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
2704 FRAME_LINE_INS_DEL_OK (f
)
2705 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
2706 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
2707 || (FRAME_SCROLL_REGION_OK (f
)
2708 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
2710 FRAME_CHAR_INS_DEL_OK (f
)
2711 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
2712 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
2713 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
2715 FRAME_FAST_CLEAR_END_OF_LINE (f
) = tty
->TS_clr_line
!= 0;
2717 init_baud_rate (fileno (TTY_INPUT (tty
)));
2718 if (read_socket_hook
) /* Baudrate is somewhat
2719 meaningless in this case */
2722 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
2723 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
2726 /* The HFT system on AIX doesn't optimize for scrolling, so it's
2727 really ugly at times. */
2728 FRAME_LINE_INS_DEL_OK (f
) = 0;
2729 FRAME_CHAR_INS_DEL_OK (f
) = 0;
2733 tty
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
2734 init_kboard (tty
->kboard
);
2735 tty
->kboard
->next_kboard
= all_kboards
;
2736 all_kboards
= tty
->kboard
;
2737 /* Don't let the initial kboard remain current longer than necessary.
2738 That would cause problems if a file loaded on startup tries to
2739 prompt in the mini-buffer. */
2740 if (current_kboard
== initial_kboard
)
2741 current_kboard
= tty
->kboard
;
2742 tty
->kboard
->reference_count
++;
2745 /* Don't do this. I think termcap may still need the buffer. */
2746 /* xfree (buffer); */
2748 /* Set the top frame to the first frame on this display. */
2749 tty
->top_frame
= frame
;
2751 /* Init system terminal modes (RAW or CBREAK, etc.). */
2752 init_sys_modes (tty
);
2754 tty_set_terminal_modes (tty
);
2757 #endif /* not WINDOWSNT */
2762 fatal (str
, arg1
, arg2
)
2763 char *str
, *arg1
, *arg2
;
2765 fprintf (stderr
, "emacs: ");
2766 fprintf (stderr
, str
, arg1
, arg2
);
2767 fprintf (stderr
, "\n");
2774 DEFUN ("delete-tty", Fdelete_tty
, Sdelete_tty
, 0, 1, 0,
2775 doc
: /* Delete all frames on the terminal named TTY, and close the device. */)
2779 struct tty_display_info
*t
;
2784 if (SBYTES (tty
) > 0)
2786 name
= (char *) alloca (SBYTES (tty
) + 1);
2787 strncpy (name
, SDATA (tty
), SBYTES (tty
));
2788 name
[SBYTES (tty
)] = 0;
2791 t
= get_named_tty (name
);
2794 error ("No such tty device: %s", name
);
2799 static int deleting_tty
= 0;
2802 delete_tty (struct tty_display_info
*tty
)
2804 Lisp_Object tail
, frame
;
2807 /* We get a recursive call when we delete the last frame on this
2813 if (tty
== tty_list
)
2814 tty_list
= tty
->next
;
2817 struct tty_display_info
*p
;
2818 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
2822 /* This should not happen. */
2825 p
->next
= tty
->next
;
2829 FOR_EACH_FRAME (tail
, frame
)
2831 struct frame
*f
= XFRAME (frame
);
2832 if (FRAME_TERMCAP_P (f
) && FRAME_LIVE_P (f
) && FRAME_TTY (f
) == tty
)
2834 Fdelete_frame (frame
, Qt
);
2835 f
->output_data
.tty
= 0;
2839 reset_sys_modes (tty
);
2848 delete_keyboard_wait_descriptor (fileno (tty
->input
));
2849 if (tty
->input
!= stdin
)
2850 fclose (tty
->input
);
2852 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
2853 fclose (tty
->output
);
2854 if (tty
->termscript
)
2855 fclose (tty
->termscript
);
2858 xfree (tty
->old_tty
);
2863 if (tty
->display_method
)
2864 xfree (tty
->display_method
);
2867 if (tty
->kboard
&& --tty
->kboard
->reference_count
> 0)
2870 delete_kboard (tty
->kboard
);
2873 bzero (tty
, sizeof (struct tty_display_info
));
2881 /* Mark the pointers in the tty_display_info objects.
2882 Called by the Fgarbage_collector. */
2886 struct tty_display_info
*tty
;
2888 for (tty
= tty_list
; tty
; tty
= tty
->next
)
2891 mark_object (tty
->top_frame
);
2900 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
2901 doc
: /* Non-nil means the system uses terminfo rather than termcap.
2902 This variable can be used by terminal emulator packages. */);
2904 system_uses_terminfo
= 1;
2906 system_uses_terminfo
= 0;
2909 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
2910 doc
: /* Non-nil means call this function to ring the bell.
2911 The function should accept no arguments. */);
2912 Vring_bell_function
= Qnil
;
2914 Qframe_tty_name
= intern ("frame-tty-name");
2915 staticpro (&Qframe_tty_name
);
2917 Qframe_tty_type
= intern ("frame-tty-type");
2918 staticpro (&Qframe_tty_type
);
2920 defsubr (&Stty_display_color_p
);
2921 defsubr (&Stty_display_color_cells
);
2922 defsubr (&Sframe_tty_name
);
2923 defsubr (&Sframe_tty_type
);
2924 defsubr (&Sdelete_tty
);
2926 Fprovide (intern ("multi-tty"), Qnil
);
2928 /* Initialize the display method template. */
2930 /* Termcap-based displays don't support window-based redisplay. */
2931 tty_display_method_template
.rif
= 0;
2937 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
2938 (do not change this comment) */