1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2012
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 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
, int);
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 (int must_succeed
, struct terminal
*terminal
,
80 const char *str1
, const char *str2
, ...)
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 (int) (FRAME_LINES (XFRAME (selected_frame)) \
92 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
93 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
95 #define OUTPUT_IF(tty, a) \
101 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
103 /* Display space properties */
105 /* Chain of all tty device parameters. */
106 struct tty_display_info
*tty_list
;
108 /* Meaning of bits in no_color_video. Each bit set means that the
109 corresponding attribute cannot be combined with colors. */
113 NC_STANDOUT
= 1 << 0,
114 NC_UNDERLINE
= 1 << 1,
125 /* The largest frame width in any call to calculate_costs. */
127 static int max_frame_cols
;
132 #include <sys/fcntl.h>
134 /* The device for which we have enabled gpm support (or NULL). */
135 struct tty_display_info
*gpm_tty
= NULL
;
137 /* Last recorded mouse coordinates. */
138 static int last_mouse_x
, last_mouse_y
;
139 #endif /* HAVE_GPM */
141 /* Ring the bell on a tty. */
144 tty_ring_bell (struct frame
*f
)
146 struct tty_display_info
*tty
= FRAME_TTY (f
);
150 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
151 ? tty
->TS_visible_bell
153 fflush (tty
->output
);
157 /* Set up termcap modes for Emacs. */
160 tty_set_terminal_modes (struct terminal
*terminal
)
162 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
166 if (tty
->TS_termcap_modes
)
167 OUTPUT (tty
, tty
->TS_termcap_modes
);
170 /* Output enough newlines to scroll all the old screen contents
171 off the screen, so it won't be overwritten and lost. */
174 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
178 OUTPUT_IF (tty
, visible_cursor
? tty
->TS_cursor_visible
: tty
->TS_cursor_normal
);
179 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
181 fflush (tty
->output
);
185 /* Reset termcap modes before exiting Emacs. */
188 tty_reset_terminal_modes (struct terminal
*terminal
)
190 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
194 tty_turn_off_highlight (tty
);
195 tty_turn_off_insert (tty
);
196 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
197 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
198 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
199 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
200 /* Output raw CR so kernel can track the cursor hpos. */
203 fflush (tty
->output
);
207 /* Flag the end of a display update on a termcap terminal. */
210 tty_update_end (struct frame
*f
)
212 struct tty_display_info
*tty
= FRAME_TTY (f
);
214 if (!XWINDOW (selected_window
)->cursor_off_p
)
215 tty_show_cursor (tty
);
216 tty_turn_off_insert (tty
);
217 tty_background_highlight (tty
);
220 /* The implementation of set_terminal_window for termcap frames. */
223 tty_set_terminal_window (struct frame
*f
, int size
)
225 struct tty_display_info
*tty
= FRAME_TTY (f
);
227 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
228 if (FRAME_SCROLL_REGION_OK (f
))
229 tty_set_scroll_region (f
, 0, tty
->specified_window
);
233 tty_set_scroll_region (struct frame
*f
, int start
, int stop
)
236 struct tty_display_info
*tty
= FRAME_TTY (f
);
238 if (tty
->TS_set_scroll_region
)
239 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1, 0, 0);
240 else if (tty
->TS_set_scroll_region_1
)
241 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
242 FRAME_LINES (f
), start
,
243 FRAME_LINES (f
) - stop
,
246 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
255 tty_turn_on_insert (struct tty_display_info
*tty
)
257 if (!tty
->insert_mode
)
258 OUTPUT (tty
, tty
->TS_insert_mode
);
259 tty
->insert_mode
= 1;
263 tty_turn_off_insert (struct tty_display_info
*tty
)
265 if (tty
->insert_mode
)
266 OUTPUT (tty
, tty
->TS_end_insert_mode
);
267 tty
->insert_mode
= 0;
270 /* Handle highlighting. */
273 tty_turn_off_highlight (struct tty_display_info
*tty
)
275 if (tty
->standout_mode
)
276 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
277 tty
->standout_mode
= 0;
281 tty_turn_on_highlight (struct tty_display_info
*tty
)
283 if (!tty
->standout_mode
)
284 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
285 tty
->standout_mode
= 1;
289 tty_toggle_highlight (struct tty_display_info
*tty
)
291 if (tty
->standout_mode
)
292 tty_turn_off_highlight (tty
);
294 tty_turn_on_highlight (tty
);
298 /* Make cursor invisible. */
301 tty_hide_cursor (struct tty_display_info
*tty
)
303 if (tty
->cursor_hidden
== 0)
305 tty
->cursor_hidden
= 1;
306 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
311 /* Ensure that cursor is visible. */
314 tty_show_cursor (struct tty_display_info
*tty
)
316 if (tty
->cursor_hidden
)
318 tty
->cursor_hidden
= 0;
319 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
321 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
326 /* Set standout mode to the state it should be in for
327 empty space inside windows. What this is,
328 depends on the user option inverse-video. */
331 tty_background_highlight (struct tty_display_info
*tty
)
334 tty_turn_on_highlight (tty
);
336 tty_turn_off_highlight (tty
);
339 /* Set standout mode to the mode specified for the text to be output. */
342 tty_highlight_if_desired (struct tty_display_info
*tty
)
345 tty_turn_on_highlight (tty
);
347 tty_turn_off_highlight (tty
);
351 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
352 frame-relative coordinates. */
355 tty_cursor_to (struct frame
*f
, int vpos
, int hpos
)
357 struct tty_display_info
*tty
= FRAME_TTY (f
);
359 /* Detect the case where we are called from reset_sys_modes
360 and the costs have never been calculated. Do nothing. */
361 if (! tty
->costs_set
)
364 if (curY (tty
) == vpos
365 && curX (tty
) == hpos
)
367 if (!tty
->TF_standout_motion
)
368 tty_background_highlight (tty
);
369 if (!tty
->TF_insmode_motion
)
370 tty_turn_off_insert (tty
);
371 cmgoto (tty
, vpos
, hpos
);
374 /* Similar but don't take any account of the wasted characters. */
377 tty_raw_cursor_to (struct frame
*f
, int row
, int col
)
379 struct tty_display_info
*tty
= FRAME_TTY (f
);
381 if (curY (tty
) == row
382 && curX (tty
) == col
)
384 if (!tty
->TF_standout_motion
)
385 tty_background_highlight (tty
);
386 if (!tty
->TF_insmode_motion
)
387 tty_turn_off_insert (tty
);
388 cmgoto (tty
, row
, col
);
391 /* Erase operations */
393 /* Clear from cursor to end of frame on a termcap device. */
396 tty_clear_to_end (struct frame
*f
)
399 struct tty_display_info
*tty
= FRAME_TTY (f
);
401 if (tty
->TS_clr_to_bottom
)
403 tty_background_highlight (tty
);
404 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
408 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
411 clear_end_of_line (f
, FRAME_COLS (f
));
416 /* Clear an entire termcap frame. */
419 tty_clear_frame (struct frame
*f
)
421 struct tty_display_info
*tty
= FRAME_TTY (f
);
423 if (tty
->TS_clr_frame
)
425 tty_background_highlight (tty
);
426 OUTPUT (tty
, tty
->TS_clr_frame
);
436 /* An implementation of clear_end_of_line for termcap frames.
438 Note that the cursor may be moved, on terminals lacking a `ce' string. */
441 tty_clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
444 struct tty_display_info
*tty
= FRAME_TTY (f
);
446 /* Detect the case where we are called from reset_sys_modes
447 and the costs have never been calculated. Do nothing. */
448 if (! tty
->costs_set
)
451 if (curX (tty
) >= first_unused_hpos
)
453 tty_background_highlight (tty
);
454 if (tty
->TS_clr_line
)
456 OUTPUT1 (tty
, tty
->TS_clr_line
);
459 { /* have to do it the hard way */
460 tty_turn_off_insert (tty
);
462 /* Do not write in last row last col with Auto-wrap on. */
464 && curY (tty
) == FrameRows (tty
) - 1
465 && first_unused_hpos
== FrameCols (tty
))
468 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
471 fputc (' ', tty
->termscript
);
472 fputc (' ', tty
->output
);
474 cmplus (tty
, first_unused_hpos
- curX (tty
));
478 /* Buffers to store the source and result of code conversion for terminal. */
479 static unsigned char *encode_terminal_src
;
480 static unsigned char *encode_terminal_dst
;
481 /* Allocated sizes of the above buffers. */
482 static ptrdiff_t encode_terminal_src_size
;
483 static ptrdiff_t encode_terminal_dst_size
;
485 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
486 Set CODING->produced to the byte-length of the resulting byte
487 sequence, and return a pointer to that byte sequence. */
490 encode_terminal_code (struct glyph
*src
, int src_len
, struct coding_system
*coding
)
492 struct glyph
*src_end
= src
+ src_len
;
494 ptrdiff_t nchars
, nbytes
, required
;
495 ptrdiff_t tlen
= GLYPH_TABLE_LENGTH
;
496 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
497 Lisp_Object charset_list
;
499 /* Allocate sufficient size of buffer to store all characters in
500 multibyte-form. But, it may be enlarged on demand if
501 Vglyph_table contains a string or a composite glyph is
503 if (min (PTRDIFF_MAX
, SIZE_MAX
) / MAX_MULTIBYTE_LENGTH
< src_len
)
504 memory_full (SIZE_MAX
);
506 required
*= MAX_MULTIBYTE_LENGTH
;
507 if (encode_terminal_src_size
< required
)
509 encode_terminal_src
= xrealloc (encode_terminal_src
, required
);
510 encode_terminal_src_size
= required
;
513 charset_list
= coding_charset_list (coding
);
515 buf
= encode_terminal_src
;
517 while (src
< src_end
)
519 if (src
->type
== COMPOSITE_GLYPH
)
521 struct composition
*cmp
IF_LINT (= NULL
);
522 Lisp_Object gstring
IF_LINT (= Qnil
);
525 nbytes
= buf
- encode_terminal_src
;
526 if (src
->u
.cmp
.automatic
)
528 gstring
= composition_gstring_from_id (src
->u
.cmp
.id
);
529 required
= src
->slice
.cmp
.to
- src
->slice
.cmp
.from
+ 1;
533 cmp
= composition_table
[src
->u
.cmp
.id
];
534 required
= cmp
->glyph_len
;
535 required
*= MAX_MULTIBYTE_LENGTH
;
538 if (encode_terminal_src_size
- nbytes
< required
)
540 encode_terminal_src
=
541 xpalloc (encode_terminal_src
, &encode_terminal_src_size
,
542 required
- (encode_terminal_src_size
- nbytes
),
544 buf
= encode_terminal_src
+ nbytes
;
547 if (src
->u
.cmp
.automatic
)
548 for (i
= src
->slice
.cmp
.from
; i
<= src
->slice
.cmp
.to
; i
++)
550 Lisp_Object g
= LGSTRING_GLYPH (gstring
, i
);
551 int c
= LGLYPH_CHAR (g
);
553 if (! char_charset (c
, charset_list
, NULL
))
555 buf
+= CHAR_STRING (c
, buf
);
559 for (i
= 0; i
< cmp
->glyph_len
; i
++)
561 int c
= COMPOSITION_GLYPH (cmp
, i
);
563 /* TAB in a composition means display glyphs with
564 padding space on the left or right. */
567 if (char_charset (c
, charset_list
, NULL
))
569 if (CHAR_WIDTH (c
) == 0
570 && i
> 0 && COMPOSITION_GLYPH (cmp
, i
- 1) == '\t')
571 /* Should be left-padded */
573 buf
+= CHAR_STRING (' ', buf
);
579 buf
+= CHAR_STRING (c
, buf
);
583 /* We must skip glyphs to be padded for a wide character. */
584 else if (! CHAR_GLYPH_PADDING_P (*src
))
591 SET_GLYPH_FROM_CHAR_GLYPH (g
, src
[0]);
593 if (GLYPH_INVALID_P (g
) || GLYPH_SIMPLE_P (tbase
, tlen
, g
))
595 /* This glyph doesn't have an entry in Vglyph_table. */
600 /* This glyph has an entry in Vglyph_table,
601 so process any alias before testing for simpleness. */
602 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
604 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
605 /* We set the multi-byte form of a character in G
606 (that should be an ASCII character) at WORKBUF. */
609 /* We have a string in Vglyph_table. */
610 string
= tbase
[GLYPH_CHAR (g
)];
615 nbytes
= buf
- encode_terminal_src
;
616 if (encode_terminal_src_size
- nbytes
< MAX_MULTIBYTE_LENGTH
)
618 encode_terminal_src
=
619 xpalloc (encode_terminal_src
, &encode_terminal_src_size
,
620 MAX_MULTIBYTE_LENGTH
, -1, 1);
621 buf
= encode_terminal_src
+ nbytes
;
624 || char_charset (c
, charset_list
, NULL
))
626 /* Store the multibyte form of C at BUF. */
627 buf
+= CHAR_STRING (c
, buf
);
632 /* C is not encodable. */
635 while (src
+ 1 < src_end
&& CHAR_GLYPH_PADDING_P (src
[1]))
645 if (! STRING_MULTIBYTE (string
))
646 string
= string_to_multibyte (string
);
647 nbytes
= buf
- encode_terminal_src
;
648 if (encode_terminal_src_size
- nbytes
< SBYTES (string
))
650 encode_terminal_src
=
651 xpalloc (encode_terminal_src
, &encode_terminal_src_size
,
653 - (encode_terminal_src_size
- nbytes
)),
655 buf
= encode_terminal_src
+ nbytes
;
657 memcpy (buf
, SDATA (string
), SBYTES (string
));
658 buf
+= SBYTES (string
);
659 nchars
+= SCHARS (string
);
667 coding
->produced
= 0;
671 nbytes
= buf
- encode_terminal_src
;
672 coding
->source
= encode_terminal_src
;
673 if (encode_terminal_dst_size
== 0)
675 encode_terminal_dst
= xrealloc (encode_terminal_dst
,
676 encode_terminal_src_size
);
677 encode_terminal_dst_size
= encode_terminal_src_size
;
679 coding
->destination
= encode_terminal_dst
;
680 coding
->dst_bytes
= encode_terminal_dst_size
;
681 encode_coding_object (coding
, Qnil
, 0, 0, nchars
, nbytes
, Qnil
);
682 /* coding->destination may have been reallocated. */
683 encode_terminal_dst
= coding
->destination
;
684 encode_terminal_dst_size
= coding
->dst_bytes
;
686 return (encode_terminal_dst
);
691 /* An implementation of write_glyphs for termcap frames. */
694 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
696 unsigned char *conversion_buffer
;
697 struct coding_system
*coding
;
700 struct tty_display_info
*tty
= FRAME_TTY (f
);
702 tty_turn_off_insert (tty
);
703 tty_hide_cursor (tty
);
705 /* Don't dare write in last column of bottom line, if Auto-Wrap,
706 since that would scroll the whole frame on some terminals. */
709 && curY (tty
) + 1 == FRAME_LINES (f
)
710 && (curX (tty
) + len
) == FRAME_COLS (f
))
717 /* If terminal_coding does any conversion, use it, otherwise use
718 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
719 because it always return 1 if the member src_multibyte is 1. */
720 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
721 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
722 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
724 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
726 for (stringlen
= len
; stringlen
!= 0; stringlen
-= n
)
728 /* Identify a run of glyphs with the same face. */
729 int face_id
= string
->face_id
;
731 for (n
= 1; n
< stringlen
; ++n
)
732 if (string
[n
].face_id
!= face_id
)
735 /* Turn appearance modes of the face of the run on. */
736 tty_highlight_if_desired (tty
);
737 turn_on_face (f
, face_id
);
740 /* This is the last run. */
741 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
742 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
743 if (coding
->produced
> 0)
746 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
747 if (ferror (tty
->output
))
748 clearerr (tty
->output
);
750 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
755 /* Turn appearance modes off. */
756 turn_off_face (f
, face_id
);
757 tty_turn_off_highlight (tty
);
763 #ifdef HAVE_GPM /* Only used by GPM code. */
766 tty_write_glyphs_with_face (register struct frame
*f
, register struct glyph
*string
,
767 register int len
, register int face_id
)
769 unsigned char *conversion_buffer
;
770 struct coding_system
*coding
;
772 struct tty_display_info
*tty
= FRAME_TTY (f
);
774 tty_turn_off_insert (tty
);
775 tty_hide_cursor (tty
);
777 /* Don't dare write in last column of bottom line, if Auto-Wrap,
778 since that would scroll the whole frame on some terminals. */
781 && curY (tty
) + 1 == FRAME_LINES (f
)
782 && (curX (tty
) + len
) == FRAME_COLS (f
))
789 /* If terminal_coding does any conversion, use it, otherwise use
790 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
791 because it always return 1 if the member src_multibyte is 1. */
792 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
793 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
794 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
796 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
798 /* Turn appearance modes of the face. */
799 tty_highlight_if_desired (tty
);
800 turn_on_face (f
, face_id
);
802 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
803 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
804 if (coding
->produced
> 0)
807 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
808 if (ferror (tty
->output
))
809 clearerr (tty
->output
);
811 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
815 /* Turn appearance modes off. */
816 turn_off_face (f
, face_id
);
817 tty_turn_off_highlight (tty
);
823 /* An implementation of insert_glyphs for termcap frames. */
826 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
829 struct glyph
*glyph
= NULL
;
830 unsigned char *conversion_buffer
;
831 unsigned char space
[1];
832 struct coding_system
*coding
;
834 struct tty_display_info
*tty
= FRAME_TTY (f
);
836 if (tty
->TS_ins_multi_chars
)
838 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
, 0, 0, 0);
842 write_glyphs (f
, start
, len
);
846 tty_turn_on_insert (tty
);
850 space
[0] = SPACEGLYPH
;
852 /* If terminal_coding does any conversion, use it, otherwise use
853 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
854 because it always return 1 if the member src_multibyte is 1. */
855 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
856 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
857 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
859 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
863 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
866 conversion_buffer
= space
;
867 coding
->produced
= 1;
871 tty_highlight_if_desired (tty
);
872 turn_on_face (f
, start
->face_id
);
875 /* We must open sufficient space for a character which
876 occupies more than one column. */
877 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
879 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
884 /* This is the last glyph. */
885 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
887 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
890 if (coding
->produced
> 0)
893 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
894 if (ferror (tty
->output
))
895 clearerr (tty
->output
);
897 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
901 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
904 turn_off_face (f
, glyph
->face_id
);
905 tty_turn_off_highlight (tty
);
912 /* An implementation of delete_glyphs for termcap frames. */
915 tty_delete_glyphs (struct frame
*f
, int n
)
920 struct tty_display_info
*tty
= FRAME_TTY (f
);
922 if (tty
->delete_in_insert_mode
)
924 tty_turn_on_insert (tty
);
928 tty_turn_off_insert (tty
);
929 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
932 if (tty
->TS_del_multi_chars
)
934 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
, 0, 0, 0);
939 for (i
= 0; i
< n
; i
++)
940 OUTPUT1 (tty
, tty
->TS_del_char
);
941 if (!tty
->delete_in_insert_mode
)
942 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
945 /* An implementation of ins_del_lines for termcap frames. */
948 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
950 struct tty_display_info
*tty
= FRAME_TTY (f
);
952 n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
953 const char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
954 const char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
956 register int i
= n
> 0 ? n
: -n
;
959 /* If the lines below the insertion are being pushed
960 into the end of the window, this is the same as clearing;
961 and we know the lines are already clear, since the matching
962 deletion has already been done. So can ignore this. */
963 /* If the lines below the deletion are blank lines coming
964 out of the end of the window, don't bother,
965 as there will be a matching inslines later that will flush them. */
966 if (FRAME_SCROLL_REGION_OK (f
)
967 && vpos
+ i
>= tty
->specified_window
)
969 if (!FRAME_MEMORY_BELOW_FRAME (f
)
970 && vpos
+ i
>= FRAME_LINES (f
))
975 raw_cursor_to (f
, vpos
, 0);
976 tty_background_highlight (tty
);
977 buf
= tparam (multi
, 0, 0, i
, 0, 0, 0);
983 raw_cursor_to (f
, vpos
, 0);
984 tty_background_highlight (tty
);
986 OUTPUT (tty
, single
);
992 tty_set_scroll_region (f
, vpos
, tty
->specified_window
);
994 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
996 raw_cursor_to (f
, vpos
, 0);
997 tty_background_highlight (tty
);
999 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1000 tty_set_scroll_region (f
, 0, tty
->specified_window
);
1003 if (!FRAME_SCROLL_REGION_OK (f
)
1004 && FRAME_MEMORY_BELOW_FRAME (f
)
1007 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
1012 /* Compute cost of sending "str", in characters,
1013 not counting any line-dependent padding. */
1016 string_cost (const char *str
)
1020 tputs (str
, 0, evalcost
);
1024 /* Compute cost of sending "str", in characters,
1025 counting any line-dependent padding at one line. */
1028 string_cost_one_line (const char *str
)
1032 tputs (str
, 1, evalcost
);
1036 /* Compute per line amount of line-dependent padding,
1037 in tenths of characters. */
1040 per_line_cost (const char *str
)
1044 tputs (str
, 0, evalcost
);
1047 tputs (str
, 10, evalcost
);
1051 /* char_ins_del_cost[n] is cost of inserting N characters.
1052 char_ins_del_cost[-n] is cost of deleting N characters.
1053 The length of this vector is based on max_frame_cols. */
1055 int *char_ins_del_vector
;
1057 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1061 calculate_ins_del_char_costs (struct frame
*f
)
1063 struct tty_display_info
*tty
= FRAME_TTY (f
);
1064 int ins_startup_cost
, del_startup_cost
;
1065 int ins_cost_per_char
, del_cost_per_char
;
1069 if (tty
->TS_ins_multi_chars
)
1071 ins_cost_per_char
= 0;
1072 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1074 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1075 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1077 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1078 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1079 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1080 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1084 ins_startup_cost
= 9999;
1085 ins_cost_per_char
= 0;
1088 if (tty
->TS_del_multi_chars
)
1090 del_cost_per_char
= 0;
1091 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1093 else if (tty
->TS_del_char
)
1095 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1096 + string_cost (tty
->TS_end_delete_mode
));
1097 if (tty
->delete_in_insert_mode
)
1098 del_startup_cost
/= 2;
1099 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1103 del_startup_cost
= 9999;
1104 del_cost_per_char
= 0;
1107 /* Delete costs are at negative offsets */
1108 p
= &char_ins_del_cost (f
)[0];
1109 for (i
= FRAME_COLS (f
); --i
>= 0;)
1110 *--p
= (del_startup_cost
+= del_cost_per_char
);
1112 /* Doing nothing is free */
1113 p
= &char_ins_del_cost (f
)[0];
1116 /* Insert costs are at positive offsets */
1117 for (i
= FRAME_COLS (f
); --i
>= 0;)
1118 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1122 calculate_costs (struct frame
*frame
)
1124 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1126 if (FRAME_TERMCAP_P (frame
))
1128 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1129 register const char *f
= (tty
->TS_set_scroll_region
1130 ? tty
->TS_set_scroll_region
1131 : tty
->TS_set_scroll_region_1
);
1133 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1137 /* These variables are only used for terminal stuff. They are
1138 allocated once for the terminal frame of X-windows emacs, but not
1141 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1142 X turns off char_ins_del_ok. */
1144 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1145 if ((min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof (int) - 1) / 2
1147 memory_full (SIZE_MAX
);
1149 char_ins_del_vector
=
1150 xrealloc (char_ins_del_vector
,
1151 (sizeof (int) + 2 * sizeof (int) * max_frame_cols
));
1153 memset (char_ins_del_vector
, 0,
1154 (sizeof (int) + 2 * sizeof (int) * max_frame_cols
));
1157 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1158 do_line_insertion_deletion_costs (frame
,
1159 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1160 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1163 do_line_insertion_deletion_costs (frame
,
1164 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1165 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1168 calculate_ins_del_char_costs (frame
);
1170 /* Don't use TS_repeat if its padding is worse than sending the chars */
1171 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1172 tty
->RPov
= string_cost (tty
->TS_repeat
);
1174 tty
->RPov
= FRAME_COLS (frame
) * 2;
1176 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1181 const char *cap
, *name
;
1184 /* Termcap capability names that correspond directly to X keysyms.
1185 Some of these (marked "terminfo") aren't supplied by old-style
1186 (Berkeley) termcap entries. They're listed in X keysym order;
1187 except we put the keypad keys first, so that if they clash with
1188 other keys (as on the IBM PC keyboard) they get overridden.
1191 static const struct fkey_table keys
[] =
1193 {"kh", "home"}, /* termcap */
1194 {"kl", "left"}, /* termcap */
1195 {"ku", "up"}, /* termcap */
1196 {"kr", "right"}, /* termcap */
1197 {"kd", "down"}, /* termcap */
1198 {"%8", "prior"}, /* terminfo */
1199 {"%5", "next"}, /* terminfo */
1200 {"@7", "end"}, /* terminfo */
1201 {"@1", "begin"}, /* terminfo */
1202 {"*6", "select"}, /* terminfo */
1203 {"%9", "print"}, /* terminfo */
1204 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1206 * "insert" --- see below
1208 {"&8", "undo"}, /* terminfo */
1209 {"%0", "redo"}, /* terminfo */
1210 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1211 {"@0", "find"}, /* terminfo */
1212 {"@2", "cancel"}, /* terminfo */
1213 {"%1", "help"}, /* terminfo */
1215 * "break" goes here, but can't be reliably intercepted with termcap
1217 {"&4", "reset"}, /* terminfo --- actually `restart' */
1219 * "system" and "user" --- no termcaps
1221 {"kE", "clearline"}, /* terminfo */
1222 {"kA", "insertline"}, /* terminfo */
1223 {"kL", "deleteline"}, /* terminfo */
1224 {"kI", "insertchar"}, /* terminfo */
1225 {"kD", "deletechar"}, /* terminfo */
1226 {"kB", "backtab"}, /* terminfo */
1228 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1230 {"@8", "kp-enter"}, /* terminfo */
1232 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1233 * "kp-multiply", "kp-add", "kp-separator",
1234 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1235 * --- no termcaps for any of these.
1237 {"K4", "kp-1"}, /* terminfo */
1239 * "kp-2" --- no termcap
1241 {"K5", "kp-3"}, /* terminfo */
1243 * "kp-4" --- no termcap
1245 {"K2", "kp-5"}, /* terminfo */
1247 * "kp-6" --- no termcap
1249 {"K1", "kp-7"}, /* terminfo */
1251 * "kp-8" --- no termcap
1253 {"K3", "kp-9"}, /* terminfo */
1255 * "kp-equal" --- no termcap
1267 {"&0", "S-cancel"}, /*shifted cancel key*/
1268 {"&9", "S-begin"}, /*shifted begin key*/
1269 {"*0", "S-find"}, /*shifted find key*/
1270 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1271 {"*4", "S-delete"}, /*shifted delete-character key*/
1272 {"*7", "S-end"}, /*shifted end key*/
1273 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1274 {"#1", "S-help"}, /*shifted help key*/
1275 {"#2", "S-home"}, /*shifted home key*/
1276 {"#3", "S-insert"}, /*shifted insert-character key*/
1277 {"#4", "S-left"}, /*shifted left-arrow key*/
1278 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1279 {"%c", "S-next"}, /*shifted next key*/
1280 {"%e", "S-prior"}, /*shifted previous key*/
1281 {"%f", "S-print"}, /*shifted print key*/
1282 {"%g", "S-redo"}, /*shifted redo key*/
1283 {"%i", "S-right"}, /*shifted right-arrow key*/
1284 {"!3", "S-undo"} /*shifted undo key*/
1288 static char **term_get_fkeys_address
;
1289 static KBOARD
*term_get_fkeys_kboard
;
1290 static Lisp_Object
term_get_fkeys_1 (void);
1292 /* Find the escape codes sent by the function keys for Vinput_decode_map.
1293 This function scans the termcap function key sequence entries, and
1294 adds entries to Vinput_decode_map for each function key it finds. */
1297 term_get_fkeys (char **address
, KBOARD
*kboard
)
1299 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1300 errors during the call. The only errors should be from Fdefine_key
1301 when given a key sequence containing an invalid prefix key. If the
1302 termcap defines function keys which use a prefix that is already bound
1303 to a command by the default bindings, we should silently ignore that
1304 function key specification, rather than giving the user an error and
1305 refusing to run at all on such a terminal. */
1307 term_get_fkeys_address
= address
;
1308 term_get_fkeys_kboard
= kboard
;
1309 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1313 term_get_fkeys_1 (void)
1317 char **address
= term_get_fkeys_address
;
1318 KBOARD
*kboard
= term_get_fkeys_kboard
;
1320 /* This can happen if CANNOT_DUMP or with strange options. */
1321 if (!KEYMAPP (KVAR (kboard
, Vinput_decode_map
)))
1322 kset_input_decode_map (kboard
, Fmake_sparse_keymap (Qnil
));
1324 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1326 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1328 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (sequence
),
1329 Fmake_vector (make_number (1),
1330 intern (keys
[i
].name
)));
1333 /* The uses of the "k0" capability are inconsistent; sometimes it
1334 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1335 We will attempt to politely accommodate both systems by testing for
1336 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1339 const char *k_semi
= tgetstr ("k;", address
);
1340 const char *k0
= tgetstr ("k0", address
);
1341 const char *k0_name
= "f10";
1346 /* Define f0 first, so that f10 takes precedence in case the
1347 key sequences happens to be the same. */
1348 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (k0
),
1349 Fmake_vector (make_number (1), intern ("f0")));
1350 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (k_semi
),
1351 Fmake_vector (make_number (1), intern ("f10")));
1354 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (k0
),
1355 Fmake_vector (make_number (1), intern (k0_name
)));
1358 /* Set up cookies for numbered function keys above f10. */
1360 char fcap
[3], fkey
[4];
1362 fcap
[0] = 'F'; fcap
[2] = '\0';
1363 for (i
= 11; i
< 64; i
++)
1366 fcap
[1] = '1' + i
- 11;
1368 fcap
[1] = 'A' + i
- 20;
1370 fcap
[1] = 'a' + i
- 46;
1373 char *sequence
= tgetstr (fcap
, address
);
1376 sprintf (fkey
, "f%d", i
);
1377 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (sequence
),
1378 Fmake_vector (make_number (1),
1386 * Various mappings to try and get a better fit.
1389 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1390 if (!tgetstr (cap1, address)) \
1392 char *sequence = tgetstr (cap2, address); \
1394 Fdefine_key (KVAR (kboard, Vinput_decode_map), build_string (sequence), \
1395 Fmake_vector (make_number (1), \
1399 /* if there's no key_next keycap, map key_npage to `next' keysym */
1400 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1401 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1402 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1403 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1404 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1405 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1406 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1408 /* IBM has their own non-standard dialect of terminfo.
1409 If the standard name isn't found, try the IBM name. */
1410 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1411 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1412 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1413 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1414 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1415 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1416 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1417 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1418 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1419 #undef CONDITIONAL_REASSIGN
1424 #endif /* not DOS_NT */
1427 /***********************************************************************
1428 Character Display Information
1429 ***********************************************************************/
1430 static void append_glyph (struct it
*);
1431 static void append_composite_glyph (struct it
*);
1432 static void produce_composite_glyph (struct it
*);
1433 static void append_glyphless_glyph (struct it
*, int, const char *);
1434 static void produce_glyphless_glyph (struct it
*, int, Lisp_Object
);
1436 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1437 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1438 the character for which to produce glyphs; IT->face_id contains the
1439 character's face. Padding glyphs are appended if IT->c has a
1440 IT->pixel_width > 1. */
1443 append_glyph (struct it
*it
)
1445 struct glyph
*glyph
, *end
;
1448 eassert (it
->glyph_row
);
1449 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1450 + it
->glyph_row
->used
[it
->area
]);
1451 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1453 /* If the glyph row is reversed, we need to prepend the glyph rather
1455 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1458 int move_by
= it
->pixel_width
;
1460 /* Make room for the new glyphs. */
1461 if (move_by
> end
- glyph
) /* don't overstep end of this area */
1462 move_by
= end
- glyph
;
1463 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1465 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1466 end
= glyph
+ move_by
;
1469 /* BIDI Note: we put the glyphs of a "multi-pixel" character left to
1470 right, even in the REVERSED_P case, since (a) all of its u.ch are
1471 identical, and (b) the PADDING_P flag needs to be set for the
1472 leftmost one, because we write to the terminal left-to-right. */
1474 i
< it
->pixel_width
&& glyph
< end
;
1477 glyph
->type
= CHAR_GLYPH
;
1478 glyph
->pixel_width
= 1;
1479 glyph
->u
.ch
= it
->char_to_display
;
1480 glyph
->face_id
= it
->face_id
;
1481 glyph
->padding_p
= i
> 0;
1482 glyph
->charpos
= CHARPOS (it
->position
);
1483 glyph
->object
= it
->object
;
1486 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1487 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1489 glyph
->bidi_type
= it
->bidi_it
.type
;
1493 glyph
->resolved_level
= 0;
1494 glyph
->bidi_type
= UNKNOWN_BT
;
1497 ++it
->glyph_row
->used
[it
->area
];
1502 /* For external use. */
1504 tty_append_glyph (struct it
*it
)
1510 /* Produce glyphs for the display element described by IT. *IT
1511 specifies what we want to produce a glyph for (character, image, ...),
1512 and where in the glyph matrix we currently are (glyph row and hpos).
1513 produce_glyphs fills in output fields of *IT with information such as the
1514 pixel width and height of a character, and maybe output actual glyphs at
1515 the same time if IT->glyph_row is non-null. For an overview, see
1516 the explanation in dispextern.h, before the definition of the
1517 display_element_type enumeration.
1519 produce_glyphs also stores the result of glyph width, ascent
1520 etc. computations in *IT.
1522 IT->glyph_row may be null, in which case produce_glyphs does not
1523 actually fill in the glyphs. This is used in the move_* functions
1524 in xdisp.c for text width and height computations.
1526 Callers usually don't call produce_glyphs directly;
1527 instead they use the macro PRODUCE_GLYPHS. */
1530 produce_glyphs (struct it
*it
)
1532 /* If a hook is installed, let it do the work. */
1534 /* Nothing but characters are supported on terminal frames. */
1535 eassert (it
->what
== IT_CHARACTER
1536 || it
->what
== IT_COMPOSITION
1537 || it
->what
== IT_STRETCH
1538 || it
->what
== IT_GLYPHLESS
);
1540 if (it
->what
== IT_STRETCH
)
1542 produce_stretch_glyph (it
);
1546 if (it
->what
== IT_COMPOSITION
)
1548 produce_composite_glyph (it
);
1552 if (it
->what
== IT_GLYPHLESS
)
1554 produce_glyphless_glyph (it
, 0, Qnil
);
1558 if (it
->char_to_display
>= 040 && it
->char_to_display
< 0177)
1560 it
->pixel_width
= it
->nglyphs
= 1;
1564 else if (it
->char_to_display
== '\n')
1565 it
->pixel_width
= it
->nglyphs
= 0;
1566 else if (it
->char_to_display
== '\t')
1568 int absolute_x
= (it
->current_x
1569 + it
->continuation_lines_width
);
1571 = (((1 + absolute_x
+ it
->tab_width
- 1)
1576 /* If part of the TAB has been displayed on the previous line
1577 which is continued now, continuation_lines_width will have
1578 been incremented already by the part that fitted on the
1579 continued line. So, we will get the right number of spaces
1581 nspaces
= next_tab_x
- absolute_x
;
1587 it
->char_to_display
= ' ';
1588 it
->pixel_width
= it
->len
= 1;
1594 it
->pixel_width
= nspaces
;
1595 it
->nglyphs
= nspaces
;
1597 else if (CHAR_BYTE8_P (it
->char_to_display
))
1599 /* Coming here means that we must send the raw 8-bit byte as is
1600 to the terminal. Although there's no way to know how many
1601 columns it occupies on a screen, it is a good assumption that
1602 a single byte code has 1-column width. */
1603 it
->pixel_width
= it
->nglyphs
= 1;
1609 Lisp_Object charset_list
= FRAME_TERMINAL (it
->f
)->charset_list
;
1611 if (char_charset (it
->char_to_display
, charset_list
, NULL
))
1613 it
->pixel_width
= CHAR_WIDTH (it
->char_to_display
);
1614 it
->nglyphs
= it
->pixel_width
;
1620 Lisp_Object acronym
= lookup_glyphless_char_display (-1, it
);
1622 eassert (it
->what
== IT_GLYPHLESS
);
1623 produce_glyphless_glyph (it
, 1, acronym
);
1628 /* Advance current_x by the pixel width as a convenience for
1630 if (it
->area
== TEXT_AREA
)
1631 it
->current_x
+= it
->pixel_width
;
1632 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1633 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1636 /* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
1637 Called from produce_composite_glyph for terminal frames if
1638 IT->glyph_row != NULL. IT->face_id contains the character's
1642 append_composite_glyph (struct it
*it
)
1644 struct glyph
*glyph
;
1646 eassert (it
->glyph_row
);
1647 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1648 if (glyph
< it
->glyph_row
->glyphs
[1 + it
->area
])
1650 /* If the glyph row is reversed, we need to prepend the glyph
1651 rather than append it. */
1652 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1656 /* Make room for the new glyph. */
1657 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1659 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1661 glyph
->type
= COMPOSITE_GLYPH
;
1662 glyph
->pixel_width
= it
->pixel_width
;
1663 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1664 if (it
->cmp_it
.ch
< 0)
1666 glyph
->u
.cmp
.automatic
= 0;
1667 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1671 glyph
->u
.cmp
.automatic
= 1;
1672 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1673 glyph
->slice
.cmp
.from
= it
->cmp_it
.from
;
1674 glyph
->slice
.cmp
.to
= it
->cmp_it
.to
- 1;
1677 glyph
->face_id
= it
->face_id
;
1678 glyph
->padding_p
= 0;
1679 glyph
->charpos
= CHARPOS (it
->position
);
1680 glyph
->object
= it
->object
;
1683 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1684 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1686 glyph
->bidi_type
= it
->bidi_it
.type
;
1690 glyph
->resolved_level
= 0;
1691 glyph
->bidi_type
= UNKNOWN_BT
;
1694 ++it
->glyph_row
->used
[it
->area
];
1700 /* Produce a composite glyph for iterator IT. IT->cmp_id is the ID of
1701 the composition. We simply produces components of the composition
1702 assuming that the terminal has a capability to layout/render it
1706 produce_composite_glyph (struct it
*it
)
1708 if (it
->cmp_it
.ch
< 0)
1710 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
1712 it
->pixel_width
= cmp
->width
;
1716 Lisp_Object gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
1718 it
->pixel_width
= composition_gstring_width (gstring
, it
->cmp_it
.from
,
1719 it
->cmp_it
.to
, NULL
);
1723 append_composite_glyph (it
);
1727 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
1728 is a face ID to be used for the glyph. What is actually appended
1729 are glyphs of type CHAR_GLYPH whose characters are in STR (which
1730 comes from it->nglyphs bytes). */
1733 append_glyphless_glyph (struct it
*it
, int face_id
, const char *str
)
1735 struct glyph
*glyph
, *end
;
1738 eassert (it
->glyph_row
);
1739 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1740 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1742 /* If the glyph row is reversed, we need to prepend the glyph rather
1744 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1747 int move_by
= it
->pixel_width
;
1749 /* Make room for the new glyphs. */
1750 if (move_by
> end
- glyph
) /* don't overstep end of this area */
1751 move_by
= end
- glyph
;
1752 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1754 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1755 end
= glyph
+ move_by
;
1760 glyph
->type
= CHAR_GLYPH
;
1761 glyph
->pixel_width
= 1;
1762 glyph
->face_id
= face_id
;
1763 glyph
->padding_p
= 0;
1764 glyph
->charpos
= CHARPOS (it
->position
);
1765 glyph
->object
= it
->object
;
1768 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1769 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1771 glyph
->bidi_type
= it
->bidi_it
.type
;
1775 glyph
->resolved_level
= 0;
1776 glyph
->bidi_type
= UNKNOWN_BT
;
1779 /* BIDI Note: we put the glyphs of characters left to right, even in
1780 the REVERSED_P case because we write to the terminal
1782 for (i
= 0; i
< it
->nglyphs
&& glyph
< end
; ++i
)
1785 glyph
[0] = glyph
[-1];
1786 glyph
->u
.ch
= str
[i
];
1787 ++it
->glyph_row
->used
[it
->area
];
1792 /* Produce glyphs for a glyphless character for iterator IT.
1793 IT->glyphless_method specifies which method to use for displaying
1794 the character. See the description of enum
1795 glyphless_display_method in dispextern.h for the details.
1797 FOR_NO_FONT is nonzero if and only if this is for a character that
1798 is not supported by the coding system of the terminal. ACRONYM, if
1799 non-nil, is an acronym string for the character.
1801 The glyphs actually produced are of type CHAR_GLYPH. */
1804 produce_glyphless_glyph (struct it
*it
, int for_no_font
, Lisp_Object acronym
)
1808 char buf
[sizeof "\\x" + max (6, (sizeof it
->c
* CHAR_BIT
+ 3) / 4)];
1809 char const *str
= " ";
1811 /* Get a face ID for the glyph by utilizing a cache (the same way as
1812 done for `escape-glyph' in get_next_display_element). */
1813 if (it
->f
== last_glyphless_glyph_frame
1814 && it
->face_id
== last_glyphless_glyph_face_id
)
1816 face_id
= last_glyphless_glyph_merged_face_id
;
1820 /* Merge the `glyphless-char' face into the current face. */
1821 face_id
= merge_faces (it
->f
, Qglyphless_char
, 0, it
->face_id
);
1822 last_glyphless_glyph_frame
= it
->f
;
1823 last_glyphless_glyph_face_id
= it
->face_id
;
1824 last_glyphless_glyph_merged_face_id
= face_id
;
1827 if (it
->glyphless_method
== GLYPHLESS_DISPLAY_THIN_SPACE
)
1829 /* As there's no way to produce a thin space, we produce a space
1830 of canonical width. */
1833 else if (it
->glyphless_method
== GLYPHLESS_DISPLAY_EMPTY_BOX
)
1835 len
= CHAR_WIDTH (it
->c
);
1840 len
= sprintf (buf
, "[%.*s]", len
, str
);
1845 if (it
->glyphless_method
== GLYPHLESS_DISPLAY_ACRONYM
)
1847 if (! STRINGP (acronym
) && CHAR_TABLE_P (Vglyphless_char_display
))
1848 acronym
= CHAR_TABLE_REF (Vglyphless_char_display
, it
->c
);
1849 if (CONSP (acronym
))
1850 acronym
= XCDR (acronym
);
1852 str
= STRINGP (acronym
) ? SSDATA (acronym
) : "";
1853 for (len
= 0; len
< 6 && str
[len
] && ASCII_BYTE_P (str
[len
]); len
++)
1854 buf
[1 + len
] = str
[len
];
1860 eassert (it
->glyphless_method
== GLYPHLESS_DISPLAY_HEX_CODE
);
1861 len
= (it
->c
< 0x10000 ? sprintf (buf
, "\\u%04X", it
->c
)
1862 : it
->c
<= MAX_UNICODE_CHAR
? sprintf (buf
, "\\U%06X", it
->c
)
1863 : sprintf (buf
, "\\x%06X", it
->c
));
1868 it
->pixel_width
= len
;
1871 append_glyphless_glyph (it
, face_id
, str
);
1875 /***********************************************************************
1877 ***********************************************************************/
1879 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1880 one of the enumerators from enum no_color_bit, or a bit set built
1881 from them. Some display attributes may not be used together with
1882 color; the termcap capability `NC' specifies which ones. */
1884 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1885 (tty->TN_max_colors > 0 \
1886 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1889 /* Turn appearances of face FACE_ID on tty frame F on.
1890 FACE_ID is a realized face ID number, in the face cache. */
1893 turn_on_face (struct frame
*f
, int face_id
)
1895 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1896 long fg
= face
->foreground
;
1897 long bg
= face
->background
;
1898 struct tty_display_info
*tty
= FRAME_TTY (f
);
1900 /* Do this first because TS_end_standout_mode may be the same
1901 as TS_exit_attribute_mode, which turns all appearances off. */
1902 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1904 if (tty
->TN_max_colors
> 0)
1906 if (fg
>= 0 && bg
>= 0)
1908 /* If the terminal supports colors, we can set them
1909 below without using reverse video. The face's fg
1910 and bg colors are set as they should appear on
1911 the screen, i.e. they take the inverse-video'ness
1912 of the face already into account. */
1914 else if (inverse_video
)
1916 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1917 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1918 tty_toggle_highlight (tty
);
1922 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1923 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1924 tty_toggle_highlight (tty
);
1929 /* If we can't display colors, use reverse video
1930 if the face specifies that. */
1933 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1934 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1935 tty_toggle_highlight (tty
);
1939 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1940 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1941 tty_toggle_highlight (tty
);
1946 if (face
->tty_bold_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1947 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1949 if (face
->tty_italic_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_ITALIC
))
1951 if (tty
->TS_enter_italic_mode
)
1952 OUTPUT1 (tty
, tty
->TS_enter_italic_mode
);
1954 /* Italics mode is unavailable on many terminals. In that
1955 case, map slant to dimmed text; we want italic text to
1956 appear different and dimming is not otherwise used. */
1957 OUTPUT1 (tty
, tty
->TS_enter_dim_mode
);
1960 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1961 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1963 if (tty
->TN_max_colors
> 0)
1968 ts
= tty
->standout_mode
? tty
->TS_set_background
: tty
->TS_set_foreground
;
1971 p
= tparam (ts
, NULL
, 0, (int) fg
, 0, 0, 0);
1976 ts
= tty
->standout_mode
? tty
->TS_set_foreground
: tty
->TS_set_background
;
1979 p
= tparam (ts
, NULL
, 0, (int) bg
, 0, 0, 0);
1987 /* Turn off appearances of face FACE_ID on tty frame F. */
1990 turn_off_face (struct frame
*f
, int face_id
)
1992 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1993 struct tty_display_info
*tty
= FRAME_TTY (f
);
1995 eassert (face
!= NULL
);
1997 if (tty
->TS_exit_attribute_mode
)
1999 /* Capability "me" will turn off appearance modes double-bright,
2000 half-bright, reverse-video, standout, underline. It may or
2001 may not turn off alt-char-mode. */
2002 if (face
->tty_bold_p
2003 || face
->tty_italic_p
2004 || face
->tty_reverse_p
2005 || face
->tty_underline_p
)
2007 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
2008 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
2009 tty
->standout_mode
= 0;
2014 /* If we don't have "me" we can only have those appearances
2015 that have exit sequences defined. */
2016 if (face
->tty_underline_p
)
2017 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
2020 /* Switch back to default colors. */
2021 if (tty
->TN_max_colors
> 0
2022 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2023 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2024 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2025 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2026 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
2030 /* Return non-zero if the terminal on frame F supports all of the
2031 capabilities in CAPS simultaneously, with foreground and background
2032 colors FG and BG. */
2035 tty_capable_p (struct tty_display_info
*tty
, unsigned int caps
,
2036 unsigned long fg
, unsigned long bg
)
2038 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
2039 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
2042 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
2043 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
2044 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
2045 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
2046 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ITALIC
, tty
->TS_enter_italic_mode
, NC_ITALIC
);
2052 /* Return non-zero if the terminal is capable to display colors. */
2054 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2056 doc
: /* Return non-nil if the tty device TERMINAL can display colors.
2058 TERMINAL can be a terminal object, a frame, or nil (meaning the
2059 selected frame's terminal). This function always returns nil if
2060 TERMINAL does not refer to a text terminal. */)
2061 (Lisp_Object terminal
)
2063 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2067 return t
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
2070 /* Return the number of supported colors. */
2071 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2072 Stty_display_color_cells
, 0, 1, 0,
2073 doc
: /* Return the number of colors supported by the tty device TERMINAL.
2075 TERMINAL can be a terminal object, a frame, or nil (meaning the
2076 selected frame's terminal). This function always returns 0 if
2077 TERMINAL does not refer to a text terminal. */)
2078 (Lisp_Object terminal
)
2080 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2082 return make_number (0);
2084 return make_number (t
->display_info
.tty
->TN_max_colors
);
2089 /* Declare here rather than in the function, as in the rest of Emacs,
2090 to work around an HPUX compiler bug (?). See
2091 http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00410.html */
2092 static int default_max_colors
;
2093 static int default_max_pairs
;
2094 static int default_no_color_video
;
2095 static char *default_orig_pair
;
2096 static char *default_set_foreground
;
2097 static char *default_set_background
;
2099 /* Save or restore the default color-related capabilities of this
2102 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
2107 xfree (default_orig_pair
);
2108 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
2110 xfree (default_set_foreground
);
2111 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
2114 xfree (default_set_background
);
2115 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
2118 default_max_colors
= tty
->TN_max_colors
;
2119 default_max_pairs
= tty
->TN_max_pairs
;
2120 default_no_color_video
= tty
->TN_no_color_video
;
2124 tty
->TS_orig_pair
= default_orig_pair
;
2125 tty
->TS_set_foreground
= default_set_foreground
;
2126 tty
->TS_set_background
= default_set_background
;
2127 tty
->TN_max_colors
= default_max_colors
;
2128 tty
->TN_max_pairs
= default_max_pairs
;
2129 tty
->TN_no_color_video
= default_no_color_video
;
2133 /* Setup one of the standard tty color schemes according to MODE.
2134 MODE's value is generally the number of colors which we want to
2135 support; zero means set up for the default capabilities, the ones
2136 we saw at init_tty time; -1 means turn off color support. */
2138 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2140 /* Canonicalize all negative values of MODE. */
2146 case -1: /* no colors at all */
2147 tty
->TN_max_colors
= 0;
2148 tty
->TN_max_pairs
= 0;
2149 tty
->TN_no_color_video
= 0;
2150 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2152 case 0: /* default colors, if any */
2154 tty_default_color_capabilities (tty
, 0);
2156 case 8: /* 8 standard ANSI colors */
2157 tty
->TS_orig_pair
= "\033[0m";
2159 tty
->TS_set_foreground
= "\033[3%p1%dm";
2160 tty
->TS_set_background
= "\033[4%p1%dm";
2162 tty
->TS_set_foreground
= "\033[3%dm";
2163 tty
->TS_set_background
= "\033[4%dm";
2165 tty
->TN_max_colors
= 8;
2166 tty
->TN_max_pairs
= 64;
2167 tty
->TN_no_color_video
= 0;
2173 set_tty_color_mode (struct tty_display_info
*tty
, struct frame
*f
)
2175 Lisp_Object tem
, val
;
2176 Lisp_Object color_mode
;
2178 Lisp_Object tty_color_mode_alist
2179 = Fintern_soft (build_string ("tty-color-mode-alist"), Qnil
);
2181 tem
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2182 val
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2186 else if (SYMBOLP (tty_color_mode_alist
))
2188 tem
= Fassq (val
, Fsymbol_value (tty_color_mode_alist
));
2189 color_mode
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2194 mode
= TYPE_RANGED_INTEGERP (int, color_mode
) ? XINT (color_mode
) : 0;
2196 if (mode
!= tty
->previous_color_mode
)
2198 tty
->previous_color_mode
= mode
;
2199 tty_setup_colors (tty
, mode
);
2200 /* This recomputes all the faces given the new color definitions. */
2201 safe_call (1, intern ("tty-set-up-initial-frame-faces"));
2205 #endif /* !DOS_NT */
2209 /* Return the tty display object specified by TERMINAL. */
2211 static struct terminal
*
2212 get_tty_terminal (Lisp_Object terminal
, int throw)
2214 struct terminal
*t
= get_terminal (terminal
, throw);
2216 if (t
&& t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2219 error ("Device %d is not a termcap terminal device", t
->id
);
2227 /* Return an active termcap device that uses the tty device with the
2230 This function ignores suspended devices.
2232 Returns NULL if the named terminal device is not opened. */
2235 get_named_tty (const char *name
)
2242 for (t
= terminal_list
; t
; t
= t
->next_terminal
)
2244 if ((t
->type
== output_termcap
|| t
->type
== output_msdos_raw
)
2245 && !strcmp (t
->display_info
.tty
->name
, name
)
2246 && TERMINAL_ACTIVE_P (t
))
2254 DEFUN ("tty-type", Ftty_type
, Stty_type
, 0, 1, 0,
2255 doc
: /* Return the type of the tty device that TERMINAL uses.
2256 Returns nil if TERMINAL is not on a tty device.
2258 TERMINAL can be a terminal object, a frame, or nil (meaning the
2259 selected frame's terminal). */)
2260 (Lisp_Object terminal
)
2262 struct terminal
*t
= get_terminal (terminal
, 1);
2264 if (t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2267 if (t
->display_info
.tty
->type
)
2268 return build_string (t
->display_info
.tty
->type
);
2273 DEFUN ("controlling-tty-p", Fcontrolling_tty_p
, Scontrolling_tty_p
, 0, 1, 0,
2274 doc
: /* Return non-nil if TERMINAL is the controlling tty of the Emacs process.
2276 TERMINAL can be a terminal object, a frame, or nil (meaning the
2277 selected frame's terminal). This function always returns nil if
2278 TERMINAL is not on a tty device. */)
2279 (Lisp_Object terminal
)
2281 struct terminal
*t
= get_terminal (terminal
, 1);
2283 if ((t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2284 || strcmp (t
->display_info
.tty
->name
, DEV_TTY
) != 0)
2290 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 1, 0,
2291 doc
: /* Declare that the tty used by TERMINAL does not handle underlining.
2292 This is used to override the terminfo data, for certain terminals that
2293 do not really do underlining, but say that they do. This function has
2294 no effect if used on a non-tty terminal.
2296 TERMINAL can be a terminal object, a frame or nil (meaning the
2297 selected frame's terminal). This function always returns nil if
2298 TERMINAL does not refer to a text terminal. */)
2299 (Lisp_Object terminal
)
2301 struct terminal
*t
= get_terminal (terminal
, 1);
2303 if (t
->type
== output_termcap
)
2304 t
->display_info
.tty
->TS_enter_underline_mode
= 0;
2308 DEFUN ("tty-top-frame", Ftty_top_frame
, Stty_top_frame
, 0, 1, 0,
2309 doc
: /* Return the topmost terminal frame on TERMINAL.
2310 TERMINAL can be a terminal object, a frame or nil (meaning the
2311 selected frame's terminal). This function returns nil if TERMINAL
2312 does not refer to a text terminal. Otherwise, it returns the
2313 top-most frame on the text terminal. */)
2314 (Lisp_Object terminal
)
2316 struct terminal
*t
= get_terminal (terminal
, 1);
2318 if (t
->type
== output_termcap
)
2319 return t
->display_info
.tty
->top_frame
;
2325 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
2326 doc
: /* Suspend the terminal device TTY.
2328 The device is restored to its default state, and Emacs ceases all
2329 access to the tty device. Frames that use the device are not deleted,
2330 but input is not read from them and if they change, their display is
2333 TTY may be a terminal object, a frame, or nil for the terminal device
2334 of the currently selected frame.
2336 This function runs `suspend-tty-functions' after suspending the
2337 device. The functions are run with one arg, the id of the suspended
2340 `suspend-tty' does nothing if it is called on a device that is already
2343 A suspended tty may be resumed by calling `resume-tty' on it. */)
2346 struct terminal
*t
= get_tty_terminal (tty
, 1);
2350 error ("Unknown tty device");
2352 f
= t
->display_info
.tty
->input
;
2356 /* First run `suspend-tty-functions' and then clean up the tty
2357 state because `suspend-tty-functions' might need to change
2359 Lisp_Object args
[2];
2360 args
[0] = intern ("suspend-tty-functions");
2361 XSETTERMINAL (args
[1], t
);
2362 Frun_hook_with_args (2, args
);
2364 reset_sys_modes (t
->display_info
.tty
);
2365 delete_keyboard_wait_descriptor (fileno (f
));
2369 if (f
!= t
->display_info
.tty
->output
)
2370 fclose (t
->display_info
.tty
->output
);
2373 t
->display_info
.tty
->input
= 0;
2374 t
->display_info
.tty
->output
= 0;
2376 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2377 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 0);
2381 /* Clear display hooks to prevent further output. */
2382 clear_tty_hooks (t
);
2387 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
2388 doc
: /* Resume the previously suspended terminal device TTY.
2389 The terminal is opened and reinitialized. Frames that are on the
2390 suspended terminal are revived.
2392 It is an error to resume a terminal while another terminal is active
2395 This function runs `resume-tty-functions' after resuming the terminal.
2396 The functions are run with one arg, the id of the resumed terminal
2399 `resume-tty' does nothing if it is called on a device that is not
2402 TTY may be a terminal object, a frame, or nil (meaning the selected
2403 frame's terminal). */)
2406 struct terminal
*t
= get_tty_terminal (tty
, 1);
2410 error ("Unknown tty device");
2412 if (!t
->display_info
.tty
->input
)
2414 if (get_named_tty (t
->display_info
.tty
->name
))
2415 error ("Cannot resume display while another display is active on the same device");
2418 t
->display_info
.tty
->output
= stdout
;
2419 t
->display_info
.tty
->input
= stdin
;
2421 fd
= emacs_open (t
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
2424 error ("Can not reopen tty device %s: %s", t
->display_info
.tty
->name
, strerror (errno
));
2426 if (strcmp (t
->display_info
.tty
->name
, DEV_TTY
))
2427 dissociate_if_controlling_tty (fd
);
2429 t
->display_info
.tty
->output
= fdopen (fd
, "w+");
2430 t
->display_info
.tty
->input
= t
->display_info
.tty
->output
;
2433 add_keyboard_wait_descriptor (fd
);
2435 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2437 struct frame
*f
= XFRAME (t
->display_info
.tty
->top_frame
);
2439 int old_height
= FRAME_COLS (f
);
2440 int old_width
= FRAME_LINES (f
);
2442 /* Check if terminal/window size has changed while the frame
2444 get_tty_size (fileno (t
->display_info
.tty
->input
), &width
, &height
);
2445 if (width
!= old_width
|| height
!= old_height
)
2446 change_frame_size (f
, height
, width
, 0, 0, 0);
2447 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 1);
2451 init_sys_modes (t
->display_info
.tty
);
2454 /* Run `resume-tty-functions'. */
2455 Lisp_Object args
[2];
2456 args
[0] = intern ("resume-tty-functions");
2457 XSETTERMINAL (args
[1], t
);
2458 Frun_hook_with_args (2, args
);
2468 /***********************************************************************
2470 ***********************************************************************/
2474 #ifndef HAVE_WINDOW_SYSTEM
2476 term_mouse_moveto (int x
, int y
)
2478 /* TODO: how to set mouse position?
2481 name = (const char *) ttyname (0);
2482 fd = open (name, O_WRONLY);
2483 SOME_FUNCTION (x, y, fd);
2486 last_mouse_y = y; */
2488 #endif /* HAVE_WINDOW_SYSTEM */
2490 /* Implementation of draw_row_with_mouse_face for TTY/GPM. */
2492 tty_draw_row_with_mouse_face (struct window
*w
, struct glyph_row
*row
,
2493 int start_hpos
, int end_hpos
,
2494 enum draw_glyphs_face draw
)
2496 int nglyphs
= end_hpos
- start_hpos
;
2497 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
2498 struct tty_display_info
*tty
= FRAME_TTY (f
);
2499 int face_id
= tty
->mouse_highlight
.mouse_face_face_id
;
2500 int save_x
, save_y
, pos_x
, pos_y
;
2502 if (end_hpos
>= row
->used
[TEXT_AREA
])
2503 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2505 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2506 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
+ WINDOW_LEFT_EDGE_X (w
);
2508 /* Save current cursor co-ordinates. */
2509 save_y
= curY (tty
);
2510 save_x
= curX (tty
);
2511 cursor_to (f
, pos_y
, pos_x
);
2513 if (draw
== DRAW_MOUSE_FACE
)
2514 tty_write_glyphs_with_face (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
,
2516 else if (draw
== DRAW_NORMAL_TEXT
)
2517 write_glyphs (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2519 cursor_to (f
, save_y
, save_x
);
2523 term_mouse_movement (FRAME_PTR frame
, Gpm_Event
*event
)
2525 /* Has the mouse moved off the glyph it was on at the last sighting? */
2526 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2528 frame
->mouse_moved
= 1;
2529 note_mouse_highlight (frame
, event
->x
, event
->y
);
2530 /* Remember which glyph we're now on. */
2531 last_mouse_x
= event
->x
;
2532 last_mouse_y
= event
->y
;
2538 /* Return the Time that corresponds to T. Wrap around on overflow. */
2540 timeval_to_Time (struct timeval
const *t
)
2546 ms
= t
->tv_usec
/ 1000;
2550 /* Return the current position of the mouse.
2552 Set *f to the frame the mouse is in, or zero if the mouse is in no
2553 Emacs frame. If it is set to zero, all the other arguments are
2556 Set *bar_window to Qnil, and *x and *y to the column and
2557 row of the character cell the mouse is over.
2559 Set *timeptr to the time the mouse was at the returned position.
2561 This clears mouse_moved until the next motion
2564 term_mouse_position (FRAME_PTR
*fp
, int insist
, Lisp_Object
*bar_window
,
2565 enum scroll_bar_part
*part
, Lisp_Object
*x
,
2566 Lisp_Object
*y
, Time
*timeptr
)
2570 *fp
= SELECTED_FRAME ();
2571 (*fp
)->mouse_moved
= 0;
2576 XSETINT (*x
, last_mouse_x
);
2577 XSETINT (*y
, last_mouse_y
);
2578 gettimeofday(&now
, 0);
2579 *timeptr
= timeval_to_Time (&now
);
2582 /* Prepare a mouse-event in *RESULT for placement in the input queue.
2584 If the event is a button press, then note that we have grabbed
2588 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
2594 result
->kind
= GPM_CLICK_EVENT
;
2595 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
2597 if (event
->buttons
& j
) {
2598 result
->code
= i
; /* button number */
2602 gettimeofday(&now
, 0);
2603 result
->timestamp
= timeval_to_Time (&now
);
2605 if (event
->type
& GPM_UP
)
2606 result
->modifiers
= up_modifier
;
2607 else if (event
->type
& GPM_DOWN
)
2608 result
->modifiers
= down_modifier
;
2610 result
->modifiers
= 0;
2612 if (event
->type
& GPM_SINGLE
)
2613 result
->modifiers
|= click_modifier
;
2615 if (event
->type
& GPM_DOUBLE
)
2616 result
->modifiers
|= double_modifier
;
2618 if (event
->type
& GPM_TRIPLE
)
2619 result
->modifiers
|= triple_modifier
;
2621 if (event
->type
& GPM_DRAG
)
2622 result
->modifiers
|= drag_modifier
;
2624 if (!(event
->type
& (GPM_MOVE
| GPM_DRAG
))) {
2627 if (event
->modifiers
& (1 << 0))
2628 result
->modifiers
|= shift_modifier
;
2631 if (event
->modifiers
& (1 << 2))
2632 result
->modifiers
|= ctrl_modifier
;
2634 /* 1 << KG_ALT || KG_ALTGR */
2635 if (event
->modifiers
& (1 << 3)
2636 || event
->modifiers
& (1 << 1))
2637 result
->modifiers
|= meta_modifier
;
2640 XSETINT (result
->x
, event
->x
);
2641 XSETINT (result
->y
, event
->y
);
2642 XSETFRAME (result
->frame_or_window
, f
);
2648 handle_one_term_event (struct tty_display_info
*tty
, Gpm_Event
*event
, struct input_event
* hold_quit
)
2650 struct frame
*f
= XFRAME (tty
->top_frame
);
2651 struct input_event ie
;
2659 if (event
->type
& (GPM_MOVE
| GPM_DRAG
)) {
2660 previous_help_echo_string
= help_echo_string
;
2661 help_echo_string
= Qnil
;
2663 Gpm_DrawPointer (event
->x
, event
->y
, fileno (tty
->output
));
2665 if (!term_mouse_movement (f
, event
))
2666 help_echo_string
= previous_help_echo_string
;
2668 /* If the contents of the global variable help_echo_string
2669 has changed, generate a HELP_EVENT. */
2670 if (!NILP (help_echo_string
)
2671 || !NILP (previous_help_echo_string
))
2678 term_mouse_click (&ie
, event
, f
);
2682 if (ie
.kind
!= NO_EVENT
)
2684 kbd_buffer_store_event_hold (&ie
, hold_quit
);
2689 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
2694 XSETFRAME (frame
, f
);
2698 gen_help_event (help_echo_string
, frame
, help_echo_window
,
2699 help_echo_object
, help_echo_pos
);
2706 DEFUN ("gpm-mouse-start", Fgpm_mouse_start
, Sgpm_mouse_start
,
2708 doc
: /* Open a connection to Gpm.
2709 Gpm-mouse can only be activated for one tty at a time. */)
2712 struct frame
*f
= SELECTED_FRAME ();
2713 struct tty_display_info
*tty
2714 = ((f
)->output_method
== output_termcap
2715 ? (f
)->terminal
->display_info
.tty
: NULL
);
2716 Gpm_Connect connection
;
2719 error ("Gpm-mouse only works in the GNU/Linux console");
2721 return Qnil
; /* Already activated, nothing to do. */
2723 error ("Gpm-mouse can only be activated for one tty at a time");
2725 connection
.eventMask
= ~0;
2726 connection
.defaultMask
= ~GPM_HARD
;
2727 connection
.maxMod
= ~0;
2728 connection
.minMod
= 0;
2731 if (Gpm_Open (&connection
, 0) < 0)
2732 error ("Gpm-mouse failed to connect to the gpm daemon");
2736 /* `init_sys_modes' arranges for mouse movements sent through gpm_fd
2737 to generate SIGIOs. Apparently we need to call reset_sys_modes
2738 before calling init_sys_modes. */
2739 reset_sys_modes (tty
);
2740 init_sys_modes (tty
);
2741 add_gpm_wait_descriptor (gpm_fd
);
2750 delete_gpm_wait_descriptor (fd
);
2751 while (Gpm_Close()); /* close all the stack */
2755 DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop
, Sgpm_mouse_stop
,
2757 doc
: /* Close a connection to Gpm. */)
2760 struct frame
*f
= SELECTED_FRAME ();
2761 struct tty_display_info
*tty
2762 = ((f
)->output_method
== output_termcap
2763 ? (f
)->terminal
->display_info
.tty
: NULL
);
2765 if (!tty
|| gpm_tty
!= tty
)
2766 return Qnil
; /* Not activated on this terminal, nothing to do. */
2771 #endif /* HAVE_GPM */
2775 /***********************************************************************
2777 ***********************************************************************/
2779 /* Initialize the tty-dependent part of frame F. The frame must
2780 already have its device initialized. */
2783 create_tty_output (struct frame
*f
)
2785 struct tty_output
*t
= xzalloc (sizeof *t
);
2787 if (! FRAME_TERMCAP_P (f
))
2790 t
->display_info
= FRAME_TERMINAL (f
)->display_info
.tty
;
2792 f
->output_data
.tty
= t
;
2795 /* Delete frame F's face cache, and its tty-dependent part. */
2798 tty_free_frame_resources (struct frame
*f
)
2800 if (! FRAME_TERMCAP_P (f
))
2803 if (FRAME_FACE_CACHE (f
))
2804 free_frame_faces (f
);
2806 xfree (f
->output_data
.tty
);
2811 /* Delete frame F's face cache. */
2814 tty_free_frame_resources (struct frame
*f
)
2816 if (! FRAME_TERMCAP_P (f
) && ! FRAME_MSDOS_P (f
))
2819 if (FRAME_FACE_CACHE (f
))
2820 free_frame_faces (f
);
2824 /* Reset the hooks in TERMINAL. */
2827 clear_tty_hooks (struct terminal
*terminal
)
2830 terminal
->cursor_to_hook
= 0;
2831 terminal
->raw_cursor_to_hook
= 0;
2832 terminal
->clear_to_end_hook
= 0;
2833 terminal
->clear_frame_hook
= 0;
2834 terminal
->clear_end_of_line_hook
= 0;
2835 terminal
->ins_del_lines_hook
= 0;
2836 terminal
->insert_glyphs_hook
= 0;
2837 terminal
->write_glyphs_hook
= 0;
2838 terminal
->delete_glyphs_hook
= 0;
2839 terminal
->ring_bell_hook
= 0;
2840 terminal
->reset_terminal_modes_hook
= 0;
2841 terminal
->set_terminal_modes_hook
= 0;
2842 terminal
->update_begin_hook
= 0;
2843 terminal
->update_end_hook
= 0;
2844 terminal
->set_terminal_window_hook
= 0;
2845 terminal
->mouse_position_hook
= 0;
2846 terminal
->frame_rehighlight_hook
= 0;
2847 terminal
->frame_raise_lower_hook
= 0;
2848 terminal
->fullscreen_hook
= 0;
2849 terminal
->set_vertical_scroll_bar_hook
= 0;
2850 terminal
->condemn_scroll_bars_hook
= 0;
2851 terminal
->redeem_scroll_bar_hook
= 0;
2852 terminal
->judge_scroll_bars_hook
= 0;
2853 terminal
->read_socket_hook
= 0;
2854 terminal
->frame_up_to_date_hook
= 0;
2856 /* Leave these two set, or suspended frames are not deleted
2858 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
2859 terminal
->delete_terminal_hook
= &delete_tty
;
2862 /* Initialize hooks in TERMINAL with the values needed for a tty. */
2865 set_tty_hooks (struct terminal
*terminal
)
2867 terminal
->rif
= 0; /* ttys don't support window-based redisplay. */
2869 terminal
->cursor_to_hook
= &tty_cursor_to
;
2870 terminal
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
2872 terminal
->clear_to_end_hook
= &tty_clear_to_end
;
2873 terminal
->clear_frame_hook
= &tty_clear_frame
;
2874 terminal
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
2876 terminal
->ins_del_lines_hook
= &tty_ins_del_lines
;
2878 terminal
->insert_glyphs_hook
= &tty_insert_glyphs
;
2879 terminal
->write_glyphs_hook
= &tty_write_glyphs
;
2880 terminal
->delete_glyphs_hook
= &tty_delete_glyphs
;
2882 terminal
->ring_bell_hook
= &tty_ring_bell
;
2884 terminal
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
2885 terminal
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
2886 terminal
->update_begin_hook
= 0; /* Not needed. */
2887 terminal
->update_end_hook
= &tty_update_end
;
2888 terminal
->set_terminal_window_hook
= &tty_set_terminal_window
;
2890 terminal
->mouse_position_hook
= 0; /* Not needed. */
2891 terminal
->frame_rehighlight_hook
= 0; /* Not needed. */
2892 terminal
->frame_raise_lower_hook
= 0; /* Not needed. */
2894 terminal
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
2895 terminal
->condemn_scroll_bars_hook
= 0; /* Not needed. */
2896 terminal
->redeem_scroll_bar_hook
= 0; /* Not needed. */
2897 terminal
->judge_scroll_bars_hook
= 0; /* Not needed. */
2899 terminal
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
2900 terminal
->frame_up_to_date_hook
= 0; /* Not needed. */
2902 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
2903 terminal
->delete_terminal_hook
= &delete_tty
;
2906 /* Drop the controlling terminal if fd is the same device. */
2908 dissociate_if_controlling_tty (int fd
)
2910 pid_t pgid
= tcgetpgrp (fd
); /* If tcgetpgrp succeeds, fd is the ctty. */
2915 /* Create a termcap display on the tty device with the given name and
2918 If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
2919 Otherwise NAME should be a path to the tty device file,
2922 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
2924 If MUST_SUCCEED is true, then all errors are fatal. */
2927 init_tty (const char *name
, const char *terminal_type
, int must_succeed
)
2930 char **address
= &area
;
2931 int buffer_size
= 4096;
2933 struct tty_display_info
*tty
= NULL
;
2934 struct terminal
*terminal
= NULL
;
2935 int ctty
= 0; /* 1 if asked to open controlling tty. */
2938 maybe_fatal (must_succeed
, 0,
2939 "Unknown terminal type",
2940 "Unknown terminal type");
2944 if (!strcmp (name
, DEV_TTY
))
2947 /* If we already have a terminal on the given device, use that. If
2948 all such terminals are suspended, create a new one instead. */
2949 /* XXX Perhaps this should be made explicit by having init_tty
2950 always create a new terminal and separating terminal and frame
2951 creation on Lisp level. */
2952 terminal
= get_named_tty (name
);
2956 terminal
= create_terminal ();
2959 maybe_fatal (0, 0, "Attempt to create another terminal %s", "",
2962 tty
= &the_only_display_info
;
2964 tty
= xzalloc (sizeof *tty
);
2966 tty
->top_frame
= Qnil
;
2967 tty
->next
= tty_list
;
2970 terminal
->type
= output_termcap
;
2971 terminal
->display_info
.tty
= tty
;
2972 tty
->terminal
= terminal
;
2974 tty
->Wcm
= xmalloc (sizeof *tty
->Wcm
);
2977 encode_terminal_src_size
= 0;
2978 encode_terminal_dst_size
= 0;
2982 set_tty_hooks (terminal
);
2985 /* Open the terminal device. */
2988 /* If !ctty, don't recognize it as our controlling terminal, and
2989 don't make it the controlling tty if we don't have one now.
2991 Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
2992 defined on Hurd. On other systems, we need to explicitly
2993 dissociate ourselves from the controlling tty when we want to
2994 open a frame on the same terminal. */
2995 int flags
= O_RDWR
| O_NOCTTY
| (ctty
? 0 : O_IGNORE_CTTY
);
2996 int fd
= emacs_open (name
, flags
, 0);
2998 tty
->name
= xstrdup (name
);
2999 terminal
->name
= xstrdup (name
);
3002 maybe_fatal (must_succeed
, terminal
,
3003 "Could not open file: %s",
3004 "Could not open file: %s",
3009 maybe_fatal (must_succeed
, terminal
,
3010 "Not a tty device: %s",
3011 "Not a tty device: %s",
3015 if (!O_IGNORE_CTTY
&& !ctty
)
3016 dissociate_if_controlling_tty (fd
);
3018 file
= fdopen (fd
, "w+");
3023 tty
->type
= xstrdup (terminal_type
);
3025 add_keyboard_wait_descriptor (fileno (tty
->input
));
3029 tty
->termcap_term_buffer
= xmalloc (buffer_size
);
3031 /* On some systems, tgetent tries to access the controlling
3035 sigemptyset (&blocked
);
3036 sigaddset (&blocked
, SIGTTOU
);
3037 pthread_sigmask (SIG_BLOCK
, &blocked
, 0);
3038 status
= tgetent (tty
->termcap_term_buffer
, terminal_type
);
3039 pthread_sigmask (SIG_UNBLOCK
, &blocked
, 0);
3045 maybe_fatal (must_succeed
, terminal
,
3046 "Cannot open terminfo database file",
3047 "Cannot open terminfo database file");
3049 maybe_fatal (must_succeed
, terminal
,
3050 "Cannot open termcap database file",
3051 "Cannot open termcap database file");
3056 maybe_fatal (must_succeed
, terminal
,
3057 "Terminal type %s is not defined",
3058 "Terminal type %s is not defined.\n\
3059 If that is not the actual type of terminal you have,\n\
3060 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3061 `setenv TERM ...') to specify the correct type. It may be necessary\n"
3063 "to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3065 "to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3071 if (strlen (tty
->termcap_term_buffer
) >= buffer_size
)
3073 buffer_size
= strlen (tty
->termcap_term_buffer
);
3075 tty
->termcap_strings_buffer
= area
= xmalloc (buffer_size
);
3076 tty
->TS_ins_line
= tgetstr ("al", address
);
3077 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
3078 tty
->TS_bell
= tgetstr ("bl", address
);
3079 BackTab (tty
) = tgetstr ("bt", address
);
3080 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
3081 tty
->TS_clr_line
= tgetstr ("ce", address
);
3082 tty
->TS_clr_frame
= tgetstr ("cl", address
);
3083 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
3084 AbsPosition (tty
) = tgetstr ("cm", address
);
3085 CR (tty
) = tgetstr ("cr", address
);
3086 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
3087 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
3088 RowPosition (tty
) = tgetstr ("cv", address
);
3089 tty
->TS_del_char
= tgetstr ("dc", address
);
3090 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
3091 tty
->TS_del_line
= tgetstr ("dl", address
);
3092 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
3093 tty
->TS_delete_mode
= tgetstr ("dm", address
);
3094 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
3095 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
3096 Home (tty
) = tgetstr ("ho", address
);
3097 tty
->TS_ins_char
= tgetstr ("ic", address
);
3098 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
3099 tty
->TS_insert_mode
= tgetstr ("im", address
);
3100 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
3101 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
3102 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
3103 LastLine (tty
) = tgetstr ("ll", address
);
3104 Right (tty
) = tgetstr ("nd", address
);
3105 Down (tty
) = tgetstr ("do", address
);
3107 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
3108 if (tgetflag ("bs"))
3109 Left (tty
) = "\b"; /* can't possibly be longer! */
3110 else /* (Actually, "bs" is obsolete...) */
3111 Left (tty
) = tgetstr ("le", address
);
3113 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
3114 tty
->TS_pad_char
= tgetstr ("pc", address
);
3115 tty
->TS_repeat
= tgetstr ("rp", address
);
3116 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
3117 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
3118 tty
->TS_standout_mode
= tgetstr ("so", address
);
3119 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
3120 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
3121 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
3122 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
3123 Up (tty
) = tgetstr ("up", address
);
3124 tty
->TS_visible_bell
= tgetstr ("vb", address
);
3125 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
3126 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
3127 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
3128 tty
->TS_set_window
= tgetstr ("wi", address
);
3130 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
3131 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
3132 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
3133 tty
->TS_enter_italic_mode
= tgetstr ("ZH", address
);
3134 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
3135 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
3136 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3137 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3138 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
3140 MultiUp (tty
) = tgetstr ("UP", address
);
3141 MultiDown (tty
) = tgetstr ("DO", address
);
3142 MultiLeft (tty
) = tgetstr ("LE", address
);
3143 MultiRight (tty
) = tgetstr ("RI", address
);
3145 /* SVr4/ANSI color support. If "op" isn't available, don't support
3146 color because we can't switch back to the default foreground and
3148 tty
->TS_orig_pair
= tgetstr ("op", address
);
3149 if (tty
->TS_orig_pair
)
3151 tty
->TS_set_foreground
= tgetstr ("AF", address
);
3152 tty
->TS_set_background
= tgetstr ("AB", address
);
3153 if (!tty
->TS_set_foreground
)
3156 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
3157 tty
->TS_set_background
= tgetstr ("Sb", address
);
3160 tty
->TN_max_colors
= tgetnum ("Co");
3161 tty
->TN_max_pairs
= tgetnum ("pa");
3163 tty
->TN_no_color_video
= tgetnum ("NC");
3164 if (tty
->TN_no_color_video
== -1)
3165 tty
->TN_no_color_video
= 0;
3168 tty_default_color_capabilities (tty
, 1);
3170 MagicWrap (tty
) = tgetflag ("xn");
3171 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3172 the former flag imply the latter. */
3173 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
3174 terminal
->memory_below_frame
= tgetflag ("db");
3175 tty
->TF_hazeltine
= tgetflag ("hz");
3176 terminal
->must_write_spaces
= tgetflag ("in");
3177 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
3178 tty
->TF_insmode_motion
= tgetflag ("mi");
3179 tty
->TF_standout_motion
= tgetflag ("ms");
3180 tty
->TF_underscore
= tgetflag ("ul");
3181 tty
->TF_teleray
= tgetflag ("xt");
3186 struct frame
*f
= XFRAME (selected_frame
);
3188 initialize_w32_display (terminal
);
3190 FrameRows (tty
) = FRAME_LINES (f
);
3191 FrameCols (tty
) = FRAME_COLS (f
);
3192 tty
->specified_window
= FRAME_LINES (f
);
3194 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
3195 terminal
->char_ins_del_ok
= 1;
3201 if (strcmp (terminal_type
, "internal") == 0)
3202 terminal
->type
= output_msdos_raw
;
3203 initialize_msdos_display (terminal
);
3205 get_tty_size (fileno (tty
->input
), &width
, &height
);
3206 FrameCols (tty
) = width
;
3207 FrameRows (tty
) = height
;
3208 terminal
->char_ins_del_ok
= 0;
3209 init_baud_rate (fileno (tty
->input
));
3212 tty
->output
= stdout
;
3214 /* The following two are inaccessible from w32console.c. */
3215 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3216 terminal
->delete_terminal_hook
= &delete_tty
;
3218 tty
->name
= xstrdup (name
);
3219 terminal
->name
= xstrdup (name
);
3220 tty
->type
= xstrdup (terminal_type
);
3222 add_keyboard_wait_descriptor (0);
3224 tty
->delete_in_insert_mode
= 1;
3227 terminal
->scroll_region_ok
= 0;
3229 /* Seems to insert lines when it's not supposed to, messing up the
3230 display. In doing a trace, it didn't seem to be called much, so I
3231 don't think we're losing anything by turning it off. */
3232 terminal
->line_ins_del_ok
= 0;
3234 tty
->TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
3238 terminal
->mouse_position_hook
= term_mouse_position
;
3239 tty
->mouse_highlight
.mouse_face_window
= Qnil
;
3242 terminal
->kboard
= xmalloc (sizeof *terminal
->kboard
);
3243 init_kboard (terminal
->kboard
);
3244 kset_window_system (terminal
->kboard
, Qnil
);
3245 terminal
->kboard
->next_kboard
= all_kboards
;
3246 all_kboards
= terminal
->kboard
;
3247 terminal
->kboard
->reference_count
++;
3248 /* Don't let the initial kboard remain current longer than necessary.
3249 That would cause problems if a file loaded on startup tries to
3250 prompt in the mini-buffer. */
3251 if (current_kboard
== initial_kboard
)
3252 current_kboard
= terminal
->kboard
;
3254 term_get_fkeys (address
, terminal
->kboard
);
3256 /* Get frame size from system, or else from termcap. */
3259 get_tty_size (fileno (tty
->input
), &width
, &height
);
3260 FrameCols (tty
) = width
;
3261 FrameRows (tty
) = height
;
3264 if (FrameCols (tty
) <= 0)
3265 FrameCols (tty
) = tgetnum ("co");
3266 if (FrameRows (tty
) <= 0)
3267 FrameRows (tty
) = tgetnum ("li");
3269 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
3270 maybe_fatal (must_succeed
, terminal
,
3271 "Screen size %dx%d is too small",
3272 "Screen size %dx%d is too small",
3273 FrameCols (tty
), FrameRows (tty
));
3275 TabWidth (tty
) = tgetnum ("tw");
3278 tty
->TS_bell
= "\07";
3280 if (!tty
->TS_fwd_scroll
)
3281 tty
->TS_fwd_scroll
= Down (tty
);
3283 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
3285 if (TabWidth (tty
) < 0)
3288 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3289 and newer termcap doc does not seem to say there is a default.
3290 if (!tty->Wcm->cm_tab)
3291 tty->Wcm->cm_tab = "\t";
3294 /* We don't support standout modes that use `magic cookies', so
3295 turn off any that do. */
3296 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
3298 tty
->TS_standout_mode
= 0;
3299 tty
->TS_end_standout_mode
= 0;
3301 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3303 tty
->TS_enter_underline_mode
= 0;
3304 tty
->TS_exit_underline_mode
= 0;
3307 /* If there's no standout mode, try to use underlining instead. */
3308 if (tty
->TS_standout_mode
== 0)
3310 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
3311 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
3314 /* If no `se' string, try using a `me' string instead.
3315 If that fails, we can't use standout mode at all. */
3316 if (tty
->TS_end_standout_mode
== 0)
3318 char *s
= tgetstr ("me", address
);
3320 tty
->TS_end_standout_mode
= s
;
3322 tty
->TS_standout_mode
= 0;
3325 if (tty
->TF_teleray
)
3327 tty
->Wcm
->cm_tab
= 0;
3328 /* We can't support standout mode, because it uses magic cookies. */
3329 tty
->TS_standout_mode
= 0;
3330 /* But that means we cannot rely on ^M to go to column zero! */
3332 /* LF can't be trusted either -- can alter hpos */
3333 /* if move at column 0 thru a line with TS_standout_mode */
3337 tty
->specified_window
= FrameRows (tty
);
3339 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
3341 maybe_fatal (must_succeed
, terminal
,
3342 "Terminal type \"%s\" is not powerful enough to run Emacs",
3343 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3344 It lacks the ability to position the cursor.\n\
3345 If that is not the actual type of terminal you have,\n\
3346 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3347 `setenv TERM ...') to specify the correct type. It may be necessary\n"
3349 "to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3350 # else /* TERMCAP */
3351 "to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3352 # endif /* TERMINFO */
3356 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
3357 maybe_fatal (must_succeed
, terminal
,
3358 "Could not determine the frame size",
3359 "Could not determine the frame size");
3361 tty
->delete_in_insert_mode
3362 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
3363 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
3365 tty
->se_is_so
= (tty
->TS_standout_mode
3366 && tty
->TS_end_standout_mode
3367 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
3369 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
3371 terminal
->scroll_region_ok
3373 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
3375 terminal
->line_ins_del_ok
3376 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
3377 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
3378 || (terminal
->scroll_region_ok
3379 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
3381 terminal
->char_ins_del_ok
3382 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
3383 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
3384 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
3386 terminal
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
3388 init_baud_rate (fileno (tty
->input
));
3390 #endif /* not DOS_NT */
3392 /* Init system terminal modes (RAW or CBREAK, etc.). */
3393 init_sys_modes (tty
);
3400 vfatal (const char *str
, va_list ap
)
3402 fprintf (stderr
, "emacs: ");
3403 vfprintf (stderr
, str
, ap
);
3404 if (!(strlen (str
) > 0 && str
[strlen (str
) - 1] == '\n'))
3405 fprintf (stderr
, "\n");
3411 /* Auxiliary error-handling function for init_tty.
3412 Delete TERMINAL, then call error or fatal with str1 or str2,
3413 respectively, according to whether MUST_SUCCEED is zero or not. */
3416 maybe_fatal (int must_succeed
, struct terminal
*terminal
,
3417 const char *str1
, const char *str2
, ...)
3420 va_start (ap
, str2
);
3422 delete_tty (terminal
);
3434 fatal (const char *str
, ...)
3444 /* Delete the given tty terminal, closing all frames on it. */
3447 delete_tty (struct terminal
*terminal
)
3449 struct tty_display_info
*tty
;
3451 /* Protect against recursive calls. delete_frame in
3452 delete_terminal calls us back when it deletes our last frame. */
3453 if (!terminal
->name
)
3456 if (terminal
->type
!= output_termcap
)
3459 tty
= terminal
->display_info
.tty
;
3461 if (tty
== tty_list
)
3462 tty_list
= tty
->next
;
3465 struct tty_display_info
*p
;
3466 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
3470 /* This should not happen. */
3473 p
->next
= tty
->next
;
3477 /* reset_sys_modes needs a valid device, so this call needs to be
3478 before delete_terminal. */
3479 reset_sys_modes (tty
);
3481 delete_terminal (terminal
);
3488 delete_keyboard_wait_descriptor (fileno (tty
->input
));
3489 if (tty
->input
!= stdin
)
3490 fclose (tty
->input
);
3492 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
3493 fclose (tty
->output
);
3494 if (tty
->termscript
)
3495 fclose (tty
->termscript
);
3497 xfree (tty
->old_tty
);
3499 xfree (tty
->termcap_strings_buffer
);
3500 xfree (tty
->termcap_term_buffer
);
3508 DEFVAR_BOOL ("system-uses-terminfo", system_uses_terminfo
,
3509 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3510 This variable can be used by terminal emulator packages. */);
3512 system_uses_terminfo
= 1;
3514 system_uses_terminfo
= 0;
3517 DEFVAR_LISP ("suspend-tty-functions", Vsuspend_tty_functions
,
3518 doc
: /* Functions run after suspending a tty.
3519 The functions are run with one argument, the terminal object to be suspended.
3520 See `suspend-tty'. */);
3521 Vsuspend_tty_functions
= Qnil
;
3524 DEFVAR_LISP ("resume-tty-functions", Vresume_tty_functions
,
3525 doc
: /* Functions run after resuming a tty.
3526 The functions are run with one argument, the terminal object that was revived.
3527 See `resume-tty'. */);
3528 Vresume_tty_functions
= Qnil
;
3530 DEFVAR_BOOL ("visible-cursor", visible_cursor
,
3531 doc
: /* Non-nil means to make the cursor very visible.
3532 This only has an effect when running in a text terminal.
3533 What means \"very visible\" is up to your terminal. It may make the cursor
3534 bigger, or it may make it blink, or it may do nothing at all. */);
3537 defsubr (&Stty_display_color_p
);
3538 defsubr (&Stty_display_color_cells
);
3539 defsubr (&Stty_no_underline
);
3540 defsubr (&Stty_type
);
3541 defsubr (&Scontrolling_tty_p
);
3542 defsubr (&Stty_top_frame
);
3543 defsubr (&Ssuspend_tty
);
3544 defsubr (&Sresume_tty
);
3546 defsubr (&Sgpm_mouse_start
);
3547 defsubr (&Sgpm_mouse_stop
);
3548 #endif /* HAVE_GPM */
3551 default_orig_pair
= NULL
;
3552 default_set_foreground
= NULL
;
3553 default_set_background
= NULL
;
3554 #endif /* !DOS_NT */
3556 encode_terminal_src
= NULL
;
3557 encode_terminal_dst
= NULL
;