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>. */
31 #include <unistd.h> /* For isatty. */
32 #include <sys/ioctl.h> /* For TIOCNOTTY. */
42 #include "termhooks.h"
43 #include "dispextern.h"
47 /* For now, don't try to include termcap.h. On some systems,
48 configure finds a non-standard termcap.h that the main build
51 #if defined HAVE_TERMCAP_H && 0
54 extern void tputs
P_ ((const char *, int, int (*)(int)));
55 extern int tgetent
P_ ((char *, const char *));
56 extern int tgetflag
P_ ((char *id
));
57 extern int tgetnum
P_ ((char *id
));
76 static void turn_on_face
P_ ((struct frame
*, int face_id
));
77 static void turn_off_face
P_ ((struct frame
*, int face_id
));
78 static void tty_show_cursor
P_ ((struct tty_display_info
*));
79 static void tty_hide_cursor
P_ ((struct tty_display_info
*));
81 void delete_initial_display
P_ ((struct display
*));
82 void delete_tty
P_ ((struct display
*));
83 void create_tty_output
P_ ((struct frame
*));
84 void delete_tty_output
P_ ((struct frame
*));
86 #define OUTPUT(tty, a) \
87 emacs_tputs ((tty), a, \
88 (int) (FRAME_LINES (XFRAME (selected_frame)) \
92 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
93 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
95 #define OUTPUT_IF(tty, a) \
98 emacs_tputs ((tty), a, \
99 (int) (FRAME_LINES (XFRAME (selected_frame)) \
104 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
106 /* Function to use to ring the bell. */
108 Lisp_Object Vring_bell_function
;
110 /* Functions to call after a tty was deleted. */
111 Lisp_Object Vdelete_tty_after_functions
;
113 /* Chain of all displays currently in use. */
114 struct display
*display_list
;
116 /* The initial display device, created by initial_term_init. */
117 struct display
*initial_display
;
119 /* Chain of all tty device parameters. */
120 struct tty_display_info
*tty_list
;
122 /* Nonzero means no need to redraw the entire frame on resuming a
123 suspended Emacs. This is useful on terminals with multiple
124 pages, where one page is used for Emacs and another for all
126 int no_redraw_on_reenter
;
128 Lisp_Object Qframe_tty_name
, Qframe_tty_type
;
132 /* Meaning of bits in no_color_video. Each bit set means that the
133 corresponding attribute cannot be combined with colors. */
137 NC_STANDOUT
= 1 << 0,
138 NC_UNDERLINE
= 1 << 1,
145 NC_ALT_CHARSET
= 1 << 8
150 /* The largest frame width in any call to calculate_costs. */
154 /* The largest frame height in any call to calculate_costs. */
158 /* Frame currently being redisplayed; 0 if not currently redisplaying.
159 (Direct output does not count). */
161 FRAME_PTR updating_frame
;
163 /* Non-zero if we have dropped our controlling tty and therefore
164 should not open a frame on stdout. */
165 static int no_controlling_tty
;
167 /* Provided for lisp packages. */
169 static int system_uses_terminfo
;
173 extern char *tgetstr ();
177 /* We aren't X windows, but we aren't termcap either. This makes me
178 uncertain as to what value to use for frame.output_method. For
179 this file, we'll define FRAME_TERMCAP_P to be zero so that our
180 output hooks get called instead of the termcap functions. Probably
181 the best long-term solution is to define an output_windows_nt... */
183 #undef FRAME_TERMCAP_P
184 #define FRAME_TERMCAP_P(_f_) 0
185 #endif /* WINDOWSNT */
190 struct frame
*f
= XFRAME (selected_frame
);
192 if (!NILP (Vring_bell_function
))
194 Lisp_Object function
;
196 /* Temporarily set the global variable to nil
197 so that if we get an error, it stays nil
198 and we don't call it over and over.
200 We don't specbind it, because that would carefully
201 restore the bad value if there's an error
202 and make the loop of errors happen anyway. */
204 function
= Vring_bell_function
;
205 Vring_bell_function
= Qnil
;
209 Vring_bell_function
= function
;
211 else if (FRAME_DISPLAY (f
)->ring_bell_hook
)
212 (*FRAME_DISPLAY (f
)->ring_bell_hook
) ();
215 /* Ring the bell on a tty. */
220 struct frame
*f
= XFRAME (selected_frame
);
221 struct tty_display_info
*tty
= FRAME_TTY (f
);
223 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
224 ? tty
->TS_visible_bell
228 /* Set up termcap modes for Emacs. */
231 tty_set_terminal_modes (struct display
*display
)
233 struct tty_display_info
*tty
= display
->display_info
.tty
;
235 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
236 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
237 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
241 /* Reset termcap modes before exiting Emacs. */
244 tty_reset_terminal_modes (struct display
*display
)
246 struct tty_display_info
*tty
= display
->display_info
.tty
;
248 turn_off_highlight (tty
);
249 turn_off_insert (tty
);
250 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
251 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
252 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
253 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
254 /* Output raw CR so kernel can track the cursor hpos. */
264 if (FRAME_DISPLAY (f
)->update_begin_hook
)
265 (*FRAME_DISPLAY (f
)->update_begin_hook
) (f
);
272 if (FRAME_DISPLAY (f
)->update_end_hook
)
273 (*FRAME_DISPLAY (f
)->update_end_hook
) (f
);
274 updating_frame
= NULL
;
277 /* Flag the end of a display update on a termcap display. */
280 tty_update_end (struct frame
*f
)
282 struct tty_display_info
*tty
= FRAME_TTY (f
);
284 if (!XWINDOW (selected_window
)->cursor_off_p
)
285 tty_show_cursor (tty
);
286 turn_off_insert (tty
);
287 background_highlight (tty
);
290 /* Specify how many text lines, from the top of the window,
291 should be affected by insert-lines and delete-lines operations.
292 This, and those operations, are used only within an update
293 that is bounded by calls to update_begin and update_end. */
296 set_terminal_window (size
)
299 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
301 if (FRAME_DISPLAY (f
)->set_terminal_window_hook
)
302 (*FRAME_DISPLAY (f
)->set_terminal_window_hook
) (size
);
305 /* The implementation of set_terminal_window for termcap frames. */
308 tty_set_terminal_window (int size
)
310 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
312 struct tty_display_info
*tty
= FRAME_TTY (f
);
314 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
315 if (FRAME_SCROLL_REGION_OK (f
))
316 set_scroll_region (0, tty
->specified_window
);
320 set_scroll_region (start
, stop
)
324 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
326 struct tty_display_info
*tty
= FRAME_TTY (f
);
328 if (tty
->TS_set_scroll_region
)
329 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
330 else if (tty
->TS_set_scroll_region_1
)
331 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
332 FRAME_LINES (f
), start
,
333 FRAME_LINES (f
) - stop
,
336 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
345 turn_on_insert (struct tty_display_info
*tty
)
347 if (!tty
->insert_mode
)
348 OUTPUT (tty
, tty
->TS_insert_mode
);
349 tty
->insert_mode
= 1;
353 turn_off_insert (struct tty_display_info
*tty
)
355 if (tty
->insert_mode
)
356 OUTPUT (tty
, tty
->TS_end_insert_mode
);
357 tty
->insert_mode
= 0;
360 /* Handle highlighting. */
363 turn_off_highlight (struct tty_display_info
*tty
)
365 if (tty
->standout_mode
)
366 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
367 tty
->standout_mode
= 0;
371 turn_on_highlight (struct tty_display_info
*tty
)
373 if (!tty
->standout_mode
)
374 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
375 tty
->standout_mode
= 1;
379 toggle_highlight (struct tty_display_info
*tty
)
381 if (tty
->standout_mode
)
382 turn_off_highlight (tty
);
384 turn_on_highlight (tty
);
388 /* Make cursor invisible. */
391 tty_hide_cursor (struct tty_display_info
*tty
)
393 if (tty
->cursor_hidden
== 0)
395 tty
->cursor_hidden
= 1;
396 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
401 /* Ensure that cursor is visible. */
404 tty_show_cursor (struct tty_display_info
*tty
)
406 if (tty
->cursor_hidden
)
408 tty
->cursor_hidden
= 0;
409 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
410 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
415 /* Set standout mode to the state it should be in for
416 empty space inside windows. What this is,
417 depends on the user option inverse-video. */
420 background_highlight (struct tty_display_info
*tty
)
423 turn_on_highlight (tty
);
425 turn_off_highlight (tty
);
428 /* Set standout mode to the mode specified for the text to be output. */
431 highlight_if_desired (struct tty_display_info
*tty
)
434 turn_on_highlight (tty
);
436 turn_off_highlight (tty
);
440 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
441 frame-relative coordinates. */
444 cursor_to (vpos
, hpos
)
447 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
449 if (FRAME_DISPLAY (f
)->cursor_to_hook
)
450 (*FRAME_DISPLAY (f
)->cursor_to_hook
) (vpos
, hpos
);
454 tty_cursor_to (int vpos
, int hpos
)
456 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
458 struct tty_display_info
*tty
= FRAME_TTY (f
);
460 /* Detect the case where we are called from reset_sys_modes
461 and the costs have never been calculated. Do nothing. */
462 if (! tty
->costs_set
)
465 if (curY (tty
) == vpos
466 && curX (tty
) == hpos
)
468 if (!tty
->TF_standout_motion
)
469 background_highlight (tty
);
470 if (!tty
->TF_insmode_motion
)
471 turn_off_insert (tty
);
472 cmgoto (tty
, vpos
, hpos
);
475 /* Similar but don't take any account of the wasted characters. */
478 raw_cursor_to (row
, col
)
481 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
483 if (FRAME_DISPLAY (f
)->raw_cursor_to_hook
)
484 (*FRAME_DISPLAY (f
)->raw_cursor_to_hook
) (row
, col
);
488 tty_raw_cursor_to (int row
, int col
)
490 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
492 struct tty_display_info
*tty
= FRAME_TTY (f
);
494 if (curY (tty
) == row
495 && curX (tty
) == col
)
497 if (!tty
->TF_standout_motion
)
498 background_highlight (tty
);
499 if (!tty
->TF_insmode_motion
)
500 turn_off_insert (tty
);
501 cmgoto (tty
, row
, col
);
504 /* Erase operations */
506 /* Clear from cursor to end of frame. */
510 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
512 if (FRAME_DISPLAY (f
)->clear_to_end_hook
)
513 (*FRAME_DISPLAY (f
)->clear_to_end_hook
) ();
516 /* Clear from cursor to end of frame on a termcap device. */
519 tty_clear_to_end (void)
522 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
523 struct tty_display_info
*tty
= FRAME_TTY (f
);
525 if (tty
->TS_clr_to_bottom
)
527 background_highlight (tty
);
528 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
532 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
535 clear_end_of_line (FRAME_COLS (f
));
540 /* Clear entire frame */
545 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
547 if (FRAME_DISPLAY (f
)->clear_frame_hook
)
548 (*FRAME_DISPLAY (f
)->clear_frame_hook
) ();
551 /* Clear an entire termcap frame. */
556 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
558 struct tty_display_info
*tty
= FRAME_TTY (f
);
560 if (tty
->TS_clr_frame
)
562 background_highlight (tty
);
563 OUTPUT (tty
, tty
->TS_clr_frame
);
573 /* Clear from cursor to end of line.
574 Assume that the line is already clear starting at column first_unused_hpos.
576 Note that the cursor may be moved, on terminals lacking a `ce' string. */
579 clear_end_of_line (first_unused_hpos
)
580 int first_unused_hpos
;
582 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
584 if (FRAME_DISPLAY (f
)->clear_end_of_line_hook
)
585 (*FRAME_DISPLAY (f
)->clear_end_of_line_hook
) (first_unused_hpos
);
588 /* An implementation of clear_end_of_line for termcap frames.
590 Note that the cursor may be moved, on terminals lacking a `ce' string. */
593 tty_clear_end_of_line (int first_unused_hpos
)
596 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
597 struct tty_display_info
*tty
= FRAME_TTY (f
);
599 /* Detect the case where we are called from reset_sys_modes
600 and the costs have never been calculated. Do nothing. */
601 if (! tty
->costs_set
)
604 if (curX (tty
) >= first_unused_hpos
)
606 background_highlight (tty
);
607 if (tty
->TS_clr_line
)
609 OUTPUT1 (tty
, tty
->TS_clr_line
);
612 { /* have to do it the hard way */
613 turn_off_insert (tty
);
615 /* Do not write in last row last col with Auto-wrap on. */
617 && curY (tty
) == FrameRows (tty
) - 1
618 && first_unused_hpos
== FrameCols (tty
))
621 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
623 if (TTY_TERMSCRIPT (tty
))
624 fputc (' ', TTY_TERMSCRIPT (tty
));
625 fputc (' ', TTY_OUTPUT (tty
));
627 cmplus (tty
, first_unused_hpos
- curX (tty
));
631 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
632 store them at DST. Do not write more than DST_LEN bytes. That may
633 require stopping before all SRC_LEN input glyphs have been
636 We store the number of glyphs actually converted in *CONSUMED. The
637 return value is the number of bytes store in DST. */
640 encode_terminal_code (src
, dst
, src_len
, dst_len
, consumed
)
644 int dst_len
, *consumed
;
646 struct glyph
*src_start
= src
, *src_end
= src
+ src_len
;
647 unsigned char *dst_start
= dst
, *dst_end
= dst
+ dst_len
;
649 unsigned char workbuf
[MAX_MULTIBYTE_LENGTH
];
650 const unsigned char *buf
;
652 register int tlen
= GLYPH_TABLE_LENGTH
;
653 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
655 struct coding_system
*coding
;
657 /* If terminal_coding does any conversion, use it, otherwise use
658 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
659 because it always return 1 if the member src_multibyte is 1. */
660 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
662 : &safe_terminal_coding
);
664 while (src
< src_end
)
666 /* We must skip glyphs to be padded for a wide character. */
667 if (! CHAR_GLYPH_PADDING_P (*src
))
669 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
671 if (g
< 0 || g
>= tlen
)
673 /* This glyph doesn't has an entry in Vglyph_table. */
674 if (! CHAR_VALID_P (src
->u
.ch
, 0))
678 coding
->src_multibyte
= 0;
682 len
= CHAR_STRING (src
->u
.ch
, workbuf
);
684 coding
->src_multibyte
= 1;
689 /* This glyph has an entry in Vglyph_table,
690 so process any alias before testing for simpleness. */
691 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
693 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
695 /* We set the multi-byte form of a character in G
696 (that should be an ASCII character) at
698 workbuf
[0] = FAST_GLYPH_CHAR (g
);
701 coding
->src_multibyte
= 0;
705 /* We have a string in Vglyph_table. */
706 len
= GLYPH_LENGTH (tbase
, g
);
707 buf
= GLYPH_STRING (tbase
, g
);
708 coding
->src_multibyte
= STRING_MULTIBYTE (tbase
[g
]);
712 result
= encode_coding (coding
, buf
, dst
, len
, dst_end
- dst
);
713 len
-= coding
->consumed
;
714 dst
+= coding
->produced
;
715 if (result
== CODING_FINISH_INSUFFICIENT_DST
716 || (result
== CODING_FINISH_INSUFFICIENT_SRC
717 && len
> dst_end
- dst
))
718 /* The remaining output buffer is too short. We must
719 break the loop here without increasing SRC so that the
720 next call of this function starts from the same glyph. */
725 /* This is the case that a code of the range 0200..0237
726 exists in buf. We must just write out such a code. */
727 buf
+= coding
->consumed
;
735 *consumed
= src
- src_start
;
736 return (dst
- dst_start
);
740 /* Output LEN glyphs starting at STRING at the nominal cursor position.
741 Advance the nominal cursor over the text. */
744 write_glyphs (string
, len
)
745 register struct glyph
*string
;
748 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
750 if (FRAME_DISPLAY (f
)->write_glyphs_hook
)
751 (*FRAME_DISPLAY (f
)->write_glyphs_hook
) (string
, len
);
754 /* An implementation of write_glyphs for termcap frames. */
757 tty_write_glyphs (struct glyph
*string
, int len
)
759 int produced
, consumed
;
760 unsigned char conversion_buffer
[1024];
761 int conversion_buffer_size
= sizeof conversion_buffer
;
763 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
765 struct tty_display_info
*tty
= FRAME_TTY (f
);
767 turn_off_insert (tty
);
768 tty_hide_cursor (tty
);
770 /* Don't dare write in last column of bottom line, if Auto-Wrap,
771 since that would scroll the whole frame on some terminals. */
774 && curY (tty
) + 1 == FRAME_LINES (f
)
775 && (curX (tty
) + len
) == FRAME_COLS (f
))
782 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
784 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
788 /* Identify a run of glyphs with the same face. */
789 int face_id
= string
->face_id
;
792 for (n
= 1; n
< len
; ++n
)
793 if (string
[n
].face_id
!= face_id
)
796 /* Turn appearance modes of the face of the run on. */
797 highlight_if_desired (tty
);
798 turn_on_face (f
, face_id
);
802 /* We use a fixed size (1024 bytes) of conversion buffer.
803 Usually it is sufficient, but if not, we just repeat the
805 produced
= encode_terminal_code (string
, conversion_buffer
,
806 n
, conversion_buffer_size
,
810 fwrite (conversion_buffer
, 1, produced
,
812 if (ferror (TTY_OUTPUT (tty
)))
813 clearerr (TTY_OUTPUT (tty
));
814 if (TTY_TERMSCRIPT (tty
))
815 fwrite (conversion_buffer
, 1, produced
,
816 TTY_TERMSCRIPT (tty
));
823 /* Turn appearance modes off. */
824 turn_off_face (f
, face_id
);
825 turn_off_highlight (tty
);
828 /* We may have to output some codes to terminate the writing. */
829 if (CODING_REQUIRE_FLUSHING (&terminal_coding
))
831 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
832 encode_coding (&terminal_coding
, "", conversion_buffer
,
833 0, conversion_buffer_size
);
834 if (terminal_coding
.produced
> 0)
836 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
838 if (ferror (TTY_OUTPUT (tty
)))
839 clearerr (TTY_OUTPUT (tty
));
840 if (TTY_TERMSCRIPT (tty
))
841 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
842 TTY_TERMSCRIPT (tty
));
849 /* Insert LEN glyphs from START at the nominal cursor position.
851 If start is zero, insert blanks instead of a string at start */
854 insert_glyphs (start
, len
)
855 register struct glyph
*start
;
858 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
863 if (FRAME_DISPLAY (f
)->insert_glyphs_hook
)
864 (*FRAME_DISPLAY (f
)->insert_glyphs_hook
) (start
, len
);
867 /* An implementation of insert_glyphs for termcap frames. */
870 tty_insert_glyphs (struct glyph
*start
, int len
)
873 struct glyph
*glyph
= NULL
;
874 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
876 struct tty_display_info
*tty
= FRAME_TTY (f
);
878 if (tty
->TS_ins_multi_chars
)
880 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
884 write_glyphs (start
, len
);
888 turn_on_insert (tty
);
890 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
891 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
894 int produced
, consumed
;
895 unsigned char conversion_buffer
[1024];
896 int conversion_buffer_size
= sizeof conversion_buffer
;
898 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
901 conversion_buffer
[0] = SPACEGLYPH
;
906 highlight_if_desired (tty
);
907 turn_on_face (f
, start
->face_id
);
910 /* We must open sufficient space for a character which
911 occupies more than one column. */
912 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
914 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
919 /* This is the last glyph. */
920 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
922 /* The size of conversion buffer (1024 bytes) is surely
923 sufficient for just one glyph. */
924 produced
= encode_terminal_code (glyph
, conversion_buffer
, 1,
925 conversion_buffer_size
, &consumed
);
930 fwrite (conversion_buffer
, 1, produced
,
932 if (ferror (TTY_OUTPUT (tty
)))
933 clearerr (TTY_OUTPUT (tty
));
934 if (TTY_TERMSCRIPT (tty
))
935 fwrite (conversion_buffer
, 1, produced
,
936 TTY_TERMSCRIPT (tty
));
939 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
942 turn_off_face (f
, glyph
->face_id
);
943 turn_off_highlight (tty
);
950 /* Delete N glyphs at the nominal cursor position. */
956 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
958 if (FRAME_DISPLAY (f
)->delete_glyphs_hook
)
959 (*FRAME_DISPLAY (f
)->delete_glyphs_hook
) (n
);
962 /* An implementation of delete_glyphs for termcap frames. */
965 tty_delete_glyphs (int n
)
969 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
971 struct tty_display_info
*tty
= FRAME_TTY (f
);
973 if (tty
->delete_in_insert_mode
)
975 turn_on_insert (tty
);
979 turn_off_insert (tty
);
980 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
983 if (tty
->TS_del_multi_chars
)
985 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
990 for (i
= 0; i
< n
; i
++)
991 OUTPUT1 (tty
, tty
->TS_del_char
);
992 if (!tty
->delete_in_insert_mode
)
993 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
996 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
999 ins_del_lines (vpos
, n
)
1002 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
1004 if (FRAME_DISPLAY (f
)->ins_del_lines_hook
)
1005 (*FRAME_DISPLAY (f
)->ins_del_lines_hook
) (vpos
, n
);
1008 /* An implementation of ins_del_lines for termcap frames. */
1011 tty_ins_del_lines (int vpos
, int n
)
1013 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
1015 struct tty_display_info
*tty
= FRAME_TTY (f
);
1016 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
1017 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
1018 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
1020 register int i
= n
> 0 ? n
: -n
;
1023 /* If the lines below the insertion are being pushed
1024 into the end of the window, this is the same as clearing;
1025 and we know the lines are already clear, since the matching
1026 deletion has already been done. So can ignore this. */
1027 /* If the lines below the deletion are blank lines coming
1028 out of the end of the window, don't bother,
1029 as there will be a matching inslines later that will flush them. */
1030 if (FRAME_SCROLL_REGION_OK (f
)
1031 && vpos
+ i
>= tty
->specified_window
)
1033 if (!FRAME_MEMORY_BELOW_FRAME (f
)
1034 && vpos
+ i
>= FRAME_LINES (f
))
1039 raw_cursor_to (vpos
, 0);
1040 background_highlight (tty
);
1041 buf
= tparam (multi
, 0, 0, i
);
1047 raw_cursor_to (vpos
, 0);
1048 background_highlight (tty
);
1050 OUTPUT (tty
, single
);
1051 if (tty
->TF_teleray
)
1056 set_scroll_region (vpos
, tty
->specified_window
);
1058 raw_cursor_to (tty
->specified_window
- 1, 0);
1060 raw_cursor_to (vpos
, 0);
1061 background_highlight (tty
);
1063 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1064 set_scroll_region (0, tty
->specified_window
);
1067 if (!FRAME_SCROLL_REGION_OK (f
)
1068 && FRAME_MEMORY_BELOW_FRAME (f
)
1071 cursor_to (FRAME_LINES (f
) + n
, 0);
1076 /* Compute cost of sending "str", in characters,
1077 not counting any line-dependent padding. */
1085 tputs (str
, 0, evalcost
);
1089 /* Compute cost of sending "str", in characters,
1090 counting any line-dependent padding at one line. */
1093 string_cost_one_line (str
)
1098 tputs (str
, 1, evalcost
);
1102 /* Compute per line amount of line-dependent padding,
1103 in tenths of characters. */
1111 tputs (str
, 0, evalcost
);
1114 tputs (str
, 10, evalcost
);
1119 /* char_ins_del_cost[n] is cost of inserting N characters.
1120 char_ins_del_cost[-n] is cost of deleting N characters.
1121 The length of this vector is based on max_frame_cols. */
1123 int *char_ins_del_vector
;
1125 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1130 calculate_ins_del_char_costs (f
)
1133 struct tty_display_info
*tty
= FRAME_TTY (f
);
1134 int ins_startup_cost
, del_startup_cost
;
1135 int ins_cost_per_char
, del_cost_per_char
;
1139 if (tty
->TS_ins_multi_chars
)
1141 ins_cost_per_char
= 0;
1142 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1144 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1145 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1147 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1148 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1149 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1150 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1154 ins_startup_cost
= 9999;
1155 ins_cost_per_char
= 0;
1158 if (tty
->TS_del_multi_chars
)
1160 del_cost_per_char
= 0;
1161 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1163 else if (tty
->TS_del_char
)
1165 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1166 + string_cost (tty
->TS_end_delete_mode
));
1167 if (tty
->delete_in_insert_mode
)
1168 del_startup_cost
/= 2;
1169 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1173 del_startup_cost
= 9999;
1174 del_cost_per_char
= 0;
1177 /* Delete costs are at negative offsets */
1178 p
= &char_ins_del_cost (f
)[0];
1179 for (i
= FRAME_COLS (f
); --i
>= 0;)
1180 *--p
= (del_startup_cost
+= del_cost_per_char
);
1182 /* Doing nothing is free */
1183 p
= &char_ins_del_cost (f
)[0];
1186 /* Insert costs are at positive offsets */
1187 for (i
= FRAME_COLS (f
); --i
>= 0;)
1188 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1192 calculate_costs (frame
)
1195 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1197 if (FRAME_TERMCAP_P (frame
))
1199 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1200 register char *f
= (tty
->TS_set_scroll_region
1201 ? tty
->TS_set_scroll_region
1202 : tty
->TS_set_scroll_region_1
);
1204 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1208 /* These variables are only used for terminal stuff. They are
1209 allocated once for the terminal frame of X-windows emacs, but not
1212 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1213 X turns off char_ins_del_ok. */
1215 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1216 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1218 if (char_ins_del_vector
!= 0)
1220 = (int *) xrealloc (char_ins_del_vector
,
1222 + 2 * max_frame_cols
* sizeof (int)));
1225 = (int *) xmalloc (sizeof (int)
1226 + 2 * max_frame_cols
* sizeof (int));
1228 bzero (char_ins_del_vector
, (sizeof (int)
1229 + 2 * max_frame_cols
* sizeof (int)));
1232 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1233 do_line_insertion_deletion_costs (frame
,
1234 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1235 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1238 do_line_insertion_deletion_costs (frame
,
1239 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1240 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1243 calculate_ins_del_char_costs (frame
);
1245 /* Don't use TS_repeat if its padding is worse than sending the chars */
1246 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1247 tty
->RPov
= string_cost (tty
->TS_repeat
);
1249 tty
->RPov
= FRAME_COLS (frame
) * 2;
1251 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1259 /* Termcap capability names that correspond directly to X keysyms.
1260 Some of these (marked "terminfo") aren't supplied by old-style
1261 (Berkeley) termcap entries. They're listed in X keysym order;
1262 except we put the keypad keys first, so that if they clash with
1263 other keys (as on the IBM PC keyboard) they get overridden.
1266 static struct fkey_table keys
[] =
1268 {"kh", "home"}, /* termcap */
1269 {"kl", "left"}, /* termcap */
1270 {"ku", "up"}, /* termcap */
1271 {"kr", "right"}, /* termcap */
1272 {"kd", "down"}, /* termcap */
1273 {"%8", "prior"}, /* terminfo */
1274 {"%5", "next"}, /* terminfo */
1275 {"@7", "end"}, /* terminfo */
1276 {"@1", "begin"}, /* terminfo */
1277 {"*6", "select"}, /* terminfo */
1278 {"%9", "print"}, /* terminfo */
1279 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1281 * "insert" --- see below
1283 {"&8", "undo"}, /* terminfo */
1284 {"%0", "redo"}, /* terminfo */
1285 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1286 {"@0", "find"}, /* terminfo */
1287 {"@2", "cancel"}, /* terminfo */
1288 {"%1", "help"}, /* terminfo */
1290 * "break" goes here, but can't be reliably intercepted with termcap
1292 {"&4", "reset"}, /* terminfo --- actually `restart' */
1294 * "system" and "user" --- no termcaps
1296 {"kE", "clearline"}, /* terminfo */
1297 {"kA", "insertline"}, /* terminfo */
1298 {"kL", "deleteline"}, /* terminfo */
1299 {"kI", "insertchar"}, /* terminfo */
1300 {"kD", "deletechar"}, /* terminfo */
1301 {"kB", "backtab"}, /* terminfo */
1303 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1305 {"@8", "kp-enter"}, /* terminfo */
1307 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1308 * "kp-multiply", "kp-add", "kp-separator",
1309 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1310 * --- no termcaps for any of these.
1312 {"K4", "kp-1"}, /* terminfo */
1314 * "kp-2" --- no termcap
1316 {"K5", "kp-3"}, /* terminfo */
1318 * "kp-4" --- no termcap
1320 {"K2", "kp-5"}, /* terminfo */
1322 * "kp-6" --- no termcap
1324 {"K1", "kp-7"}, /* terminfo */
1326 * "kp-8" --- no termcap
1328 {"K3", "kp-9"}, /* terminfo */
1330 * "kp-equal" --- no termcap
1343 static char **term_get_fkeys_arg
;
1344 static Lisp_Object
term_get_fkeys_1 ();
1346 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1347 This function scans the termcap function key sequence entries, and
1348 adds entries to Vfunction_key_map for each function key it finds. */
1351 term_get_fkeys (address
)
1354 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1355 errors during the call. The only errors should be from Fdefine_key
1356 when given a key sequence containing an invalid prefix key. If the
1357 termcap defines function keys which use a prefix that is already bound
1358 to a command by the default bindings, we should silently ignore that
1359 function key specification, rather than giving the user an error and
1360 refusing to run at all on such a terminal. */
1362 extern Lisp_Object
Fidentity ();
1363 term_get_fkeys_arg
= address
;
1364 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1372 char **address
= term_get_fkeys_arg
;
1374 /* This can happen if CANNOT_DUMP or with strange options. */
1376 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1378 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1380 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1382 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1383 Fmake_vector (make_number (1),
1384 intern (keys
[i
].name
)));
1387 /* The uses of the "k0" capability are inconsistent; sometimes it
1388 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1389 We will attempt to politely accommodate both systems by testing for
1390 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1393 char *k_semi
= tgetstr ("k;", address
);
1394 char *k0
= tgetstr ("k0", address
);
1395 char *k0_name
= "f10";
1400 /* Define f0 first, so that f10 takes precedence in case the
1401 key sequences happens to be the same. */
1402 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1403 Fmake_vector (make_number (1), intern ("f0")));
1404 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1405 Fmake_vector (make_number (1), intern ("f10")));
1408 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1409 Fmake_vector (make_number (1), intern (k0_name
)));
1412 /* Set up cookies for numbered function keys above f10. */
1414 char fcap
[3], fkey
[4];
1416 fcap
[0] = 'F'; fcap
[2] = '\0';
1417 for (i
= 11; i
< 64; i
++)
1420 fcap
[1] = '1' + i
- 11;
1422 fcap
[1] = 'A' + i
- 20;
1424 fcap
[1] = 'a' + i
- 46;
1427 char *sequence
= tgetstr (fcap
, address
);
1430 sprintf (fkey
, "f%d", i
);
1431 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1432 Fmake_vector (make_number (1),
1440 * Various mappings to try and get a better fit.
1443 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1444 if (!tgetstr (cap1, address)) \
1446 char *sequence = tgetstr (cap2, address); \
1448 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1449 Fmake_vector (make_number (1), \
1453 /* if there's no key_next keycap, map key_npage to `next' keysym */
1454 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1455 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1456 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1457 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1458 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1459 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1460 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1462 /* IBM has their own non-standard dialect of terminfo.
1463 If the standard name isn't found, try the IBM name. */
1464 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1465 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1466 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1467 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1468 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1469 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1470 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1471 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1472 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1473 #undef CONDITIONAL_REASSIGN
1480 /***********************************************************************
1481 Character Display Information
1482 ***********************************************************************/
1484 static void append_glyph
P_ ((struct it
*));
1487 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1488 terminal frames if IT->glyph_row != NULL. IT->c is the character
1489 for which to produce glyphs; IT->face_id contains the character's
1490 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1497 struct glyph
*glyph
, *end
;
1500 xassert (it
->glyph_row
);
1501 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1502 + it
->glyph_row
->used
[it
->area
]);
1503 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1506 i
< it
->pixel_width
&& glyph
< end
;
1509 glyph
->type
= CHAR_GLYPH
;
1510 glyph
->pixel_width
= 1;
1511 glyph
->u
.ch
= it
->c
;
1512 glyph
->face_id
= it
->face_id
;
1513 glyph
->padding_p
= i
> 0;
1514 glyph
->charpos
= CHARPOS (it
->position
);
1515 glyph
->object
= it
->object
;
1517 ++it
->glyph_row
->used
[it
->area
];
1523 /* Produce glyphs for the display element described by IT. *IT
1524 specifies what we want to produce a glyph for (character, image, ...),
1525 and where in the glyph matrix we currently are (glyph row and hpos).
1526 produce_glyphs fills in output fields of *IT with information such as the
1527 pixel width and height of a character, and maybe output actual glyphs at
1528 the same time if IT->glyph_row is non-null. See the explanation of
1529 struct display_iterator in dispextern.h for an overview.
1531 produce_glyphs also stores the result of glyph width, ascent
1532 etc. computations in *IT.
1534 IT->glyph_row may be null, in which case produce_glyphs does not
1535 actually fill in the glyphs. This is used in the move_* functions
1536 in xdisp.c for text width and height computations.
1538 Callers usually don't call produce_glyphs directly;
1539 instead they use the macro PRODUCE_GLYPHS. */
1545 /* If a hook is installed, let it do the work. */
1546 xassert (it
->what
== IT_CHARACTER
1547 || it
->what
== IT_COMPOSITION
1548 || it
->what
== IT_IMAGE
1549 || it
->what
== IT_STRETCH
);
1551 /* Nothing but characters are supported on terminal frames. For a
1552 composition sequence, it->c is the first character of the
1554 xassert (it
->what
== IT_CHARACTER
1555 || it
->what
== IT_COMPOSITION
);
1557 if (it
->c
>= 040 && it
->c
< 0177)
1559 it
->pixel_width
= it
->nglyphs
= 1;
1563 else if (it
->c
== '\n')
1564 it
->pixel_width
= it
->nglyphs
= 0;
1565 else if (it
->c
== '\t')
1567 int absolute_x
= (it
->current_x
1568 + it
->continuation_lines_width
);
1570 = (((1 + absolute_x
+ it
->tab_width
- 1)
1575 /* If part of the TAB has been displayed on the previous line
1576 which is continued now, continuation_lines_width will have
1577 been incremented already by the part that fitted on the
1578 continued line. So, we will get the right number of spaces
1580 nspaces
= next_tab_x
- absolute_x
;
1587 it
->pixel_width
= it
->len
= 1;
1595 it
->pixel_width
= nspaces
;
1596 it
->nglyphs
= nspaces
;
1598 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1600 /* Coming here means that it->c is from display table, thus we
1601 must send the code as is to the terminal. Although there's
1602 no way to know how many columns it occupies on a screen, it
1603 is a good assumption that a single byte code has 1-column
1605 it
->pixel_width
= it
->nglyphs
= 1;
1611 /* A multi-byte character. The display width is fixed for all
1612 characters of the set. Some of the glyphs may have to be
1613 ignored because they are already displayed in a continued
1615 int charset
= CHAR_CHARSET (it
->c
);
1617 it
->pixel_width
= CHARSET_WIDTH (charset
);
1618 it
->nglyphs
= it
->pixel_width
;
1624 /* Advance current_x by the pixel width as a convenience for
1626 if (it
->area
== TEXT_AREA
)
1627 it
->current_x
+= it
->pixel_width
;
1628 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1629 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1633 /* Get information about special display element WHAT in an
1634 environment described by IT. WHAT is one of IT_TRUNCATION or
1635 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1636 non-null glyph_row member. This function ensures that fields like
1637 face_id, c, len of IT are left untouched. */
1640 produce_special_glyphs (it
, what
)
1642 enum display_element_type what
;
1648 temp_it
.what
= IT_CHARACTER
;
1650 temp_it
.object
= make_number (0);
1651 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1653 if (what
== IT_CONTINUATION
)
1655 /* Continuation glyph. */
1657 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1658 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1660 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it
->dp
)));
1661 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1666 produce_glyphs (&temp_it
);
1667 it
->pixel_width
= temp_it
.pixel_width
;
1668 it
->nglyphs
= temp_it
.pixel_width
;
1670 else if (what
== IT_TRUNCATION
)
1672 /* Truncation glyph. */
1674 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1675 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1677 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it
->dp
)));
1678 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1683 produce_glyphs (&temp_it
);
1684 it
->pixel_width
= temp_it
.pixel_width
;
1685 it
->nglyphs
= temp_it
.pixel_width
;
1693 /***********************************************************************
1695 ***********************************************************************/
1697 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1698 one of the enumerators from enum no_color_bit, or a bit set built
1699 from them. Some display attributes may not be used together with
1700 color; the termcap capability `NC' specifies which ones. */
1702 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1703 (tty->TN_max_colors > 0 \
1704 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1707 /* Turn appearances of face FACE_ID on tty frame F on. */
1710 turn_on_face (f
, face_id
)
1714 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1715 long fg
= face
->foreground
;
1716 long bg
= face
->background
;
1717 struct tty_display_info
*tty
= FRAME_TTY (f
);
1719 /* Do this first because TS_end_standout_mode may be the same
1720 as TS_exit_attribute_mode, which turns all appearances off. */
1721 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1723 if (tty
->TN_max_colors
> 0)
1725 if (fg
>= 0 && bg
>= 0)
1727 /* If the terminal supports colors, we can set them
1728 below without using reverse video. The face's fg
1729 and bg colors are set as they should appear on
1730 the screen, i.e. they take the inverse-video'ness
1731 of the face already into account. */
1733 else if (inverse_video
)
1735 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1736 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1737 toggle_highlight (tty
);
1741 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1742 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1743 toggle_highlight (tty
);
1748 /* If we can't display colors, use reverse video
1749 if the face specifies that. */
1752 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1753 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1754 toggle_highlight (tty
);
1758 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1759 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1760 toggle_highlight (tty
);
1765 if (face
->tty_bold_p
)
1767 if (MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1768 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1770 else if (face
->tty_dim_p
)
1771 if (MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1772 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1774 /* Alternate charset and blinking not yet used. */
1775 if (face
->tty_alt_charset_p
1776 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1777 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1779 if (face
->tty_blinking_p
1780 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1781 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1783 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1784 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1786 if (tty
->TN_max_colors
> 0)
1790 if (fg
>= 0 && tty
->TS_set_foreground
)
1792 p
= tparam (tty
->TS_set_foreground
, NULL
, 0, (int) fg
);
1797 if (bg
>= 0 && tty
->TS_set_background
)
1799 p
= tparam (tty
->TS_set_background
, NULL
, 0, (int) bg
);
1807 /* Turn off appearances of face FACE_ID on tty frame F. */
1810 turn_off_face (f
, face_id
)
1814 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1815 struct tty_display_info
*tty
= FRAME_TTY (f
);
1817 xassert (face
!= NULL
);
1819 if (tty
->TS_exit_attribute_mode
)
1821 /* Capability "me" will turn off appearance modes double-bright,
1822 half-bright, reverse-video, standout, underline. It may or
1823 may not turn off alt-char-mode. */
1824 if (face
->tty_bold_p
1826 || face
->tty_reverse_p
1827 || face
->tty_alt_charset_p
1828 || face
->tty_blinking_p
1829 || face
->tty_underline_p
)
1831 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
1832 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
1833 tty
->standout_mode
= 0;
1836 if (face
->tty_alt_charset_p
)
1837 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1841 /* If we don't have "me" we can only have those appearances
1842 that have exit sequences defined. */
1843 if (face
->tty_alt_charset_p
)
1844 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1846 if (face
->tty_underline_p
)
1847 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
1850 /* Switch back to default colors. */
1851 if (tty
->TN_max_colors
> 0
1852 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
1853 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
1854 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
1855 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
1856 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
1860 /* Return non-zero if the terminal on frame F supports all of the
1861 capabilities in CAPS simultaneously, with foreground and background
1862 colors FG and BG. */
1865 tty_capable_p (tty
, caps
, fg
, bg
)
1866 struct tty_display_info
*tty
;
1868 unsigned long fg
, bg
;
1870 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
1871 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
1874 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
1875 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
1876 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
1877 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
1878 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
1879 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
1885 /* Return the tty display object specified by DISPLAY.
1886 DISPLAY may be a frame or a string. */
1888 static struct display
*
1889 get_tty_display (Lisp_Object display
)
1893 if (! FRAMEP (display
) && ! STRINGP (display
))
1896 /* The initial frame does not support colors. */
1897 if (FRAMEP (display
) && FRAME_INITIAL_P (XFRAME (display
)))
1900 if (FRAMEP (display
))
1902 if (! FRAME_TERMCAP_P (XFRAME (display
)))
1903 #if 0 /* XXX We need a predicate as the first argument; find one. */
1904 wrong_type_argument ("Not a termcap frame", display
);
1905 #else /* Until we fix the wrong_type_argument call above, simply throw
1907 error ("DISPLAY is not a termcap frame");
1910 d
= FRAME_DISPLAY (XFRAME (display
));
1912 else if (STRINGP (display
))
1914 char *name
= (char *) alloca (SBYTES (display
) + 1);
1915 strncpy (name
, SDATA (display
), SBYTES (display
));
1916 name
[SBYTES (display
)] = 0;
1918 d
= get_named_tty_display (name
);
1921 error ("There is no tty display on %s", name
);
1928 /* Return non-zero if the terminal is capable to display colors. */
1930 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
1932 doc
: /* Return non-nil if TTY can display colors on DISPLAY. */)
1934 Lisp_Object display
;
1936 struct display
*d
= get_tty_display (display
);
1940 return d
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
1943 /* Return the number of supported colors. */
1944 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
1945 Stty_display_color_cells
, 0, 1, 0,
1946 doc
: /* Return the number of colors supported by TTY on DISPLAY. */)
1948 Lisp_Object display
;
1950 struct display
*d
= get_tty_display (display
);
1954 return make_number (d
->display_info
.tty
->TN_max_colors
);
1959 /* Save or restore the default color-related capabilities of this
1962 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
1965 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
1966 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
1970 if (default_orig_pair
)
1971 xfree (default_orig_pair
);
1972 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
1974 if (default_set_foreground
)
1975 xfree (default_set_foreground
);
1976 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
1979 if (default_set_background
)
1980 xfree (default_set_background
);
1981 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
1984 default_max_colors
= tty
->TN_max_colors
;
1985 default_max_pairs
= tty
->TN_max_pairs
;
1986 default_no_color_video
= tty
->TN_no_color_video
;
1990 tty
->TS_orig_pair
= default_orig_pair
;
1991 tty
->TS_set_foreground
= default_set_foreground
;
1992 tty
->TS_set_background
= default_set_background
;
1993 tty
->TN_max_colors
= default_max_colors
;
1994 tty
->TN_max_pairs
= default_max_pairs
;
1995 tty
->TN_no_color_video
= default_no_color_video
;
1999 /* Setup one of the standard tty color schemes according to MODE.
2000 MODE's value is generally the number of colors which we want to
2001 support; zero means set up for the default capabilities, the ones
2002 we saw at term_init time; -1 means turn off color support. */
2004 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2006 /* Canonicalize all negative values of MODE. */
2012 case -1: /* no colors at all */
2013 tty
->TN_max_colors
= 0;
2014 tty
->TN_max_pairs
= 0;
2015 tty
->TN_no_color_video
= 0;
2016 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2018 case 0: /* default colors, if any */
2020 tty_default_color_capabilities (tty
, 0);
2022 case 8: /* 8 standard ANSI colors */
2023 tty
->TS_orig_pair
= "\033[0m";
2025 tty
->TS_set_foreground
= "\033[3%p1%dm";
2026 tty
->TS_set_background
= "\033[4%p1%dm";
2028 tty
->TS_set_foreground
= "\033[3%dm";
2029 tty
->TS_set_background
= "\033[4%dm";
2031 tty
->TN_max_colors
= 8;
2032 tty
->TN_max_pairs
= 64;
2033 tty
->TN_no_color_video
= 0;
2039 set_tty_color_mode (f
, val
)
2043 Lisp_Object color_mode_spec
, current_mode_spec
;
2044 Lisp_Object color_mode
, current_mode
;
2046 extern Lisp_Object Qtty_color_mode
;
2047 Lisp_Object tty_color_mode_alist
;
2049 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2056 if (NILP (tty_color_mode_alist
))
2057 color_mode_spec
= Qnil
;
2059 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2061 if (CONSP (color_mode_spec
))
2062 color_mode
= XCDR (color_mode_spec
);
2067 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2069 if (CONSP (current_mode_spec
))
2070 current_mode
= XCDR (current_mode_spec
);
2072 current_mode
= Qnil
;
2073 if (INTEGERP (color_mode
))
2074 mode
= XINT (color_mode
);
2076 mode
= 0; /* meaning default */
2077 if (INTEGERP (current_mode
))
2078 old_mode
= XINT (current_mode
);
2082 if (mode
!= old_mode
)
2084 tty_setup_colors (FRAME_TTY (f
), mode
);
2085 /* This recomputes all the faces given the new color
2087 call0 (intern ("tty-set-up-initial-frame-faces"));
2092 #endif /* !WINDOWSNT */
2096 /* Return the termcap display with the given name. If NAME is null,
2097 return the display corresponding to our controlling terminal.
2099 Returns NULL if the named terminal device is not opened. */
2102 get_named_tty_display (name
)
2107 for (d
= display_list
; d
; d
= d
->next_display
) {
2108 if (d
->type
== output_termcap
2109 && ((d
->display_info
.tty
->name
== 0 && name
== 0)
2110 || (name
&& d
->display_info
.tty
->name
2111 && !strcmp (d
->display_info
.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 /* Create the bootstrap display device for the initial frame.
2178 Returns a display of type output_initial. */
2181 init_initial_display (void)
2183 if (initialized
|| display_list
|| tty_list
)
2186 initial_display
= create_display ();
2187 initial_display
->type
= output_initial
;
2189 initial_display
->delete_display_hook
= &delete_initial_display
;
2190 /* All other hooks are NULL. */
2192 return initial_display
;
2195 /* Deletes the bootstrap display device.
2196 Called through delete_display_hook. */
2199 delete_initial_display (struct display
*display
)
2201 if (display
!= initial_display
)
2204 delete_display (display
);
2205 initial_display
= NULL
;
2208 /* Create a termcap display on the tty device with the given name and
2211 If NAME is NULL, then use the controlling tty, i.e., stdin/stdout.
2212 Otherwise NAME should be a path to the tty device file,
2215 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
2217 If MUST_SUCCEED is true, then all errors are fatal. */
2220 term_init (char *name
, char *terminal_type
, int must_succeed
)
2223 char **address
= &area
;
2224 char *buffer
= NULL
;
2225 int buffer_size
= 4096;
2228 struct tty_display_info
*tty
;
2229 struct display
*display
;
2231 static void maybe_fatal();
2234 maybe_fatal (must_succeed
, 0, 0,
2235 "Unknown terminal type",
2236 "Unknown terminal type");
2238 display
= get_named_tty_display (name
);
2240 return display
; /* We have already opened a display there. */
2242 display
= create_display ();
2243 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
2244 bzero (tty
, sizeof (struct tty_display_info
));
2245 tty
->next
= tty_list
;
2248 display
->type
= output_termcap
;
2249 display
->display_info
.tty
= tty
;
2250 tty
->display
= display
;
2252 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
2255 display
->rif
= 0; /* ttys don't support window-based redisplay. */
2257 display
->cursor_to_hook
= &tty_cursor_to
;
2258 display
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
2260 display
->clear_to_end_hook
= &tty_clear_to_end
;
2261 display
->clear_frame_hook
= &tty_clear_frame
;
2262 display
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
2264 display
->ins_del_lines_hook
= &tty_ins_del_lines
;
2266 display
->insert_glyphs_hook
= &tty_insert_glyphs
;
2267 display
->write_glyphs_hook
= &tty_write_glyphs
;
2268 display
->delete_glyphs_hook
= &tty_delete_glyphs
;
2270 display
->ring_bell_hook
= &tty_ring_bell
;
2272 display
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
2273 display
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
2274 display
->update_begin_hook
= 0; /* Not needed. */
2275 display
->update_end_hook
= &tty_update_end
;
2276 display
->set_terminal_window_hook
= &tty_set_terminal_window
;
2278 display
->mouse_position_hook
= 0; /* Not needed. */
2279 display
->frame_rehighlight_hook
= 0; /* Not needed. */
2280 display
->frame_raise_lower_hook
= 0; /* Not needed. */
2282 display
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
2283 display
->condemn_scroll_bars_hook
= 0; /* Not needed. */
2284 display
->redeem_scroll_bar_hook
= 0; /* Not needed. */
2285 display
->judge_scroll_bars_hook
= 0; /* Not needed. */
2287 display
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
2288 display
->frame_up_to_date_hook
= 0; /* Not needed. */
2290 display
->delete_frame_hook
= &delete_tty_output
;
2291 display
->delete_display_hook
= &delete_tty
;
2298 #ifdef O_IGNORE_CTTY
2299 /* Open the terminal device. Don't recognize it as our
2300 controlling terminal, and don't make it the controlling tty
2301 if we don't have one at the moment. */
2302 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
2304 /* Alas, O_IGNORE_CTTY is a GNU extension that is only defined
2305 on Hurd. On other systems, we need to dissociate ourselves
2306 from the controlling tty when we want to open a frame on the
2307 same terminal. The function setsid should be used for this,
2308 but it didn't work for me. */
2310 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
2313 /* Drop our controlling tty if it is the same device. */
2314 if (ioctl (fd
, TIOCNOTTY
, 0) != -1)
2316 no_controlling_tty
= 1;
2319 #endif /* O_IGNORE_CTTY */
2323 delete_tty (display
);
2324 error ("Could not open file: %s", name
);
2329 error ("Not a tty device: %s", name
);
2332 file
= fdopen (fd
, "w+");
2333 tty
->name
= xstrdup (name
);
2339 if (no_controlling_tty
)
2341 /* Opening a frame on stdout is unsafe if we have
2342 disconnected our controlling terminal. */
2343 error ("There is no controlling terminal any more");
2347 tty
->output
= stdout
;
2350 tty
->type
= xstrdup (terminal_type
);
2352 add_keyboard_wait_descriptor (fileno (tty
->input
));
2355 initialize_w32_display ();
2359 area
= (char *) xmalloc (2044);
2361 FrameRows (tty
) = FRAME_LINES (f
); /* XXX */
2362 FrameCols (tty
) = FRAME_COLS (f
); /* XXX */
2363 tty
->specified_window
= FRAME_LINES (f
); /* XXX */
2365 tty
->display
->delete_in_insert_mode
= 1;
2368 display
->scroll_region_ok
= 0;
2370 /* Seems to insert lines when it's not supposed to, messing
2371 up the display. In doing a trace, it didn't seem to be
2372 called much, so I don't think we're losing anything by
2374 display
->line_ins_del_ok
= 0;
2375 display
->char_ins_del_ok
= 1;
2379 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0; /* XXX */
2380 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
; /* XXX */
2381 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2384 #else /* not WINDOWSNT */
2388 buffer
= (char *) xmalloc (buffer_size
);
2389 status
= tgetent (buffer
, terminal_type
);
2393 maybe_fatal (must_succeed
, buffer
, display
,
2394 "Cannot open terminfo database file",
2395 "Cannot open terminfo database file");
2397 maybe_fatal (must_succeed
, buffer
, display
,
2398 "Cannot open termcap database file",
2399 "Cannot open termcap database file");
2405 maybe_fatal (must_succeed
, buffer
, display
,
2406 "Terminal type %s is not defined",
2407 "Terminal type %s is not defined.\n\
2408 If that is not the actual type of terminal you have,\n\
2409 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2410 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2411 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2414 maybe_fatal (must_succeed
, buffer
, display
,
2415 "Terminal type %s is not defined",
2416 "Terminal type %s is not defined.\n\
2417 If that is not the actual type of terminal you have,\n\
2418 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2419 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2420 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2426 if (strlen (buffer
) >= buffer_size
)
2428 buffer_size
= strlen (buffer
);
2430 area
= (char *) xmalloc (buffer_size
);
2432 tty
->TS_ins_line
= tgetstr ("al", address
);
2433 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
2434 tty
->TS_bell
= tgetstr ("bl", address
);
2435 BackTab (tty
) = tgetstr ("bt", address
);
2436 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
2437 tty
->TS_clr_line
= tgetstr ("ce", address
);
2438 tty
->TS_clr_frame
= tgetstr ("cl", address
);
2439 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
2440 AbsPosition (tty
) = tgetstr ("cm", address
);
2441 CR (tty
) = tgetstr ("cr", address
);
2442 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
2443 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
2444 RowPosition (tty
) = tgetstr ("cv", address
);
2445 tty
->TS_del_char
= tgetstr ("dc", address
);
2446 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
2447 tty
->TS_del_line
= tgetstr ("dl", address
);
2448 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
2449 tty
->TS_delete_mode
= tgetstr ("dm", address
);
2450 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
2451 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
2452 Home (tty
) = tgetstr ("ho", address
);
2453 tty
->TS_ins_char
= tgetstr ("ic", address
);
2454 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
2455 tty
->TS_insert_mode
= tgetstr ("im", address
);
2456 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
2457 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
2458 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
2459 LastLine (tty
) = tgetstr ("ll", address
);
2460 Right (tty
) = tgetstr ("nd", address
);
2461 Down (tty
) = tgetstr ("do", address
);
2463 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
2465 /* VMS puts a carriage return before each linefeed,
2466 so it is not safe to use linefeeds. */
2467 if (Down (tty
) && Down (tty
)[0] == '\n' && Down (tty
)[1] == '\0')
2470 if (tgetflag ("bs"))
2471 Left (tty
) = "\b"; /* can't possibly be longer! */
2472 else /* (Actually, "bs" is obsolete...) */
2473 Left (tty
) = tgetstr ("le", address
);
2475 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
2476 tty
->TS_pad_char
= tgetstr ("pc", address
);
2477 tty
->TS_repeat
= tgetstr ("rp", address
);
2478 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
2479 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
2480 tty
->TS_standout_mode
= tgetstr ("so", address
);
2481 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
2482 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
2483 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
2484 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
2485 Up (tty
) = tgetstr ("up", address
);
2486 tty
->TS_visible_bell
= tgetstr ("vb", address
);
2487 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
2488 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
2489 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
2490 tty
->TS_set_window
= tgetstr ("wi", address
);
2492 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
2493 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
2494 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
2495 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
2496 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
2497 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
2498 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2499 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2500 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
2502 MultiUp (tty
) = tgetstr ("UP", address
);
2503 MultiDown (tty
) = tgetstr ("DO", address
);
2504 MultiLeft (tty
) = tgetstr ("LE", address
);
2505 MultiRight (tty
) = tgetstr ("RI", address
);
2507 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2508 color because we can't switch back to the default foreground and
2510 tty
->TS_orig_pair
= tgetstr ("op", address
);
2511 if (tty
->TS_orig_pair
)
2513 tty
->TS_set_foreground
= tgetstr ("AF", address
);
2514 tty
->TS_set_background
= tgetstr ("AB", address
);
2515 if (!tty
->TS_set_foreground
)
2518 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
2519 tty
->TS_set_background
= tgetstr ("Sb", address
);
2522 tty
->TN_max_colors
= tgetnum ("Co");
2523 tty
->TN_max_pairs
= tgetnum ("pa");
2525 tty
->TN_no_color_video
= tgetnum ("NC");
2526 if (tty
->TN_no_color_video
== -1)
2527 tty
->TN_no_color_video
= 0;
2530 tty_default_color_capabilities (tty
, 1);
2532 MagicWrap (tty
) = tgetflag ("xn");
2533 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2534 the former flag imply the latter. */
2535 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
2536 display
->memory_below_frame
= tgetflag ("db");
2537 tty
->TF_hazeltine
= tgetflag ("hz");
2538 display
->must_write_spaces
= tgetflag ("in");
2539 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
2540 tty
->TF_insmode_motion
= tgetflag ("mi");
2541 tty
->TF_standout_motion
= tgetflag ("ms");
2542 tty
->TF_underscore
= tgetflag ("ul");
2543 tty
->TF_teleray
= tgetflag ("xt");
2545 term_get_fkeys (address
);
2547 /* Get frame size from system, or else from termcap. */
2550 get_tty_size (fileno (TTY_INPUT (tty
)), &width
, &height
);
2551 FrameCols (tty
) = width
;
2552 FrameRows (tty
) = height
;
2555 if (FrameCols (tty
) <= 0)
2556 FrameCols (tty
) = tgetnum ("co");
2557 if (FrameRows (tty
) <= 0)
2558 FrameRows (tty
) = tgetnum ("li");
2560 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
2561 maybe_fatal (must_succeed
, NULL
, display
,
2562 "Screen size %dx%d is too small"
2563 "Screen size %dx%d is too small",
2564 FrameCols (tty
), FrameRows (tty
));
2566 #if 0 /* This is not used anywhere. */
2567 tty
->display
->min_padding_speed
= tgetnum ("pb");
2570 TabWidth (tty
) = tgetnum ("tw");
2573 /* These capabilities commonly use ^J.
2574 I don't know why, but sending them on VMS does not work;
2575 it causes following spaces to be lost, sometimes.
2576 For now, the simplest fix is to avoid using these capabilities ever. */
2577 if (Down (tty
) && Down (tty
)[0] == '\n')
2582 tty
->TS_bell
= "\07";
2584 if (!tty
->TS_fwd_scroll
)
2585 tty
->TS_fwd_scroll
= Down (tty
);
2587 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
2589 if (TabWidth (tty
) < 0)
2592 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2593 and newer termcap doc does not seem to say there is a default.
2594 if (!tty->Wcm->cm_tab)
2595 tty->Wcm->cm_tab = "\t";
2598 /* We don't support standout modes that use `magic cookies', so
2599 turn off any that do. */
2600 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
2602 tty
->TS_standout_mode
= 0;
2603 tty
->TS_end_standout_mode
= 0;
2605 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
2607 tty
->TS_enter_underline_mode
= 0;
2608 tty
->TS_exit_underline_mode
= 0;
2611 /* If there's no standout mode, try to use underlining instead. */
2612 if (tty
->TS_standout_mode
== 0)
2614 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
2615 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
2618 /* If no `se' string, try using a `me' string instead.
2619 If that fails, we can't use standout mode at all. */
2620 if (tty
->TS_end_standout_mode
== 0)
2622 char *s
= tgetstr ("me", address
);
2624 tty
->TS_end_standout_mode
= s
;
2626 tty
->TS_standout_mode
= 0;
2629 if (tty
->TF_teleray
)
2631 tty
->Wcm
->cm_tab
= 0;
2632 /* We can't support standout mode, because it uses magic cookies. */
2633 tty
->TS_standout_mode
= 0;
2634 /* But that means we cannot rely on ^M to go to column zero! */
2636 /* LF can't be trusted either -- can alter hpos */
2637 /* if move at column 0 thru a line with TS_standout_mode */
2641 /* Special handling for certain terminal types known to need it */
2643 if (!strcmp (terminal_type
, "supdup"))
2645 display
->memory_below_frame
= 1;
2646 tty
->Wcm
->cm_losewrap
= 1;
2648 if (!strncmp (terminal_type
, "c10", 3)
2649 || !strcmp (terminal_type
, "perq"))
2651 /* Supply a makeshift :wi string.
2652 This string is not valid in general since it works only
2653 for windows starting at the upper left corner;
2654 but that is all Emacs uses.
2656 This string works only if the frame is using
2657 the top of the video memory, because addressing is memory-relative.
2658 So first check the :ti string to see if that is true.
2660 It would be simpler if the :wi string could go in the termcap
2661 entry, but it can't because it is not fully valid.
2662 If it were in the termcap entry, it would confuse other programs. */
2663 if (!tty
->TS_set_window
)
2665 p
= tty
->TS_termcap_modes
;
2666 while (*p
&& strcmp (p
, "\033v "))
2669 tty
->TS_set_window
= "\033v%C %C %C %C ";
2671 /* Termcap entry often fails to have :in: flag */
2672 display
->must_write_spaces
= 1;
2673 /* :ti string typically fails to have \E^G! in it */
2674 /* This limits scope of insert-char to one line. */
2675 strcpy (area
, tty
->TS_termcap_modes
);
2676 strcat (area
, "\033\007!");
2677 tty
->TS_termcap_modes
= area
;
2678 area
+= strlen (area
) + 1;
2679 p
= AbsPosition (tty
);
2680 /* Change all %+ parameters to %C, to handle
2681 values above 96 correctly for the C100. */
2684 if (p
[0] == '%' && p
[1] == '+')
2690 tty
->specified_window
= FrameRows (tty
);
2692 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
2694 maybe_fatal (must_succeed
, NULL
, display
,
2695 "Terminal type \"%s\" is not powerful enough to run Emacs",
2697 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2698 It lacks the ability to position the cursor.\n\
2699 If that is not the actual type of terminal you have, use either the\n\
2700 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2701 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2704 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2705 It lacks the ability to position the cursor.\n\
2706 If that is not the actual type of terminal you have,\n\
2707 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2708 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2709 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2710 # else /* TERMCAP */
2711 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2712 It lacks the ability to position the cursor.\n\
2713 If that is not the actual type of terminal you have,\n\
2714 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2715 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2716 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2717 # endif /* TERMINFO */
2722 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
2723 maybe_fatal (must_succeed
, NULL
, display
,
2724 "Could not determine the frame size",
2725 "Could not determine the frame size");
2727 tty
->delete_in_insert_mode
2728 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
2729 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
2731 tty
->se_is_so
= (tty
->TS_standout_mode
2732 && tty
->TS_end_standout_mode
2733 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
2735 UseTabs (tty
) = tabs_safe_p (fileno (TTY_INPUT (tty
))) && TabWidth (tty
) == 8;
2737 display
->scroll_region_ok
2739 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
2741 display
->line_ins_del_ok
2742 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
2743 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
2744 || (display
->scroll_region_ok
2745 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
2747 display
->char_ins_del_ok
2748 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
2749 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
2750 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
2752 display
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
2754 init_baud_rate (fileno (TTY_INPUT (tty
)));
2757 /* The HFT system on AIX doesn't optimize for scrolling, so it's
2758 really ugly at times. */
2759 display
->line_ins_del_ok
= 0;
2760 display
->char_ins_del_ok
= 0;
2764 tty
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
2765 init_kboard (tty
->kboard
);
2766 tty
->kboard
->next_kboard
= all_kboards
;
2767 all_kboards
= tty
->kboard
;
2768 /* Don't let the initial kboard remain current longer than necessary.
2769 That would cause problems if a file loaded on startup tries to
2770 prompt in the mini-buffer. */
2771 if (current_kboard
== initial_kboard
)
2772 current_kboard
= tty
->kboard
;
2773 tty
->kboard
->reference_count
++;
2776 /* Don't do this. I think termcap may still need the buffer. */
2777 /* xfree (buffer); */
2779 /* Init system terminal modes (RAW or CBREAK, etc.). */
2780 init_sys_modes (tty
);
2783 #endif /* not WINDOWSNT */
2786 /* Auxiliary error-handling function for term_init.
2787 Free BUFFER and delete DISPLAY, then call error or fatal
2788 with str1 or str2, respectively, according to MUST_SUCCEED. */
2791 maybe_fatal (must_succeed
, buffer
, display
, str1
, str2
, arg1
, arg2
)
2794 struct display
*display
;
2795 char *str1
, *str2
, *arg1
, *arg2
;
2801 delete_tty (display
);
2804 fatal (str2
, arg1
, arg2
);
2806 error (str1
, arg1
, arg2
);
2813 fatal (str
, arg1
, arg2
)
2814 char *str
, *arg1
, *arg2
;
2816 fprintf (stderr
, "emacs: ");
2817 fprintf (stderr
, str
, arg1
, arg2
);
2818 fprintf (stderr
, "\n");
2825 DEFUN ("delete-tty", Fdelete_tty
, Sdelete_tty
, 0, 1, 0,
2826 doc
: /* Delete all frames on the terminal named TTY, and close the device.
2827 If omitted, TTY defaults to the controlling terminal.
2829 This function runs `delete-tty-after-functions' after closing the
2830 tty. The functions are run with one arg, the frame to be deleted. */)
2839 if (SBYTES (tty
) > 0)
2841 name
= (char *) alloca (SBYTES (tty
) + 1);
2842 strncpy (name
, SDATA (tty
), SBYTES (tty
));
2843 name
[SBYTES (tty
)] = 0;
2846 d
= get_named_tty_display (name
);
2849 error ("No such terminal device: %s", name
);
2856 static int deleting_tty
= 0;
2859 /* Delete the given terminal device, closing all frames on it. */
2862 delete_tty (struct display
*display
)
2864 struct tty_display_info
*tty
;
2865 Lisp_Object tail
, frame
;
2869 /* We get a recursive call when we delete the last frame on this
2875 if (display
->type
!= output_termcap
)
2878 tty
= display
->display_info
.tty
;
2880 if (tty
== tty_list
)
2881 tty_list
= tty
->next
;
2884 struct tty_display_info
*p
;
2885 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
2889 /* This should not happen. */
2892 p
->next
= tty
->next
;
2896 FOR_EACH_FRAME (tail
, frame
)
2898 struct frame
*f
= XFRAME (frame
);
2899 if (FRAME_TERMCAP_P (f
) && FRAME_LIVE_P (f
) && FRAME_TTY (f
) == tty
)
2901 Fdelete_frame (frame
, Qt
);
2905 /* reset_sys_modes needs a valid display, so this call needs to be
2906 before delete_display. */
2907 reset_sys_modes (tty
);
2909 delete_display (display
);
2911 tty_name
= tty
->name
;
2917 delete_keyboard_wait_descriptor (fileno (tty
->input
));
2918 if (tty
->input
!= stdin
)
2919 fclose (tty
->input
);
2921 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
2922 fclose (tty
->output
);
2923 if (tty
->termscript
)
2924 fclose (tty
->termscript
);
2927 xfree (tty
->old_tty
);
2933 if (tty
->kboard
&& --tty
->kboard
->reference_count
> 0)
2936 delete_kboard (tty
->kboard
);
2939 bzero (tty
, sizeof (struct tty_display_info
));
2943 /* Run `delete-tty-after-functions'. */
2944 if (!NILP (Vrun_hooks
))
2946 Lisp_Object args
[2];
2947 args
[0] = intern ("delete-tty-after-functions");
2950 args
[1] = build_string (tty_name
);
2955 Frun_hook_with_args (2, args
);
2961 /* Initialize the tty-dependent part of frame F. The frame must
2962 already have its display initialized. */
2965 create_tty_output (struct frame
*f
)
2967 struct tty_output
*t
;
2969 if (! FRAME_TERMCAP_P (f
))
2972 t
= xmalloc (sizeof (struct tty_output
));
2973 bzero (t
, sizeof (struct tty_output
));
2975 t
->display_info
= FRAME_DISPLAY (f
)->display_info
.tty
;
2977 f
->output_data
.tty
= t
;
2980 /* Delete the tty-dependent part of frame F. */
2983 delete_tty_output (struct frame
*f
)
2985 if (! FRAME_TERMCAP_P (f
))
2988 xfree (f
->output_data
.tty
);
2994 /* Mark the pointers in the tty_display_info objects.
2995 Called by the Fgarbage_collector. */
3000 struct tty_display_info
*tty
;
3002 for (tty
= tty_list
; tty
; tty
= tty
->next
)
3005 mark_object (tty
->top_frame
);
3011 /* Create a new display object and add it to the display list. */
3014 create_display (void)
3016 struct display
*dev
= (struct display
*) xmalloc (sizeof (struct display
));
3018 bzero (dev
, sizeof (struct display
));
3019 dev
->next_display
= display_list
;
3025 /* Remove a display from the display list and free its memory. */
3028 delete_display (struct display
*dev
)
3030 struct display
**dp
;
3031 Lisp_Object tail
, frame
;
3033 /* Check for and close live frames that are still on this
3035 FOR_EACH_FRAME (tail
, frame
)
3037 struct frame
*f
= XFRAME (frame
);
3038 if (FRAME_LIVE_P (f
) && f
->display
== dev
)
3040 Fdelete_frame (frame
, Qt
);
3044 for (dp
= &display_list
; *dp
!= dev
; dp
= &(*dp
)->next_display
)
3047 *dp
= dev
->next_display
;
3049 bzero (dev
, sizeof (struct display
));
3058 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
3059 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3060 This variable can be used by terminal emulator packages. */);
3062 system_uses_terminfo
= 1;
3064 system_uses_terminfo
= 0;
3067 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
3068 doc
: /* Non-nil means call this function to ring the bell.
3069 The function should accept no arguments. */);
3070 Vring_bell_function
= Qnil
;
3072 DEFVAR_LISP ("delete-tty-after-functions", &Vdelete_tty_after_functions
,
3073 doc
: /* Functions to be run after deleting a tty.
3074 The functions are run with one argument, the name of the tty to be deleted.
3075 See `delete-tty'. */);
3076 Vdelete_tty_after_functions
= Qnil
;
3078 Qframe_tty_name
= intern ("frame-tty-name");
3079 staticpro (&Qframe_tty_name
);
3081 Qframe_tty_type
= intern ("frame-tty-type");
3082 staticpro (&Qframe_tty_type
);
3084 defsubr (&Stty_display_color_p
);
3085 defsubr (&Stty_display_color_cells
);
3086 defsubr (&Sframe_tty_name
);
3087 defsubr (&Sframe_tty_type
);
3088 defsubr (&Sdelete_tty
);
3090 Fprovide (intern ("multi-tty"), Qnil
);
3096 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
3097 (do not change this comment) */