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>. */
34 #include "character.h"
38 #include "composite.h"
42 #include "termhooks.h"
43 #include "dispextern.h"
46 #include "blockinput.h"
47 #include "syssignal.h"
49 #include "intervals.h"
52 static int been_here
= -1;
68 /* The name of the default console device. */
70 #define DEV_TTY "CONOUT$"
72 #define DEV_TTY "/dev/tty"
75 static void tty_set_scroll_region (struct frame
*f
, int start
, int stop
);
76 static void turn_on_face (struct frame
*, int face_id
);
77 static void turn_off_face (struct frame
*, int face_id
);
78 static void tty_turn_off_highlight (struct tty_display_info
*);
79 static void tty_show_cursor (struct tty_display_info
*);
80 static void tty_hide_cursor (struct tty_display_info
*);
81 static void tty_background_highlight (struct tty_display_info
*tty
);
82 static struct terminal
*get_tty_terminal (Lisp_Object
, int);
83 static void clear_tty_hooks (struct terminal
*terminal
);
84 static void set_tty_hooks (struct terminal
*terminal
);
85 static void dissociate_if_controlling_tty (int fd
);
86 static void delete_tty (struct terminal
*);
87 static _Noreturn
void maybe_fatal (int must_succeed
, struct terminal
*terminal
,
88 const char *str1
, const char *str2
, ...)
89 ATTRIBUTE_FORMAT_PRINTF (3, 5) ATTRIBUTE_FORMAT_PRINTF (4, 5);
90 static _Noreturn
void vfatal (const char *str
, va_list ap
)
91 ATTRIBUTE_FORMAT_PRINTF (1, 0);
94 #define OUTPUT(tty, a) \
95 emacs_tputs ((tty), a, \
96 (int) (FRAME_LINES (XFRAME (selected_frame)) \
100 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
101 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
103 #define OUTPUT_IF(tty, a) \
109 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
111 /* Display space properties */
113 /* Chain of all tty device parameters. */
114 struct tty_display_info
*tty_list
;
116 /* Meaning of bits in no_color_video. Each bit set means that the
117 corresponding attribute cannot be combined with colors. */
121 NC_STANDOUT
= 1 << 0,
122 NC_UNDERLINE
= 1 << 1,
133 /* The largest frame width in any call to calculate_costs. */
135 static int max_frame_cols
;
137 /* Non-zero if we have dropped our controlling tty and therefore
138 should not open a frame on stdout. */
139 static int no_controlling_tty
;
144 #include <sys/fcntl.h>
146 /* The device for which we have enabled gpm support (or NULL). */
147 struct tty_display_info
*gpm_tty
= NULL
;
149 /* Last recorded mouse coordinates. */
150 static int last_mouse_x
, last_mouse_y
;
151 #endif /* HAVE_GPM */
153 /* Ring the bell on a tty. */
156 tty_ring_bell (struct frame
*f
)
158 struct tty_display_info
*tty
= FRAME_TTY (f
);
162 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
163 ? tty
->TS_visible_bell
165 fflush (tty
->output
);
169 /* Set up termcap modes for Emacs. */
172 tty_set_terminal_modes (struct terminal
*terminal
)
174 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
178 if (tty
->TS_termcap_modes
)
179 OUTPUT (tty
, tty
->TS_termcap_modes
);
182 /* Output enough newlines to scroll all the old screen contents
183 off the screen, so it won't be overwritten and lost. */
186 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
190 OUTPUT_IF (tty
, visible_cursor
? tty
->TS_cursor_visible
: tty
->TS_cursor_normal
);
191 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
193 fflush (tty
->output
);
197 /* Reset termcap modes before exiting Emacs. */
200 tty_reset_terminal_modes (struct terminal
*terminal
)
202 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
206 tty_turn_off_highlight (tty
);
207 tty_turn_off_insert (tty
);
208 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
209 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
210 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
211 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
212 /* Output raw CR so kernel can track the cursor hpos. */
215 fflush (tty
->output
);
219 /* Flag the end of a display update on a termcap terminal. */
222 tty_update_end (struct frame
*f
)
224 struct tty_display_info
*tty
= FRAME_TTY (f
);
226 if (!XWINDOW (selected_window
)->cursor_off_p
)
227 tty_show_cursor (tty
);
228 tty_turn_off_insert (tty
);
229 tty_background_highlight (tty
);
232 /* The implementation of set_terminal_window for termcap frames. */
235 tty_set_terminal_window (struct frame
*f
, int size
)
237 struct tty_display_info
*tty
= FRAME_TTY (f
);
239 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
240 if (FRAME_SCROLL_REGION_OK (f
))
241 tty_set_scroll_region (f
, 0, tty
->specified_window
);
245 tty_set_scroll_region (struct frame
*f
, int start
, int stop
)
248 struct tty_display_info
*tty
= FRAME_TTY (f
);
250 if (tty
->TS_set_scroll_region
)
251 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1, 0, 0);
252 else if (tty
->TS_set_scroll_region_1
)
253 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
254 FRAME_LINES (f
), start
,
255 FRAME_LINES (f
) - stop
,
258 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
267 tty_turn_on_insert (struct tty_display_info
*tty
)
269 if (!tty
->insert_mode
)
270 OUTPUT (tty
, tty
->TS_insert_mode
);
271 tty
->insert_mode
= 1;
275 tty_turn_off_insert (struct tty_display_info
*tty
)
277 if (tty
->insert_mode
)
278 OUTPUT (tty
, tty
->TS_end_insert_mode
);
279 tty
->insert_mode
= 0;
282 /* Handle highlighting. */
285 tty_turn_off_highlight (struct tty_display_info
*tty
)
287 if (tty
->standout_mode
)
288 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
289 tty
->standout_mode
= 0;
293 tty_turn_on_highlight (struct tty_display_info
*tty
)
295 if (!tty
->standout_mode
)
296 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
297 tty
->standout_mode
= 1;
301 tty_toggle_highlight (struct tty_display_info
*tty
)
303 if (tty
->standout_mode
)
304 tty_turn_off_highlight (tty
);
306 tty_turn_on_highlight (tty
);
310 /* Make cursor invisible. */
313 tty_hide_cursor (struct tty_display_info
*tty
)
315 if (tty
->cursor_hidden
== 0)
317 tty
->cursor_hidden
= 1;
318 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
323 /* Ensure that cursor is visible. */
326 tty_show_cursor (struct tty_display_info
*tty
)
328 if (tty
->cursor_hidden
)
330 tty
->cursor_hidden
= 0;
331 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
333 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
338 /* Set standout mode to the state it should be in for
339 empty space inside windows. What this is,
340 depends on the user option inverse-video. */
343 tty_background_highlight (struct tty_display_info
*tty
)
346 tty_turn_on_highlight (tty
);
348 tty_turn_off_highlight (tty
);
351 /* Set standout mode to the mode specified for the text to be output. */
354 tty_highlight_if_desired (struct tty_display_info
*tty
)
357 tty_turn_on_highlight (tty
);
359 tty_turn_off_highlight (tty
);
363 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
364 frame-relative coordinates. */
367 tty_cursor_to (struct frame
*f
, int vpos
, int hpos
)
369 struct tty_display_info
*tty
= FRAME_TTY (f
);
371 /* Detect the case where we are called from reset_sys_modes
372 and the costs have never been calculated. Do nothing. */
373 if (! tty
->costs_set
)
376 if (curY (tty
) == vpos
377 && curX (tty
) == hpos
)
379 if (!tty
->TF_standout_motion
)
380 tty_background_highlight (tty
);
381 if (!tty
->TF_insmode_motion
)
382 tty_turn_off_insert (tty
);
383 cmgoto (tty
, vpos
, hpos
);
386 /* Similar but don't take any account of the wasted characters. */
389 tty_raw_cursor_to (struct frame
*f
, int row
, int col
)
391 struct tty_display_info
*tty
= FRAME_TTY (f
);
393 if (curY (tty
) == row
394 && curX (tty
) == col
)
396 if (!tty
->TF_standout_motion
)
397 tty_background_highlight (tty
);
398 if (!tty
->TF_insmode_motion
)
399 tty_turn_off_insert (tty
);
400 cmgoto (tty
, row
, col
);
403 /* Erase operations */
405 /* Clear from cursor to end of frame on a termcap device. */
408 tty_clear_to_end (struct frame
*f
)
411 struct tty_display_info
*tty
= FRAME_TTY (f
);
413 if (tty
->TS_clr_to_bottom
)
415 tty_background_highlight (tty
);
416 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
420 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
423 clear_end_of_line (f
, FRAME_COLS (f
));
428 /* Clear an entire termcap frame. */
431 tty_clear_frame (struct frame
*f
)
433 struct tty_display_info
*tty
= FRAME_TTY (f
);
435 if (tty
->TS_clr_frame
)
437 tty_background_highlight (tty
);
438 OUTPUT (tty
, tty
->TS_clr_frame
);
448 /* An implementation of clear_end_of_line for termcap frames.
450 Note that the cursor may be moved, on terminals lacking a `ce' string. */
453 tty_clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
456 struct tty_display_info
*tty
= FRAME_TTY (f
);
458 /* Detect the case where we are called from reset_sys_modes
459 and the costs have never been calculated. Do nothing. */
460 if (! tty
->costs_set
)
463 if (curX (tty
) >= first_unused_hpos
)
465 tty_background_highlight (tty
);
466 if (tty
->TS_clr_line
)
468 OUTPUT1 (tty
, tty
->TS_clr_line
);
471 { /* have to do it the hard way */
472 tty_turn_off_insert (tty
);
474 /* Do not write in last row last col with Auto-wrap on. */
476 && curY (tty
) == FrameRows (tty
) - 1
477 && first_unused_hpos
== FrameCols (tty
))
480 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
483 fputc (' ', tty
->termscript
);
484 fputc (' ', tty
->output
);
486 cmplus (tty
, first_unused_hpos
- curX (tty
));
490 /* Buffers to store the source and result of code conversion for terminal. */
491 static unsigned char *encode_terminal_src
;
492 static unsigned char *encode_terminal_dst
;
493 /* Allocated sizes of the above buffers. */
494 static ptrdiff_t encode_terminal_src_size
;
495 static ptrdiff_t encode_terminal_dst_size
;
497 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
498 Set CODING->produced to the byte-length of the resulting byte
499 sequence, and return a pointer to that byte sequence. */
502 encode_terminal_code (struct glyph
*src
, int src_len
, struct coding_system
*coding
)
504 struct glyph
*src_end
= src
+ src_len
;
506 ptrdiff_t nchars
, nbytes
, required
;
507 ptrdiff_t tlen
= GLYPH_TABLE_LENGTH
;
508 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
509 Lisp_Object charset_list
;
511 /* Allocate sufficient size of buffer to store all characters in
512 multibyte-form. But, it may be enlarged on demand if
513 Vglyph_table contains a string or a composite glyph is
515 if (min (PTRDIFF_MAX
, SIZE_MAX
) / MAX_MULTIBYTE_LENGTH
< src_len
)
516 memory_full (SIZE_MAX
);
518 required
*= MAX_MULTIBYTE_LENGTH
;
519 if (encode_terminal_src_size
< required
)
521 encode_terminal_src
= xrealloc (encode_terminal_src
, required
);
522 encode_terminal_src_size
= required
;
525 charset_list
= coding_charset_list (coding
);
527 buf
= encode_terminal_src
;
529 while (src
< src_end
)
531 if (src
->type
== COMPOSITE_GLYPH
)
533 struct composition
*cmp
IF_LINT (= NULL
);
534 Lisp_Object gstring
IF_LINT (= Qnil
);
537 nbytes
= buf
- encode_terminal_src
;
538 if (src
->u
.cmp
.automatic
)
540 gstring
= composition_gstring_from_id (src
->u
.cmp
.id
);
541 required
= src
->slice
.cmp
.to
- src
->slice
.cmp
.from
+ 1;
545 cmp
= composition_table
[src
->u
.cmp
.id
];
546 required
= cmp
->glyph_len
;
547 required
*= MAX_MULTIBYTE_LENGTH
;
550 if (encode_terminal_src_size
- nbytes
< required
)
552 encode_terminal_src
=
553 xpalloc (encode_terminal_src
, &encode_terminal_src_size
,
554 required
- (encode_terminal_src_size
- nbytes
),
556 buf
= encode_terminal_src
+ nbytes
;
559 if (src
->u
.cmp
.automatic
)
560 for (i
= src
->slice
.cmp
.from
; i
<= src
->slice
.cmp
.to
; i
++)
562 Lisp_Object g
= LGSTRING_GLYPH (gstring
, i
);
563 int c
= LGLYPH_CHAR (g
);
565 if (! char_charset (c
, charset_list
, NULL
))
567 buf
+= CHAR_STRING (c
, buf
);
571 for (i
= 0; i
< cmp
->glyph_len
; i
++)
573 int c
= COMPOSITION_GLYPH (cmp
, i
);
575 /* TAB in a composition means display glyphs with
576 padding space on the left or right. */
579 if (char_charset (c
, charset_list
, NULL
))
581 if (CHAR_WIDTH (c
) == 0
582 && i
> 0 && COMPOSITION_GLYPH (cmp
, i
- 1) == '\t')
583 /* Should be left-padded */
585 buf
+= CHAR_STRING (' ', buf
);
591 buf
+= CHAR_STRING (c
, buf
);
595 /* We must skip glyphs to be padded for a wide character. */
596 else if (! CHAR_GLYPH_PADDING_P (*src
))
603 SET_GLYPH_FROM_CHAR_GLYPH (g
, src
[0]);
605 if (GLYPH_INVALID_P (g
) || GLYPH_SIMPLE_P (tbase
, tlen
, g
))
607 /* This glyph doesn't have an entry in Vglyph_table. */
612 /* This glyph has an entry in Vglyph_table,
613 so process any alias before testing for simpleness. */
614 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
616 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
617 /* We set the multi-byte form of a character in G
618 (that should be an ASCII character) at WORKBUF. */
621 /* We have a string in Vglyph_table. */
622 string
= tbase
[GLYPH_CHAR (g
)];
627 nbytes
= buf
- encode_terminal_src
;
628 if (encode_terminal_src_size
- nbytes
< MAX_MULTIBYTE_LENGTH
)
630 encode_terminal_src
=
631 xpalloc (encode_terminal_src
, &encode_terminal_src_size
,
632 MAX_MULTIBYTE_LENGTH
, -1, 1);
633 buf
= encode_terminal_src
+ nbytes
;
636 || char_charset (c
, charset_list
, NULL
))
638 /* Store the multibyte form of C at BUF. */
639 buf
+= CHAR_STRING (c
, buf
);
644 /* C is not encodable. */
647 while (src
+ 1 < src_end
&& CHAR_GLYPH_PADDING_P (src
[1]))
657 if (! STRING_MULTIBYTE (string
))
658 string
= string_to_multibyte (string
);
659 nbytes
= buf
- encode_terminal_src
;
660 if (encode_terminal_src_size
- nbytes
< SBYTES (string
))
662 encode_terminal_src
=
663 xpalloc (encode_terminal_src
, &encode_terminal_src_size
,
665 - (encode_terminal_src_size
- nbytes
)),
667 buf
= encode_terminal_src
+ nbytes
;
669 memcpy (buf
, SDATA (string
), SBYTES (string
));
670 buf
+= SBYTES (string
);
671 nchars
+= SCHARS (string
);
679 coding
->produced
= 0;
683 nbytes
= buf
- encode_terminal_src
;
684 coding
->source
= encode_terminal_src
;
685 if (encode_terminal_dst_size
== 0)
687 encode_terminal_dst
= xrealloc (encode_terminal_dst
,
688 encode_terminal_src_size
);
689 encode_terminal_dst_size
= encode_terminal_src_size
;
691 coding
->destination
= encode_terminal_dst
;
692 coding
->dst_bytes
= encode_terminal_dst_size
;
693 encode_coding_object (coding
, Qnil
, 0, 0, nchars
, nbytes
, Qnil
);
694 /* coding->destination may have been reallocated. */
695 encode_terminal_dst
= coding
->destination
;
696 encode_terminal_dst_size
= coding
->dst_bytes
;
698 return (encode_terminal_dst
);
703 /* An implementation of write_glyphs for termcap frames. */
706 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
708 unsigned char *conversion_buffer
;
709 struct coding_system
*coding
;
712 struct tty_display_info
*tty
= FRAME_TTY (f
);
714 tty_turn_off_insert (tty
);
715 tty_hide_cursor (tty
);
717 /* Don't dare write in last column of bottom line, if Auto-Wrap,
718 since that would scroll the whole frame on some terminals. */
721 && curY (tty
) + 1 == FRAME_LINES (f
)
722 && (curX (tty
) + len
) == FRAME_COLS (f
))
729 /* If terminal_coding does any conversion, use it, otherwise use
730 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
731 because it always return 1 if the member src_multibyte is 1. */
732 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
733 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
734 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
736 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
738 for (stringlen
= len
; stringlen
!= 0; stringlen
-= n
)
740 /* Identify a run of glyphs with the same face. */
741 int face_id
= string
->face_id
;
743 for (n
= 1; n
< stringlen
; ++n
)
744 if (string
[n
].face_id
!= face_id
)
747 /* Turn appearance modes of the face of the run on. */
748 tty_highlight_if_desired (tty
);
749 turn_on_face (f
, face_id
);
752 /* This is the last run. */
753 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
754 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
755 if (coding
->produced
> 0)
758 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
759 if (ferror (tty
->output
))
760 clearerr (tty
->output
);
762 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
767 /* Turn appearance modes off. */
768 turn_off_face (f
, face_id
);
769 tty_turn_off_highlight (tty
);
775 #ifdef HAVE_GPM /* Only used by GPM code. */
778 tty_write_glyphs_with_face (register struct frame
*f
, register struct glyph
*string
,
779 register int len
, register int face_id
)
781 unsigned char *conversion_buffer
;
782 struct coding_system
*coding
;
784 struct tty_display_info
*tty
= FRAME_TTY (f
);
786 tty_turn_off_insert (tty
);
787 tty_hide_cursor (tty
);
789 /* Don't dare write in last column of bottom line, if Auto-Wrap,
790 since that would scroll the whole frame on some terminals. */
793 && curY (tty
) + 1 == FRAME_LINES (f
)
794 && (curX (tty
) + len
) == FRAME_COLS (f
))
801 /* If terminal_coding does any conversion, use it, otherwise use
802 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
803 because it always return 1 if the member src_multibyte is 1. */
804 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
805 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
806 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
808 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
810 /* Turn appearance modes of the face. */
811 tty_highlight_if_desired (tty
);
812 turn_on_face (f
, face_id
);
814 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
815 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
816 if (coding
->produced
> 0)
819 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
820 if (ferror (tty
->output
))
821 clearerr (tty
->output
);
823 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
827 /* Turn appearance modes off. */
828 turn_off_face (f
, face_id
);
829 tty_turn_off_highlight (tty
);
835 /* An implementation of insert_glyphs for termcap frames. */
838 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
841 struct glyph
*glyph
= NULL
;
842 unsigned char *conversion_buffer
;
843 unsigned char space
[1];
844 struct coding_system
*coding
;
846 struct tty_display_info
*tty
= FRAME_TTY (f
);
848 if (tty
->TS_ins_multi_chars
)
850 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
, 0, 0, 0);
854 write_glyphs (f
, start
, len
);
858 tty_turn_on_insert (tty
);
862 space
[0] = SPACEGLYPH
;
864 /* If terminal_coding does any conversion, use it, otherwise use
865 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
866 because it always return 1 if the member src_multibyte is 1. */
867 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
868 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
869 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
871 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
875 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
878 conversion_buffer
= space
;
879 coding
->produced
= 1;
883 tty_highlight_if_desired (tty
);
884 turn_on_face (f
, start
->face_id
);
887 /* We must open sufficient space for a character which
888 occupies more than one column. */
889 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
891 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
896 /* This is the last glyph. */
897 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
899 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
902 if (coding
->produced
> 0)
905 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
906 if (ferror (tty
->output
))
907 clearerr (tty
->output
);
909 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
913 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
916 turn_off_face (f
, glyph
->face_id
);
917 tty_turn_off_highlight (tty
);
924 /* An implementation of delete_glyphs for termcap frames. */
927 tty_delete_glyphs (struct frame
*f
, int n
)
932 struct tty_display_info
*tty
= FRAME_TTY (f
);
934 if (tty
->delete_in_insert_mode
)
936 tty_turn_on_insert (tty
);
940 tty_turn_off_insert (tty
);
941 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
944 if (tty
->TS_del_multi_chars
)
946 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
, 0, 0, 0);
951 for (i
= 0; i
< n
; i
++)
952 OUTPUT1 (tty
, tty
->TS_del_char
);
953 if (!tty
->delete_in_insert_mode
)
954 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
957 /* An implementation of ins_del_lines for termcap frames. */
960 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
962 struct tty_display_info
*tty
= FRAME_TTY (f
);
964 n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
965 const char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
966 const char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
968 register int i
= n
> 0 ? n
: -n
;
971 /* If the lines below the insertion are being pushed
972 into the end of the window, this is the same as clearing;
973 and we know the lines are already clear, since the matching
974 deletion has already been done. So can ignore this. */
975 /* If the lines below the deletion are blank lines coming
976 out of the end of the window, don't bother,
977 as there will be a matching inslines later that will flush them. */
978 if (FRAME_SCROLL_REGION_OK (f
)
979 && vpos
+ i
>= tty
->specified_window
)
981 if (!FRAME_MEMORY_BELOW_FRAME (f
)
982 && vpos
+ i
>= FRAME_LINES (f
))
987 raw_cursor_to (f
, vpos
, 0);
988 tty_background_highlight (tty
);
989 buf
= tparam (multi
, 0, 0, i
, 0, 0, 0);
995 raw_cursor_to (f
, vpos
, 0);
996 tty_background_highlight (tty
);
998 OUTPUT (tty
, single
);
1004 tty_set_scroll_region (f
, vpos
, tty
->specified_window
);
1006 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
1008 raw_cursor_to (f
, vpos
, 0);
1009 tty_background_highlight (tty
);
1011 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1012 tty_set_scroll_region (f
, 0, tty
->specified_window
);
1015 if (!FRAME_SCROLL_REGION_OK (f
)
1016 && FRAME_MEMORY_BELOW_FRAME (f
)
1019 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
1024 /* Compute cost of sending "str", in characters,
1025 not counting any line-dependent padding. */
1028 string_cost (const char *str
)
1032 tputs (str
, 0, evalcost
);
1036 /* Compute cost of sending "str", in characters,
1037 counting any line-dependent padding at one line. */
1040 string_cost_one_line (const char *str
)
1044 tputs (str
, 1, evalcost
);
1048 /* Compute per line amount of line-dependent padding,
1049 in tenths of characters. */
1052 per_line_cost (const char *str
)
1056 tputs (str
, 0, evalcost
);
1059 tputs (str
, 10, evalcost
);
1063 /* char_ins_del_cost[n] is cost of inserting N characters.
1064 char_ins_del_cost[-n] is cost of deleting N characters.
1065 The length of this vector is based on max_frame_cols. */
1067 int *char_ins_del_vector
;
1069 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1073 calculate_ins_del_char_costs (struct frame
*f
)
1075 struct tty_display_info
*tty
= FRAME_TTY (f
);
1076 int ins_startup_cost
, del_startup_cost
;
1077 int ins_cost_per_char
, del_cost_per_char
;
1081 if (tty
->TS_ins_multi_chars
)
1083 ins_cost_per_char
= 0;
1084 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1086 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1087 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1089 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1090 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1091 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1092 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1096 ins_startup_cost
= 9999;
1097 ins_cost_per_char
= 0;
1100 if (tty
->TS_del_multi_chars
)
1102 del_cost_per_char
= 0;
1103 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1105 else if (tty
->TS_del_char
)
1107 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1108 + string_cost (tty
->TS_end_delete_mode
));
1109 if (tty
->delete_in_insert_mode
)
1110 del_startup_cost
/= 2;
1111 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1115 del_startup_cost
= 9999;
1116 del_cost_per_char
= 0;
1119 /* Delete costs are at negative offsets */
1120 p
= &char_ins_del_cost (f
)[0];
1121 for (i
= FRAME_COLS (f
); --i
>= 0;)
1122 *--p
= (del_startup_cost
+= del_cost_per_char
);
1124 /* Doing nothing is free */
1125 p
= &char_ins_del_cost (f
)[0];
1128 /* Insert costs are at positive offsets */
1129 for (i
= FRAME_COLS (f
); --i
>= 0;)
1130 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1134 calculate_costs (struct frame
*frame
)
1136 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1138 if (FRAME_TERMCAP_P (frame
))
1140 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1141 register const char *f
= (tty
->TS_set_scroll_region
1142 ? tty
->TS_set_scroll_region
1143 : tty
->TS_set_scroll_region_1
);
1145 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1149 /* These variables are only used for terminal stuff. They are
1150 allocated once for the terminal frame of X-windows emacs, but not
1153 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1154 X turns off char_ins_del_ok. */
1156 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1157 if ((min (PTRDIFF_MAX
, SIZE_MAX
) / sizeof (int) - 1) / 2
1159 memory_full (SIZE_MAX
);
1161 char_ins_del_vector
=
1162 xrealloc (char_ins_del_vector
,
1163 (sizeof (int) + 2 * sizeof (int) * max_frame_cols
));
1165 memset (char_ins_del_vector
, 0,
1166 (sizeof (int) + 2 * sizeof (int) * max_frame_cols
));
1169 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1170 do_line_insertion_deletion_costs (frame
,
1171 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1172 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1175 do_line_insertion_deletion_costs (frame
,
1176 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1177 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1180 calculate_ins_del_char_costs (frame
);
1182 /* Don't use TS_repeat if its padding is worse than sending the chars */
1183 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1184 tty
->RPov
= string_cost (tty
->TS_repeat
);
1186 tty
->RPov
= FRAME_COLS (frame
) * 2;
1188 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1193 const char *cap
, *name
;
1196 /* Termcap capability names that correspond directly to X keysyms.
1197 Some of these (marked "terminfo") aren't supplied by old-style
1198 (Berkeley) termcap entries. They're listed in X keysym order;
1199 except we put the keypad keys first, so that if they clash with
1200 other keys (as on the IBM PC keyboard) they get overridden.
1203 static const struct fkey_table keys
[] =
1205 {"kh", "home"}, /* termcap */
1206 {"kl", "left"}, /* termcap */
1207 {"ku", "up"}, /* termcap */
1208 {"kr", "right"}, /* termcap */
1209 {"kd", "down"}, /* termcap */
1210 {"%8", "prior"}, /* terminfo */
1211 {"%5", "next"}, /* terminfo */
1212 {"@7", "end"}, /* terminfo */
1213 {"@1", "begin"}, /* terminfo */
1214 {"*6", "select"}, /* terminfo */
1215 {"%9", "print"}, /* terminfo */
1216 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1218 * "insert" --- see below
1220 {"&8", "undo"}, /* terminfo */
1221 {"%0", "redo"}, /* terminfo */
1222 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1223 {"@0", "find"}, /* terminfo */
1224 {"@2", "cancel"}, /* terminfo */
1225 {"%1", "help"}, /* terminfo */
1227 * "break" goes here, but can't be reliably intercepted with termcap
1229 {"&4", "reset"}, /* terminfo --- actually `restart' */
1231 * "system" and "user" --- no termcaps
1233 {"kE", "clearline"}, /* terminfo */
1234 {"kA", "insertline"}, /* terminfo */
1235 {"kL", "deleteline"}, /* terminfo */
1236 {"kI", "insertchar"}, /* terminfo */
1237 {"kD", "deletechar"}, /* terminfo */
1238 {"kB", "backtab"}, /* terminfo */
1240 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1242 {"@8", "kp-enter"}, /* terminfo */
1244 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1245 * "kp-multiply", "kp-add", "kp-separator",
1246 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1247 * --- no termcaps for any of these.
1249 {"K4", "kp-1"}, /* terminfo */
1251 * "kp-2" --- no termcap
1253 {"K5", "kp-3"}, /* terminfo */
1255 * "kp-4" --- no termcap
1257 {"K2", "kp-5"}, /* terminfo */
1259 * "kp-6" --- no termcap
1261 {"K1", "kp-7"}, /* terminfo */
1263 * "kp-8" --- no termcap
1265 {"K3", "kp-9"}, /* terminfo */
1267 * "kp-equal" --- no termcap
1279 {"&0", "S-cancel"}, /*shifted cancel key*/
1280 {"&9", "S-begin"}, /*shifted begin key*/
1281 {"*0", "S-find"}, /*shifted find key*/
1282 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1283 {"*4", "S-delete"}, /*shifted delete-character key*/
1284 {"*7", "S-end"}, /*shifted end key*/
1285 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1286 {"#1", "S-help"}, /*shifted help key*/
1287 {"#2", "S-home"}, /*shifted home key*/
1288 {"#3", "S-insert"}, /*shifted insert-character key*/
1289 {"#4", "S-left"}, /*shifted left-arrow key*/
1290 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1291 {"%c", "S-next"}, /*shifted next key*/
1292 {"%e", "S-prior"}, /*shifted previous key*/
1293 {"%f", "S-print"}, /*shifted print key*/
1294 {"%g", "S-redo"}, /*shifted redo key*/
1295 {"%i", "S-right"}, /*shifted right-arrow key*/
1296 {"!3", "S-undo"} /*shifted undo key*/
1300 static char **term_get_fkeys_address
;
1301 static KBOARD
*term_get_fkeys_kboard
;
1302 static Lisp_Object
term_get_fkeys_1 (void);
1304 /* Find the escape codes sent by the function keys for Vinput_decode_map.
1305 This function scans the termcap function key sequence entries, and
1306 adds entries to Vinput_decode_map for each function key it finds. */
1309 term_get_fkeys (char **address
, KBOARD
*kboard
)
1311 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1312 errors during the call. The only errors should be from Fdefine_key
1313 when given a key sequence containing an invalid prefix key. If the
1314 termcap defines function keys which use a prefix that is already bound
1315 to a command by the default bindings, we should silently ignore that
1316 function key specification, rather than giving the user an error and
1317 refusing to run at all on such a terminal. */
1319 term_get_fkeys_address
= address
;
1320 term_get_fkeys_kboard
= kboard
;
1321 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1325 term_get_fkeys_1 (void)
1329 char **address
= term_get_fkeys_address
;
1330 KBOARD
*kboard
= term_get_fkeys_kboard
;
1332 /* This can happen if CANNOT_DUMP or with strange options. */
1333 if (!KEYMAPP (KVAR (kboard
, Vinput_decode_map
)))
1334 kset_input_decode_map (kboard
, Fmake_sparse_keymap (Qnil
));
1336 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1338 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1340 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (sequence
),
1341 Fmake_vector (make_number (1),
1342 intern (keys
[i
].name
)));
1345 /* The uses of the "k0" capability are inconsistent; sometimes it
1346 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1347 We will attempt to politely accommodate both systems by testing for
1348 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1351 const char *k_semi
= tgetstr ("k;", address
);
1352 const char *k0
= tgetstr ("k0", address
);
1353 const char *k0_name
= "f10";
1358 /* Define f0 first, so that f10 takes precedence in case the
1359 key sequences happens to be the same. */
1360 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (k0
),
1361 Fmake_vector (make_number (1), intern ("f0")));
1362 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (k_semi
),
1363 Fmake_vector (make_number (1), intern ("f10")));
1366 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (k0
),
1367 Fmake_vector (make_number (1), intern (k0_name
)));
1370 /* Set up cookies for numbered function keys above f10. */
1372 char fcap
[3], fkey
[4];
1374 fcap
[0] = 'F'; fcap
[2] = '\0';
1375 for (i
= 11; i
< 64; i
++)
1378 fcap
[1] = '1' + i
- 11;
1380 fcap
[1] = 'A' + i
- 20;
1382 fcap
[1] = 'a' + i
- 46;
1385 char *sequence
= tgetstr (fcap
, address
);
1388 sprintf (fkey
, "f%d", i
);
1389 Fdefine_key (KVAR (kboard
, Vinput_decode_map
), build_string (sequence
),
1390 Fmake_vector (make_number (1),
1398 * Various mappings to try and get a better fit.
1401 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1402 if (!tgetstr (cap1, address)) \
1404 char *sequence = tgetstr (cap2, address); \
1406 Fdefine_key (KVAR (kboard, Vinput_decode_map), build_string (sequence), \
1407 Fmake_vector (make_number (1), \
1411 /* if there's no key_next keycap, map key_npage to `next' keysym */
1412 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1413 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1414 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1415 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1416 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1417 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1418 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1420 /* IBM has their own non-standard dialect of terminfo.
1421 If the standard name isn't found, try the IBM name. */
1422 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1423 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1424 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1425 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1426 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1427 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1428 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1429 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1430 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1431 #undef CONDITIONAL_REASSIGN
1436 #endif /* not DOS_NT */
1439 /***********************************************************************
1440 Character Display Information
1441 ***********************************************************************/
1442 static void append_glyph (struct it
*);
1443 static void append_composite_glyph (struct it
*);
1444 static void produce_composite_glyph (struct it
*);
1445 static void append_glyphless_glyph (struct it
*, int, const char *);
1446 static void produce_glyphless_glyph (struct it
*, int, Lisp_Object
);
1448 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1449 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1450 the character for which to produce glyphs; IT->face_id contains the
1451 character's face. Padding glyphs are appended if IT->c has a
1452 IT->pixel_width > 1. */
1455 append_glyph (struct it
*it
)
1457 struct glyph
*glyph
, *end
;
1460 eassert (it
->glyph_row
);
1461 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1462 + it
->glyph_row
->used
[it
->area
]);
1463 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1465 /* If the glyph row is reversed, we need to prepend the glyph rather
1467 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1470 int move_by
= it
->pixel_width
;
1472 /* Make room for the new glyphs. */
1473 if (move_by
> end
- glyph
) /* don't overstep end of this area */
1474 move_by
= end
- glyph
;
1475 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1477 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1478 end
= glyph
+ move_by
;
1481 /* BIDI Note: we put the glyphs of a "multi-pixel" character left to
1482 right, even in the REVERSED_P case, since (a) all of its u.ch are
1483 identical, and (b) the PADDING_P flag needs to be set for the
1484 leftmost one, because we write to the terminal left-to-right. */
1486 i
< it
->pixel_width
&& glyph
< end
;
1489 glyph
->type
= CHAR_GLYPH
;
1490 glyph
->pixel_width
= 1;
1491 glyph
->u
.ch
= it
->char_to_display
;
1492 glyph
->face_id
= it
->face_id
;
1493 glyph
->padding_p
= i
> 0;
1494 glyph
->charpos
= CHARPOS (it
->position
);
1495 glyph
->object
= it
->object
;
1498 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1499 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1501 glyph
->bidi_type
= it
->bidi_it
.type
;
1505 glyph
->resolved_level
= 0;
1506 glyph
->bidi_type
= UNKNOWN_BT
;
1509 ++it
->glyph_row
->used
[it
->area
];
1514 /* For external use. */
1516 tty_append_glyph (struct it
*it
)
1522 /* Produce glyphs for the display element described by IT. *IT
1523 specifies what we want to produce a glyph for (character, image, ...),
1524 and where in the glyph matrix we currently are (glyph row and hpos).
1525 produce_glyphs fills in output fields of *IT with information such as the
1526 pixel width and height of a character, and maybe output actual glyphs at
1527 the same time if IT->glyph_row is non-null. For an overview, see
1528 the explanation in dispextern.h, before the definition of the
1529 display_element_type enumeration.
1531 produce_glyphs also stores the result of glyph width, ascent
1532 etc. computations in *IT.
1534 IT->glyph_row may be null, in which case produce_glyphs does not
1535 actually fill in the glyphs. This is used in the move_* functions
1536 in xdisp.c for text width and height computations.
1538 Callers usually don't call produce_glyphs directly;
1539 instead they use the macro PRODUCE_GLYPHS. */
1542 produce_glyphs (struct it
*it
)
1544 /* If a hook is installed, let it do the work. */
1546 /* Nothing but characters are supported on terminal frames. */
1547 eassert (it
->what
== IT_CHARACTER
1548 || it
->what
== IT_COMPOSITION
1549 || it
->what
== IT_STRETCH
1550 || it
->what
== IT_GLYPHLESS
);
1552 if (it
->what
== IT_STRETCH
)
1554 produce_stretch_glyph (it
);
1558 if (it
->what
== IT_COMPOSITION
)
1560 produce_composite_glyph (it
);
1564 if (it
->what
== IT_GLYPHLESS
)
1566 produce_glyphless_glyph (it
, 0, Qnil
);
1570 if (it
->char_to_display
>= 040 && it
->char_to_display
< 0177)
1572 it
->pixel_width
= it
->nglyphs
= 1;
1576 else if (it
->char_to_display
== '\n')
1577 it
->pixel_width
= it
->nglyphs
= 0;
1578 else if (it
->char_to_display
== '\t')
1580 int absolute_x
= (it
->current_x
1581 + it
->continuation_lines_width
);
1583 = (((1 + absolute_x
+ it
->tab_width
- 1)
1588 /* If part of the TAB has been displayed on the previous line
1589 which is continued now, continuation_lines_width will have
1590 been incremented already by the part that fitted on the
1591 continued line. So, we will get the right number of spaces
1593 nspaces
= next_tab_x
- absolute_x
;
1599 it
->char_to_display
= ' ';
1600 it
->pixel_width
= it
->len
= 1;
1606 it
->pixel_width
= nspaces
;
1607 it
->nglyphs
= nspaces
;
1609 else if (CHAR_BYTE8_P (it
->char_to_display
))
1611 /* Coming here means that we must send the raw 8-bit byte as is
1612 to the terminal. Although there's no way to know how many
1613 columns it occupies on a screen, it is a good assumption that
1614 a single byte code has 1-column width. */
1615 it
->pixel_width
= it
->nglyphs
= 1;
1621 Lisp_Object charset_list
= FRAME_TERMINAL (it
->f
)->charset_list
;
1623 if (char_charset (it
->char_to_display
, charset_list
, NULL
))
1625 it
->pixel_width
= CHAR_WIDTH (it
->char_to_display
);
1626 it
->nglyphs
= it
->pixel_width
;
1632 Lisp_Object acronym
= lookup_glyphless_char_display (-1, it
);
1634 eassert (it
->what
== IT_GLYPHLESS
);
1635 produce_glyphless_glyph (it
, 1, acronym
);
1640 /* Advance current_x by the pixel width as a convenience for
1642 if (it
->area
== TEXT_AREA
)
1643 it
->current_x
+= it
->pixel_width
;
1644 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1645 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1648 /* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
1649 Called from produce_composite_glyph for terminal frames if
1650 IT->glyph_row != NULL. IT->face_id contains the character's
1654 append_composite_glyph (struct it
*it
)
1656 struct glyph
*glyph
;
1658 eassert (it
->glyph_row
);
1659 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1660 if (glyph
< it
->glyph_row
->glyphs
[1 + it
->area
])
1662 /* If the glyph row is reversed, we need to prepend the glyph
1663 rather than append it. */
1664 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1668 /* Make room for the new glyph. */
1669 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1671 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1673 glyph
->type
= COMPOSITE_GLYPH
;
1674 glyph
->pixel_width
= it
->pixel_width
;
1675 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1676 if (it
->cmp_it
.ch
< 0)
1678 glyph
->u
.cmp
.automatic
= 0;
1679 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1683 glyph
->u
.cmp
.automatic
= 1;
1684 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1685 glyph
->slice
.cmp
.from
= it
->cmp_it
.from
;
1686 glyph
->slice
.cmp
.to
= it
->cmp_it
.to
- 1;
1689 glyph
->face_id
= it
->face_id
;
1690 glyph
->padding_p
= 0;
1691 glyph
->charpos
= CHARPOS (it
->position
);
1692 glyph
->object
= it
->object
;
1695 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1696 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1698 glyph
->bidi_type
= it
->bidi_it
.type
;
1702 glyph
->resolved_level
= 0;
1703 glyph
->bidi_type
= UNKNOWN_BT
;
1706 ++it
->glyph_row
->used
[it
->area
];
1712 /* Produce a composite glyph for iterator IT. IT->cmp_id is the ID of
1713 the composition. We simply produces components of the composition
1714 assuming that the terminal has a capability to layout/render it
1718 produce_composite_glyph (struct it
*it
)
1720 if (it
->cmp_it
.ch
< 0)
1722 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
1724 it
->pixel_width
= cmp
->width
;
1728 Lisp_Object gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
1730 it
->pixel_width
= composition_gstring_width (gstring
, it
->cmp_it
.from
,
1731 it
->cmp_it
.to
, NULL
);
1735 append_composite_glyph (it
);
1739 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
1740 is a face ID to be used for the glyph. What is actually appended
1741 are glyphs of type CHAR_GLYPH whose characters are in STR (which
1742 comes from it->nglyphs bytes). */
1745 append_glyphless_glyph (struct it
*it
, int face_id
, const char *str
)
1747 struct glyph
*glyph
, *end
;
1750 eassert (it
->glyph_row
);
1751 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1752 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1754 /* If the glyph row is reversed, we need to prepend the glyph rather
1756 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1759 int move_by
= it
->pixel_width
;
1761 /* Make room for the new glyphs. */
1762 if (move_by
> end
- glyph
) /* don't overstep end of this area */
1763 move_by
= end
- glyph
;
1764 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1766 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1767 end
= glyph
+ move_by
;
1772 glyph
->type
= CHAR_GLYPH
;
1773 glyph
->pixel_width
= 1;
1774 glyph
->face_id
= face_id
;
1775 glyph
->padding_p
= 0;
1776 glyph
->charpos
= CHARPOS (it
->position
);
1777 glyph
->object
= it
->object
;
1780 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1781 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1783 glyph
->bidi_type
= it
->bidi_it
.type
;
1787 glyph
->resolved_level
= 0;
1788 glyph
->bidi_type
= UNKNOWN_BT
;
1791 /* BIDI Note: we put the glyphs of characters left to right, even in
1792 the REVERSED_P case because we write to the terminal
1794 for (i
= 0; i
< it
->nglyphs
&& glyph
< end
; ++i
)
1797 glyph
[0] = glyph
[-1];
1798 glyph
->u
.ch
= str
[i
];
1799 ++it
->glyph_row
->used
[it
->area
];
1804 /* Produce glyphs for a glyphless character for iterator IT.
1805 IT->glyphless_method specifies which method to use for displaying
1806 the character. See the description of enum
1807 glyphless_display_method in dispextern.h for the details.
1809 FOR_NO_FONT is nonzero if and only if this is for a character that
1810 is not supported by the coding system of the terminal. ACRONYM, if
1811 non-nil, is an acronym string for the character.
1813 The glyphs actually produced are of type CHAR_GLYPH. */
1816 produce_glyphless_glyph (struct it
*it
, int for_no_font
, Lisp_Object acronym
)
1820 char buf
[sizeof "\\x" + max (6, (sizeof it
->c
* CHAR_BIT
+ 3) / 4)];
1821 char const *str
= " ";
1823 /* Get a face ID for the glyph by utilizing a cache (the same way as
1824 done for `escape-glyph' in get_next_display_element). */
1825 if (it
->f
== last_glyphless_glyph_frame
1826 && it
->face_id
== last_glyphless_glyph_face_id
)
1828 face_id
= last_glyphless_glyph_merged_face_id
;
1832 /* Merge the `glyphless-char' face into the current face. */
1833 face_id
= merge_faces (it
->f
, Qglyphless_char
, 0, it
->face_id
);
1834 last_glyphless_glyph_frame
= it
->f
;
1835 last_glyphless_glyph_face_id
= it
->face_id
;
1836 last_glyphless_glyph_merged_face_id
= face_id
;
1839 if (it
->glyphless_method
== GLYPHLESS_DISPLAY_THIN_SPACE
)
1841 /* As there's no way to produce a thin space, we produce a space
1842 of canonical width. */
1845 else if (it
->glyphless_method
== GLYPHLESS_DISPLAY_EMPTY_BOX
)
1847 len
= CHAR_WIDTH (it
->c
);
1852 len
= sprintf (buf
, "[%.*s]", len
, str
);
1857 if (it
->glyphless_method
== GLYPHLESS_DISPLAY_ACRONYM
)
1859 if (! STRINGP (acronym
) && CHAR_TABLE_P (Vglyphless_char_display
))
1860 acronym
= CHAR_TABLE_REF (Vglyphless_char_display
, it
->c
);
1861 if (CONSP (acronym
))
1862 acronym
= XCDR (acronym
);
1864 str
= STRINGP (acronym
) ? SSDATA (acronym
) : "";
1865 for (len
= 0; len
< 6 && str
[len
] && ASCII_BYTE_P (str
[len
]); len
++)
1866 buf
[1 + len
] = str
[len
];
1872 eassert (it
->glyphless_method
== GLYPHLESS_DISPLAY_HEX_CODE
);
1873 len
= (it
->c
< 0x10000 ? sprintf (buf
, "\\u%04X", it
->c
)
1874 : it
->c
<= MAX_UNICODE_CHAR
? sprintf (buf
, "\\U%06X", it
->c
)
1875 : sprintf (buf
, "\\x%06X", it
->c
));
1880 it
->pixel_width
= len
;
1883 append_glyphless_glyph (it
, face_id
, str
);
1887 /***********************************************************************
1889 ***********************************************************************/
1891 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1892 one of the enumerators from enum no_color_bit, or a bit set built
1893 from them. Some display attributes may not be used together with
1894 color; the termcap capability `NC' specifies which ones. */
1896 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1897 (tty->TN_max_colors > 0 \
1898 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1901 /* Turn appearances of face FACE_ID on tty frame F on.
1902 FACE_ID is a realized face ID number, in the face cache. */
1905 turn_on_face (struct frame
*f
, int face_id
)
1907 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1908 long fg
= face
->foreground
;
1909 long bg
= face
->background
;
1910 struct tty_display_info
*tty
= FRAME_TTY (f
);
1912 /* Do this first because TS_end_standout_mode may be the same
1913 as TS_exit_attribute_mode, which turns all appearances off. */
1914 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1916 if (tty
->TN_max_colors
> 0)
1918 if (fg
>= 0 && bg
>= 0)
1920 /* If the terminal supports colors, we can set them
1921 below without using reverse video. The face's fg
1922 and bg colors are set as they should appear on
1923 the screen, i.e. they take the inverse-video'ness
1924 of the face already into account. */
1926 else if (inverse_video
)
1928 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1929 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1930 tty_toggle_highlight (tty
);
1934 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1935 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1936 tty_toggle_highlight (tty
);
1941 /* If we can't display colors, use reverse video
1942 if the face specifies that. */
1945 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1946 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1947 tty_toggle_highlight (tty
);
1951 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1952 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1953 tty_toggle_highlight (tty
);
1958 if (face
->tty_bold_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1959 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1961 if (face
->tty_italic_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_ITALIC
))
1963 if (tty
->TS_enter_italic_mode
)
1964 OUTPUT1 (tty
, tty
->TS_enter_italic_mode
);
1966 /* Italics mode is unavailable on many terminals. In that
1967 case, map slant to dimmed text; we want italic text to
1968 appear different and dimming is not otherwise used. */
1969 OUTPUT1 (tty
, tty
->TS_enter_dim_mode
);
1972 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1973 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1975 if (tty
->TN_max_colors
> 0)
1980 ts
= tty
->standout_mode
? tty
->TS_set_background
: tty
->TS_set_foreground
;
1983 p
= tparam (ts
, NULL
, 0, (int) fg
, 0, 0, 0);
1988 ts
= tty
->standout_mode
? tty
->TS_set_foreground
: tty
->TS_set_background
;
1991 p
= tparam (ts
, NULL
, 0, (int) bg
, 0, 0, 0);
1999 /* Turn off appearances of face FACE_ID on tty frame F. */
2002 turn_off_face (struct frame
*f
, int face_id
)
2004 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2005 struct tty_display_info
*tty
= FRAME_TTY (f
);
2007 eassert (face
!= NULL
);
2009 if (tty
->TS_exit_attribute_mode
)
2011 /* Capability "me" will turn off appearance modes double-bright,
2012 half-bright, reverse-video, standout, underline. It may or
2013 may not turn off alt-char-mode. */
2014 if (face
->tty_bold_p
2015 || face
->tty_italic_p
2016 || face
->tty_reverse_p
2017 || face
->tty_underline_p
)
2019 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
2020 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
2021 tty
->standout_mode
= 0;
2026 /* If we don't have "me" we can only have those appearances
2027 that have exit sequences defined. */
2028 if (face
->tty_underline_p
)
2029 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
2032 /* Switch back to default colors. */
2033 if (tty
->TN_max_colors
> 0
2034 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2035 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2036 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2037 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2038 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
2042 /* Return non-zero if the terminal on frame F supports all of the
2043 capabilities in CAPS simultaneously, with foreground and background
2044 colors FG and BG. */
2047 tty_capable_p (struct tty_display_info
*tty
, unsigned int caps
,
2048 unsigned long fg
, unsigned long bg
)
2050 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
2051 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
2054 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
2055 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
2056 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
2057 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
2058 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ITALIC
, tty
->TS_enter_italic_mode
, NC_ITALIC
);
2064 /* Return non-zero if the terminal is capable to display colors. */
2066 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2068 doc
: /* Return non-nil if the tty device TERMINAL can display colors.
2070 TERMINAL can be a terminal object, a frame, or nil (meaning the
2071 selected frame's terminal). This function always returns nil if
2072 TERMINAL does not refer to a text terminal. */)
2073 (Lisp_Object terminal
)
2075 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2079 return t
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
2082 /* Return the number of supported colors. */
2083 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2084 Stty_display_color_cells
, 0, 1, 0,
2085 doc
: /* Return the number of colors supported by the tty device TERMINAL.
2087 TERMINAL can be a terminal object, a frame, or nil (meaning the
2088 selected frame's terminal). This function always returns 0 if
2089 TERMINAL does not refer to a text terminal. */)
2090 (Lisp_Object terminal
)
2092 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2094 return make_number (0);
2096 return make_number (t
->display_info
.tty
->TN_max_colors
);
2101 /* Declare here rather than in the function, as in the rest of Emacs,
2102 to work around an HPUX compiler bug (?). See
2103 http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00410.html */
2104 static int default_max_colors
;
2105 static int default_max_pairs
;
2106 static int default_no_color_video
;
2107 static char *default_orig_pair
;
2108 static char *default_set_foreground
;
2109 static char *default_set_background
;
2111 /* Save or restore the default color-related capabilities of this
2114 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
2119 xfree (default_orig_pair
);
2120 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
2122 xfree (default_set_foreground
);
2123 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
2126 xfree (default_set_background
);
2127 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
2130 default_max_colors
= tty
->TN_max_colors
;
2131 default_max_pairs
= tty
->TN_max_pairs
;
2132 default_no_color_video
= tty
->TN_no_color_video
;
2136 tty
->TS_orig_pair
= default_orig_pair
;
2137 tty
->TS_set_foreground
= default_set_foreground
;
2138 tty
->TS_set_background
= default_set_background
;
2139 tty
->TN_max_colors
= default_max_colors
;
2140 tty
->TN_max_pairs
= default_max_pairs
;
2141 tty
->TN_no_color_video
= default_no_color_video
;
2145 /* Setup one of the standard tty color schemes according to MODE.
2146 MODE's value is generally the number of colors which we want to
2147 support; zero means set up for the default capabilities, the ones
2148 we saw at init_tty time; -1 means turn off color support. */
2150 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2152 /* Canonicalize all negative values of MODE. */
2158 case -1: /* no colors at all */
2159 tty
->TN_max_colors
= 0;
2160 tty
->TN_max_pairs
= 0;
2161 tty
->TN_no_color_video
= 0;
2162 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2164 case 0: /* default colors, if any */
2166 tty_default_color_capabilities (tty
, 0);
2168 case 8: /* 8 standard ANSI colors */
2169 tty
->TS_orig_pair
= "\033[0m";
2171 tty
->TS_set_foreground
= "\033[3%p1%dm";
2172 tty
->TS_set_background
= "\033[4%p1%dm";
2174 tty
->TS_set_foreground
= "\033[3%dm";
2175 tty
->TS_set_background
= "\033[4%dm";
2177 tty
->TN_max_colors
= 8;
2178 tty
->TN_max_pairs
= 64;
2179 tty
->TN_no_color_video
= 0;
2185 set_tty_color_mode (struct tty_display_info
*tty
, struct frame
*f
)
2187 Lisp_Object tem
, val
;
2188 Lisp_Object color_mode
;
2190 Lisp_Object tty_color_mode_alist
2191 = Fintern_soft (build_string ("tty-color-mode-alist"), Qnil
);
2193 tem
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2194 val
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2198 else if (SYMBOLP (tty_color_mode_alist
))
2200 tem
= Fassq (val
, Fsymbol_value (tty_color_mode_alist
));
2201 color_mode
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2206 mode
= TYPE_RANGED_INTEGERP (int, color_mode
) ? XINT (color_mode
) : 0;
2208 if (mode
!= tty
->previous_color_mode
)
2210 tty
->previous_color_mode
= mode
;
2211 tty_setup_colors (tty
, mode
);
2212 /* This recomputes all the faces given the new color definitions. */
2213 safe_call (1, intern ("tty-set-up-initial-frame-faces"));
2217 #endif /* !DOS_NT */
2221 /* Return the tty display object specified by TERMINAL. */
2223 static struct terminal
*
2224 get_tty_terminal (Lisp_Object terminal
, int throw)
2226 struct terminal
*t
= get_terminal (terminal
, throw);
2228 if (t
&& t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2231 error ("Device %d is not a termcap terminal device", t
->id
);
2239 /* Return an active termcap device that uses the tty device with the
2242 This function ignores suspended devices.
2244 Returns NULL if the named terminal device is not opened. */
2247 get_named_tty (const char *name
)
2254 for (t
= terminal_list
; t
; t
= t
->next_terminal
)
2256 if ((t
->type
== output_termcap
|| t
->type
== output_msdos_raw
)
2257 && !strcmp (t
->display_info
.tty
->name
, name
)
2258 && TERMINAL_ACTIVE_P (t
))
2266 DEFUN ("tty-type", Ftty_type
, Stty_type
, 0, 1, 0,
2267 doc
: /* Return the type of the tty device that TERMINAL uses.
2268 Returns nil if TERMINAL is not on a tty device.
2270 TERMINAL can be a terminal object, a frame, or nil (meaning the
2271 selected frame's terminal). */)
2272 (Lisp_Object terminal
)
2274 struct terminal
*t
= get_terminal (terminal
, 1);
2276 if (t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2279 if (t
->display_info
.tty
->type
)
2280 return build_string (t
->display_info
.tty
->type
);
2285 DEFUN ("controlling-tty-p", Fcontrolling_tty_p
, Scontrolling_tty_p
, 0, 1, 0,
2286 doc
: /* Return non-nil if TERMINAL is the controlling tty of the Emacs process.
2288 TERMINAL can be a terminal object, a frame, or nil (meaning the
2289 selected frame's terminal). This function always returns nil if
2290 TERMINAL is not on a tty device. */)
2291 (Lisp_Object terminal
)
2293 struct terminal
*t
= get_terminal (terminal
, 1);
2295 if ((t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2296 || strcmp (t
->display_info
.tty
->name
, DEV_TTY
) != 0)
2302 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 1, 0,
2303 doc
: /* Declare that the tty used by TERMINAL does not handle underlining.
2304 This is used to override the terminfo data, for certain terminals that
2305 do not really do underlining, but say that they do. This function has
2306 no effect if used on a non-tty terminal.
2308 TERMINAL can be a terminal object, a frame or nil (meaning the
2309 selected frame's terminal). This function always returns nil if
2310 TERMINAL does not refer to a text terminal. */)
2311 (Lisp_Object terminal
)
2313 struct terminal
*t
= get_terminal (terminal
, 1);
2315 if (t
->type
== output_termcap
)
2316 t
->display_info
.tty
->TS_enter_underline_mode
= 0;
2320 DEFUN ("tty-top-frame", Ftty_top_frame
, Stty_top_frame
, 0, 1, 0,
2321 doc
: /* Return the topmost terminal frame on TERMINAL.
2322 TERMINAL can be a terminal object, a frame or nil (meaning the
2323 selected frame's terminal). This function returns nil if TERMINAL
2324 does not refer to a text terminal. Otherwise, it returns the
2325 top-most frame on the text terminal. */)
2326 (Lisp_Object terminal
)
2328 struct terminal
*t
= get_terminal (terminal
, 1);
2330 if (t
->type
== output_termcap
)
2331 return t
->display_info
.tty
->top_frame
;
2337 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
2338 doc
: /* Suspend the terminal device TTY.
2340 The device is restored to its default state, and Emacs ceases all
2341 access to the tty device. Frames that use the device are not deleted,
2342 but input is not read from them and if they change, their display is
2345 TTY may be a terminal object, a frame, or nil for the terminal device
2346 of the currently selected frame.
2348 This function runs `suspend-tty-functions' after suspending the
2349 device. The functions are run with one arg, the id of the suspended
2352 `suspend-tty' does nothing if it is called on a device that is already
2355 A suspended tty may be resumed by calling `resume-tty' on it. */)
2358 struct terminal
*t
= get_tty_terminal (tty
, 1);
2362 error ("Unknown tty device");
2364 f
= t
->display_info
.tty
->input
;
2368 /* First run `suspend-tty-functions' and then clean up the tty
2369 state because `suspend-tty-functions' might need to change
2371 Lisp_Object args
[2];
2372 args
[0] = intern ("suspend-tty-functions");
2373 XSETTERMINAL (args
[1], t
);
2374 Frun_hook_with_args (2, args
);
2376 reset_sys_modes (t
->display_info
.tty
);
2377 delete_keyboard_wait_descriptor (fileno (f
));
2381 if (f
!= t
->display_info
.tty
->output
)
2382 fclose (t
->display_info
.tty
->output
);
2385 t
->display_info
.tty
->input
= 0;
2386 t
->display_info
.tty
->output
= 0;
2388 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2389 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 0);
2393 /* Clear display hooks to prevent further output. */
2394 clear_tty_hooks (t
);
2399 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
2400 doc
: /* Resume the previously suspended terminal device TTY.
2401 The terminal is opened and reinitialized. Frames that are on the
2402 suspended terminal are revived.
2404 It is an error to resume a terminal while another terminal is active
2407 This function runs `resume-tty-functions' after resuming the terminal.
2408 The functions are run with one arg, the id of the resumed terminal
2411 `resume-tty' does nothing if it is called on a device that is not
2414 TTY may be a terminal object, a frame, or nil (meaning the selected
2415 frame's terminal). */)
2418 struct terminal
*t
= get_tty_terminal (tty
, 1);
2422 error ("Unknown tty device");
2424 if (!t
->display_info
.tty
->input
)
2426 if (get_named_tty (t
->display_info
.tty
->name
))
2427 error ("Cannot resume display while another display is active on the same device");
2430 t
->display_info
.tty
->output
= stdout
;
2431 t
->display_info
.tty
->input
= stdin
;
2433 fd
= emacs_open (t
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
2436 error ("Can not reopen tty device %s: %s", t
->display_info
.tty
->name
, strerror (errno
));
2438 if (strcmp (t
->display_info
.tty
->name
, DEV_TTY
))
2439 dissociate_if_controlling_tty (fd
);
2441 t
->display_info
.tty
->output
= fdopen (fd
, "w+");
2442 t
->display_info
.tty
->input
= t
->display_info
.tty
->output
;
2445 add_keyboard_wait_descriptor (fd
);
2447 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2449 struct frame
*f
= XFRAME (t
->display_info
.tty
->top_frame
);
2451 int old_height
= FRAME_COLS (f
);
2452 int old_width
= FRAME_LINES (f
);
2454 /* Check if terminal/window size has changed while the frame
2456 get_tty_size (fileno (t
->display_info
.tty
->input
), &width
, &height
);
2457 if (width
!= old_width
|| height
!= old_height
)
2458 change_frame_size (f
, height
, width
, 0, 0, 0);
2459 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 1);
2463 init_sys_modes (t
->display_info
.tty
);
2466 /* Run `resume-tty-functions'. */
2467 Lisp_Object args
[2];
2468 args
[0] = intern ("resume-tty-functions");
2469 XSETTERMINAL (args
[1], t
);
2470 Frun_hook_with_args (2, args
);
2480 /***********************************************************************
2482 ***********************************************************************/
2486 #ifndef HAVE_WINDOW_SYSTEM
2488 term_mouse_moveto (int x
, int y
)
2490 /* TODO: how to set mouse position?
2493 name = (const char *) ttyname (0);
2494 fd = open (name, O_WRONLY);
2495 SOME_FUNCTION (x, y, fd);
2498 last_mouse_y = y; */
2500 #endif /* HAVE_WINDOW_SYSTEM */
2502 /* Implementation of draw_row_with_mouse_face for TTY/GPM. */
2504 tty_draw_row_with_mouse_face (struct window
*w
, struct glyph_row
*row
,
2505 int start_hpos
, int end_hpos
,
2506 enum draw_glyphs_face draw
)
2508 int nglyphs
= end_hpos
- start_hpos
;
2509 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
2510 struct tty_display_info
*tty
= FRAME_TTY (f
);
2511 int face_id
= tty
->mouse_highlight
.mouse_face_face_id
;
2512 int save_x
, save_y
, pos_x
, pos_y
;
2514 if (end_hpos
>= row
->used
[TEXT_AREA
])
2515 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2517 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2518 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
+ WINDOW_LEFT_EDGE_X (w
);
2520 /* Save current cursor co-ordinates. */
2521 save_y
= curY (tty
);
2522 save_x
= curX (tty
);
2523 cursor_to (f
, pos_y
, pos_x
);
2525 if (draw
== DRAW_MOUSE_FACE
)
2526 tty_write_glyphs_with_face (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
,
2528 else if (draw
== DRAW_NORMAL_TEXT
)
2529 write_glyphs (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2531 cursor_to (f
, save_y
, save_x
);
2535 term_mouse_movement (FRAME_PTR frame
, Gpm_Event
*event
)
2537 /* Has the mouse moved off the glyph it was on at the last sighting? */
2538 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2540 frame
->mouse_moved
= 1;
2541 note_mouse_highlight (frame
, event
->x
, event
->y
);
2542 /* Remember which glyph we're now on. */
2543 last_mouse_x
= event
->x
;
2544 last_mouse_y
= event
->y
;
2550 /* Return the Time that corresponds to T. Wrap around on overflow. */
2552 timeval_to_Time (struct timeval
const *t
)
2558 ms
= t
->tv_usec
/ 1000;
2562 /* Return the current position of the mouse.
2564 Set *f to the frame the mouse is in, or zero if the mouse is in no
2565 Emacs frame. If it is set to zero, all the other arguments are
2568 Set *bar_window to Qnil, and *x and *y to the column and
2569 row of the character cell the mouse is over.
2571 Set *timeptr to the time the mouse was at the returned position.
2573 This clears mouse_moved until the next motion
2576 term_mouse_position (FRAME_PTR
*fp
, int insist
, Lisp_Object
*bar_window
,
2577 enum scroll_bar_part
*part
, Lisp_Object
*x
,
2578 Lisp_Object
*y
, Time
*timeptr
)
2582 *fp
= SELECTED_FRAME ();
2583 (*fp
)->mouse_moved
= 0;
2588 XSETINT (*x
, last_mouse_x
);
2589 XSETINT (*y
, last_mouse_y
);
2590 gettimeofday(&now
, 0);
2591 *timeptr
= timeval_to_Time (&now
);
2594 /* Prepare a mouse-event in *RESULT for placement in the input queue.
2596 If the event is a button press, then note that we have grabbed
2600 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
2606 result
->kind
= GPM_CLICK_EVENT
;
2607 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
2609 if (event
->buttons
& j
) {
2610 result
->code
= i
; /* button number */
2614 gettimeofday(&now
, 0);
2615 result
->timestamp
= timeval_to_Time (&now
);
2617 if (event
->type
& GPM_UP
)
2618 result
->modifiers
= up_modifier
;
2619 else if (event
->type
& GPM_DOWN
)
2620 result
->modifiers
= down_modifier
;
2622 result
->modifiers
= 0;
2624 if (event
->type
& GPM_SINGLE
)
2625 result
->modifiers
|= click_modifier
;
2627 if (event
->type
& GPM_DOUBLE
)
2628 result
->modifiers
|= double_modifier
;
2630 if (event
->type
& GPM_TRIPLE
)
2631 result
->modifiers
|= triple_modifier
;
2633 if (event
->type
& GPM_DRAG
)
2634 result
->modifiers
|= drag_modifier
;
2636 if (!(event
->type
& (GPM_MOVE
| GPM_DRAG
))) {
2639 if (event
->modifiers
& (1 << 0))
2640 result
->modifiers
|= shift_modifier
;
2643 if (event
->modifiers
& (1 << 2))
2644 result
->modifiers
|= ctrl_modifier
;
2646 /* 1 << KG_ALT || KG_ALTGR */
2647 if (event
->modifiers
& (1 << 3)
2648 || event
->modifiers
& (1 << 1))
2649 result
->modifiers
|= meta_modifier
;
2652 XSETINT (result
->x
, event
->x
);
2653 XSETINT (result
->y
, event
->y
);
2654 XSETFRAME (result
->frame_or_window
, f
);
2660 handle_one_term_event (struct tty_display_info
*tty
, Gpm_Event
*event
, struct input_event
* hold_quit
)
2662 struct frame
*f
= XFRAME (tty
->top_frame
);
2663 struct input_event ie
;
2671 if (event
->type
& (GPM_MOVE
| GPM_DRAG
)) {
2672 previous_help_echo_string
= help_echo_string
;
2673 help_echo_string
= Qnil
;
2675 Gpm_DrawPointer (event
->x
, event
->y
, fileno (tty
->output
));
2677 if (!term_mouse_movement (f
, event
))
2678 help_echo_string
= previous_help_echo_string
;
2680 /* If the contents of the global variable help_echo_string
2681 has changed, generate a HELP_EVENT. */
2682 if (!NILP (help_echo_string
)
2683 || !NILP (previous_help_echo_string
))
2690 term_mouse_click (&ie
, event
, f
);
2694 if (ie
.kind
!= NO_EVENT
)
2696 kbd_buffer_store_event_hold (&ie
, hold_quit
);
2701 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
2706 XSETFRAME (frame
, f
);
2710 gen_help_event (help_echo_string
, frame
, help_echo_window
,
2711 help_echo_object
, help_echo_pos
);
2718 DEFUN ("gpm-mouse-start", Fgpm_mouse_start
, Sgpm_mouse_start
,
2720 doc
: /* Open a connection to Gpm.
2721 Gpm-mouse can only be activated for one tty at a time. */)
2724 struct frame
*f
= SELECTED_FRAME ();
2725 struct tty_display_info
*tty
2726 = ((f
)->output_method
== output_termcap
2727 ? (f
)->terminal
->display_info
.tty
: NULL
);
2728 Gpm_Connect connection
;
2731 error ("Gpm-mouse only works in the GNU/Linux console");
2733 return Qnil
; /* Already activated, nothing to do. */
2735 error ("Gpm-mouse can only be activated for one tty at a time");
2737 connection
.eventMask
= ~0;
2738 connection
.defaultMask
= ~GPM_HARD
;
2739 connection
.maxMod
= ~0;
2740 connection
.minMod
= 0;
2743 if (Gpm_Open (&connection
, 0) < 0)
2744 error ("Gpm-mouse failed to connect to the gpm daemon");
2748 /* `init_sys_modes' arranges for mouse movements sent through gpm_fd
2749 to generate SIGIOs. Apparently we need to call reset_sys_modes
2750 before calling init_sys_modes. */
2751 reset_sys_modes (tty
);
2752 init_sys_modes (tty
);
2753 add_gpm_wait_descriptor (gpm_fd
);
2762 delete_gpm_wait_descriptor (fd
);
2763 while (Gpm_Close()); /* close all the stack */
2767 DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop
, Sgpm_mouse_stop
,
2769 doc
: /* Close a connection to Gpm. */)
2772 struct frame
*f
= SELECTED_FRAME ();
2773 struct tty_display_info
*tty
2774 = ((f
)->output_method
== output_termcap
2775 ? (f
)->terminal
->display_info
.tty
: NULL
);
2777 if (!tty
|| gpm_tty
!= tty
)
2778 return Qnil
; /* Not activated on this terminal, nothing to do. */
2783 #endif /* HAVE_GPM */
2787 /***********************************************************************
2789 ***********************************************************************/
2791 /* Initialize the tty-dependent part of frame F. The frame must
2792 already have its device initialized. */
2795 create_tty_output (struct frame
*f
)
2797 struct tty_output
*t
= xzalloc (sizeof *t
);
2799 if (! FRAME_TERMCAP_P (f
))
2802 t
->display_info
= FRAME_TERMINAL (f
)->display_info
.tty
;
2804 f
->output_data
.tty
= t
;
2807 /* Delete frame F's face cache, and its tty-dependent part. */
2810 tty_free_frame_resources (struct frame
*f
)
2812 if (! FRAME_TERMCAP_P (f
))
2815 if (FRAME_FACE_CACHE (f
))
2816 free_frame_faces (f
);
2818 xfree (f
->output_data
.tty
);
2823 /* Delete frame F's face cache. */
2826 tty_free_frame_resources (struct frame
*f
)
2828 if (! FRAME_TERMCAP_P (f
) && ! FRAME_MSDOS_P (f
))
2831 if (FRAME_FACE_CACHE (f
))
2832 free_frame_faces (f
);
2836 /* Reset the hooks in TERMINAL. */
2839 clear_tty_hooks (struct terminal
*terminal
)
2842 terminal
->cursor_to_hook
= 0;
2843 terminal
->raw_cursor_to_hook
= 0;
2844 terminal
->clear_to_end_hook
= 0;
2845 terminal
->clear_frame_hook
= 0;
2846 terminal
->clear_end_of_line_hook
= 0;
2847 terminal
->ins_del_lines_hook
= 0;
2848 terminal
->insert_glyphs_hook
= 0;
2849 terminal
->write_glyphs_hook
= 0;
2850 terminal
->delete_glyphs_hook
= 0;
2851 terminal
->ring_bell_hook
= 0;
2852 terminal
->reset_terminal_modes_hook
= 0;
2853 terminal
->set_terminal_modes_hook
= 0;
2854 terminal
->update_begin_hook
= 0;
2855 terminal
->update_end_hook
= 0;
2856 terminal
->set_terminal_window_hook
= 0;
2857 terminal
->mouse_position_hook
= 0;
2858 terminal
->frame_rehighlight_hook
= 0;
2859 terminal
->frame_raise_lower_hook
= 0;
2860 terminal
->fullscreen_hook
= 0;
2861 terminal
->set_vertical_scroll_bar_hook
= 0;
2862 terminal
->condemn_scroll_bars_hook
= 0;
2863 terminal
->redeem_scroll_bar_hook
= 0;
2864 terminal
->judge_scroll_bars_hook
= 0;
2865 terminal
->read_socket_hook
= 0;
2866 terminal
->frame_up_to_date_hook
= 0;
2868 /* Leave these two set, or suspended frames are not deleted
2870 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
2871 terminal
->delete_terminal_hook
= &delete_tty
;
2874 /* Initialize hooks in TERMINAL with the values needed for a tty. */
2877 set_tty_hooks (struct terminal
*terminal
)
2879 terminal
->rif
= 0; /* ttys don't support window-based redisplay. */
2881 terminal
->cursor_to_hook
= &tty_cursor_to
;
2882 terminal
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
2884 terminal
->clear_to_end_hook
= &tty_clear_to_end
;
2885 terminal
->clear_frame_hook
= &tty_clear_frame
;
2886 terminal
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
2888 terminal
->ins_del_lines_hook
= &tty_ins_del_lines
;
2890 terminal
->insert_glyphs_hook
= &tty_insert_glyphs
;
2891 terminal
->write_glyphs_hook
= &tty_write_glyphs
;
2892 terminal
->delete_glyphs_hook
= &tty_delete_glyphs
;
2894 terminal
->ring_bell_hook
= &tty_ring_bell
;
2896 terminal
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
2897 terminal
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
2898 terminal
->update_begin_hook
= 0; /* Not needed. */
2899 terminal
->update_end_hook
= &tty_update_end
;
2900 terminal
->set_terminal_window_hook
= &tty_set_terminal_window
;
2902 terminal
->mouse_position_hook
= 0; /* Not needed. */
2903 terminal
->frame_rehighlight_hook
= 0; /* Not needed. */
2904 terminal
->frame_raise_lower_hook
= 0; /* Not needed. */
2906 terminal
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
2907 terminal
->condemn_scroll_bars_hook
= 0; /* Not needed. */
2908 terminal
->redeem_scroll_bar_hook
= 0; /* Not needed. */
2909 terminal
->judge_scroll_bars_hook
= 0; /* Not needed. */
2911 terminal
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
2912 terminal
->frame_up_to_date_hook
= 0; /* Not needed. */
2914 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
2915 terminal
->delete_terminal_hook
= &delete_tty
;
2918 /* Drop the controlling terminal if fd is the same device. */
2920 dissociate_if_controlling_tty (int fd
)
2923 int pgid
= tcgetpgrp (fd
); /* If tcgetpgrp succeeds, fd is the ctty. */
2928 no_controlling_tty
= 1;
2929 #elif defined (CYGWIN)
2931 no_controlling_tty
= 1;
2933 #ifdef TIOCNOTTY /* Try BSD ioctls. */
2935 sigemptyset (&blocked
);
2936 sigaddset (&blocked
, SIGTTOU
);
2937 pthread_sigmask (SIG_BLOCK
, &blocked
, 0);
2938 fd
= emacs_open (DEV_TTY
, O_RDWR
, 0);
2939 if (fd
!= -1 && ioctl (fd
, TIOCNOTTY
, 0) != -1)
2941 no_controlling_tty
= 1;
2945 pthread_sigmask (SIG_UNBLOCK
, &blocked
, 0);
2947 /* Unknown system. */
2949 #endif /* ! TIOCNOTTY */
2952 #endif /* !DOS_NT */
2955 /* Create a termcap display on the tty device with the given name and
2958 If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
2959 Otherwise NAME should be a path to the tty device file,
2962 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
2964 If MUST_SUCCEED is true, then all errors are fatal. */
2967 init_tty (const char *name
, const char *terminal_type
, int must_succeed
)
2970 char **address
= &area
;
2971 int buffer_size
= 4096;
2973 struct tty_display_info
*tty
= NULL
;
2974 struct terminal
*terminal
= NULL
;
2975 int ctty
= 0; /* 1 if asked to open controlling tty. */
2978 maybe_fatal (must_succeed
, 0,
2979 "Unknown terminal type",
2980 "Unknown terminal type");
2984 if (!strcmp (name
, DEV_TTY
))
2987 /* If we already have a terminal on the given device, use that. If
2988 all such terminals are suspended, create a new one instead. */
2989 /* XXX Perhaps this should be made explicit by having init_tty
2990 always create a new terminal and separating terminal and frame
2991 creation on Lisp level. */
2992 terminal
= get_named_tty (name
);
2996 terminal
= create_terminal ();
2999 maybe_fatal (0, 0, "Attempt to create another terminal %s", "",
3002 tty
= &the_only_display_info
;
3004 tty
= xzalloc (sizeof *tty
);
3006 tty
->top_frame
= Qnil
;
3007 tty
->next
= tty_list
;
3010 terminal
->type
= output_termcap
;
3011 terminal
->display_info
.tty
= tty
;
3012 tty
->terminal
= terminal
;
3014 tty
->Wcm
= xmalloc (sizeof *tty
->Wcm
);
3017 encode_terminal_src_size
= 0;
3018 encode_terminal_dst_size
= 0;
3022 set_tty_hooks (terminal
);
3028 #ifdef O_IGNORE_CTTY
3030 /* Open the terminal device. Don't recognize it as our
3031 controlling terminal, and don't make it the controlling tty
3032 if we don't have one at the moment. */
3033 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
3035 #endif /* O_IGNORE_CTTY */
3036 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
3037 defined on Hurd. On other systems, we need to explicitly
3038 dissociate ourselves from the controlling tty when we want to
3039 open a frame on the same terminal. */
3040 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
3042 tty
->name
= xstrdup (name
);
3043 terminal
->name
= xstrdup (name
);
3046 maybe_fatal (must_succeed
, terminal
,
3047 "Could not open file: %s",
3048 "Could not open file: %s",
3053 maybe_fatal (must_succeed
, terminal
,
3054 "Not a tty device: %s",
3055 "Not a tty device: %s",
3059 #ifndef O_IGNORE_CTTY
3061 dissociate_if_controlling_tty (fd
);
3064 file
= fdopen (fd
, "w+");
3069 tty
->type
= xstrdup (terminal_type
);
3071 add_keyboard_wait_descriptor (fileno (tty
->input
));
3075 tty
->termcap_term_buffer
= xmalloc (buffer_size
);
3077 /* On some systems, tgetent tries to access the controlling
3081 sigemptyset (&blocked
);
3082 sigaddset (&blocked
, SIGTTOU
);
3083 pthread_sigmask (SIG_BLOCK
, &blocked
, 0);
3084 status
= tgetent (tty
->termcap_term_buffer
, terminal_type
);
3085 pthread_sigmask (SIG_UNBLOCK
, &blocked
, 0);
3091 maybe_fatal (must_succeed
, terminal
,
3092 "Cannot open terminfo database file",
3093 "Cannot open terminfo database file");
3095 maybe_fatal (must_succeed
, terminal
,
3096 "Cannot open termcap database file",
3097 "Cannot open termcap database file");
3102 maybe_fatal (must_succeed
, terminal
,
3103 "Terminal type %s is not defined",
3104 "Terminal type %s is not defined.\n\
3105 If that is not the actual type of terminal you have,\n\
3106 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3107 `setenv TERM ...') to specify the correct type. It may be necessary\n"
3109 "to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3111 "to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3117 if (strlen (tty
->termcap_term_buffer
) >= buffer_size
)
3119 buffer_size
= strlen (tty
->termcap_term_buffer
);
3121 tty
->termcap_strings_buffer
= area
= xmalloc (buffer_size
);
3122 tty
->TS_ins_line
= tgetstr ("al", address
);
3123 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
3124 tty
->TS_bell
= tgetstr ("bl", address
);
3125 BackTab (tty
) = tgetstr ("bt", address
);
3126 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
3127 tty
->TS_clr_line
= tgetstr ("ce", address
);
3128 tty
->TS_clr_frame
= tgetstr ("cl", address
);
3129 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
3130 AbsPosition (tty
) = tgetstr ("cm", address
);
3131 CR (tty
) = tgetstr ("cr", address
);
3132 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
3133 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
3134 RowPosition (tty
) = tgetstr ("cv", address
);
3135 tty
->TS_del_char
= tgetstr ("dc", address
);
3136 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
3137 tty
->TS_del_line
= tgetstr ("dl", address
);
3138 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
3139 tty
->TS_delete_mode
= tgetstr ("dm", address
);
3140 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
3141 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
3142 Home (tty
) = tgetstr ("ho", address
);
3143 tty
->TS_ins_char
= tgetstr ("ic", address
);
3144 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
3145 tty
->TS_insert_mode
= tgetstr ("im", address
);
3146 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
3147 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
3148 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
3149 LastLine (tty
) = tgetstr ("ll", address
);
3150 Right (tty
) = tgetstr ("nd", address
);
3151 Down (tty
) = tgetstr ("do", address
);
3153 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
3154 if (tgetflag ("bs"))
3155 Left (tty
) = "\b"; /* can't possibly be longer! */
3156 else /* (Actually, "bs" is obsolete...) */
3157 Left (tty
) = tgetstr ("le", address
);
3159 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
3160 tty
->TS_pad_char
= tgetstr ("pc", address
);
3161 tty
->TS_repeat
= tgetstr ("rp", address
);
3162 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
3163 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
3164 tty
->TS_standout_mode
= tgetstr ("so", address
);
3165 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
3166 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
3167 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
3168 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
3169 Up (tty
) = tgetstr ("up", address
);
3170 tty
->TS_visible_bell
= tgetstr ("vb", address
);
3171 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
3172 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
3173 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
3174 tty
->TS_set_window
= tgetstr ("wi", address
);
3176 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
3177 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
3178 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
3179 tty
->TS_enter_italic_mode
= tgetstr ("ZH", address
);
3180 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
3181 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
3182 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3183 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3184 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
3186 MultiUp (tty
) = tgetstr ("UP", address
);
3187 MultiDown (tty
) = tgetstr ("DO", address
);
3188 MultiLeft (tty
) = tgetstr ("LE", address
);
3189 MultiRight (tty
) = tgetstr ("RI", address
);
3191 /* SVr4/ANSI color support. If "op" isn't available, don't support
3192 color because we can't switch back to the default foreground and
3194 tty
->TS_orig_pair
= tgetstr ("op", address
);
3195 if (tty
->TS_orig_pair
)
3197 tty
->TS_set_foreground
= tgetstr ("AF", address
);
3198 tty
->TS_set_background
= tgetstr ("AB", address
);
3199 if (!tty
->TS_set_foreground
)
3202 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
3203 tty
->TS_set_background
= tgetstr ("Sb", address
);
3206 tty
->TN_max_colors
= tgetnum ("Co");
3207 tty
->TN_max_pairs
= tgetnum ("pa");
3209 tty
->TN_no_color_video
= tgetnum ("NC");
3210 if (tty
->TN_no_color_video
== -1)
3211 tty
->TN_no_color_video
= 0;
3214 tty_default_color_capabilities (tty
, 1);
3216 MagicWrap (tty
) = tgetflag ("xn");
3217 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3218 the former flag imply the latter. */
3219 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
3220 terminal
->memory_below_frame
= tgetflag ("db");
3221 tty
->TF_hazeltine
= tgetflag ("hz");
3222 terminal
->must_write_spaces
= tgetflag ("in");
3223 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
3224 tty
->TF_insmode_motion
= tgetflag ("mi");
3225 tty
->TF_standout_motion
= tgetflag ("ms");
3226 tty
->TF_underscore
= tgetflag ("ul");
3227 tty
->TF_teleray
= tgetflag ("xt");
3232 struct frame
*f
= XFRAME (selected_frame
);
3234 initialize_w32_display (terminal
);
3236 FrameRows (tty
) = FRAME_LINES (f
);
3237 FrameCols (tty
) = FRAME_COLS (f
);
3238 tty
->specified_window
= FRAME_LINES (f
);
3240 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
3241 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
3242 terminal
->char_ins_del_ok
= 1;
3248 if (strcmp (terminal_type
, "internal") == 0)
3249 terminal
->type
= output_msdos_raw
;
3250 initialize_msdos_display (terminal
);
3252 get_tty_size (fileno (tty
->input
), &width
, &height
);
3253 FrameCols (tty
) = width
;
3254 FrameRows (tty
) = height
;
3255 terminal
->char_ins_del_ok
= 0;
3256 init_baud_rate (fileno (tty
->input
));
3259 tty
->output
= stdout
;
3261 /* The following two are inaccessible from w32console.c. */
3262 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3263 terminal
->delete_terminal_hook
= &delete_tty
;
3265 tty
->name
= xstrdup (name
);
3266 terminal
->name
= xstrdup (name
);
3267 tty
->type
= xstrdup (terminal_type
);
3269 add_keyboard_wait_descriptor (0);
3271 tty
->delete_in_insert_mode
= 1;
3274 terminal
->scroll_region_ok
= 0;
3276 /* Seems to insert lines when it's not supposed to, messing up the
3277 display. In doing a trace, it didn't seem to be called much, so I
3278 don't think we're losing anything by turning it off. */
3279 terminal
->line_ins_del_ok
= 0;
3281 tty
->TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
3285 terminal
->mouse_position_hook
= term_mouse_position
;
3286 tty
->mouse_highlight
.mouse_face_window
= Qnil
;
3289 terminal
->kboard
= xmalloc (sizeof *terminal
->kboard
);
3290 init_kboard (terminal
->kboard
);
3291 kset_window_system (terminal
->kboard
, Qnil
);
3292 terminal
->kboard
->next_kboard
= all_kboards
;
3293 all_kboards
= terminal
->kboard
;
3294 terminal
->kboard
->reference_count
++;
3295 /* Don't let the initial kboard remain current longer than necessary.
3296 That would cause problems if a file loaded on startup tries to
3297 prompt in the mini-buffer. */
3298 if (current_kboard
== initial_kboard
)
3299 current_kboard
= terminal
->kboard
;
3301 term_get_fkeys (address
, terminal
->kboard
);
3303 /* Get frame size from system, or else from termcap. */
3306 get_tty_size (fileno (tty
->input
), &width
, &height
);
3307 FrameCols (tty
) = width
;
3308 FrameRows (tty
) = height
;
3311 if (FrameCols (tty
) <= 0)
3312 FrameCols (tty
) = tgetnum ("co");
3313 if (FrameRows (tty
) <= 0)
3314 FrameRows (tty
) = tgetnum ("li");
3316 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
3317 maybe_fatal (must_succeed
, terminal
,
3318 "Screen size %dx%d is too small",
3319 "Screen size %dx%d is too small",
3320 FrameCols (tty
), FrameRows (tty
));
3322 TabWidth (tty
) = tgetnum ("tw");
3325 tty
->TS_bell
= "\07";
3327 if (!tty
->TS_fwd_scroll
)
3328 tty
->TS_fwd_scroll
= Down (tty
);
3330 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
3332 if (TabWidth (tty
) < 0)
3335 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3336 and newer termcap doc does not seem to say there is a default.
3337 if (!tty->Wcm->cm_tab)
3338 tty->Wcm->cm_tab = "\t";
3341 /* We don't support standout modes that use `magic cookies', so
3342 turn off any that do. */
3343 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
3345 tty
->TS_standout_mode
= 0;
3346 tty
->TS_end_standout_mode
= 0;
3348 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3350 tty
->TS_enter_underline_mode
= 0;
3351 tty
->TS_exit_underline_mode
= 0;
3354 /* If there's no standout mode, try to use underlining instead. */
3355 if (tty
->TS_standout_mode
== 0)
3357 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
3358 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
3361 /* If no `se' string, try using a `me' string instead.
3362 If that fails, we can't use standout mode at all. */
3363 if (tty
->TS_end_standout_mode
== 0)
3365 char *s
= tgetstr ("me", address
);
3367 tty
->TS_end_standout_mode
= s
;
3369 tty
->TS_standout_mode
= 0;
3372 if (tty
->TF_teleray
)
3374 tty
->Wcm
->cm_tab
= 0;
3375 /* We can't support standout mode, because it uses magic cookies. */
3376 tty
->TS_standout_mode
= 0;
3377 /* But that means we cannot rely on ^M to go to column zero! */
3379 /* LF can't be trusted either -- can alter hpos */
3380 /* if move at column 0 thru a line with TS_standout_mode */
3384 tty
->specified_window
= FrameRows (tty
);
3386 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
3388 maybe_fatal (must_succeed
, terminal
,
3389 "Terminal type \"%s\" is not powerful enough to run Emacs",
3390 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3391 It lacks the ability to position the cursor.\n\
3392 If that is not the actual type of terminal you have,\n\
3393 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3394 `setenv TERM ...') to specify the correct type. It may be necessary\n"
3396 "to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3397 # else /* TERMCAP */
3398 "to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3399 # endif /* TERMINFO */
3403 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
3404 maybe_fatal (must_succeed
, terminal
,
3405 "Could not determine the frame size",
3406 "Could not determine the frame size");
3408 tty
->delete_in_insert_mode
3409 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
3410 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
3412 tty
->se_is_so
= (tty
->TS_standout_mode
3413 && tty
->TS_end_standout_mode
3414 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
3416 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
3418 terminal
->scroll_region_ok
3420 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
3422 terminal
->line_ins_del_ok
3423 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
3424 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
3425 || (terminal
->scroll_region_ok
3426 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
3428 terminal
->char_ins_del_ok
3429 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
3430 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
3431 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
3433 terminal
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
3435 init_baud_rate (fileno (tty
->input
));
3437 #endif /* not DOS_NT */
3439 /* Init system terminal modes (RAW or CBREAK, etc.). */
3440 init_sys_modes (tty
);
3447 vfatal (const char *str
, va_list ap
)
3449 fprintf (stderr
, "emacs: ");
3450 vfprintf (stderr
, str
, ap
);
3451 if (!(strlen (str
) > 0 && str
[strlen (str
) - 1] == '\n'))
3452 fprintf (stderr
, "\n");
3458 /* Auxiliary error-handling function for init_tty.
3459 Delete TERMINAL, then call error or fatal with str1 or str2,
3460 respectively, according to whether MUST_SUCCEED is zero or not. */
3463 maybe_fatal (int must_succeed
, struct terminal
*terminal
,
3464 const char *str1
, const char *str2
, ...)
3467 va_start (ap
, str2
);
3469 delete_tty (terminal
);
3481 fatal (const char *str
, ...)
3491 /* Delete the given tty terminal, closing all frames on it. */
3494 delete_tty (struct terminal
*terminal
)
3496 struct tty_display_info
*tty
;
3498 /* Protect against recursive calls. delete_frame in
3499 delete_terminal calls us back when it deletes our last frame. */
3500 if (!terminal
->name
)
3503 if (terminal
->type
!= output_termcap
)
3506 tty
= terminal
->display_info
.tty
;
3508 if (tty
== tty_list
)
3509 tty_list
= tty
->next
;
3512 struct tty_display_info
*p
;
3513 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
3517 /* This should not happen. */
3520 p
->next
= tty
->next
;
3524 /* reset_sys_modes needs a valid device, so this call needs to be
3525 before delete_terminal. */
3526 reset_sys_modes (tty
);
3528 delete_terminal (terminal
);
3535 delete_keyboard_wait_descriptor (fileno (tty
->input
));
3536 if (tty
->input
!= stdin
)
3537 fclose (tty
->input
);
3539 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
3540 fclose (tty
->output
);
3541 if (tty
->termscript
)
3542 fclose (tty
->termscript
);
3544 xfree (tty
->old_tty
);
3546 xfree (tty
->termcap_strings_buffer
);
3547 xfree (tty
->termcap_term_buffer
);
3555 DEFVAR_BOOL ("system-uses-terminfo", system_uses_terminfo
,
3556 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3557 This variable can be used by terminal emulator packages. */);
3559 system_uses_terminfo
= 1;
3561 system_uses_terminfo
= 0;
3564 DEFVAR_LISP ("suspend-tty-functions", Vsuspend_tty_functions
,
3565 doc
: /* Functions run after suspending a tty.
3566 The functions are run with one argument, the terminal object to be suspended.
3567 See `suspend-tty'. */);
3568 Vsuspend_tty_functions
= Qnil
;
3571 DEFVAR_LISP ("resume-tty-functions", Vresume_tty_functions
,
3572 doc
: /* Functions run after resuming a tty.
3573 The functions are run with one argument, the terminal object that was revived.
3574 See `resume-tty'. */);
3575 Vresume_tty_functions
= Qnil
;
3577 DEFVAR_BOOL ("visible-cursor", visible_cursor
,
3578 doc
: /* Non-nil means to make the cursor very visible.
3579 This only has an effect when running in a text terminal.
3580 What means \"very visible\" is up to your terminal. It may make the cursor
3581 bigger, or it may make it blink, or it may do nothing at all. */);
3584 defsubr (&Stty_display_color_p
);
3585 defsubr (&Stty_display_color_cells
);
3586 defsubr (&Stty_no_underline
);
3587 defsubr (&Stty_type
);
3588 defsubr (&Scontrolling_tty_p
);
3589 defsubr (&Stty_top_frame
);
3590 defsubr (&Ssuspend_tty
);
3591 defsubr (&Sresume_tty
);
3593 defsubr (&Sgpm_mouse_start
);
3594 defsubr (&Sgpm_mouse_stop
);
3595 #endif /* HAVE_GPM */
3598 default_orig_pair
= NULL
;
3599 default_set_foreground
= NULL
;
3600 default_set_background
= NULL
;
3601 #endif /* !DOS_NT */
3603 encode_terminal_src
= NULL
;
3604 encode_terminal_dst
= NULL
;