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>. */
35 #include <termios.h> /* For TIOCNOTTY. */
46 #include "character.h"
49 #include "composite.h"
53 #include "termhooks.h"
54 #include "dispextern.h"
57 #include "blockinput.h"
58 #include "syssignal.h"
60 #include "intervals.h"
63 static int been_here
= -1;
66 /* For now, don't try to include termcap.h. On some systems,
67 configure finds a non-standard termcap.h that the main build
69 extern void tputs (const char *, int, int (*)(int));
70 extern int tgetent (char *, const char *);
71 extern int tgetflag (char *id
);
72 extern int tgetnum (char *id
);
87 /* The name of the default console device. */
89 #define DEV_TTY "CONOUT$"
91 #define DEV_TTY "/dev/tty"
94 static void tty_set_scroll_region (struct frame
*f
, int start
, int stop
);
95 static void turn_on_face (struct frame
*, int face_id
);
96 static void turn_off_face (struct frame
*, int face_id
);
97 static void tty_show_cursor (struct tty_display_info
*);
98 static void tty_hide_cursor (struct tty_display_info
*);
99 static void tty_background_highlight (struct tty_display_info
*tty
);
100 static void clear_tty_hooks (struct terminal
*terminal
);
101 static void set_tty_hooks (struct terminal
*terminal
);
102 static void dissociate_if_controlling_tty (int fd
);
103 static void delete_tty (struct terminal
*);
104 static void maybe_fatal (int must_succeed
, struct terminal
*terminal
,
105 const char *str1
, const char *str2
, ...) NO_RETURN
;
106 static void vfatal (const char *str
, va_list ap
) NO_RETURN
;
109 #define OUTPUT(tty, a) \
110 emacs_tputs ((tty), a, \
111 (int) (FRAME_LINES (XFRAME (selected_frame)) \
115 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
116 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
118 #define OUTPUT_IF(tty, a) \
121 emacs_tputs ((tty), a, \
122 (int) (FRAME_LINES (XFRAME (selected_frame)) \
127 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
129 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */
131 static int visible_cursor
;
133 /* Display space properties */
135 /* Functions to call after suspending a tty. */
136 Lisp_Object Vsuspend_tty_functions
;
138 /* Functions to call after resuming a tty. */
139 Lisp_Object Vresume_tty_functions
;
141 /* Chain of all tty device parameters. */
142 struct tty_display_info
*tty_list
;
144 /* Nonzero means no need to redraw the entire frame on resuming a
145 suspended Emacs. This is useful on terminals with multiple
146 pages, where one page is used for Emacs and another for all
148 int no_redraw_on_reenter
;
150 /* Meaning of bits in no_color_video. Each bit set means that the
151 corresponding attribute cannot be combined with colors. */
155 NC_STANDOUT
= 1 << 0,
156 NC_UNDERLINE
= 1 << 1,
163 NC_ALT_CHARSET
= 1 << 8
168 /* The largest frame width in any call to calculate_costs. */
172 /* The largest frame height in any call to calculate_costs. */
176 /* Non-zero if we have dropped our controlling tty and therefore
177 should not open a frame on stdout. */
178 static int no_controlling_tty
;
180 /* Provided for lisp packages. */
182 static int system_uses_terminfo
;
184 char *tparam (char *, char *, int, int, ...);
186 extern char *tgetstr (char *, char **);
190 #include <sys/fcntl.h>
192 static void term_clear_mouse_face (void);
193 static void term_mouse_highlight (struct frame
*f
, int x
, int y
);
195 /* The device for which we have enabled gpm support (or NULL). */
196 struct tty_display_info
*gpm_tty
= NULL
;
198 /* These variables describe the range of text currently shown in its
199 mouse-face, together with the window they apply to. As long as
200 the mouse stays within this range, we need not redraw anything on
201 its account. Rows and columns are glyph matrix positions in
202 MOUSE_FACE_WINDOW. */
203 static int mouse_face_beg_row
, mouse_face_beg_col
;
204 static int mouse_face_end_row
, mouse_face_end_col
;
205 static int mouse_face_past_end
;
206 static Lisp_Object mouse_face_window
;
207 static int mouse_face_face_id
;
209 static int pos_x
, pos_y
;
210 static int last_mouse_x
, last_mouse_y
;
211 #endif /* HAVE_GPM */
213 /* Ring the bell on a tty. */
216 tty_ring_bell (struct frame
*f
)
218 struct tty_display_info
*tty
= FRAME_TTY (f
);
222 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
223 ? tty
->TS_visible_bell
225 fflush (tty
->output
);
229 /* Set up termcap modes for Emacs. */
232 tty_set_terminal_modes (struct terminal
*terminal
)
234 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
238 if (tty
->TS_termcap_modes
)
239 OUTPUT (tty
, tty
->TS_termcap_modes
);
242 /* Output enough newlines to scroll all the old screen contents
243 off the screen, so it won't be overwritten and lost. */
246 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
250 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
251 OUTPUT_IF (tty
, visible_cursor
? tty
->TS_cursor_visible
: tty
->TS_cursor_normal
);
252 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
254 fflush (tty
->output
);
258 /* Reset termcap modes before exiting Emacs. */
261 tty_reset_terminal_modes (struct terminal
*terminal
)
263 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
267 tty_turn_off_highlight (tty
);
268 tty_turn_off_insert (tty
);
269 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
270 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
271 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
272 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
273 /* Output raw CR so kernel can track the cursor hpos. */
276 fflush (tty
->output
);
280 /* Flag the end of a display update on a termcap terminal. */
283 tty_update_end (struct frame
*f
)
285 struct tty_display_info
*tty
= FRAME_TTY (f
);
287 if (!XWINDOW (selected_window
)->cursor_off_p
)
288 tty_show_cursor (tty
);
289 tty_turn_off_insert (tty
);
290 tty_background_highlight (tty
);
293 /* The implementation of set_terminal_window for termcap frames. */
296 tty_set_terminal_window (struct frame
*f
, int size
)
298 struct tty_display_info
*tty
= FRAME_TTY (f
);
300 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
301 if (FRAME_SCROLL_REGION_OK (f
))
302 tty_set_scroll_region (f
, 0, tty
->specified_window
);
306 tty_set_scroll_region (struct frame
*f
, int start
, int stop
)
309 struct tty_display_info
*tty
= FRAME_TTY (f
);
311 if (tty
->TS_set_scroll_region
)
312 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
313 else if (tty
->TS_set_scroll_region_1
)
314 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
315 FRAME_LINES (f
), start
,
316 FRAME_LINES (f
) - stop
,
319 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
328 tty_turn_on_insert (struct tty_display_info
*tty
)
330 if (!tty
->insert_mode
)
331 OUTPUT (tty
, tty
->TS_insert_mode
);
332 tty
->insert_mode
= 1;
336 tty_turn_off_insert (struct tty_display_info
*tty
)
338 if (tty
->insert_mode
)
339 OUTPUT (tty
, tty
->TS_end_insert_mode
);
340 tty
->insert_mode
= 0;
343 /* Handle highlighting. */
346 tty_turn_off_highlight (struct tty_display_info
*tty
)
348 if (tty
->standout_mode
)
349 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
350 tty
->standout_mode
= 0;
354 tty_turn_on_highlight (struct tty_display_info
*tty
)
356 if (!tty
->standout_mode
)
357 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
358 tty
->standout_mode
= 1;
362 tty_toggle_highlight (struct tty_display_info
*tty
)
364 if (tty
->standout_mode
)
365 tty_turn_off_highlight (tty
);
367 tty_turn_on_highlight (tty
);
371 /* Make cursor invisible. */
374 tty_hide_cursor (struct tty_display_info
*tty
)
376 if (tty
->cursor_hidden
== 0)
378 tty
->cursor_hidden
= 1;
379 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
384 /* Ensure that cursor is visible. */
387 tty_show_cursor (struct tty_display_info
*tty
)
389 if (tty
->cursor_hidden
)
391 tty
->cursor_hidden
= 0;
392 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
394 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
399 /* Set standout mode to the state it should be in for
400 empty space inside windows. What this is,
401 depends on the user option inverse-video. */
404 tty_background_highlight (struct tty_display_info
*tty
)
407 tty_turn_on_highlight (tty
);
409 tty_turn_off_highlight (tty
);
412 /* Set standout mode to the mode specified for the text to be output. */
415 tty_highlight_if_desired (struct tty_display_info
*tty
)
418 tty_turn_on_highlight (tty
);
420 tty_turn_off_highlight (tty
);
424 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
425 frame-relative coordinates. */
428 tty_cursor_to (struct frame
*f
, int vpos
, int hpos
)
430 struct tty_display_info
*tty
= FRAME_TTY (f
);
432 /* Detect the case where we are called from reset_sys_modes
433 and the costs have never been calculated. Do nothing. */
434 if (! tty
->costs_set
)
437 if (curY (tty
) == vpos
438 && curX (tty
) == hpos
)
440 if (!tty
->TF_standout_motion
)
441 tty_background_highlight (tty
);
442 if (!tty
->TF_insmode_motion
)
443 tty_turn_off_insert (tty
);
444 cmgoto (tty
, vpos
, hpos
);
447 /* Similar but don't take any account of the wasted characters. */
450 tty_raw_cursor_to (struct frame
*f
, int row
, int col
)
452 struct tty_display_info
*tty
= FRAME_TTY (f
);
454 if (curY (tty
) == row
455 && curX (tty
) == col
)
457 if (!tty
->TF_standout_motion
)
458 tty_background_highlight (tty
);
459 if (!tty
->TF_insmode_motion
)
460 tty_turn_off_insert (tty
);
461 cmgoto (tty
, row
, col
);
464 /* Erase operations */
466 /* Clear from cursor to end of frame on a termcap device. */
469 tty_clear_to_end (struct frame
*f
)
472 struct tty_display_info
*tty
= FRAME_TTY (f
);
474 if (tty
->TS_clr_to_bottom
)
476 tty_background_highlight (tty
);
477 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
481 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
484 clear_end_of_line (f
, FRAME_COLS (f
));
489 /* Clear an entire termcap frame. */
492 tty_clear_frame (struct frame
*f
)
494 struct tty_display_info
*tty
= FRAME_TTY (f
);
496 if (tty
->TS_clr_frame
)
498 tty_background_highlight (tty
);
499 OUTPUT (tty
, tty
->TS_clr_frame
);
509 /* An implementation of clear_end_of_line for termcap frames.
511 Note that the cursor may be moved, on terminals lacking a `ce' string. */
514 tty_clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
517 struct tty_display_info
*tty
= FRAME_TTY (f
);
519 /* Detect the case where we are called from reset_sys_modes
520 and the costs have never been calculated. Do nothing. */
521 if (! tty
->costs_set
)
524 if (curX (tty
) >= first_unused_hpos
)
526 tty_background_highlight (tty
);
527 if (tty
->TS_clr_line
)
529 OUTPUT1 (tty
, tty
->TS_clr_line
);
532 { /* have to do it the hard way */
533 tty_turn_off_insert (tty
);
535 /* Do not write in last row last col with Auto-wrap on. */
537 && curY (tty
) == FrameRows (tty
) - 1
538 && first_unused_hpos
== FrameCols (tty
))
541 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
544 fputc (' ', tty
->termscript
);
545 fputc (' ', tty
->output
);
547 cmplus (tty
, first_unused_hpos
- curX (tty
));
551 /* Buffers to store the source and result of code conversion for terminal. */
552 static unsigned char *encode_terminal_src
;
553 static unsigned char *encode_terminal_dst
;
554 /* Allocated sizes of the above buffers. */
555 static int encode_terminal_src_size
;
556 static int encode_terminal_dst_size
;
558 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
559 Set CODING->produced to the byte-length of the resulting byte
560 sequence, and return a pointer to that byte sequence. */
563 encode_terminal_code (struct glyph
*src
, int src_len
, struct coding_system
*coding
)
565 struct glyph
*src_end
= src
+ src_len
;
567 int nchars
, nbytes
, required
;
568 register int tlen
= GLYPH_TABLE_LENGTH
;
569 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
570 Lisp_Object charset_list
;
572 /* Allocate sufficient size of buffer to store all characters in
573 multibyte-form. But, it may be enlarged on demand if
574 Vglyph_table contains a string or a composite glyph is
576 required
= MAX_MULTIBYTE_LENGTH
* src_len
;
577 if (encode_terminal_src_size
< required
)
579 if (encode_terminal_src
)
580 encode_terminal_src
= xrealloc (encode_terminal_src
, required
);
582 encode_terminal_src
= xmalloc (required
);
583 encode_terminal_src_size
= required
;
586 charset_list
= coding_charset_list (coding
);
588 buf
= encode_terminal_src
;
590 while (src
< src_end
)
592 if (src
->type
== COMPOSITE_GLYPH
)
594 struct composition
*cmp
;
598 nbytes
= buf
- encode_terminal_src
;
599 if (src
->u
.cmp
.automatic
)
601 gstring
= composition_gstring_from_id (src
->u
.cmp
.id
);
602 required
= src
->u
.cmp
.to
+ 1 - src
->u
.cmp
.from
;
606 cmp
= composition_table
[src
->u
.cmp
.id
];
607 required
= MAX_MULTIBYTE_LENGTH
* cmp
->glyph_len
;
610 if (encode_terminal_src_size
< nbytes
+ required
)
612 encode_terminal_src_size
= nbytes
+ required
;
613 encode_terminal_src
= xrealloc (encode_terminal_src
,
614 encode_terminal_src_size
);
615 buf
= encode_terminal_src
+ nbytes
;
618 if (src
->u
.cmp
.automatic
)
619 for (i
= src
->u
.cmp
.from
; i
<= src
->u
.cmp
.to
; i
++)
621 Lisp_Object g
= LGSTRING_GLYPH (gstring
, i
);
622 int c
= LGLYPH_CHAR (g
);
624 if (! char_charset (c
, charset_list
, NULL
))
626 buf
+= CHAR_STRING (c
, buf
);
630 for (i
= 0; i
< cmp
->glyph_len
; i
++)
632 int c
= COMPOSITION_GLYPH (cmp
, i
);
636 if (char_charset (c
, charset_list
, NULL
))
638 if (CHAR_WIDTH (c
) == 0
639 && i
> 0 && COMPOSITION_GLYPH (cmp
, i
- 1) == '\t')
640 /* Should be left-padded */
642 buf
+= CHAR_STRING (' ', buf
);
648 buf
+= CHAR_STRING (c
, buf
);
652 /* We must skip glyphs to be padded for a wide character. */
653 else if (! CHAR_GLYPH_PADDING_P (*src
))
660 SET_GLYPH_FROM_CHAR_GLYPH (g
, src
[0]);
662 if (GLYPH_INVALID_P (g
) || GLYPH_SIMPLE_P (tbase
, tlen
, g
))
664 /* This glyph doesn't have an entry in Vglyph_table. */
669 /* This glyph has an entry in Vglyph_table,
670 so process any alias before testing for simpleness. */
671 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
673 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
674 /* We set the multi-byte form of a character in G
675 (that should be an ASCII character) at WORKBUF. */
678 /* We have a string in Vglyph_table. */
679 string
= tbase
[GLYPH_CHAR (g
)];
684 nbytes
= buf
- encode_terminal_src
;
685 if (encode_terminal_src_size
< nbytes
+ MAX_MULTIBYTE_LENGTH
)
687 encode_terminal_src_size
= nbytes
+ MAX_MULTIBYTE_LENGTH
;
688 encode_terminal_src
= xrealloc (encode_terminal_src
,
689 encode_terminal_src_size
);
690 buf
= encode_terminal_src
+ nbytes
;
692 if (char_charset (c
, charset_list
, NULL
))
694 /* Store the multibyte form of C at BUF. */
695 buf
+= CHAR_STRING (c
, buf
);
700 /* C is not encodable. */
703 while (src
+ 1 < src_end
&& CHAR_GLYPH_PADDING_P (src
[1]))
713 unsigned char *p
= SDATA (string
);
715 if (! STRING_MULTIBYTE (string
))
716 string
= string_to_multibyte (string
);
717 nbytes
= buf
- encode_terminal_src
;
718 if (encode_terminal_src_size
< nbytes
+ SBYTES (string
))
720 encode_terminal_src_size
= nbytes
+ SBYTES (string
);
721 encode_terminal_src
= xrealloc (encode_terminal_src
,
722 encode_terminal_src_size
);
723 buf
= encode_terminal_src
+ nbytes
;
725 memcpy (buf
, SDATA (string
), SBYTES (string
));
726 buf
+= SBYTES (string
);
727 nchars
+= SCHARS (string
);
735 coding
->produced
= 0;
739 nbytes
= buf
- encode_terminal_src
;
740 coding
->source
= encode_terminal_src
;
741 if (encode_terminal_dst_size
== 0)
743 encode_terminal_dst_size
= encode_terminal_src_size
;
744 if (encode_terminal_dst
)
745 encode_terminal_dst
= xrealloc (encode_terminal_dst
,
746 encode_terminal_dst_size
);
748 encode_terminal_dst
= xmalloc (encode_terminal_dst_size
);
750 coding
->destination
= encode_terminal_dst
;
751 coding
->dst_bytes
= encode_terminal_dst_size
;
752 encode_coding_object (coding
, Qnil
, 0, 0, nchars
, nbytes
, Qnil
);
753 /* coding->destination may have been reallocated. */
754 encode_terminal_dst
= coding
->destination
;
755 encode_terminal_dst_size
= coding
->dst_bytes
;
757 return (encode_terminal_dst
);
762 /* An implementation of write_glyphs for termcap frames. */
765 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
767 unsigned char *conversion_buffer
;
768 struct coding_system
*coding
;
770 struct tty_display_info
*tty
= FRAME_TTY (f
);
772 tty_turn_off_insert (tty
);
773 tty_hide_cursor (tty
);
775 /* Don't dare write in last column of bottom line, if Auto-Wrap,
776 since that would scroll the whole frame on some terminals. */
779 && curY (tty
) + 1 == FRAME_LINES (f
)
780 && (curX (tty
) + len
) == FRAME_COLS (f
))
787 /* If terminal_coding does any conversion, use it, otherwise use
788 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
789 because it always return 1 if the member src_multibyte is 1. */
790 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
791 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
792 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
794 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
798 /* Identify a run of glyphs with the same face. */
799 int face_id
= string
->face_id
;
802 for (n
= 1; n
< len
; ++n
)
803 if (string
[n
].face_id
!= face_id
)
806 /* Turn appearance modes of the face of the run on. */
807 tty_highlight_if_desired (tty
);
808 turn_on_face (f
, face_id
);
811 /* This is the last run. */
812 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
813 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
814 if (coding
->produced
> 0)
817 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
818 if (ferror (tty
->output
))
819 clearerr (tty
->output
);
821 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
827 /* Turn appearance modes off. */
828 turn_off_face (f
, face_id
);
829 tty_turn_off_highlight (tty
);
835 #ifdef HAVE_GPM /* Only used by GPM code. */
838 tty_write_glyphs_with_face (register struct frame
*f
, register struct glyph
*string
,
839 register int len
, register int face_id
)
841 unsigned char *conversion_buffer
;
842 struct coding_system
*coding
;
844 struct tty_display_info
*tty
= FRAME_TTY (f
);
846 tty_turn_off_insert (tty
);
847 tty_hide_cursor (tty
);
849 /* Don't dare write in last column of bottom line, if Auto-Wrap,
850 since that would scroll the whole frame on some terminals. */
853 && curY (tty
) + 1 == FRAME_LINES (f
)
854 && (curX (tty
) + len
) == FRAME_COLS (f
))
861 /* If terminal_coding does any conversion, use it, otherwise use
862 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
863 because it always return 1 if the member src_multibyte is 1. */
864 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
865 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
866 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
868 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
870 /* Turn appearance modes of the face. */
871 tty_highlight_if_desired (tty
);
872 turn_on_face (f
, face_id
);
874 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
875 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
876 if (coding
->produced
> 0)
879 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
880 if (ferror (tty
->output
))
881 clearerr (tty
->output
);
883 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
887 /* Turn appearance modes off. */
888 turn_off_face (f
, face_id
);
889 tty_turn_off_highlight (tty
);
895 /* An implementation of insert_glyphs for termcap frames. */
898 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
901 struct glyph
*glyph
= NULL
;
902 unsigned char *conversion_buffer
;
903 unsigned char space
[1];
904 struct coding_system
*coding
;
906 struct tty_display_info
*tty
= FRAME_TTY (f
);
908 if (tty
->TS_ins_multi_chars
)
910 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
914 write_glyphs (f
, start
, len
);
918 tty_turn_on_insert (tty
);
922 space
[0] = SPACEGLYPH
;
924 /* If terminal_coding does any conversion, use it, otherwise use
925 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
926 because it always return 1 if the member src_multibyte is 1. */
927 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
928 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
929 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
931 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
935 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
938 conversion_buffer
= space
;
939 coding
->produced
= 1;
943 tty_highlight_if_desired (tty
);
944 turn_on_face (f
, start
->face_id
);
947 /* We must open sufficient space for a character which
948 occupies more than one column. */
949 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
951 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
956 /* This is the last glyph. */
957 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
959 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
962 if (coding
->produced
> 0)
965 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
966 if (ferror (tty
->output
))
967 clearerr (tty
->output
);
969 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
973 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
976 turn_off_face (f
, glyph
->face_id
);
977 tty_turn_off_highlight (tty
);
984 /* An implementation of delete_glyphs for termcap frames. */
987 tty_delete_glyphs (struct frame
*f
, int n
)
992 struct tty_display_info
*tty
= FRAME_TTY (f
);
994 if (tty
->delete_in_insert_mode
)
996 tty_turn_on_insert (tty
);
1000 tty_turn_off_insert (tty
);
1001 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
1004 if (tty
->TS_del_multi_chars
)
1006 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
1011 for (i
= 0; i
< n
; i
++)
1012 OUTPUT1 (tty
, tty
->TS_del_char
);
1013 if (!tty
->delete_in_insert_mode
)
1014 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
1017 /* An implementation of ins_del_lines for termcap frames. */
1020 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
1022 struct tty_display_info
*tty
= FRAME_TTY (f
);
1023 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
1024 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
1025 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
1027 register int i
= n
> 0 ? n
: -n
;
1030 /* If the lines below the insertion are being pushed
1031 into the end of the window, this is the same as clearing;
1032 and we know the lines are already clear, since the matching
1033 deletion has already been done. So can ignore this. */
1034 /* If the lines below the deletion are blank lines coming
1035 out of the end of the window, don't bother,
1036 as there will be a matching inslines later that will flush them. */
1037 if (FRAME_SCROLL_REGION_OK (f
)
1038 && vpos
+ i
>= tty
->specified_window
)
1040 if (!FRAME_MEMORY_BELOW_FRAME (f
)
1041 && vpos
+ i
>= FRAME_LINES (f
))
1046 raw_cursor_to (f
, vpos
, 0);
1047 tty_background_highlight (tty
);
1048 buf
= tparam (multi
, 0, 0, i
);
1054 raw_cursor_to (f
, vpos
, 0);
1055 tty_background_highlight (tty
);
1057 OUTPUT (tty
, single
);
1058 if (tty
->TF_teleray
)
1063 tty_set_scroll_region (f
, vpos
, tty
->specified_window
);
1065 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
1067 raw_cursor_to (f
, vpos
, 0);
1068 tty_background_highlight (tty
);
1070 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1071 tty_set_scroll_region (f
, 0, tty
->specified_window
);
1074 if (!FRAME_SCROLL_REGION_OK (f
)
1075 && FRAME_MEMORY_BELOW_FRAME (f
)
1078 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
1083 /* Compute cost of sending "str", in characters,
1084 not counting any line-dependent padding. */
1087 string_cost (char *str
)
1091 tputs (str
, 0, evalcost
);
1095 /* Compute cost of sending "str", in characters,
1096 counting any line-dependent padding at one line. */
1099 string_cost_one_line (char *str
)
1103 tputs (str
, 1, evalcost
);
1107 /* Compute per line amount of line-dependent padding,
1108 in tenths of characters. */
1111 per_line_cost (char *str
)
1115 tputs (str
, 0, evalcost
);
1118 tputs (str
, 10, evalcost
);
1123 /* char_ins_del_cost[n] is cost of inserting N characters.
1124 char_ins_del_cost[-n] is cost of deleting N characters.
1125 The length of this vector is based on max_frame_cols. */
1127 int *char_ins_del_vector
;
1129 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1134 calculate_ins_del_char_costs (struct frame
*f
)
1136 struct tty_display_info
*tty
= FRAME_TTY (f
);
1137 int ins_startup_cost
, del_startup_cost
;
1138 int ins_cost_per_char
, del_cost_per_char
;
1142 if (tty
->TS_ins_multi_chars
)
1144 ins_cost_per_char
= 0;
1145 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1147 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1148 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1150 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1151 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1152 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1153 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1157 ins_startup_cost
= 9999;
1158 ins_cost_per_char
= 0;
1161 if (tty
->TS_del_multi_chars
)
1163 del_cost_per_char
= 0;
1164 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1166 else if (tty
->TS_del_char
)
1168 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1169 + string_cost (tty
->TS_end_delete_mode
));
1170 if (tty
->delete_in_insert_mode
)
1171 del_startup_cost
/= 2;
1172 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1176 del_startup_cost
= 9999;
1177 del_cost_per_char
= 0;
1180 /* Delete costs are at negative offsets */
1181 p
= &char_ins_del_cost (f
)[0];
1182 for (i
= FRAME_COLS (f
); --i
>= 0;)
1183 *--p
= (del_startup_cost
+= del_cost_per_char
);
1185 /* Doing nothing is free */
1186 p
= &char_ins_del_cost (f
)[0];
1189 /* Insert costs are at positive offsets */
1190 for (i
= FRAME_COLS (f
); --i
>= 0;)
1191 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1195 calculate_costs (struct frame
*frame
)
1197 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1199 if (FRAME_TERMCAP_P (frame
))
1201 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1202 register char *f
= (tty
->TS_set_scroll_region
1203 ? tty
->TS_set_scroll_region
1204 : tty
->TS_set_scroll_region_1
);
1206 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1210 /* These variables are only used for terminal stuff. They are
1211 allocated once for the terminal frame of X-windows emacs, but not
1214 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1215 X turns off char_ins_del_ok. */
1217 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1218 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1220 if (char_ins_del_vector
!= 0)
1222 = (int *) xrealloc (char_ins_del_vector
,
1224 + 2 * max_frame_cols
* sizeof (int)));
1227 = (int *) xmalloc (sizeof (int)
1228 + 2 * max_frame_cols
* sizeof (int));
1230 memset (char_ins_del_vector
, 0,
1231 (sizeof (int) + 2 * max_frame_cols
* sizeof (int)));
1234 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1235 do_line_insertion_deletion_costs (frame
,
1236 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1237 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1240 do_line_insertion_deletion_costs (frame
,
1241 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1242 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1245 calculate_ins_del_char_costs (frame
);
1247 /* Don't use TS_repeat if its padding is worse than sending the chars */
1248 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1249 tty
->RPov
= string_cost (tty
->TS_repeat
);
1251 tty
->RPov
= FRAME_COLS (frame
) * 2;
1253 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1261 /* Termcap capability names that correspond directly to X keysyms.
1262 Some of these (marked "terminfo") aren't supplied by old-style
1263 (Berkeley) termcap entries. They're listed in X keysym order;
1264 except we put the keypad keys first, so that if they clash with
1265 other keys (as on the IBM PC keyboard) they get overridden.
1268 static struct fkey_table keys
[] =
1270 {"kh", "home"}, /* termcap */
1271 {"kl", "left"}, /* termcap */
1272 {"ku", "up"}, /* termcap */
1273 {"kr", "right"}, /* termcap */
1274 {"kd", "down"}, /* termcap */
1275 {"%8", "prior"}, /* terminfo */
1276 {"%5", "next"}, /* terminfo */
1277 {"@7", "end"}, /* terminfo */
1278 {"@1", "begin"}, /* terminfo */
1279 {"*6", "select"}, /* terminfo */
1280 {"%9", "print"}, /* terminfo */
1281 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1283 * "insert" --- see below
1285 {"&8", "undo"}, /* terminfo */
1286 {"%0", "redo"}, /* terminfo */
1287 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1288 {"@0", "find"}, /* terminfo */
1289 {"@2", "cancel"}, /* terminfo */
1290 {"%1", "help"}, /* terminfo */
1292 * "break" goes here, but can't be reliably intercepted with termcap
1294 {"&4", "reset"}, /* terminfo --- actually `restart' */
1296 * "system" and "user" --- no termcaps
1298 {"kE", "clearline"}, /* terminfo */
1299 {"kA", "insertline"}, /* terminfo */
1300 {"kL", "deleteline"}, /* terminfo */
1301 {"kI", "insertchar"}, /* terminfo */
1302 {"kD", "deletechar"}, /* terminfo */
1303 {"kB", "backtab"}, /* terminfo */
1305 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1307 {"@8", "kp-enter"}, /* terminfo */
1309 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1310 * "kp-multiply", "kp-add", "kp-separator",
1311 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1312 * --- no termcaps for any of these.
1314 {"K4", "kp-1"}, /* terminfo */
1316 * "kp-2" --- no termcap
1318 {"K5", "kp-3"}, /* terminfo */
1320 * "kp-4" --- no termcap
1322 {"K2", "kp-5"}, /* terminfo */
1324 * "kp-6" --- no termcap
1326 {"K1", "kp-7"}, /* terminfo */
1328 * "kp-8" --- no termcap
1330 {"K3", "kp-9"}, /* terminfo */
1332 * "kp-equal" --- no termcap
1344 {"&0", "S-cancel"}, /*shifted cancel key*/
1345 {"&9", "S-begin"}, /*shifted begin key*/
1346 {"*0", "S-find"}, /*shifted find key*/
1347 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1348 {"*4", "S-delete"}, /*shifted delete-character key*/
1349 {"*7", "S-end"}, /*shifted end key*/
1350 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1351 {"#1", "S-help"}, /*shifted help key*/
1352 {"#2", "S-home"}, /*shifted home key*/
1353 {"#3", "S-insert"}, /*shifted insert-character key*/
1354 {"#4", "S-left"}, /*shifted left-arrow key*/
1355 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1356 {"%c", "S-next"}, /*shifted next key*/
1357 {"%e", "S-prior"}, /*shifted previous key*/
1358 {"%f", "S-print"}, /*shifted print key*/
1359 {"%g", "S-redo"}, /*shifted redo key*/
1360 {"%i", "S-right"}, /*shifted right-arrow key*/
1361 {"!3", "S-undo"} /*shifted undo key*/
1365 static char **term_get_fkeys_address
;
1366 static KBOARD
*term_get_fkeys_kboard
;
1367 static Lisp_Object
term_get_fkeys_1 (void);
1369 /* Find the escape codes sent by the function keys for Vinput_decode_map.
1370 This function scans the termcap function key sequence entries, and
1371 adds entries to Vinput_decode_map for each function key it finds. */
1374 term_get_fkeys (char **address
, KBOARD
*kboard
)
1376 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1377 errors during the call. The only errors should be from Fdefine_key
1378 when given a key sequence containing an invalid prefix key. If the
1379 termcap defines function keys which use a prefix that is already bound
1380 to a command by the default bindings, we should silently ignore that
1381 function key specification, rather than giving the user an error and
1382 refusing to run at all on such a terminal. */
1384 term_get_fkeys_address
= address
;
1385 term_get_fkeys_kboard
= kboard
;
1386 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1390 term_get_fkeys_1 (void)
1394 char **address
= term_get_fkeys_address
;
1395 KBOARD
*kboard
= term_get_fkeys_kboard
;
1397 /* This can happen if CANNOT_DUMP or with strange options. */
1398 if (!KEYMAPP (kboard
->Vinput_decode_map
))
1399 kboard
->Vinput_decode_map
= Fmake_sparse_keymap (Qnil
);
1401 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1403 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1405 Fdefine_key (kboard
->Vinput_decode_map
, build_string (sequence
),
1406 Fmake_vector (make_number (1),
1407 intern (keys
[i
].name
)));
1410 /* The uses of the "k0" capability are inconsistent; sometimes it
1411 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1412 We will attempt to politely accommodate both systems by testing for
1413 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1416 char *k_semi
= tgetstr ("k;", address
);
1417 char *k0
= tgetstr ("k0", address
);
1418 char *k0_name
= "f10";
1423 /* Define f0 first, so that f10 takes precedence in case the
1424 key sequences happens to be the same. */
1425 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k0
),
1426 Fmake_vector (make_number (1), intern ("f0")));
1427 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k_semi
),
1428 Fmake_vector (make_number (1), intern ("f10")));
1431 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k0
),
1432 Fmake_vector (make_number (1), intern (k0_name
)));
1435 /* Set up cookies for numbered function keys above f10. */
1437 char fcap
[3], fkey
[4];
1439 fcap
[0] = 'F'; fcap
[2] = '\0';
1440 for (i
= 11; i
< 64; i
++)
1443 fcap
[1] = '1' + i
- 11;
1445 fcap
[1] = 'A' + i
- 20;
1447 fcap
[1] = 'a' + i
- 46;
1450 char *sequence
= tgetstr (fcap
, address
);
1453 sprintf (fkey
, "f%d", i
);
1454 Fdefine_key (kboard
->Vinput_decode_map
, build_string (sequence
),
1455 Fmake_vector (make_number (1),
1463 * Various mappings to try and get a better fit.
1466 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1467 if (!tgetstr (cap1, address)) \
1469 char *sequence = tgetstr (cap2, address); \
1471 Fdefine_key (kboard->Vinput_decode_map, build_string (sequence), \
1472 Fmake_vector (make_number (1), \
1476 /* if there's no key_next keycap, map key_npage to `next' keysym */
1477 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1478 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1479 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1480 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1481 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1482 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1483 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1485 /* IBM has their own non-standard dialect of terminfo.
1486 If the standard name isn't found, try the IBM name. */
1487 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1488 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1489 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1490 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1491 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1492 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1493 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1494 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1495 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1496 #undef CONDITIONAL_REASSIGN
1501 #endif /* not DOS_NT */
1504 /***********************************************************************
1505 Character Display Information
1506 ***********************************************************************/
1508 /* Avoid name clash with functions defined in xterm.c */
1510 #define append_glyph append_glyph_term
1511 #define produce_stretch_glyph produce_stretch_glyph_term
1512 #define append_composite_glyph append_composite_glyph_term
1513 #define produce_composite_glyph produce_composite_glyph_term
1516 static void append_glyph (struct it
*);
1517 static void produce_stretch_glyph (struct it
*);
1518 static void append_composite_glyph (struct it
*);
1519 static void produce_composite_glyph (struct it
*);
1521 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1522 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1523 the character for which to produce glyphs; IT->face_id contains the
1524 character's face. Padding glyphs are appended if IT->c has a
1525 IT->pixel_width > 1. */
1528 append_glyph (struct it
*it
)
1530 struct glyph
*glyph
, *end
;
1533 xassert (it
->glyph_row
);
1534 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1535 + it
->glyph_row
->used
[it
->area
]);
1536 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1538 /* If the glyph row is reversed, we need to prepend the glyph rather
1540 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1543 int move_by
= it
->pixel_width
;
1545 /* Make room for the new glyphs. */
1546 if (move_by
> end
- glyph
) /* don't overstep end of this area */
1547 move_by
= end
- glyph
;
1548 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1550 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1551 end
= glyph
+ move_by
;
1554 /* BIDI Note: we put the glyphs of a "multi-pixel" character left to
1555 right, even in the REVERSED_P case, since (a) all of its u.ch are
1556 identical, and (b) the PADDING_P flag needs to be set for the
1557 leftmost one, because we write to the terminal left-to-right. */
1559 i
< it
->pixel_width
&& glyph
< end
;
1562 glyph
->type
= CHAR_GLYPH
;
1563 glyph
->pixel_width
= 1;
1564 glyph
->u
.ch
= it
->char_to_display
;
1565 glyph
->face_id
= it
->face_id
;
1566 glyph
->padding_p
= i
> 0;
1567 glyph
->charpos
= CHARPOS (it
->position
);
1568 glyph
->object
= it
->object
;
1571 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1572 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1574 glyph
->bidi_type
= it
->bidi_it
.type
;
1578 glyph
->resolved_level
= 0;
1579 glyph
->bidi_type
= UNKNOWN_BT
;
1582 ++it
->glyph_row
->used
[it
->area
];
1587 /* Produce glyphs for the display element described by IT. *IT
1588 specifies what we want to produce a glyph for (character, image, ...),
1589 and where in the glyph matrix we currently are (glyph row and hpos).
1590 produce_glyphs fills in output fields of *IT with information such as the
1591 pixel width and height of a character, and maybe output actual glyphs at
1592 the same time if IT->glyph_row is non-null. For an overview, see
1593 the explanation in dispextern.h, before the definition of the
1594 display_element_type enumeration.
1596 produce_glyphs also stores the result of glyph width, ascent
1597 etc. computations in *IT.
1599 IT->glyph_row may be null, in which case produce_glyphs does not
1600 actually fill in the glyphs. This is used in the move_* functions
1601 in xdisp.c for text width and height computations.
1603 Callers usually don't call produce_glyphs directly;
1604 instead they use the macro PRODUCE_GLYPHS. */
1607 produce_glyphs (struct it
*it
)
1609 /* If a hook is installed, let it do the work. */
1611 /* Nothing but characters are supported on terminal frames. */
1612 xassert (it
->what
== IT_CHARACTER
1613 || it
->what
== IT_COMPOSITION
1614 || it
->what
== IT_STRETCH
);
1616 if (it
->what
== IT_STRETCH
)
1618 produce_stretch_glyph (it
);
1622 if (it
->what
== IT_COMPOSITION
)
1624 produce_composite_glyph (it
);
1628 /* Maybe translate single-byte characters to multibyte. */
1629 it
->char_to_display
= it
->c
;
1631 if (it
->c
>= 040 && it
->c
< 0177)
1633 it
->pixel_width
= it
->nglyphs
= 1;
1637 else if (it
->c
== '\n')
1638 it
->pixel_width
= it
->nglyphs
= 0;
1639 else if (it
->c
== '\t')
1641 int absolute_x
= (it
->current_x
1642 + it
->continuation_lines_width
);
1644 = (((1 + absolute_x
+ it
->tab_width
- 1)
1649 /* If part of the TAB has been displayed on the previous line
1650 which is continued now, continuation_lines_width will have
1651 been incremented already by the part that fitted on the
1652 continued line. So, we will get the right number of spaces
1654 nspaces
= next_tab_x
- absolute_x
;
1660 it
->char_to_display
= ' ';
1661 it
->pixel_width
= it
->len
= 1;
1667 it
->pixel_width
= nspaces
;
1668 it
->nglyphs
= nspaces
;
1670 else if (CHAR_BYTE8_P (it
->c
))
1672 if (unibyte_display_via_language_environment
1675 it
->char_to_display
= BYTE8_TO_CHAR (it
->c
);
1676 it
->pixel_width
= CHAR_WIDTH (it
->char_to_display
);
1677 it
->nglyphs
= it
->pixel_width
;
1683 /* Coming here means that it->c is from display table, thus
1684 we must send the raw 8-bit byte as is to the terminal.
1685 Although there's no way to know how many columns it
1686 occupies on a screen, it is a good assumption that a
1687 single byte code has 1-column width. */
1688 it
->pixel_width
= it
->nglyphs
= 1;
1695 it
->pixel_width
= CHAR_WIDTH (it
->c
);
1696 it
->nglyphs
= it
->pixel_width
;
1703 /* Advance current_x by the pixel width as a convenience for
1705 if (it
->area
== TEXT_AREA
)
1706 it
->current_x
+= it
->pixel_width
;
1707 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1708 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1712 /* Produce a stretch glyph for iterator IT. IT->object is the value
1713 of the glyph property displayed. The value must be a list
1714 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1717 1. `:width WIDTH' specifies that the space should be WIDTH *
1718 canonical char width wide. WIDTH may be an integer or floating
1721 2. `:align-to HPOS' specifies that the space should be wide enough
1722 to reach HPOS, a value in canonical character units. */
1725 produce_stretch_glyph (struct it
*it
)
1727 /* (space :width WIDTH ...) */
1728 Lisp_Object prop
, plist
;
1729 int width
= 0, align_to
= -1;
1730 int zero_width_ok_p
= 0;
1733 /* List should start with `space'. */
1734 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1735 plist
= XCDR (it
->object
);
1737 /* Compute the width of the stretch. */
1738 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1739 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1741 /* Absolute width `:width WIDTH' specified and valid. */
1742 zero_width_ok_p
= 1;
1743 width
= (int)(tem
+ 0.5);
1745 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1746 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1748 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1749 align_to
= (align_to
< 0
1751 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1752 else if (align_to
< 0)
1753 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1754 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1755 zero_width_ok_p
= 1;
1758 /* Nothing specified -> width defaults to canonical char width. */
1759 width
= FRAME_COLUMN_WIDTH (it
->f
);
1761 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1764 if (width
> 0 && it
->line_wrap
!= TRUNCATE
1765 && it
->current_x
+ width
> it
->last_visible_x
)
1766 width
= it
->last_visible_x
- it
->current_x
- 1;
1768 if (width
> 0 && it
->glyph_row
)
1770 Lisp_Object o_object
= it
->object
;
1771 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1774 if (!STRINGP (object
))
1775 object
= it
->w
->buffer
;
1776 it
->object
= object
;
1777 it
->char_to_display
= ' ';
1778 it
->pixel_width
= it
->len
= 1;
1781 it
->object
= o_object
;
1783 it
->pixel_width
= width
;
1784 it
->nglyphs
= width
;
1788 /* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
1789 Called from produce_composite_glyph for terminal frames if
1790 IT->glyph_row != NULL. IT->face_id contains the character's
1794 append_composite_glyph (struct it
*it
)
1796 struct glyph
*glyph
;
1798 xassert (it
->glyph_row
);
1799 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1800 if (glyph
< it
->glyph_row
->glyphs
[1 + it
->area
])
1802 /* If the glyph row is reversed, we need to prepend the glyph
1803 rather than append it. */
1804 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1808 /* Make room for the new glyph. */
1809 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1811 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1813 glyph
->type
= COMPOSITE_GLYPH
;
1814 glyph
->pixel_width
= it
->pixel_width
;
1815 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1816 if (it
->cmp_it
.ch
< 0)
1818 glyph
->u
.cmp
.automatic
= 0;
1819 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1823 glyph
->u
.cmp
.automatic
= 1;
1824 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1825 glyph
->u
.cmp
.from
= it
->cmp_it
.from
;
1826 glyph
->u
.cmp
.to
= it
->cmp_it
.to
- 1;
1829 glyph
->face_id
= it
->face_id
;
1830 glyph
->padding_p
= 0;
1831 glyph
->charpos
= CHARPOS (it
->position
);
1832 glyph
->object
= it
->object
;
1835 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1836 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1838 glyph
->bidi_type
= it
->bidi_it
.type
;
1842 glyph
->resolved_level
= 0;
1843 glyph
->bidi_type
= UNKNOWN_BT
;
1846 ++it
->glyph_row
->used
[it
->area
];
1852 /* Produce a composite glyph for iterator IT. IT->cmp_id is the ID of
1853 the composition. We simply produces components of the composition
1854 assuming that the terminal has a capability to layout/render it
1858 produce_composite_glyph (struct it
*it
)
1860 if (it
->cmp_it
.ch
< 0)
1862 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
1864 it
->pixel_width
= cmp
->width
;
1868 Lisp_Object gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
1870 it
->pixel_width
= composition_gstring_width (gstring
, it
->cmp_it
.from
,
1871 it
->cmp_it
.to
, NULL
);
1875 append_composite_glyph (it
);
1879 /* Get information about special display element WHAT in an
1880 environment described by IT. WHAT is one of IT_TRUNCATION or
1881 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1882 non-null glyph_row member. This function ensures that fields like
1883 face_id, c, len of IT are left untouched. */
1886 produce_special_glyphs (struct it
*it
, enum display_element_type what
)
1894 temp_it
.what
= IT_CHARACTER
;
1896 temp_it
.object
= make_number (0);
1897 memset (&temp_it
.current
, 0, sizeof temp_it
.current
);
1899 if (what
== IT_CONTINUATION
)
1901 /* Continuation glyph. For R2L lines, we mirror it by hand. */
1902 if (it
->bidi_it
.paragraph_dir
== R2L
)
1903 SET_GLYPH_FROM_CHAR (glyph
, '/');
1905 SET_GLYPH_FROM_CHAR (glyph
, '\\');
1907 && (gc
= DISP_CONTINUE_GLYPH (it
->dp
), GLYPH_CODE_P (gc
))
1908 && GLYPH_CODE_CHAR_VALID_P (gc
))
1910 /* FIXME: Should we mirror GC for R2L lines? */
1911 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
1912 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
1915 else if (what
== IT_TRUNCATION
)
1917 /* Truncation glyph. */
1918 SET_GLYPH_FROM_CHAR (glyph
, '$');
1920 && (gc
= DISP_TRUNC_GLYPH (it
->dp
), GLYPH_CODE_P (gc
))
1921 && GLYPH_CODE_CHAR_VALID_P (gc
))
1923 /* FIXME: Should we mirror GC for R2L lines? */
1924 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
1925 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
1931 temp_it
.c
= GLYPH_CHAR (glyph
);
1932 temp_it
.face_id
= GLYPH_FACE (glyph
);
1933 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1935 produce_glyphs (&temp_it
);
1936 it
->pixel_width
= temp_it
.pixel_width
;
1937 it
->nglyphs
= temp_it
.pixel_width
;
1942 /***********************************************************************
1944 ***********************************************************************/
1946 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1947 one of the enumerators from enum no_color_bit, or a bit set built
1948 from them. Some display attributes may not be used together with
1949 color; the termcap capability `NC' specifies which ones. */
1951 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1952 (tty->TN_max_colors > 0 \
1953 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1956 /* Turn appearances of face FACE_ID on tty frame F on.
1957 FACE_ID is a realized face ID number, in the face cache. */
1960 turn_on_face (struct frame
*f
, int face_id
)
1962 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1963 long fg
= face
->foreground
;
1964 long bg
= face
->background
;
1965 struct tty_display_info
*tty
= FRAME_TTY (f
);
1967 /* Do this first because TS_end_standout_mode may be the same
1968 as TS_exit_attribute_mode, which turns all appearances off. */
1969 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1971 if (tty
->TN_max_colors
> 0)
1973 if (fg
>= 0 && bg
>= 0)
1975 /* If the terminal supports colors, we can set them
1976 below without using reverse video. The face's fg
1977 and bg colors are set as they should appear on
1978 the screen, i.e. they take the inverse-video'ness
1979 of the face already into account. */
1981 else if (inverse_video
)
1983 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1984 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1985 tty_toggle_highlight (tty
);
1989 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1990 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1991 tty_toggle_highlight (tty
);
1996 /* If we can't display colors, use reverse video
1997 if the face specifies that. */
2000 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
2001 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
2002 tty_toggle_highlight (tty
);
2006 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
2007 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
2008 tty_toggle_highlight (tty
);
2013 if (face
->tty_bold_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
2014 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
2016 if (face
->tty_dim_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
2017 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
2019 /* Alternate charset and blinking not yet used. */
2020 if (face
->tty_alt_charset_p
2021 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
2022 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
2024 if (face
->tty_blinking_p
2025 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
2026 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
2028 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
2029 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
2031 if (tty
->TN_max_colors
> 0)
2035 ts
= tty
->standout_mode
? tty
->TS_set_background
: tty
->TS_set_foreground
;
2038 p
= tparam (ts
, NULL
, 0, (int) fg
);
2043 ts
= tty
->standout_mode
? tty
->TS_set_foreground
: tty
->TS_set_background
;
2046 p
= tparam (ts
, NULL
, 0, (int) bg
);
2054 /* Turn off appearances of face FACE_ID on tty frame F. */
2057 turn_off_face (struct frame
*f
, int face_id
)
2059 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2060 struct tty_display_info
*tty
= FRAME_TTY (f
);
2062 xassert (face
!= NULL
);
2064 if (tty
->TS_exit_attribute_mode
)
2066 /* Capability "me" will turn off appearance modes double-bright,
2067 half-bright, reverse-video, standout, underline. It may or
2068 may not turn off alt-char-mode. */
2069 if (face
->tty_bold_p
2071 || face
->tty_reverse_p
2072 || face
->tty_alt_charset_p
2073 || face
->tty_blinking_p
2074 || face
->tty_underline_p
)
2076 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
2077 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
2078 tty
->standout_mode
= 0;
2081 if (face
->tty_alt_charset_p
)
2082 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
2086 /* If we don't have "me" we can only have those appearances
2087 that have exit sequences defined. */
2088 if (face
->tty_alt_charset_p
)
2089 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
2091 if (face
->tty_underline_p
)
2092 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
2095 /* Switch back to default colors. */
2096 if (tty
->TN_max_colors
> 0
2097 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2098 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2099 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2100 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2101 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
2105 /* Return non-zero if the terminal on frame F supports all of the
2106 capabilities in CAPS simultaneously, with foreground and background
2107 colors FG and BG. */
2110 tty_capable_p (struct tty_display_info
*tty
, unsigned int caps
,
2111 unsigned long fg
, unsigned long bg
)
2113 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
2114 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
2117 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
2118 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
2119 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
2120 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
2121 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
2122 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
2128 /* Return non-zero if the terminal is capable to display colors. */
2130 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2132 doc
: /* Return non-nil if the tty device TERMINAL can display colors.
2134 TERMINAL can be a terminal object, a frame, or nil (meaning the
2135 selected frame's terminal). This function always returns nil if
2136 TERMINAL does not refer to a text-only terminal. */)
2137 (Lisp_Object terminal
)
2139 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2143 return t
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
2146 /* Return the number of supported colors. */
2147 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2148 Stty_display_color_cells
, 0, 1, 0,
2149 doc
: /* Return the number of colors supported by the tty device TERMINAL.
2151 TERMINAL can be a terminal object, a frame, or nil (meaning the
2152 selected frame's terminal). This function always returns 0 if
2153 TERMINAL does not refer to a text-only terminal. */)
2154 (Lisp_Object terminal
)
2156 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2158 return make_number (0);
2160 return make_number (t
->display_info
.tty
->TN_max_colors
);
2165 /* Declare here rather than in the function, as in the rest of Emacs,
2166 to work around an HPUX compiler bug (?). See
2167 http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00410.html */
2168 static int default_max_colors
;
2169 static int default_max_pairs
;
2170 static int default_no_color_video
;
2171 static char *default_orig_pair
;
2172 static char *default_set_foreground
;
2173 static char *default_set_background
;
2175 /* Save or restore the default color-related capabilities of this
2178 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
2183 xfree (default_orig_pair
);
2184 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
2186 xfree (default_set_foreground
);
2187 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
2190 xfree (default_set_background
);
2191 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
2194 default_max_colors
= tty
->TN_max_colors
;
2195 default_max_pairs
= tty
->TN_max_pairs
;
2196 default_no_color_video
= tty
->TN_no_color_video
;
2200 tty
->TS_orig_pair
= default_orig_pair
;
2201 tty
->TS_set_foreground
= default_set_foreground
;
2202 tty
->TS_set_background
= default_set_background
;
2203 tty
->TN_max_colors
= default_max_colors
;
2204 tty
->TN_max_pairs
= default_max_pairs
;
2205 tty
->TN_no_color_video
= default_no_color_video
;
2209 /* Setup one of the standard tty color schemes according to MODE.
2210 MODE's value is generally the number of colors which we want to
2211 support; zero means set up for the default capabilities, the ones
2212 we saw at init_tty time; -1 means turn off color support. */
2214 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2216 /* Canonicalize all negative values of MODE. */
2222 case -1: /* no colors at all */
2223 tty
->TN_max_colors
= 0;
2224 tty
->TN_max_pairs
= 0;
2225 tty
->TN_no_color_video
= 0;
2226 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2228 case 0: /* default colors, if any */
2230 tty_default_color_capabilities (tty
, 0);
2232 case 8: /* 8 standard ANSI colors */
2233 tty
->TS_orig_pair
= "\033[0m";
2235 tty
->TS_set_foreground
= "\033[3%p1%dm";
2236 tty
->TS_set_background
= "\033[4%p1%dm";
2238 tty
->TS_set_foreground
= "\033[3%dm";
2239 tty
->TS_set_background
= "\033[4%dm";
2241 tty
->TN_max_colors
= 8;
2242 tty
->TN_max_pairs
= 64;
2243 tty
->TN_no_color_video
= 0;
2249 set_tty_color_mode (struct tty_display_info
*tty
, struct frame
*f
)
2251 Lisp_Object tem
, val
;
2252 Lisp_Object color_mode
;
2254 Lisp_Object tty_color_mode_alist
2255 = Fintern_soft (build_string ("tty-color-mode-alist"), Qnil
);
2257 tem
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2258 val
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2262 else if (SYMBOLP (tty_color_mode_alist
))
2264 tem
= Fassq (val
, Fsymbol_value (tty_color_mode_alist
));
2265 color_mode
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2270 mode
= INTEGERP (color_mode
) ? XINT (color_mode
) : 0;
2272 if (mode
!= tty
->previous_color_mode
)
2274 Lisp_Object funsym
= intern ("tty-set-up-initial-frame-faces");
2275 tty
->previous_color_mode
= mode
;
2276 tty_setup_colors (tty
, mode
);
2277 /* This recomputes all the faces given the new color definitions. */
2278 safe_call (1, &funsym
);
2282 #endif /* !DOS_NT */
2286 /* Return the tty display object specified by TERMINAL. */
2289 get_tty_terminal (Lisp_Object terminal
, int throw)
2291 struct terminal
*t
= get_terminal (terminal
, throw);
2293 if (t
&& t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2296 error ("Device %d is not a termcap terminal device", t
->id
);
2304 /* Return an active termcap device that uses the tty device with the
2307 This function ignores suspended devices.
2309 Returns NULL if the named terminal device is not opened. */
2312 get_named_tty (char *name
)
2319 for (t
= terminal_list
; t
; t
= t
->next_terminal
)
2321 if ((t
->type
== output_termcap
|| t
->type
== output_msdos_raw
)
2322 && !strcmp (t
->display_info
.tty
->name
, name
)
2323 && TERMINAL_ACTIVE_P (t
))
2331 DEFUN ("tty-type", Ftty_type
, Stty_type
, 0, 1, 0,
2332 doc
: /* Return the type of the tty device that TERMINAL uses.
2333 Returns nil if TERMINAL is not on a tty device.
2335 TERMINAL can be a terminal object, a frame, or nil (meaning the
2336 selected frame's terminal). */)
2337 (Lisp_Object terminal
)
2339 struct terminal
*t
= get_terminal (terminal
, 1);
2341 if (t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2344 if (t
->display_info
.tty
->type
)
2345 return build_string (t
->display_info
.tty
->type
);
2350 DEFUN ("controlling-tty-p", Fcontrolling_tty_p
, Scontrolling_tty_p
, 0, 1, 0,
2351 doc
: /* Return non-nil if TERMINAL is the controlling tty of the Emacs process.
2353 TERMINAL can be a terminal object, a frame, or nil (meaning the
2354 selected frame's terminal). This function always returns nil if
2355 TERMINAL is not on a tty device. */)
2356 (Lisp_Object terminal
)
2358 struct terminal
*t
= get_terminal (terminal
, 1);
2360 if ((t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2361 || strcmp (t
->display_info
.tty
->name
, DEV_TTY
) != 0)
2367 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 1, 0,
2368 doc
: /* Declare that the tty used by TERMINAL does not handle underlining.
2369 This is used to override the terminfo data, for certain terminals that
2370 do not really do underlining, but say that they do. This function has
2371 no effect if used on a non-tty terminal.
2373 TERMINAL can be a terminal object, a frame or nil (meaning the
2374 selected frame's terminal). This function always returns nil if
2375 TERMINAL does not refer to a text-only terminal. */)
2376 (Lisp_Object terminal
)
2378 struct terminal
*t
= get_terminal (terminal
, 1);
2380 if (t
->type
== output_termcap
)
2381 t
->display_info
.tty
->TS_enter_underline_mode
= 0;
2387 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
2388 doc
: /* Suspend the terminal device TTY.
2390 The device is restored to its default state, and Emacs ceases all
2391 access to the tty device. Frames that use the device are not deleted,
2392 but input is not read from them and if they change, their display is
2395 TTY may be a terminal object, a frame, or nil for the terminal device
2396 of the currently selected frame.
2398 This function runs `suspend-tty-functions' after suspending the
2399 device. The functions are run with one arg, the id of the suspended
2402 `suspend-tty' does nothing if it is called on a device that is already
2405 A suspended tty may be resumed by calling `resume-tty' on it. */)
2408 struct terminal
*t
= get_tty_terminal (tty
, 1);
2412 error ("Unknown tty device");
2414 f
= t
->display_info
.tty
->input
;
2418 /* First run `suspend-tty-functions' and then clean up the tty
2419 state because `suspend-tty-functions' might need to change
2421 if (!NILP (Vrun_hooks
))
2423 Lisp_Object args
[2];
2424 args
[0] = intern ("suspend-tty-functions");
2425 XSETTERMINAL (args
[1], t
);
2426 Frun_hook_with_args (2, args
);
2429 reset_sys_modes (t
->display_info
.tty
);
2430 delete_keyboard_wait_descriptor (fileno (f
));
2434 if (f
!= t
->display_info
.tty
->output
)
2435 fclose (t
->display_info
.tty
->output
);
2438 t
->display_info
.tty
->input
= 0;
2439 t
->display_info
.tty
->output
= 0;
2441 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2442 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 0);
2446 /* Clear display hooks to prevent further output. */
2447 clear_tty_hooks (t
);
2452 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
2453 doc
: /* Resume the previously suspended terminal device TTY.
2454 The terminal is opened and reinitialized. Frames that are on the
2455 suspended terminal are revived.
2457 It is an error to resume a terminal while another terminal is active
2460 This function runs `resume-tty-functions' after resuming the terminal.
2461 The functions are run with one arg, the id of the resumed terminal
2464 `resume-tty' does nothing if it is called on a device that is not
2467 TTY may be a terminal object, a frame, or nil (meaning the selected
2468 frame's terminal). */)
2471 struct terminal
*t
= get_tty_terminal (tty
, 1);
2475 error ("Unknown tty device");
2477 if (!t
->display_info
.tty
->input
)
2479 if (get_named_tty (t
->display_info
.tty
->name
))
2480 error ("Cannot resume display while another display is active on the same device");
2483 t
->display_info
.tty
->output
= stdout
;
2484 t
->display_info
.tty
->input
= stdin
;
2486 fd
= emacs_open (t
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
2489 error ("Can not reopen tty device %s: %s", t
->display_info
.tty
->name
, strerror (errno
));
2491 if (strcmp (t
->display_info
.tty
->name
, DEV_TTY
))
2492 dissociate_if_controlling_tty (fd
);
2494 t
->display_info
.tty
->output
= fdopen (fd
, "w+");
2495 t
->display_info
.tty
->input
= t
->display_info
.tty
->output
;
2498 add_keyboard_wait_descriptor (fd
);
2500 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2502 struct frame
*f
= XFRAME (t
->display_info
.tty
->top_frame
);
2504 int old_height
= FRAME_COLS (f
);
2505 int old_width
= FRAME_LINES (f
);
2507 /* Check if terminal/window size has changed while the frame
2509 get_tty_size (fileno (t
->display_info
.tty
->input
), &width
, &height
);
2510 if (width
!= old_width
|| height
!= old_height
)
2511 change_frame_size (f
, height
, width
, 0, 0, 0);
2512 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 1);
2515 init_sys_modes (t
->display_info
.tty
);
2517 /* Run `resume-tty-functions'. */
2518 if (!NILP (Vrun_hooks
))
2520 Lisp_Object args
[2];
2521 args
[0] = intern ("resume-tty-functions");
2522 XSETTERMINAL (args
[1], t
);
2523 Frun_hook_with_args (2, args
);
2533 /***********************************************************************
2535 ***********************************************************************/
2539 term_mouse_moveto (int x
, int y
)
2541 /* TODO: how to set mouse position?
2544 name = (const char *) ttyname (0);
2545 fd = open (name, O_WRONLY);
2546 SOME_FUNCTION (x, y, fd);
2549 last_mouse_y = y; */
2553 term_show_mouse_face (enum draw_glyphs_face draw
)
2555 struct window
*w
= XWINDOW (mouse_face_window
);
2559 struct frame
*f
= XFRAME (w
->frame
);
2560 struct tty_display_info
*tty
= FRAME_TTY (f
);
2562 if (/* If window is in the process of being destroyed, don't bother
2564 w
->current_matrix
!= NULL
2565 /* Recognize when we are called to operate on rows that don't exist
2566 anymore. This can happen when a window is split. */
2567 && mouse_face_end_row
< w
->current_matrix
->nrows
)
2569 /* write_glyphs writes at cursor position, so we need to
2570 temporarily move cursor coordinates to the beginning of
2571 the highlight region. */
2573 /* Save current cursor co-ordinates */
2574 save_y
= curY (tty
);
2575 save_x
= curX (tty
);
2577 /* Note that mouse_face_beg_row etc. are window relative. */
2578 for (i
= mouse_face_beg_row
; i
<= mouse_face_end_row
; i
++)
2580 int start_hpos
, end_hpos
, nglyphs
;
2581 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
2583 /* Don't do anything if row doesn't have valid contents. */
2584 if (!row
->enabled_p
)
2587 /* For all but the first row, the highlight starts at column 0. */
2588 if (i
== mouse_face_beg_row
)
2589 start_hpos
= mouse_face_beg_col
;
2593 if (i
== mouse_face_end_row
)
2594 end_hpos
= mouse_face_end_col
;
2597 end_hpos
= row
->used
[TEXT_AREA
];
2598 if (draw
== DRAW_NORMAL_TEXT
)
2599 row
->fill_line_p
= 1; /* Clear to end of line */
2602 if (end_hpos
<= start_hpos
)
2604 /* Record that some glyphs of this row are displayed in
2606 row
->mouse_face_p
= draw
> 0;
2608 nglyphs
= end_hpos
- start_hpos
;
2610 if (end_hpos
>= row
->used
[TEXT_AREA
])
2611 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2613 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2614 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
2615 + WINDOW_LEFT_EDGE_X (w
);
2617 cursor_to (f
, pos_y
, pos_x
);
2619 if (draw
== DRAW_MOUSE_FACE
)
2621 tty_write_glyphs_with_face (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
,
2622 nglyphs
, mouse_face_face_id
);
2624 else /* draw == DRAW_NORMAL_TEXT */
2625 write_glyphs (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2627 cursor_to (f
, save_y
, save_x
);
2632 term_clear_mouse_face (void)
2634 if (!NILP (mouse_face_window
))
2635 term_show_mouse_face (DRAW_NORMAL_TEXT
);
2637 mouse_face_beg_row
= mouse_face_beg_col
= -1;
2638 mouse_face_end_row
= mouse_face_end_col
= -1;
2639 mouse_face_window
= Qnil
;
2642 /* Find the glyph matrix position of buffer position POS in window W.
2643 *HPOS and *VPOS are set to the positions found. W's current glyphs
2644 must be up to date. If POS is above window start return (0, 0).
2645 If POS is after end of W, return end of last line in W.
2646 - taken from msdos.c */
2648 fast_find_position (struct window
*w
, int pos
, int *hpos
, int *vpos
)
2650 int i
, lastcol
, line_start_position
, maybe_next_line_p
= 0;
2651 int yb
= window_text_bottom_y (w
);
2652 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0), *best_row
= row
;
2656 if (row
->used
[TEXT_AREA
])
2657 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
2659 line_start_position
= 0;
2661 if (line_start_position
> pos
)
2663 /* If the position sought is the end of the buffer,
2664 don't include the blank lines at the bottom of the window. */
2665 else if (line_start_position
== pos
2666 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
2668 maybe_next_line_p
= 1;
2671 else if (line_start_position
> 0)
2674 /* Don't overstep the last matrix row, lest we get into the
2675 never-never land... */
2676 if (row
->y
+ 1 >= yb
)
2682 /* Find the right column within BEST_ROW. */
2685 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
2687 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + i
;
2690 charpos
= glyph
->charpos
;
2697 else if (charpos
> pos
)
2699 else if (charpos
> 0)
2703 /* If we're looking for the end of the buffer,
2704 and we didn't find it in the line we scanned,
2705 use the start of the following line. */
2706 if (maybe_next_line_p
)
2713 *hpos
= lastcol
+ 1;
2718 term_mouse_highlight (struct frame
*f
, int x
, int y
)
2720 enum window_part part
;
2725 if (NILP (Vmouse_highlight
)
2726 || !f
->glyphs_initialized_p
)
2729 /* Which window is that in? */
2730 window
= window_from_coordinates (f
, x
, y
, &part
, &x
, &y
, 0);
2732 /* Not on a window -> return. */
2733 if (!WINDOWP (window
))
2736 if (!EQ (window
, mouse_face_window
))
2737 term_clear_mouse_face ();
2739 w
= XWINDOW (window
);
2741 /* Are we in a window whose display is up to date?
2742 And verify the buffer's text has not changed. */
2743 b
= XBUFFER (w
->buffer
);
2745 && EQ (w
->window_end_valid
, w
->buffer
)
2746 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
2747 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
2749 int pos
, i
, nrows
= w
->current_matrix
->nrows
;
2750 struct glyph_row
*row
;
2751 struct glyph
*glyph
;
2753 /* Find the glyph under X/Y. */
2755 if (y
>= 0 && y
< nrows
)
2757 row
= MATRIX_ROW (w
->current_matrix
, y
);
2758 /* Give up if some row before the one we are looking for is
2760 for (i
= 0; i
<= y
; i
++)
2761 if (!MATRIX_ROW (w
->current_matrix
, i
)->enabled_p
)
2763 if (i
> y
/* all rows upto and including the one at Y are enabled */
2764 && row
->displays_text_p
2765 && x
< window_box_width (w
, TEXT_AREA
))
2767 glyph
= row
->glyphs
[TEXT_AREA
];
2768 if (x
>= row
->used
[TEXT_AREA
])
2773 if (!BUFFERP (glyph
->object
))
2779 /* Clear mouse face if X/Y not over text. */
2782 term_clear_mouse_face ();
2786 if (!BUFFERP (glyph
->object
))
2788 pos
= glyph
->charpos
;
2790 /* Check for mouse-face. */
2792 Lisp_Object mouse_face
, overlay
, position
, *overlay_vec
;
2793 int noverlays
, obegv
, ozv
;
2794 struct buffer
*obuf
;
2796 /* If we get an out-of-range value, return now; avoid an error. */
2797 if (pos
> BUF_Z (b
))
2800 /* Make the window's buffer temporarily current for
2801 overlays_at and compute_char_face. */
2802 obuf
= current_buffer
;
2809 /* Is this char mouse-active? */
2810 XSETINT (position
, pos
);
2812 /* Put all the overlays we want in a vector in overlay_vec. */
2813 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
2814 /* Sort overlays into increasing priority order. */
2815 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
2817 /* Check mouse-face highlighting. */
2818 if (!(EQ (window
, mouse_face_window
)
2819 && y
>= mouse_face_beg_row
2820 && y
<= mouse_face_end_row
2821 && (y
> mouse_face_beg_row
2822 || x
>= mouse_face_beg_col
)
2823 && (y
< mouse_face_end_row
2824 || x
< mouse_face_end_col
2825 || mouse_face_past_end
)))
2827 /* Clear the display of the old active region, if any. */
2828 term_clear_mouse_face ();
2830 /* Find the highest priority overlay that has a mouse-face
2833 for (i
= noverlays
- 1; i
>= 0; --i
)
2835 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
2836 if (!NILP (mouse_face
))
2838 overlay
= overlay_vec
[i
];
2843 /* If no overlay applies, get a text property. */
2845 mouse_face
= Fget_text_property (position
, Qmouse_face
,
2848 /* Handle the overlay case. */
2849 if (!NILP (overlay
))
2851 /* Find the range of text around this char that
2852 should be active. */
2853 Lisp_Object before
, after
;
2857 before
= Foverlay_start (overlay
);
2858 after
= Foverlay_end (overlay
);
2859 /* Record this as the current active region. */
2860 fast_find_position (w
, XFASTINT (before
),
2861 &mouse_face_beg_col
,
2862 &mouse_face_beg_row
);
2865 = !fast_find_position (w
, XFASTINT (after
),
2866 &mouse_face_end_col
,
2867 &mouse_face_end_row
);
2868 mouse_face_window
= window
;
2871 = face_at_buffer_position (w
, pos
, 0, 0,
2872 &ignore
, pos
+ 1, 1, -1);
2874 /* Display it as active. */
2875 term_show_mouse_face (DRAW_MOUSE_FACE
);
2877 /* Handle the text property case. */
2878 else if (!NILP (mouse_face
))
2880 /* Find the range of text around this char that
2881 should be active. */
2882 Lisp_Object before
, after
, beginning
, end
;
2885 beginning
= Fmarker_position (w
->start
);
2886 XSETINT (end
, (BUF_Z (b
) - XFASTINT (w
->window_end_pos
)));
2888 = Fprevious_single_property_change (make_number (pos
+ 1),
2890 w
->buffer
, beginning
);
2892 = Fnext_single_property_change (position
, Qmouse_face
,
2895 /* Record this as the current active region. */
2896 fast_find_position (w
, XFASTINT (before
),
2897 &mouse_face_beg_col
,
2898 &mouse_face_beg_row
);
2900 = !fast_find_position (w
, XFASTINT (after
),
2901 &mouse_face_end_col
,
2902 &mouse_face_end_row
);
2903 mouse_face_window
= window
;
2906 = face_at_buffer_position (w
, pos
, 0, 0,
2907 &ignore
, pos
+ 1, 1, -1);
2909 /* Display it as active. */
2910 term_show_mouse_face (DRAW_MOUSE_FACE
);
2914 /* Look for a `help-echo' property. */
2917 extern Lisp_Object Qhelp_echo
;
2919 /* Check overlays first. */
2921 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
2923 overlay
= overlay_vec
[i
];
2924 help
= Foverlay_get (overlay
, Qhelp_echo
);
2929 help_echo_string
= help
;
2930 help_echo_window
= window
;
2931 help_echo_object
= overlay
;
2932 help_echo_pos
= pos
;
2934 /* Try text properties. */
2935 else if (NILP (help
)
2936 && ((STRINGP (glyph
->object
)
2937 && glyph
->charpos
>= 0
2938 && glyph
->charpos
< SCHARS (glyph
->object
))
2939 || (BUFFERP (glyph
->object
)
2940 && glyph
->charpos
>= BEGV
2941 && glyph
->charpos
< ZV
)))
2943 help
= Fget_text_property (make_number (glyph
->charpos
),
2944 Qhelp_echo
, glyph
->object
);
2947 help_echo_string
= help
;
2948 help_echo_window
= window
;
2949 help_echo_object
= glyph
->object
;
2950 help_echo_pos
= glyph
->charpos
;
2957 current_buffer
= obuf
;
2963 term_mouse_movement (FRAME_PTR frame
, Gpm_Event
*event
)
2965 /* Has the mouse moved off the glyph it was on at the last sighting? */
2966 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2968 frame
->mouse_moved
= 1;
2969 term_mouse_highlight (frame
, event
->x
, event
->y
);
2970 /* Remember which glyph we're now on. */
2971 last_mouse_x
= event
->x
;
2972 last_mouse_y
= event
->y
;
2978 /* Return the current position of the mouse.
2980 Set *f to the frame the mouse is in, or zero if the mouse is in no
2981 Emacs frame. If it is set to zero, all the other arguments are
2984 Set *bar_window to Qnil, and *x and *y to the column and
2985 row of the character cell the mouse is over.
2987 Set *time to the time the mouse was at the returned position.
2989 This clears mouse_moved until the next motion
2992 term_mouse_position (FRAME_PTR
*fp
, int insist
, Lisp_Object
*bar_window
,
2993 enum scroll_bar_part
*part
, Lisp_Object
*x
,
2994 Lisp_Object
*y
, unsigned long *time
)
2998 *fp
= SELECTED_FRAME ();
2999 (*fp
)->mouse_moved
= 0;
3004 XSETINT (*x
, last_mouse_x
);
3005 XSETINT (*y
, last_mouse_y
);
3006 gettimeofday(&now
, 0);
3007 *time
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
3010 /* Prepare a mouse-event in *RESULT for placement in the input queue.
3012 If the event is a button press, then note that we have grabbed
3016 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
3022 result
->kind
= GPM_CLICK_EVENT
;
3023 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
3025 if (event
->buttons
& j
) {
3026 result
->code
= i
; /* button number */
3030 gettimeofday(&now
, 0);
3031 result
->timestamp
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
3033 if (event
->type
& GPM_UP
)
3034 result
->modifiers
= up_modifier
;
3035 else if (event
->type
& GPM_DOWN
)
3036 result
->modifiers
= down_modifier
;
3038 result
->modifiers
= 0;
3040 if (event
->type
& GPM_SINGLE
)
3041 result
->modifiers
|= click_modifier
;
3043 if (event
->type
& GPM_DOUBLE
)
3044 result
->modifiers
|= double_modifier
;
3046 if (event
->type
& GPM_TRIPLE
)
3047 result
->modifiers
|= triple_modifier
;
3049 if (event
->type
& GPM_DRAG
)
3050 result
->modifiers
|= drag_modifier
;
3052 if (!(event
->type
& (GPM_MOVE
| GPM_DRAG
))) {
3055 if (event
->modifiers
& (1 << 0))
3056 result
->modifiers
|= shift_modifier
;
3059 if (event
->modifiers
& (1 << 2))
3060 result
->modifiers
|= ctrl_modifier
;
3062 /* 1 << KG_ALT || KG_ALTGR */
3063 if (event
->modifiers
& (1 << 3)
3064 || event
->modifiers
& (1 << 1))
3065 result
->modifiers
|= meta_modifier
;
3068 XSETINT (result
->x
, event
->x
);
3069 XSETINT (result
->y
, event
->y
);
3070 XSETFRAME (result
->frame_or_window
, f
);
3076 handle_one_term_event (struct tty_display_info
*tty
, Gpm_Event
*event
, struct input_event
* hold_quit
)
3078 struct frame
*f
= XFRAME (tty
->top_frame
);
3079 struct input_event ie
;
3087 if (event
->type
& (GPM_MOVE
| GPM_DRAG
)) {
3088 previous_help_echo_string
= help_echo_string
;
3089 help_echo_string
= Qnil
;
3091 Gpm_DrawPointer (event
->x
, event
->y
, fileno (tty
->output
));
3093 if (!term_mouse_movement (f
, event
))
3094 help_echo_string
= previous_help_echo_string
;
3096 /* If the contents of the global variable help_echo_string
3097 has changed, generate a HELP_EVENT. */
3098 if (!NILP (help_echo_string
)
3099 || !NILP (previous_help_echo_string
))
3106 term_mouse_click (&ie
, event
, f
);
3110 if (ie
.kind
!= NO_EVENT
)
3112 kbd_buffer_store_event_hold (&ie
, hold_quit
);
3117 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
3122 XSETFRAME (frame
, f
);
3126 gen_help_event (help_echo_string
, frame
, help_echo_window
,
3127 help_echo_object
, help_echo_pos
);
3134 DEFUN ("gpm-mouse-start", Fgpm_mouse_start
, Sgpm_mouse_start
,
3136 doc
: /* Open a connection to Gpm.
3137 Gpm-mouse can only be activated for one tty at a time. */)
3140 struct frame
*f
= SELECTED_FRAME ();
3141 struct tty_display_info
*tty
3142 = ((f
)->output_method
== output_termcap
3143 ? (f
)->terminal
->display_info
.tty
: NULL
);
3144 Gpm_Connect connection
;
3147 error ("Gpm-mouse only works in the GNU/Linux console");
3149 return Qnil
; /* Already activated, nothing to do. */
3151 error ("Gpm-mouse can only be activated for one tty at a time");
3153 connection
.eventMask
= ~0;
3154 connection
.defaultMask
= ~GPM_HARD
;
3155 connection
.maxMod
= ~0;
3156 connection
.minMod
= 0;
3159 if (Gpm_Open (&connection
, 0) < 0)
3160 error ("Gpm-mouse failed to connect to the gpm daemon");
3164 /* `init_sys_modes' arranges for mouse movements sent through gpm_fd
3165 to generate SIGIOs. Apparently we need to call reset_sys_modes
3166 before calling init_sys_modes. */
3167 reset_sys_modes (tty
);
3168 init_sys_modes (tty
);
3169 add_gpm_wait_descriptor (gpm_fd
);
3178 delete_gpm_wait_descriptor (fd
);
3179 while (Gpm_Close()); /* close all the stack */
3183 DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop
, Sgpm_mouse_stop
,
3185 doc
: /* Close a connection to Gpm. */)
3188 struct frame
*f
= SELECTED_FRAME ();
3189 struct tty_display_info
*tty
3190 = ((f
)->output_method
== output_termcap
3191 ? (f
)->terminal
->display_info
.tty
: NULL
);
3193 if (!tty
|| gpm_tty
!= tty
)
3194 return Qnil
; /* Not activated on this terminal, nothing to do. */
3199 #endif /* HAVE_GPM */
3203 /***********************************************************************
3205 ***********************************************************************/
3207 /* Initialize the tty-dependent part of frame F. The frame must
3208 already have its device initialized. */
3211 create_tty_output (struct frame
*f
)
3213 struct tty_output
*t
;
3215 if (! FRAME_TERMCAP_P (f
))
3218 t
= xmalloc (sizeof (struct tty_output
));
3219 memset (t
, 0, sizeof (struct tty_output
));
3221 t
->display_info
= FRAME_TERMINAL (f
)->display_info
.tty
;
3223 f
->output_data
.tty
= t
;
3226 /* Delete frame F's face cache, and its tty-dependent part. */
3229 tty_free_frame_resources (struct frame
*f
)
3231 if (! FRAME_TERMCAP_P (f
))
3234 if (FRAME_FACE_CACHE (f
))
3235 free_frame_faces (f
);
3237 xfree (f
->output_data
.tty
);
3242 /* Delete frame F's face cache. */
3245 tty_free_frame_resources (struct frame
*f
)
3247 if (! FRAME_TERMCAP_P (f
) && ! FRAME_MSDOS_P (f
))
3250 if (FRAME_FACE_CACHE (f
))
3251 free_frame_faces (f
);
3255 /* Reset the hooks in TERMINAL. */
3258 clear_tty_hooks (struct terminal
*terminal
)
3261 terminal
->cursor_to_hook
= 0;
3262 terminal
->raw_cursor_to_hook
= 0;
3263 terminal
->clear_to_end_hook
= 0;
3264 terminal
->clear_frame_hook
= 0;
3265 terminal
->clear_end_of_line_hook
= 0;
3266 terminal
->ins_del_lines_hook
= 0;
3267 terminal
->insert_glyphs_hook
= 0;
3268 terminal
->write_glyphs_hook
= 0;
3269 terminal
->delete_glyphs_hook
= 0;
3270 terminal
->ring_bell_hook
= 0;
3271 terminal
->reset_terminal_modes_hook
= 0;
3272 terminal
->set_terminal_modes_hook
= 0;
3273 terminal
->update_begin_hook
= 0;
3274 terminal
->update_end_hook
= 0;
3275 terminal
->set_terminal_window_hook
= 0;
3276 terminal
->mouse_position_hook
= 0;
3277 terminal
->frame_rehighlight_hook
= 0;
3278 terminal
->frame_raise_lower_hook
= 0;
3279 terminal
->fullscreen_hook
= 0;
3280 terminal
->set_vertical_scroll_bar_hook
= 0;
3281 terminal
->condemn_scroll_bars_hook
= 0;
3282 terminal
->redeem_scroll_bar_hook
= 0;
3283 terminal
->judge_scroll_bars_hook
= 0;
3284 terminal
->read_socket_hook
= 0;
3285 terminal
->frame_up_to_date_hook
= 0;
3287 /* Leave these two set, or suspended frames are not deleted
3289 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3290 terminal
->delete_terminal_hook
= &delete_tty
;
3293 /* Initialize hooks in TERMINAL with the values needed for a tty. */
3296 set_tty_hooks (struct terminal
*terminal
)
3298 terminal
->rif
= 0; /* ttys don't support window-based redisplay. */
3300 terminal
->cursor_to_hook
= &tty_cursor_to
;
3301 terminal
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
3303 terminal
->clear_to_end_hook
= &tty_clear_to_end
;
3304 terminal
->clear_frame_hook
= &tty_clear_frame
;
3305 terminal
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
3307 terminal
->ins_del_lines_hook
= &tty_ins_del_lines
;
3309 terminal
->insert_glyphs_hook
= &tty_insert_glyphs
;
3310 terminal
->write_glyphs_hook
= &tty_write_glyphs
;
3311 terminal
->delete_glyphs_hook
= &tty_delete_glyphs
;
3313 terminal
->ring_bell_hook
= &tty_ring_bell
;
3315 terminal
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
3316 terminal
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
3317 terminal
->update_begin_hook
= 0; /* Not needed. */
3318 terminal
->update_end_hook
= &tty_update_end
;
3319 terminal
->set_terminal_window_hook
= &tty_set_terminal_window
;
3321 terminal
->mouse_position_hook
= 0; /* Not needed. */
3322 terminal
->frame_rehighlight_hook
= 0; /* Not needed. */
3323 terminal
->frame_raise_lower_hook
= 0; /* Not needed. */
3325 terminal
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
3326 terminal
->condemn_scroll_bars_hook
= 0; /* Not needed. */
3327 terminal
->redeem_scroll_bar_hook
= 0; /* Not needed. */
3328 terminal
->judge_scroll_bars_hook
= 0; /* Not needed. */
3330 terminal
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
3331 terminal
->frame_up_to_date_hook
= 0; /* Not needed. */
3333 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3334 terminal
->delete_terminal_hook
= &delete_tty
;
3337 /* Drop the controlling terminal if fd is the same device. */
3339 dissociate_if_controlling_tty (int fd
)
3343 EMACS_GET_TTY_PGRP (fd
, &pgid
); /* If tcgetpgrp succeeds, fd is the ctty. */
3348 no_controlling_tty
= 1;
3349 #elif defined (CYGWIN)
3351 no_controlling_tty
= 1;
3353 #ifdef TIOCNOTTY /* Try BSD ioctls. */
3354 sigblock (sigmask (SIGTTOU
));
3355 fd
= emacs_open (DEV_TTY
, O_RDWR
, 0);
3356 if (fd
!= -1 && ioctl (fd
, TIOCNOTTY
, 0) != -1)
3358 no_controlling_tty
= 1;
3362 sigunblock (sigmask (SIGTTOU
));
3364 /* Unknown system. */
3366 #endif /* ! TIOCNOTTY */
3369 #endif /* !DOS_NT */
3372 /* Create a termcap display on the tty device with the given name and
3375 If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
3376 Otherwise NAME should be a path to the tty device file,
3379 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
3381 If MUST_SUCCEED is true, then all errors are fatal. */
3384 init_tty (char *name
, char *terminal_type
, int must_succeed
)
3387 char **address
= &area
;
3388 int buffer_size
= 4096;
3389 register char *p
= NULL
;
3391 struct tty_display_info
*tty
= NULL
;
3392 struct terminal
*terminal
= NULL
;
3393 int ctty
= 0; /* 1 if asked to open controlling tty. */
3396 maybe_fatal (must_succeed
, 0,
3397 "Unknown terminal type",
3398 "Unknown terminal type");
3402 if (!strcmp (name
, DEV_TTY
))
3405 /* If we already have a terminal on the given device, use that. If
3406 all such terminals are suspended, create a new one instead. */
3407 /* XXX Perhaps this should be made explicit by having init_tty
3408 always create a new terminal and separating terminal and frame
3409 creation on Lisp level. */
3410 terminal
= get_named_tty (name
);
3414 terminal
= create_terminal ();
3417 maybe_fatal (1, 0, "Attempt to create another terminal %s", "",
3420 tty
= &the_only_display_info
;
3422 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
3424 memset (tty
, 0, sizeof (struct tty_display_info
));
3425 tty
->next
= tty_list
;
3428 terminal
->type
= output_termcap
;
3429 terminal
->display_info
.tty
= tty
;
3430 tty
->terminal
= terminal
;
3432 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
3436 set_tty_hooks (terminal
);
3442 #ifdef O_IGNORE_CTTY
3444 /* Open the terminal device. Don't recognize it as our
3445 controlling terminal, and don't make it the controlling tty
3446 if we don't have one at the moment. */
3447 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
3450 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
3451 defined on Hurd. On other systems, we need to explicitly
3452 dissociate ourselves from the controlling tty when we want to
3453 open a frame on the same terminal. */
3454 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
3455 #endif /* O_IGNORE_CTTY */
3457 tty
->name
= xstrdup (name
);
3458 terminal
->name
= xstrdup (name
);
3461 maybe_fatal (must_succeed
, terminal
,
3462 "Could not open file: %s",
3463 "Could not open file: %s",
3468 maybe_fatal (must_succeed
, terminal
,
3469 "Not a tty device: %s",
3470 "Not a tty device: %s",
3474 #ifndef O_IGNORE_CTTY
3476 dissociate_if_controlling_tty (fd
);
3479 file
= fdopen (fd
, "w+");
3484 tty
->type
= xstrdup (terminal_type
);
3486 add_keyboard_wait_descriptor (fileno (tty
->input
));
3488 #endif /* !DOS_NT */
3490 encode_terminal_src_size
= 0;
3491 encode_terminal_dst_size
= 0;
3494 terminal
->mouse_position_hook
= term_mouse_position
;
3495 mouse_face_window
= Qnil
;
3500 initialize_w32_display (terminal
);
3502 if (strcmp (terminal_type
, "internal") == 0)
3503 terminal
->type
= output_msdos_raw
;
3504 initialize_msdos_display (terminal
);
3506 tty
->output
= stdout
;
3508 /* The following two are inaccessible from w32console.c. */
3509 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3510 terminal
->delete_terminal_hook
= &delete_tty
;
3512 tty
->name
= xstrdup (name
);
3513 terminal
->name
= xstrdup (name
);
3514 tty
->type
= xstrdup (terminal_type
);
3516 add_keyboard_wait_descriptor (0);
3522 struct frame
*f
= XFRAME (selected_frame
);
3524 FrameRows (tty
) = FRAME_LINES (f
);
3525 FrameCols (tty
) = FRAME_COLS (f
);
3526 tty
->specified_window
= FRAME_LINES (f
);
3528 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
3529 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
3534 get_tty_size (fileno (tty
->input
), &width
, &height
);
3535 FrameCols (tty
) = width
;
3536 FrameRows (tty
) = height
;
3539 tty
->delete_in_insert_mode
= 1;
3542 terminal
->scroll_region_ok
= 0;
3544 /* Seems to insert lines when it's not supposed to, messing up the
3545 display. In doing a trace, it didn't seem to be called much, so I
3546 don't think we're losing anything by turning it off. */
3547 terminal
->line_ins_del_ok
= 0;
3549 terminal
->char_ins_del_ok
= 1;
3552 terminal
->char_ins_del_ok
= 0;
3553 init_baud_rate (fileno (tty
->input
));
3556 tty
->TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
3558 #else /* not DOS_NT */
3562 tty
->termcap_term_buffer
= (char *) xmalloc (buffer_size
);
3564 /* On some systems, tgetent tries to access the controlling
3566 sigblock (sigmask (SIGTTOU
));
3567 status
= tgetent (tty
->termcap_term_buffer
, terminal_type
);
3568 sigunblock (sigmask (SIGTTOU
));
3573 maybe_fatal (must_succeed
, terminal
,
3574 "Cannot open terminfo database file",
3575 "Cannot open terminfo database file");
3577 maybe_fatal (must_succeed
, terminal
,
3578 "Cannot open termcap database file",
3579 "Cannot open termcap database file");
3584 maybe_fatal (must_succeed
, terminal
,
3585 "Terminal type %s is not defined",
3586 "Terminal type %s is not defined.\n\
3587 If that is not the actual type of terminal you have,\n\
3588 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3589 `setenv TERM ...') to specify the correct type. It may be necessary\n"
3591 "to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3593 "to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3599 if (strlen (tty
->termcap_term_buffer
) >= buffer_size
)
3601 buffer_size
= strlen (tty
->termcap_term_buffer
);
3603 tty
->termcap_strings_buffer
= area
= (char *) xmalloc (buffer_size
);
3604 tty
->TS_ins_line
= tgetstr ("al", address
);
3605 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
3606 tty
->TS_bell
= tgetstr ("bl", address
);
3607 BackTab (tty
) = tgetstr ("bt", address
);
3608 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
3609 tty
->TS_clr_line
= tgetstr ("ce", address
);
3610 tty
->TS_clr_frame
= tgetstr ("cl", address
);
3611 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
3612 AbsPosition (tty
) = tgetstr ("cm", address
);
3613 CR (tty
) = tgetstr ("cr", address
);
3614 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
3615 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
3616 RowPosition (tty
) = tgetstr ("cv", address
);
3617 tty
->TS_del_char
= tgetstr ("dc", address
);
3618 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
3619 tty
->TS_del_line
= tgetstr ("dl", address
);
3620 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
3621 tty
->TS_delete_mode
= tgetstr ("dm", address
);
3622 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
3623 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
3624 Home (tty
) = tgetstr ("ho", address
);
3625 tty
->TS_ins_char
= tgetstr ("ic", address
);
3626 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
3627 tty
->TS_insert_mode
= tgetstr ("im", address
);
3628 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
3629 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
3630 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
3631 LastLine (tty
) = tgetstr ("ll", address
);
3632 Right (tty
) = tgetstr ("nd", address
);
3633 Down (tty
) = tgetstr ("do", address
);
3635 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
3636 if (tgetflag ("bs"))
3637 Left (tty
) = "\b"; /* can't possibly be longer! */
3638 else /* (Actually, "bs" is obsolete...) */
3639 Left (tty
) = tgetstr ("le", address
);
3641 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
3642 tty
->TS_pad_char
= tgetstr ("pc", address
);
3643 tty
->TS_repeat
= tgetstr ("rp", address
);
3644 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
3645 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
3646 tty
->TS_standout_mode
= tgetstr ("so", address
);
3647 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
3648 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
3649 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
3650 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
3651 Up (tty
) = tgetstr ("up", address
);
3652 tty
->TS_visible_bell
= tgetstr ("vb", address
);
3653 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
3654 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
3655 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
3656 tty
->TS_set_window
= tgetstr ("wi", address
);
3658 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
3659 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
3660 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
3661 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
3662 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
3663 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
3664 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3665 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3666 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
3668 MultiUp (tty
) = tgetstr ("UP", address
);
3669 MultiDown (tty
) = tgetstr ("DO", address
);
3670 MultiLeft (tty
) = tgetstr ("LE", address
);
3671 MultiRight (tty
) = tgetstr ("RI", address
);
3673 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
3674 color because we can't switch back to the default foreground and
3676 tty
->TS_orig_pair
= tgetstr ("op", address
);
3677 if (tty
->TS_orig_pair
)
3679 tty
->TS_set_foreground
= tgetstr ("AF", address
);
3680 tty
->TS_set_background
= tgetstr ("AB", address
);
3681 if (!tty
->TS_set_foreground
)
3684 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
3685 tty
->TS_set_background
= tgetstr ("Sb", address
);
3688 tty
->TN_max_colors
= tgetnum ("Co");
3689 tty
->TN_max_pairs
= tgetnum ("pa");
3691 tty
->TN_no_color_video
= tgetnum ("NC");
3692 if (tty
->TN_no_color_video
== -1)
3693 tty
->TN_no_color_video
= 0;
3696 tty_default_color_capabilities (tty
, 1);
3698 MagicWrap (tty
) = tgetflag ("xn");
3699 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3700 the former flag imply the latter. */
3701 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
3702 terminal
->memory_below_frame
= tgetflag ("db");
3703 tty
->TF_hazeltine
= tgetflag ("hz");
3704 terminal
->must_write_spaces
= tgetflag ("in");
3705 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
3706 tty
->TF_insmode_motion
= tgetflag ("mi");
3707 tty
->TF_standout_motion
= tgetflag ("ms");
3708 tty
->TF_underscore
= tgetflag ("ul");
3709 tty
->TF_teleray
= tgetflag ("xt");
3711 #endif /* !DOS_NT */
3712 terminal
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
3713 init_kboard (terminal
->kboard
);
3714 terminal
->kboard
->Vwindow_system
= Qnil
;
3715 terminal
->kboard
->next_kboard
= all_kboards
;
3716 all_kboards
= terminal
->kboard
;
3717 terminal
->kboard
->reference_count
++;
3718 /* Don't let the initial kboard remain current longer than necessary.
3719 That would cause problems if a file loaded on startup tries to
3720 prompt in the mini-buffer. */
3721 if (current_kboard
== initial_kboard
)
3722 current_kboard
= terminal
->kboard
;
3724 term_get_fkeys (address
, terminal
->kboard
);
3726 /* Get frame size from system, or else from termcap. */
3729 get_tty_size (fileno (tty
->input
), &width
, &height
);
3730 FrameCols (tty
) = width
;
3731 FrameRows (tty
) = height
;
3734 if (FrameCols (tty
) <= 0)
3735 FrameCols (tty
) = tgetnum ("co");
3736 if (FrameRows (tty
) <= 0)
3737 FrameRows (tty
) = tgetnum ("li");
3739 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
3740 maybe_fatal (must_succeed
, terminal
,
3741 "Screen size %dx%d is too small",
3742 "Screen size %dx%d is too small",
3743 FrameCols (tty
), FrameRows (tty
));
3745 TabWidth (tty
) = tgetnum ("tw");
3748 tty
->TS_bell
= "\07";
3750 if (!tty
->TS_fwd_scroll
)
3751 tty
->TS_fwd_scroll
= Down (tty
);
3753 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
3755 if (TabWidth (tty
) < 0)
3758 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3759 and newer termcap doc does not seem to say there is a default.
3760 if (!tty->Wcm->cm_tab)
3761 tty->Wcm->cm_tab = "\t";
3764 /* We don't support standout modes that use `magic cookies', so
3765 turn off any that do. */
3766 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
3768 tty
->TS_standout_mode
= 0;
3769 tty
->TS_end_standout_mode
= 0;
3771 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3773 tty
->TS_enter_underline_mode
= 0;
3774 tty
->TS_exit_underline_mode
= 0;
3777 /* If there's no standout mode, try to use underlining instead. */
3778 if (tty
->TS_standout_mode
== 0)
3780 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
3781 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
3784 /* If no `se' string, try using a `me' string instead.
3785 If that fails, we can't use standout mode at all. */
3786 if (tty
->TS_end_standout_mode
== 0)
3788 char *s
= tgetstr ("me", address
);
3790 tty
->TS_end_standout_mode
= s
;
3792 tty
->TS_standout_mode
= 0;
3795 if (tty
->TF_teleray
)
3797 tty
->Wcm
->cm_tab
= 0;
3798 /* We can't support standout mode, because it uses magic cookies. */
3799 tty
->TS_standout_mode
= 0;
3800 /* But that means we cannot rely on ^M to go to column zero! */
3802 /* LF can't be trusted either -- can alter hpos */
3803 /* if move at column 0 thru a line with TS_standout_mode */
3807 /* Special handling for certain terminal types known to need it */
3809 if (!strcmp (terminal_type
, "supdup"))
3811 terminal
->memory_below_frame
= 1;
3812 tty
->Wcm
->cm_losewrap
= 1;
3814 if (!strncmp (terminal_type
, "c10", 3)
3815 || !strcmp (terminal_type
, "perq"))
3817 /* Supply a makeshift :wi string.
3818 This string is not valid in general since it works only
3819 for windows starting at the upper left corner;
3820 but that is all Emacs uses.
3822 This string works only if the frame is using
3823 the top of the video memory, because addressing is memory-relative.
3824 So first check the :ti string to see if that is true.
3826 It would be simpler if the :wi string could go in the termcap
3827 entry, but it can't because it is not fully valid.
3828 If it were in the termcap entry, it would confuse other programs. */
3829 if (!tty
->TS_set_window
)
3831 p
= tty
->TS_termcap_modes
;
3832 while (*p
&& strcmp (p
, "\033v "))
3835 tty
->TS_set_window
= "\033v%C %C %C %C ";
3837 /* Termcap entry often fails to have :in: flag */
3838 terminal
->must_write_spaces
= 1;
3839 /* :ti string typically fails to have \E^G! in it */
3840 /* This limits scope of insert-char to one line. */
3841 strcpy (area
, tty
->TS_termcap_modes
);
3842 strcat (area
, "\033\007!");
3843 tty
->TS_termcap_modes
= area
;
3844 area
+= strlen (area
) + 1;
3845 p
= AbsPosition (tty
);
3846 /* Change all %+ parameters to %C, to handle
3847 values above 96 correctly for the C100. */
3850 if (p
[0] == '%' && p
[1] == '+')
3856 tty
->specified_window
= FrameRows (tty
);
3858 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
3860 maybe_fatal (must_succeed
, terminal
,
3861 "Terminal type \"%s\" is not powerful enough to run Emacs",
3862 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3863 It lacks the ability to position the cursor.\n\
3864 If that is not the actual type of terminal you have,\n\
3865 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3866 `setenv TERM ...') to specify the correct type. It may be necessary\n"
3868 "to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3869 # else /* TERMCAP */
3870 "to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3871 # endif /* TERMINFO */
3875 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
3876 maybe_fatal (must_succeed
, terminal
,
3877 "Could not determine the frame size",
3878 "Could not determine the frame size");
3880 tty
->delete_in_insert_mode
3881 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
3882 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
3884 tty
->se_is_so
= (tty
->TS_standout_mode
3885 && tty
->TS_end_standout_mode
3886 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
3888 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
3890 terminal
->scroll_region_ok
3892 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
3894 terminal
->line_ins_del_ok
3895 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
3896 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
3897 || (terminal
->scroll_region_ok
3898 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
3900 terminal
->char_ins_del_ok
3901 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
3902 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
3903 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
3905 terminal
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
3907 init_baud_rate (fileno (tty
->input
));
3909 #endif /* not DOS_NT */
3911 /* Init system terminal modes (RAW or CBREAK, etc.). */
3912 init_sys_modes (tty
);
3919 vfatal (const char *str
, va_list ap
)
3921 fprintf (stderr
, "emacs: ");
3922 vfprintf (stderr
, str
, ap
);
3923 if (!(strlen (str
) > 0 && str
[strlen (str
) - 1] == '\n'))
3924 fprintf (stderr
, "\n");
3931 /* Auxiliary error-handling function for init_tty.
3932 Delete TERMINAL, then call error or fatal with str1 or str2,
3933 respectively, according to MUST_SUCCEED. */
3936 maybe_fatal (int must_succeed
, struct terminal
*terminal
,
3937 const char *str1
, const char *str2
, ...)
3940 va_start (ap
, str2
);
3942 delete_tty (terminal
);
3954 fatal (const char *str
, ...)
3964 /* Delete the given tty terminal, closing all frames on it. */
3967 delete_tty (struct terminal
*terminal
)
3969 struct tty_display_info
*tty
;
3971 /* Protect against recursive calls. delete_frame in
3972 delete_terminal calls us back when it deletes our last frame. */
3973 if (!terminal
->name
)
3976 if (terminal
->type
!= output_termcap
)
3979 tty
= terminal
->display_info
.tty
;
3981 if (tty
== tty_list
)
3982 tty_list
= tty
->next
;
3985 struct tty_display_info
*p
;
3986 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
3990 /* This should not happen. */
3993 p
->next
= tty
->next
;
3997 /* reset_sys_modes needs a valid device, so this call needs to be
3998 before delete_terminal. */
3999 reset_sys_modes (tty
);
4001 delete_terminal (terminal
);
4008 delete_keyboard_wait_descriptor (fileno (tty
->input
));
4009 if (tty
->input
!= stdin
)
4010 fclose (tty
->input
);
4012 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
4013 fclose (tty
->output
);
4014 if (tty
->termscript
)
4015 fclose (tty
->termscript
);
4017 xfree (tty
->old_tty
);
4019 xfree (tty
->termcap_strings_buffer
);
4020 xfree (tty
->termcap_term_buffer
);
4022 memset (tty
, 0, sizeof (struct tty_display_info
));
4028 /* Mark the pointers in the tty_display_info objects.
4029 Called by the Fgarbage_collector. */
4034 struct tty_display_info
*tty
;
4036 for (tty
= tty_list
; tty
; tty
= tty
->next
)
4037 mark_object (tty
->top_frame
);
4045 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
4046 doc
: /* Non-nil means the system uses terminfo rather than termcap.
4047 This variable can be used by terminal emulator packages. */);
4049 system_uses_terminfo
= 1;
4051 system_uses_terminfo
= 0;
4054 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions
,
4055 doc
: /* Functions to be run after suspending a tty.
4056 The functions are run with one argument, the terminal object to be suspended.
4057 See `suspend-tty'. */);
4058 Vsuspend_tty_functions
= Qnil
;
4061 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions
,
4062 doc
: /* Functions to be run after resuming a tty.
4063 The functions are run with one argument, the terminal object that was revived.
4064 See `resume-tty'. */);
4065 Vresume_tty_functions
= Qnil
;
4067 DEFVAR_BOOL ("visible-cursor", &visible_cursor
,
4068 doc
: /* Non-nil means to make the cursor very visible.
4069 This only has an effect when running in a text terminal.
4070 What means \"very visible\" is up to your terminal. It may make the cursor
4071 bigger, or it may make it blink, or it may do nothing at all. */);
4074 defsubr (&Stty_display_color_p
);
4075 defsubr (&Stty_display_color_cells
);
4076 defsubr (&Stty_no_underline
);
4077 defsubr (&Stty_type
);
4078 defsubr (&Scontrolling_tty_p
);
4079 defsubr (&Ssuspend_tty
);
4080 defsubr (&Sresume_tty
);
4082 defsubr (&Sgpm_mouse_start
);
4083 defsubr (&Sgpm_mouse_stop
);
4085 staticpro (&mouse_face_window
);
4086 #endif /* HAVE_GPM */
4089 default_orig_pair
= NULL
;
4090 default_set_foreground
= NULL
;
4091 default_set_background
= NULL
;
4092 #endif /* !DOS_NT */
4094 encode_terminal_src
= NULL
;
4095 encode_terminal_dst
= NULL
;
4100 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
4101 (do not change this comment) */