1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
41 #include "character.h"
44 #include "composite.h"
48 #include "termhooks.h"
49 #include "dispextern.h"
52 #include "blockinput.h"
53 #include "syssignal.h"
55 #include "intervals.h"
58 static int been_here
= -1;
61 /* For now, don't try to include termcap.h. On some systems,
62 configure finds a non-standard termcap.h that the main build
64 extern void tputs (const char *, int, int (*)(int));
65 extern int tgetent (char *, const char *);
66 extern int tgetflag (char *id
);
67 extern int tgetnum (char *id
);
69 char *tparam (char *, char *, int, int, ...);
71 extern char *tgetstr (char *, char **);
86 /* The name of the default console device. */
88 #define DEV_TTY "CONOUT$"
90 #define DEV_TTY "/dev/tty"
93 static void tty_set_scroll_region (struct frame
*f
, int start
, int stop
);
94 static void turn_on_face (struct frame
*, int face_id
);
95 static void turn_off_face (struct frame
*, int face_id
);
96 static void tty_show_cursor (struct tty_display_info
*);
97 static void tty_hide_cursor (struct tty_display_info
*);
98 static void tty_background_highlight (struct tty_display_info
*tty
);
99 static void clear_tty_hooks (struct terminal
*terminal
);
100 static void set_tty_hooks (struct terminal
*terminal
);
101 static void dissociate_if_controlling_tty (int fd
);
102 static void delete_tty (struct terminal
*);
103 static void maybe_fatal (int must_succeed
, struct terminal
*terminal
,
104 const char *str1
, const char *str2
, ...) NO_RETURN
;
105 static void vfatal (const char *str
, va_list ap
) NO_RETURN
;
108 #define OUTPUT(tty, a) \
109 emacs_tputs ((tty), a, \
110 (int) (FRAME_LINES (XFRAME (selected_frame)) \
114 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
115 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
117 #define OUTPUT_IF(tty, a) \
120 emacs_tputs ((tty), a, \
121 (int) (FRAME_LINES (XFRAME (selected_frame)) \
126 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
128 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */
130 static int visible_cursor
;
132 /* Display space properties */
134 /* Functions to call after suspending a tty. */
135 Lisp_Object Vsuspend_tty_functions
;
137 /* Functions to call after resuming a tty. */
138 Lisp_Object Vresume_tty_functions
;
140 /* Chain of all tty device parameters. */
141 struct tty_display_info
*tty_list
;
143 /* Nonzero means no need to redraw the entire frame on resuming a
144 suspended Emacs. This is useful on terminals with multiple
145 pages, where one page is used for Emacs and another for all
147 int no_redraw_on_reenter
;
149 /* Meaning of bits in no_color_video. Each bit set means that the
150 corresponding attribute cannot be combined with colors. */
154 NC_STANDOUT
= 1 << 0,
155 NC_UNDERLINE
= 1 << 1,
162 NC_ALT_CHARSET
= 1 << 8
167 /* The largest frame width in any call to calculate_costs. */
171 /* The largest frame height in any call to calculate_costs. */
175 /* Non-zero if we have dropped our controlling tty and therefore
176 should not open a frame on stdout. */
177 static int no_controlling_tty
;
179 /* Provided for lisp packages. */
181 static int system_uses_terminfo
;
186 #include <sys/fcntl.h>
188 /* The device for which we have enabled gpm support (or NULL). */
189 struct tty_display_info
*gpm_tty
= NULL
;
191 /* Last recorded mouse coordinates. */
192 static int last_mouse_x
, last_mouse_y
;
193 #endif /* HAVE_GPM */
195 /* Ring the bell on a tty. */
198 tty_ring_bell (struct frame
*f
)
200 struct tty_display_info
*tty
= FRAME_TTY (f
);
204 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
205 ? tty
->TS_visible_bell
207 fflush (tty
->output
);
211 /* Set up termcap modes for Emacs. */
214 tty_set_terminal_modes (struct terminal
*terminal
)
216 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
220 if (tty
->TS_termcap_modes
)
221 OUTPUT (tty
, tty
->TS_termcap_modes
);
224 /* Output enough newlines to scroll all the old screen contents
225 off the screen, so it won't be overwritten and lost. */
228 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
232 OUTPUT_IF (tty
, visible_cursor
? tty
->TS_cursor_visible
: tty
->TS_cursor_normal
);
233 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
235 fflush (tty
->output
);
239 /* Reset termcap modes before exiting Emacs. */
242 tty_reset_terminal_modes (struct terminal
*terminal
)
244 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
248 tty_turn_off_highlight (tty
);
249 tty_turn_off_insert (tty
);
250 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
251 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
252 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
253 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
254 /* Output raw CR so kernel can track the cursor hpos. */
257 fflush (tty
->output
);
261 /* Flag the end of a display update on a termcap terminal. */
264 tty_update_end (struct frame
*f
)
266 struct tty_display_info
*tty
= FRAME_TTY (f
);
268 if (!XWINDOW (selected_window
)->cursor_off_p
)
269 tty_show_cursor (tty
);
270 tty_turn_off_insert (tty
);
271 tty_background_highlight (tty
);
274 /* The implementation of set_terminal_window for termcap frames. */
277 tty_set_terminal_window (struct frame
*f
, int size
)
279 struct tty_display_info
*tty
= FRAME_TTY (f
);
281 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
282 if (FRAME_SCROLL_REGION_OK (f
))
283 tty_set_scroll_region (f
, 0, tty
->specified_window
);
287 tty_set_scroll_region (struct frame
*f
, int start
, int stop
)
290 struct tty_display_info
*tty
= FRAME_TTY (f
);
292 if (tty
->TS_set_scroll_region
)
293 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
294 else if (tty
->TS_set_scroll_region_1
)
295 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
296 FRAME_LINES (f
), start
,
297 FRAME_LINES (f
) - stop
,
300 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
309 tty_turn_on_insert (struct tty_display_info
*tty
)
311 if (!tty
->insert_mode
)
312 OUTPUT (tty
, tty
->TS_insert_mode
);
313 tty
->insert_mode
= 1;
317 tty_turn_off_insert (struct tty_display_info
*tty
)
319 if (tty
->insert_mode
)
320 OUTPUT (tty
, tty
->TS_end_insert_mode
);
321 tty
->insert_mode
= 0;
324 /* Handle highlighting. */
327 tty_turn_off_highlight (struct tty_display_info
*tty
)
329 if (tty
->standout_mode
)
330 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
331 tty
->standout_mode
= 0;
335 tty_turn_on_highlight (struct tty_display_info
*tty
)
337 if (!tty
->standout_mode
)
338 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
339 tty
->standout_mode
= 1;
343 tty_toggle_highlight (struct tty_display_info
*tty
)
345 if (tty
->standout_mode
)
346 tty_turn_off_highlight (tty
);
348 tty_turn_on_highlight (tty
);
352 /* Make cursor invisible. */
355 tty_hide_cursor (struct tty_display_info
*tty
)
357 if (tty
->cursor_hidden
== 0)
359 tty
->cursor_hidden
= 1;
360 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
365 /* Ensure that cursor is visible. */
368 tty_show_cursor (struct tty_display_info
*tty
)
370 if (tty
->cursor_hidden
)
372 tty
->cursor_hidden
= 0;
373 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
375 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
380 /* Set standout mode to the state it should be in for
381 empty space inside windows. What this is,
382 depends on the user option inverse-video. */
385 tty_background_highlight (struct tty_display_info
*tty
)
388 tty_turn_on_highlight (tty
);
390 tty_turn_off_highlight (tty
);
393 /* Set standout mode to the mode specified for the text to be output. */
396 tty_highlight_if_desired (struct tty_display_info
*tty
)
399 tty_turn_on_highlight (tty
);
401 tty_turn_off_highlight (tty
);
405 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
406 frame-relative coordinates. */
409 tty_cursor_to (struct frame
*f
, int vpos
, int hpos
)
411 struct tty_display_info
*tty
= FRAME_TTY (f
);
413 /* Detect the case where we are called from reset_sys_modes
414 and the costs have never been calculated. Do nothing. */
415 if (! tty
->costs_set
)
418 if (curY (tty
) == vpos
419 && curX (tty
) == hpos
)
421 if (!tty
->TF_standout_motion
)
422 tty_background_highlight (tty
);
423 if (!tty
->TF_insmode_motion
)
424 tty_turn_off_insert (tty
);
425 cmgoto (tty
, vpos
, hpos
);
428 /* Similar but don't take any account of the wasted characters. */
431 tty_raw_cursor_to (struct frame
*f
, int row
, int col
)
433 struct tty_display_info
*tty
= FRAME_TTY (f
);
435 if (curY (tty
) == row
436 && curX (tty
) == col
)
438 if (!tty
->TF_standout_motion
)
439 tty_background_highlight (tty
);
440 if (!tty
->TF_insmode_motion
)
441 tty_turn_off_insert (tty
);
442 cmgoto (tty
, row
, col
);
445 /* Erase operations */
447 /* Clear from cursor to end of frame on a termcap device. */
450 tty_clear_to_end (struct frame
*f
)
453 struct tty_display_info
*tty
= FRAME_TTY (f
);
455 if (tty
->TS_clr_to_bottom
)
457 tty_background_highlight (tty
);
458 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
462 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
465 clear_end_of_line (f
, FRAME_COLS (f
));
470 /* Clear an entire termcap frame. */
473 tty_clear_frame (struct frame
*f
)
475 struct tty_display_info
*tty
= FRAME_TTY (f
);
477 if (tty
->TS_clr_frame
)
479 tty_background_highlight (tty
);
480 OUTPUT (tty
, tty
->TS_clr_frame
);
490 /* An implementation of clear_end_of_line for termcap frames.
492 Note that the cursor may be moved, on terminals lacking a `ce' string. */
495 tty_clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
498 struct tty_display_info
*tty
= FRAME_TTY (f
);
500 /* Detect the case where we are called from reset_sys_modes
501 and the costs have never been calculated. Do nothing. */
502 if (! tty
->costs_set
)
505 if (curX (tty
) >= first_unused_hpos
)
507 tty_background_highlight (tty
);
508 if (tty
->TS_clr_line
)
510 OUTPUT1 (tty
, tty
->TS_clr_line
);
513 { /* have to do it the hard way */
514 tty_turn_off_insert (tty
);
516 /* Do not write in last row last col with Auto-wrap on. */
518 && curY (tty
) == FrameRows (tty
) - 1
519 && first_unused_hpos
== FrameCols (tty
))
522 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
525 fputc (' ', tty
->termscript
);
526 fputc (' ', tty
->output
);
528 cmplus (tty
, first_unused_hpos
- curX (tty
));
532 /* Buffers to store the source and result of code conversion for terminal. */
533 static unsigned char *encode_terminal_src
;
534 static unsigned char *encode_terminal_dst
;
535 /* Allocated sizes of the above buffers. */
536 static int encode_terminal_src_size
;
537 static int encode_terminal_dst_size
;
539 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
540 Set CODING->produced to the byte-length of the resulting byte
541 sequence, and return a pointer to that byte sequence. */
544 encode_terminal_code (struct glyph
*src
, int src_len
, struct coding_system
*coding
)
546 struct glyph
*src_end
= src
+ src_len
;
548 int nchars
, nbytes
, required
;
549 register int tlen
= GLYPH_TABLE_LENGTH
;
550 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
551 Lisp_Object charset_list
;
553 /* Allocate sufficient size of buffer to store all characters in
554 multibyte-form. But, it may be enlarged on demand if
555 Vglyph_table contains a string or a composite glyph is
557 required
= MAX_MULTIBYTE_LENGTH
* src_len
;
558 if (encode_terminal_src_size
< required
)
560 if (encode_terminal_src
)
561 encode_terminal_src
= xrealloc (encode_terminal_src
, required
);
563 encode_terminal_src
= xmalloc (required
);
564 encode_terminal_src_size
= required
;
567 charset_list
= coding_charset_list (coding
);
569 buf
= encode_terminal_src
;
571 while (src
< src_end
)
573 if (src
->type
== COMPOSITE_GLYPH
)
575 struct composition
*cmp
;
579 nbytes
= buf
- encode_terminal_src
;
580 if (src
->u
.cmp
.automatic
)
582 gstring
= composition_gstring_from_id (src
->u
.cmp
.id
);
583 required
= src
->slice
.cmp
.to
+ 1 - src
->slice
.cmp
.from
;
587 cmp
= composition_table
[src
->u
.cmp
.id
];
588 required
= MAX_MULTIBYTE_LENGTH
* cmp
->glyph_len
;
591 if (encode_terminal_src_size
< nbytes
+ required
)
593 encode_terminal_src_size
= nbytes
+ required
;
594 encode_terminal_src
= xrealloc (encode_terminal_src
,
595 encode_terminal_src_size
);
596 buf
= encode_terminal_src
+ nbytes
;
599 if (src
->u
.cmp
.automatic
)
600 for (i
= src
->slice
.cmp
.from
; i
<= src
->slice
.cmp
.to
; i
++)
602 Lisp_Object g
= LGSTRING_GLYPH (gstring
, i
);
603 int c
= LGLYPH_CHAR (g
);
605 if (! char_charset (c
, charset_list
, NULL
))
607 buf
+= CHAR_STRING (c
, buf
);
611 for (i
= 0; i
< cmp
->glyph_len
; i
++)
613 int c
= COMPOSITION_GLYPH (cmp
, i
);
617 if (char_charset (c
, charset_list
, NULL
))
619 if (CHAR_WIDTH (c
) == 0
620 && i
> 0 && COMPOSITION_GLYPH (cmp
, i
- 1) == '\t')
621 /* Should be left-padded */
623 buf
+= CHAR_STRING (' ', buf
);
629 buf
+= CHAR_STRING (c
, buf
);
633 /* We must skip glyphs to be padded for a wide character. */
634 else if (! CHAR_GLYPH_PADDING_P (*src
))
641 SET_GLYPH_FROM_CHAR_GLYPH (g
, src
[0]);
643 if (GLYPH_INVALID_P (g
) || GLYPH_SIMPLE_P (tbase
, tlen
, g
))
645 /* This glyph doesn't have an entry in Vglyph_table. */
650 /* This glyph has an entry in Vglyph_table,
651 so process any alias before testing for simpleness. */
652 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
654 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
655 /* We set the multi-byte form of a character in G
656 (that should be an ASCII character) at WORKBUF. */
659 /* We have a string in Vglyph_table. */
660 string
= tbase
[GLYPH_CHAR (g
)];
665 nbytes
= buf
- encode_terminal_src
;
666 if (encode_terminal_src_size
< nbytes
+ MAX_MULTIBYTE_LENGTH
)
668 encode_terminal_src_size
= nbytes
+ MAX_MULTIBYTE_LENGTH
;
669 encode_terminal_src
= xrealloc (encode_terminal_src
,
670 encode_terminal_src_size
);
671 buf
= encode_terminal_src
+ nbytes
;
674 || char_charset (c
, charset_list
, NULL
))
676 /* Store the multibyte form of C at BUF. */
677 buf
+= CHAR_STRING (c
, buf
);
682 /* C is not encodable. */
685 while (src
+ 1 < src_end
&& CHAR_GLYPH_PADDING_P (src
[1]))
695 unsigned char *p
= SDATA (string
);
697 if (! STRING_MULTIBYTE (string
))
698 string
= string_to_multibyte (string
);
699 nbytes
= buf
- encode_terminal_src
;
700 if (encode_terminal_src_size
< nbytes
+ SBYTES (string
))
702 encode_terminal_src_size
= nbytes
+ SBYTES (string
);
703 encode_terminal_src
= xrealloc (encode_terminal_src
,
704 encode_terminal_src_size
);
705 buf
= encode_terminal_src
+ nbytes
;
707 memcpy (buf
, SDATA (string
), SBYTES (string
));
708 buf
+= SBYTES (string
);
709 nchars
+= SCHARS (string
);
717 coding
->produced
= 0;
721 nbytes
= buf
- encode_terminal_src
;
722 coding
->source
= encode_terminal_src
;
723 if (encode_terminal_dst_size
== 0)
725 encode_terminal_dst_size
= encode_terminal_src_size
;
726 if (encode_terminal_dst
)
727 encode_terminal_dst
= xrealloc (encode_terminal_dst
,
728 encode_terminal_dst_size
);
730 encode_terminal_dst
= xmalloc (encode_terminal_dst_size
);
732 coding
->destination
= encode_terminal_dst
;
733 coding
->dst_bytes
= encode_terminal_dst_size
;
734 encode_coding_object (coding
, Qnil
, 0, 0, nchars
, nbytes
, Qnil
);
735 /* coding->destination may have been reallocated. */
736 encode_terminal_dst
= coding
->destination
;
737 encode_terminal_dst_size
= coding
->dst_bytes
;
739 return (encode_terminal_dst
);
744 /* An implementation of write_glyphs for termcap frames. */
747 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
749 unsigned char *conversion_buffer
;
750 struct coding_system
*coding
;
752 struct tty_display_info
*tty
= FRAME_TTY (f
);
754 tty_turn_off_insert (tty
);
755 tty_hide_cursor (tty
);
757 /* Don't dare write in last column of bottom line, if Auto-Wrap,
758 since that would scroll the whole frame on some terminals. */
761 && curY (tty
) + 1 == FRAME_LINES (f
)
762 && (curX (tty
) + len
) == FRAME_COLS (f
))
769 /* If terminal_coding does any conversion, use it, otherwise use
770 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
771 because it always return 1 if the member src_multibyte is 1. */
772 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
773 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
774 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
776 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
780 /* Identify a run of glyphs with the same face. */
781 int face_id
= string
->face_id
;
784 for (n
= 1; n
< len
; ++n
)
785 if (string
[n
].face_id
!= face_id
)
788 /* Turn appearance modes of the face of the run on. */
789 tty_highlight_if_desired (tty
);
790 turn_on_face (f
, face_id
);
793 /* This is the last run. */
794 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
795 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
796 if (coding
->produced
> 0)
799 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
800 if (ferror (tty
->output
))
801 clearerr (tty
->output
);
803 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
809 /* Turn appearance modes off. */
810 turn_off_face (f
, face_id
);
811 tty_turn_off_highlight (tty
);
817 #ifdef HAVE_GPM /* Only used by GPM code. */
820 tty_write_glyphs_with_face (register struct frame
*f
, register struct glyph
*string
,
821 register int len
, register int face_id
)
823 unsigned char *conversion_buffer
;
824 struct coding_system
*coding
;
826 struct tty_display_info
*tty
= FRAME_TTY (f
);
828 tty_turn_off_insert (tty
);
829 tty_hide_cursor (tty
);
831 /* Don't dare write in last column of bottom line, if Auto-Wrap,
832 since that would scroll the whole frame on some terminals. */
835 && curY (tty
) + 1 == FRAME_LINES (f
)
836 && (curX (tty
) + len
) == FRAME_COLS (f
))
843 /* If terminal_coding does any conversion, use it, otherwise use
844 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
845 because it always return 1 if the member src_multibyte is 1. */
846 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
847 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
848 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
850 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
852 /* Turn appearance modes of the face. */
853 tty_highlight_if_desired (tty
);
854 turn_on_face (f
, face_id
);
856 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
857 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
858 if (coding
->produced
> 0)
861 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
862 if (ferror (tty
->output
))
863 clearerr (tty
->output
);
865 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
869 /* Turn appearance modes off. */
870 turn_off_face (f
, face_id
);
871 tty_turn_off_highlight (tty
);
877 /* An implementation of insert_glyphs for termcap frames. */
880 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
883 struct glyph
*glyph
= NULL
;
884 unsigned char *conversion_buffer
;
885 unsigned char space
[1];
886 struct coding_system
*coding
;
888 struct tty_display_info
*tty
= FRAME_TTY (f
);
890 if (tty
->TS_ins_multi_chars
)
892 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
896 write_glyphs (f
, start
, len
);
900 tty_turn_on_insert (tty
);
904 space
[0] = SPACEGLYPH
;
906 /* If terminal_coding does any conversion, use it, otherwise use
907 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
908 because it always return 1 if the member src_multibyte is 1. */
909 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
910 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
911 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
913 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
917 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
920 conversion_buffer
= space
;
921 coding
->produced
= 1;
925 tty_highlight_if_desired (tty
);
926 turn_on_face (f
, start
->face_id
);
929 /* We must open sufficient space for a character which
930 occupies more than one column. */
931 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
933 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
938 /* This is the last glyph. */
939 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
941 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
944 if (coding
->produced
> 0)
947 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
948 if (ferror (tty
->output
))
949 clearerr (tty
->output
);
951 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
955 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
958 turn_off_face (f
, glyph
->face_id
);
959 tty_turn_off_highlight (tty
);
966 /* An implementation of delete_glyphs for termcap frames. */
969 tty_delete_glyphs (struct frame
*f
, int n
)
974 struct tty_display_info
*tty
= FRAME_TTY (f
);
976 if (tty
->delete_in_insert_mode
)
978 tty_turn_on_insert (tty
);
982 tty_turn_off_insert (tty
);
983 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
986 if (tty
->TS_del_multi_chars
)
988 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
993 for (i
= 0; i
< n
; i
++)
994 OUTPUT1 (tty
, tty
->TS_del_char
);
995 if (!tty
->delete_in_insert_mode
)
996 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
999 /* An implementation of ins_del_lines for termcap frames. */
1002 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
1004 struct tty_display_info
*tty
= FRAME_TTY (f
);
1005 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
1006 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
1007 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
1009 register int i
= n
> 0 ? n
: -n
;
1012 /* If the lines below the insertion are being pushed
1013 into the end of the window, this is the same as clearing;
1014 and we know the lines are already clear, since the matching
1015 deletion has already been done. So can ignore this. */
1016 /* If the lines below the deletion are blank lines coming
1017 out of the end of the window, don't bother,
1018 as there will be a matching inslines later that will flush them. */
1019 if (FRAME_SCROLL_REGION_OK (f
)
1020 && vpos
+ i
>= tty
->specified_window
)
1022 if (!FRAME_MEMORY_BELOW_FRAME (f
)
1023 && vpos
+ i
>= FRAME_LINES (f
))
1028 raw_cursor_to (f
, vpos
, 0);
1029 tty_background_highlight (tty
);
1030 buf
= tparam (multi
, 0, 0, i
);
1036 raw_cursor_to (f
, vpos
, 0);
1037 tty_background_highlight (tty
);
1039 OUTPUT (tty
, single
);
1040 if (tty
->TF_teleray
)
1045 tty_set_scroll_region (f
, vpos
, tty
->specified_window
);
1047 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
1049 raw_cursor_to (f
, vpos
, 0);
1050 tty_background_highlight (tty
);
1052 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1053 tty_set_scroll_region (f
, 0, tty
->specified_window
);
1056 if (!FRAME_SCROLL_REGION_OK (f
)
1057 && FRAME_MEMORY_BELOW_FRAME (f
)
1060 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
1065 /* Compute cost of sending "str", in characters,
1066 not counting any line-dependent padding. */
1069 string_cost (const char *str
)
1073 tputs (str
, 0, evalcost
);
1077 /* Compute cost of sending "str", in characters,
1078 counting any line-dependent padding at one line. */
1081 string_cost_one_line (const char *str
)
1085 tputs (str
, 1, evalcost
);
1089 /* Compute per line amount of line-dependent padding,
1090 in tenths of characters. */
1093 per_line_cost (const char *str
)
1097 tputs (str
, 0, evalcost
);
1100 tputs (str
, 10, evalcost
);
1104 /* char_ins_del_cost[n] is cost of inserting N characters.
1105 char_ins_del_cost[-n] is cost of deleting N characters.
1106 The length of this vector is based on max_frame_cols. */
1108 int *char_ins_del_vector
;
1110 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1114 calculate_ins_del_char_costs (struct frame
*f
)
1116 struct tty_display_info
*tty
= FRAME_TTY (f
);
1117 int ins_startup_cost
, del_startup_cost
;
1118 int ins_cost_per_char
, del_cost_per_char
;
1122 if (tty
->TS_ins_multi_chars
)
1124 ins_cost_per_char
= 0;
1125 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1127 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1128 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1130 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1131 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1132 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1133 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1137 ins_startup_cost
= 9999;
1138 ins_cost_per_char
= 0;
1141 if (tty
->TS_del_multi_chars
)
1143 del_cost_per_char
= 0;
1144 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1146 else if (tty
->TS_del_char
)
1148 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1149 + string_cost (tty
->TS_end_delete_mode
));
1150 if (tty
->delete_in_insert_mode
)
1151 del_startup_cost
/= 2;
1152 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1156 del_startup_cost
= 9999;
1157 del_cost_per_char
= 0;
1160 /* Delete costs are at negative offsets */
1161 p
= &char_ins_del_cost (f
)[0];
1162 for (i
= FRAME_COLS (f
); --i
>= 0;)
1163 *--p
= (del_startup_cost
+= del_cost_per_char
);
1165 /* Doing nothing is free */
1166 p
= &char_ins_del_cost (f
)[0];
1169 /* Insert costs are at positive offsets */
1170 for (i
= FRAME_COLS (f
); --i
>= 0;)
1171 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1175 calculate_costs (struct frame
*frame
)
1177 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1179 if (FRAME_TERMCAP_P (frame
))
1181 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1182 register char *f
= (tty
->TS_set_scroll_region
1183 ? tty
->TS_set_scroll_region
1184 : tty
->TS_set_scroll_region_1
);
1186 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1190 /* These variables are only used for terminal stuff. They are
1191 allocated once for the terminal frame of X-windows emacs, but not
1194 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1195 X turns off char_ins_del_ok. */
1197 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1198 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1200 if (char_ins_del_vector
!= 0)
1202 = (int *) xrealloc (char_ins_del_vector
,
1204 + 2 * max_frame_cols
* sizeof (int)));
1207 = (int *) xmalloc (sizeof (int)
1208 + 2 * max_frame_cols
* sizeof (int));
1210 memset (char_ins_del_vector
, 0,
1211 (sizeof (int) + 2 * max_frame_cols
* sizeof (int)));
1214 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1215 do_line_insertion_deletion_costs (frame
,
1216 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1217 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1220 do_line_insertion_deletion_costs (frame
,
1221 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1222 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1225 calculate_ins_del_char_costs (frame
);
1227 /* Don't use TS_repeat if its padding is worse than sending the chars */
1228 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1229 tty
->RPov
= string_cost (tty
->TS_repeat
);
1231 tty
->RPov
= FRAME_COLS (frame
) * 2;
1233 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1241 /* Termcap capability names that correspond directly to X keysyms.
1242 Some of these (marked "terminfo") aren't supplied by old-style
1243 (Berkeley) termcap entries. They're listed in X keysym order;
1244 except we put the keypad keys first, so that if they clash with
1245 other keys (as on the IBM PC keyboard) they get overridden.
1248 static const struct fkey_table keys
[] =
1250 {"kh", "home"}, /* termcap */
1251 {"kl", "left"}, /* termcap */
1252 {"ku", "up"}, /* termcap */
1253 {"kr", "right"}, /* termcap */
1254 {"kd", "down"}, /* termcap */
1255 {"%8", "prior"}, /* terminfo */
1256 {"%5", "next"}, /* terminfo */
1257 {"@7", "end"}, /* terminfo */
1258 {"@1", "begin"}, /* terminfo */
1259 {"*6", "select"}, /* terminfo */
1260 {"%9", "print"}, /* terminfo */
1261 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1263 * "insert" --- see below
1265 {"&8", "undo"}, /* terminfo */
1266 {"%0", "redo"}, /* terminfo */
1267 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1268 {"@0", "find"}, /* terminfo */
1269 {"@2", "cancel"}, /* terminfo */
1270 {"%1", "help"}, /* terminfo */
1272 * "break" goes here, but can't be reliably intercepted with termcap
1274 {"&4", "reset"}, /* terminfo --- actually `restart' */
1276 * "system" and "user" --- no termcaps
1278 {"kE", "clearline"}, /* terminfo */
1279 {"kA", "insertline"}, /* terminfo */
1280 {"kL", "deleteline"}, /* terminfo */
1281 {"kI", "insertchar"}, /* terminfo */
1282 {"kD", "deletechar"}, /* terminfo */
1283 {"kB", "backtab"}, /* terminfo */
1285 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1287 {"@8", "kp-enter"}, /* terminfo */
1289 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1290 * "kp-multiply", "kp-add", "kp-separator",
1291 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1292 * --- no termcaps for any of these.
1294 {"K4", "kp-1"}, /* terminfo */
1296 * "kp-2" --- no termcap
1298 {"K5", "kp-3"}, /* terminfo */
1300 * "kp-4" --- no termcap
1302 {"K2", "kp-5"}, /* terminfo */
1304 * "kp-6" --- no termcap
1306 {"K1", "kp-7"}, /* terminfo */
1308 * "kp-8" --- no termcap
1310 {"K3", "kp-9"}, /* terminfo */
1312 * "kp-equal" --- no termcap
1324 {"&0", "S-cancel"}, /*shifted cancel key*/
1325 {"&9", "S-begin"}, /*shifted begin key*/
1326 {"*0", "S-find"}, /*shifted find key*/
1327 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1328 {"*4", "S-delete"}, /*shifted delete-character key*/
1329 {"*7", "S-end"}, /*shifted end key*/
1330 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1331 {"#1", "S-help"}, /*shifted help key*/
1332 {"#2", "S-home"}, /*shifted home key*/
1333 {"#3", "S-insert"}, /*shifted insert-character key*/
1334 {"#4", "S-left"}, /*shifted left-arrow key*/
1335 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1336 {"%c", "S-next"}, /*shifted next key*/
1337 {"%e", "S-prior"}, /*shifted previous key*/
1338 {"%f", "S-print"}, /*shifted print key*/
1339 {"%g", "S-redo"}, /*shifted redo key*/
1340 {"%i", "S-right"}, /*shifted right-arrow key*/
1341 {"!3", "S-undo"} /*shifted undo key*/
1345 static char **term_get_fkeys_address
;
1346 static KBOARD
*term_get_fkeys_kboard
;
1347 static Lisp_Object
term_get_fkeys_1 (void);
1349 /* Find the escape codes sent by the function keys for Vinput_decode_map.
1350 This function scans the termcap function key sequence entries, and
1351 adds entries to Vinput_decode_map for each function key it finds. */
1354 term_get_fkeys (char **address
, KBOARD
*kboard
)
1356 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1357 errors during the call. The only errors should be from Fdefine_key
1358 when given a key sequence containing an invalid prefix key. If the
1359 termcap defines function keys which use a prefix that is already bound
1360 to a command by the default bindings, we should silently ignore that
1361 function key specification, rather than giving the user an error and
1362 refusing to run at all on such a terminal. */
1364 term_get_fkeys_address
= address
;
1365 term_get_fkeys_kboard
= kboard
;
1366 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1370 term_get_fkeys_1 (void)
1374 char **address
= term_get_fkeys_address
;
1375 KBOARD
*kboard
= term_get_fkeys_kboard
;
1377 /* This can happen if CANNOT_DUMP or with strange options. */
1378 if (!KEYMAPP (kboard
->Vinput_decode_map
))
1379 kboard
->Vinput_decode_map
= Fmake_sparse_keymap (Qnil
);
1381 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1383 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1385 Fdefine_key (kboard
->Vinput_decode_map
, build_string (sequence
),
1386 Fmake_vector (make_number (1),
1387 intern (keys
[i
].name
)));
1390 /* The uses of the "k0" capability are inconsistent; sometimes it
1391 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1392 We will attempt to politely accommodate both systems by testing for
1393 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1396 char *k_semi
= tgetstr ("k;", address
);
1397 char *k0
= tgetstr ("k0", address
);
1398 char *k0_name
= "f10";
1403 /* Define f0 first, so that f10 takes precedence in case the
1404 key sequences happens to be the same. */
1405 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k0
),
1406 Fmake_vector (make_number (1), intern ("f0")));
1407 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k_semi
),
1408 Fmake_vector (make_number (1), intern ("f10")));
1411 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k0
),
1412 Fmake_vector (make_number (1), intern (k0_name
)));
1415 /* Set up cookies for numbered function keys above f10. */
1417 char fcap
[3], fkey
[4];
1419 fcap
[0] = 'F'; fcap
[2] = '\0';
1420 for (i
= 11; i
< 64; i
++)
1423 fcap
[1] = '1' + i
- 11;
1425 fcap
[1] = 'A' + i
- 20;
1427 fcap
[1] = 'a' + i
- 46;
1430 char *sequence
= tgetstr (fcap
, address
);
1433 sprintf (fkey
, "f%d", i
);
1434 Fdefine_key (kboard
->Vinput_decode_map
, build_string (sequence
),
1435 Fmake_vector (make_number (1),
1443 * Various mappings to try and get a better fit.
1446 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1447 if (!tgetstr (cap1, address)) \
1449 char *sequence = tgetstr (cap2, address); \
1451 Fdefine_key (kboard->Vinput_decode_map, build_string (sequence), \
1452 Fmake_vector (make_number (1), \
1456 /* if there's no key_next keycap, map key_npage to `next' keysym */
1457 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1458 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1459 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1460 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1461 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1462 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1463 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1465 /* IBM has their own non-standard dialect of terminfo.
1466 If the standard name isn't found, try the IBM name. */
1467 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1468 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1469 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1470 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1471 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1472 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1473 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1474 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1475 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1476 #undef CONDITIONAL_REASSIGN
1481 #endif /* not DOS_NT */
1484 /***********************************************************************
1485 Character Display Information
1486 ***********************************************************************/
1487 static void append_glyph (struct it
*);
1488 static void produce_stretch_glyph (struct it
*);
1489 static void append_composite_glyph (struct it
*);
1490 static void produce_composite_glyph (struct it
*);
1491 static void append_glyphless_glyph (struct it
*, int, char *);
1492 static void produce_glyphless_glyph (struct it
*, int, Lisp_Object
);
1494 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1495 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1496 the character for which to produce glyphs; IT->face_id contains the
1497 character's face. Padding glyphs are appended if IT->c has a
1498 IT->pixel_width > 1. */
1501 append_glyph (struct it
*it
)
1503 struct glyph
*glyph
, *end
;
1506 xassert (it
->glyph_row
);
1507 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1508 + it
->glyph_row
->used
[it
->area
]);
1509 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1511 /* If the glyph row is reversed, we need to prepend the glyph rather
1513 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1516 int move_by
= it
->pixel_width
;
1518 /* Make room for the new glyphs. */
1519 if (move_by
> end
- glyph
) /* don't overstep end of this area */
1520 move_by
= end
- glyph
;
1521 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1523 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1524 end
= glyph
+ move_by
;
1527 /* BIDI Note: we put the glyphs of a "multi-pixel" character left to
1528 right, even in the REVERSED_P case, since (a) all of its u.ch are
1529 identical, and (b) the PADDING_P flag needs to be set for the
1530 leftmost one, because we write to the terminal left-to-right. */
1532 i
< it
->pixel_width
&& glyph
< end
;
1535 glyph
->type
= CHAR_GLYPH
;
1536 glyph
->pixel_width
= 1;
1537 glyph
->u
.ch
= it
->char_to_display
;
1538 glyph
->face_id
= it
->face_id
;
1539 glyph
->padding_p
= i
> 0;
1540 glyph
->charpos
= CHARPOS (it
->position
);
1541 glyph
->object
= it
->object
;
1544 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1545 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1547 glyph
->bidi_type
= it
->bidi_it
.type
;
1551 glyph
->resolved_level
= 0;
1552 glyph
->bidi_type
= UNKNOWN_BT
;
1555 ++it
->glyph_row
->used
[it
->area
];
1560 /* Produce glyphs for the display element described by IT. *IT
1561 specifies what we want to produce a glyph for (character, image, ...),
1562 and where in the glyph matrix we currently are (glyph row and hpos).
1563 produce_glyphs fills in output fields of *IT with information such as the
1564 pixel width and height of a character, and maybe output actual glyphs at
1565 the same time if IT->glyph_row is non-null. For an overview, see
1566 the explanation in dispextern.h, before the definition of the
1567 display_element_type enumeration.
1569 produce_glyphs also stores the result of glyph width, ascent
1570 etc. computations in *IT.
1572 IT->glyph_row may be null, in which case produce_glyphs does not
1573 actually fill in the glyphs. This is used in the move_* functions
1574 in xdisp.c for text width and height computations.
1576 Callers usually don't call produce_glyphs directly;
1577 instead they use the macro PRODUCE_GLYPHS. */
1580 produce_glyphs (struct it
*it
)
1582 /* If a hook is installed, let it do the work. */
1584 /* Nothing but characters are supported on terminal frames. */
1585 xassert (it
->what
== IT_CHARACTER
1586 || it
->what
== IT_COMPOSITION
1587 || it
->what
== IT_STRETCH
);
1589 if (it
->what
== IT_STRETCH
)
1591 produce_stretch_glyph (it
);
1595 if (it
->what
== IT_COMPOSITION
)
1597 produce_composite_glyph (it
);
1601 if (it
->what
== IT_GLYPHLESS
)
1603 produce_glyphless_glyph (it
, 0, Qnil
);
1607 if (it
->char_to_display
>= 040 && it
->char_to_display
< 0177)
1609 it
->pixel_width
= it
->nglyphs
= 1;
1613 else if (it
->char_to_display
== '\n')
1614 it
->pixel_width
= it
->nglyphs
= 0;
1615 else if (it
->char_to_display
== '\t')
1617 int absolute_x
= (it
->current_x
1618 + it
->continuation_lines_width
);
1620 = (((1 + absolute_x
+ it
->tab_width
- 1)
1625 /* If part of the TAB has been displayed on the previous line
1626 which is continued now, continuation_lines_width will have
1627 been incremented already by the part that fitted on the
1628 continued line. So, we will get the right number of spaces
1630 nspaces
= next_tab_x
- absolute_x
;
1636 it
->char_to_display
= ' ';
1637 it
->pixel_width
= it
->len
= 1;
1643 it
->pixel_width
= nspaces
;
1644 it
->nglyphs
= nspaces
;
1646 else if (CHAR_BYTE8_P (it
->char_to_display
))
1648 /* Coming here means that we must send the raw 8-bit byte as is
1649 to the terminal. Although there's no way to know how many
1650 columns it occupies on a screen, it is a good assumption that
1651 a single byte code has 1-column width. */
1652 it
->pixel_width
= it
->nglyphs
= 1;
1658 Lisp_Object charset_list
= FRAME_TERMINAL (it
->f
)->charset_list
;
1660 if (char_charset (it
->char_to_display
, charset_list
, NULL
))
1662 it
->pixel_width
= CHAR_WIDTH (it
->char_to_display
);
1663 it
->nglyphs
= it
->pixel_width
;
1669 Lisp_Object acronym
= lookup_glyphless_char_display (-1, it
);
1671 xassert (it
->what
== IT_GLYPHLESS
);
1672 produce_glyphless_glyph (it
, 1, acronym
);
1677 /* Advance current_x by the pixel width as a convenience for
1679 if (it
->area
== TEXT_AREA
)
1680 it
->current_x
+= it
->pixel_width
;
1681 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1682 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1686 /* Produce a stretch glyph for iterator IT. IT->object is the value
1687 of the glyph property displayed. The value must be a list
1688 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1691 1. `:width WIDTH' specifies that the space should be WIDTH *
1692 canonical char width wide. WIDTH may be an integer or floating
1695 2. `:align-to HPOS' specifies that the space should be wide enough
1696 to reach HPOS, a value in canonical character units. */
1699 produce_stretch_glyph (struct it
*it
)
1701 /* (space :width WIDTH ...) */
1702 Lisp_Object prop
, plist
;
1703 int width
= 0, align_to
= -1;
1704 int zero_width_ok_p
= 0;
1707 /* List should start with `space'. */
1708 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1709 plist
= XCDR (it
->object
);
1711 /* Compute the width of the stretch. */
1712 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1713 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1715 /* Absolute width `:width WIDTH' specified and valid. */
1716 zero_width_ok_p
= 1;
1717 width
= (int)(tem
+ 0.5);
1719 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1720 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1722 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1723 align_to
= (align_to
< 0
1725 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1726 else if (align_to
< 0)
1727 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1728 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1729 zero_width_ok_p
= 1;
1732 /* Nothing specified -> width defaults to canonical char width. */
1733 width
= FRAME_COLUMN_WIDTH (it
->f
);
1735 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1738 if (width
> 0 && it
->line_wrap
!= TRUNCATE
1739 && it
->current_x
+ width
> it
->last_visible_x
)
1740 width
= it
->last_visible_x
- it
->current_x
- 1;
1742 if (width
> 0 && it
->glyph_row
)
1744 Lisp_Object o_object
= it
->object
;
1745 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1748 if (!STRINGP (object
))
1749 object
= it
->w
->buffer
;
1750 it
->object
= object
;
1751 it
->char_to_display
= ' ';
1752 it
->pixel_width
= it
->len
= 1;
1755 it
->object
= o_object
;
1757 it
->pixel_width
= width
;
1758 it
->nglyphs
= width
;
1762 /* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
1763 Called from produce_composite_glyph for terminal frames if
1764 IT->glyph_row != NULL. IT->face_id contains the character's
1768 append_composite_glyph (struct it
*it
)
1770 struct glyph
*glyph
;
1772 xassert (it
->glyph_row
);
1773 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1774 if (glyph
< it
->glyph_row
->glyphs
[1 + it
->area
])
1776 /* If the glyph row is reversed, we need to prepend the glyph
1777 rather than append it. */
1778 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1782 /* Make room for the new glyph. */
1783 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1785 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1787 glyph
->type
= COMPOSITE_GLYPH
;
1788 glyph
->pixel_width
= it
->pixel_width
;
1789 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1790 if (it
->cmp_it
.ch
< 0)
1792 glyph
->u
.cmp
.automatic
= 0;
1793 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1797 glyph
->u
.cmp
.automatic
= 1;
1798 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1799 glyph
->slice
.cmp
.from
= it
->cmp_it
.from
;
1800 glyph
->slice
.cmp
.to
= it
->cmp_it
.to
- 1;
1803 glyph
->face_id
= it
->face_id
;
1804 glyph
->padding_p
= 0;
1805 glyph
->charpos
= CHARPOS (it
->position
);
1806 glyph
->object
= it
->object
;
1809 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1810 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1812 glyph
->bidi_type
= it
->bidi_it
.type
;
1816 glyph
->resolved_level
= 0;
1817 glyph
->bidi_type
= UNKNOWN_BT
;
1820 ++it
->glyph_row
->used
[it
->area
];
1826 /* Produce a composite glyph for iterator IT. IT->cmp_id is the ID of
1827 the composition. We simply produces components of the composition
1828 assuming that the terminal has a capability to layout/render it
1832 produce_composite_glyph (struct it
*it
)
1834 if (it
->cmp_it
.ch
< 0)
1836 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
1838 it
->pixel_width
= cmp
->width
;
1842 Lisp_Object gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
1844 it
->pixel_width
= composition_gstring_width (gstring
, it
->cmp_it
.from
,
1845 it
->cmp_it
.to
, NULL
);
1849 append_composite_glyph (it
);
1853 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
1854 is a face ID to be used for the glyph. What is actually appended
1855 are glyphs of type CHAR_GLYPH whose characters are in STR (which
1856 comes from it->nglyphs bytes). */
1859 append_glyphless_glyph (struct it
*it
, int face_id
, char *str
)
1861 struct glyph
*glyph
, *end
;
1864 xassert (it
->glyph_row
);
1865 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1866 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1868 /* If the glyph row is reversed, we need to prepend the glyph rather
1870 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1873 int move_by
= it
->pixel_width
;
1875 /* Make room for the new glyphs. */
1876 if (move_by
> end
- glyph
) /* don't overstep end of this area */
1877 move_by
= end
- glyph
;
1878 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1880 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1881 end
= glyph
+ move_by
;
1886 glyph
->type
= CHAR_GLYPH
;
1887 glyph
->pixel_width
= 1;
1888 glyph
->face_id
= face_id
;
1889 glyph
->padding_p
= 0;
1890 glyph
->charpos
= CHARPOS (it
->position
);
1891 glyph
->object
= it
->object
;
1894 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1895 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1897 glyph
->bidi_type
= it
->bidi_it
.type
;
1901 glyph
->resolved_level
= 0;
1902 glyph
->bidi_type
= UNKNOWN_BT
;
1905 /* BIDI Note: we put the glyphs of characters left to right, even in
1906 the REVERSED_P case because we write to the terminal
1908 for (i
= 0; i
< it
->nglyphs
&& glyph
< end
; ++i
)
1911 glyph
[0] = glyph
[-1];
1912 glyph
->u
.ch
= str
[i
];
1913 ++it
->glyph_row
->used
[it
->area
];
1918 /* Produce glyphs for a glyphless character for iterator IT.
1919 IT->glyphless_method specifies which method to use for displaying
1920 the character. See the description of enum
1921 glyphless_display_method in dispextern.h for the details.
1923 FOR_NO_FONT is nonzero if and only if this is for a character that
1924 is not supproted by the coding system of the terminal. ACRONYM, if
1925 non-nil, is an acronym string for the character.
1927 The glyphs actually produced are of type CHAR_GLYPH. */
1930 produce_glyphless_glyph (struct it
*it
, int for_no_font
, Lisp_Object acronym
)
1934 char buf
[9], *str
= " ";
1936 /* Get a face ID for the glyph by utilizing a cache (the same way as
1937 done for `escape-glyph' in get_next_display_element). */
1938 if (it
->f
== last_glyphless_glyph_frame
1939 && it
->face_id
== last_glyphless_glyph_face_id
)
1941 face_id
= last_glyphless_glyph_merged_face_id
;
1945 /* Merge the `glyphless-char' face into the current face. */
1946 face_id
= merge_faces (it
->f
, Qglyphless_char
, 0, it
->face_id
);
1947 last_glyphless_glyph_frame
= it
->f
;
1948 last_glyphless_glyph_face_id
= it
->face_id
;
1949 last_glyphless_glyph_merged_face_id
= face_id
;
1952 if (it
->glyphless_method
== GLYPHLESS_DISPLAY_THIN_SPACE
)
1954 /* As there's no way to produce a thin space, we produce a space
1955 of canonical width. */
1958 else if (it
->glyphless_method
== GLYPHLESS_DISPLAY_EMPTY_BOX
)
1960 len
= CHAR_WIDTH (it
->c
);
1965 sprintf (buf
, "[%.*s]", len
, str
);
1971 if (it
->glyphless_method
== GLYPHLESS_DISPLAY_ACRONYM
)
1973 if (! STRINGP (acronym
) && CHAR_TABLE_P (Vglyphless_char_display
))
1974 acronym
= CHAR_TABLE_REF (Vglyphless_char_display
, it
->c
);
1976 str
= STRINGP (acronym
) ? (char *) SDATA (acronym
) : "";
1977 for (len
= 0; len
< 6 && str
[len
] && ASCII_BYTE_P (str
[len
]); len
++)
1978 buf
[1 + len
] = str
[len
];
1984 xassert (it
->glyphless_method
== GLYPHLESS_DISPLAY_HEX_CODE
);
1985 len
= (it
->c
< 0x10000 ? sprintf (buf
, "\\u%04X", it
->c
)
1986 : it
->c
<= MAX_UNICODE_CHAR
? sprintf (buf
, "\\U%06X", it
->c
)
1987 : sprintf (buf
, "\\x%06X", it
->c
));
1992 it
->pixel_width
= len
;
1994 if (len
> 0 && it
->glyph_row
)
1995 append_glyphless_glyph (it
, face_id
, str
);
1999 /* Get information about special display element WHAT in an
2000 environment described by IT. WHAT is one of IT_TRUNCATION or
2001 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
2002 non-null glyph_row member. This function ensures that fields like
2003 face_id, c, len of IT are left untouched. */
2006 produce_special_glyphs (struct it
*it
, enum display_element_type what
)
2014 temp_it
.what
= IT_CHARACTER
;
2016 temp_it
.object
= make_number (0);
2017 memset (&temp_it
.current
, 0, sizeof temp_it
.current
);
2019 if (what
== IT_CONTINUATION
)
2021 /* Continuation glyph. For R2L lines, we mirror it by hand. */
2022 if (it
->bidi_it
.paragraph_dir
== R2L
)
2023 SET_GLYPH_FROM_CHAR (glyph
, '/');
2025 SET_GLYPH_FROM_CHAR (glyph
, '\\');
2027 && (gc
= DISP_CONTINUE_GLYPH (it
->dp
), GLYPH_CODE_P (gc
))
2028 && GLYPH_CODE_CHAR_VALID_P (gc
))
2030 /* FIXME: Should we mirror GC for R2L lines? */
2031 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
2032 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
2035 else if (what
== IT_TRUNCATION
)
2037 /* Truncation glyph. */
2038 SET_GLYPH_FROM_CHAR (glyph
, '$');
2040 && (gc
= DISP_TRUNC_GLYPH (it
->dp
), GLYPH_CODE_P (gc
))
2041 && GLYPH_CODE_CHAR_VALID_P (gc
))
2043 /* FIXME: Should we mirror GC for R2L lines? */
2044 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
2045 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
2051 temp_it
.c
= temp_it
.char_to_display
= GLYPH_CHAR (glyph
);
2052 temp_it
.face_id
= GLYPH_FACE (glyph
);
2053 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
2055 produce_glyphs (&temp_it
);
2056 it
->pixel_width
= temp_it
.pixel_width
;
2057 it
->nglyphs
= temp_it
.pixel_width
;
2062 /***********************************************************************
2064 ***********************************************************************/
2066 /* Value is non-zero if attribute ATTR may be used. ATTR should be
2067 one of the enumerators from enum no_color_bit, or a bit set built
2068 from them. Some display attributes may not be used together with
2069 color; the termcap capability `NC' specifies which ones. */
2071 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
2072 (tty->TN_max_colors > 0 \
2073 ? (tty->TN_no_color_video & (ATTR)) == 0 \
2076 /* Turn appearances of face FACE_ID on tty frame F on.
2077 FACE_ID is a realized face ID number, in the face cache. */
2080 turn_on_face (struct frame
*f
, int face_id
)
2082 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2083 long fg
= face
->foreground
;
2084 long bg
= face
->background
;
2085 struct tty_display_info
*tty
= FRAME_TTY (f
);
2087 /* Do this first because TS_end_standout_mode may be the same
2088 as TS_exit_attribute_mode, which turns all appearances off. */
2089 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
2091 if (tty
->TN_max_colors
> 0)
2093 if (fg
>= 0 && bg
>= 0)
2095 /* If the terminal supports colors, we can set them
2096 below without using reverse video. The face's fg
2097 and bg colors are set as they should appear on
2098 the screen, i.e. they take the inverse-video'ness
2099 of the face already into account. */
2101 else if (inverse_video
)
2103 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
2104 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
2105 tty_toggle_highlight (tty
);
2109 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
2110 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
2111 tty_toggle_highlight (tty
);
2116 /* If we can't display colors, use reverse video
2117 if the face specifies that. */
2120 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
2121 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
2122 tty_toggle_highlight (tty
);
2126 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
2127 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
2128 tty_toggle_highlight (tty
);
2133 if (face
->tty_bold_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
2134 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
2136 if (face
->tty_dim_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
2137 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
2139 /* Alternate charset and blinking not yet used. */
2140 if (face
->tty_alt_charset_p
2141 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
2142 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
2144 if (face
->tty_blinking_p
2145 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
2146 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
2148 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
2149 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
2151 if (tty
->TN_max_colors
> 0)
2155 ts
= tty
->standout_mode
? tty
->TS_set_background
: tty
->TS_set_foreground
;
2158 p
= tparam (ts
, NULL
, 0, (int) fg
);
2163 ts
= tty
->standout_mode
? tty
->TS_set_foreground
: tty
->TS_set_background
;
2166 p
= tparam (ts
, NULL
, 0, (int) bg
);
2174 /* Turn off appearances of face FACE_ID on tty frame F. */
2177 turn_off_face (struct frame
*f
, int face_id
)
2179 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2180 struct tty_display_info
*tty
= FRAME_TTY (f
);
2182 xassert (face
!= NULL
);
2184 if (tty
->TS_exit_attribute_mode
)
2186 /* Capability "me" will turn off appearance modes double-bright,
2187 half-bright, reverse-video, standout, underline. It may or
2188 may not turn off alt-char-mode. */
2189 if (face
->tty_bold_p
2191 || face
->tty_reverse_p
2192 || face
->tty_alt_charset_p
2193 || face
->tty_blinking_p
2194 || face
->tty_underline_p
)
2196 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
2197 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
2198 tty
->standout_mode
= 0;
2201 if (face
->tty_alt_charset_p
)
2202 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
2206 /* If we don't have "me" we can only have those appearances
2207 that have exit sequences defined. */
2208 if (face
->tty_alt_charset_p
)
2209 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
2211 if (face
->tty_underline_p
)
2212 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
2215 /* Switch back to default colors. */
2216 if (tty
->TN_max_colors
> 0
2217 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2218 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2219 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2220 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2221 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
2225 /* Return non-zero if the terminal on frame F supports all of the
2226 capabilities in CAPS simultaneously, with foreground and background
2227 colors FG and BG. */
2230 tty_capable_p (struct tty_display_info
*tty
, unsigned int caps
,
2231 unsigned long fg
, unsigned long bg
)
2233 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
2234 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
2237 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
2238 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
2239 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
2240 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
2241 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
2242 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
2248 /* Return non-zero if the terminal is capable to display colors. */
2250 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2252 doc
: /* Return non-nil if the tty device TERMINAL can display colors.
2254 TERMINAL can be a terminal object, a frame, or nil (meaning the
2255 selected frame's terminal). This function always returns nil if
2256 TERMINAL does not refer to a text-only terminal. */)
2257 (Lisp_Object terminal
)
2259 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2263 return t
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
2266 /* Return the number of supported colors. */
2267 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2268 Stty_display_color_cells
, 0, 1, 0,
2269 doc
: /* Return the number of colors supported by the tty device TERMINAL.
2271 TERMINAL can be a terminal object, a frame, or nil (meaning the
2272 selected frame's terminal). This function always returns 0 if
2273 TERMINAL does not refer to a text-only terminal. */)
2274 (Lisp_Object terminal
)
2276 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2278 return make_number (0);
2280 return make_number (t
->display_info
.tty
->TN_max_colors
);
2285 /* Declare here rather than in the function, as in the rest of Emacs,
2286 to work around an HPUX compiler bug (?). See
2287 http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00410.html */
2288 static int default_max_colors
;
2289 static int default_max_pairs
;
2290 static int default_no_color_video
;
2291 static char *default_orig_pair
;
2292 static char *default_set_foreground
;
2293 static char *default_set_background
;
2295 /* Save or restore the default color-related capabilities of this
2298 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
2303 xfree (default_orig_pair
);
2304 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
2306 xfree (default_set_foreground
);
2307 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
2310 xfree (default_set_background
);
2311 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
2314 default_max_colors
= tty
->TN_max_colors
;
2315 default_max_pairs
= tty
->TN_max_pairs
;
2316 default_no_color_video
= tty
->TN_no_color_video
;
2320 tty
->TS_orig_pair
= default_orig_pair
;
2321 tty
->TS_set_foreground
= default_set_foreground
;
2322 tty
->TS_set_background
= default_set_background
;
2323 tty
->TN_max_colors
= default_max_colors
;
2324 tty
->TN_max_pairs
= default_max_pairs
;
2325 tty
->TN_no_color_video
= default_no_color_video
;
2329 /* Setup one of the standard tty color schemes according to MODE.
2330 MODE's value is generally the number of colors which we want to
2331 support; zero means set up for the default capabilities, the ones
2332 we saw at init_tty time; -1 means turn off color support. */
2334 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2336 /* Canonicalize all negative values of MODE. */
2342 case -1: /* no colors at all */
2343 tty
->TN_max_colors
= 0;
2344 tty
->TN_max_pairs
= 0;
2345 tty
->TN_no_color_video
= 0;
2346 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2348 case 0: /* default colors, if any */
2350 tty_default_color_capabilities (tty
, 0);
2352 case 8: /* 8 standard ANSI colors */
2353 tty
->TS_orig_pair
= "\033[0m";
2355 tty
->TS_set_foreground
= "\033[3%p1%dm";
2356 tty
->TS_set_background
= "\033[4%p1%dm";
2358 tty
->TS_set_foreground
= "\033[3%dm";
2359 tty
->TS_set_background
= "\033[4%dm";
2361 tty
->TN_max_colors
= 8;
2362 tty
->TN_max_pairs
= 64;
2363 tty
->TN_no_color_video
= 0;
2369 set_tty_color_mode (struct tty_display_info
*tty
, struct frame
*f
)
2371 Lisp_Object tem
, val
;
2372 Lisp_Object color_mode
;
2374 Lisp_Object tty_color_mode_alist
2375 = Fintern_soft (build_string ("tty-color-mode-alist"), Qnil
);
2377 tem
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2378 val
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2382 else if (SYMBOLP (tty_color_mode_alist
))
2384 tem
= Fassq (val
, Fsymbol_value (tty_color_mode_alist
));
2385 color_mode
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2390 mode
= INTEGERP (color_mode
) ? XINT (color_mode
) : 0;
2392 if (mode
!= tty
->previous_color_mode
)
2394 Lisp_Object funsym
= intern ("tty-set-up-initial-frame-faces");
2395 tty
->previous_color_mode
= mode
;
2396 tty_setup_colors (tty
, mode
);
2397 /* This recomputes all the faces given the new color definitions. */
2398 safe_call (1, &funsym
);
2402 #endif /* !DOS_NT */
2406 /* Return the tty display object specified by TERMINAL. */
2409 get_tty_terminal (Lisp_Object terminal
, int throw)
2411 struct terminal
*t
= get_terminal (terminal
, throw);
2413 if (t
&& t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2416 error ("Device %d is not a termcap terminal device", t
->id
);
2424 /* Return an active termcap device that uses the tty device with the
2427 This function ignores suspended devices.
2429 Returns NULL if the named terminal device is not opened. */
2432 get_named_tty (const char *name
)
2439 for (t
= terminal_list
; t
; t
= t
->next_terminal
)
2441 if ((t
->type
== output_termcap
|| t
->type
== output_msdos_raw
)
2442 && !strcmp (t
->display_info
.tty
->name
, name
)
2443 && TERMINAL_ACTIVE_P (t
))
2451 DEFUN ("tty-type", Ftty_type
, Stty_type
, 0, 1, 0,
2452 doc
: /* Return the type of the tty device that TERMINAL uses.
2453 Returns nil if TERMINAL is not on a tty device.
2455 TERMINAL can be a terminal object, a frame, or nil (meaning the
2456 selected frame's terminal). */)
2457 (Lisp_Object terminal
)
2459 struct terminal
*t
= get_terminal (terminal
, 1);
2461 if (t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2464 if (t
->display_info
.tty
->type
)
2465 return build_string (t
->display_info
.tty
->type
);
2470 DEFUN ("controlling-tty-p", Fcontrolling_tty_p
, Scontrolling_tty_p
, 0, 1, 0,
2471 doc
: /* Return non-nil if TERMINAL is the controlling tty of the Emacs process.
2473 TERMINAL can be a terminal object, a frame, or nil (meaning the
2474 selected frame's terminal). This function always returns nil if
2475 TERMINAL is not on a tty device. */)
2476 (Lisp_Object terminal
)
2478 struct terminal
*t
= get_terminal (terminal
, 1);
2480 if ((t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2481 || strcmp (t
->display_info
.tty
->name
, DEV_TTY
) != 0)
2487 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 1, 0,
2488 doc
: /* Declare that the tty used by TERMINAL does not handle underlining.
2489 This is used to override the terminfo data, for certain terminals that
2490 do not really do underlining, but say that they do. This function has
2491 no effect if used on a non-tty terminal.
2493 TERMINAL can be a terminal object, a frame or nil (meaning the
2494 selected frame's terminal). This function always returns nil if
2495 TERMINAL does not refer to a text-only terminal. */)
2496 (Lisp_Object terminal
)
2498 struct terminal
*t
= get_terminal (terminal
, 1);
2500 if (t
->type
== output_termcap
)
2501 t
->display_info
.tty
->TS_enter_underline_mode
= 0;
2507 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
2508 doc
: /* Suspend the terminal device TTY.
2510 The device is restored to its default state, and Emacs ceases all
2511 access to the tty device. Frames that use the device are not deleted,
2512 but input is not read from them and if they change, their display is
2515 TTY may be a terminal object, a frame, or nil for the terminal device
2516 of the currently selected frame.
2518 This function runs `suspend-tty-functions' after suspending the
2519 device. The functions are run with one arg, the id of the suspended
2522 `suspend-tty' does nothing if it is called on a device that is already
2525 A suspended tty may be resumed by calling `resume-tty' on it. */)
2528 struct terminal
*t
= get_tty_terminal (tty
, 1);
2532 error ("Unknown tty device");
2534 f
= t
->display_info
.tty
->input
;
2538 /* First run `suspend-tty-functions' and then clean up the tty
2539 state because `suspend-tty-functions' might need to change
2541 if (!NILP (Vrun_hooks
))
2543 Lisp_Object args
[2];
2544 args
[0] = intern ("suspend-tty-functions");
2545 XSETTERMINAL (args
[1], t
);
2546 Frun_hook_with_args (2, args
);
2549 reset_sys_modes (t
->display_info
.tty
);
2550 delete_keyboard_wait_descriptor (fileno (f
));
2554 if (f
!= t
->display_info
.tty
->output
)
2555 fclose (t
->display_info
.tty
->output
);
2558 t
->display_info
.tty
->input
= 0;
2559 t
->display_info
.tty
->output
= 0;
2561 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2562 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 0);
2566 /* Clear display hooks to prevent further output. */
2567 clear_tty_hooks (t
);
2572 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
2573 doc
: /* Resume the previously suspended terminal device TTY.
2574 The terminal is opened and reinitialized. Frames that are on the
2575 suspended terminal are revived.
2577 It is an error to resume a terminal while another terminal is active
2580 This function runs `resume-tty-functions' after resuming the terminal.
2581 The functions are run with one arg, the id of the resumed terminal
2584 `resume-tty' does nothing if it is called on a device that is not
2587 TTY may be a terminal object, a frame, or nil (meaning the selected
2588 frame's terminal). */)
2591 struct terminal
*t
= get_tty_terminal (tty
, 1);
2595 error ("Unknown tty device");
2597 if (!t
->display_info
.tty
->input
)
2599 if (get_named_tty (t
->display_info
.tty
->name
))
2600 error ("Cannot resume display while another display is active on the same device");
2603 t
->display_info
.tty
->output
= stdout
;
2604 t
->display_info
.tty
->input
= stdin
;
2606 fd
= emacs_open (t
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
2609 error ("Can not reopen tty device %s: %s", t
->display_info
.tty
->name
, strerror (errno
));
2611 if (strcmp (t
->display_info
.tty
->name
, DEV_TTY
))
2612 dissociate_if_controlling_tty (fd
);
2614 t
->display_info
.tty
->output
= fdopen (fd
, "w+");
2615 t
->display_info
.tty
->input
= t
->display_info
.tty
->output
;
2618 add_keyboard_wait_descriptor (fd
);
2620 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2622 struct frame
*f
= XFRAME (t
->display_info
.tty
->top_frame
);
2624 int old_height
= FRAME_COLS (f
);
2625 int old_width
= FRAME_LINES (f
);
2627 /* Check if terminal/window size has changed while the frame
2629 get_tty_size (fileno (t
->display_info
.tty
->input
), &width
, &height
);
2630 if (width
!= old_width
|| height
!= old_height
)
2631 change_frame_size (f
, height
, width
, 0, 0, 0);
2632 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 1);
2635 init_sys_modes (t
->display_info
.tty
);
2637 /* Run `resume-tty-functions'. */
2638 if (!NILP (Vrun_hooks
))
2640 Lisp_Object args
[2];
2641 args
[0] = intern ("resume-tty-functions");
2642 XSETTERMINAL (args
[1], t
);
2643 Frun_hook_with_args (2, args
);
2653 /***********************************************************************
2655 ***********************************************************************/
2659 term_mouse_moveto (int x
, int y
)
2661 /* TODO: how to set mouse position?
2664 name = (const char *) ttyname (0);
2665 fd = open (name, O_WRONLY);
2666 SOME_FUNCTION (x, y, fd);
2669 last_mouse_y = y; */
2672 /* Implementation of draw_row_with_mouse_face for TTY/GPM. */
2674 tty_draw_row_with_mouse_face (struct window
*w
, struct glyph_row
*row
,
2675 int start_hpos
, int end_hpos
,
2676 enum draw_glyphs_face draw
)
2678 int nglyphs
= end_hpos
- start_hpos
;
2679 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
2680 struct tty_display_info
*tty
= FRAME_TTY (f
);
2681 int face_id
= tty
->mouse_highlight
.mouse_face_face_id
;
2682 int save_x
, save_y
, pos_x
, pos_y
;
2684 if (end_hpos
>= row
->used
[TEXT_AREA
])
2685 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2687 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2688 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
+ WINDOW_LEFT_EDGE_X (w
);
2690 /* Save current cursor co-ordinates. */
2691 save_y
= curY (tty
);
2692 save_x
= curX (tty
);
2693 cursor_to (f
, pos_y
, pos_x
);
2695 if (draw
== DRAW_MOUSE_FACE
)
2696 tty_write_glyphs_with_face (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
,
2698 else if (draw
== DRAW_NORMAL_TEXT
)
2699 write_glyphs (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2701 cursor_to (f
, save_y
, save_x
);
2705 term_mouse_movement (FRAME_PTR frame
, Gpm_Event
*event
)
2707 /* Has the mouse moved off the glyph it was on at the last sighting? */
2708 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2710 frame
->mouse_moved
= 1;
2711 note_mouse_highlight (frame
, event
->x
, event
->y
);
2712 /* Remember which glyph we're now on. */
2713 last_mouse_x
= event
->x
;
2714 last_mouse_y
= event
->y
;
2720 /* Return the current position of the mouse.
2722 Set *f to the frame the mouse is in, or zero if the mouse is in no
2723 Emacs frame. If it is set to zero, all the other arguments are
2726 Set *bar_window to Qnil, and *x and *y to the column and
2727 row of the character cell the mouse is over.
2729 Set *time to the time the mouse was at the returned position.
2731 This clears mouse_moved until the next motion
2734 term_mouse_position (FRAME_PTR
*fp
, int insist
, Lisp_Object
*bar_window
,
2735 enum scroll_bar_part
*part
, Lisp_Object
*x
,
2736 Lisp_Object
*y
, unsigned long *time
)
2740 *fp
= SELECTED_FRAME ();
2741 (*fp
)->mouse_moved
= 0;
2746 XSETINT (*x
, last_mouse_x
);
2747 XSETINT (*y
, last_mouse_y
);
2748 gettimeofday(&now
, 0);
2749 *time
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2752 /* Prepare a mouse-event in *RESULT for placement in the input queue.
2754 If the event is a button press, then note that we have grabbed
2758 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
2764 result
->kind
= GPM_CLICK_EVENT
;
2765 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
2767 if (event
->buttons
& j
) {
2768 result
->code
= i
; /* button number */
2772 gettimeofday(&now
, 0);
2773 result
->timestamp
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2775 if (event
->type
& GPM_UP
)
2776 result
->modifiers
= up_modifier
;
2777 else if (event
->type
& GPM_DOWN
)
2778 result
->modifiers
= down_modifier
;
2780 result
->modifiers
= 0;
2782 if (event
->type
& GPM_SINGLE
)
2783 result
->modifiers
|= click_modifier
;
2785 if (event
->type
& GPM_DOUBLE
)
2786 result
->modifiers
|= double_modifier
;
2788 if (event
->type
& GPM_TRIPLE
)
2789 result
->modifiers
|= triple_modifier
;
2791 if (event
->type
& GPM_DRAG
)
2792 result
->modifiers
|= drag_modifier
;
2794 if (!(event
->type
& (GPM_MOVE
| GPM_DRAG
))) {
2797 if (event
->modifiers
& (1 << 0))
2798 result
->modifiers
|= shift_modifier
;
2801 if (event
->modifiers
& (1 << 2))
2802 result
->modifiers
|= ctrl_modifier
;
2804 /* 1 << KG_ALT || KG_ALTGR */
2805 if (event
->modifiers
& (1 << 3)
2806 || event
->modifiers
& (1 << 1))
2807 result
->modifiers
|= meta_modifier
;
2810 XSETINT (result
->x
, event
->x
);
2811 XSETINT (result
->y
, event
->y
);
2812 XSETFRAME (result
->frame_or_window
, f
);
2818 handle_one_term_event (struct tty_display_info
*tty
, Gpm_Event
*event
, struct input_event
* hold_quit
)
2820 struct frame
*f
= XFRAME (tty
->top_frame
);
2821 struct input_event ie
;
2829 if (event
->type
& (GPM_MOVE
| GPM_DRAG
)) {
2830 previous_help_echo_string
= help_echo_string
;
2831 help_echo_string
= Qnil
;
2833 Gpm_DrawPointer (event
->x
, event
->y
, fileno (tty
->output
));
2835 if (!term_mouse_movement (f
, event
))
2836 help_echo_string
= previous_help_echo_string
;
2838 /* If the contents of the global variable help_echo_string
2839 has changed, generate a HELP_EVENT. */
2840 if (!NILP (help_echo_string
)
2841 || !NILP (previous_help_echo_string
))
2848 term_mouse_click (&ie
, event
, f
);
2852 if (ie
.kind
!= NO_EVENT
)
2854 kbd_buffer_store_event_hold (&ie
, hold_quit
);
2859 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
2864 XSETFRAME (frame
, f
);
2868 gen_help_event (help_echo_string
, frame
, help_echo_window
,
2869 help_echo_object
, help_echo_pos
);
2876 DEFUN ("gpm-mouse-start", Fgpm_mouse_start
, Sgpm_mouse_start
,
2878 doc
: /* Open a connection to Gpm.
2879 Gpm-mouse can only be activated for one tty at a time. */)
2882 struct frame
*f
= SELECTED_FRAME ();
2883 struct tty_display_info
*tty
2884 = ((f
)->output_method
== output_termcap
2885 ? (f
)->terminal
->display_info
.tty
: NULL
);
2886 Gpm_Connect connection
;
2889 error ("Gpm-mouse only works in the GNU/Linux console");
2891 return Qnil
; /* Already activated, nothing to do. */
2893 error ("Gpm-mouse can only be activated for one tty at a time");
2895 connection
.eventMask
= ~0;
2896 connection
.defaultMask
= ~GPM_HARD
;
2897 connection
.maxMod
= ~0;
2898 connection
.minMod
= 0;
2901 if (Gpm_Open (&connection
, 0) < 0)
2902 error ("Gpm-mouse failed to connect to the gpm daemon");
2906 /* `init_sys_modes' arranges for mouse movements sent through gpm_fd
2907 to generate SIGIOs. Apparently we need to call reset_sys_modes
2908 before calling init_sys_modes. */
2909 reset_sys_modes (tty
);
2910 init_sys_modes (tty
);
2911 add_gpm_wait_descriptor (gpm_fd
);
2920 delete_gpm_wait_descriptor (fd
);
2921 while (Gpm_Close()); /* close all the stack */
2925 DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop
, Sgpm_mouse_stop
,
2927 doc
: /* Close a connection to Gpm. */)
2930 struct frame
*f
= SELECTED_FRAME ();
2931 struct tty_display_info
*tty
2932 = ((f
)->output_method
== output_termcap
2933 ? (f
)->terminal
->display_info
.tty
: NULL
);
2935 if (!tty
|| gpm_tty
!= tty
)
2936 return Qnil
; /* Not activated on this terminal, nothing to do. */
2941 #endif /* HAVE_GPM */
2945 /***********************************************************************
2947 ***********************************************************************/
2949 /* Initialize the tty-dependent part of frame F. The frame must
2950 already have its device initialized. */
2953 create_tty_output (struct frame
*f
)
2955 struct tty_output
*t
;
2957 if (! FRAME_TERMCAP_P (f
))
2960 t
= xmalloc (sizeof (struct tty_output
));
2961 memset (t
, 0, sizeof (struct tty_output
));
2963 t
->display_info
= FRAME_TERMINAL (f
)->display_info
.tty
;
2965 f
->output_data
.tty
= t
;
2968 /* Delete frame F's face cache, and its tty-dependent part. */
2971 tty_free_frame_resources (struct frame
*f
)
2973 if (! FRAME_TERMCAP_P (f
))
2976 if (FRAME_FACE_CACHE (f
))
2977 free_frame_faces (f
);
2979 xfree (f
->output_data
.tty
);
2984 /* Delete frame F's face cache. */
2987 tty_free_frame_resources (struct frame
*f
)
2989 if (! FRAME_TERMCAP_P (f
) && ! FRAME_MSDOS_P (f
))
2992 if (FRAME_FACE_CACHE (f
))
2993 free_frame_faces (f
);
2997 /* Reset the hooks in TERMINAL. */
3000 clear_tty_hooks (struct terminal
*terminal
)
3003 terminal
->cursor_to_hook
= 0;
3004 terminal
->raw_cursor_to_hook
= 0;
3005 terminal
->clear_to_end_hook
= 0;
3006 terminal
->clear_frame_hook
= 0;
3007 terminal
->clear_end_of_line_hook
= 0;
3008 terminal
->ins_del_lines_hook
= 0;
3009 terminal
->insert_glyphs_hook
= 0;
3010 terminal
->write_glyphs_hook
= 0;
3011 terminal
->delete_glyphs_hook
= 0;
3012 terminal
->ring_bell_hook
= 0;
3013 terminal
->reset_terminal_modes_hook
= 0;
3014 terminal
->set_terminal_modes_hook
= 0;
3015 terminal
->update_begin_hook
= 0;
3016 terminal
->update_end_hook
= 0;
3017 terminal
->set_terminal_window_hook
= 0;
3018 terminal
->mouse_position_hook
= 0;
3019 terminal
->frame_rehighlight_hook
= 0;
3020 terminal
->frame_raise_lower_hook
= 0;
3021 terminal
->fullscreen_hook
= 0;
3022 terminal
->set_vertical_scroll_bar_hook
= 0;
3023 terminal
->condemn_scroll_bars_hook
= 0;
3024 terminal
->redeem_scroll_bar_hook
= 0;
3025 terminal
->judge_scroll_bars_hook
= 0;
3026 terminal
->read_socket_hook
= 0;
3027 terminal
->frame_up_to_date_hook
= 0;
3029 /* Leave these two set, or suspended frames are not deleted
3031 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3032 terminal
->delete_terminal_hook
= &delete_tty
;
3035 /* Initialize hooks in TERMINAL with the values needed for a tty. */
3038 set_tty_hooks (struct terminal
*terminal
)
3040 terminal
->rif
= 0; /* ttys don't support window-based redisplay. */
3042 terminal
->cursor_to_hook
= &tty_cursor_to
;
3043 terminal
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
3045 terminal
->clear_to_end_hook
= &tty_clear_to_end
;
3046 terminal
->clear_frame_hook
= &tty_clear_frame
;
3047 terminal
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
3049 terminal
->ins_del_lines_hook
= &tty_ins_del_lines
;
3051 terminal
->insert_glyphs_hook
= &tty_insert_glyphs
;
3052 terminal
->write_glyphs_hook
= &tty_write_glyphs
;
3053 terminal
->delete_glyphs_hook
= &tty_delete_glyphs
;
3055 terminal
->ring_bell_hook
= &tty_ring_bell
;
3057 terminal
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
3058 terminal
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
3059 terminal
->update_begin_hook
= 0; /* Not needed. */
3060 terminal
->update_end_hook
= &tty_update_end
;
3061 terminal
->set_terminal_window_hook
= &tty_set_terminal_window
;
3063 terminal
->mouse_position_hook
= 0; /* Not needed. */
3064 terminal
->frame_rehighlight_hook
= 0; /* Not needed. */
3065 terminal
->frame_raise_lower_hook
= 0; /* Not needed. */
3067 terminal
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
3068 terminal
->condemn_scroll_bars_hook
= 0; /* Not needed. */
3069 terminal
->redeem_scroll_bar_hook
= 0; /* Not needed. */
3070 terminal
->judge_scroll_bars_hook
= 0; /* Not needed. */
3072 terminal
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
3073 terminal
->frame_up_to_date_hook
= 0; /* Not needed. */
3075 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3076 terminal
->delete_terminal_hook
= &delete_tty
;
3079 /* Drop the controlling terminal if fd is the same device. */
3081 dissociate_if_controlling_tty (int fd
)
3084 int pgid
= tcgetpgrp (fd
); /* If tcgetpgrp succeeds, fd is the ctty. */
3089 no_controlling_tty
= 1;
3090 #elif defined (CYGWIN)
3092 no_controlling_tty
= 1;
3094 #ifdef TIOCNOTTY /* Try BSD ioctls. */
3095 sigblock (sigmask (SIGTTOU
));
3096 fd
= emacs_open (DEV_TTY
, O_RDWR
, 0);
3097 if (fd
!= -1 && ioctl (fd
, TIOCNOTTY
, 0) != -1)
3099 no_controlling_tty
= 1;
3103 sigunblock (sigmask (SIGTTOU
));
3105 /* Unknown system. */
3107 #endif /* ! TIOCNOTTY */
3110 #endif /* !DOS_NT */
3113 /* Create a termcap display on the tty device with the given name and
3116 If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
3117 Otherwise NAME should be a path to the tty device file,
3120 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
3122 If MUST_SUCCEED is true, then all errors are fatal. */
3125 init_tty (const char *name
, const char *terminal_type
, int must_succeed
)
3128 char **address
= &area
;
3129 int buffer_size
= 4096;
3130 register char *p
= NULL
;
3132 struct tty_display_info
*tty
= NULL
;
3133 struct terminal
*terminal
= NULL
;
3134 int ctty
= 0; /* 1 if asked to open controlling tty. */
3137 maybe_fatal (must_succeed
, 0,
3138 "Unknown terminal type",
3139 "Unknown terminal type");
3143 if (!strcmp (name
, DEV_TTY
))
3146 /* If we already have a terminal on the given device, use that. If
3147 all such terminals are suspended, create a new one instead. */
3148 /* XXX Perhaps this should be made explicit by having init_tty
3149 always create a new terminal and separating terminal and frame
3150 creation on Lisp level. */
3151 terminal
= get_named_tty (name
);
3155 terminal
= create_terminal ();
3158 maybe_fatal (1, 0, "Attempt to create another terminal %s", "",
3161 tty
= &the_only_display_info
;
3163 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
3165 memset (tty
, 0, sizeof (struct tty_display_info
));
3166 tty
->next
= tty_list
;
3169 terminal
->type
= output_termcap
;
3170 terminal
->display_info
.tty
= tty
;
3171 tty
->terminal
= terminal
;
3173 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
3176 encode_terminal_src_size
= 0;
3177 encode_terminal_dst_size
= 0;
3180 terminal
->mouse_position_hook
= term_mouse_position
;
3181 tty
->mouse_highlight
.mouse_face_window
= Qnil
;
3186 set_tty_hooks (terminal
);
3192 #ifdef O_IGNORE_CTTY
3194 /* Open the terminal device. Don't recognize it as our
3195 controlling terminal, and don't make it the controlling tty
3196 if we don't have one at the moment. */
3197 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
3200 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
3201 defined on Hurd. On other systems, we need to explicitly
3202 dissociate ourselves from the controlling tty when we want to
3203 open a frame on the same terminal. */
3204 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
3205 #endif /* O_IGNORE_CTTY */
3207 tty
->name
= xstrdup (name
);
3208 terminal
->name
= xstrdup (name
);
3211 maybe_fatal (must_succeed
, terminal
,
3212 "Could not open file: %s",
3213 "Could not open file: %s",
3218 maybe_fatal (must_succeed
, terminal
,
3219 "Not a tty device: %s",
3220 "Not a tty device: %s",
3224 #ifndef O_IGNORE_CTTY
3226 dissociate_if_controlling_tty (fd
);
3229 file
= fdopen (fd
, "w+");
3234 tty
->type
= xstrdup (terminal_type
);
3236 add_keyboard_wait_descriptor (fileno (tty
->input
));
3240 tty
->termcap_term_buffer
= (char *) xmalloc (buffer_size
);
3242 /* On some systems, tgetent tries to access the controlling
3244 sigblock (sigmask (SIGTTOU
));
3245 status
= tgetent (tty
->termcap_term_buffer
, terminal_type
);
3246 sigunblock (sigmask (SIGTTOU
));
3251 maybe_fatal (must_succeed
, terminal
,
3252 "Cannot open terminfo database file",
3253 "Cannot open terminfo database file");
3255 maybe_fatal (must_succeed
, terminal
,
3256 "Cannot open termcap database file",
3257 "Cannot open termcap database file");
3262 maybe_fatal (must_succeed
, terminal
,
3263 "Terminal type %s is not defined",
3264 "Terminal type %s is not defined.\n\
3265 If that is not the actual type of terminal you have,\n\
3266 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3267 `setenv TERM ...') to specify the correct type. It may be necessary\n"
3269 "to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3271 "to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3277 if (strlen (tty
->termcap_term_buffer
) >= buffer_size
)
3279 buffer_size
= strlen (tty
->termcap_term_buffer
);
3281 tty
->termcap_strings_buffer
= area
= (char *) xmalloc (buffer_size
);
3282 tty
->TS_ins_line
= tgetstr ("al", address
);
3283 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
3284 tty
->TS_bell
= tgetstr ("bl", address
);
3285 BackTab (tty
) = tgetstr ("bt", address
);
3286 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
3287 tty
->TS_clr_line
= tgetstr ("ce", address
);
3288 tty
->TS_clr_frame
= tgetstr ("cl", address
);
3289 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
3290 AbsPosition (tty
) = tgetstr ("cm", address
);
3291 CR (tty
) = tgetstr ("cr", address
);
3292 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
3293 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
3294 RowPosition (tty
) = tgetstr ("cv", address
);
3295 tty
->TS_del_char
= tgetstr ("dc", address
);
3296 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
3297 tty
->TS_del_line
= tgetstr ("dl", address
);
3298 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
3299 tty
->TS_delete_mode
= tgetstr ("dm", address
);
3300 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
3301 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
3302 Home (tty
) = tgetstr ("ho", address
);
3303 tty
->TS_ins_char
= tgetstr ("ic", address
);
3304 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
3305 tty
->TS_insert_mode
= tgetstr ("im", address
);
3306 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
3307 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
3308 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
3309 LastLine (tty
) = tgetstr ("ll", address
);
3310 Right (tty
) = tgetstr ("nd", address
);
3311 Down (tty
) = tgetstr ("do", address
);
3313 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
3314 if (tgetflag ("bs"))
3315 Left (tty
) = "\b"; /* can't possibly be longer! */
3316 else /* (Actually, "bs" is obsolete...) */
3317 Left (tty
) = tgetstr ("le", address
);
3319 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
3320 tty
->TS_pad_char
= tgetstr ("pc", address
);
3321 tty
->TS_repeat
= tgetstr ("rp", address
);
3322 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
3323 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
3324 tty
->TS_standout_mode
= tgetstr ("so", address
);
3325 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
3326 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
3327 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
3328 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
3329 Up (tty
) = tgetstr ("up", address
);
3330 tty
->TS_visible_bell
= tgetstr ("vb", address
);
3331 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
3332 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
3333 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
3334 tty
->TS_set_window
= tgetstr ("wi", address
);
3336 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
3337 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
3338 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
3339 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
3340 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
3341 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
3342 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3343 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3344 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
3346 MultiUp (tty
) = tgetstr ("UP", address
);
3347 MultiDown (tty
) = tgetstr ("DO", address
);
3348 MultiLeft (tty
) = tgetstr ("LE", address
);
3349 MultiRight (tty
) = tgetstr ("RI", address
);
3351 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
3352 color because we can't switch back to the default foreground and
3354 tty
->TS_orig_pair
= tgetstr ("op", address
);
3355 if (tty
->TS_orig_pair
)
3357 tty
->TS_set_foreground
= tgetstr ("AF", address
);
3358 tty
->TS_set_background
= tgetstr ("AB", address
);
3359 if (!tty
->TS_set_foreground
)
3362 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
3363 tty
->TS_set_background
= tgetstr ("Sb", address
);
3366 tty
->TN_max_colors
= tgetnum ("Co");
3367 tty
->TN_max_pairs
= tgetnum ("pa");
3369 tty
->TN_no_color_video
= tgetnum ("NC");
3370 if (tty
->TN_no_color_video
== -1)
3371 tty
->TN_no_color_video
= 0;
3374 tty_default_color_capabilities (tty
, 1);
3376 MagicWrap (tty
) = tgetflag ("xn");
3377 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3378 the former flag imply the latter. */
3379 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
3380 terminal
->memory_below_frame
= tgetflag ("db");
3381 tty
->TF_hazeltine
= tgetflag ("hz");
3382 terminal
->must_write_spaces
= tgetflag ("in");
3383 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
3384 tty
->TF_insmode_motion
= tgetflag ("mi");
3385 tty
->TF_standout_motion
= tgetflag ("ms");
3386 tty
->TF_underscore
= tgetflag ("ul");
3387 tty
->TF_teleray
= tgetflag ("xt");
3392 struct frame
*f
= XFRAME (selected_frame
);
3394 initialize_w32_display (terminal
);
3396 FrameRows (tty
) = FRAME_LINES (f
);
3397 FrameCols (tty
) = FRAME_COLS (f
);
3398 tty
->specified_window
= FRAME_LINES (f
);
3400 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
3401 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
3402 terminal
->char_ins_del_ok
= 1;
3408 if (strcmp (terminal_type
, "internal") == 0)
3409 terminal
->type
= output_msdos_raw
;
3410 initialize_msdos_display (terminal
);
3412 get_tty_size (fileno (tty
->input
), &width
, &height
);
3413 FrameCols (tty
) = width
;
3414 FrameRows (tty
) = height
;
3415 terminal
->char_ins_del_ok
= 0;
3416 init_baud_rate (fileno (tty
->input
));
3419 tty
->output
= stdout
;
3421 /* The following two are inaccessible from w32console.c. */
3422 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3423 terminal
->delete_terminal_hook
= &delete_tty
;
3425 tty
->name
= xstrdup (name
);
3426 terminal
->name
= xstrdup (name
);
3427 tty
->type
= xstrdup (terminal_type
);
3429 add_keyboard_wait_descriptor (0);
3431 tty
->delete_in_insert_mode
= 1;
3434 terminal
->scroll_region_ok
= 0;
3436 /* Seems to insert lines when it's not supposed to, messing up the
3437 display. In doing a trace, it didn't seem to be called much, so I
3438 don't think we're losing anything by turning it off. */
3439 terminal
->line_ins_del_ok
= 0;
3441 tty
->TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
3444 terminal
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
3445 init_kboard (terminal
->kboard
);
3446 terminal
->kboard
->Vwindow_system
= Qnil
;
3447 terminal
->kboard
->next_kboard
= all_kboards
;
3448 all_kboards
= terminal
->kboard
;
3449 terminal
->kboard
->reference_count
++;
3450 /* Don't let the initial kboard remain current longer than necessary.
3451 That would cause problems if a file loaded on startup tries to
3452 prompt in the mini-buffer. */
3453 if (current_kboard
== initial_kboard
)
3454 current_kboard
= terminal
->kboard
;
3456 term_get_fkeys (address
, terminal
->kboard
);
3458 /* Get frame size from system, or else from termcap. */
3461 get_tty_size (fileno (tty
->input
), &width
, &height
);
3462 FrameCols (tty
) = width
;
3463 FrameRows (tty
) = height
;
3466 if (FrameCols (tty
) <= 0)
3467 FrameCols (tty
) = tgetnum ("co");
3468 if (FrameRows (tty
) <= 0)
3469 FrameRows (tty
) = tgetnum ("li");
3471 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
3472 maybe_fatal (must_succeed
, terminal
,
3473 "Screen size %dx%d is too small",
3474 "Screen size %dx%d is too small",
3475 FrameCols (tty
), FrameRows (tty
));
3477 TabWidth (tty
) = tgetnum ("tw");
3480 tty
->TS_bell
= "\07";
3482 if (!tty
->TS_fwd_scroll
)
3483 tty
->TS_fwd_scroll
= Down (tty
);
3485 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
3487 if (TabWidth (tty
) < 0)
3490 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3491 and newer termcap doc does not seem to say there is a default.
3492 if (!tty->Wcm->cm_tab)
3493 tty->Wcm->cm_tab = "\t";
3496 /* We don't support standout modes that use `magic cookies', so
3497 turn off any that do. */
3498 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
3500 tty
->TS_standout_mode
= 0;
3501 tty
->TS_end_standout_mode
= 0;
3503 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3505 tty
->TS_enter_underline_mode
= 0;
3506 tty
->TS_exit_underline_mode
= 0;
3509 /* If there's no standout mode, try to use underlining instead. */
3510 if (tty
->TS_standout_mode
== 0)
3512 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
3513 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
3516 /* If no `se' string, try using a `me' string instead.
3517 If that fails, we can't use standout mode at all. */
3518 if (tty
->TS_end_standout_mode
== 0)
3520 char *s
= tgetstr ("me", address
);
3522 tty
->TS_end_standout_mode
= s
;
3524 tty
->TS_standout_mode
= 0;
3527 if (tty
->TF_teleray
)
3529 tty
->Wcm
->cm_tab
= 0;
3530 /* We can't support standout mode, because it uses magic cookies. */
3531 tty
->TS_standout_mode
= 0;
3532 /* But that means we cannot rely on ^M to go to column zero! */
3534 /* LF can't be trusted either -- can alter hpos */
3535 /* if move at column 0 thru a line with TS_standout_mode */
3539 /* Special handling for certain terminal types known to need it */
3541 if (!strcmp (terminal_type
, "supdup"))
3543 terminal
->memory_below_frame
= 1;
3544 tty
->Wcm
->cm_losewrap
= 1;
3546 if (!strncmp (terminal_type
, "c10", 3)
3547 || !strcmp (terminal_type
, "perq"))
3549 /* Supply a makeshift :wi string.
3550 This string is not valid in general since it works only
3551 for windows starting at the upper left corner;
3552 but that is all Emacs uses.
3554 This string works only if the frame is using
3555 the top of the video memory, because addressing is memory-relative.
3556 So first check the :ti string to see if that is true.
3558 It would be simpler if the :wi string could go in the termcap
3559 entry, but it can't because it is not fully valid.
3560 If it were in the termcap entry, it would confuse other programs. */
3561 if (!tty
->TS_set_window
)
3563 p
= tty
->TS_termcap_modes
;
3564 while (*p
&& strcmp (p
, "\033v "))
3567 tty
->TS_set_window
= "\033v%C %C %C %C ";
3569 /* Termcap entry often fails to have :in: flag */
3570 terminal
->must_write_spaces
= 1;
3571 /* :ti string typically fails to have \E^G! in it */
3572 /* This limits scope of insert-char to one line. */
3573 strcpy (area
, tty
->TS_termcap_modes
);
3574 strcat (area
, "\033\007!");
3575 tty
->TS_termcap_modes
= area
;
3576 area
+= strlen (area
) + 1;
3577 p
= AbsPosition (tty
);
3578 /* Change all %+ parameters to %C, to handle
3579 values above 96 correctly for the C100. */
3582 if (p
[0] == '%' && p
[1] == '+')
3588 tty
->specified_window
= FrameRows (tty
);
3590 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
3592 maybe_fatal (must_succeed
, terminal
,
3593 "Terminal type \"%s\" is not powerful enough to run Emacs",
3594 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3595 It lacks the ability to position the cursor.\n\
3596 If that is not the actual type of terminal you have,\n\
3597 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3598 `setenv TERM ...') to specify the correct type. It may be necessary\n"
3600 "to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3601 # else /* TERMCAP */
3602 "to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3603 # endif /* TERMINFO */
3607 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
3608 maybe_fatal (must_succeed
, terminal
,
3609 "Could not determine the frame size",
3610 "Could not determine the frame size");
3612 tty
->delete_in_insert_mode
3613 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
3614 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
3616 tty
->se_is_so
= (tty
->TS_standout_mode
3617 && tty
->TS_end_standout_mode
3618 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
3620 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
3622 terminal
->scroll_region_ok
3624 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
3626 terminal
->line_ins_del_ok
3627 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
3628 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
3629 || (terminal
->scroll_region_ok
3630 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
3632 terminal
->char_ins_del_ok
3633 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
3634 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
3635 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
3637 terminal
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
3639 init_baud_rate (fileno (tty
->input
));
3641 #endif /* not DOS_NT */
3643 /* Init system terminal modes (RAW or CBREAK, etc.). */
3644 init_sys_modes (tty
);
3651 vfatal (const char *str
, va_list ap
)
3653 fprintf (stderr
, "emacs: ");
3654 vfprintf (stderr
, str
, ap
);
3655 if (!(strlen (str
) > 0 && str
[strlen (str
) - 1] == '\n'))
3656 fprintf (stderr
, "\n");
3663 /* Auxiliary error-handling function for init_tty.
3664 Delete TERMINAL, then call error or fatal with str1 or str2,
3665 respectively, according to MUST_SUCCEED. */
3668 maybe_fatal (int must_succeed
, struct terminal
*terminal
,
3669 const char *str1
, const char *str2
, ...)
3672 va_start (ap
, str2
);
3674 delete_tty (terminal
);
3686 fatal (const char *str
, ...)
3696 /* Delete the given tty terminal, closing all frames on it. */
3699 delete_tty (struct terminal
*terminal
)
3701 struct tty_display_info
*tty
;
3703 /* Protect against recursive calls. delete_frame in
3704 delete_terminal calls us back when it deletes our last frame. */
3705 if (!terminal
->name
)
3708 if (terminal
->type
!= output_termcap
)
3711 tty
= terminal
->display_info
.tty
;
3713 if (tty
== tty_list
)
3714 tty_list
= tty
->next
;
3717 struct tty_display_info
*p
;
3718 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
3722 /* This should not happen. */
3725 p
->next
= tty
->next
;
3729 /* reset_sys_modes needs a valid device, so this call needs to be
3730 before delete_terminal. */
3731 reset_sys_modes (tty
);
3733 delete_terminal (terminal
);
3740 delete_keyboard_wait_descriptor (fileno (tty
->input
));
3741 if (tty
->input
!= stdin
)
3742 fclose (tty
->input
);
3744 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
3745 fclose (tty
->output
);
3746 if (tty
->termscript
)
3747 fclose (tty
->termscript
);
3749 xfree (tty
->old_tty
);
3751 xfree (tty
->termcap_strings_buffer
);
3752 xfree (tty
->termcap_term_buffer
);
3754 memset (tty
, 0, sizeof (struct tty_display_info
));
3760 /* Mark the pointers in the tty_display_info objects.
3761 Called by the Fgarbage_collector. */
3766 struct tty_display_info
*tty
;
3768 for (tty
= tty_list
; tty
; tty
= tty
->next
)
3769 mark_object (tty
->top_frame
);
3777 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
3778 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3779 This variable can be used by terminal emulator packages. */);
3781 system_uses_terminfo
= 1;
3783 system_uses_terminfo
= 0;
3786 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions
,
3787 doc
: /* Functions to be run after suspending a tty.
3788 The functions are run with one argument, the terminal object to be suspended.
3789 See `suspend-tty'. */);
3790 Vsuspend_tty_functions
= Qnil
;
3793 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions
,
3794 doc
: /* Functions to be run after resuming a tty.
3795 The functions are run with one argument, the terminal object that was revived.
3796 See `resume-tty'. */);
3797 Vresume_tty_functions
= Qnil
;
3799 DEFVAR_BOOL ("visible-cursor", &visible_cursor
,
3800 doc
: /* Non-nil means to make the cursor very visible.
3801 This only has an effect when running in a text terminal.
3802 What means \"very visible\" is up to your terminal. It may make the cursor
3803 bigger, or it may make it blink, or it may do nothing at all. */);
3806 defsubr (&Stty_display_color_p
);
3807 defsubr (&Stty_display_color_cells
);
3808 defsubr (&Stty_no_underline
);
3809 defsubr (&Stty_type
);
3810 defsubr (&Scontrolling_tty_p
);
3811 defsubr (&Ssuspend_tty
);
3812 defsubr (&Sresume_tty
);
3814 defsubr (&Sgpm_mouse_start
);
3815 defsubr (&Sgpm_mouse_stop
);
3816 #endif /* HAVE_GPM */
3819 default_orig_pair
= NULL
;
3820 default_set_foreground
= NULL
;
3821 default_set_background
= NULL
;
3822 #endif /* !DOS_NT */
3824 encode_terminal_src
= NULL
;
3825 encode_terminal_dst
= NULL
;