1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001,
3 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
31 #include <unistd.h> /* For isatty. */
34 #include <termios.h> /* For TIOCNOTTY. */
47 #include "termhooks.h"
48 #include "dispextern.h"
51 #include "syssignal.h"
54 /* For now, don't try to include termcap.h. On some systems,
55 configure finds a non-standard termcap.h that the main build
58 #if defined HAVE_TERMCAP_H && 0
61 extern void tputs
P_ ((const char *, int, int (*)(int)));
62 extern int tgetent
P_ ((char *, const char *));
63 extern int tgetflag
P_ ((char *id
));
64 extern int tgetnum
P_ ((char *id
));
83 static void tty_set_scroll_region
P_ ((struct frame
*f
, int start
, int stop
));
84 static void turn_on_face
P_ ((struct frame
*, int face_id
));
85 static void turn_off_face
P_ ((struct frame
*, int face_id
));
86 static void tty_show_cursor
P_ ((struct tty_display_info
*));
87 static void tty_hide_cursor
P_ ((struct tty_display_info
*));
88 static void tty_background_highlight
P_ ((struct tty_display_info
*tty
));
89 static void dissociate_if_controlling_tty
P_ ((int fd
));
90 static void delete_tty
P_ ((struct terminal
*));
92 #define OUTPUT(tty, a) \
93 emacs_tputs ((tty), a, \
94 (int) (FRAME_LINES (XFRAME (selected_frame)) \
98 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
99 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
101 #define OUTPUT_IF(tty, a) \
104 emacs_tputs ((tty), a, \
105 (int) (FRAME_LINES (XFRAME (selected_frame)) \
110 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
112 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */
114 static int visible_cursor
;
116 /* Display space properties */
118 extern Lisp_Object Qspace
, QCalign_to
, QCwidth
;
120 /* Functions to call after suspending a tty. */
121 Lisp_Object Vsuspend_tty_functions
;
123 /* Functions to call after resuming a tty. */
124 Lisp_Object Vresume_tty_functions
;
126 /* Chain of all tty device parameters. */
127 struct tty_display_info
*tty_list
;
129 /* Nonzero means no need to redraw the entire frame on resuming a
130 suspended Emacs. This is useful on terminals with multiple
131 pages, where one page is used for Emacs and another for all
133 int no_redraw_on_reenter
;
135 /* Meaning of bits in no_color_video. Each bit set means that the
136 corresponding attribute cannot be combined with colors. */
140 NC_STANDOUT
= 1 << 0,
141 NC_UNDERLINE
= 1 << 1,
148 NC_ALT_CHARSET
= 1 << 8
153 /* The largest frame width in any call to calculate_costs. */
157 /* The largest frame height in any call to calculate_costs. */
161 /* Non-zero if we have dropped our controlling tty and therefore
162 should not open a frame on stdout. */
163 static int no_controlling_tty
;
165 /* Provided for lisp packages. */
167 static int system_uses_terminfo
;
171 extern char *tgetstr ();
175 /* We aren't X windows, but we aren't termcap either. This makes me
176 uncertain as to what value to use for frame.output_method. For
177 this file, we'll define FRAME_TERMCAP_P to be zero so that our
178 output hooks get called instead of the termcap functions. Probably
179 the best long-term solution is to define an output_windows_nt... */
181 #undef FRAME_TERMCAP_P
182 #define FRAME_TERMCAP_P(_f_) 0
183 #endif /* WINDOWSNT */
186 /* Ring the bell on a tty. */
189 tty_ring_bell (struct frame
*f
)
191 struct tty_display_info
*tty
= FRAME_TTY (f
);
195 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
196 ? tty
->TS_visible_bell
198 fflush (tty
->output
);
202 /* Set up termcap modes for Emacs. */
205 tty_set_terminal_modes (struct terminal
*terminal
)
207 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
211 if (tty
->TS_termcap_modes
)
212 OUTPUT (tty
, tty
->TS_termcap_modes
);
215 /* Output enough newlines to scroll all the old screen contents
216 off the screen, so it won't be overwritten and lost. */
219 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
223 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
224 OUTPUT_IF (tty
, visible_cursor
? tty
->TS_cursor_visible
: tty
->TS_cursor_normal
);
225 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
227 fflush (tty
->output
);
231 /* Reset termcap modes before exiting Emacs. */
234 tty_reset_terminal_modes (struct terminal
*terminal
)
236 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
240 tty_turn_off_highlight (tty
);
241 tty_turn_off_insert (tty
);
242 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
243 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
244 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
245 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
246 /* Output raw CR so kernel can track the cursor hpos. */
249 fflush (tty
->output
);
253 /* Flag the end of a display update on a termcap terminal. */
256 tty_update_end (struct frame
*f
)
258 struct tty_display_info
*tty
= FRAME_TTY (f
);
260 if (!XWINDOW (selected_window
)->cursor_off_p
)
261 tty_show_cursor (tty
);
262 tty_turn_off_insert (tty
);
263 tty_background_highlight (tty
);
266 /* The implementation of set_terminal_window for termcap frames. */
269 tty_set_terminal_window (struct frame
*f
, int size
)
271 struct tty_display_info
*tty
= FRAME_TTY (f
);
273 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
274 if (FRAME_SCROLL_REGION_OK (f
))
275 tty_set_scroll_region (f
, 0, tty
->specified_window
);
279 tty_set_scroll_region (struct frame
*f
, int start
, int stop
)
282 struct tty_display_info
*tty
= FRAME_TTY (f
);
284 if (tty
->TS_set_scroll_region
)
285 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
286 else if (tty
->TS_set_scroll_region_1
)
287 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
288 FRAME_LINES (f
), start
,
289 FRAME_LINES (f
) - stop
,
292 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
301 tty_turn_on_insert (struct tty_display_info
*tty
)
303 if (!tty
->insert_mode
)
304 OUTPUT (tty
, tty
->TS_insert_mode
);
305 tty
->insert_mode
= 1;
309 tty_turn_off_insert (struct tty_display_info
*tty
)
311 if (tty
->insert_mode
)
312 OUTPUT (tty
, tty
->TS_end_insert_mode
);
313 tty
->insert_mode
= 0;
316 /* Handle highlighting. */
319 tty_turn_off_highlight (struct tty_display_info
*tty
)
321 if (tty
->standout_mode
)
322 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
323 tty
->standout_mode
= 0;
327 tty_turn_on_highlight (struct tty_display_info
*tty
)
329 if (!tty
->standout_mode
)
330 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
331 tty
->standout_mode
= 1;
335 tty_toggle_highlight (struct tty_display_info
*tty
)
337 if (tty
->standout_mode
)
338 tty_turn_off_highlight (tty
);
340 tty_turn_on_highlight (tty
);
344 /* Make cursor invisible. */
347 tty_hide_cursor (struct tty_display_info
*tty
)
349 if (tty
->cursor_hidden
== 0)
351 tty
->cursor_hidden
= 1;
352 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
357 /* Ensure that cursor is visible. */
360 tty_show_cursor (struct tty_display_info
*tty
)
362 if (tty
->cursor_hidden
)
364 tty
->cursor_hidden
= 0;
365 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
367 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
372 /* Set standout mode to the state it should be in for
373 empty space inside windows. What this is,
374 depends on the user option inverse-video. */
377 tty_background_highlight (struct tty_display_info
*tty
)
380 tty_turn_on_highlight (tty
);
382 tty_turn_off_highlight (tty
);
385 /* Set standout mode to the mode specified for the text to be output. */
388 tty_highlight_if_desired (struct tty_display_info
*tty
)
391 tty_turn_on_highlight (tty
);
393 tty_turn_off_highlight (tty
);
397 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
398 frame-relative coordinates. */
401 tty_cursor_to (struct frame
*f
, int vpos
, int hpos
)
403 struct tty_display_info
*tty
= FRAME_TTY (f
);
405 /* Detect the case where we are called from reset_sys_modes
406 and the costs have never been calculated. Do nothing. */
407 if (! tty
->costs_set
)
410 if (curY (tty
) == vpos
411 && curX (tty
) == hpos
)
413 if (!tty
->TF_standout_motion
)
414 tty_background_highlight (tty
);
415 if (!tty
->TF_insmode_motion
)
416 tty_turn_off_insert (tty
);
417 cmgoto (tty
, vpos
, hpos
);
420 /* Similar but don't take any account of the wasted characters. */
423 tty_raw_cursor_to (struct frame
*f
, int row
, int col
)
425 struct tty_display_info
*tty
= FRAME_TTY (f
);
427 if (curY (tty
) == row
428 && curX (tty
) == col
)
430 if (!tty
->TF_standout_motion
)
431 tty_background_highlight (tty
);
432 if (!tty
->TF_insmode_motion
)
433 tty_turn_off_insert (tty
);
434 cmgoto (tty
, row
, col
);
437 /* Erase operations */
439 /* Clear from cursor to end of frame on a termcap device. */
442 tty_clear_to_end (struct frame
*f
)
445 struct tty_display_info
*tty
= FRAME_TTY (f
);
447 if (tty
->TS_clr_to_bottom
)
449 tty_background_highlight (tty
);
450 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
454 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
457 clear_end_of_line (f
, FRAME_COLS (f
));
462 /* Clear an entire termcap frame. */
465 tty_clear_frame (struct frame
*f
)
467 struct tty_display_info
*tty
= FRAME_TTY (f
);
469 if (tty
->TS_clr_frame
)
471 tty_background_highlight (tty
);
472 OUTPUT (tty
, tty
->TS_clr_frame
);
482 /* An implementation of clear_end_of_line for termcap frames.
484 Note that the cursor may be moved, on terminals lacking a `ce' string. */
487 tty_clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
490 struct tty_display_info
*tty
= FRAME_TTY (f
);
492 /* Detect the case where we are called from reset_sys_modes
493 and the costs have never been calculated. Do nothing. */
494 if (! tty
->costs_set
)
497 if (curX (tty
) >= first_unused_hpos
)
499 tty_background_highlight (tty
);
500 if (tty
->TS_clr_line
)
502 OUTPUT1 (tty
, tty
->TS_clr_line
);
505 { /* have to do it the hard way */
506 tty_turn_off_insert (tty
);
508 /* Do not write in last row last col with Auto-wrap on. */
510 && curY (tty
) == FrameRows (tty
) - 1
511 && first_unused_hpos
== FrameCols (tty
))
514 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
517 fputc (' ', tty
->termscript
);
518 fputc (' ', tty
->output
);
520 cmplus (tty
, first_unused_hpos
- curX (tty
));
524 /* Buffer to store the source and result of code conversion for terminal. */
525 static unsigned char *encode_terminal_buf
;
526 /* Allocated size of the above buffer. */
527 static int encode_terminal_bufsize
;
529 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
530 Set CODING->produced to the byte-length of the resulting byte
531 sequence, and return a pointer to that byte sequence. */
534 encode_terminal_code (src
, src_len
, coding
)
537 struct coding_system
*coding
;
539 struct glyph
*src_end
= src
+ src_len
;
542 int nchars
, nbytes
, required
;
543 register int tlen
= GLYPH_TABLE_LENGTH
;
544 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
546 /* Allocate sufficient size of buffer to store all characters in
547 multibyte-form. But, it may be enlarged on demand if
548 Vglyph_table contains a string. */
549 required
= MAX_MULTIBYTE_LENGTH
* src_len
;
550 if (encode_terminal_bufsize
< required
)
552 if (encode_terminal_bufsize
== 0)
553 encode_terminal_buf
= xmalloc (required
);
555 encode_terminal_buf
= xrealloc (encode_terminal_buf
, required
);
556 encode_terminal_bufsize
= required
;
559 buf
= encode_terminal_buf
;
561 while (src
< src_end
)
563 /* We must skip glyphs to be padded for a wide character. */
564 if (! CHAR_GLYPH_PADDING_P (*src
))
566 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
568 if (g
< 0 || g
>= tlen
)
570 /* This glyph doesn't has an entry in Vglyph_table. */
571 if (CHAR_VALID_P (src
->u
.ch
, 0))
572 buf
+= CHAR_STRING (src
->u
.ch
, buf
);
579 /* This glyph has an entry in Vglyph_table,
580 so process any alias before testing for simpleness. */
581 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
583 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
585 int c
= FAST_GLYPH_CHAR (g
);
587 if (CHAR_VALID_P (c
, 0))
588 buf
+= CHAR_STRING (c
, buf
);
595 /* We have a string in Vglyph_table. */
599 if (! STRING_MULTIBYTE (string
))
600 string
= string_to_multibyte (string
);
601 nbytes
= buf
- encode_terminal_buf
;
602 if (encode_terminal_bufsize
< nbytes
+ SBYTES (string
))
604 encode_terminal_bufsize
= nbytes
+ SBYTES (string
);
605 encode_terminal_buf
= xrealloc (encode_terminal_buf
,
606 encode_terminal_bufsize
);
607 buf
= encode_terminal_buf
+ nbytes
;
609 bcopy (SDATA (string
), buf
, SBYTES (string
));
610 buf
+= SBYTES (string
);
611 nchars
+= SCHARS (string
);
618 nbytes
= buf
- encode_terminal_buf
;
619 coding
->src_multibyte
= 1;
620 coding
->dst_multibyte
= 0;
621 if (SYMBOLP (coding
->pre_write_conversion
)
622 && ! NILP (Ffboundp (coding
->pre_write_conversion
)))
624 run_pre_write_conversin_on_c_str (&encode_terminal_buf
,
625 &encode_terminal_bufsize
,
626 nchars
, nbytes
, coding
);
627 nchars
= coding
->produced_char
;
628 nbytes
= coding
->produced
;
630 required
= nbytes
+ encoding_buffer_size (coding
, nbytes
);
631 if (encode_terminal_bufsize
< required
)
633 encode_terminal_bufsize
= required
;
634 encode_terminal_buf
= xrealloc (encode_terminal_buf
, required
);
637 encode_coding (coding
, encode_terminal_buf
, encode_terminal_buf
+ nbytes
,
638 nbytes
, encode_terminal_bufsize
- nbytes
);
639 return encode_terminal_buf
+ nbytes
;
643 /* An implementation of write_glyphs for termcap frames. */
646 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
648 unsigned char *conversion_buffer
;
649 struct coding_system
*coding
;
651 struct tty_display_info
*tty
= FRAME_TTY (f
);
653 tty_turn_off_insert (tty
);
654 tty_hide_cursor (tty
);
656 /* Don't dare write in last column of bottom line, if Auto-Wrap,
657 since that would scroll the whole frame on some terminals. */
660 && curY (tty
) + 1 == FRAME_LINES (f
)
661 && (curX (tty
) + len
) == FRAME_COLS (f
))
668 /* If terminal_coding does any conversion, use it, otherwise use
669 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
670 because it always return 1 if the member src_multibyte is 1. */
671 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
672 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
673 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
675 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
679 /* Identify a run of glyphs with the same face. */
680 int face_id
= string
->face_id
;
683 for (n
= 1; n
< len
; ++n
)
684 if (string
[n
].face_id
!= face_id
)
687 /* Turn appearance modes of the face of the run on. */
688 tty_highlight_if_desired (tty
);
689 turn_on_face (f
, face_id
);
692 /* This is the last run. */
693 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
694 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
695 if (coding
->produced
> 0)
697 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
698 if (ferror (tty
->output
))
699 clearerr (tty
->output
);
701 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
706 /* Turn appearance modes off. */
707 turn_off_face (f
, face_id
);
708 tty_turn_off_highlight (tty
);
714 /* An implementation of insert_glyphs for termcap frames. */
717 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
720 struct glyph
*glyph
= NULL
;
721 unsigned char *conversion_buffer
;
722 unsigned char space
[1];
723 struct coding_system
*coding
;
725 struct tty_display_info
*tty
= FRAME_TTY (f
);
727 if (tty
->TS_ins_multi_chars
)
729 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
733 write_glyphs (f
, start
, len
);
737 tty_turn_on_insert (tty
);
741 space
[0] = SPACEGLYPH
;
743 /* If terminal_coding does any conversion, use it, otherwise use
744 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
745 because it always return 1 if the member src_multibyte is 1. */
746 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
747 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
748 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
750 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
754 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
757 conversion_buffer
= space
;
758 coding
->produced
= 1;
762 tty_highlight_if_desired (tty
);
763 turn_on_face (f
, start
->face_id
);
766 /* We must open sufficient space for a character which
767 occupies more than one column. */
768 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
770 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
775 /* This is the last glyph. */
776 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
778 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
781 if (coding
->produced
> 0)
783 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
784 if (ferror (tty
->output
))
785 clearerr (tty
->output
);
787 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
790 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
793 turn_off_face (f
, glyph
->face_id
);
794 tty_turn_off_highlight (tty
);
801 /* An implementation of delete_glyphs for termcap frames. */
804 tty_delete_glyphs (struct frame
*f
, int n
)
809 struct tty_display_info
*tty
= FRAME_TTY (f
);
811 if (tty
->delete_in_insert_mode
)
813 tty_turn_on_insert (tty
);
817 tty_turn_off_insert (tty
);
818 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
821 if (tty
->TS_del_multi_chars
)
823 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
828 for (i
= 0; i
< n
; i
++)
829 OUTPUT1 (tty
, tty
->TS_del_char
);
830 if (!tty
->delete_in_insert_mode
)
831 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
834 /* An implementation of ins_del_lines for termcap frames. */
837 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
839 struct tty_display_info
*tty
= FRAME_TTY (f
);
840 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
841 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
842 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
844 register int i
= n
> 0 ? n
: -n
;
847 /* If the lines below the insertion are being pushed
848 into the end of the window, this is the same as clearing;
849 and we know the lines are already clear, since the matching
850 deletion has already been done. So can ignore this. */
851 /* If the lines below the deletion are blank lines coming
852 out of the end of the window, don't bother,
853 as there will be a matching inslines later that will flush them. */
854 if (FRAME_SCROLL_REGION_OK (f
)
855 && vpos
+ i
>= tty
->specified_window
)
857 if (!FRAME_MEMORY_BELOW_FRAME (f
)
858 && vpos
+ i
>= FRAME_LINES (f
))
863 raw_cursor_to (f
, vpos
, 0);
864 tty_background_highlight (tty
);
865 buf
= tparam (multi
, 0, 0, i
);
871 raw_cursor_to (f
, vpos
, 0);
872 tty_background_highlight (tty
);
874 OUTPUT (tty
, single
);
880 tty_set_scroll_region (f
, vpos
, tty
->specified_window
);
882 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
884 raw_cursor_to (f
, vpos
, 0);
885 tty_background_highlight (tty
);
887 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
888 tty_set_scroll_region (f
, 0, tty
->specified_window
);
891 if (!FRAME_SCROLL_REGION_OK (f
)
892 && FRAME_MEMORY_BELOW_FRAME (f
)
895 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
900 /* Compute cost of sending "str", in characters,
901 not counting any line-dependent padding. */
904 string_cost (char *str
)
908 tputs (str
, 0, evalcost
);
912 /* Compute cost of sending "str", in characters,
913 counting any line-dependent padding at one line. */
916 string_cost_one_line (char *str
)
920 tputs (str
, 1, evalcost
);
924 /* Compute per line amount of line-dependent padding,
925 in tenths of characters. */
928 per_line_cost (char *str
)
932 tputs (str
, 0, evalcost
);
935 tputs (str
, 10, evalcost
);
940 /* char_ins_del_cost[n] is cost of inserting N characters.
941 char_ins_del_cost[-n] is cost of deleting N characters.
942 The length of this vector is based on max_frame_cols. */
944 int *char_ins_del_vector
;
946 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
951 calculate_ins_del_char_costs (struct frame
*f
)
953 struct tty_display_info
*tty
= FRAME_TTY (f
);
954 int ins_startup_cost
, del_startup_cost
;
955 int ins_cost_per_char
, del_cost_per_char
;
959 if (tty
->TS_ins_multi_chars
)
961 ins_cost_per_char
= 0;
962 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
964 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
965 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
967 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
968 + string_cost (tty
->TS_end_insert_mode
))) / 100;
969 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
970 + string_cost_one_line (tty
->TS_pad_inserted_char
));
974 ins_startup_cost
= 9999;
975 ins_cost_per_char
= 0;
978 if (tty
->TS_del_multi_chars
)
980 del_cost_per_char
= 0;
981 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
983 else if (tty
->TS_del_char
)
985 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
986 + string_cost (tty
->TS_end_delete_mode
));
987 if (tty
->delete_in_insert_mode
)
988 del_startup_cost
/= 2;
989 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
993 del_startup_cost
= 9999;
994 del_cost_per_char
= 0;
997 /* Delete costs are at negative offsets */
998 p
= &char_ins_del_cost (f
)[0];
999 for (i
= FRAME_COLS (f
); --i
>= 0;)
1000 *--p
= (del_startup_cost
+= del_cost_per_char
);
1002 /* Doing nothing is free */
1003 p
= &char_ins_del_cost (f
)[0];
1006 /* Insert costs are at positive offsets */
1007 for (i
= FRAME_COLS (f
); --i
>= 0;)
1008 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1012 calculate_costs (struct frame
*frame
)
1014 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1016 if (FRAME_TERMCAP_P (frame
))
1018 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1019 register char *f
= (tty
->TS_set_scroll_region
1020 ? tty
->TS_set_scroll_region
1021 : tty
->TS_set_scroll_region_1
);
1023 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1027 /* These variables are only used for terminal stuff. They are
1028 allocated once for the terminal frame of X-windows emacs, but not
1031 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1032 X turns off char_ins_del_ok. */
1034 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1035 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1037 if (char_ins_del_vector
!= 0)
1039 = (int *) xrealloc (char_ins_del_vector
,
1041 + 2 * max_frame_cols
* sizeof (int)));
1044 = (int *) xmalloc (sizeof (int)
1045 + 2 * max_frame_cols
* sizeof (int));
1047 bzero (char_ins_del_vector
, (sizeof (int)
1048 + 2 * max_frame_cols
* sizeof (int)));
1051 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1052 do_line_insertion_deletion_costs (frame
,
1053 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1054 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1057 do_line_insertion_deletion_costs (frame
,
1058 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1059 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1062 calculate_ins_del_char_costs (frame
);
1064 /* Don't use TS_repeat if its padding is worse than sending the chars */
1065 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1066 tty
->RPov
= string_cost (tty
->TS_repeat
);
1068 tty
->RPov
= FRAME_COLS (frame
) * 2;
1070 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1078 /* Termcap capability names that correspond directly to X keysyms.
1079 Some of these (marked "terminfo") aren't supplied by old-style
1080 (Berkeley) termcap entries. They're listed in X keysym order;
1081 except we put the keypad keys first, so that if they clash with
1082 other keys (as on the IBM PC keyboard) they get overridden.
1085 static struct fkey_table keys
[] =
1087 {"kh", "home"}, /* termcap */
1088 {"kl", "left"}, /* termcap */
1089 {"ku", "up"}, /* termcap */
1090 {"kr", "right"}, /* termcap */
1091 {"kd", "down"}, /* termcap */
1092 {"%8", "prior"}, /* terminfo */
1093 {"%5", "next"}, /* terminfo */
1094 {"@7", "end"}, /* terminfo */
1095 {"@1", "begin"}, /* terminfo */
1096 {"*6", "select"}, /* terminfo */
1097 {"%9", "print"}, /* terminfo */
1098 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1100 * "insert" --- see below
1102 {"&8", "undo"}, /* terminfo */
1103 {"%0", "redo"}, /* terminfo */
1104 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1105 {"@0", "find"}, /* terminfo */
1106 {"@2", "cancel"}, /* terminfo */
1107 {"%1", "help"}, /* terminfo */
1109 * "break" goes here, but can't be reliably intercepted with termcap
1111 {"&4", "reset"}, /* terminfo --- actually `restart' */
1113 * "system" and "user" --- no termcaps
1115 {"kE", "clearline"}, /* terminfo */
1116 {"kA", "insertline"}, /* terminfo */
1117 {"kL", "deleteline"}, /* terminfo */
1118 {"kI", "insertchar"}, /* terminfo */
1119 {"kD", "deletechar"}, /* terminfo */
1120 {"kB", "backtab"}, /* terminfo */
1122 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1124 {"@8", "kp-enter"}, /* terminfo */
1126 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1127 * "kp-multiply", "kp-add", "kp-separator",
1128 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1129 * --- no termcaps for any of these.
1131 {"K4", "kp-1"}, /* terminfo */
1133 * "kp-2" --- no termcap
1135 {"K5", "kp-3"}, /* terminfo */
1137 * "kp-4" --- no termcap
1139 {"K2", "kp-5"}, /* terminfo */
1141 * "kp-6" --- no termcap
1143 {"K1", "kp-7"}, /* terminfo */
1145 * "kp-8" --- no termcap
1147 {"K3", "kp-9"}, /* terminfo */
1149 * "kp-equal" --- no termcap
1161 {"&0", "S-cancel"}, /*shifted cancel key*/
1162 {"&9", "S-begin"}, /*shifted begin key*/
1163 {"*0", "S-find"}, /*shifted find key*/
1164 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1165 {"*4", "S-delete"}, /*shifted delete-character key*/
1166 {"*7", "S-end"}, /*shifted end key*/
1167 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1168 {"#1", "S-help"}, /*shifted help key*/
1169 {"#2", "S-home"}, /*shifted home key*/
1170 {"#3", "S-insert"}, /*shifted insert-character key*/
1171 {"#4", "S-left"}, /*shifted left-arrow key*/
1172 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1173 {"%c", "S-next"}, /*shifted next key*/
1174 {"%e", "S-prior"}, /*shifted previous key*/
1175 {"%f", "S-print"}, /*shifted print key*/
1176 {"%g", "S-redo"}, /*shifted redo key*/
1177 {"%i", "S-right"}, /*shifted right-arrow key*/
1178 {"!3", "S-undo"} /*shifted undo key*/
1181 static char **term_get_fkeys_address
;
1182 static KBOARD
*term_get_fkeys_kboard
;
1183 static Lisp_Object
term_get_fkeys_1 ();
1185 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1186 This function scans the termcap function key sequence entries, and
1187 adds entries to Vfunction_key_map for each function key it finds. */
1190 term_get_fkeys (address
, kboard
)
1194 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1195 errors during the call. The only errors should be from Fdefine_key
1196 when given a key sequence containing an invalid prefix key. If the
1197 termcap defines function keys which use a prefix that is already bound
1198 to a command by the default bindings, we should silently ignore that
1199 function key specification, rather than giving the user an error and
1200 refusing to run at all on such a terminal. */
1202 extern Lisp_Object
Fidentity ();
1203 term_get_fkeys_address
= address
;
1204 term_get_fkeys_kboard
= kboard
;
1205 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1213 char **address
= term_get_fkeys_address
;
1214 KBOARD
*kboard
= term_get_fkeys_kboard
;
1216 /* This can happen if CANNOT_DUMP or with strange options. */
1218 kboard
->Vlocal_function_key_map
= Fmake_sparse_keymap (Qnil
);
1220 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1222 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1224 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (sequence
),
1225 Fmake_vector (make_number (1),
1226 intern (keys
[i
].name
)));
1229 /* The uses of the "k0" capability are inconsistent; sometimes it
1230 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1231 We will attempt to politely accommodate both systems by testing for
1232 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1235 char *k_semi
= tgetstr ("k;", address
);
1236 char *k0
= tgetstr ("k0", address
);
1237 char *k0_name
= "f10";
1242 /* Define f0 first, so that f10 takes precedence in case the
1243 key sequences happens to be the same. */
1244 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (k0
),
1245 Fmake_vector (make_number (1), intern ("f0")));
1246 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (k_semi
),
1247 Fmake_vector (make_number (1), intern ("f10")));
1250 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (k0
),
1251 Fmake_vector (make_number (1), intern (k0_name
)));
1254 /* Set up cookies for numbered function keys above f10. */
1256 char fcap
[3], fkey
[4];
1258 fcap
[0] = 'F'; fcap
[2] = '\0';
1259 for (i
= 11; i
< 64; i
++)
1262 fcap
[1] = '1' + i
- 11;
1264 fcap
[1] = 'A' + i
- 20;
1266 fcap
[1] = 'a' + i
- 46;
1269 char *sequence
= tgetstr (fcap
, address
);
1272 sprintf (fkey
, "f%d", i
);
1273 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (sequence
),
1274 Fmake_vector (make_number (1),
1282 * Various mappings to try and get a better fit.
1285 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1286 if (!tgetstr (cap1, address)) \
1288 char *sequence = tgetstr (cap2, address); \
1290 Fdefine_key (kboard->Vlocal_function_key_map, build_string (sequence), \
1291 Fmake_vector (make_number (1), \
1295 /* if there's no key_next keycap, map key_npage to `next' keysym */
1296 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1297 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1298 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1299 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1300 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1301 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1302 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1304 /* IBM has their own non-standard dialect of terminfo.
1305 If the standard name isn't found, try the IBM name. */
1306 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1307 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1308 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1309 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1310 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1311 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1312 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1313 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1314 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1315 #undef CONDITIONAL_REASSIGN
1322 /***********************************************************************
1323 Character Display Information
1324 ***********************************************************************/
1326 static void append_glyph
P_ ((struct it
*));
1327 static void produce_stretch_glyph
P_ ((struct it
*));
1330 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1331 terminal frames if IT->glyph_row != NULL. IT->c is the character
1332 for which to produce glyphs; IT->face_id contains the character's
1333 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1340 struct glyph
*glyph
, *end
;
1343 xassert (it
->glyph_row
);
1344 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1345 + it
->glyph_row
->used
[it
->area
]);
1346 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1349 i
< it
->pixel_width
&& glyph
< end
;
1352 glyph
->type
= CHAR_GLYPH
;
1353 glyph
->pixel_width
= 1;
1354 glyph
->u
.ch
= it
->c
;
1355 glyph
->face_id
= it
->face_id
;
1356 glyph
->padding_p
= i
> 0;
1357 glyph
->charpos
= CHARPOS (it
->position
);
1358 glyph
->object
= it
->object
;
1360 ++it
->glyph_row
->used
[it
->area
];
1366 /* Produce glyphs for the display element described by IT. *IT
1367 specifies what we want to produce a glyph for (character, image, ...),
1368 and where in the glyph matrix we currently are (glyph row and hpos).
1369 produce_glyphs fills in output fields of *IT with information such as the
1370 pixel width and height of a character, and maybe output actual glyphs at
1371 the same time if IT->glyph_row is non-null. See the explanation of
1372 struct display_iterator in dispextern.h for an overview.
1374 produce_glyphs also stores the result of glyph width, ascent
1375 etc. computations in *IT.
1377 IT->glyph_row may be null, in which case produce_glyphs does not
1378 actually fill in the glyphs. This is used in the move_* functions
1379 in xdisp.c for text width and height computations.
1381 Callers usually don't call produce_glyphs directly;
1382 instead they use the macro PRODUCE_GLYPHS. */
1388 /* If a hook is installed, let it do the work. */
1389 xassert (it
->what
== IT_CHARACTER
1390 || it
->what
== IT_COMPOSITION
1391 || it
->what
== IT_STRETCH
);
1393 if (it
->what
== IT_STRETCH
)
1395 produce_stretch_glyph (it
);
1399 /* Nothing but characters are supported on terminal frames. For a
1400 composition sequence, it->c is the first character of the
1402 xassert (it
->what
== IT_CHARACTER
1403 || it
->what
== IT_COMPOSITION
);
1405 if (it
->c
>= 040 && it
->c
< 0177)
1407 it
->pixel_width
= it
->nglyphs
= 1;
1411 else if (it
->c
== '\n')
1412 it
->pixel_width
= it
->nglyphs
= 0;
1413 else if (it
->c
== '\t')
1415 int absolute_x
= (it
->current_x
1416 + it
->continuation_lines_width
);
1418 = (((1 + absolute_x
+ it
->tab_width
- 1)
1423 /* If part of the TAB has been displayed on the previous line
1424 which is continued now, continuation_lines_width will have
1425 been incremented already by the part that fitted on the
1426 continued line. So, we will get the right number of spaces
1428 nspaces
= next_tab_x
- absolute_x
;
1435 it
->pixel_width
= it
->len
= 1;
1443 it
->pixel_width
= nspaces
;
1444 it
->nglyphs
= nspaces
;
1446 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1448 /* Coming here means that it->c is from display table, thus we
1449 must send the code as is to the terminal. Although there's
1450 no way to know how many columns it occupies on a screen, it
1451 is a good assumption that a single byte code has 1-column
1453 it
->pixel_width
= it
->nglyphs
= 1;
1459 /* A multi-byte character. The display width is fixed for all
1460 characters of the set. Some of the glyphs may have to be
1461 ignored because they are already displayed in a continued
1463 int charset
= CHAR_CHARSET (it
->c
);
1465 it
->pixel_width
= CHARSET_WIDTH (charset
);
1466 it
->nglyphs
= it
->pixel_width
;
1473 /* Advance current_x by the pixel width as a convenience for
1475 if (it
->area
== TEXT_AREA
)
1476 it
->current_x
+= it
->pixel_width
;
1477 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1478 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1482 /* Produce a stretch glyph for iterator IT. IT->object is the value
1483 of the glyph property displayed. The value must be a list
1484 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1487 1. `:width WIDTH' specifies that the space should be WIDTH *
1488 canonical char width wide. WIDTH may be an integer or floating
1491 2. `:align-to HPOS' specifies that the space should be wide enough
1492 to reach HPOS, a value in canonical character units. */
1495 produce_stretch_glyph (it
)
1498 /* (space :width WIDTH ...) */
1499 Lisp_Object prop
, plist
;
1500 int width
= 0, align_to
= -1;
1501 int zero_width_ok_p
= 0;
1504 /* List should start with `space'. */
1505 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1506 plist
= XCDR (it
->object
);
1508 /* Compute the width of the stretch. */
1509 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1510 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1512 /* Absolute width `:width WIDTH' specified and valid. */
1513 zero_width_ok_p
= 1;
1514 width
= (int)(tem
+ 0.5);
1516 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1517 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1519 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1520 align_to
= (align_to
< 0
1522 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1523 else if (align_to
< 0)
1524 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1525 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1526 zero_width_ok_p
= 1;
1529 /* Nothing specified -> width defaults to canonical char width. */
1530 width
= FRAME_COLUMN_WIDTH (it
->f
);
1532 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1535 if (width
> 0 && it
->glyph_row
)
1537 Lisp_Object o_object
= it
->object
;
1538 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1542 if (!STRINGP (object
))
1543 object
= it
->w
->buffer
;
1544 it
->object
= object
;
1546 it
->pixel_width
= it
->len
= 1;
1549 it
->object
= o_object
;
1552 it
->pixel_width
= width
;
1553 it
->nglyphs
= width
;
1557 /* Get information about special display element WHAT in an
1558 environment described by IT. WHAT is one of IT_TRUNCATION or
1559 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1560 non-null glyph_row member. This function ensures that fields like
1561 face_id, c, len of IT are left untouched. */
1564 produce_special_glyphs (it
, what
)
1566 enum display_element_type what
;
1573 temp_it
.what
= IT_CHARACTER
;
1575 temp_it
.object
= make_number (0);
1576 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1578 if (what
== IT_CONTINUATION
)
1580 /* Continuation glyph. */
1582 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1583 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1585 glyph
= XINT (DISP_CONTINUE_GLYPH (it
->dp
));
1586 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
1591 else if (what
== IT_TRUNCATION
)
1593 /* Truncation glyph. */
1595 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1596 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1598 glyph
= XINT (DISP_TRUNC_GLYPH (it
->dp
));
1599 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
1607 temp_it
.c
= FAST_GLYPH_CHAR (glyph
);
1608 temp_it
.face_id
= FAST_GLYPH_FACE (glyph
);
1609 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1611 produce_glyphs (&temp_it
);
1612 it
->pixel_width
= temp_it
.pixel_width
;
1613 it
->nglyphs
= temp_it
.pixel_width
;
1618 /***********************************************************************
1620 ***********************************************************************/
1622 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1623 one of the enumerators from enum no_color_bit, or a bit set built
1624 from them. Some display attributes may not be used together with
1625 color; the termcap capability `NC' specifies which ones. */
1627 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1628 (tty->TN_max_colors > 0 \
1629 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1632 /* Turn appearances of face FACE_ID on tty frame F on.
1633 FACE_ID is a realized face ID number, in the face cache. */
1636 turn_on_face (f
, face_id
)
1640 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1641 long fg
= face
->foreground
;
1642 long bg
= face
->background
;
1643 struct tty_display_info
*tty
= FRAME_TTY (f
);
1645 /* Do this first because TS_end_standout_mode may be the same
1646 as TS_exit_attribute_mode, which turns all appearances off. */
1647 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1649 if (tty
->TN_max_colors
> 0)
1651 if (fg
>= 0 && bg
>= 0)
1653 /* If the terminal supports colors, we can set them
1654 below without using reverse video. The face's fg
1655 and bg colors are set as they should appear on
1656 the screen, i.e. they take the inverse-video'ness
1657 of the face already into account. */
1659 else if (inverse_video
)
1661 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1662 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1663 tty_toggle_highlight (tty
);
1667 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1668 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1669 tty_toggle_highlight (tty
);
1674 /* If we can't display colors, use reverse video
1675 if the face specifies that. */
1678 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1679 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1680 tty_toggle_highlight (tty
);
1684 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1685 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1686 tty_toggle_highlight (tty
);
1691 if (face
->tty_bold_p
)
1693 if (MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1694 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1696 else if (face
->tty_dim_p
)
1697 if (MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1698 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1700 /* Alternate charset and blinking not yet used. */
1701 if (face
->tty_alt_charset_p
1702 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1703 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1705 if (face
->tty_blinking_p
1706 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1707 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1709 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1710 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1712 if (tty
->TN_max_colors
> 0)
1716 ts
= tty
->standout_mode
? tty
->TS_set_background
: tty
->TS_set_foreground
;
1719 p
= tparam (ts
, NULL
, 0, (int) fg
);
1724 ts
= tty
->standout_mode
? tty
->TS_set_foreground
: tty
->TS_set_background
;
1727 p
= tparam (ts
, NULL
, 0, (int) bg
);
1735 /* Turn off appearances of face FACE_ID on tty frame F. */
1738 turn_off_face (f
, face_id
)
1742 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1743 struct tty_display_info
*tty
= FRAME_TTY (f
);
1745 xassert (face
!= NULL
);
1747 if (tty
->TS_exit_attribute_mode
)
1749 /* Capability "me" will turn off appearance modes double-bright,
1750 half-bright, reverse-video, standout, underline. It may or
1751 may not turn off alt-char-mode. */
1752 if (face
->tty_bold_p
1754 || face
->tty_reverse_p
1755 || face
->tty_alt_charset_p
1756 || face
->tty_blinking_p
1757 || face
->tty_underline_p
)
1759 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
1760 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
1761 tty
->standout_mode
= 0;
1764 if (face
->tty_alt_charset_p
)
1765 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1769 /* If we don't have "me" we can only have those appearances
1770 that have exit sequences defined. */
1771 if (face
->tty_alt_charset_p
)
1772 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1774 if (face
->tty_underline_p
)
1775 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
1778 /* Switch back to default colors. */
1779 if (tty
->TN_max_colors
> 0
1780 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
1781 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
1782 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
1783 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
1784 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
1788 /* Return non-zero if the terminal on frame F supports all of the
1789 capabilities in CAPS simultaneously, with foreground and background
1790 colors FG and BG. */
1793 tty_capable_p (tty
, caps
, fg
, bg
)
1794 struct tty_display_info
*tty
;
1796 unsigned long fg
, bg
;
1798 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
1799 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
1802 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
1803 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
1804 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
1805 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
1806 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
1807 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
1813 /* Return non-zero if the terminal is capable to display colors. */
1815 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
1817 doc
: /* Return non-nil if the tty device TERMINAL can display colors.
1819 TERMINAL can be a terminal id, a frame or nil (meaning the selected
1820 frame's terminal). This function always returns nil if TERMINAL
1821 is not on a tty device. */)
1823 Lisp_Object terminal
;
1825 struct terminal
*t
= get_tty_terminal (terminal
);
1829 return t
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
1832 /* Return the number of supported colors. */
1833 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
1834 Stty_display_color_cells
, 0, 1, 0,
1835 doc
: /* Return the number of colors supported by the tty device TERMINAL.
1837 TERMINAL can be a terminal id, a frame or nil (meaning the selected
1838 frame's terminal). This function always returns nil if TERMINAL
1839 is not on a tty device. */)
1841 Lisp_Object terminal
;
1843 struct terminal
*t
= get_tty_terminal (terminal
);
1845 return make_number (0);
1847 return make_number (t
->display_info
.tty
->TN_max_colors
);
1852 /* Save or restore the default color-related capabilities of this
1855 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
1858 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
1859 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
1863 if (default_orig_pair
)
1864 xfree (default_orig_pair
);
1865 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
1867 if (default_set_foreground
)
1868 xfree (default_set_foreground
);
1869 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
1872 if (default_set_background
)
1873 xfree (default_set_background
);
1874 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
1877 default_max_colors
= tty
->TN_max_colors
;
1878 default_max_pairs
= tty
->TN_max_pairs
;
1879 default_no_color_video
= tty
->TN_no_color_video
;
1883 tty
->TS_orig_pair
= default_orig_pair
;
1884 tty
->TS_set_foreground
= default_set_foreground
;
1885 tty
->TS_set_background
= default_set_background
;
1886 tty
->TN_max_colors
= default_max_colors
;
1887 tty
->TN_max_pairs
= default_max_pairs
;
1888 tty
->TN_no_color_video
= default_no_color_video
;
1892 /* Setup one of the standard tty color schemes according to MODE.
1893 MODE's value is generally the number of colors which we want to
1894 support; zero means set up for the default capabilities, the ones
1895 we saw at init_tty time; -1 means turn off color support. */
1897 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
1899 /* Canonicalize all negative values of MODE. */
1905 case -1: /* no colors at all */
1906 tty
->TN_max_colors
= 0;
1907 tty
->TN_max_pairs
= 0;
1908 tty
->TN_no_color_video
= 0;
1909 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
1911 case 0: /* default colors, if any */
1913 tty_default_color_capabilities (tty
, 0);
1915 case 8: /* 8 standard ANSI colors */
1916 tty
->TS_orig_pair
= "\033[0m";
1918 tty
->TS_set_foreground
= "\033[3%p1%dm";
1919 tty
->TS_set_background
= "\033[4%p1%dm";
1921 tty
->TS_set_foreground
= "\033[3%dm";
1922 tty
->TS_set_background
= "\033[4%dm";
1924 tty
->TN_max_colors
= 8;
1925 tty
->TN_max_pairs
= 64;
1926 tty
->TN_no_color_video
= 0;
1932 set_tty_color_mode (f
, val
)
1936 Lisp_Object color_mode_spec
, current_mode_spec
;
1937 Lisp_Object color_mode
, current_mode
;
1939 extern Lisp_Object Qtty_color_mode
;
1940 Lisp_Object tty_color_mode_alist
;
1942 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
1949 if (NILP (tty_color_mode_alist
))
1950 color_mode_spec
= Qnil
;
1952 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
1954 if (CONSP (color_mode_spec
))
1955 color_mode
= XCDR (color_mode_spec
);
1960 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
1962 if (CONSP (current_mode_spec
))
1963 current_mode
= XCDR (current_mode_spec
);
1965 current_mode
= Qnil
;
1966 if (INTEGERP (color_mode
))
1967 mode
= XINT (color_mode
);
1969 mode
= 0; /* meaning default */
1970 if (INTEGERP (current_mode
))
1971 old_mode
= XINT (current_mode
);
1975 if (mode
!= old_mode
)
1977 tty_setup_colors (FRAME_TTY (f
), mode
);
1978 /* This recomputes all the faces given the new color
1980 call0 (intern ("tty-set-up-initial-frame-faces"));
1985 #endif /* !WINDOWSNT */
1989 /* Return the tty display object specified by TERMINAL. */
1992 get_tty_terminal (Lisp_Object terminal
)
1994 struct terminal
*t
= get_terminal (terminal
, 0);
1996 if (t
&& t
->type
== output_initial
)
1999 if (t
&& t
->type
!= output_termcap
)
2000 error ("Device %d is not a termcap terminal device", t
->id
);
2005 /* Return the active termcap device that uses the tty device with the
2006 given name. If NAME is NULL, return the device corresponding to
2007 our controlling terminal.
2009 This function ignores suspended devices.
2011 Returns NULL if the named terminal device is not opened. */
2014 get_named_tty (name
)
2019 for (t
= terminal_list
; t
; t
= t
->next_terminal
) {
2020 if (t
->type
== output_termcap
2021 && ((t
->display_info
.tty
->name
== 0 && name
== 0)
2022 || (name
&& t
->display_info
.tty
->name
2023 && !strcmp (t
->display_info
.tty
->name
, name
)))
2024 && TERMINAL_ACTIVE_P (t
))
2032 DEFUN ("tty-type", Ftty_type
, Stty_type
, 0, 1, 0,
2033 doc
: /* Return the type of the tty device that TERMINAL uses.
2035 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2036 frame's terminal). */)
2038 Lisp_Object terminal
;
2040 struct terminal
*t
= get_terminal (terminal
, 1);
2042 if (t
->type
!= output_termcap
)
2043 error ("Terminal %d is not a termcap terminal", t
->id
);
2045 if (t
->display_info
.tty
->type
)
2046 return build_string (t
->display_info
.tty
->type
);
2051 DEFUN ("controlling-tty-p", Fcontrolling_tty_p
, Scontrolling_tty_p
, 0, 1, 0,
2052 doc
: /* Return non-nil if TERMINAL is on the controlling tty of the Emacs process.
2054 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2055 frame's terminal). This function always returns nil if TERMINAL
2056 is not on a tty device. */)
2058 Lisp_Object terminal
;
2060 struct terminal
*t
= get_terminal (terminal
, 1);
2062 if (t
->type
!= output_termcap
|| t
->display_info
.tty
->name
)
2068 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 1, 0,
2069 doc
: /* Declare that the tty used by TERMINAL does not handle underlining.
2070 This is used to override the terminfo data, for certain terminals that
2071 do not really do underlining, but say that they do. This function has
2072 no effect if used on a non-tty terminal.
2074 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2075 frame's terminal). This function always returns nil if TERMINAL
2076 is not on a tty device. */)
2078 Lisp_Object terminal
;
2080 struct terminal
*t
= get_terminal (terminal
, 1);
2082 if (t
->type
== output_termcap
)
2083 t
->display_info
.tty
->TS_enter_underline_mode
= 0;
2089 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
2090 doc
: /* Suspend the terminal device TTY.
2092 The device is restored to its default state, and Emacs ceases all
2093 access to the tty device. Frames that use the device are not deleted,
2094 but input is not read from them and if they change, their display is
2097 TTY may be a terminal id, a frame, or nil for the terminal device of
2098 the currently selected frame.
2100 This function runs `suspend-tty-functions' after suspending the
2101 device. The functions are run with one arg, the id of the suspended
2104 `suspend-tty' does nothing if it is called on a device that is already
2107 A suspended tty may be resumed by calling `resume-tty' on it. */)
2111 struct terminal
*t
= get_tty_terminal (tty
);
2115 error ("Unknown tty device");
2117 f
= t
->display_info
.tty
->input
;
2121 reset_sys_modes (t
->display_info
.tty
);
2123 delete_keyboard_wait_descriptor (fileno (f
));
2126 if (f
!= t
->display_info
.tty
->output
)
2127 fclose (t
->display_info
.tty
->output
);
2129 t
->display_info
.tty
->input
= 0;
2130 t
->display_info
.tty
->output
= 0;
2132 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2133 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 0);
2135 /* Run `suspend-tty-functions'. */
2136 if (!NILP (Vrun_hooks
))
2138 Lisp_Object args
[2];
2139 args
[0] = intern ("suspend-tty-functions");
2140 args
[1] = make_number (t
->id
);
2141 Frun_hook_with_args (2, args
);
2148 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
2149 doc
: /* Resume the previously suspended terminal device TTY.
2150 The terminal is opened and reinitialized. Frames that are on the
2151 suspended terminal are revived.
2153 It is an error to resume a terminal while another terminal is active
2156 This function runs `resume-tty-functions' after resuming the terminal.
2157 The functions are run with one arg, the id of the resumed terminal
2160 `resume-tty' does nothing if it is called on a device that is not
2163 TTY may be a terminal id, a frame, or nil for the terminal device of
2164 the currently selected frame. */)
2168 struct terminal
*t
= get_tty_terminal (tty
);
2172 error ("Unknown tty device");
2174 if (!t
->display_info
.tty
->input
)
2176 if (get_named_tty (t
->display_info
.tty
->name
))
2177 error ("Cannot resume display while another display is active on the same device");
2179 fd
= emacs_open (t
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
2181 /* XXX What if open fails? */
2183 dissociate_if_controlling_tty (fd
);
2185 t
->display_info
.tty
->output
= fdopen (fd
, "w+");
2186 t
->display_info
.tty
->input
= t
->display_info
.tty
->output
;
2188 add_keyboard_wait_descriptor (fd
);
2190 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2191 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 1);
2193 init_sys_modes (t
->display_info
.tty
);
2195 /* Run `suspend-tty-functions'. */
2196 if (!NILP (Vrun_hooks
))
2198 Lisp_Object args
[2];
2199 args
[0] = intern ("resume-tty-functions");
2200 args
[1] = make_number (t
->id
);
2201 Frun_hook_with_args (2, args
);
2209 /***********************************************************************
2211 ***********************************************************************/
2213 /* Initialize the tty-dependent part of frame F. The frame must
2214 already have its device initialized. */
2217 create_tty_output (struct frame
*f
)
2219 struct tty_output
*t
;
2221 if (! FRAME_TERMCAP_P (f
))
2224 t
= xmalloc (sizeof (struct tty_output
));
2225 bzero (t
, sizeof (struct tty_output
));
2227 t
->display_info
= FRAME_TERMINAL (f
)->display_info
.tty
;
2229 f
->output_data
.tty
= t
;
2232 /* Delete the tty-dependent part of frame F. */
2235 delete_tty_output (struct frame
*f
)
2237 if (! FRAME_TERMCAP_P (f
))
2240 xfree (f
->output_data
.tty
);
2245 /* Drop the controlling terminal if fd is the same device. */
2247 dissociate_if_controlling_tty (int fd
)
2250 EMACS_GET_TTY_PGRP (fd
, &pgid
); /* If tcgetpgrp succeeds, fd is the ctty. */
2253 #if defined (USG) && !defined (BSD_PGRPS)
2255 no_controlling_tty
= 1;
2257 #ifdef TIOCNOTTY /* Try BSD ioctls. */
2258 sigblock (sigmask (SIGTTOU
));
2259 fd
= emacs_open ("/dev/tty", O_RDWR
, 0);
2260 if (fd
!= -1 && ioctl (fd
, TIOCNOTTY
, 0) != -1)
2262 no_controlling_tty
= 1;
2266 sigunblock (sigmask (SIGTTOU
));
2268 /* Unknown system. */
2270 #endif /* ! TIOCNOTTY */
2275 static void maybe_fatal();
2277 /* Create a termcap display on the tty device with the given name and
2280 If NAME is NULL, then use the controlling tty, i.e., stdin/stdout.
2281 Otherwise NAME should be a path to the tty device file,
2284 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
2286 If MUST_SUCCEED is true, then all errors are fatal. */
2289 init_tty (char *name
, char *terminal_type
, int must_succeed
)
2292 char **address
= &area
;
2293 char *buffer
= NULL
;
2294 int buffer_size
= 4096;
2297 struct tty_display_info
*tty
;
2298 struct terminal
*terminal
;
2301 maybe_fatal (must_succeed
, 0, 0,
2302 "Unknown terminal type",
2303 "Unknown terminal type");
2305 /* If we already have a terminal on the given device, use that. If
2306 all such terminals are suspended, create a new one instead. */
2307 /* XXX Perhaps this should be made explicit by having init_tty
2308 always create a new terminal and separating terminal and frame
2309 creation on Lisp level. */
2310 terminal
= get_named_tty (name
);
2314 terminal
= create_terminal ();
2315 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
2316 bzero (tty
, sizeof (struct tty_display_info
));
2317 tty
->next
= tty_list
;
2320 terminal
->type
= output_termcap
;
2321 terminal
->display_info
.tty
= tty
;
2322 tty
->terminal
= terminal
;
2324 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
2327 terminal
->rif
= 0; /* ttys don't support window-based redisplay. */
2329 terminal
->cursor_to_hook
= &tty_cursor_to
;
2330 terminal
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
2332 terminal
->clear_to_end_hook
= &tty_clear_to_end
;
2333 terminal
->clear_frame_hook
= &tty_clear_frame
;
2334 terminal
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
2336 terminal
->ins_del_lines_hook
= &tty_ins_del_lines
;
2338 terminal
->insert_glyphs_hook
= &tty_insert_glyphs
;
2339 terminal
->write_glyphs_hook
= &tty_write_glyphs
;
2340 terminal
->delete_glyphs_hook
= &tty_delete_glyphs
;
2342 terminal
->ring_bell_hook
= &tty_ring_bell
;
2344 terminal
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
2345 terminal
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
2346 terminal
->update_begin_hook
= 0; /* Not needed. */
2347 terminal
->update_end_hook
= &tty_update_end
;
2348 terminal
->set_terminal_window_hook
= &tty_set_terminal_window
;
2350 terminal
->mouse_position_hook
= 0; /* Not needed. */
2351 terminal
->frame_rehighlight_hook
= 0; /* Not needed. */
2352 terminal
->frame_raise_lower_hook
= 0; /* Not needed. */
2354 terminal
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
2355 terminal
->condemn_scroll_bars_hook
= 0; /* Not needed. */
2356 terminal
->redeem_scroll_bar_hook
= 0; /* Not needed. */
2357 terminal
->judge_scroll_bars_hook
= 0; /* Not needed. */
2359 terminal
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
2360 terminal
->frame_up_to_date_hook
= 0; /* Not needed. */
2362 terminal
->delete_frame_hook
= &delete_tty_output
;
2363 terminal
->delete_terminal_hook
= &delete_tty
;
2370 #ifdef O_IGNORE_CTTY
2371 /* Open the terminal device. Don't recognize it as our
2372 controlling terminal, and don't make it the controlling tty
2373 if we don't have one at the moment. */
2374 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
2376 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
2377 defined on Hurd. On other systems, we need to dissociate
2378 ourselves from the controlling tty when we want to open a
2379 frame on the same terminal. */
2381 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
2383 #endif /* O_IGNORE_CTTY */
2387 delete_tty (terminal
);
2388 error ("Could not open file: %s", name
);
2393 error ("Not a tty device: %s", name
);
2396 dissociate_if_controlling_tty (fd
);
2398 file
= fdopen (fd
, "w+");
2399 tty
->name
= xstrdup (name
);
2400 terminal
->name
= xstrdup (name
);
2406 if (no_controlling_tty
)
2408 /* Opening a frame on stdout is unsafe if we have
2409 disconnected our controlling terminal. */
2410 error ("There is no controlling terminal any more");
2413 terminal
->name
= xstrdup (ttyname (0));
2415 tty
->output
= stdout
;
2418 tty
->type
= xstrdup (terminal_type
);
2420 add_keyboard_wait_descriptor (fileno (tty
->input
));
2422 encode_terminal_bufsize
= 0;
2425 initialize_w32_display ();
2429 area
= (char *) xmalloc (2044);
2431 FrameRows (tty
) = FRAME_LINES (f
); /* XXX */
2432 FrameCols (tty
) = FRAME_COLS (f
); /* XXX */
2433 tty
->specified_window
= FRAME_LINES (f
); /* XXX */
2435 tty
->terminal
->delete_in_insert_mode
= 1;
2438 terminal
->scroll_region_ok
= 0;
2440 /* Seems to insert lines when it's not supposed to, messing up the
2441 display. In doing a trace, it didn't seem to be called much, so I
2442 don't think we're losing anything by turning it off. */
2443 terminal
->line_ins_del_ok
= 0;
2444 terminal
->char_ins_del_ok
= 1;
2448 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0; /* XXX */
2449 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
; /* XXX */
2450 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2453 #else /* not WINDOWSNT */
2457 buffer
= (char *) xmalloc (buffer_size
);
2459 /* On some systems, tgetent tries to access the controlling
2461 sigblock (sigmask (SIGTTOU
));
2462 status
= tgetent (buffer
, terminal_type
);
2463 sigunblock (sigmask (SIGTTOU
));
2468 maybe_fatal (must_succeed
, buffer
, terminal
,
2469 "Cannot open terminfo database file",
2470 "Cannot open terminfo database file");
2472 maybe_fatal (must_succeed
, buffer
, terminal
,
2473 "Cannot open termcap database file",
2474 "Cannot open termcap database file");
2480 maybe_fatal (must_succeed
, buffer
, terminal
,
2481 "Terminal type %s is not defined",
2482 "Terminal type %s is not defined.\n\
2483 If that is not the actual type of terminal you have,\n\
2484 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2485 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2486 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2489 maybe_fatal (must_succeed
, buffer
, terminal
,
2490 "Terminal type %s is not defined",
2491 "Terminal type %s is not defined.\n\
2492 If that is not the actual type of terminal you have,\n\
2493 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2494 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2495 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2501 if (strlen (buffer
) >= buffer_size
)
2503 buffer_size
= strlen (buffer
);
2505 area
= (char *) xmalloc (buffer_size
);
2507 tty
->TS_ins_line
= tgetstr ("al", address
);
2508 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
2509 tty
->TS_bell
= tgetstr ("bl", address
);
2510 BackTab (tty
) = tgetstr ("bt", address
);
2511 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
2512 tty
->TS_clr_line
= tgetstr ("ce", address
);
2513 tty
->TS_clr_frame
= tgetstr ("cl", address
);
2514 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
2515 AbsPosition (tty
) = tgetstr ("cm", address
);
2516 CR (tty
) = tgetstr ("cr", address
);
2517 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
2518 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
2519 RowPosition (tty
) = tgetstr ("cv", address
);
2520 tty
->TS_del_char
= tgetstr ("dc", address
);
2521 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
2522 tty
->TS_del_line
= tgetstr ("dl", address
);
2523 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
2524 tty
->TS_delete_mode
= tgetstr ("dm", address
);
2525 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
2526 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
2527 Home (tty
) = tgetstr ("ho", address
);
2528 tty
->TS_ins_char
= tgetstr ("ic", address
);
2529 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
2530 tty
->TS_insert_mode
= tgetstr ("im", address
);
2531 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
2532 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
2533 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
2534 LastLine (tty
) = tgetstr ("ll", address
);
2535 Right (tty
) = tgetstr ("nd", address
);
2536 Down (tty
) = tgetstr ("do", address
);
2538 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
2540 /* VMS puts a carriage return before each linefeed,
2541 so it is not safe to use linefeeds. */
2542 if (Down (tty
) && Down (tty
)[0] == '\n' && Down (tty
)[1] == '\0')
2545 if (tgetflag ("bs"))
2546 Left (tty
) = "\b"; /* can't possibly be longer! */
2547 else /* (Actually, "bs" is obsolete...) */
2548 Left (tty
) = tgetstr ("le", address
);
2550 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
2551 tty
->TS_pad_char
= tgetstr ("pc", address
);
2552 tty
->TS_repeat
= tgetstr ("rp", address
);
2553 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
2554 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
2555 tty
->TS_standout_mode
= tgetstr ("so", address
);
2556 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
2557 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
2558 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
2559 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
2560 Up (tty
) = tgetstr ("up", address
);
2561 tty
->TS_visible_bell
= tgetstr ("vb", address
);
2562 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
2563 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
2564 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
2565 tty
->TS_set_window
= tgetstr ("wi", address
);
2567 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
2568 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
2569 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
2570 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
2571 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
2572 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
2573 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2574 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2575 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
2577 MultiUp (tty
) = tgetstr ("UP", address
);
2578 MultiDown (tty
) = tgetstr ("DO", address
);
2579 MultiLeft (tty
) = tgetstr ("LE", address
);
2580 MultiRight (tty
) = tgetstr ("RI", address
);
2582 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2583 color because we can't switch back to the default foreground and
2585 tty
->TS_orig_pair
= tgetstr ("op", address
);
2586 if (tty
->TS_orig_pair
)
2588 tty
->TS_set_foreground
= tgetstr ("AF", address
);
2589 tty
->TS_set_background
= tgetstr ("AB", address
);
2590 if (!tty
->TS_set_foreground
)
2593 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
2594 tty
->TS_set_background
= tgetstr ("Sb", address
);
2597 tty
->TN_max_colors
= tgetnum ("Co");
2598 tty
->TN_max_pairs
= tgetnum ("pa");
2600 tty
->TN_no_color_video
= tgetnum ("NC");
2601 if (tty
->TN_no_color_video
== -1)
2602 tty
->TN_no_color_video
= 0;
2605 tty_default_color_capabilities (tty
, 1);
2607 MagicWrap (tty
) = tgetflag ("xn");
2608 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2609 the former flag imply the latter. */
2610 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
2611 terminal
->memory_below_frame
= tgetflag ("db");
2612 tty
->TF_hazeltine
= tgetflag ("hz");
2613 terminal
->must_write_spaces
= tgetflag ("in");
2614 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
2615 tty
->TF_insmode_motion
= tgetflag ("mi");
2616 tty
->TF_standout_motion
= tgetflag ("ms");
2617 tty
->TF_underscore
= tgetflag ("ul");
2618 tty
->TF_teleray
= tgetflag ("xt");
2621 terminal
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
2622 init_kboard (terminal
->kboard
);
2623 terminal
->kboard
->next_kboard
= all_kboards
;
2624 all_kboards
= terminal
->kboard
;
2625 terminal
->kboard
->reference_count
++;
2626 /* Don't let the initial kboard remain current longer than necessary.
2627 That would cause problems if a file loaded on startup tries to
2628 prompt in the mini-buffer. */
2629 if (current_kboard
== initial_kboard
)
2630 current_kboard
= terminal
->kboard
;
2633 term_get_fkeys (address
, terminal
->kboard
);
2635 /* Get frame size from system, or else from termcap. */
2638 get_tty_size (fileno (tty
->input
), &width
, &height
);
2639 FrameCols (tty
) = width
;
2640 FrameRows (tty
) = height
;
2643 if (FrameCols (tty
) <= 0)
2644 FrameCols (tty
) = tgetnum ("co");
2645 if (FrameRows (tty
) <= 0)
2646 FrameRows (tty
) = tgetnum ("li");
2648 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
2649 maybe_fatal (must_succeed
, NULL
, terminal
,
2650 "Screen size %dx%d is too small"
2651 "Screen size %dx%d is too small",
2652 FrameCols (tty
), FrameRows (tty
));
2654 #if 0 /* This is not used anywhere. */
2655 tty
->terminal
->min_padding_speed
= tgetnum ("pb");
2658 TabWidth (tty
) = tgetnum ("tw");
2661 /* These capabilities commonly use ^J.
2662 I don't know why, but sending them on VMS does not work;
2663 it causes following spaces to be lost, sometimes.
2664 For now, the simplest fix is to avoid using these capabilities ever. */
2665 if (Down (tty
) && Down (tty
)[0] == '\n')
2670 tty
->TS_bell
= "\07";
2672 if (!tty
->TS_fwd_scroll
)
2673 tty
->TS_fwd_scroll
= Down (tty
);
2675 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
2677 if (TabWidth (tty
) < 0)
2680 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2681 and newer termcap doc does not seem to say there is a default.
2682 if (!tty->Wcm->cm_tab)
2683 tty->Wcm->cm_tab = "\t";
2686 /* We don't support standout modes that use `magic cookies', so
2687 turn off any that do. */
2688 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
2690 tty
->TS_standout_mode
= 0;
2691 tty
->TS_end_standout_mode
= 0;
2693 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
2695 tty
->TS_enter_underline_mode
= 0;
2696 tty
->TS_exit_underline_mode
= 0;
2699 /* If there's no standout mode, try to use underlining instead. */
2700 if (tty
->TS_standout_mode
== 0)
2702 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
2703 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
2706 /* If no `se' string, try using a `me' string instead.
2707 If that fails, we can't use standout mode at all. */
2708 if (tty
->TS_end_standout_mode
== 0)
2710 char *s
= tgetstr ("me", address
);
2712 tty
->TS_end_standout_mode
= s
;
2714 tty
->TS_standout_mode
= 0;
2717 if (tty
->TF_teleray
)
2719 tty
->Wcm
->cm_tab
= 0;
2720 /* We can't support standout mode, because it uses magic cookies. */
2721 tty
->TS_standout_mode
= 0;
2722 /* But that means we cannot rely on ^M to go to column zero! */
2724 /* LF can't be trusted either -- can alter hpos */
2725 /* if move at column 0 thru a line with TS_standout_mode */
2729 /* Special handling for certain terminal types known to need it */
2731 if (!strcmp (terminal_type
, "supdup"))
2733 terminal
->memory_below_frame
= 1;
2734 tty
->Wcm
->cm_losewrap
= 1;
2736 if (!strncmp (terminal_type
, "c10", 3)
2737 || !strcmp (terminal_type
, "perq"))
2739 /* Supply a makeshift :wi string.
2740 This string is not valid in general since it works only
2741 for windows starting at the upper left corner;
2742 but that is all Emacs uses.
2744 This string works only if the frame is using
2745 the top of the video memory, because addressing is memory-relative.
2746 So first check the :ti string to see if that is true.
2748 It would be simpler if the :wi string could go in the termcap
2749 entry, but it can't because it is not fully valid.
2750 If it were in the termcap entry, it would confuse other programs. */
2751 if (!tty
->TS_set_window
)
2753 p
= tty
->TS_termcap_modes
;
2754 while (*p
&& strcmp (p
, "\033v "))
2757 tty
->TS_set_window
= "\033v%C %C %C %C ";
2759 /* Termcap entry often fails to have :in: flag */
2760 terminal
->must_write_spaces
= 1;
2761 /* :ti string typically fails to have \E^G! in it */
2762 /* This limits scope of insert-char to one line. */
2763 strcpy (area
, tty
->TS_termcap_modes
);
2764 strcat (area
, "\033\007!");
2765 tty
->TS_termcap_modes
= area
;
2766 area
+= strlen (area
) + 1;
2767 p
= AbsPosition (tty
);
2768 /* Change all %+ parameters to %C, to handle
2769 values above 96 correctly for the C100. */
2772 if (p
[0] == '%' && p
[1] == '+')
2778 tty
->specified_window
= FrameRows (tty
);
2780 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
2782 maybe_fatal (must_succeed
, NULL
, terminal
,
2783 "Terminal type \"%s\" is not powerful enough to run Emacs",
2785 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2786 It lacks the ability to position the cursor.\n\
2787 If that is not the actual type of terminal you have, use either the\n\
2788 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2789 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2792 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2793 It lacks the ability to position the cursor.\n\
2794 If that is not the actual type of terminal you have,\n\
2795 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2796 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2797 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2798 # else /* TERMCAP */
2799 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2800 It lacks the ability to position the cursor.\n\
2801 If that is not the actual type of terminal you have,\n\
2802 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2803 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2804 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2805 # endif /* TERMINFO */
2810 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
2811 maybe_fatal (must_succeed
, NULL
, terminal
,
2812 "Could not determine the frame size",
2813 "Could not determine the frame size");
2815 tty
->delete_in_insert_mode
2816 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
2817 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
2819 tty
->se_is_so
= (tty
->TS_standout_mode
2820 && tty
->TS_end_standout_mode
2821 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
2823 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
2825 terminal
->scroll_region_ok
2827 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
2829 terminal
->line_ins_del_ok
2830 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
2831 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
2832 || (terminal
->scroll_region_ok
2833 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
2835 terminal
->char_ins_del_ok
2836 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
2837 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
2838 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
2840 terminal
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
2842 init_baud_rate (fileno (tty
->input
));
2845 /* The HFT system on AIX doesn't optimize for scrolling, so it's
2846 really ugly at times. */
2847 terminal
->line_ins_del_ok
= 0;
2848 terminal
->char_ins_del_ok
= 0;
2851 /* Don't do this. I think termcap may still need the buffer. */
2852 /* xfree (buffer); */
2854 /* Init system terminal modes (RAW or CBREAK, etc.). */
2855 init_sys_modes (tty
);
2858 #endif /* not WINDOWSNT */
2861 /* Auxiliary error-handling function for init_tty.
2862 Free BUFFER and delete TERMINAL, then call error or fatal
2863 with str1 or str2, respectively, according to MUST_SUCCEED. */
2866 maybe_fatal (must_succeed
, buffer
, terminal
, str1
, str2
, arg1
, arg2
)
2869 struct terminal
*terminal
;
2870 char *str1
, *str2
, *arg1
, *arg2
;
2876 delete_tty (terminal
);
2879 fatal (str2
, arg1
, arg2
);
2881 error (str1
, arg1
, arg2
);
2888 fatal (str
, arg1
, arg2
)
2889 char *str
, *arg1
, *arg2
;
2891 fprintf (stderr
, "emacs: ");
2892 fprintf (stderr
, str
, arg1
, arg2
);
2893 fprintf (stderr
, "\n");
2900 static int deleting_tty
= 0;
2903 /* Delete the given tty terminal, closing all frames on it. */
2906 delete_tty (struct terminal
*terminal
)
2908 struct tty_display_info
*tty
;
2909 Lisp_Object tail
, frame
;
2914 /* We get a recursive call when we delete the last frame on this
2918 if (terminal
->type
!= output_termcap
)
2921 tty
= terminal
->display_info
.tty
;
2924 FOR_EACH_FRAME (tail
, frame
)
2926 struct frame
*f
= XFRAME (frame
);
2927 if (FRAME_LIVE_P (f
) && (!FRAME_TERMCAP_P (f
) || FRAME_TTY (f
) != tty
))
2934 error ("Attempt to delete the sole terminal device with live frames");
2936 if (tty
== tty_list
)
2937 tty_list
= tty
->next
;
2940 struct tty_display_info
*p
;
2941 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
2945 /* This should not happen. */
2948 p
->next
= tty
->next
;
2954 FOR_EACH_FRAME (tail
, frame
)
2956 struct frame
*f
= XFRAME (frame
);
2957 if (FRAME_TERMCAP_P (f
) && FRAME_LIVE_P (f
) && FRAME_TTY (f
) == tty
)
2959 Fdelete_frame (frame
, Qt
);
2963 /* reset_sys_modes needs a valid device, so this call needs to be
2964 before delete_terminal. */
2965 reset_sys_modes (tty
);
2967 delete_terminal (terminal
);
2969 tty_name
= tty
->name
;
2975 delete_keyboard_wait_descriptor (fileno (tty
->input
));
2976 if (tty
->input
!= stdin
)
2977 fclose (tty
->input
);
2979 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
2980 fclose (tty
->output
);
2981 if (tty
->termscript
)
2982 fclose (tty
->termscript
);
2985 xfree (tty
->old_tty
);
2990 bzero (tty
, sizeof (struct tty_display_info
));
2997 /* Mark the pointers in the tty_display_info objects.
2998 Called by the Fgarbage_collector. */
3003 struct tty_display_info
*tty
;
3005 for (tty
= tty_list
; tty
; tty
= tty
->next
)
3008 mark_object (tty
->top_frame
);
3017 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
3018 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3019 This variable can be used by terminal emulator packages. */);
3021 system_uses_terminfo
= 1;
3023 system_uses_terminfo
= 0;
3026 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions
,
3027 doc
: /* Functions to be run after suspending a tty.
3028 The functions are run with one argument, the name of the tty to be suspended.
3029 See `suspend-tty'. */);
3030 Vsuspend_tty_functions
= Qnil
;
3033 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions
,
3034 doc
: /* Functions to be run after resuming a tty.
3035 The functions are run with one argument, the name of the tty that was revived.
3036 See `resume-tty'. */);
3037 Vresume_tty_functions
= Qnil
;
3039 DEFVAR_BOOL ("visible-cursor", &visible_cursor
,
3040 doc
: /* Non-nil means to make the cursor very visible.
3041 This only has an effect when running in a text terminal.
3042 What means \"very visible\" is up to your terminal. It may make the cursor
3043 bigger, or it may make it blink, or it may do nothing at all. */);
3046 defsubr (&Stty_display_color_p
);
3047 defsubr (&Stty_display_color_cells
);
3048 defsubr (&Stty_no_underline
);
3049 defsubr (&Stty_type
);
3050 defsubr (&Scontrolling_tty_p
);
3051 defsubr (&Ssuspend_tty
);
3052 defsubr (&Sresume_tty
);
3057 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
3058 (do not change this comment) */