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;
67 /* The name of the default console device. */
69 #define DEV_TTY "CONOUT$"
71 #define DEV_TTY "/dev/tty"
74 static void tty_set_scroll_region (struct frame
*f
, int start
, int stop
);
75 static void turn_on_face (struct frame
*, int face_id
);
76 static void turn_off_face (struct frame
*, int face_id
);
77 static void tty_turn_off_highlight (struct tty_display_info
*);
78 static void tty_show_cursor (struct tty_display_info
*);
79 static void tty_hide_cursor (struct tty_display_info
*);
80 static void tty_background_highlight (struct tty_display_info
*tty
);
81 static struct terminal
*get_tty_terminal (Lisp_Object
, int);
82 static void clear_tty_hooks (struct terminal
*terminal
);
83 static void set_tty_hooks (struct terminal
*terminal
);
84 static void dissociate_if_controlling_tty (int fd
);
85 static void delete_tty (struct terminal
*);
86 static _Noreturn
void maybe_fatal (int must_succeed
, struct terminal
*terminal
,
87 const char *str1
, const char *str2
, ...)
88 ATTRIBUTE_FORMAT_PRINTF (3, 5) ATTRIBUTE_FORMAT_PRINTF (4, 5);
89 static _Noreturn
void vfatal (const char *str
, va_list ap
)
90 ATTRIBUTE_FORMAT_PRINTF (1, 0);
93 #define OUTPUT(tty, a) \
94 emacs_tputs ((tty), a, \
95 (int) (FRAME_LINES (XFRAME (selected_frame)) \
99 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
100 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
102 #define OUTPUT_IF(tty, a) \
108 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
110 /* Display space properties */
112 /* Chain of all tty device parameters. */
113 struct tty_display_info
*tty_list
;
115 /* Meaning of bits in no_color_video. Each bit set means that the
116 corresponding attribute cannot be combined with colors. */
120 NC_STANDOUT
= 1 << 0,
121 NC_UNDERLINE
= 1 << 1,
132 /* The largest frame width in any call to calculate_costs. */
134 static int max_frame_cols
;
136 /* Non-zero if we have dropped our controlling tty and therefore
137 should not open a frame on stdout. */
138 static int no_controlling_tty
;
143 #include <sys/fcntl.h>
145 /* The device for which we have enabled gpm support (or NULL). */
146 struct tty_display_info
*gpm_tty
= NULL
;
148 /* Last recorded mouse coordinates. */
149 static int last_mouse_x
, last_mouse_y
;
150 #endif /* HAVE_GPM */
152 /* Ring the bell on a tty. */
155 tty_ring_bell (struct frame
*f
)
157 struct tty_display_info
*tty
= FRAME_TTY (f
);
161 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
162 ? tty
->TS_visible_bell
164 fflush (tty
->output
);
168 /* Set up termcap modes for Emacs. */
171 tty_set_terminal_modes (struct terminal
*terminal
)
173 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
177 if (tty
->TS_termcap_modes
)
178 OUTPUT (tty
, tty
->TS_termcap_modes
);
181 /* Output enough newlines to scroll all the old screen contents
182 off the screen, so it won't be overwritten and lost. */
185 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
189 OUTPUT_IF (tty
, visible_cursor
? tty
->TS_cursor_visible
: tty
->TS_cursor_normal
);
190 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
192 fflush (tty
->output
);
196 /* Reset termcap modes before exiting Emacs. */
199 tty_reset_terminal_modes (struct terminal
*terminal
)
201 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
205 tty_turn_off_highlight (tty
);
206 tty_turn_off_insert (tty
);
207 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
208 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
209 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
210 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
211 /* Output raw CR so kernel can track the cursor hpos. */
214 fflush (tty
->output
);
218 /* Flag the end of a display update on a termcap terminal. */
221 tty_update_end (struct frame
*f
)
223 struct tty_display_info
*tty
= FRAME_TTY (f
);
225 if (!XWINDOW (selected_window
)->cursor_off_p
)
226 tty_show_cursor (tty
);
227 tty_turn_off_insert (tty
);
228 tty_background_highlight (tty
);
231 /* The implementation of set_terminal_window for termcap frames. */
234 tty_set_terminal_window (struct frame
*f
, int size
)
236 struct tty_display_info
*tty
= FRAME_TTY (f
);
238 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
239 if (FRAME_SCROLL_REGION_OK (f
))
240 tty_set_scroll_region (f
, 0, tty
->specified_window
);
244 tty_set_scroll_region (struct frame
*f
, int start
, int stop
)
247 struct tty_display_info
*tty
= FRAME_TTY (f
);
249 if (tty
->TS_set_scroll_region
)
250 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1, 0, 0);
251 else if (tty
->TS_set_scroll_region_1
)
252 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
253 FRAME_LINES (f
), start
,
254 FRAME_LINES (f
) - stop
,
257 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
266 tty_turn_on_insert (struct tty_display_info
*tty
)
268 if (!tty
->insert_mode
)
269 OUTPUT (tty
, tty
->TS_insert_mode
);
270 tty
->insert_mode
= 1;
274 tty_turn_off_insert (struct tty_display_info
*tty
)
276 if (tty
->insert_mode
)
277 OUTPUT (tty
, tty
->TS_end_insert_mode
);
278 tty
->insert_mode
= 0;
281 /* Handle highlighting. */
284 tty_turn_off_highlight (struct tty_display_info
*tty
)
286 if (tty
->standout_mode
)
287 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
288 tty
->standout_mode
= 0;
292 tty_turn_on_highlight (struct tty_display_info
*tty
)
294 if (!tty
->standout_mode
)
295 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
296 tty
->standout_mode
= 1;
300 tty_toggle_highlight (struct tty_display_info
*tty
)
302 if (tty
->standout_mode
)
303 tty_turn_off_highlight (tty
);
305 tty_turn_on_highlight (tty
);
309 /* Make cursor invisible. */
312 tty_hide_cursor (struct tty_display_info
*tty
)
314 if (tty
->cursor_hidden
== 0)
316 tty
->cursor_hidden
= 1;
317 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
322 /* Ensure that cursor is visible. */
325 tty_show_cursor (struct tty_display_info
*tty
)
327 if (tty
->cursor_hidden
)
329 tty
->cursor_hidden
= 0;
330 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
332 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
337 /* Set standout mode to the state it should be in for
338 empty space inside windows. What this is,
339 depends on the user option inverse-video. */
342 tty_background_highlight (struct tty_display_info
*tty
)
345 tty_turn_on_highlight (tty
);
347 tty_turn_off_highlight (tty
);
350 /* Set standout mode to the mode specified for the text to be output. */
353 tty_highlight_if_desired (struct tty_display_info
*tty
)
356 tty_turn_on_highlight (tty
);
358 tty_turn_off_highlight (tty
);
362 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
363 frame-relative coordinates. */
366 tty_cursor_to (struct frame
*f
, int vpos
, int hpos
)
368 struct tty_display_info
*tty
= FRAME_TTY (f
);
370 /* Detect the case where we are called from reset_sys_modes
371 and the costs have never been calculated. Do nothing. */
372 if (! tty
->costs_set
)
375 if (curY (tty
) == vpos
376 && curX (tty
) == hpos
)
378 if (!tty
->TF_standout_motion
)
379 tty_background_highlight (tty
);
380 if (!tty
->TF_insmode_motion
)
381 tty_turn_off_insert (tty
);
382 cmgoto (tty
, vpos
, hpos
);
385 /* Similar but don't take any account of the wasted characters. */
388 tty_raw_cursor_to (struct frame
*f
, int row
, int col
)
390 struct tty_display_info
*tty
= FRAME_TTY (f
);
392 if (curY (tty
) == row
393 && curX (tty
) == col
)
395 if (!tty
->TF_standout_motion
)
396 tty_background_highlight (tty
);
397 if (!tty
->TF_insmode_motion
)
398 tty_turn_off_insert (tty
);
399 cmgoto (tty
, row
, col
);
402 /* Erase operations */
404 /* Clear from cursor to end of frame on a termcap device. */
407 tty_clear_to_end (struct frame
*f
)
410 struct tty_display_info
*tty
= FRAME_TTY (f
);
412 if (tty
->TS_clr_to_bottom
)
414 tty_background_highlight (tty
);
415 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
419 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
422 clear_end_of_line (f
, FRAME_COLS (f
));
427 /* Clear an entire termcap frame. */
430 tty_clear_frame (struct frame
*f
)
432 struct tty_display_info
*tty
= FRAME_TTY (f
);
434 if (tty
->TS_clr_frame
)
436 tty_background_highlight (tty
);
437 OUTPUT (tty
, tty
->TS_clr_frame
);
447 /* An implementation of clear_end_of_line for termcap frames.
449 Note that the cursor may be moved, on terminals lacking a `ce' string. */
452 tty_clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
455 struct tty_display_info
*tty
= FRAME_TTY (f
);
457 /* Detect the case where we are called from reset_sys_modes
458 and the costs have never been calculated. Do nothing. */
459 if (! tty
->costs_set
)
462 if (curX (tty
) >= first_unused_hpos
)
464 tty_background_highlight (tty
);
465 if (tty
->TS_clr_line
)
467 OUTPUT1 (tty
, tty
->TS_clr_line
);
470 { /* have to do it the hard way */
471 tty_turn_off_insert (tty
);
473 /* Do not write in last row last col with Auto-wrap on. */
475 && curY (tty
) == FrameRows (tty
) - 1
476 && first_unused_hpos
== FrameCols (tty
))
479 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
482 fputc (' ', tty
->termscript
);
483 fputc (' ', tty
->output
);
485 cmplus (tty
, first_unused_hpos
- curX (tty
));
489 /* Buffers to store the source and result of code conversion for terminal. */
490 static unsigned char *encode_terminal_src
;
491 static unsigned char *encode_terminal_dst
;
492 /* Allocated sizes of the above buffers. */
493 static ptrdiff_t encode_terminal_src_size
;
494 static ptrdiff_t encode_terminal_dst_size
;
496 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
497 Set CODING->produced to the byte-length of the resulting byte
498 sequence, and return a pointer to that byte sequence. */
501 encode_terminal_code (struct glyph
*src
, int src_len
, struct coding_system
*coding
)
503 struct glyph
*src_end
= src
+ src_len
;
505 ptrdiff_t nchars
, nbytes
, required
;
506 ptrdiff_t tlen
= GLYPH_TABLE_LENGTH
;
507 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
508 Lisp_Object charset_list
;
510 /* Allocate sufficient size of buffer to store all characters in
511 multibyte-form. But, it may be enlarged on demand if
512 Vglyph_table contains a string or a composite glyph is
514 if (min (PTRDIFF_MAX
, SIZE_MAX
) / MAX_MULTIBYTE_LENGTH
< src_len
)
515 memory_full (SIZE_MAX
);
517 required
*= MAX_MULTIBYTE_LENGTH
;
518 if (encode_terminal_src_size
< required
)
520 encode_terminal_src
= xrealloc (encode_terminal_src
, required
);
521 encode_terminal_src_size
= required
;
524 charset_list
= coding_charset_list (coding
);
526 buf
= encode_terminal_src
;
528 while (src
< src_end
)
530 if (src
->type
== COMPOSITE_GLYPH
)
532 struct composition
*cmp
IF_LINT (= NULL
);
533 Lisp_Object gstring
IF_LINT (= Qnil
);
536 nbytes
= buf
- encode_terminal_src
;
537 if (src
->u
.cmp
.automatic
)
539 gstring
= composition_gstring_from_id (src
->u
.cmp
.id
);
540 required
= src
->slice
.cmp
.to
- src
->slice
.cmp
.from
+ 1;
544 cmp
= composition_table
[src
->u
.cmp
.id
];
545 required
= cmp
->glyph_len
;
546 required
*= MAX_MULTIBYTE_LENGTH
;
549 if (encode_terminal_src_size
- nbytes
< required
)
551 encode_terminal_src
=
552 xpalloc (encode_terminal_src
, &encode_terminal_src_size
,
553 required
- (encode_terminal_src_size
- nbytes
),
555 buf
= encode_terminal_src
+ nbytes
;
558 if (src
->u
.cmp
.automatic
)
559 for (i
= src
->slice
.cmp
.from
; i
<= src
->slice
.cmp
.to
; i
++)
561 Lisp_Object g
= LGSTRING_GLYPH (gstring
, i
);
562 int c
= LGLYPH_CHAR (g
);
564 if (! char_charset (c
, charset_list
, NULL
))
566 buf
+= CHAR_STRING (c
, buf
);
570 for (i
= 0; i
< cmp
->glyph_len
; i
++)
572 int c
= COMPOSITION_GLYPH (cmp
, i
);
574 /* TAB in a composition means display glyphs with
575 padding space on the left or right. */
578 if (char_charset (c
, charset_list
, NULL
))
580 if (CHAR_WIDTH (c
) == 0
581 && i
> 0 && COMPOSITION_GLYPH (cmp
, i
- 1) == '\t')
582 /* Should be left-padded */
584 buf
+= CHAR_STRING (' ', buf
);
590 buf
+= CHAR_STRING (c
, buf
);
594 /* We must skip glyphs to be padded for a wide character. */
595 else if (! CHAR_GLYPH_PADDING_P (*src
))
602 SET_GLYPH_FROM_CHAR_GLYPH (g
, src
[0]);
604 if (GLYPH_INVALID_P (g
) || GLYPH_SIMPLE_P (tbase
, tlen
, g
))
606 /* This glyph doesn't have an entry in Vglyph_table. */
611 /* This glyph has an entry in Vglyph_table,
612 so process any alias before testing for simpleness. */
613 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
615 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
616 /* We set the multi-byte form of a character in G
617 (that should be an ASCII character) at WORKBUF. */
620 /* We have a string in Vglyph_table. */
621 string
= tbase
[GLYPH_CHAR (g
)];
626 nbytes
= buf
- encode_terminal_src
;
627 if (encode_terminal_src_size
- nbytes
< MAX_MULTIBYTE_LENGTH
)
629 encode_terminal_src
=
630 xpalloc (encode_terminal_src
, &encode_terminal_src_size
,
631 MAX_MULTIBYTE_LENGTH
, -1, 1);
632 buf
= encode_terminal_src
+ nbytes
;
635 || char_charset (c
, charset_list
, NULL
))
637 /* Store the multibyte form of C at BUF. */
638 buf
+= CHAR_STRING (c
, buf
);
643 /* C is not encodable. */
646 while (src
+ 1 < src_end
&& CHAR_GLYPH_PADDING_P (src
[1]))
656 if (! STRING_MULTIBYTE (string
))
657 string
= string_to_multibyte (string
);
658 nbytes
= buf
- encode_terminal_src
;
659 if (encode_terminal_src_size
- nbytes
< SBYTES (string
))
661 encode_terminal_src
=
662 xpalloc (encode_terminal_src
, &encode_terminal_src_size
,
664 - (encode_terminal_src_size
- nbytes
)),
666 buf
= encode_terminal_src
+ nbytes
;
668 memcpy (buf
, SDATA (string
), SBYTES (string
));
669 buf
+= SBYTES (string
);
670 nchars
+= SCHARS (string
);
678 coding
->produced
= 0;
682 nbytes
= buf
- encode_terminal_src
;
683 coding
->source
= encode_terminal_src
;
684 if (encode_terminal_dst_size
== 0)
686 encode_terminal_dst
= xrealloc (encode_terminal_dst
,
687 encode_terminal_src_size
);
688 encode_terminal_dst_size
= encode_terminal_src_size
;
690 coding
->destination
= encode_terminal_dst
;
691 coding
->dst_bytes
= encode_terminal_dst_size
;
692 encode_coding_object (coding
, Qnil
, 0, 0, nchars
, nbytes
, Qnil
);
693 /* coding->destination may have been reallocated. */
694 encode_terminal_dst
= coding
->destination
;
695 encode_terminal_dst_size
= coding
->dst_bytes
;
697 return (encode_terminal_dst
);
702 /* An implementation of write_glyphs for termcap frames. */
705 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
707 unsigned char *conversion_buffer
;
708 struct coding_system
*coding
;
711 struct tty_display_info
*tty
= FRAME_TTY (f
);
713 tty_turn_off_insert (tty
);
714 tty_hide_cursor (tty
);
716 /* Don't dare write in last column of bottom line, if Auto-Wrap,
717 since that would scroll the whole frame on some terminals. */
720 && curY (tty
) + 1 == FRAME_LINES (f
)
721 && (curX (tty
) + len
) == FRAME_COLS (f
))
728 /* If terminal_coding does any conversion, use it, otherwise use
729 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
730 because it always return 1 if the member src_multibyte is 1. */
731 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
732 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
733 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
735 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
737 for (stringlen
= len
; stringlen
!= 0; stringlen
-= n
)
739 /* Identify a run of glyphs with the same face. */
740 int face_id
= string
->face_id
;
742 for (n
= 1; n
< stringlen
; ++n
)
743 if (string
[n
].face_id
!= face_id
)
746 /* Turn appearance modes of the face of the run on. */
747 tty_highlight_if_desired (tty
);
748 turn_on_face (f
, face_id
);
751 /* This is the last run. */
752 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
753 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
754 if (coding
->produced
> 0)
757 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
758 if (ferror (tty
->output
))
759 clearerr (tty
->output
);
761 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
766 /* Turn appearance modes off. */
767 turn_off_face (f
, face_id
);
768 tty_turn_off_highlight (tty
);
774 #ifdef HAVE_GPM /* Only used by GPM code. */
777 tty_write_glyphs_with_face (register struct frame
*f
, register struct glyph
*string
,
778 register int len
, register int face_id
)
780 unsigned char *conversion_buffer
;
781 struct coding_system
*coding
;
783 struct tty_display_info
*tty
= FRAME_TTY (f
);
785 tty_turn_off_insert (tty
);
786 tty_hide_cursor (tty
);
788 /* Don't dare write in last column of bottom line, if Auto-Wrap,
789 since that would scroll the whole frame on some terminals. */
792 && curY (tty
) + 1 == FRAME_LINES (f
)
793 && (curX (tty
) + len
) == FRAME_COLS (f
))
800 /* If terminal_coding does any conversion, use it, otherwise use
801 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
802 because it always return 1 if the member src_multibyte is 1. */
803 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
804 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
805 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
807 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
809 /* Turn appearance modes of the face. */
810 tty_highlight_if_desired (tty
);
811 turn_on_face (f
, face_id
);
813 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
814 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
815 if (coding
->produced
> 0)
818 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
819 if (ferror (tty
->output
))
820 clearerr (tty
->output
);
822 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
826 /* Turn appearance modes off. */
827 turn_off_face (f
, face_id
);
828 tty_turn_off_highlight (tty
);
834 /* An implementation of insert_glyphs for termcap frames. */
837 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
840 struct glyph
*glyph
= NULL
;
841 unsigned char *conversion_buffer
;
842 unsigned char space
[1];
843 struct coding_system
*coding
;
845 struct tty_display_info
*tty
= FRAME_TTY (f
);
847 if (tty
->TS_ins_multi_chars
)
849 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
, 0, 0, 0);
853 write_glyphs (f
, start
, len
);
857 tty_turn_on_insert (tty
);
861 space
[0] = SPACEGLYPH
;
863 /* If terminal_coding does any conversion, use it, otherwise use
864 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
865 because it always return 1 if the member src_multibyte is 1. */
866 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
867 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
868 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
870 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
874 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
877 conversion_buffer
= space
;
878 coding
->produced
= 1;
882 tty_highlight_if_desired (tty
);
883 turn_on_face (f
, start
->face_id
);
886 /* We must open sufficient space for a character which
887 occupies more than one column. */
888 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
890 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
895 /* This is the last glyph. */
896 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
898 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
901 if (coding
->produced
> 0)
904 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
905 if (ferror (tty
->output
))
906 clearerr (tty
->output
);
908 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
912 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
915 turn_off_face (f
, glyph
->face_id
);
916 tty_turn_off_highlight (tty
);
923 /* An implementation of delete_glyphs for termcap frames. */
926 tty_delete_glyphs (struct frame
*f
, int n
)
931 struct tty_display_info
*tty
= FRAME_TTY (f
);
933 if (tty
->delete_in_insert_mode
)
935 tty_turn_on_insert (tty
);
939 tty_turn_off_insert (tty
);
940 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
943 if (tty
->TS_del_multi_chars
)
945 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
, 0, 0, 0);
950 for (i
= 0; i
< n
; i
++)
951 OUTPUT1 (tty
, tty
->TS_del_char
);
952 if (!tty
->delete_in_insert_mode
)
953 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
956 /* An implementation of ins_del_lines for termcap frames. */
959 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
961 struct tty_display_info
*tty
= FRAME_TTY (f
);
963 n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
964 const char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
965 const char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
967 register int i
= n
> 0 ? n
: -n
;
970 /* If the lines below the insertion are being pushed
971 into the end of the window, this is the same as clearing;
972 and we know the lines are already clear, since the matching
973 deletion has already been done. So can ignore this. */
974 /* If the lines below the deletion are blank lines coming
975 out of the end of the window, don't bother,
976 as there will be a matching inslines later that will flush them. */
977 if (FRAME_SCROLL_REGION_OK (f
)
978 && vpos
+ i
>= tty
->specified_window
)
980 if (!FRAME_MEMORY_BELOW_FRAME (f
)
981 && vpos
+ i
>= FRAME_LINES (f
))
986 raw_cursor_to (f
, vpos
, 0);
987 tty_background_highlight (tty
);
988 buf
= tparam (multi
, 0, 0, i
, 0, 0, 0);
994 raw_cursor_to (f
, vpos
, 0);
995 tty_background_highlight (tty
);
997 OUTPUT (tty
, single
);
1003 tty_set_scroll_region (f
, vpos
, tty
->specified_window
);
1005 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
1007 raw_cursor_to (f
, vpos
, 0);
1008 tty_background_highlight (tty
);
1010 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1011 tty_set_scroll_region (f
, 0, tty
->specified_window
);
1014 if (!FRAME_SCROLL_REGION_OK (f
)
1015 && FRAME_MEMORY_BELOW_FRAME (f
)
1018 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
1023 /* Compute cost of sending "str", in characters,
1024 not counting any line-dependent padding. */
1027 string_cost (const char *str
)
1031 tputs (str
, 0, evalcost
);
1035 /* Compute cost of sending "str", in characters,
1036 counting any line-dependent padding at one line. */
1039 string_cost_one_line (const char *str
)
1043 tputs (str
, 1, evalcost
);
1047 /* Compute per line amount of line-dependent padding,
1048 in tenths of characters. */
1051 per_line_cost (const char *str
)
1055 tputs (str
, 0, evalcost
);
1058 tputs (str
, 10, evalcost
);
1062 /* char_ins_del_cost[n] is cost of inserting N characters.
1063 char_ins_del_cost[-n] is cost of deleting N characters.
1064 The length of this vector is based on max_frame_cols. */
1066 int *char_ins_del_vector
;
1068 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1072 calculate_ins_del_char_costs (struct frame
*f
)
1074 struct tty_display_info
*tty
= FRAME_TTY (f
);
1075 int ins_startup_cost
, del_startup_cost
;
1076 int ins_cost_per_char
, del_cost_per_char
;
1080 if (tty
->TS_ins_multi_chars
)
1082 ins_cost_per_char
= 0;
1083 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1085 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1086 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1088 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1089 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1090 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1091 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1095 ins_startup_cost
= 9999;
1096 ins_cost_per_char
= 0;
1099 if (tty
->TS_del_multi_chars
)
1101 del_cost_per_char
= 0;
1102 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1104 else if (tty
->TS_del_char
)
1106 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1107 + string_cost (tty
->TS_end_delete_mode
));
1108 if (tty
->delete_in_insert_mode
)
1109 del_startup_cost
/= 2;
1110 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1114 del_startup_cost
= 9999;
1115 del_cost_per_char
= 0;
1118 /* Delete costs are at negative offsets */
1119 p
= &char_ins_del_cost (f
)[0];
1120 for (i
= FRAME_COLS (f
); --i
>= 0;)
1121 *--p
= (del_startup_cost
+= del_cost_per_char
);
1123 /* Doing nothing is free */
1124 p
= &char_ins_del_cost (f
)[0];
1127 /* Insert costs are at positive offsets */
1128 for (i
= FRAME_COLS (f
); --i
>= 0;)
1129 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1133 calculate_costs (struct frame
*frame
)
1135 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1137 if (FRAME_TERMCAP_P (frame
))
1139 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1140 register const char *f
= (tty
->TS_set_scroll_region
1141 ? tty
->TS_set_scroll_region
1142 : tty
->TS_set_scroll_region_1
);
1144 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1148 /* These variables are only used for terminal stuff. They are
1149 allocated once for the terminal frame of X-windows emacs, but not
1152 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1153 X turns off char_ins_del_ok. */
1155 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1156 if ((min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof (int) - 1) / 2
1158 memory_full (SIZE_MAX
);
1160 char_ins_del_vector
=
1161 xrealloc (char_ins_del_vector
,
1162 (sizeof (int) + 2 * sizeof (int) * max_frame_cols
));
1164 memset (char_ins_del_vector
, 0,
1165 (sizeof (int) + 2 * sizeof (int) * max_frame_cols
));
1168 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1169 do_line_insertion_deletion_costs (frame
,
1170 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1171 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1174 do_line_insertion_deletion_costs (frame
,
1175 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1176 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1179 calculate_ins_del_char_costs (frame
);
1181 /* Don't use TS_repeat if its padding is worse than sending the chars */
1182 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1183 tty
->RPov
= string_cost (tty
->TS_repeat
);
1185 tty
->RPov
= FRAME_COLS (frame
) * 2;
1187 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1192 const char *cap
, *name
;
1195 /* Termcap capability names that correspond directly to X keysyms.
1196 Some of these (marked "terminfo") aren't supplied by old-style
1197 (Berkeley) termcap entries. They're listed in X keysym order;
1198 except we put the keypad keys first, so that if they clash with
1199 other keys (as on the IBM PC keyboard) they get overridden.
1202 static const struct fkey_table keys
[] =
1204 {"kh", "home"}, /* termcap */
1205 {"kl", "left"}, /* termcap */
1206 {"ku", "up"}, /* termcap */
1207 {"kr", "right"}, /* termcap */
1208 {"kd", "down"}, /* termcap */
1209 {"%8", "prior"}, /* terminfo */
1210 {"%5", "next"}, /* terminfo */
1211 {"@7", "end"}, /* terminfo */
1212 {"@1", "begin"}, /* terminfo */
1213 {"*6", "select"}, /* terminfo */
1214 {"%9", "print"}, /* terminfo */
1215 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1217 * "insert" --- see below
1219 {"&8", "undo"}, /* terminfo */
1220 {"%0", "redo"}, /* terminfo */
1221 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1222 {"@0", "find"}, /* terminfo */
1223 {"@2", "cancel"}, /* terminfo */
1224 {"%1", "help"}, /* terminfo */
1226 * "break" goes here, but can't be reliably intercepted with termcap
1228 {"&4", "reset"}, /* terminfo --- actually `restart' */
1230 * "system" and "user" --- no termcaps
1232 {"kE", "clearline"}, /* terminfo */
1233 {"kA", "insertline"}, /* terminfo */
1234 {"kL", "deleteline"}, /* terminfo */
1235 {"kI", "insertchar"}, /* terminfo */
1236 {"kD", "deletechar"}, /* terminfo */
1237 {"kB", "backtab"}, /* terminfo */
1239 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1241 {"@8", "kp-enter"}, /* terminfo */
1243 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1244 * "kp-multiply", "kp-add", "kp-separator",
1245 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1246 * --- no termcaps for any of these.
1248 {"K4", "kp-1"}, /* terminfo */
1250 * "kp-2" --- no termcap
1252 {"K5", "kp-3"}, /* terminfo */
1254 * "kp-4" --- no termcap
1256 {"K2", "kp-5"}, /* terminfo */
1258 * "kp-6" --- no termcap
1260 {"K1", "kp-7"}, /* terminfo */
1262 * "kp-8" --- no termcap
1264 {"K3", "kp-9"}, /* terminfo */
1266 * "kp-equal" --- no termcap
1278 {"&0", "S-cancel"}, /*shifted cancel key*/
1279 {"&9", "S-begin"}, /*shifted begin key*/
1280 {"*0", "S-find"}, /*shifted find key*/
1281 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1282 {"*4", "S-delete"}, /*shifted delete-character key*/
1283 {"*7", "S-end"}, /*shifted end key*/
1284 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1285 {"#1", "S-help"}, /*shifted help key*/
1286 {"#2", "S-home"}, /*shifted home key*/
1287 {"#3", "S-insert"}, /*shifted insert-character key*/
1288 {"#4", "S-left"}, /*shifted left-arrow key*/
1289 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1290 {"%c", "S-next"}, /*shifted next key*/
1291 {"%e", "S-prior"}, /*shifted previous key*/
1292 {"%f", "S-print"}, /*shifted print key*/
1293 {"%g", "S-redo"}, /*shifted redo key*/
1294 {"%i", "S-right"}, /*shifted right-arrow key*/
1295 {"!3", "S-undo"} /*shifted undo key*/
1299 static char **term_get_fkeys_address
;
1300 static KBOARD
*term_get_fkeys_kboard
;
1301 static Lisp_Object
term_get_fkeys_1 (void);
1303 /* Find the escape codes sent by the function keys for Vinput_decode_map.
1304 This function scans the termcap function key sequence entries, and
1305 adds entries to Vinput_decode_map for each function key it finds. */
1308 term_get_fkeys (char **address
, KBOARD
*kboard
)
1310 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1311 errors during the call. The only errors should be from Fdefine_key
1312 when given a key sequence containing an invalid prefix key. If the
1313 termcap defines function keys which use a prefix that is already bound
1314 to a command by the default bindings, we should silently ignore that
1315 function key specification, rather than giving the user an error and
1316 refusing to run at all on such a terminal. */
1318 term_get_fkeys_address
= address
;
1319 term_get_fkeys_kboard
= kboard
;
1320 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1324 term_get_fkeys_1 (void)
1328 char **address
= term_get_fkeys_address
;
1329 KBOARD
*kboard
= term_get_fkeys_kboard
;
1331 /* This can happen if CANNOT_DUMP or with strange options. */
1332 if (!KEYMAPP (KVAR (kboard
, Vinput_decode_map
)))
1333 kset_input_decode_map (kboard
, Fmake_sparse_keymap (Qnil
));
1335 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1337 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1339 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (sequence
),
1340 Fmake_vector (make_number (1),
1341 intern (keys
[i
].name
)));
1344 /* The uses of the "k0" capability are inconsistent; sometimes it
1345 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1346 We will attempt to politely accommodate both systems by testing for
1347 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1350 const char *k_semi
= tgetstr ("k;", address
);
1351 const char *k0
= tgetstr ("k0", address
);
1352 const char *k0_name
= "f10";
1357 /* Define f0 first, so that f10 takes precedence in case the
1358 key sequences happens to be the same. */
1359 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (k0
),
1360 Fmake_vector (make_number (1), intern ("f0")));
1361 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (k_semi
),
1362 Fmake_vector (make_number (1), intern ("f10")));
1365 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (k0
),
1366 Fmake_vector (make_number (1), intern (k0_name
)));
1369 /* Set up cookies for numbered function keys above f10. */
1371 char fcap
[3], fkey
[4];
1373 fcap
[0] = 'F'; fcap
[2] = '\0';
1374 for (i
= 11; i
< 64; i
++)
1377 fcap
[1] = '1' + i
- 11;
1379 fcap
[1] = 'A' + i
- 20;
1381 fcap
[1] = 'a' + i
- 46;
1384 char *sequence
= tgetstr (fcap
, address
);
1387 sprintf (fkey
, "f%d", i
);
1388 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (sequence
),
1389 Fmake_vector (make_number (1),
1397 * Various mappings to try and get a better fit.
1400 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1401 if (!tgetstr (cap1, address)) \
1403 char *sequence = tgetstr (cap2, address); \
1405 Fdefine_key (KVAR (kboard, Vinput_decode_map), build_string (sequence), \
1406 Fmake_vector (make_number (1), \
1410 /* if there's no key_next keycap, map key_npage to `next' keysym */
1411 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1412 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1413 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1414 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1415 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1416 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1417 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1419 /* IBM has their own non-standard dialect of terminfo.
1420 If the standard name isn't found, try the IBM name. */
1421 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1422 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1423 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1424 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1425 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1426 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1427 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1428 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1429 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1430 #undef CONDITIONAL_REASSIGN
1435 #endif /* not DOS_NT */
1438 /***********************************************************************
1439 Character Display Information
1440 ***********************************************************************/
1441 static void append_glyph (struct it
*);
1442 static void append_composite_glyph (struct it
*);
1443 static void produce_composite_glyph (struct it
*);
1444 static void append_glyphless_glyph (struct it
*, int, const char *);
1445 static void produce_glyphless_glyph (struct it
*, int, Lisp_Object
);
1447 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1448 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1449 the character for which to produce glyphs; IT->face_id contains the
1450 character's face. Padding glyphs are appended if IT->c has a
1451 IT->pixel_width > 1. */
1454 append_glyph (struct it
*it
)
1456 struct glyph
*glyph
, *end
;
1459 eassert (it
->glyph_row
);
1460 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1461 + it
->glyph_row
->used
[it
->area
]);
1462 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1464 /* If the glyph row is reversed, we need to prepend the glyph rather
1466 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1469 int move_by
= it
->pixel_width
;
1471 /* Make room for the new glyphs. */
1472 if (move_by
> end
- glyph
) /* don't overstep end of this area */
1473 move_by
= end
- glyph
;
1474 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1476 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1477 end
= glyph
+ move_by
;
1480 /* BIDI Note: we put the glyphs of a "multi-pixel" character left to
1481 right, even in the REVERSED_P case, since (a) all of its u.ch are
1482 identical, and (b) the PADDING_P flag needs to be set for the
1483 leftmost one, because we write to the terminal left-to-right. */
1485 i
< it
->pixel_width
&& glyph
< end
;
1488 glyph
->type
= CHAR_GLYPH
;
1489 glyph
->pixel_width
= 1;
1490 glyph
->u
.ch
= it
->char_to_display
;
1491 glyph
->face_id
= it
->face_id
;
1492 glyph
->padding_p
= i
> 0;
1493 glyph
->charpos
= CHARPOS (it
->position
);
1494 glyph
->object
= it
->object
;
1497 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1498 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1500 glyph
->bidi_type
= it
->bidi_it
.type
;
1504 glyph
->resolved_level
= 0;
1505 glyph
->bidi_type
= UNKNOWN_BT
;
1508 ++it
->glyph_row
->used
[it
->area
];
1513 /* For external use. */
1515 tty_append_glyph (struct it
*it
)
1521 /* Produce glyphs for the display element described by IT. *IT
1522 specifies what we want to produce a glyph for (character, image, ...),
1523 and where in the glyph matrix we currently are (glyph row and hpos).
1524 produce_glyphs fills in output fields of *IT with information such as the
1525 pixel width and height of a character, and maybe output actual glyphs at
1526 the same time if IT->glyph_row is non-null. For an overview, see
1527 the explanation in dispextern.h, before the definition of the
1528 display_element_type enumeration.
1530 produce_glyphs also stores the result of glyph width, ascent
1531 etc. computations in *IT.
1533 IT->glyph_row may be null, in which case produce_glyphs does not
1534 actually fill in the glyphs. This is used in the move_* functions
1535 in xdisp.c for text width and height computations.
1537 Callers usually don't call produce_glyphs directly;
1538 instead they use the macro PRODUCE_GLYPHS. */
1541 produce_glyphs (struct it
*it
)
1543 /* If a hook is installed, let it do the work. */
1545 /* Nothing but characters are supported on terminal frames. */
1546 eassert (it
->what
== IT_CHARACTER
1547 || it
->what
== IT_COMPOSITION
1548 || it
->what
== IT_STRETCH
1549 || it
->what
== IT_GLYPHLESS
);
1551 if (it
->what
== IT_STRETCH
)
1553 produce_stretch_glyph (it
);
1557 if (it
->what
== IT_COMPOSITION
)
1559 produce_composite_glyph (it
);
1563 if (it
->what
== IT_GLYPHLESS
)
1565 produce_glyphless_glyph (it
, 0, Qnil
);
1569 if (it
->char_to_display
>= 040 && it
->char_to_display
< 0177)
1571 it
->pixel_width
= it
->nglyphs
= 1;
1575 else if (it
->char_to_display
== '\n')
1576 it
->pixel_width
= it
->nglyphs
= 0;
1577 else if (it
->char_to_display
== '\t')
1579 int absolute_x
= (it
->current_x
1580 + it
->continuation_lines_width
);
1582 = (((1 + absolute_x
+ it
->tab_width
- 1)
1587 /* If part of the TAB has been displayed on the previous line
1588 which is continued now, continuation_lines_width will have
1589 been incremented already by the part that fitted on the
1590 continued line. So, we will get the right number of spaces
1592 nspaces
= next_tab_x
- absolute_x
;
1598 it
->char_to_display
= ' ';
1599 it
->pixel_width
= it
->len
= 1;
1605 it
->pixel_width
= nspaces
;
1606 it
->nglyphs
= nspaces
;
1608 else if (CHAR_BYTE8_P (it
->char_to_display
))
1610 /* Coming here means that we must send the raw 8-bit byte as is
1611 to the terminal. Although there's no way to know how many
1612 columns it occupies on a screen, it is a good assumption that
1613 a single byte code has 1-column width. */
1614 it
->pixel_width
= it
->nglyphs
= 1;
1620 Lisp_Object charset_list
= FRAME_TERMINAL (it
->f
)->charset_list
;
1622 if (char_charset (it
->char_to_display
, charset_list
, NULL
))
1624 it
->pixel_width
= CHAR_WIDTH (it
->char_to_display
);
1625 it
->nglyphs
= it
->pixel_width
;
1631 Lisp_Object acronym
= lookup_glyphless_char_display (-1, it
);
1633 eassert (it
->what
== IT_GLYPHLESS
);
1634 produce_glyphless_glyph (it
, 1, acronym
);
1639 /* Advance current_x by the pixel width as a convenience for
1641 if (it
->area
== TEXT_AREA
)
1642 it
->current_x
+= it
->pixel_width
;
1643 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1644 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1647 /* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
1648 Called from produce_composite_glyph for terminal frames if
1649 IT->glyph_row != NULL. IT->face_id contains the character's
1653 append_composite_glyph (struct it
*it
)
1655 struct glyph
*glyph
;
1657 eassert (it
->glyph_row
);
1658 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1659 if (glyph
< it
->glyph_row
->glyphs
[1 + it
->area
])
1661 /* If the glyph row is reversed, we need to prepend the glyph
1662 rather than append it. */
1663 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1667 /* Make room for the new glyph. */
1668 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1670 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1672 glyph
->type
= COMPOSITE_GLYPH
;
1673 glyph
->pixel_width
= it
->pixel_width
;
1674 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1675 if (it
->cmp_it
.ch
< 0)
1677 glyph
->u
.cmp
.automatic
= 0;
1678 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1682 glyph
->u
.cmp
.automatic
= 1;
1683 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1684 glyph
->slice
.cmp
.from
= it
->cmp_it
.from
;
1685 glyph
->slice
.cmp
.to
= it
->cmp_it
.to
- 1;
1688 glyph
->face_id
= it
->face_id
;
1689 glyph
->padding_p
= 0;
1690 glyph
->charpos
= CHARPOS (it
->position
);
1691 glyph
->object
= it
->object
;
1694 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1695 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1697 glyph
->bidi_type
= it
->bidi_it
.type
;
1701 glyph
->resolved_level
= 0;
1702 glyph
->bidi_type
= UNKNOWN_BT
;
1705 ++it
->glyph_row
->used
[it
->area
];
1711 /* Produce a composite glyph for iterator IT. IT->cmp_id is the ID of
1712 the composition. We simply produces components of the composition
1713 assuming that the terminal has a capability to layout/render it
1717 produce_composite_glyph (struct it
*it
)
1719 if (it
->cmp_it
.ch
< 0)
1721 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
1723 it
->pixel_width
= cmp
->width
;
1727 Lisp_Object gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
1729 it
->pixel_width
= composition_gstring_width (gstring
, it
->cmp_it
.from
,
1730 it
->cmp_it
.to
, NULL
);
1734 append_composite_glyph (it
);
1738 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
1739 is a face ID to be used for the glyph. What is actually appended
1740 are glyphs of type CHAR_GLYPH whose characters are in STR (which
1741 comes from it->nglyphs bytes). */
1744 append_glyphless_glyph (struct it
*it
, int face_id
, const char *str
)
1746 struct glyph
*glyph
, *end
;
1749 eassert (it
->glyph_row
);
1750 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1751 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1753 /* If the glyph row is reversed, we need to prepend the glyph rather
1755 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1758 int move_by
= it
->pixel_width
;
1760 /* Make room for the new glyphs. */
1761 if (move_by
> end
- glyph
) /* don't overstep end of this area */
1762 move_by
= end
- glyph
;
1763 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1765 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1766 end
= glyph
+ move_by
;
1771 glyph
->type
= CHAR_GLYPH
;
1772 glyph
->pixel_width
= 1;
1773 glyph
->face_id
= face_id
;
1774 glyph
->padding_p
= 0;
1775 glyph
->charpos
= CHARPOS (it
->position
);
1776 glyph
->object
= it
->object
;
1779 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1780 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1782 glyph
->bidi_type
= it
->bidi_it
.type
;
1786 glyph
->resolved_level
= 0;
1787 glyph
->bidi_type
= UNKNOWN_BT
;
1790 /* BIDI Note: we put the glyphs of characters left to right, even in
1791 the REVERSED_P case because we write to the terminal
1793 for (i
= 0; i
< it
->nglyphs
&& glyph
< end
; ++i
)
1796 glyph
[0] = glyph
[-1];
1797 glyph
->u
.ch
= str
[i
];
1798 ++it
->glyph_row
->used
[it
->area
];
1803 /* Produce glyphs for a glyphless character for iterator IT.
1804 IT->glyphless_method specifies which method to use for displaying
1805 the character. See the description of enum
1806 glyphless_display_method in dispextern.h for the details.
1808 FOR_NO_FONT is nonzero if and only if this is for a character that
1809 is not supported by the coding system of the terminal. ACRONYM, if
1810 non-nil, is an acronym string for the character.
1812 The glyphs actually produced are of type CHAR_GLYPH. */
1815 produce_glyphless_glyph (struct it
*it
, int for_no_font
, Lisp_Object acronym
)
1819 char buf
[sizeof "\\x" + max (6, (sizeof it
->c
* CHAR_BIT
+ 3) / 4)];
1820 char const *str
= " ";
1822 /* Get a face ID for the glyph by utilizing a cache (the same way as
1823 done for `escape-glyph' in get_next_display_element). */
1824 if (it
->f
== last_glyphless_glyph_frame
1825 && it
->face_id
== last_glyphless_glyph_face_id
)
1827 face_id
= last_glyphless_glyph_merged_face_id
;
1831 /* Merge the `glyphless-char' face into the current face. */
1832 face_id
= merge_faces (it
->f
, Qglyphless_char
, 0, it
->face_id
);
1833 last_glyphless_glyph_frame
= it
->f
;
1834 last_glyphless_glyph_face_id
= it
->face_id
;
1835 last_glyphless_glyph_merged_face_id
= face_id
;
1838 if (it
->glyphless_method
== GLYPHLESS_DISPLAY_THIN_SPACE
)
1840 /* As there's no way to produce a thin space, we produce a space
1841 of canonical width. */
1844 else if (it
->glyphless_method
== GLYPHLESS_DISPLAY_EMPTY_BOX
)
1846 len
= CHAR_WIDTH (it
->c
);
1851 len
= sprintf (buf
, "[%.*s]", len
, str
);
1856 if (it
->glyphless_method
== GLYPHLESS_DISPLAY_ACRONYM
)
1858 if (! STRINGP (acronym
) && CHAR_TABLE_P (Vglyphless_char_display
))
1859 acronym
= CHAR_TABLE_REF (Vglyphless_char_display
, it
->c
);
1860 if (CONSP (acronym
))
1861 acronym
= XCDR (acronym
);
1863 str
= STRINGP (acronym
) ? SSDATA (acronym
) : "";
1864 for (len
= 0; len
< 6 && str
[len
] && ASCII_BYTE_P (str
[len
]); len
++)
1865 buf
[1 + len
] = str
[len
];
1871 eassert (it
->glyphless_method
== GLYPHLESS_DISPLAY_HEX_CODE
);
1872 len
= (it
->c
< 0x10000 ? sprintf (buf
, "\\u%04X", it
->c
)
1873 : it
->c
<= MAX_UNICODE_CHAR
? sprintf (buf
, "\\U%06X", it
->c
)
1874 : sprintf (buf
, "\\x%06X", it
->c
));
1879 it
->pixel_width
= len
;
1882 append_glyphless_glyph (it
, face_id
, str
);
1886 /***********************************************************************
1888 ***********************************************************************/
1890 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1891 one of the enumerators from enum no_color_bit, or a bit set built
1892 from them. Some display attributes may not be used together with
1893 color; the termcap capability `NC' specifies which ones. */
1895 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1896 (tty->TN_max_colors > 0 \
1897 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1900 /* Turn appearances of face FACE_ID on tty frame F on.
1901 FACE_ID is a realized face ID number, in the face cache. */
1904 turn_on_face (struct frame
*f
, int face_id
)
1906 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1907 long fg
= face
->foreground
;
1908 long bg
= face
->background
;
1909 struct tty_display_info
*tty
= FRAME_TTY (f
);
1911 /* Do this first because TS_end_standout_mode may be the same
1912 as TS_exit_attribute_mode, which turns all appearances off. */
1913 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1915 if (tty
->TN_max_colors
> 0)
1917 if (fg
>= 0 && bg
>= 0)
1919 /* If the terminal supports colors, we can set them
1920 below without using reverse video. The face's fg
1921 and bg colors are set as they should appear on
1922 the screen, i.e. they take the inverse-video'ness
1923 of the face already into account. */
1925 else if (inverse_video
)
1927 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1928 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1929 tty_toggle_highlight (tty
);
1933 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1934 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1935 tty_toggle_highlight (tty
);
1940 /* If we can't display colors, use reverse video
1941 if the face specifies that. */
1944 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1945 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1946 tty_toggle_highlight (tty
);
1950 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1951 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1952 tty_toggle_highlight (tty
);
1957 if (face
->tty_bold_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1958 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1960 if (face
->tty_italic_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_ITALIC
))
1962 if (tty
->TS_enter_italic_mode
)
1963 OUTPUT1 (tty
, tty
->TS_enter_italic_mode
);
1965 /* Italics mode is unavailable on many terminals. In that
1966 case, map slant to dimmed text; we want italic text to
1967 appear different and dimming is not otherwise used. */
1968 OUTPUT1 (tty
, tty
->TS_enter_dim_mode
);
1971 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1972 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1974 if (tty
->TN_max_colors
> 0)
1979 ts
= tty
->standout_mode
? tty
->TS_set_background
: tty
->TS_set_foreground
;
1982 p
= tparam (ts
, NULL
, 0, (int) fg
, 0, 0, 0);
1987 ts
= tty
->standout_mode
? tty
->TS_set_foreground
: tty
->TS_set_background
;
1990 p
= tparam (ts
, NULL
, 0, (int) bg
, 0, 0, 0);
1998 /* Turn off appearances of face FACE_ID on tty frame F. */
2001 turn_off_face (struct frame
*f
, int face_id
)
2003 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2004 struct tty_display_info
*tty
= FRAME_TTY (f
);
2006 eassert (face
!= NULL
);
2008 if (tty
->TS_exit_attribute_mode
)
2010 /* Capability "me" will turn off appearance modes double-bright,
2011 half-bright, reverse-video, standout, underline. It may or
2012 may not turn off alt-char-mode. */
2013 if (face
->tty_bold_p
2014 || face
->tty_italic_p
2015 || face
->tty_reverse_p
2016 || face
->tty_underline_p
)
2018 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
2019 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
2020 tty
->standout_mode
= 0;
2025 /* If we don't have "me" we can only have those appearances
2026 that have exit sequences defined. */
2027 if (face
->tty_underline_p
)
2028 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
2031 /* Switch back to default colors. */
2032 if (tty
->TN_max_colors
> 0
2033 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2034 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2035 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2036 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2037 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
2041 /* Return non-zero if the terminal on frame F supports all of the
2042 capabilities in CAPS simultaneously, with foreground and background
2043 colors FG and BG. */
2046 tty_capable_p (struct tty_display_info
*tty
, unsigned int caps
,
2047 unsigned long fg
, unsigned long bg
)
2049 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
2050 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
2053 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
2054 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
2055 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
2056 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
2057 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ITALIC
, tty
->TS_enter_italic_mode
, NC_ITALIC
);
2063 /* Return non-zero if the terminal is capable to display colors. */
2065 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2067 doc
: /* Return non-nil if the tty device TERMINAL can display colors.
2069 TERMINAL can be a terminal object, a frame, or nil (meaning the
2070 selected frame's terminal). This function always returns nil if
2071 TERMINAL does not refer to a text terminal. */)
2072 (Lisp_Object terminal
)
2074 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2078 return t
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
2081 /* Return the number of supported colors. */
2082 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2083 Stty_display_color_cells
, 0, 1, 0,
2084 doc
: /* Return the number of colors supported by the tty device TERMINAL.
2086 TERMINAL can be a terminal object, a frame, or nil (meaning the
2087 selected frame's terminal). This function always returns 0 if
2088 TERMINAL does not refer to a text terminal. */)
2089 (Lisp_Object terminal
)
2091 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2093 return make_number (0);
2095 return make_number (t
->display_info
.tty
->TN_max_colors
);
2100 /* Declare here rather than in the function, as in the rest of Emacs,
2101 to work around an HPUX compiler bug (?). See
2102 http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00410.html */
2103 static int default_max_colors
;
2104 static int default_max_pairs
;
2105 static int default_no_color_video
;
2106 static char *default_orig_pair
;
2107 static char *default_set_foreground
;
2108 static char *default_set_background
;
2110 /* Save or restore the default color-related capabilities of this
2113 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
2118 xfree (default_orig_pair
);
2119 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
2121 xfree (default_set_foreground
);
2122 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
2125 xfree (default_set_background
);
2126 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
2129 default_max_colors
= tty
->TN_max_colors
;
2130 default_max_pairs
= tty
->TN_max_pairs
;
2131 default_no_color_video
= tty
->TN_no_color_video
;
2135 tty
->TS_orig_pair
= default_orig_pair
;
2136 tty
->TS_set_foreground
= default_set_foreground
;
2137 tty
->TS_set_background
= default_set_background
;
2138 tty
->TN_max_colors
= default_max_colors
;
2139 tty
->TN_max_pairs
= default_max_pairs
;
2140 tty
->TN_no_color_video
= default_no_color_video
;
2144 /* Setup one of the standard tty color schemes according to MODE.
2145 MODE's value is generally the number of colors which we want to
2146 support; zero means set up for the default capabilities, the ones
2147 we saw at init_tty time; -1 means turn off color support. */
2149 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2151 /* Canonicalize all negative values of MODE. */
2157 case -1: /* no colors at all */
2158 tty
->TN_max_colors
= 0;
2159 tty
->TN_max_pairs
= 0;
2160 tty
->TN_no_color_video
= 0;
2161 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2163 case 0: /* default colors, if any */
2165 tty_default_color_capabilities (tty
, 0);
2167 case 8: /* 8 standard ANSI colors */
2168 tty
->TS_orig_pair
= "\033[0m";
2170 tty
->TS_set_foreground
= "\033[3%p1%dm";
2171 tty
->TS_set_background
= "\033[4%p1%dm";
2173 tty
->TS_set_foreground
= "\033[3%dm";
2174 tty
->TS_set_background
= "\033[4%dm";
2176 tty
->TN_max_colors
= 8;
2177 tty
->TN_max_pairs
= 64;
2178 tty
->TN_no_color_video
= 0;
2184 set_tty_color_mode (struct tty_display_info
*tty
, struct frame
*f
)
2186 Lisp_Object tem
, val
;
2187 Lisp_Object color_mode
;
2189 Lisp_Object tty_color_mode_alist
2190 = Fintern_soft (build_string ("tty-color-mode-alist"), Qnil
);
2192 tem
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2193 val
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2197 else if (SYMBOLP (tty_color_mode_alist
))
2199 tem
= Fassq (val
, Fsymbol_value (tty_color_mode_alist
));
2200 color_mode
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2205 mode
= TYPE_RANGED_INTEGERP (int, color_mode
) ? XINT (color_mode
) : 0;
2207 if (mode
!= tty
->previous_color_mode
)
2209 tty
->previous_color_mode
= mode
;
2210 tty_setup_colors (tty
, mode
);
2211 /* This recomputes all the faces given the new color definitions. */
2212 safe_call (1, intern ("tty-set-up-initial-frame-faces"));
2216 #endif /* !DOS_NT */
2220 /* Return the tty display object specified by TERMINAL. */
2222 static struct terminal
*
2223 get_tty_terminal (Lisp_Object terminal
, int throw)
2225 struct terminal
*t
= get_terminal (terminal
, throw);
2227 if (t
&& t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2230 error ("Device %d is not a termcap terminal device", t
->id
);
2238 /* Return an active termcap device that uses the tty device with the
2241 This function ignores suspended devices.
2243 Returns NULL if the named terminal device is not opened. */
2246 get_named_tty (const char *name
)
2253 for (t
= terminal_list
; t
; t
= t
->next_terminal
)
2255 if ((t
->type
== output_termcap
|| t
->type
== output_msdos_raw
)
2256 && !strcmp (t
->display_info
.tty
->name
, name
)
2257 && TERMINAL_ACTIVE_P (t
))
2265 DEFUN ("tty-type", Ftty_type
, Stty_type
, 0, 1, 0,
2266 doc
: /* Return the type of the tty device that TERMINAL uses.
2267 Returns nil if TERMINAL is not on a tty device.
2269 TERMINAL can be a terminal object, a frame, or nil (meaning the
2270 selected frame's terminal). */)
2271 (Lisp_Object terminal
)
2273 struct terminal
*t
= get_terminal (terminal
, 1);
2275 if (t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2278 if (t
->display_info
.tty
->type
)
2279 return build_string (t
->display_info
.tty
->type
);
2284 DEFUN ("controlling-tty-p", Fcontrolling_tty_p
, Scontrolling_tty_p
, 0, 1, 0,
2285 doc
: /* Return non-nil if TERMINAL is the controlling tty of the Emacs process.
2287 TERMINAL can be a terminal object, a frame, or nil (meaning the
2288 selected frame's terminal). This function always returns nil if
2289 TERMINAL is not on a tty device. */)
2290 (Lisp_Object terminal
)
2292 struct terminal
*t
= get_terminal (terminal
, 1);
2294 if ((t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2295 || strcmp (t
->display_info
.tty
->name
, DEV_TTY
) != 0)
2301 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 1, 0,
2302 doc
: /* Declare that the tty used by TERMINAL does not handle underlining.
2303 This is used to override the terminfo data, for certain terminals that
2304 do not really do underlining, but say that they do. This function has
2305 no effect if used on a non-tty terminal.
2307 TERMINAL can be a terminal object, a frame or nil (meaning the
2308 selected frame's terminal). This function always returns nil if
2309 TERMINAL does not refer to a text terminal. */)
2310 (Lisp_Object terminal
)
2312 struct terminal
*t
= get_terminal (terminal
, 1);
2314 if (t
->type
== output_termcap
)
2315 t
->display_info
.tty
->TS_enter_underline_mode
= 0;
2319 DEFUN ("tty-top-frame", Ftty_top_frame
, Stty_top_frame
, 0, 1, 0,
2320 doc
: /* Return the topmost terminal frame on TERMINAL.
2321 TERMINAL can be a terminal object, a frame or nil (meaning the
2322 selected frame's terminal). This function returns nil if TERMINAL
2323 does not refer to a text terminal. Otherwise, it returns the
2324 top-most frame on the text terminal. */)
2325 (Lisp_Object terminal
)
2327 struct terminal
*t
= get_terminal (terminal
, 1);
2329 if (t
->type
== output_termcap
)
2330 return t
->display_info
.tty
->top_frame
;
2336 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
2337 doc
: /* Suspend the terminal device TTY.
2339 The device is restored to its default state, and Emacs ceases all
2340 access to the tty device. Frames that use the device are not deleted,
2341 but input is not read from them and if they change, their display is
2344 TTY may be a terminal object, a frame, or nil for the terminal device
2345 of the currently selected frame.
2347 This function runs `suspend-tty-functions' after suspending the
2348 device. The functions are run with one arg, the id of the suspended
2351 `suspend-tty' does nothing if it is called on a device that is already
2354 A suspended tty may be resumed by calling `resume-tty' on it. */)
2357 struct terminal
*t
= get_tty_terminal (tty
, 1);
2361 error ("Unknown tty device");
2363 f
= t
->display_info
.tty
->input
;
2367 /* First run `suspend-tty-functions' and then clean up the tty
2368 state because `suspend-tty-functions' might need to change
2370 Lisp_Object args
[2];
2371 args
[0] = intern ("suspend-tty-functions");
2372 XSETTERMINAL (args
[1], t
);
2373 Frun_hook_with_args (2, args
);
2375 reset_sys_modes (t
->display_info
.tty
);
2376 delete_keyboard_wait_descriptor (fileno (f
));
2380 if (f
!= t
->display_info
.tty
->output
)
2381 fclose (t
->display_info
.tty
->output
);
2384 t
->display_info
.tty
->input
= 0;
2385 t
->display_info
.tty
->output
= 0;
2387 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2388 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 0);
2392 /* Clear display hooks to prevent further output. */
2393 clear_tty_hooks (t
);
2398 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
2399 doc
: /* Resume the previously suspended terminal device TTY.
2400 The terminal is opened and reinitialized. Frames that are on the
2401 suspended terminal are revived.
2403 It is an error to resume a terminal while another terminal is active
2406 This function runs `resume-tty-functions' after resuming the terminal.
2407 The functions are run with one arg, the id of the resumed terminal
2410 `resume-tty' does nothing if it is called on a device that is not
2413 TTY may be a terminal object, a frame, or nil (meaning the selected
2414 frame's terminal). */)
2417 struct terminal
*t
= get_tty_terminal (tty
, 1);
2421 error ("Unknown tty device");
2423 if (!t
->display_info
.tty
->input
)
2425 if (get_named_tty (t
->display_info
.tty
->name
))
2426 error ("Cannot resume display while another display is active on the same device");
2429 t
->display_info
.tty
->output
= stdout
;
2430 t
->display_info
.tty
->input
= stdin
;
2432 fd
= emacs_open (t
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
2435 error ("Can not reopen tty device %s: %s", t
->display_info
.tty
->name
, strerror (errno
));
2437 if (strcmp (t
->display_info
.tty
->name
, DEV_TTY
))
2438 dissociate_if_controlling_tty (fd
);
2440 t
->display_info
.tty
->output
= fdopen (fd
, "w+");
2441 t
->display_info
.tty
->input
= t
->display_info
.tty
->output
;
2444 add_keyboard_wait_descriptor (fd
);
2446 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2448 struct frame
*f
= XFRAME (t
->display_info
.tty
->top_frame
);
2450 int old_height
= FRAME_COLS (f
);
2451 int old_width
= FRAME_LINES (f
);
2453 /* Check if terminal/window size has changed while the frame
2455 get_tty_size (fileno (t
->display_info
.tty
->input
), &width
, &height
);
2456 if (width
!= old_width
|| height
!= old_height
)
2457 change_frame_size (f
, height
, width
, 0, 0, 0);
2458 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 1);
2462 init_sys_modes (t
->display_info
.tty
);
2465 /* Run `resume-tty-functions'. */
2466 Lisp_Object args
[2];
2467 args
[0] = intern ("resume-tty-functions");
2468 XSETTERMINAL (args
[1], t
);
2469 Frun_hook_with_args (2, args
);
2479 /***********************************************************************
2481 ***********************************************************************/
2485 #ifndef HAVE_WINDOW_SYSTEM
2487 term_mouse_moveto (int x
, int y
)
2489 /* TODO: how to set mouse position?
2492 name = (const char *) ttyname (0);
2493 fd = open (name, O_WRONLY);
2494 SOME_FUNCTION (x, y, fd);
2497 last_mouse_y = y; */
2499 #endif /* HAVE_WINDOW_SYSTEM */
2501 /* Implementation of draw_row_with_mouse_face for TTY/GPM. */
2503 tty_draw_row_with_mouse_face (struct window
*w
, struct glyph_row
*row
,
2504 int start_hpos
, int end_hpos
,
2505 enum draw_glyphs_face draw
)
2507 int nglyphs
= end_hpos
- start_hpos
;
2508 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
2509 struct tty_display_info
*tty
= FRAME_TTY (f
);
2510 int face_id
= tty
->mouse_highlight
.mouse_face_face_id
;
2511 int save_x
, save_y
, pos_x
, pos_y
;
2513 if (end_hpos
>= row
->used
[TEXT_AREA
])
2514 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2516 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2517 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
+ WINDOW_LEFT_EDGE_X (w
);
2519 /* Save current cursor co-ordinates. */
2520 save_y
= curY (tty
);
2521 save_x
= curX (tty
);
2522 cursor_to (f
, pos_y
, pos_x
);
2524 if (draw
== DRAW_MOUSE_FACE
)
2525 tty_write_glyphs_with_face (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
,
2527 else if (draw
== DRAW_NORMAL_TEXT
)
2528 write_glyphs (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2530 cursor_to (f
, save_y
, save_x
);
2534 term_mouse_movement (FRAME_PTR frame
, Gpm_Event
*event
)
2536 /* Has the mouse moved off the glyph it was on at the last sighting? */
2537 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2539 frame
->mouse_moved
= 1;
2540 note_mouse_highlight (frame
, event
->x
, event
->y
);
2541 /* Remember which glyph we're now on. */
2542 last_mouse_x
= event
->x
;
2543 last_mouse_y
= event
->y
;
2549 /* Return the Time that corresponds to T. Wrap around on overflow. */
2551 timeval_to_Time (struct timeval
const *t
)
2557 ms
= t
->tv_usec
/ 1000;
2561 /* Return the current position of the mouse.
2563 Set *f to the frame the mouse is in, or zero if the mouse is in no
2564 Emacs frame. If it is set to zero, all the other arguments are
2567 Set *bar_window to Qnil, and *x and *y to the column and
2568 row of the character cell the mouse is over.
2570 Set *timeptr to the time the mouse was at the returned position.
2572 This clears mouse_moved until the next motion
2575 term_mouse_position (FRAME_PTR
*fp
, int insist
, Lisp_Object
*bar_window
,
2576 enum scroll_bar_part
*part
, Lisp_Object
*x
,
2577 Lisp_Object
*y
, Time
*timeptr
)
2581 *fp
= SELECTED_FRAME ();
2582 (*fp
)->mouse_moved
= 0;
2587 XSETINT (*x
, last_mouse_x
);
2588 XSETINT (*y
, last_mouse_y
);
2589 gettimeofday(&now
, 0);
2590 *timeptr
= timeval_to_Time (&now
);
2593 /* Prepare a mouse-event in *RESULT for placement in the input queue.
2595 If the event is a button press, then note that we have grabbed
2599 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
2605 result
->kind
= GPM_CLICK_EVENT
;
2606 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
2608 if (event
->buttons
& j
) {
2609 result
->code
= i
; /* button number */
2613 gettimeofday(&now
, 0);
2614 result
->timestamp
= timeval_to_Time (&now
);
2616 if (event
->type
& GPM_UP
)
2617 result
->modifiers
= up_modifier
;
2618 else if (event
->type
& GPM_DOWN
)
2619 result
->modifiers
= down_modifier
;
2621 result
->modifiers
= 0;
2623 if (event
->type
& GPM_SINGLE
)
2624 result
->modifiers
|= click_modifier
;
2626 if (event
->type
& GPM_DOUBLE
)
2627 result
->modifiers
|= double_modifier
;
2629 if (event
->type
& GPM_TRIPLE
)
2630 result
->modifiers
|= triple_modifier
;
2632 if (event
->type
& GPM_DRAG
)
2633 result
->modifiers
|= drag_modifier
;
2635 if (!(event
->type
& (GPM_MOVE
| GPM_DRAG
))) {
2638 if (event
->modifiers
& (1 << 0))
2639 result
->modifiers
|= shift_modifier
;
2642 if (event
->modifiers
& (1 << 2))
2643 result
->modifiers
|= ctrl_modifier
;
2645 /* 1 << KG_ALT || KG_ALTGR */
2646 if (event
->modifiers
& (1 << 3)
2647 || event
->modifiers
& (1 << 1))
2648 result
->modifiers
|= meta_modifier
;
2651 XSETINT (result
->x
, event
->x
);
2652 XSETINT (result
->y
, event
->y
);
2653 XSETFRAME (result
->frame_or_window
, f
);
2659 handle_one_term_event (struct tty_display_info
*tty
, Gpm_Event
*event
, struct input_event
* hold_quit
)
2661 struct frame
*f
= XFRAME (tty
->top_frame
);
2662 struct input_event ie
;
2670 if (event
->type
& (GPM_MOVE
| GPM_DRAG
)) {
2671 previous_help_echo_string
= help_echo_string
;
2672 help_echo_string
= Qnil
;
2674 Gpm_DrawPointer (event
->x
, event
->y
, fileno (tty
->output
));
2676 if (!term_mouse_movement (f
, event
))
2677 help_echo_string
= previous_help_echo_string
;
2679 /* If the contents of the global variable help_echo_string
2680 has changed, generate a HELP_EVENT. */
2681 if (!NILP (help_echo_string
)
2682 || !NILP (previous_help_echo_string
))
2689 term_mouse_click (&ie
, event
, f
);
2693 if (ie
.kind
!= NO_EVENT
)
2695 kbd_buffer_store_event_hold (&ie
, hold_quit
);
2700 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
2705 XSETFRAME (frame
, f
);
2709 gen_help_event (help_echo_string
, frame
, help_echo_window
,
2710 help_echo_object
, help_echo_pos
);
2717 DEFUN ("gpm-mouse-start", Fgpm_mouse_start
, Sgpm_mouse_start
,
2719 doc
: /* Open a connection to Gpm.
2720 Gpm-mouse can only be activated for one tty at a time. */)
2723 struct frame
*f
= SELECTED_FRAME ();
2724 struct tty_display_info
*tty
2725 = ((f
)->output_method
== output_termcap
2726 ? (f
)->terminal
->display_info
.tty
: NULL
);
2727 Gpm_Connect connection
;
2730 error ("Gpm-mouse only works in the GNU/Linux console");
2732 return Qnil
; /* Already activated, nothing to do. */
2734 error ("Gpm-mouse can only be activated for one tty at a time");
2736 connection
.eventMask
= ~0;
2737 connection
.defaultMask
= ~GPM_HARD
;
2738 connection
.maxMod
= ~0;
2739 connection
.minMod
= 0;
2742 if (Gpm_Open (&connection
, 0) < 0)
2743 error ("Gpm-mouse failed to connect to the gpm daemon");
2747 /* `init_sys_modes' arranges for mouse movements sent through gpm_fd
2748 to generate SIGIOs. Apparently we need to call reset_sys_modes
2749 before calling init_sys_modes. */
2750 reset_sys_modes (tty
);
2751 init_sys_modes (tty
);
2752 add_gpm_wait_descriptor (gpm_fd
);
2761 delete_gpm_wait_descriptor (fd
);
2762 while (Gpm_Close()); /* close all the stack */
2766 DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop
, Sgpm_mouse_stop
,
2768 doc
: /* Close a connection to Gpm. */)
2771 struct frame
*f
= SELECTED_FRAME ();
2772 struct tty_display_info
*tty
2773 = ((f
)->output_method
== output_termcap
2774 ? (f
)->terminal
->display_info
.tty
: NULL
);
2776 if (!tty
|| gpm_tty
!= tty
)
2777 return Qnil
; /* Not activated on this terminal, nothing to do. */
2782 #endif /* HAVE_GPM */
2786 /***********************************************************************
2788 ***********************************************************************/
2790 /* Initialize the tty-dependent part of frame F. The frame must
2791 already have its device initialized. */
2794 create_tty_output (struct frame
*f
)
2796 struct tty_output
*t
= xzalloc (sizeof *t
);
2798 if (! FRAME_TERMCAP_P (f
))
2801 t
->display_info
= FRAME_TERMINAL (f
)->display_info
.tty
;
2803 f
->output_data
.tty
= t
;
2806 /* Delete frame F's face cache, and its tty-dependent part. */
2809 tty_free_frame_resources (struct frame
*f
)
2811 if (! FRAME_TERMCAP_P (f
))
2814 if (FRAME_FACE_CACHE (f
))
2815 free_frame_faces (f
);
2817 xfree (f
->output_data
.tty
);
2822 /* Delete frame F's face cache. */
2825 tty_free_frame_resources (struct frame
*f
)
2827 if (! FRAME_TERMCAP_P (f
) && ! FRAME_MSDOS_P (f
))
2830 if (FRAME_FACE_CACHE (f
))
2831 free_frame_faces (f
);
2835 /* Reset the hooks in TERMINAL. */
2838 clear_tty_hooks (struct terminal
*terminal
)
2841 terminal
->cursor_to_hook
= 0;
2842 terminal
->raw_cursor_to_hook
= 0;
2843 terminal
->clear_to_end_hook
= 0;
2844 terminal
->clear_frame_hook
= 0;
2845 terminal
->clear_end_of_line_hook
= 0;
2846 terminal
->ins_del_lines_hook
= 0;
2847 terminal
->insert_glyphs_hook
= 0;
2848 terminal
->write_glyphs_hook
= 0;
2849 terminal
->delete_glyphs_hook
= 0;
2850 terminal
->ring_bell_hook
= 0;
2851 terminal
->reset_terminal_modes_hook
= 0;
2852 terminal
->set_terminal_modes_hook
= 0;
2853 terminal
->update_begin_hook
= 0;
2854 terminal
->update_end_hook
= 0;
2855 terminal
->set_terminal_window_hook
= 0;
2856 terminal
->mouse_position_hook
= 0;
2857 terminal
->frame_rehighlight_hook
= 0;
2858 terminal
->frame_raise_lower_hook
= 0;
2859 terminal
->fullscreen_hook
= 0;
2860 terminal
->set_vertical_scroll_bar_hook
= 0;
2861 terminal
->condemn_scroll_bars_hook
= 0;
2862 terminal
->redeem_scroll_bar_hook
= 0;
2863 terminal
->judge_scroll_bars_hook
= 0;
2864 terminal
->read_socket_hook
= 0;
2865 terminal
->frame_up_to_date_hook
= 0;
2867 /* Leave these two set, or suspended frames are not deleted
2869 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
2870 terminal
->delete_terminal_hook
= &delete_tty
;
2873 /* Initialize hooks in TERMINAL with the values needed for a tty. */
2876 set_tty_hooks (struct terminal
*terminal
)
2878 terminal
->rif
= 0; /* ttys don't support window-based redisplay. */
2880 terminal
->cursor_to_hook
= &tty_cursor_to
;
2881 terminal
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
2883 terminal
->clear_to_end_hook
= &tty_clear_to_end
;
2884 terminal
->clear_frame_hook
= &tty_clear_frame
;
2885 terminal
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
2887 terminal
->ins_del_lines_hook
= &tty_ins_del_lines
;
2889 terminal
->insert_glyphs_hook
= &tty_insert_glyphs
;
2890 terminal
->write_glyphs_hook
= &tty_write_glyphs
;
2891 terminal
->delete_glyphs_hook
= &tty_delete_glyphs
;
2893 terminal
->ring_bell_hook
= &tty_ring_bell
;
2895 terminal
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
2896 terminal
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
2897 terminal
->update_begin_hook
= 0; /* Not needed. */
2898 terminal
->update_end_hook
= &tty_update_end
;
2899 terminal
->set_terminal_window_hook
= &tty_set_terminal_window
;
2901 terminal
->mouse_position_hook
= 0; /* Not needed. */
2902 terminal
->frame_rehighlight_hook
= 0; /* Not needed. */
2903 terminal
->frame_raise_lower_hook
= 0; /* Not needed. */
2905 terminal
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
2906 terminal
->condemn_scroll_bars_hook
= 0; /* Not needed. */
2907 terminal
->redeem_scroll_bar_hook
= 0; /* Not needed. */
2908 terminal
->judge_scroll_bars_hook
= 0; /* Not needed. */
2910 terminal
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
2911 terminal
->frame_up_to_date_hook
= 0; /* Not needed. */
2913 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
2914 terminal
->delete_terminal_hook
= &delete_tty
;
2917 /* Drop the controlling terminal if fd is the same device. */
2919 dissociate_if_controlling_tty (int fd
)
2922 int pgid
= tcgetpgrp (fd
); /* If tcgetpgrp succeeds, fd is the ctty. */
2927 no_controlling_tty
= 1;
2928 #elif defined (CYGWIN)
2930 no_controlling_tty
= 1;
2932 #ifdef TIOCNOTTY /* Try BSD ioctls. */
2934 sigemptyset (&blocked
);
2935 sigaddset (&blocked
, SIGTTOU
);
2936 pthread_sigmask (SIG_BLOCK
, &blocked
, 0);
2937 fd
= emacs_open (DEV_TTY
, O_RDWR
, 0);
2938 if (fd
!= -1 && ioctl (fd
, TIOCNOTTY
, 0) != -1)
2940 no_controlling_tty
= 1;
2944 pthread_sigmask (SIG_UNBLOCK
, &blocked
, 0);
2946 # error "Unknown system."
2947 #endif /* ! TIOCNOTTY */
2950 #endif /* !DOS_NT */
2953 /* Create a termcap display on the tty device with the given name and
2956 If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
2957 Otherwise NAME should be a path to the tty device file,
2960 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
2962 If MUST_SUCCEED is true, then all errors are fatal. */
2965 init_tty (const char *name
, const char *terminal_type
, int must_succeed
)
2968 char **address
= &area
;
2969 int buffer_size
= 4096;
2971 struct tty_display_info
*tty
= NULL
;
2972 struct terminal
*terminal
= NULL
;
2973 int ctty
= 0; /* 1 if asked to open controlling tty. */
2976 maybe_fatal (must_succeed
, 0,
2977 "Unknown terminal type",
2978 "Unknown terminal type");
2982 if (!strcmp (name
, DEV_TTY
))
2985 /* If we already have a terminal on the given device, use that. If
2986 all such terminals are suspended, create a new one instead. */
2987 /* XXX Perhaps this should be made explicit by having init_tty
2988 always create a new terminal and separating terminal and frame
2989 creation on Lisp level. */
2990 terminal
= get_named_tty (name
);
2994 terminal
= create_terminal ();
2997 maybe_fatal (0, 0, "Attempt to create another terminal %s", "",
3000 tty
= &the_only_display_info
;
3002 tty
= xzalloc (sizeof *tty
);
3004 tty
->top_frame
= Qnil
;
3005 tty
->next
= tty_list
;
3008 terminal
->type
= output_termcap
;
3009 terminal
->display_info
.tty
= tty
;
3010 tty
->terminal
= terminal
;
3012 tty
->Wcm
= xmalloc (sizeof *tty
->Wcm
);
3015 encode_terminal_src_size
= 0;
3016 encode_terminal_dst_size
= 0;
3020 set_tty_hooks (terminal
);
3026 #ifdef O_IGNORE_CTTY
3028 /* Open the terminal device. Don't recognize it as our
3029 controlling terminal, and don't make it the controlling tty
3030 if we don't have one at the moment. */
3031 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
3033 #endif /* O_IGNORE_CTTY */
3034 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
3035 defined on Hurd. On other systems, we need to explicitly
3036 dissociate ourselves from the controlling tty when we want to
3037 open a frame on the same terminal. */
3038 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
3040 tty
->name
= xstrdup (name
);
3041 terminal
->name
= xstrdup (name
);
3044 maybe_fatal (must_succeed
, terminal
,
3045 "Could not open file: %s",
3046 "Could not open file: %s",
3051 maybe_fatal (must_succeed
, terminal
,
3052 "Not a tty device: %s",
3053 "Not a tty device: %s",
3057 #ifndef O_IGNORE_CTTY
3059 dissociate_if_controlling_tty (fd
);
3062 file
= fdopen (fd
, "w+");
3067 tty
->type
= xstrdup (terminal_type
);
3069 add_keyboard_wait_descriptor (fileno (tty
->input
));
3073 tty
->termcap_term_buffer
= xmalloc (buffer_size
);
3075 /* On some systems, tgetent tries to access the controlling
3079 sigemptyset (&blocked
);
3080 sigaddset (&blocked
, SIGTTOU
);
3081 pthread_sigmask (SIG_BLOCK
, &blocked
, 0);
3082 status
= tgetent (tty
->termcap_term_buffer
, terminal_type
);
3083 pthread_sigmask (SIG_UNBLOCK
, &blocked
, 0);
3089 maybe_fatal (must_succeed
, terminal
,
3090 "Cannot open terminfo database file",
3091 "Cannot open terminfo database file");
3093 maybe_fatal (must_succeed
, terminal
,
3094 "Cannot open termcap database file",
3095 "Cannot open termcap database file");
3100 maybe_fatal (must_succeed
, terminal
,
3101 "Terminal type %s is not defined",
3102 "Terminal type %s is not defined.\n\
3103 If that is not the actual type of terminal you have,\n\
3104 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3105 `setenv TERM ...') to specify the correct type. It may be necessary\n"
3107 "to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3109 "to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3115 if (strlen (tty
->termcap_term_buffer
) >= buffer_size
)
3117 buffer_size
= strlen (tty
->termcap_term_buffer
);
3119 tty
->termcap_strings_buffer
= area
= xmalloc (buffer_size
);
3120 tty
->TS_ins_line
= tgetstr ("al", address
);
3121 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
3122 tty
->TS_bell
= tgetstr ("bl", address
);
3123 BackTab (tty
) = tgetstr ("bt", address
);
3124 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
3125 tty
->TS_clr_line
= tgetstr ("ce", address
);
3126 tty
->TS_clr_frame
= tgetstr ("cl", address
);
3127 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
3128 AbsPosition (tty
) = tgetstr ("cm", address
);
3129 CR (tty
) = tgetstr ("cr", address
);
3130 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
3131 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
3132 RowPosition (tty
) = tgetstr ("cv", address
);
3133 tty
->TS_del_char
= tgetstr ("dc", address
);
3134 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
3135 tty
->TS_del_line
= tgetstr ("dl", address
);
3136 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
3137 tty
->TS_delete_mode
= tgetstr ("dm", address
);
3138 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
3139 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
3140 Home (tty
) = tgetstr ("ho", address
);
3141 tty
->TS_ins_char
= tgetstr ("ic", address
);
3142 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
3143 tty
->TS_insert_mode
= tgetstr ("im", address
);
3144 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
3145 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
3146 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
3147 LastLine (tty
) = tgetstr ("ll", address
);
3148 Right (tty
) = tgetstr ("nd", address
);
3149 Down (tty
) = tgetstr ("do", address
);
3151 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
3152 if (tgetflag ("bs"))
3153 Left (tty
) = "\b"; /* can't possibly be longer! */
3154 else /* (Actually, "bs" is obsolete...) */
3155 Left (tty
) = tgetstr ("le", address
);
3157 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
3158 tty
->TS_pad_char
= tgetstr ("pc", address
);
3159 tty
->TS_repeat
= tgetstr ("rp", address
);
3160 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
3161 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
3162 tty
->TS_standout_mode
= tgetstr ("so", address
);
3163 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
3164 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
3165 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
3166 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
3167 Up (tty
) = tgetstr ("up", address
);
3168 tty
->TS_visible_bell
= tgetstr ("vb", address
);
3169 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
3170 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
3171 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
3172 tty
->TS_set_window
= tgetstr ("wi", address
);
3174 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
3175 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
3176 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
3177 tty
->TS_enter_italic_mode
= tgetstr ("ZH", address
);
3178 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
3179 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
3180 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3181 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3182 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
3184 MultiUp (tty
) = tgetstr ("UP", address
);
3185 MultiDown (tty
) = tgetstr ("DO", address
);
3186 MultiLeft (tty
) = tgetstr ("LE", address
);
3187 MultiRight (tty
) = tgetstr ("RI", address
);
3189 /* SVr4/ANSI color support. If "op" isn't available, don't support
3190 color because we can't switch back to the default foreground and
3192 tty
->TS_orig_pair
= tgetstr ("op", address
);
3193 if (tty
->TS_orig_pair
)
3195 tty
->TS_set_foreground
= tgetstr ("AF", address
);
3196 tty
->TS_set_background
= tgetstr ("AB", address
);
3197 if (!tty
->TS_set_foreground
)
3200 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
3201 tty
->TS_set_background
= tgetstr ("Sb", address
);
3204 tty
->TN_max_colors
= tgetnum ("Co");
3205 tty
->TN_max_pairs
= tgetnum ("pa");
3207 tty
->TN_no_color_video
= tgetnum ("NC");
3208 if (tty
->TN_no_color_video
== -1)
3209 tty
->TN_no_color_video
= 0;
3212 tty_default_color_capabilities (tty
, 1);
3214 MagicWrap (tty
) = tgetflag ("xn");
3215 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3216 the former flag imply the latter. */
3217 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
3218 terminal
->memory_below_frame
= tgetflag ("db");
3219 tty
->TF_hazeltine
= tgetflag ("hz");
3220 terminal
->must_write_spaces
= tgetflag ("in");
3221 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
3222 tty
->TF_insmode_motion
= tgetflag ("mi");
3223 tty
->TF_standout_motion
= tgetflag ("ms");
3224 tty
->TF_underscore
= tgetflag ("ul");
3225 tty
->TF_teleray
= tgetflag ("xt");
3230 struct frame
*f
= XFRAME (selected_frame
);
3232 initialize_w32_display (terminal
);
3234 FrameRows (tty
) = FRAME_LINES (f
);
3235 FrameCols (tty
) = FRAME_COLS (f
);
3236 tty
->specified_window
= FRAME_LINES (f
);
3238 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
3239 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
3240 terminal
->char_ins_del_ok
= 1;
3246 if (strcmp (terminal_type
, "internal") == 0)
3247 terminal
->type
= output_msdos_raw
;
3248 initialize_msdos_display (terminal
);
3250 get_tty_size (fileno (tty
->input
), &width
, &height
);
3251 FrameCols (tty
) = width
;
3252 FrameRows (tty
) = height
;
3253 terminal
->char_ins_del_ok
= 0;
3254 init_baud_rate (fileno (tty
->input
));
3257 tty
->output
= stdout
;
3259 /* The following two are inaccessible from w32console.c. */
3260 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3261 terminal
->delete_terminal_hook
= &delete_tty
;
3263 tty
->name
= xstrdup (name
);
3264 terminal
->name
= xstrdup (name
);
3265 tty
->type
= xstrdup (terminal_type
);
3267 add_keyboard_wait_descriptor (0);
3269 tty
->delete_in_insert_mode
= 1;
3272 terminal
->scroll_region_ok
= 0;
3274 /* Seems to insert lines when it's not supposed to, messing up the
3275 display. In doing a trace, it didn't seem to be called much, so I
3276 don't think we're losing anything by turning it off. */
3277 terminal
->line_ins_del_ok
= 0;
3279 tty
->TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
3283 terminal
->mouse_position_hook
= term_mouse_position
;
3284 tty
->mouse_highlight
.mouse_face_window
= Qnil
;
3287 terminal
->kboard
= xmalloc (sizeof *terminal
->kboard
);
3288 init_kboard (terminal
->kboard
);
3289 kset_window_system (terminal
->kboard
, Qnil
);
3290 terminal
->kboard
->next_kboard
= all_kboards
;
3291 all_kboards
= terminal
->kboard
;
3292 terminal
->kboard
->reference_count
++;
3293 /* Don't let the initial kboard remain current longer than necessary.
3294 That would cause problems if a file loaded on startup tries to
3295 prompt in the mini-buffer. */
3296 if (current_kboard
== initial_kboard
)
3297 current_kboard
= terminal
->kboard
;
3299 term_get_fkeys (address
, terminal
->kboard
);
3301 /* Get frame size from system, or else from termcap. */
3304 get_tty_size (fileno (tty
->input
), &width
, &height
);
3305 FrameCols (tty
) = width
;
3306 FrameRows (tty
) = height
;
3309 if (FrameCols (tty
) <= 0)
3310 FrameCols (tty
) = tgetnum ("co");
3311 if (FrameRows (tty
) <= 0)
3312 FrameRows (tty
) = tgetnum ("li");
3314 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
3315 maybe_fatal (must_succeed
, terminal
,
3316 "Screen size %dx%d is too small",
3317 "Screen size %dx%d is too small",
3318 FrameCols (tty
), FrameRows (tty
));
3320 TabWidth (tty
) = tgetnum ("tw");
3323 tty
->TS_bell
= "\07";
3325 if (!tty
->TS_fwd_scroll
)
3326 tty
->TS_fwd_scroll
= Down (tty
);
3328 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
3330 if (TabWidth (tty
) < 0)
3333 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3334 and newer termcap doc does not seem to say there is a default.
3335 if (!tty->Wcm->cm_tab)
3336 tty->Wcm->cm_tab = "\t";
3339 /* We don't support standout modes that use `magic cookies', so
3340 turn off any that do. */
3341 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
3343 tty
->TS_standout_mode
= 0;
3344 tty
->TS_end_standout_mode
= 0;
3346 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3348 tty
->TS_enter_underline_mode
= 0;
3349 tty
->TS_exit_underline_mode
= 0;
3352 /* If there's no standout mode, try to use underlining instead. */
3353 if (tty
->TS_standout_mode
== 0)
3355 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
3356 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
3359 /* If no `se' string, try using a `me' string instead.
3360 If that fails, we can't use standout mode at all. */
3361 if (tty
->TS_end_standout_mode
== 0)
3363 char *s
= tgetstr ("me", address
);
3365 tty
->TS_end_standout_mode
= s
;
3367 tty
->TS_standout_mode
= 0;
3370 if (tty
->TF_teleray
)
3372 tty
->Wcm
->cm_tab
= 0;
3373 /* We can't support standout mode, because it uses magic cookies. */
3374 tty
->TS_standout_mode
= 0;
3375 /* But that means we cannot rely on ^M to go to column zero! */
3377 /* LF can't be trusted either -- can alter hpos */
3378 /* if move at column 0 thru a line with TS_standout_mode */
3382 tty
->specified_window
= FrameRows (tty
);
3384 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
3386 maybe_fatal (must_succeed
, terminal
,
3387 "Terminal type \"%s\" is not powerful enough to run Emacs",
3388 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3389 It lacks the ability to position the cursor.\n\
3390 If that is not the actual type of terminal you have,\n\
3391 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3392 `setenv TERM ...') to specify the correct type. It may be necessary\n"
3394 "to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3395 # else /* TERMCAP */
3396 "to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3397 # endif /* TERMINFO */
3401 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
3402 maybe_fatal (must_succeed
, terminal
,
3403 "Could not determine the frame size",
3404 "Could not determine the frame size");
3406 tty
->delete_in_insert_mode
3407 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
3408 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
3410 tty
->se_is_so
= (tty
->TS_standout_mode
3411 && tty
->TS_end_standout_mode
3412 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
3414 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
3416 terminal
->scroll_region_ok
3418 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
3420 terminal
->line_ins_del_ok
3421 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
3422 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
3423 || (terminal
->scroll_region_ok
3424 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
3426 terminal
->char_ins_del_ok
3427 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
3428 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
3429 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
3431 terminal
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
3433 init_baud_rate (fileno (tty
->input
));
3435 #endif /* not DOS_NT */
3437 /* Init system terminal modes (RAW or CBREAK, etc.). */
3438 init_sys_modes (tty
);
3445 vfatal (const char *str
, va_list ap
)
3447 fprintf (stderr
, "emacs: ");
3448 vfprintf (stderr
, str
, ap
);
3449 if (!(strlen (str
) > 0 && str
[strlen (str
) - 1] == '\n'))
3450 fprintf (stderr
, "\n");
3456 /* Auxiliary error-handling function for init_tty.
3457 Delete TERMINAL, then call error or fatal with str1 or str2,
3458 respectively, according to whether MUST_SUCCEED is zero or not. */
3461 maybe_fatal (int must_succeed
, struct terminal
*terminal
,
3462 const char *str1
, const char *str2
, ...)
3465 va_start (ap
, str2
);
3467 delete_tty (terminal
);
3479 fatal (const char *str
, ...)
3489 /* Delete the given tty terminal, closing all frames on it. */
3492 delete_tty (struct terminal
*terminal
)
3494 struct tty_display_info
*tty
;
3496 /* Protect against recursive calls. delete_frame in
3497 delete_terminal calls us back when it deletes our last frame. */
3498 if (!terminal
->name
)
3501 if (terminal
->type
!= output_termcap
)
3504 tty
= terminal
->display_info
.tty
;
3506 if (tty
== tty_list
)
3507 tty_list
= tty
->next
;
3510 struct tty_display_info
*p
;
3511 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
3515 /* This should not happen. */
3518 p
->next
= tty
->next
;
3522 /* reset_sys_modes needs a valid device, so this call needs to be
3523 before delete_terminal. */
3524 reset_sys_modes (tty
);
3526 delete_terminal (terminal
);
3533 delete_keyboard_wait_descriptor (fileno (tty
->input
));
3534 if (tty
->input
!= stdin
)
3535 fclose (tty
->input
);
3537 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
3538 fclose (tty
->output
);
3539 if (tty
->termscript
)
3540 fclose (tty
->termscript
);
3542 xfree (tty
->old_tty
);
3544 xfree (tty
->termcap_strings_buffer
);
3545 xfree (tty
->termcap_term_buffer
);
3553 DEFVAR_BOOL ("system-uses-terminfo", system_uses_terminfo
,
3554 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3555 This variable can be used by terminal emulator packages. */);
3557 system_uses_terminfo
= 1;
3559 system_uses_terminfo
= 0;
3562 DEFVAR_LISP ("suspend-tty-functions", Vsuspend_tty_functions
,
3563 doc
: /* Functions run after suspending a tty.
3564 The functions are run with one argument, the terminal object to be suspended.
3565 See `suspend-tty'. */);
3566 Vsuspend_tty_functions
= Qnil
;
3569 DEFVAR_LISP ("resume-tty-functions", Vresume_tty_functions
,
3570 doc
: /* Functions run after resuming a tty.
3571 The functions are run with one argument, the terminal object that was revived.
3572 See `resume-tty'. */);
3573 Vresume_tty_functions
= Qnil
;
3575 DEFVAR_BOOL ("visible-cursor", visible_cursor
,
3576 doc
: /* Non-nil means to make the cursor very visible.
3577 This only has an effect when running in a text terminal.
3578 What means \"very visible\" is up to your terminal. It may make the cursor
3579 bigger, or it may make it blink, or it may do nothing at all. */);
3582 defsubr (&Stty_display_color_p
);
3583 defsubr (&Stty_display_color_cells
);
3584 defsubr (&Stty_no_underline
);
3585 defsubr (&Stty_type
);
3586 defsubr (&Scontrolling_tty_p
);
3587 defsubr (&Stty_top_frame
);
3588 defsubr (&Ssuspend_tty
);
3589 defsubr (&Sresume_tty
);
3591 defsubr (&Sgpm_mouse_start
);
3592 defsubr (&Sgpm_mouse_stop
);
3593 #endif /* HAVE_GPM */
3596 default_orig_pair
= NULL
;
3597 default_set_foreground
= NULL
;
3598 default_set_background
= NULL
;
3599 #endif /* !DOS_NT */
3601 encode_terminal_src
= NULL
;
3602 encode_terminal_dst
= NULL
;