1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2013 Free Software
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 3 of the License, or
10 (at your option) any later version.
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. If not, see <http://www.gnu.org/licenses/>. */
20 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
33 #include "character.h"
37 #include "composite.h"
41 #include "termhooks.h"
42 #include "dispextern.h"
45 #include "blockinput.h"
46 #include "syssignal.h"
48 #include "intervals.h"
51 static int been_here
= -1;
59 /* The name of the default console device. */
61 #define DEV_TTY "CONOUT$"
64 #define DEV_TTY "/dev/tty"
67 static void tty_set_scroll_region (struct frame
*f
, int start
, int stop
);
68 static void turn_on_face (struct frame
*, int face_id
);
69 static void turn_off_face (struct frame
*, int face_id
);
70 static void tty_turn_off_highlight (struct tty_display_info
*);
71 static void tty_show_cursor (struct tty_display_info
*);
72 static void tty_hide_cursor (struct tty_display_info
*);
73 static void tty_background_highlight (struct tty_display_info
*tty
);
74 static struct terminal
*get_tty_terminal (Lisp_Object
, bool);
75 static void clear_tty_hooks (struct terminal
*terminal
);
76 static void set_tty_hooks (struct terminal
*terminal
);
77 static void dissociate_if_controlling_tty (int fd
);
78 static void delete_tty (struct terminal
*);
79 static _Noreturn
void maybe_fatal (bool, struct terminal
*,
80 const char *, const char *, ...)
81 ATTRIBUTE_FORMAT_PRINTF (3, 5) ATTRIBUTE_FORMAT_PRINTF (4, 5);
82 static _Noreturn
void vfatal (const char *str
, va_list ap
)
83 ATTRIBUTE_FORMAT_PRINTF (1, 0);
86 #define OUTPUT(tty, a) \
87 emacs_tputs ((tty), a, \
88 FRAME_LINES (XFRAME (selected_frame)) - curY (tty), \
91 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
92 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
94 #define OUTPUT_IF(tty, a) \
100 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
102 /* Display space properties */
104 /* Chain of all tty device parameters. */
105 struct tty_display_info
*tty_list
;
107 /* Meaning of bits in no_color_video. Each bit set means that the
108 corresponding attribute cannot be combined with colors. */
112 NC_STANDOUT
= 1 << 0,
113 NC_UNDERLINE
= 1 << 1,
124 /* The largest frame width in any call to calculate_costs. */
126 static int max_frame_cols
;
131 #include <sys/fcntl.h>
133 /* The device for which we have enabled gpm support (or NULL). */
134 struct tty_display_info
*gpm_tty
= NULL
;
136 /* Last recorded mouse coordinates. */
137 static int last_mouse_x
, last_mouse_y
;
138 #endif /* HAVE_GPM */
140 /* Ring the bell on a tty. */
143 tty_ring_bell (struct frame
*f
)
145 struct tty_display_info
*tty
= FRAME_TTY (f
);
149 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
150 ? tty
->TS_visible_bell
152 fflush (tty
->output
);
156 /* Set up termcap modes for Emacs. */
159 tty_set_terminal_modes (struct terminal
*terminal
)
161 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
165 if (tty
->TS_termcap_modes
)
166 OUTPUT (tty
, tty
->TS_termcap_modes
);
169 /* Output enough newlines to scroll all the old screen contents
170 off the screen, so it won't be overwritten and lost. */
173 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
177 OUTPUT_IF (tty
, visible_cursor
? tty
->TS_cursor_visible
: tty
->TS_cursor_normal
);
178 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
180 fflush (tty
->output
);
184 /* Reset termcap modes before exiting Emacs. */
187 tty_reset_terminal_modes (struct terminal
*terminal
)
189 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
193 tty_turn_off_highlight (tty
);
194 tty_turn_off_insert (tty
);
195 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
196 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
197 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
198 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
199 /* Output raw CR so kernel can track the cursor hpos. */
202 fflush (tty
->output
);
206 /* Flag the end of a display update on a termcap terminal. */
209 tty_update_end (struct frame
*f
)
211 struct tty_display_info
*tty
= FRAME_TTY (f
);
213 if (!XWINDOW (selected_window
)->cursor_off_p
)
214 tty_show_cursor (tty
);
215 tty_turn_off_insert (tty
);
216 tty_background_highlight (tty
);
219 /* The implementation of set_terminal_window for termcap frames. */
222 tty_set_terminal_window (struct frame
*f
, int size
)
224 struct tty_display_info
*tty
= FRAME_TTY (f
);
226 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
227 if (FRAME_SCROLL_REGION_OK (f
))
228 tty_set_scroll_region (f
, 0, tty
->specified_window
);
232 tty_set_scroll_region (struct frame
*f
, int start
, int stop
)
235 struct tty_display_info
*tty
= FRAME_TTY (f
);
237 if (tty
->TS_set_scroll_region
)
238 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1, 0, 0);
239 else if (tty
->TS_set_scroll_region_1
)
240 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
241 FRAME_LINES (f
), start
,
242 FRAME_LINES (f
) - stop
,
245 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
254 tty_turn_on_insert (struct tty_display_info
*tty
)
256 if (!tty
->insert_mode
)
257 OUTPUT (tty
, tty
->TS_insert_mode
);
258 tty
->insert_mode
= 1;
262 tty_turn_off_insert (struct tty_display_info
*tty
)
264 if (tty
->insert_mode
)
265 OUTPUT (tty
, tty
->TS_end_insert_mode
);
266 tty
->insert_mode
= 0;
269 /* Handle highlighting. */
272 tty_turn_off_highlight (struct tty_display_info
*tty
)
274 if (tty
->standout_mode
)
275 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
276 tty
->standout_mode
= 0;
280 tty_turn_on_highlight (struct tty_display_info
*tty
)
282 if (!tty
->standout_mode
)
283 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
284 tty
->standout_mode
= 1;
288 tty_toggle_highlight (struct tty_display_info
*tty
)
290 if (tty
->standout_mode
)
291 tty_turn_off_highlight (tty
);
293 tty_turn_on_highlight (tty
);
297 /* Make cursor invisible. */
300 tty_hide_cursor (struct tty_display_info
*tty
)
302 if (tty
->cursor_hidden
== 0)
304 tty
->cursor_hidden
= 1;
305 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
310 /* Ensure that cursor is visible. */
313 tty_show_cursor (struct tty_display_info
*tty
)
315 if (tty
->cursor_hidden
)
317 tty
->cursor_hidden
= 0;
318 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
320 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
325 /* Set standout mode to the state it should be in for
326 empty space inside windows. What this is,
327 depends on the user option inverse-video. */
330 tty_background_highlight (struct tty_display_info
*tty
)
333 tty_turn_on_highlight (tty
);
335 tty_turn_off_highlight (tty
);
338 /* Set standout mode to the mode specified for the text to be output. */
341 tty_highlight_if_desired (struct tty_display_info
*tty
)
344 tty_turn_on_highlight (tty
);
346 tty_turn_off_highlight (tty
);
350 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
351 frame-relative coordinates. */
354 tty_cursor_to (struct frame
*f
, int vpos
, int hpos
)
356 struct tty_display_info
*tty
= FRAME_TTY (f
);
358 /* Detect the case where we are called from reset_sys_modes
359 and the costs have never been calculated. Do nothing. */
360 if (! tty
->costs_set
)
363 if (curY (tty
) == vpos
364 && curX (tty
) == hpos
)
366 if (!tty
->TF_standout_motion
)
367 tty_background_highlight (tty
);
368 if (!tty
->TF_insmode_motion
)
369 tty_turn_off_insert (tty
);
370 cmgoto (tty
, vpos
, hpos
);
373 /* Similar but don't take any account of the wasted characters. */
376 tty_raw_cursor_to (struct frame
*f
, int row
, int col
)
378 struct tty_display_info
*tty
= FRAME_TTY (f
);
380 if (curY (tty
) == row
381 && curX (tty
) == col
)
383 if (!tty
->TF_standout_motion
)
384 tty_background_highlight (tty
);
385 if (!tty
->TF_insmode_motion
)
386 tty_turn_off_insert (tty
);
387 cmgoto (tty
, row
, col
);
390 /* Erase operations */
392 /* Clear from cursor to end of frame on a termcap device. */
395 tty_clear_to_end (struct frame
*f
)
398 struct tty_display_info
*tty
= FRAME_TTY (f
);
400 if (tty
->TS_clr_to_bottom
)
402 tty_background_highlight (tty
);
403 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
407 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
410 clear_end_of_line (f
, FRAME_COLS (f
));
415 /* Clear an entire termcap frame. */
418 tty_clear_frame (struct frame
*f
)
420 struct tty_display_info
*tty
= FRAME_TTY (f
);
422 if (tty
->TS_clr_frame
)
424 tty_background_highlight (tty
);
425 OUTPUT (tty
, tty
->TS_clr_frame
);
435 /* An implementation of clear_end_of_line for termcap frames.
437 Note that the cursor may be moved, on terminals lacking a `ce' string. */
440 tty_clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
443 struct tty_display_info
*tty
= FRAME_TTY (f
);
445 /* Detect the case where we are called from reset_sys_modes
446 and the costs have never been calculated. Do nothing. */
447 if (! tty
->costs_set
)
450 if (curX (tty
) >= first_unused_hpos
)
452 tty_background_highlight (tty
);
453 if (tty
->TS_clr_line
)
455 OUTPUT1 (tty
, tty
->TS_clr_line
);
458 { /* have to do it the hard way */
459 tty_turn_off_insert (tty
);
461 /* Do not write in last row last col with Auto-wrap on. */
463 && curY (tty
) == FrameRows (tty
) - 1
464 && first_unused_hpos
== FrameCols (tty
))
467 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
470 fputc (' ', tty
->termscript
);
471 fputc (' ', tty
->output
);
473 cmplus (tty
, first_unused_hpos
- curX (tty
));
477 /* Buffers to store the source and result of code conversion for terminal. */
478 static unsigned char *encode_terminal_src
;
479 static unsigned char *encode_terminal_dst
;
480 /* Allocated sizes of the above buffers. */
481 static ptrdiff_t encode_terminal_src_size
;
482 static ptrdiff_t encode_terminal_dst_size
;
484 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
485 Set CODING->produced to the byte-length of the resulting byte
486 sequence, and return a pointer to that byte sequence. */
489 encode_terminal_code (struct glyph
*src
, int src_len
, struct coding_system
*coding
)
491 struct glyph
*src_end
= src
+ src_len
;
493 ptrdiff_t nchars
, nbytes
, required
;
494 ptrdiff_t tlen
= GLYPH_TABLE_LENGTH
;
495 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
496 Lisp_Object charset_list
;
498 /* Allocate sufficient size of buffer to store all characters in
499 multibyte-form. But, it may be enlarged on demand if
500 Vglyph_table contains a string or a composite glyph is
502 if (min (PTRDIFF_MAX
, SIZE_MAX
) / MAX_MULTIBYTE_LENGTH
< src_len
)
503 memory_full (SIZE_MAX
);
505 required
*= MAX_MULTIBYTE_LENGTH
;
506 if (encode_terminal_src_size
< required
)
508 encode_terminal_src
= xrealloc (encode_terminal_src
, required
);
509 encode_terminal_src_size
= required
;
512 charset_list
= coding_charset_list (coding
);
514 buf
= encode_terminal_src
;
516 while (src
< src_end
)
518 if (src
->type
== COMPOSITE_GLYPH
)
520 struct composition
*cmp
IF_LINT (= NULL
);
521 Lisp_Object gstring
IF_LINT (= Qnil
);
524 nbytes
= buf
- encode_terminal_src
;
525 if (src
->u
.cmp
.automatic
)
527 gstring
= composition_gstring_from_id (src
->u
.cmp
.id
);
528 required
= src
->slice
.cmp
.to
- src
->slice
.cmp
.from
+ 1;
532 cmp
= composition_table
[src
->u
.cmp
.id
];
533 required
= cmp
->glyph_len
;
534 required
*= MAX_MULTIBYTE_LENGTH
;
537 if (encode_terminal_src_size
- nbytes
< required
)
539 encode_terminal_src
=
540 xpalloc (encode_terminal_src
, &encode_terminal_src_size
,
541 required
- (encode_terminal_src_size
- nbytes
),
543 buf
= encode_terminal_src
+ nbytes
;
546 if (src
->u
.cmp
.automatic
)
547 for (i
= src
->slice
.cmp
.from
; i
<= src
->slice
.cmp
.to
; i
++)
549 Lisp_Object g
= LGSTRING_GLYPH (gstring
, i
);
550 int c
= LGLYPH_CHAR (g
);
552 if (! char_charset (c
, charset_list
, NULL
))
554 buf
+= CHAR_STRING (c
, buf
);
558 for (i
= 0; i
< cmp
->glyph_len
; i
++)
560 int c
= COMPOSITION_GLYPH (cmp
, i
);
562 /* TAB in a composition means display glyphs with
563 padding space on the left or right. */
566 if (char_charset (c
, charset_list
, NULL
))
568 if (CHAR_WIDTH (c
) == 0
569 && i
> 0 && COMPOSITION_GLYPH (cmp
, i
- 1) == '\t')
570 /* Should be left-padded */
572 buf
+= CHAR_STRING (' ', buf
);
578 buf
+= CHAR_STRING (c
, buf
);
582 /* We must skip glyphs to be padded for a wide character. */
583 else if (! CHAR_GLYPH_PADDING_P (*src
))
590 SET_GLYPH_FROM_CHAR_GLYPH (g
, src
[0]);
592 if (GLYPH_INVALID_P (g
) || GLYPH_SIMPLE_P (tbase
, tlen
, g
))
594 /* This glyph doesn't have an entry in Vglyph_table. */
599 /* This glyph has an entry in Vglyph_table,
600 so process any alias before testing for simpleness. */
601 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
603 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
604 /* We set the multi-byte form of a character in G
605 (that should be an ASCII character) at WORKBUF. */
608 /* We have a string in Vglyph_table. */
609 string
= tbase
[GLYPH_CHAR (g
)];
614 nbytes
= buf
- encode_terminal_src
;
615 if (encode_terminal_src_size
- nbytes
< MAX_MULTIBYTE_LENGTH
)
617 encode_terminal_src
=
618 xpalloc (encode_terminal_src
, &encode_terminal_src_size
,
619 MAX_MULTIBYTE_LENGTH
, -1, 1);
620 buf
= encode_terminal_src
+ nbytes
;
623 || char_charset (c
, charset_list
, NULL
))
625 /* Store the multibyte form of C at BUF. */
626 buf
+= CHAR_STRING (c
, buf
);
631 /* C is not encodable. */
634 while (src
+ 1 < src_end
&& CHAR_GLYPH_PADDING_P (src
[1]))
644 if (! STRING_MULTIBYTE (string
))
645 string
= string_to_multibyte (string
);
646 nbytes
= buf
- encode_terminal_src
;
647 if (encode_terminal_src_size
- nbytes
< SBYTES (string
))
649 encode_terminal_src
=
650 xpalloc (encode_terminal_src
, &encode_terminal_src_size
,
652 - (encode_terminal_src_size
- nbytes
)),
654 buf
= encode_terminal_src
+ nbytes
;
656 memcpy (buf
, SDATA (string
), SBYTES (string
));
657 buf
+= SBYTES (string
);
658 nchars
+= SCHARS (string
);
666 coding
->produced
= 0;
670 nbytes
= buf
- encode_terminal_src
;
671 coding
->source
= encode_terminal_src
;
672 if (encode_terminal_dst_size
== 0)
674 encode_terminal_dst
= xrealloc (encode_terminal_dst
,
675 encode_terminal_src_size
);
676 encode_terminal_dst_size
= encode_terminal_src_size
;
678 coding
->destination
= encode_terminal_dst
;
679 coding
->dst_bytes
= encode_terminal_dst_size
;
680 encode_coding_object (coding
, Qnil
, 0, 0, nchars
, nbytes
, Qnil
);
681 /* coding->destination may have been reallocated. */
682 encode_terminal_dst
= coding
->destination
;
683 encode_terminal_dst_size
= coding
->dst_bytes
;
685 return (encode_terminal_dst
);
690 /* An implementation of write_glyphs for termcap frames. */
693 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
695 unsigned char *conversion_buffer
;
696 struct coding_system
*coding
;
699 struct tty_display_info
*tty
= FRAME_TTY (f
);
701 tty_turn_off_insert (tty
);
702 tty_hide_cursor (tty
);
704 /* Don't dare write in last column of bottom line, if Auto-Wrap,
705 since that would scroll the whole frame on some terminals. */
708 && curY (tty
) + 1 == FRAME_LINES (f
)
709 && (curX (tty
) + len
) == FRAME_COLS (f
))
716 /* If terminal_coding does any conversion, use it, otherwise use
717 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
718 because it always return 1 if the member src_multibyte is 1. */
719 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
720 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
721 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
723 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
725 for (stringlen
= len
; stringlen
!= 0; stringlen
-= n
)
727 /* Identify a run of glyphs with the same face. */
728 int face_id
= string
->face_id
;
730 for (n
= 1; n
< stringlen
; ++n
)
731 if (string
[n
].face_id
!= face_id
)
734 /* Turn appearance modes of the face of the run on. */
735 tty_highlight_if_desired (tty
);
736 turn_on_face (f
, face_id
);
739 /* This is the last run. */
740 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
741 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
742 if (coding
->produced
> 0)
745 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
746 if (ferror (tty
->output
))
747 clearerr (tty
->output
);
749 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
754 /* Turn appearance modes off. */
755 turn_off_face (f
, face_id
);
756 tty_turn_off_highlight (tty
);
762 #ifdef HAVE_GPM /* Only used by GPM code. */
765 tty_write_glyphs_with_face (register struct frame
*f
, register struct glyph
*string
,
766 register int len
, register int face_id
)
768 unsigned char *conversion_buffer
;
769 struct coding_system
*coding
;
771 struct tty_display_info
*tty
= FRAME_TTY (f
);
773 tty_turn_off_insert (tty
);
774 tty_hide_cursor (tty
);
776 /* Don't dare write in last column of bottom line, if Auto-Wrap,
777 since that would scroll the whole frame on some terminals. */
780 && curY (tty
) + 1 == FRAME_LINES (f
)
781 && (curX (tty
) + len
) == FRAME_COLS (f
))
788 /* If terminal_coding does any conversion, use it, otherwise use
789 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
790 because it always return 1 if the member src_multibyte is 1. */
791 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
792 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
793 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
795 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
797 /* Turn appearance modes of the face. */
798 tty_highlight_if_desired (tty
);
799 turn_on_face (f
, face_id
);
801 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
802 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
803 if (coding
->produced
> 0)
806 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
807 if (ferror (tty
->output
))
808 clearerr (tty
->output
);
810 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
814 /* Turn appearance modes off. */
815 turn_off_face (f
, face_id
);
816 tty_turn_off_highlight (tty
);
822 /* An implementation of insert_glyphs for termcap frames. */
825 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
828 struct glyph
*glyph
= NULL
;
829 unsigned char *conversion_buffer
;
830 unsigned char space
[1];
831 struct coding_system
*coding
;
833 struct tty_display_info
*tty
= FRAME_TTY (f
);
835 if (tty
->TS_ins_multi_chars
)
837 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
, 0, 0, 0);
841 write_glyphs (f
, start
, len
);
845 tty_turn_on_insert (tty
);
849 space
[0] = SPACEGLYPH
;
851 /* If terminal_coding does any conversion, use it, otherwise use
852 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
853 because it always return 1 if the member src_multibyte is 1. */
854 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
855 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
856 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
858 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
862 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
865 conversion_buffer
= space
;
866 coding
->produced
= 1;
870 tty_highlight_if_desired (tty
);
871 turn_on_face (f
, start
->face_id
);
874 /* We must open sufficient space for a character which
875 occupies more than one column. */
876 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
878 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
883 /* This is the last glyph. */
884 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
886 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
889 if (coding
->produced
> 0)
892 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
893 if (ferror (tty
->output
))
894 clearerr (tty
->output
);
896 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
900 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
903 turn_off_face (f
, glyph
->face_id
);
904 tty_turn_off_highlight (tty
);
911 /* An implementation of delete_glyphs for termcap frames. */
914 tty_delete_glyphs (struct frame
*f
, int n
)
919 struct tty_display_info
*tty
= FRAME_TTY (f
);
921 if (tty
->delete_in_insert_mode
)
923 tty_turn_on_insert (tty
);
927 tty_turn_off_insert (tty
);
928 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
931 if (tty
->TS_del_multi_chars
)
933 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
, 0, 0, 0);
938 for (i
= 0; i
< n
; i
++)
939 OUTPUT1 (tty
, tty
->TS_del_char
);
940 if (!tty
->delete_in_insert_mode
)
941 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
944 /* An implementation of ins_del_lines for termcap frames. */
947 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
949 struct tty_display_info
*tty
= FRAME_TTY (f
);
951 n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
952 const char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
953 const char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
958 /* If the lines below the insertion are being pushed
959 into the end of the window, this is the same as clearing;
960 and we know the lines are already clear, since the matching
961 deletion has already been done. So can ignore this. */
962 /* If the lines below the deletion are blank lines coming
963 out of the end of the window, don't bother,
964 as there will be a matching inslines later that will flush them. */
965 if (FRAME_SCROLL_REGION_OK (f
)
966 && vpos
+ i
>= tty
->specified_window
)
968 if (!FRAME_MEMORY_BELOW_FRAME (f
)
969 && vpos
+ i
>= FRAME_LINES (f
))
974 raw_cursor_to (f
, vpos
, 0);
975 tty_background_highlight (tty
);
976 buf
= tparam (multi
, 0, 0, i
, 0, 0, 0);
982 raw_cursor_to (f
, vpos
, 0);
983 tty_background_highlight (tty
);
985 OUTPUT (tty
, single
);
991 tty_set_scroll_region (f
, vpos
, tty
->specified_window
);
993 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
995 raw_cursor_to (f
, vpos
, 0);
996 tty_background_highlight (tty
);
998 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
999 tty_set_scroll_region (f
, 0, tty
->specified_window
);
1002 if (!FRAME_SCROLL_REGION_OK (f
)
1003 && FRAME_MEMORY_BELOW_FRAME (f
)
1006 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
1011 /* Compute cost of sending "str", in characters,
1012 not counting any line-dependent padding. */
1015 string_cost (const char *str
)
1019 tputs (str
, 0, evalcost
);
1023 /* Compute cost of sending "str", in characters,
1024 counting any line-dependent padding at one line. */
1027 string_cost_one_line (const char *str
)
1031 tputs (str
, 1, evalcost
);
1035 /* Compute per line amount of line-dependent padding,
1036 in tenths of characters. */
1039 per_line_cost (const char *str
)
1043 tputs (str
, 0, evalcost
);
1046 tputs (str
, 10, evalcost
);
1050 /* char_ins_del_cost[n] is cost of inserting N characters.
1051 char_ins_del_cost[-n] is cost of deleting N characters.
1052 The length of this vector is based on max_frame_cols. */
1054 int *char_ins_del_vector
;
1056 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1060 calculate_ins_del_char_costs (struct frame
*f
)
1062 struct tty_display_info
*tty
= FRAME_TTY (f
);
1063 int ins_startup_cost
, del_startup_cost
;
1064 int ins_cost_per_char
, del_cost_per_char
;
1068 if (tty
->TS_ins_multi_chars
)
1070 ins_cost_per_char
= 0;
1071 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1073 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1074 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1076 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1077 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1078 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1079 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1083 ins_startup_cost
= 9999;
1084 ins_cost_per_char
= 0;
1087 if (tty
->TS_del_multi_chars
)
1089 del_cost_per_char
= 0;
1090 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1092 else if (tty
->TS_del_char
)
1094 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1095 + string_cost (tty
->TS_end_delete_mode
));
1096 if (tty
->delete_in_insert_mode
)
1097 del_startup_cost
/= 2;
1098 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1102 del_startup_cost
= 9999;
1103 del_cost_per_char
= 0;
1106 /* Delete costs are at negative offsets */
1107 p
= &char_ins_del_cost (f
)[0];
1108 for (i
= FRAME_COLS (f
); --i
>= 0;)
1109 *--p
= (del_startup_cost
+= del_cost_per_char
);
1111 /* Doing nothing is free */
1112 p
= &char_ins_del_cost (f
)[0];
1115 /* Insert costs are at positive offsets */
1116 for (i
= FRAME_COLS (f
); --i
>= 0;)
1117 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1121 calculate_costs (struct frame
*frame
)
1123 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1125 if (FRAME_TERMCAP_P (frame
))
1127 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1128 register const char *f
= (tty
->TS_set_scroll_region
1129 ? tty
->TS_set_scroll_region
1130 : tty
->TS_set_scroll_region_1
);
1132 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1136 /* These variables are only used for terminal stuff. They are
1137 allocated once for the terminal frame of X-windows emacs, but not
1140 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1141 X turns off char_ins_del_ok. */
1143 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1144 if ((min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof (int) - 1) / 2
1146 memory_full (SIZE_MAX
);
1148 char_ins_del_vector
=
1149 xrealloc (char_ins_del_vector
,
1150 (sizeof (int) + 2 * sizeof (int) * max_frame_cols
));
1152 memset (char_ins_del_vector
, 0,
1153 (sizeof (int) + 2 * sizeof (int) * max_frame_cols
));
1156 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1157 do_line_insertion_deletion_costs (frame
,
1158 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1159 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1162 do_line_insertion_deletion_costs (frame
,
1163 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1164 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1167 calculate_ins_del_char_costs (frame
);
1169 /* Don't use TS_repeat if its padding is worse than sending the chars */
1170 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1171 tty
->RPov
= string_cost (tty
->TS_repeat
);
1173 tty
->RPov
= FRAME_COLS (frame
) * 2;
1175 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1180 const char *cap
, *name
;
1183 /* Termcap capability names that correspond directly to X keysyms.
1184 Some of these (marked "terminfo") aren't supplied by old-style
1185 (Berkeley) termcap entries. They're listed in X keysym order;
1186 except we put the keypad keys first, so that if they clash with
1187 other keys (as on the IBM PC keyboard) they get overridden.
1190 static const struct fkey_table keys
[] =
1192 {"kh", "home"}, /* termcap */
1193 {"kl", "left"}, /* termcap */
1194 {"ku", "up"}, /* termcap */
1195 {"kr", "right"}, /* termcap */
1196 {"kd", "down"}, /* termcap */
1197 {"%8", "prior"}, /* terminfo */
1198 {"%5", "next"}, /* terminfo */
1199 {"@7", "end"}, /* terminfo */
1200 {"@1", "begin"}, /* terminfo */
1201 {"*6", "select"}, /* terminfo */
1202 {"%9", "print"}, /* terminfo */
1203 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1205 * "insert" --- see below
1207 {"&8", "undo"}, /* terminfo */
1208 {"%0", "redo"}, /* terminfo */
1209 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1210 {"@0", "find"}, /* terminfo */
1211 {"@2", "cancel"}, /* terminfo */
1212 {"%1", "help"}, /* terminfo */
1214 * "break" goes here, but can't be reliably intercepted with termcap
1216 {"&4", "reset"}, /* terminfo --- actually `restart' */
1218 * "system" and "user" --- no termcaps
1220 {"kE", "clearline"}, /* terminfo */
1221 {"kA", "insertline"}, /* terminfo */
1222 {"kL", "deleteline"}, /* terminfo */
1223 {"kI", "insertchar"}, /* terminfo */
1224 {"kD", "deletechar"}, /* terminfo */
1225 {"kB", "backtab"}, /* terminfo */
1227 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1229 {"@8", "kp-enter"}, /* terminfo */
1231 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1232 * "kp-multiply", "kp-add", "kp-separator",
1233 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1234 * --- no termcaps for any of these.
1236 {"K4", "kp-1"}, /* terminfo */
1238 * "kp-2" --- no termcap
1240 {"K5", "kp-3"}, /* terminfo */
1242 * "kp-4" --- no termcap
1244 {"K2", "kp-5"}, /* terminfo */
1246 * "kp-6" --- no termcap
1248 {"K1", "kp-7"}, /* terminfo */
1250 * "kp-8" --- no termcap
1252 {"K3", "kp-9"}, /* terminfo */
1254 * "kp-equal" --- no termcap
1266 {"&0", "S-cancel"}, /*shifted cancel key*/
1267 {"&9", "S-begin"}, /*shifted begin key*/
1268 {"*0", "S-find"}, /*shifted find key*/
1269 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1270 {"*4", "S-delete"}, /*shifted delete-character key*/
1271 {"*7", "S-end"}, /*shifted end key*/
1272 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1273 {"#1", "S-help"}, /*shifted help key*/
1274 {"#2", "S-home"}, /*shifted home key*/
1275 {"#3", "S-insert"}, /*shifted insert-character key*/
1276 {"#4", "S-left"}, /*shifted left-arrow key*/
1277 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1278 {"%c", "S-next"}, /*shifted next key*/
1279 {"%e", "S-prior"}, /*shifted previous key*/
1280 {"%f", "S-print"}, /*shifted print key*/
1281 {"%g", "S-redo"}, /*shifted redo key*/
1282 {"%i", "S-right"}, /*shifted right-arrow key*/
1283 {"!3", "S-undo"} /*shifted undo key*/
1287 static char **term_get_fkeys_address
;
1288 static KBOARD
*term_get_fkeys_kboard
;
1289 static Lisp_Object
term_get_fkeys_1 (void);
1291 /* Find the escape codes sent by the function keys for Vinput_decode_map.
1292 This function scans the termcap function key sequence entries, and
1293 adds entries to Vinput_decode_map for each function key it finds. */
1296 term_get_fkeys (char **address
, KBOARD
*kboard
)
1298 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1299 errors during the call. The only errors should be from Fdefine_key
1300 when given a key sequence containing an invalid prefix key. If the
1301 termcap defines function keys which use a prefix that is already bound
1302 to a command by the default bindings, we should silently ignore that
1303 function key specification, rather than giving the user an error and
1304 refusing to run at all on such a terminal. */
1306 term_get_fkeys_address
= address
;
1307 term_get_fkeys_kboard
= kboard
;
1308 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1312 term_get_fkeys_1 (void)
1316 char **address
= term_get_fkeys_address
;
1317 KBOARD
*kboard
= term_get_fkeys_kboard
;
1319 /* This can happen if CANNOT_DUMP or with strange options. */
1320 if (!KEYMAPP (KVAR (kboard
, Vinput_decode_map
)))
1321 kset_input_decode_map (kboard
, Fmake_sparse_keymap (Qnil
));
1323 for (i
= 0; i
< (sizeof (keys
) / sizeof (keys
[0])); i
++)
1325 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1327 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (sequence
),
1328 Fmake_vector (make_number (1),
1329 intern (keys
[i
].name
)));
1332 /* The uses of the "k0" capability are inconsistent; sometimes it
1333 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1334 We will attempt to politely accommodate both systems by testing for
1335 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1338 const char *k_semi
= tgetstr ("k;", address
);
1339 const char *k0
= tgetstr ("k0", address
);
1340 const char *k0_name
= "f10";
1345 /* Define f0 first, so that f10 takes precedence in case the
1346 key sequences happens to be the same. */
1347 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (k0
),
1348 Fmake_vector (make_number (1), intern ("f0")));
1349 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (k_semi
),
1350 Fmake_vector (make_number (1), intern ("f10")));
1353 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (k0
),
1354 Fmake_vector (make_number (1), intern (k0_name
)));
1357 /* Set up cookies for numbered function keys above f10. */
1359 char fcap
[3], fkey
[4];
1361 fcap
[0] = 'F'; fcap
[2] = '\0';
1362 for (i
= 11; i
< 64; i
++)
1365 fcap
[1] = '1' + i
- 11;
1367 fcap
[1] = 'A' + i
- 20;
1369 fcap
[1] = 'a' + i
- 46;
1372 char *sequence
= tgetstr (fcap
, address
);
1375 sprintf (fkey
, "f%d", i
);
1376 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (sequence
),
1377 Fmake_vector (make_number (1),
1385 * Various mappings to try and get a better fit.
1388 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1389 if (!tgetstr (cap1, address)) \
1391 char *sequence = tgetstr (cap2, address); \
1393 Fdefine_key (KVAR (kboard, Vinput_decode_map), build_string (sequence), \
1394 Fmake_vector (make_number (1), \
1398 /* if there's no key_next keycap, map key_npage to `next' keysym */
1399 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1400 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1401 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1402 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1403 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1404 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1405 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1407 /* IBM has their own non-standard dialect of terminfo.
1408 If the standard name isn't found, try the IBM name. */
1409 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1410 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1411 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1412 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1413 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1414 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1415 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1416 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1417 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1418 #undef CONDITIONAL_REASSIGN
1423 #endif /* not DOS_NT */
1426 /***********************************************************************
1427 Character Display Information
1428 ***********************************************************************/
1429 static void append_glyph (struct it
*);
1430 static void append_composite_glyph (struct it
*);
1431 static void produce_composite_glyph (struct it
*);
1432 static void append_glyphless_glyph (struct it
*, int, const char *);
1433 static void produce_glyphless_glyph (struct it
*, Lisp_Object
);
1435 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1436 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1437 the character for which to produce glyphs; IT->face_id contains the
1438 character's face. Padding glyphs are appended if IT->c has a
1439 IT->pixel_width > 1. */
1442 append_glyph (struct it
*it
)
1444 struct glyph
*glyph
, *end
;
1447 eassert (it
->glyph_row
);
1448 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1449 + it
->glyph_row
->used
[it
->area
]);
1450 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1452 /* If the glyph row is reversed, we need to prepend the glyph rather
1454 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1457 int move_by
= it
->pixel_width
;
1459 /* Make room for the new glyphs. */
1460 if (move_by
> end
- glyph
) /* don't overstep end of this area */
1461 move_by
= end
- glyph
;
1462 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1464 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1465 end
= glyph
+ move_by
;
1468 /* BIDI Note: we put the glyphs of a "multi-pixel" character left to
1469 right, even in the REVERSED_P case, since (a) all of its u.ch are
1470 identical, and (b) the PADDING_P flag needs to be set for the
1471 leftmost one, because we write to the terminal left-to-right. */
1473 i
< it
->pixel_width
&& glyph
< end
;
1476 glyph
->type
= CHAR_GLYPH
;
1477 glyph
->pixel_width
= 1;
1478 glyph
->u
.ch
= it
->char_to_display
;
1479 glyph
->face_id
= it
->face_id
;
1480 glyph
->padding_p
= i
> 0;
1481 glyph
->charpos
= CHARPOS (it
->position
);
1482 glyph
->object
= it
->object
;
1485 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1486 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1488 glyph
->bidi_type
= it
->bidi_it
.type
;
1492 glyph
->resolved_level
= 0;
1493 glyph
->bidi_type
= UNKNOWN_BT
;
1496 ++it
->glyph_row
->used
[it
->area
];
1501 /* For external use. */
1503 tty_append_glyph (struct it
*it
)
1509 /* Produce glyphs for the display element described by IT. *IT
1510 specifies what we want to produce a glyph for (character, image, ...),
1511 and where in the glyph matrix we currently are (glyph row and hpos).
1512 produce_glyphs fills in output fields of *IT with information such as the
1513 pixel width and height of a character, and maybe output actual glyphs at
1514 the same time if IT->glyph_row is non-null. For an overview, see
1515 the explanation in dispextern.h, before the definition of the
1516 display_element_type enumeration.
1518 produce_glyphs also stores the result of glyph width, ascent
1519 etc. computations in *IT.
1521 IT->glyph_row may be null, in which case produce_glyphs does not
1522 actually fill in the glyphs. This is used in the move_* functions
1523 in xdisp.c for text width and height computations.
1525 Callers usually don't call produce_glyphs directly;
1526 instead they use the macro PRODUCE_GLYPHS. */
1529 produce_glyphs (struct it
*it
)
1531 /* If a hook is installed, let it do the work. */
1533 /* Nothing but characters are supported on terminal frames. */
1534 eassert (it
->what
== IT_CHARACTER
1535 || it
->what
== IT_COMPOSITION
1536 || it
->what
== IT_STRETCH
1537 || it
->what
== IT_GLYPHLESS
);
1539 if (it
->what
== IT_STRETCH
)
1541 produce_stretch_glyph (it
);
1545 if (it
->what
== IT_COMPOSITION
)
1547 produce_composite_glyph (it
);
1551 if (it
->what
== IT_GLYPHLESS
)
1553 produce_glyphless_glyph (it
, Qnil
);
1557 if (it
->char_to_display
>= 040 && it
->char_to_display
< 0177)
1559 it
->pixel_width
= it
->nglyphs
= 1;
1563 else if (it
->char_to_display
== '\n')
1564 it
->pixel_width
= it
->nglyphs
= 0;
1565 else if (it
->char_to_display
== '\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
;
1586 it
->char_to_display
= ' ';
1587 it
->pixel_width
= it
->len
= 1;
1593 it
->pixel_width
= nspaces
;
1594 it
->nglyphs
= nspaces
;
1596 else if (CHAR_BYTE8_P (it
->char_to_display
))
1598 /* Coming here means that we must send the raw 8-bit byte as is
1599 to the terminal. Although there's no way to know how many
1600 columns it occupies on a screen, it is a good assumption that
1601 a single byte code has 1-column width. */
1602 it
->pixel_width
= it
->nglyphs
= 1;
1608 Lisp_Object charset_list
= FRAME_TERMINAL (it
->f
)->charset_list
;
1610 if (char_charset (it
->char_to_display
, charset_list
, NULL
))
1612 it
->pixel_width
= CHAR_WIDTH (it
->char_to_display
);
1613 it
->nglyphs
= it
->pixel_width
;
1619 Lisp_Object acronym
= lookup_glyphless_char_display (-1, it
);
1621 eassert (it
->what
== IT_GLYPHLESS
);
1622 produce_glyphless_glyph (it
, acronym
);
1627 /* Advance current_x by the pixel width as a convenience for
1629 if (it
->area
== TEXT_AREA
)
1630 it
->current_x
+= it
->pixel_width
;
1631 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1632 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1635 /* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
1636 Called from produce_composite_glyph for terminal frames if
1637 IT->glyph_row != NULL. IT->face_id contains the character's
1641 append_composite_glyph (struct it
*it
)
1643 struct glyph
*glyph
;
1645 eassert (it
->glyph_row
);
1646 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1647 if (glyph
< it
->glyph_row
->glyphs
[1 + it
->area
])
1649 /* If the glyph row is reversed, we need to prepend the glyph
1650 rather than append it. */
1651 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1655 /* Make room for the new glyph. */
1656 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1658 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1660 glyph
->type
= COMPOSITE_GLYPH
;
1661 glyph
->pixel_width
= it
->pixel_width
;
1662 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1663 if (it
->cmp_it
.ch
< 0)
1665 glyph
->u
.cmp
.automatic
= 0;
1666 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1670 glyph
->u
.cmp
.automatic
= 1;
1671 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1672 glyph
->slice
.cmp
.from
= it
->cmp_it
.from
;
1673 glyph
->slice
.cmp
.to
= it
->cmp_it
.to
- 1;
1676 glyph
->face_id
= it
->face_id
;
1677 glyph
->padding_p
= 0;
1678 glyph
->charpos
= CHARPOS (it
->position
);
1679 glyph
->object
= it
->object
;
1682 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1683 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1685 glyph
->bidi_type
= it
->bidi_it
.type
;
1689 glyph
->resolved_level
= 0;
1690 glyph
->bidi_type
= UNKNOWN_BT
;
1693 ++it
->glyph_row
->used
[it
->area
];
1699 /* Produce a composite glyph for iterator IT. IT->cmp_id is the ID of
1700 the composition. We simply produces components of the composition
1701 assuming that the terminal has a capability to layout/render it
1705 produce_composite_glyph (struct it
*it
)
1707 if (it
->cmp_it
.ch
< 0)
1709 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
1711 it
->pixel_width
= cmp
->width
;
1715 Lisp_Object gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
1717 it
->pixel_width
= composition_gstring_width (gstring
, it
->cmp_it
.from
,
1718 it
->cmp_it
.to
, NULL
);
1722 append_composite_glyph (it
);
1726 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
1727 is a face ID to be used for the glyph. What is actually appended
1728 are glyphs of type CHAR_GLYPH whose characters are in STR (which
1729 comes from it->nglyphs bytes). */
1732 append_glyphless_glyph (struct it
*it
, int face_id
, const char *str
)
1734 struct glyph
*glyph
, *end
;
1737 eassert (it
->glyph_row
);
1738 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1739 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1741 /* If the glyph row is reversed, we need to prepend the glyph rather
1743 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1746 int move_by
= it
->pixel_width
;
1748 /* Make room for the new glyphs. */
1749 if (move_by
> end
- glyph
) /* don't overstep end of this area */
1750 move_by
= end
- glyph
;
1751 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1753 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1754 end
= glyph
+ move_by
;
1759 glyph
->type
= CHAR_GLYPH
;
1760 glyph
->pixel_width
= 1;
1761 glyph
->face_id
= face_id
;
1762 glyph
->padding_p
= 0;
1763 glyph
->charpos
= CHARPOS (it
->position
);
1764 glyph
->object
= it
->object
;
1767 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1768 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1770 glyph
->bidi_type
= it
->bidi_it
.type
;
1774 glyph
->resolved_level
= 0;
1775 glyph
->bidi_type
= UNKNOWN_BT
;
1778 /* BIDI Note: we put the glyphs of characters left to right, even in
1779 the REVERSED_P case because we write to the terminal
1781 for (i
= 0; i
< it
->nglyphs
&& glyph
< end
; ++i
)
1784 glyph
[0] = glyph
[-1];
1785 glyph
->u
.ch
= str
[i
];
1786 ++it
->glyph_row
->used
[it
->area
];
1791 /* Produce glyphs for a glyphless character for iterator IT.
1792 IT->glyphless_method specifies which method to use for displaying
1793 the character. See the description of enum
1794 glyphless_display_method in dispextern.h for the details.
1796 ACRONYM, if non-nil, is an acronym string for the character.
1798 The glyphs actually produced are of type CHAR_GLYPH. */
1801 produce_glyphless_glyph (struct it
*it
, Lisp_Object acronym
)
1803 int len
, face_id
= merge_glyphless_glyph_face (it
);
1804 char buf
[sizeof "\\x" + max (6, (sizeof it
->c
* CHAR_BIT
+ 3) / 4)];
1805 char const *str
= " ";
1807 if (it
->glyphless_method
== GLYPHLESS_DISPLAY_THIN_SPACE
)
1809 /* As there's no way to produce a thin space, we produce a space
1810 of canonical width. */
1813 else if (it
->glyphless_method
== GLYPHLESS_DISPLAY_EMPTY_BOX
)
1815 len
= CHAR_WIDTH (it
->c
);
1820 len
= sprintf (buf
, "[%.*s]", len
, str
);
1825 if (it
->glyphless_method
== GLYPHLESS_DISPLAY_ACRONYM
)
1827 if (! STRINGP (acronym
) && CHAR_TABLE_P (Vglyphless_char_display
))
1828 acronym
= CHAR_TABLE_REF (Vglyphless_char_display
, it
->c
);
1829 if (CONSP (acronym
))
1830 acronym
= XCDR (acronym
);
1832 str
= STRINGP (acronym
) ? SSDATA (acronym
) : "";
1833 for (len
= 0; len
< 6 && str
[len
] && ASCII_BYTE_P (str
[len
]); len
++)
1834 buf
[1 + len
] = str
[len
];
1840 eassert (it
->glyphless_method
== GLYPHLESS_DISPLAY_HEX_CODE
);
1841 len
= (it
->c
< 0x10000 ? sprintf (buf
, "\\u%04X", it
->c
)
1842 : it
->c
<= MAX_UNICODE_CHAR
? sprintf (buf
, "\\U%06X", it
->c
)
1843 : sprintf (buf
, "\\x%06X", it
->c
));
1848 it
->pixel_width
= len
;
1851 append_glyphless_glyph (it
, face_id
, str
);
1855 /***********************************************************************
1857 ***********************************************************************/
1859 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1860 one of the enumerators from enum no_color_bit, or a bit set built
1861 from them. Some display attributes may not be used together with
1862 color; the termcap capability `NC' specifies which ones. */
1864 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1865 (tty->TN_max_colors > 0 \
1866 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1869 /* Turn appearances of face FACE_ID on tty frame F on.
1870 FACE_ID is a realized face ID number, in the face cache. */
1873 turn_on_face (struct frame
*f
, int face_id
)
1875 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1876 long fg
= face
->foreground
;
1877 long bg
= face
->background
;
1878 struct tty_display_info
*tty
= FRAME_TTY (f
);
1880 /* Do this first because TS_end_standout_mode may be the same
1881 as TS_exit_attribute_mode, which turns all appearances off. */
1882 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1884 if (tty
->TN_max_colors
> 0)
1886 if (fg
>= 0 && bg
>= 0)
1888 /* If the terminal supports colors, we can set them
1889 below without using reverse video. The face's fg
1890 and bg colors are set as they should appear on
1891 the screen, i.e. they take the inverse-video'ness
1892 of the face already into account. */
1894 else if (inverse_video
)
1896 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1897 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1898 tty_toggle_highlight (tty
);
1902 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1903 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1904 tty_toggle_highlight (tty
);
1909 /* If we can't display colors, use reverse video
1910 if the face specifies that. */
1913 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1914 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1915 tty_toggle_highlight (tty
);
1919 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1920 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1921 tty_toggle_highlight (tty
);
1926 if (face
->tty_bold_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1927 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1929 if (face
->tty_italic_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_ITALIC
))
1931 if (tty
->TS_enter_italic_mode
)
1932 OUTPUT1 (tty
, tty
->TS_enter_italic_mode
);
1934 /* Italics mode is unavailable on many terminals. In that
1935 case, map slant to dimmed text; we want italic text to
1936 appear different and dimming is not otherwise used. */
1937 OUTPUT1 (tty
, tty
->TS_enter_dim_mode
);
1940 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1941 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1943 if (tty
->TN_max_colors
> 0)
1948 ts
= tty
->standout_mode
? tty
->TS_set_background
: tty
->TS_set_foreground
;
1951 p
= tparam (ts
, NULL
, 0, fg
, 0, 0, 0);
1956 ts
= tty
->standout_mode
? tty
->TS_set_foreground
: tty
->TS_set_background
;
1959 p
= tparam (ts
, NULL
, 0, bg
, 0, 0, 0);
1967 /* Turn off appearances of face FACE_ID on tty frame F. */
1970 turn_off_face (struct frame
*f
, int face_id
)
1972 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1973 struct tty_display_info
*tty
= FRAME_TTY (f
);
1975 eassert (face
!= NULL
);
1977 if (tty
->TS_exit_attribute_mode
)
1979 /* Capability "me" will turn off appearance modes double-bright,
1980 half-bright, reverse-video, standout, underline. It may or
1981 may not turn off alt-char-mode. */
1982 if (face
->tty_bold_p
1983 || face
->tty_italic_p
1984 || face
->tty_reverse_p
1985 || face
->tty_underline_p
)
1987 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
1988 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
1989 tty
->standout_mode
= 0;
1994 /* If we don't have "me" we can only have those appearances
1995 that have exit sequences defined. */
1996 if (face
->tty_underline_p
)
1997 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
2000 /* Switch back to default colors. */
2001 if (tty
->TN_max_colors
> 0
2002 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2003 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2004 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2005 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2006 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
2010 /* Return true if the terminal on frame F supports all of the
2011 capabilities in CAPS simultaneously, with foreground and background
2012 colors FG and BG. */
2015 tty_capable_p (struct tty_display_info
*tty
, unsigned int caps
,
2016 unsigned long fg
, unsigned long bg
)
2018 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
2019 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
2022 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
2023 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
2024 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
2025 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
2026 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ITALIC
, tty
->TS_enter_italic_mode
, NC_ITALIC
);
2032 /* Return non-zero if the terminal is capable to display colors. */
2034 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2036 doc
: /* Return non-nil if the tty device TERMINAL can display colors.
2038 TERMINAL can be a terminal object, a frame, or nil (meaning the
2039 selected frame's terminal). This function always returns nil if
2040 TERMINAL does not refer to a text terminal. */)
2041 (Lisp_Object terminal
)
2043 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2047 return t
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
2050 /* Return the number of supported colors. */
2051 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2052 Stty_display_color_cells
, 0, 1, 0,
2053 doc
: /* Return the number of colors supported by the tty device TERMINAL.
2055 TERMINAL can be a terminal object, a frame, or nil (meaning the
2056 selected frame's terminal). This function always returns 0 if
2057 TERMINAL does not refer to a text terminal. */)
2058 (Lisp_Object terminal
)
2060 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2062 return make_number (0);
2064 return make_number (t
->display_info
.tty
->TN_max_colors
);
2069 /* Declare here rather than in the function, as in the rest of Emacs,
2070 to work around an HPUX compiler bug (?). See
2071 http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00410.html */
2072 static int default_max_colors
;
2073 static int default_max_pairs
;
2074 static int default_no_color_video
;
2075 static char *default_orig_pair
;
2076 static char *default_set_foreground
;
2077 static char *default_set_background
;
2079 /* Save or restore the default color-related capabilities of this
2082 tty_default_color_capabilities (struct tty_display_info
*tty
, bool save
)
2087 xfree (default_orig_pair
);
2088 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
2090 xfree (default_set_foreground
);
2091 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
2094 xfree (default_set_background
);
2095 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
2098 default_max_colors
= tty
->TN_max_colors
;
2099 default_max_pairs
= tty
->TN_max_pairs
;
2100 default_no_color_video
= tty
->TN_no_color_video
;
2104 tty
->TS_orig_pair
= default_orig_pair
;
2105 tty
->TS_set_foreground
= default_set_foreground
;
2106 tty
->TS_set_background
= default_set_background
;
2107 tty
->TN_max_colors
= default_max_colors
;
2108 tty
->TN_max_pairs
= default_max_pairs
;
2109 tty
->TN_no_color_video
= default_no_color_video
;
2113 /* Setup one of the standard tty color schemes according to MODE.
2114 MODE's value is generally the number of colors which we want to
2115 support; zero means set up for the default capabilities, the ones
2116 we saw at init_tty time; -1 means turn off color support. */
2118 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2120 /* Canonicalize all negative values of MODE. */
2126 case -1: /* no colors at all */
2127 tty
->TN_max_colors
= 0;
2128 tty
->TN_max_pairs
= 0;
2129 tty
->TN_no_color_video
= 0;
2130 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2132 case 0: /* default colors, if any */
2134 tty_default_color_capabilities (tty
, 0);
2136 case 8: /* 8 standard ANSI colors */
2137 tty
->TS_orig_pair
= "\033[0m";
2139 tty
->TS_set_foreground
= "\033[3%p1%dm";
2140 tty
->TS_set_background
= "\033[4%p1%dm";
2142 tty
->TS_set_foreground
= "\033[3%dm";
2143 tty
->TS_set_background
= "\033[4%dm";
2145 tty
->TN_max_colors
= 8;
2146 tty
->TN_max_pairs
= 64;
2147 tty
->TN_no_color_video
= 0;
2153 set_tty_color_mode (struct tty_display_info
*tty
, struct frame
*f
)
2155 Lisp_Object tem
, val
;
2156 Lisp_Object color_mode
;
2158 Lisp_Object tty_color_mode_alist
2159 = Fintern_soft (build_string ("tty-color-mode-alist"), Qnil
);
2161 tem
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2162 val
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2166 else if (SYMBOLP (tty_color_mode_alist
))
2168 tem
= Fassq (val
, Fsymbol_value (tty_color_mode_alist
));
2169 color_mode
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2174 mode
= TYPE_RANGED_INTEGERP (int, color_mode
) ? XINT (color_mode
) : 0;
2176 if (mode
!= tty
->previous_color_mode
)
2178 tty
->previous_color_mode
= mode
;
2179 tty_setup_colors (tty
, mode
);
2180 /* This recomputes all the faces given the new color definitions. */
2181 safe_call (1, intern ("tty-set-up-initial-frame-faces"));
2185 #endif /* !DOS_NT */
2189 /* Return the tty display object specified by TERMINAL. */
2191 static struct terminal
*
2192 get_tty_terminal (Lisp_Object terminal
, bool throw)
2194 struct terminal
*t
= get_terminal (terminal
, throw);
2196 if (t
&& t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2199 error ("Device %d is not a termcap terminal device", t
->id
);
2207 /* Return an active termcap device that uses the tty device with the
2210 This function ignores suspended devices.
2212 Returns NULL if the named terminal device is not opened. */
2215 get_named_tty (const char *name
)
2221 for (t
= terminal_list
; t
; t
= t
->next_terminal
)
2223 if ((t
->type
== output_termcap
|| t
->type
== output_msdos_raw
)
2224 && !strcmp (t
->display_info
.tty
->name
, name
)
2225 && TERMINAL_ACTIVE_P (t
))
2233 DEFUN ("tty-type", Ftty_type
, Stty_type
, 0, 1, 0,
2234 doc
: /* Return the type of the tty device that TERMINAL uses.
2235 Returns nil if TERMINAL is not on a tty device.
2237 TERMINAL can be a terminal object, a frame, or nil (meaning the
2238 selected frame's terminal). */)
2239 (Lisp_Object terminal
)
2241 struct terminal
*t
= get_terminal (terminal
, 1);
2243 if (t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2246 if (t
->display_info
.tty
->type
)
2247 return build_string (t
->display_info
.tty
->type
);
2252 DEFUN ("controlling-tty-p", Fcontrolling_tty_p
, Scontrolling_tty_p
, 0, 1, 0,
2253 doc
: /* Return non-nil if TERMINAL is the controlling tty of the Emacs process.
2255 TERMINAL can be a terminal object, a frame, or nil (meaning the
2256 selected frame's terminal). This function always returns nil if
2257 TERMINAL is not on a tty device. */)
2258 (Lisp_Object terminal
)
2260 struct terminal
*t
= get_terminal (terminal
, 1);
2262 if ((t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2263 || strcmp (t
->display_info
.tty
->name
, DEV_TTY
) != 0)
2269 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 1, 0,
2270 doc
: /* Declare that the tty used by TERMINAL does not handle underlining.
2271 This is used to override the terminfo data, for certain terminals that
2272 do not really do underlining, but say that they do. This function has
2273 no effect if used on a non-tty terminal.
2275 TERMINAL can be a terminal object, a frame or nil (meaning the
2276 selected frame's terminal). This function always returns nil if
2277 TERMINAL does not refer to a text terminal. */)
2278 (Lisp_Object terminal
)
2280 struct terminal
*t
= get_terminal (terminal
, 1);
2282 if (t
->type
== output_termcap
)
2283 t
->display_info
.tty
->TS_enter_underline_mode
= 0;
2287 DEFUN ("tty-top-frame", Ftty_top_frame
, Stty_top_frame
, 0, 1, 0,
2288 doc
: /* Return the topmost terminal frame on TERMINAL.
2289 TERMINAL can be a terminal object, a frame or nil (meaning the
2290 selected frame's terminal). This function returns nil if TERMINAL
2291 does not refer to a text terminal. Otherwise, it returns the
2292 top-most frame on the text terminal. */)
2293 (Lisp_Object terminal
)
2295 struct terminal
*t
= get_terminal (terminal
, 1);
2297 if (t
->type
== output_termcap
)
2298 return t
->display_info
.tty
->top_frame
;
2304 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
2305 doc
: /* Suspend the terminal device TTY.
2307 The device is restored to its default state, and Emacs ceases all
2308 access to the tty device. Frames that use the device are not deleted,
2309 but input is not read from them and if they change, their display is
2312 TTY may be a terminal object, a frame, or nil for the terminal device
2313 of the currently selected frame.
2315 This function runs `suspend-tty-functions' after suspending the
2316 device. The functions are run with one arg, the id of the suspended
2319 `suspend-tty' does nothing if it is called on a device that is already
2322 A suspended tty may be resumed by calling `resume-tty' on it. */)
2325 struct terminal
*t
= get_tty_terminal (tty
, 1);
2329 error ("Unknown tty device");
2331 f
= t
->display_info
.tty
->input
;
2335 /* First run `suspend-tty-functions' and then clean up the tty
2336 state because `suspend-tty-functions' might need to change
2338 Lisp_Object args
[2];
2339 args
[0] = intern ("suspend-tty-functions");
2340 XSETTERMINAL (args
[1], t
);
2341 Frun_hook_with_args (2, args
);
2343 reset_sys_modes (t
->display_info
.tty
);
2344 delete_keyboard_wait_descriptor (fileno (f
));
2348 if (f
!= t
->display_info
.tty
->output
)
2349 fclose (t
->display_info
.tty
->output
);
2352 t
->display_info
.tty
->input
= 0;
2353 t
->display_info
.tty
->output
= 0;
2355 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2356 SET_FRAME_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 0);
2360 /* Clear display hooks to prevent further output. */
2361 clear_tty_hooks (t
);
2366 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
2367 doc
: /* Resume the previously suspended terminal device TTY.
2368 The terminal is opened and reinitialized. Frames that are on the
2369 suspended terminal are revived.
2371 It is an error to resume a terminal while another terminal is active
2374 This function runs `resume-tty-functions' after resuming the terminal.
2375 The functions are run with one arg, the id of the resumed terminal
2378 `resume-tty' does nothing if it is called on a device that is not
2381 TTY may be a terminal object, a frame, or nil (meaning the selected
2382 frame's terminal). */)
2385 struct terminal
*t
= get_tty_terminal (tty
, 1);
2389 error ("Unknown tty device");
2391 if (!t
->display_info
.tty
->input
)
2393 if (get_named_tty (t
->display_info
.tty
->name
))
2394 error ("Cannot resume display while another display is active on the same device");
2397 t
->display_info
.tty
->output
= stdout
;
2398 t
->display_info
.tty
->input
= stdin
;
2400 fd
= emacs_open (t
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
2401 t
->display_info
.tty
->input
= t
->display_info
.tty
->output
2402 = fd
< 0 ? 0 : fdopen (fd
, "w+");
2404 if (! t
->display_info
.tty
->input
)
2406 int open_errno
= errno
;
2408 report_file_errno ("Cannot reopen tty device",
2409 build_string (t
->display_info
.tty
->name
),
2413 if (!O_IGNORE_CTTY
&& strcmp (t
->display_info
.tty
->name
, DEV_TTY
) != 0)
2414 dissociate_if_controlling_tty (fd
);
2417 add_keyboard_wait_descriptor (fd
);
2419 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2421 struct frame
*f
= XFRAME (t
->display_info
.tty
->top_frame
);
2423 int old_height
= FRAME_COLS (f
);
2424 int old_width
= FRAME_LINES (f
);
2426 /* Check if terminal/window size has changed while the frame
2428 get_tty_size (fileno (t
->display_info
.tty
->input
), &width
, &height
);
2429 if (width
!= old_width
|| height
!= old_height
)
2430 change_frame_size (f
, height
, width
, 0, 0, 0);
2431 SET_FRAME_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 1);
2435 init_sys_modes (t
->display_info
.tty
);
2438 /* Run `resume-tty-functions'. */
2439 Lisp_Object args
[2];
2440 args
[0] = intern ("resume-tty-functions");
2441 XSETTERMINAL (args
[1], t
);
2442 Frun_hook_with_args (2, args
);
2452 /***********************************************************************
2454 ***********************************************************************/
2458 #ifndef HAVE_WINDOW_SYSTEM
2460 term_mouse_moveto (int x
, int y
)
2462 /* TODO: how to set mouse position?
2465 name = (const char *) ttyname (0);
2466 fd = emacs_open (name, O_WRONLY, 0);
2467 SOME_FUNCTION (x, y, fd);
2470 last_mouse_y = y; */
2472 #endif /* HAVE_WINDOW_SYSTEM */
2474 /* Implementation of draw_row_with_mouse_face for TTY/GPM. */
2476 tty_draw_row_with_mouse_face (struct window
*w
, struct glyph_row
*row
,
2477 int start_hpos
, int end_hpos
,
2478 enum draw_glyphs_face draw
)
2480 int nglyphs
= end_hpos
- start_hpos
;
2481 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
2482 struct tty_display_info
*tty
= FRAME_TTY (f
);
2483 int face_id
= tty
->mouse_highlight
.mouse_face_face_id
;
2484 int save_x
, save_y
, pos_x
, pos_y
;
2486 if (end_hpos
>= row
->used
[TEXT_AREA
])
2487 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2489 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2490 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
+ WINDOW_LEFT_EDGE_X (w
);
2492 /* Save current cursor co-ordinates. */
2493 save_y
= curY (tty
);
2494 save_x
= curX (tty
);
2495 cursor_to (f
, pos_y
, pos_x
);
2497 if (draw
== DRAW_MOUSE_FACE
)
2498 tty_write_glyphs_with_face (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
,
2500 else if (draw
== DRAW_NORMAL_TEXT
)
2501 write_glyphs (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2503 cursor_to (f
, save_y
, save_x
);
2507 term_mouse_movement (struct frame
*frame
, Gpm_Event
*event
)
2509 /* Has the mouse moved off the glyph it was on at the last sighting? */
2510 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2512 frame
->mouse_moved
= 1;
2513 note_mouse_highlight (frame
, event
->x
, event
->y
);
2514 /* Remember which glyph we're now on. */
2515 last_mouse_x
= event
->x
;
2516 last_mouse_y
= event
->y
;
2522 /* Return the Time that corresponds to T. Wrap around on overflow. */
2524 timeval_to_Time (struct timeval
const *t
)
2530 ms
= t
->tv_usec
/ 1000;
2534 /* Return the current position of the mouse.
2536 Set *f to the frame the mouse is in, or zero if the mouse is in no
2537 Emacs frame. If it is set to zero, all the other arguments are
2540 Set *bar_window to Qnil, and *x and *y to the column and
2541 row of the character cell the mouse is over.
2543 Set *timeptr to the time the mouse was at the returned position.
2545 This clears mouse_moved until the next motion
2548 term_mouse_position (struct frame
**fp
, int insist
, Lisp_Object
*bar_window
,
2549 enum scroll_bar_part
*part
, Lisp_Object
*x
,
2550 Lisp_Object
*y
, Time
*timeptr
)
2554 *fp
= SELECTED_FRAME ();
2555 (*fp
)->mouse_moved
= 0;
2560 XSETINT (*x
, last_mouse_x
);
2561 XSETINT (*y
, last_mouse_y
);
2562 gettimeofday(&now
, 0);
2563 *timeptr
= timeval_to_Time (&now
);
2566 /* Prepare a mouse-event in *RESULT for placement in the input queue.
2568 If the event is a button press, then note that we have grabbed
2572 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
2578 result
->kind
= GPM_CLICK_EVENT
;
2579 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
2581 if (event
->buttons
& j
) {
2582 result
->code
= i
; /* button number */
2586 gettimeofday(&now
, 0);
2587 result
->timestamp
= timeval_to_Time (&now
);
2589 if (event
->type
& GPM_UP
)
2590 result
->modifiers
= up_modifier
;
2591 else if (event
->type
& GPM_DOWN
)
2592 result
->modifiers
= down_modifier
;
2594 result
->modifiers
= 0;
2596 if (event
->type
& GPM_SINGLE
)
2597 result
->modifiers
|= click_modifier
;
2599 if (event
->type
& GPM_DOUBLE
)
2600 result
->modifiers
|= double_modifier
;
2602 if (event
->type
& GPM_TRIPLE
)
2603 result
->modifiers
|= triple_modifier
;
2605 if (event
->type
& GPM_DRAG
)
2606 result
->modifiers
|= drag_modifier
;
2608 if (!(event
->type
& (GPM_MOVE
| GPM_DRAG
))) {
2611 if (event
->modifiers
& (1 << 0))
2612 result
->modifiers
|= shift_modifier
;
2615 if (event
->modifiers
& (1 << 2))
2616 result
->modifiers
|= ctrl_modifier
;
2618 /* 1 << KG_ALT || KG_ALTGR */
2619 if (event
->modifiers
& (1 << 3)
2620 || event
->modifiers
& (1 << 1))
2621 result
->modifiers
|= meta_modifier
;
2624 XSETINT (result
->x
, event
->x
);
2625 XSETINT (result
->y
, event
->y
);
2626 XSETFRAME (result
->frame_or_window
, f
);
2632 handle_one_term_event (struct tty_display_info
*tty
, Gpm_Event
*event
, struct input_event
* hold_quit
)
2634 struct frame
*f
= XFRAME (tty
->top_frame
);
2635 struct input_event ie
;
2643 if (event
->type
& (GPM_MOVE
| GPM_DRAG
)) {
2644 previous_help_echo_string
= help_echo_string
;
2645 help_echo_string
= Qnil
;
2647 Gpm_DrawPointer (event
->x
, event
->y
, fileno (tty
->output
));
2649 if (!term_mouse_movement (f
, event
))
2650 help_echo_string
= previous_help_echo_string
;
2652 /* If the contents of the global variable help_echo_string
2653 has changed, generate a HELP_EVENT. */
2654 if (!NILP (help_echo_string
)
2655 || !NILP (previous_help_echo_string
))
2662 term_mouse_click (&ie
, event
, f
);
2666 if (ie
.kind
!= NO_EVENT
)
2668 kbd_buffer_store_event_hold (&ie
, hold_quit
);
2673 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
2678 XSETFRAME (frame
, f
);
2682 gen_help_event (help_echo_string
, frame
, help_echo_window
,
2683 help_echo_object
, help_echo_pos
);
2690 DEFUN ("gpm-mouse-start", Fgpm_mouse_start
, Sgpm_mouse_start
,
2692 doc
: /* Open a connection to Gpm.
2693 Gpm-mouse can only be activated for one tty at a time. */)
2696 struct frame
*f
= SELECTED_FRAME ();
2697 struct tty_display_info
*tty
2698 = ((f
)->output_method
== output_termcap
2699 ? (f
)->terminal
->display_info
.tty
: NULL
);
2700 Gpm_Connect connection
;
2703 error ("Gpm-mouse only works in the GNU/Linux console");
2705 return Qnil
; /* Already activated, nothing to do. */
2707 error ("Gpm-mouse can only be activated for one tty at a time");
2709 connection
.eventMask
= ~0;
2710 connection
.defaultMask
= ~GPM_HARD
;
2711 connection
.maxMod
= ~0;
2712 connection
.minMod
= 0;
2715 if (Gpm_Open (&connection
, 0) < 0)
2716 error ("Gpm-mouse failed to connect to the gpm daemon");
2720 /* `init_sys_modes' arranges for mouse movements sent through gpm_fd
2721 to generate SIGIOs. Apparently we need to call reset_sys_modes
2722 before calling init_sys_modes. */
2723 reset_sys_modes (tty
);
2724 init_sys_modes (tty
);
2725 add_gpm_wait_descriptor (gpm_fd
);
2734 delete_gpm_wait_descriptor (fd
);
2735 while (Gpm_Close()); /* close all the stack */
2739 DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop
, Sgpm_mouse_stop
,
2741 doc
: /* Close a connection to Gpm. */)
2744 struct frame
*f
= SELECTED_FRAME ();
2745 struct tty_display_info
*tty
2746 = ((f
)->output_method
== output_termcap
2747 ? (f
)->terminal
->display_info
.tty
: NULL
);
2749 if (!tty
|| gpm_tty
!= tty
)
2750 return Qnil
; /* Not activated on this terminal, nothing to do. */
2755 #endif /* HAVE_GPM */
2759 /***********************************************************************
2761 ***********************************************************************/
2763 /* Initialize the tty-dependent part of frame F. The frame must
2764 already have its device initialized. */
2767 create_tty_output (struct frame
*f
)
2769 struct tty_output
*t
= xzalloc (sizeof *t
);
2771 eassert (FRAME_TERMCAP_P (f
));
2773 t
->display_info
= FRAME_TERMINAL (f
)->display_info
.tty
;
2775 f
->output_data
.tty
= t
;
2778 /* Delete frame F's face cache, and its tty-dependent part. */
2781 tty_free_frame_resources (struct frame
*f
)
2783 eassert (FRAME_TERMCAP_P (f
));
2785 if (FRAME_FACE_CACHE (f
))
2786 free_frame_faces (f
);
2788 xfree (f
->output_data
.tty
);
2793 /* Delete frame F's face cache. */
2796 tty_free_frame_resources (struct frame
*f
)
2798 eassert (FRAME_TERMCAP_P (f
) || FRAME_MSDOS_P (f
));
2800 if (FRAME_FACE_CACHE (f
))
2801 free_frame_faces (f
);
2805 /* Reset the hooks in TERMINAL. */
2808 clear_tty_hooks (struct terminal
*terminal
)
2811 terminal
->cursor_to_hook
= 0;
2812 terminal
->raw_cursor_to_hook
= 0;
2813 terminal
->clear_to_end_hook
= 0;
2814 terminal
->clear_frame_hook
= 0;
2815 terminal
->clear_end_of_line_hook
= 0;
2816 terminal
->ins_del_lines_hook
= 0;
2817 terminal
->insert_glyphs_hook
= 0;
2818 terminal
->write_glyphs_hook
= 0;
2819 terminal
->delete_glyphs_hook
= 0;
2820 terminal
->ring_bell_hook
= 0;
2821 terminal
->reset_terminal_modes_hook
= 0;
2822 terminal
->set_terminal_modes_hook
= 0;
2823 terminal
->update_begin_hook
= 0;
2824 terminal
->update_end_hook
= 0;
2825 terminal
->set_terminal_window_hook
= 0;
2826 terminal
->mouse_position_hook
= 0;
2827 terminal
->frame_rehighlight_hook
= 0;
2828 terminal
->frame_raise_lower_hook
= 0;
2829 terminal
->fullscreen_hook
= 0;
2830 terminal
->set_vertical_scroll_bar_hook
= 0;
2831 terminal
->condemn_scroll_bars_hook
= 0;
2832 terminal
->redeem_scroll_bar_hook
= 0;
2833 terminal
->judge_scroll_bars_hook
= 0;
2834 terminal
->read_socket_hook
= 0;
2835 terminal
->frame_up_to_date_hook
= 0;
2837 /* Leave these two set, or suspended frames are not deleted
2839 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
2840 terminal
->delete_terminal_hook
= &delete_tty
;
2843 /* Initialize hooks in TERMINAL with the values needed for a tty. */
2846 set_tty_hooks (struct terminal
*terminal
)
2848 terminal
->rif
= 0; /* ttys don't support window-based redisplay. */
2850 terminal
->cursor_to_hook
= &tty_cursor_to
;
2851 terminal
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
2853 terminal
->clear_to_end_hook
= &tty_clear_to_end
;
2854 terminal
->clear_frame_hook
= &tty_clear_frame
;
2855 terminal
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
2857 terminal
->ins_del_lines_hook
= &tty_ins_del_lines
;
2859 terminal
->insert_glyphs_hook
= &tty_insert_glyphs
;
2860 terminal
->write_glyphs_hook
= &tty_write_glyphs
;
2861 terminal
->delete_glyphs_hook
= &tty_delete_glyphs
;
2863 terminal
->ring_bell_hook
= &tty_ring_bell
;
2865 terminal
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
2866 terminal
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
2867 terminal
->update_begin_hook
= 0; /* Not needed. */
2868 terminal
->update_end_hook
= &tty_update_end
;
2869 terminal
->set_terminal_window_hook
= &tty_set_terminal_window
;
2871 terminal
->mouse_position_hook
= 0; /* Not needed. */
2872 terminal
->frame_rehighlight_hook
= 0; /* Not needed. */
2873 terminal
->frame_raise_lower_hook
= 0; /* Not needed. */
2875 terminal
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
2876 terminal
->condemn_scroll_bars_hook
= 0; /* Not needed. */
2877 terminal
->redeem_scroll_bar_hook
= 0; /* Not needed. */
2878 terminal
->judge_scroll_bars_hook
= 0; /* Not needed. */
2880 terminal
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
2881 terminal
->frame_up_to_date_hook
= 0; /* Not needed. */
2883 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
2884 terminal
->delete_terminal_hook
= &delete_tty
;
2887 /* If FD is the controlling terminal, drop it. */
2889 dissociate_if_controlling_tty (int fd
)
2891 /* If tcgetpgrp succeeds, fd is the controlling terminal,
2892 so dissociate it by invoking setsid. */
2893 if (tcgetpgrp (fd
) >= 0 && setsid () < 0)
2896 /* setsid failed, presumably because Emacs is already a process
2897 group leader. Fall back on the obsolescent way to dissociate
2898 a controlling tty. */
2899 block_tty_out_signal ();
2900 ioctl (fd
, TIOCNOTTY
, 0);
2901 unblock_tty_out_signal ();
2906 /* Create a termcap display on the tty device with the given name and
2909 If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
2910 Otherwise NAME should be a path to the tty device file,
2913 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
2915 If MUST_SUCCEED is true, then all errors are fatal. */
2918 init_tty (const char *name
, const char *terminal_type
, bool must_succeed
)
2921 char **address
= &area
;
2923 struct tty_display_info
*tty
= NULL
;
2924 struct terminal
*terminal
= NULL
;
2925 bool ctty
= false; /* True if asked to open controlling tty. */
2928 maybe_fatal (must_succeed
, 0,
2929 "Unknown terminal type",
2930 "Unknown terminal type");
2934 if (!strcmp (name
, DEV_TTY
))
2937 /* If we already have a terminal on the given device, use that. If
2938 all such terminals are suspended, create a new one instead. */
2939 /* XXX Perhaps this should be made explicit by having init_tty
2940 always create a new terminal and separating terminal and frame
2941 creation on Lisp level. */
2942 terminal
= get_named_tty (name
);
2946 terminal
= create_terminal ();
2949 maybe_fatal (0, 0, "Attempt to create another terminal %s", "",
2952 tty
= &the_only_display_info
;
2954 tty
= xzalloc (sizeof *tty
);
2956 tty
->top_frame
= Qnil
;
2957 tty
->next
= tty_list
;
2960 terminal
->type
= output_termcap
;
2961 terminal
->display_info
.tty
= tty
;
2962 tty
->terminal
= terminal
;
2964 tty
->Wcm
= xmalloc (sizeof *tty
->Wcm
);
2967 encode_terminal_src_size
= 0;
2968 encode_terminal_dst_size
= 0;
2972 set_tty_hooks (terminal
);
2975 /* Open the terminal device. */
2977 /* If !ctty, don't recognize it as our controlling terminal, and
2978 don't make it the controlling tty if we don't have one now.
2980 Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
2981 defined on Hurd. On other systems, we need to explicitly
2982 dissociate ourselves from the controlling tty when we want to
2983 open a frame on the same terminal. */
2984 int flags
= O_RDWR
| O_NOCTTY
| (ctty
? 0 : O_IGNORE_CTTY
);
2985 int fd
= emacs_open (name
, flags
, 0);
2986 tty
->input
= tty
->output
= fd
< 0 || ! isatty (fd
) ? 0 : fdopen (fd
, "w+");
2990 char const *diagnostic
2991 = tty
->input
? "Not a tty device: %s" : "Could not open file: %s";
2993 maybe_fatal (must_succeed
, terminal
, diagnostic
, diagnostic
, name
);
2996 tty
->name
= xstrdup (name
);
2997 terminal
->name
= xstrdup (name
);
2999 if (!O_IGNORE_CTTY
&& !ctty
)
3000 dissociate_if_controlling_tty (fd
);
3003 tty
->type
= xstrdup (terminal_type
);
3005 add_keyboard_wait_descriptor (fileno (tty
->input
));
3009 /* On some systems, tgetent tries to access the controlling
3011 block_tty_out_signal ();
3012 status
= tgetent (tty
->termcap_term_buffer
, terminal_type
);
3013 if (tty
->termcap_term_buffer
[TERMCAP_BUFFER_SIZE
- 1])
3015 unblock_tty_out_signal ();
3020 maybe_fatal (must_succeed
, terminal
,
3021 "Cannot open terminfo database file",
3022 "Cannot open terminfo database file");
3024 maybe_fatal (must_succeed
, terminal
,
3025 "Cannot open termcap database file",
3026 "Cannot open termcap database file");
3031 maybe_fatal (must_succeed
, terminal
,
3032 "Terminal type %s is not defined",
3033 "Terminal type %s is not defined.\n\
3034 If that is not the actual type of terminal you have,\n\
3035 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3036 `setenv TERM ...') to specify the correct type. It may be necessary\n"
3038 "to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3040 "to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3045 area
= tty
->termcap_strings_buffer
;
3046 tty
->TS_ins_line
= tgetstr ("al", address
);
3047 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
3048 tty
->TS_bell
= tgetstr ("bl", address
);
3049 BackTab (tty
) = tgetstr ("bt", address
);
3050 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
3051 tty
->TS_clr_line
= tgetstr ("ce", address
);
3052 tty
->TS_clr_frame
= tgetstr ("cl", address
);
3053 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
3054 AbsPosition (tty
) = tgetstr ("cm", address
);
3055 CR (tty
) = tgetstr ("cr", address
);
3056 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
3057 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
3058 RowPosition (tty
) = tgetstr ("cv", address
);
3059 tty
->TS_del_char
= tgetstr ("dc", address
);
3060 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
3061 tty
->TS_del_line
= tgetstr ("dl", address
);
3062 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
3063 tty
->TS_delete_mode
= tgetstr ("dm", address
);
3064 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
3065 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
3066 Home (tty
) = tgetstr ("ho", address
);
3067 tty
->TS_ins_char
= tgetstr ("ic", address
);
3068 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
3069 tty
->TS_insert_mode
= tgetstr ("im", address
);
3070 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
3071 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
3072 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
3073 LastLine (tty
) = tgetstr ("ll", address
);
3074 Right (tty
) = tgetstr ("nd", address
);
3075 Down (tty
) = tgetstr ("do", address
);
3077 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do". */
3078 if (tgetflag ("bs"))
3079 Left (tty
) = "\b"; /* Can't possibly be longer! */
3080 else /* (Actually, "bs" is obsolete...) */
3081 Left (tty
) = tgetstr ("le", address
);
3083 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le". */
3084 tty
->TS_pad_char
= tgetstr ("pc", address
);
3085 tty
->TS_repeat
= tgetstr ("rp", address
);
3086 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
3087 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
3088 tty
->TS_standout_mode
= tgetstr ("so", address
);
3089 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
3090 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
3091 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
3092 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
3093 Up (tty
) = tgetstr ("up", address
);
3094 tty
->TS_visible_bell
= tgetstr ("vb", address
);
3095 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
3096 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
3097 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
3098 tty
->TS_set_window
= tgetstr ("wi", address
);
3100 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
3101 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
3102 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
3103 tty
->TS_enter_italic_mode
= tgetstr ("ZH", address
);
3104 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
3105 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
3106 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3107 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3108 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
3110 MultiUp (tty
) = tgetstr ("UP", address
);
3111 MultiDown (tty
) = tgetstr ("DO", address
);
3112 MultiLeft (tty
) = tgetstr ("LE", address
);
3113 MultiRight (tty
) = tgetstr ("RI", address
);
3115 /* SVr4/ANSI color support. If "op" isn't available, don't support
3116 color because we can't switch back to the default foreground and
3118 tty
->TS_orig_pair
= tgetstr ("op", address
);
3119 if (tty
->TS_orig_pair
)
3121 tty
->TS_set_foreground
= tgetstr ("AF", address
);
3122 tty
->TS_set_background
= tgetstr ("AB", address
);
3123 if (!tty
->TS_set_foreground
)
3126 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
3127 tty
->TS_set_background
= tgetstr ("Sb", address
);
3130 tty
->TN_max_colors
= tgetnum ("Co");
3131 tty
->TN_max_pairs
= tgetnum ("pa");
3133 tty
->TN_no_color_video
= tgetnum ("NC");
3134 if (tty
->TN_no_color_video
== -1)
3135 tty
->TN_no_color_video
= 0;
3138 tty_default_color_capabilities (tty
, 1);
3140 MagicWrap (tty
) = tgetflag ("xn");
3141 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3142 the former flag imply the latter. */
3143 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
3144 terminal
->memory_below_frame
= tgetflag ("db");
3145 tty
->TF_hazeltine
= tgetflag ("hz");
3146 terminal
->must_write_spaces
= tgetflag ("in");
3147 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
3148 tty
->TF_insmode_motion
= tgetflag ("mi");
3149 tty
->TF_standout_motion
= tgetflag ("ms");
3150 tty
->TF_underscore
= tgetflag ("ul");
3151 tty
->TF_teleray
= tgetflag ("xt");
3156 struct frame
*f
= XFRAME (selected_frame
);
3159 initialize_w32_display (terminal
, &width
, &height
);
3161 FrameRows (tty
) = height
;
3162 FrameCols (tty
) = width
;
3163 tty
->specified_window
= height
;
3165 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
3166 terminal
->char_ins_del_ok
= 1;
3172 if (strcmp (terminal_type
, "internal") == 0)
3173 terminal
->type
= output_msdos_raw
;
3174 initialize_msdos_display (terminal
);
3176 get_tty_size (fileno (tty
->input
), &width
, &height
);
3177 FrameCols (tty
) = width
;
3178 FrameRows (tty
) = height
;
3179 terminal
->char_ins_del_ok
= 0;
3180 init_baud_rate (fileno (tty
->input
));
3183 tty
->output
= stdout
;
3185 /* The following two are inaccessible from w32console.c. */
3186 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3187 terminal
->delete_terminal_hook
= &delete_tty
;
3189 tty
->name
= xstrdup (name
);
3190 terminal
->name
= xstrdup (name
);
3191 tty
->type
= xstrdup (terminal_type
);
3193 add_keyboard_wait_descriptor (0);
3195 tty
->delete_in_insert_mode
= 1;
3198 terminal
->scroll_region_ok
= 0;
3200 /* Seems to insert lines when it's not supposed to, messing up the
3201 display. In doing a trace, it didn't seem to be called much, so I
3202 don't think we're losing anything by turning it off. */
3203 terminal
->line_ins_del_ok
= 0;
3205 tty
->TN_max_colors
= 16; /* Must be non-zero for tty-display-color-p. */
3209 terminal
->mouse_position_hook
= term_mouse_position
;
3210 tty
->mouse_highlight
.mouse_face_window
= Qnil
;
3213 terminal
->kboard
= xmalloc (sizeof *terminal
->kboard
);
3214 init_kboard (terminal
->kboard
);
3215 kset_window_system (terminal
->kboard
, Qnil
);
3216 terminal
->kboard
->next_kboard
= all_kboards
;
3217 all_kboards
= terminal
->kboard
;
3218 terminal
->kboard
->reference_count
++;
3219 /* Don't let the initial kboard remain current longer than necessary.
3220 That would cause problems if a file loaded on startup tries to
3221 prompt in the mini-buffer. */
3222 if (current_kboard
== initial_kboard
)
3223 current_kboard
= terminal
->kboard
;
3225 term_get_fkeys (address
, terminal
->kboard
);
3227 /* Get frame size from system, or else from termcap. */
3230 get_tty_size (fileno (tty
->input
), &width
, &height
);
3231 FrameCols (tty
) = width
;
3232 FrameRows (tty
) = height
;
3235 if (FrameCols (tty
) <= 0)
3236 FrameCols (tty
) = tgetnum ("co");
3237 if (FrameRows (tty
) <= 0)
3238 FrameRows (tty
) = tgetnum ("li");
3240 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
3241 maybe_fatal (must_succeed
, terminal
,
3242 "Screen size %dx%d is too small",
3243 "Screen size %dx%d is too small",
3244 FrameCols (tty
), FrameRows (tty
));
3246 TabWidth (tty
) = tgetnum ("tw");
3249 tty
->TS_bell
= "\07";
3251 if (!tty
->TS_fwd_scroll
)
3252 tty
->TS_fwd_scroll
= Down (tty
);
3254 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
3256 if (TabWidth (tty
) < 0)
3259 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3260 and newer termcap doc does not seem to say there is a default.
3261 if (!tty->Wcm->cm_tab)
3262 tty->Wcm->cm_tab = "\t";
3265 /* We don't support standout modes that use `magic cookies', so
3266 turn off any that do. */
3267 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
3269 tty
->TS_standout_mode
= 0;
3270 tty
->TS_end_standout_mode
= 0;
3272 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3274 tty
->TS_enter_underline_mode
= 0;
3275 tty
->TS_exit_underline_mode
= 0;
3278 /* If there's no standout mode, try to use underlining instead. */
3279 if (tty
->TS_standout_mode
== 0)
3281 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
3282 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
3285 /* If no `se' string, try using a `me' string instead.
3286 If that fails, we can't use standout mode at all. */
3287 if (tty
->TS_end_standout_mode
== 0)
3289 char *s
= tgetstr ("me", address
);
3291 tty
->TS_end_standout_mode
= s
;
3293 tty
->TS_standout_mode
= 0;
3296 if (tty
->TF_teleray
)
3298 tty
->Wcm
->cm_tab
= 0;
3299 /* We can't support standout mode, because it uses magic cookies. */
3300 tty
->TS_standout_mode
= 0;
3301 /* But that means we cannot rely on ^M to go to column zero! */
3303 /* LF can't be trusted either -- can alter hpos. */
3304 /* If move at column 0 thru a line with TS_standout_mode. */
3308 tty
->specified_window
= FrameRows (tty
);
3310 if (Wcm_init (tty
) == -1) /* Can't do cursor motion. */
3312 maybe_fatal (must_succeed
, terminal
,
3313 "Terminal type \"%s\" is not powerful enough to run Emacs",
3314 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3315 It lacks the ability to position the cursor.\n\
3316 If that is not the actual type of terminal you have,\n\
3317 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3318 `setenv TERM ...') to specify the correct type. It may be necessary\n"
3320 "to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3321 # else /* TERMCAP */
3322 "to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3323 # endif /* TERMINFO */
3327 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
3328 maybe_fatal (must_succeed
, terminal
,
3329 "Could not determine the frame size",
3330 "Could not determine the frame size");
3332 tty
->delete_in_insert_mode
3333 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
3334 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
3336 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
3338 terminal
->scroll_region_ok
3340 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
3342 terminal
->line_ins_del_ok
3343 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
3344 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
3345 || (terminal
->scroll_region_ok
3346 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
3348 terminal
->char_ins_del_ok
3349 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
3350 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
3351 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
3353 terminal
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
3355 init_baud_rate (fileno (tty
->input
));
3357 #endif /* not DOS_NT */
3359 /* Init system terminal modes (RAW or CBREAK, etc.). */
3360 init_sys_modes (tty
);
3367 vfatal (const char *str
, va_list ap
)
3369 fprintf (stderr
, "emacs: ");
3370 vfprintf (stderr
, str
, ap
);
3371 if (!(strlen (str
) > 0 && str
[strlen (str
) - 1] == '\n'))
3372 fprintf (stderr
, "\n");
3378 /* Auxiliary error-handling function for init_tty.
3379 Delete TERMINAL, then call error or fatal with str1 or str2,
3380 respectively, according to whether MUST_SUCCEED is true. */
3383 maybe_fatal (bool must_succeed
, struct terminal
*terminal
,
3384 const char *str1
, const char *str2
, ...)
3387 va_start (ap
, str2
);
3389 delete_tty (terminal
);
3398 fatal (const char *str
, ...)
3407 /* Delete the given tty terminal, closing all frames on it. */
3410 delete_tty (struct terminal
*terminal
)
3412 struct tty_display_info
*tty
;
3414 /* Protect against recursive calls. delete_frame in
3415 delete_terminal calls us back when it deletes our last frame. */
3416 if (!terminal
->name
)
3419 eassert (terminal
->type
== output_termcap
);
3421 tty
= terminal
->display_info
.tty
;
3423 if (tty
== tty_list
)
3424 tty_list
= tty
->next
;
3427 struct tty_display_info
*p
;
3428 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
3432 /* This should not happen. */
3435 p
->next
= tty
->next
;
3439 /* reset_sys_modes needs a valid device, so this call needs to be
3440 before delete_terminal. */
3441 reset_sys_modes (tty
);
3443 delete_terminal (terminal
);
3450 delete_keyboard_wait_descriptor (fileno (tty
->input
));
3451 if (tty
->input
!= stdin
)
3452 fclose (tty
->input
);
3454 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
3455 fclose (tty
->output
);
3456 if (tty
->termscript
)
3457 fclose (tty
->termscript
);
3459 xfree (tty
->old_tty
);
3467 DEFVAR_BOOL ("system-uses-terminfo", system_uses_terminfo
,
3468 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3469 This variable can be used by terminal emulator packages. */);
3471 system_uses_terminfo
= 1;
3473 system_uses_terminfo
= 0;
3476 DEFVAR_LISP ("suspend-tty-functions", Vsuspend_tty_functions
,
3477 doc
: /* Functions run after suspending a tty.
3478 The functions are run with one argument, the terminal object to be suspended.
3479 See `suspend-tty'. */);
3480 Vsuspend_tty_functions
= Qnil
;
3483 DEFVAR_LISP ("resume-tty-functions", Vresume_tty_functions
,
3484 doc
: /* Functions run after resuming a tty.
3485 The functions are run with one argument, the terminal object that was revived.
3486 See `resume-tty'. */);
3487 Vresume_tty_functions
= Qnil
;
3489 DEFVAR_BOOL ("visible-cursor", visible_cursor
,
3490 doc
: /* Non-nil means to make the cursor very visible.
3491 This only has an effect when running in a text terminal.
3492 What means \"very visible\" is up to your terminal. It may make the cursor
3493 bigger, or it may make it blink, or it may do nothing at all. */);
3496 defsubr (&Stty_display_color_p
);
3497 defsubr (&Stty_display_color_cells
);
3498 defsubr (&Stty_no_underline
);
3499 defsubr (&Stty_type
);
3500 defsubr (&Scontrolling_tty_p
);
3501 defsubr (&Stty_top_frame
);
3502 defsubr (&Ssuspend_tty
);
3503 defsubr (&Sresume_tty
);
3505 defsubr (&Sgpm_mouse_start
);
3506 defsubr (&Sgpm_mouse_stop
);
3507 #endif /* HAVE_GPM */
3510 default_orig_pair
= NULL
;
3511 default_set_foreground
= NULL
;
3512 default_set_background
= NULL
;
3513 #endif /* !DOS_NT */
3515 encode_terminal_src
= NULL
;
3516 encode_terminal_dst
= NULL
;