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
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. */
45 #include "character.h"
48 #include "composite.h"
52 #include "termhooks.h"
53 #include "dispextern.h"
56 #include "blockinput.h"
57 #include "syssignal.h"
59 #include "intervals.h"
62 static int been_here
= -1;
65 /* For now, don't try to include termcap.h. On some systems,
66 configure finds a non-standard termcap.h that the main build
69 #if defined HAVE_TERMCAP_H && 0
72 extern void tputs
P_ ((const char *, int, int (*)(int)));
73 extern int tgetent
P_ ((char *, const char *));
74 extern int tgetflag
P_ ((char *id
));
75 extern int tgetnum
P_ ((char *id
));
91 /* The name of the default console device. */
93 #define DEV_TTY "CONOUT$"
95 #define DEV_TTY "/dev/tty"
98 static void tty_set_scroll_region
P_ ((struct frame
*f
, int start
, int stop
));
99 static void turn_on_face
P_ ((struct frame
*, int face_id
));
100 static void turn_off_face
P_ ((struct frame
*, int face_id
));
101 static void tty_show_cursor
P_ ((struct tty_display_info
*));
102 static void tty_hide_cursor
P_ ((struct tty_display_info
*));
103 static void tty_background_highlight
P_ ((struct tty_display_info
*tty
));
104 static void clear_tty_hooks
P_ ((struct terminal
*terminal
));
105 static void set_tty_hooks
P_ ((struct terminal
*terminal
));
106 static void dissociate_if_controlling_tty
P_ ((int fd
));
107 static void delete_tty
P_ ((struct terminal
*));
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 extern Lisp_Object Qspace
, QCalign_to
, QCwidth
;
137 /* Functions to call after suspending a tty. */
138 Lisp_Object Vsuspend_tty_functions
;
140 /* Functions to call after resuming a tty. */
141 Lisp_Object Vresume_tty_functions
;
143 /* Chain of all tty device parameters. */
144 struct tty_display_info
*tty_list
;
146 /* Nonzero means no need to redraw the entire frame on resuming a
147 suspended Emacs. This is useful on terminals with multiple
148 pages, where one page is used for Emacs and another for all
150 int no_redraw_on_reenter
;
152 /* Meaning of bits in no_color_video. Each bit set means that the
153 corresponding attribute cannot be combined with colors. */
157 NC_STANDOUT
= 1 << 0,
158 NC_UNDERLINE
= 1 << 1,
165 NC_ALT_CHARSET
= 1 << 8
170 /* The largest frame width in any call to calculate_costs. */
174 /* The largest frame height in any call to calculate_costs. */
178 /* Non-zero if we have dropped our controlling tty and therefore
179 should not open a frame on stdout. */
180 static int no_controlling_tty
;
182 /* Provided for lisp packages. */
184 static int system_uses_terminfo
;
188 extern char *tgetstr ();
192 #include <sys/fcntl.h>
194 static void term_clear_mouse_face ();
195 static void term_mouse_highlight (struct frame
*f
, int x
, int y
);
197 /* The device for which we have enabled gpm support (or NULL). */
198 struct tty_display_info
*gpm_tty
= NULL
;
200 /* These variables describe the range of text currently shown in its
201 mouse-face, together with the window they apply to. As long as
202 the mouse stays within this range, we need not redraw anything on
203 its account. Rows and columns are glyph matrix positions in
204 MOUSE_FACE_WINDOW. */
205 static int mouse_face_beg_row
, mouse_face_beg_col
;
206 static int mouse_face_end_row
, mouse_face_end_col
;
207 static int mouse_face_past_end
;
208 static Lisp_Object mouse_face_window
;
209 static int mouse_face_face_id
;
211 static int pos_x
, pos_y
;
212 static int last_mouse_x
, last_mouse_y
;
213 #endif /* HAVE_GPM */
215 /* Ring the bell on a tty. */
218 tty_ring_bell (struct frame
*f
)
220 struct tty_display_info
*tty
= FRAME_TTY (f
);
224 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
225 ? tty
->TS_visible_bell
227 fflush (tty
->output
);
231 /* Set up termcap modes for Emacs. */
234 tty_set_terminal_modes (struct terminal
*terminal
)
236 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
240 if (tty
->TS_termcap_modes
)
241 OUTPUT (tty
, tty
->TS_termcap_modes
);
244 /* Output enough newlines to scroll all the old screen contents
245 off the screen, so it won't be overwritten and lost. */
248 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
252 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
253 OUTPUT_IF (tty
, visible_cursor
? tty
->TS_cursor_visible
: tty
->TS_cursor_normal
);
254 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
256 fflush (tty
->output
);
260 /* Reset termcap modes before exiting Emacs. */
263 tty_reset_terminal_modes (struct terminal
*terminal
)
265 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
269 tty_turn_off_highlight (tty
);
270 tty_turn_off_insert (tty
);
271 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
272 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
273 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
274 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
275 /* Output raw CR so kernel can track the cursor hpos. */
278 fflush (tty
->output
);
282 /* Flag the end of a display update on a termcap terminal. */
285 tty_update_end (struct frame
*f
)
287 struct tty_display_info
*tty
= FRAME_TTY (f
);
289 if (!XWINDOW (selected_window
)->cursor_off_p
)
290 tty_show_cursor (tty
);
291 tty_turn_off_insert (tty
);
292 tty_background_highlight (tty
);
295 /* The implementation of set_terminal_window for termcap frames. */
298 tty_set_terminal_window (struct frame
*f
, int size
)
300 struct tty_display_info
*tty
= FRAME_TTY (f
);
302 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
303 if (FRAME_SCROLL_REGION_OK (f
))
304 tty_set_scroll_region (f
, 0, tty
->specified_window
);
308 tty_set_scroll_region (struct frame
*f
, int start
, int stop
)
311 struct tty_display_info
*tty
= FRAME_TTY (f
);
313 if (tty
->TS_set_scroll_region
)
314 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
315 else if (tty
->TS_set_scroll_region_1
)
316 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
317 FRAME_LINES (f
), start
,
318 FRAME_LINES (f
) - stop
,
321 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
330 tty_turn_on_insert (struct tty_display_info
*tty
)
332 if (!tty
->insert_mode
)
333 OUTPUT (tty
, tty
->TS_insert_mode
);
334 tty
->insert_mode
= 1;
338 tty_turn_off_insert (struct tty_display_info
*tty
)
340 if (tty
->insert_mode
)
341 OUTPUT (tty
, tty
->TS_end_insert_mode
);
342 tty
->insert_mode
= 0;
345 /* Handle highlighting. */
348 tty_turn_off_highlight (struct tty_display_info
*tty
)
350 if (tty
->standout_mode
)
351 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
352 tty
->standout_mode
= 0;
356 tty_turn_on_highlight (struct tty_display_info
*tty
)
358 if (!tty
->standout_mode
)
359 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
360 tty
->standout_mode
= 1;
364 tty_toggle_highlight (struct tty_display_info
*tty
)
366 if (tty
->standout_mode
)
367 tty_turn_off_highlight (tty
);
369 tty_turn_on_highlight (tty
);
373 /* Make cursor invisible. */
376 tty_hide_cursor (struct tty_display_info
*tty
)
378 if (tty
->cursor_hidden
== 0)
380 tty
->cursor_hidden
= 1;
381 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
386 /* Ensure that cursor is visible. */
389 tty_show_cursor (struct tty_display_info
*tty
)
391 if (tty
->cursor_hidden
)
393 tty
->cursor_hidden
= 0;
394 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
396 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
401 /* Set standout mode to the state it should be in for
402 empty space inside windows. What this is,
403 depends on the user option inverse-video. */
406 tty_background_highlight (struct tty_display_info
*tty
)
409 tty_turn_on_highlight (tty
);
411 tty_turn_off_highlight (tty
);
414 /* Set standout mode to the mode specified for the text to be output. */
417 tty_highlight_if_desired (struct tty_display_info
*tty
)
420 tty_turn_on_highlight (tty
);
422 tty_turn_off_highlight (tty
);
426 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
427 frame-relative coordinates. */
430 tty_cursor_to (struct frame
*f
, int vpos
, int hpos
)
432 struct tty_display_info
*tty
= FRAME_TTY (f
);
434 /* Detect the case where we are called from reset_sys_modes
435 and the costs have never been calculated. Do nothing. */
436 if (! tty
->costs_set
)
439 if (curY (tty
) == vpos
440 && curX (tty
) == hpos
)
442 if (!tty
->TF_standout_motion
)
443 tty_background_highlight (tty
);
444 if (!tty
->TF_insmode_motion
)
445 tty_turn_off_insert (tty
);
446 cmgoto (tty
, vpos
, hpos
);
449 /* Similar but don't take any account of the wasted characters. */
452 tty_raw_cursor_to (struct frame
*f
, int row
, int col
)
454 struct tty_display_info
*tty
= FRAME_TTY (f
);
456 if (curY (tty
) == row
457 && curX (tty
) == col
)
459 if (!tty
->TF_standout_motion
)
460 tty_background_highlight (tty
);
461 if (!tty
->TF_insmode_motion
)
462 tty_turn_off_insert (tty
);
463 cmgoto (tty
, row
, col
);
466 /* Erase operations */
468 /* Clear from cursor to end of frame on a termcap device. */
471 tty_clear_to_end (struct frame
*f
)
474 struct tty_display_info
*tty
= FRAME_TTY (f
);
476 if (tty
->TS_clr_to_bottom
)
478 tty_background_highlight (tty
);
479 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
483 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
486 clear_end_of_line (f
, FRAME_COLS (f
));
491 /* Clear an entire termcap frame. */
494 tty_clear_frame (struct frame
*f
)
496 struct tty_display_info
*tty
= FRAME_TTY (f
);
498 if (tty
->TS_clr_frame
)
500 tty_background_highlight (tty
);
501 OUTPUT (tty
, tty
->TS_clr_frame
);
511 /* An implementation of clear_end_of_line for termcap frames.
513 Note that the cursor may be moved, on terminals lacking a `ce' string. */
516 tty_clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
519 struct tty_display_info
*tty
= FRAME_TTY (f
);
521 /* Detect the case where we are called from reset_sys_modes
522 and the costs have never been calculated. Do nothing. */
523 if (! tty
->costs_set
)
526 if (curX (tty
) >= first_unused_hpos
)
528 tty_background_highlight (tty
);
529 if (tty
->TS_clr_line
)
531 OUTPUT1 (tty
, tty
->TS_clr_line
);
534 { /* have to do it the hard way */
535 tty_turn_off_insert (tty
);
537 /* Do not write in last row last col with Auto-wrap on. */
539 && curY (tty
) == FrameRows (tty
) - 1
540 && first_unused_hpos
== FrameCols (tty
))
543 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
546 fputc (' ', tty
->termscript
);
547 fputc (' ', tty
->output
);
549 cmplus (tty
, first_unused_hpos
- curX (tty
));
553 /* Buffers to store the source and result of code conversion for terminal. */
554 static unsigned char *encode_terminal_src
;
555 static unsigned char *encode_terminal_dst
;
556 /* Allocated sizes of the above buffers. */
557 static int encode_terminal_src_size
;
558 static int encode_terminal_dst_size
;
560 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
561 Set CODING->produced to the byte-length of the resulting byte
562 sequence, and return a pointer to that byte sequence. */
565 encode_terminal_code (src
, src_len
, coding
)
568 struct coding_system
*coding
;
570 struct glyph
*src_end
= src
+ src_len
;
572 int nchars
, nbytes
, required
;
573 register int tlen
= GLYPH_TABLE_LENGTH
;
574 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
575 Lisp_Object charset_list
;
577 /* Allocate sufficient size of buffer to store all characters in
578 multibyte-form. But, it may be enlarged on demand if
579 Vglyph_table contains a string or a composite glyph is
581 required
= MAX_MULTIBYTE_LENGTH
* src_len
;
582 if (encode_terminal_src_size
< required
)
584 if (encode_terminal_src
)
585 encode_terminal_src
= xrealloc (encode_terminal_src
, required
);
587 encode_terminal_src
= xmalloc (required
);
588 encode_terminal_src_size
= required
;
591 charset_list
= coding_charset_list (coding
);
593 buf
= encode_terminal_src
;
595 while (src
< src_end
)
597 if (src
->type
== COMPOSITE_GLYPH
)
599 struct composition
*cmp
;
603 nbytes
= buf
- encode_terminal_src
;
604 if (src
->u
.cmp
.automatic
)
606 gstring
= composition_gstring_from_id (src
->u
.cmp
.id
);
607 required
= src
->u
.cmp
.to
- src
->u
.cmp
.from
;
611 cmp
= composition_table
[src
->u
.cmp
.id
];
612 required
= MAX_MULTIBYTE_LENGTH
* cmp
->glyph_len
;
615 if (encode_terminal_src_size
< nbytes
+ required
)
617 encode_terminal_src_size
= nbytes
+ required
;
618 encode_terminal_src
= xrealloc (encode_terminal_src
,
619 encode_terminal_src_size
);
620 buf
= encode_terminal_src
+ nbytes
;
623 if (src
->u
.cmp
.automatic
)
624 for (i
= src
->u
.cmp
.from
; i
< src
->u
.cmp
.to
; i
++)
626 Lisp_Object g
= LGSTRING_GLYPH (gstring
, i
);
627 int c
= LGLYPH_CHAR (g
);
629 if (! char_charset (c
, charset_list
, NULL
))
631 buf
+= CHAR_STRING (c
, buf
);
635 for (i
= 0; i
< cmp
->glyph_len
; i
++)
637 int c
= COMPOSITION_GLYPH (cmp
, i
);
639 if (! char_charset (c
, charset_list
, NULL
))
641 buf
+= CHAR_STRING (c
, buf
);
646 /* The first character of the composition is not encodable. */
651 /* We must skip glyphs to be padded for a wide character. */
652 else if (! CHAR_GLYPH_PADDING_P (*src
))
659 SET_GLYPH_FROM_CHAR_GLYPH (g
, src
[0]);
661 if (GLYPH_INVALID_P (g
) || GLYPH_SIMPLE_P (tbase
, tlen
, g
))
663 /* This glyph doesn't have an entry in Vglyph_table. */
668 /* This glyph has an entry in Vglyph_table,
669 so process any alias before testing for simpleness. */
670 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
672 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
673 /* We set the multi-byte form of a character in G
674 (that should be an ASCII character) at WORKBUF. */
677 /* We have a string in Vglyph_table. */
678 string
= tbase
[GLYPH_CHAR (g
)];
683 nbytes
= buf
- encode_terminal_src
;
684 if (encode_terminal_src_size
< nbytes
+ MAX_MULTIBYTE_LENGTH
)
686 encode_terminal_src_size
= nbytes
+ MAX_MULTIBYTE_LENGTH
;
687 encode_terminal_src
= xrealloc (encode_terminal_src
,
688 encode_terminal_src_size
);
689 buf
= encode_terminal_src
+ nbytes
;
691 if (char_charset (c
, charset_list
, NULL
))
693 /* Store the multibyte form of C at BUF. */
694 buf
+= CHAR_STRING (c
, buf
);
699 /* C is not encodable. */
702 while (src
+ 1 < src_end
&& CHAR_GLYPH_PADDING_P (src
[1]))
712 unsigned char *p
= SDATA (string
), *pend
= p
+ SBYTES (string
);
714 if (! STRING_MULTIBYTE (string
))
715 string
= string_to_multibyte (string
);
716 nbytes
= buf
- encode_terminal_src
;
717 if (encode_terminal_src_size
< nbytes
+ SBYTES (string
))
719 encode_terminal_src_size
= nbytes
+ SBYTES (string
);
720 encode_terminal_src
= xrealloc (encode_terminal_src
,
721 encode_terminal_src_size
);
722 buf
= encode_terminal_src
+ nbytes
;
724 bcopy (SDATA (string
), buf
, SBYTES (string
));
725 buf
+= SBYTES (string
);
726 nchars
+= SCHARS (string
);
734 coding
->produced
= 0;
738 nbytes
= buf
- encode_terminal_src
;
739 coding
->source
= encode_terminal_src
;
740 if (encode_terminal_dst_size
== 0)
742 encode_terminal_dst_size
= encode_terminal_src_size
;
743 if (encode_terminal_dst
)
744 encode_terminal_dst
= xrealloc (encode_terminal_dst
,
745 encode_terminal_dst_size
);
747 encode_terminal_dst
= xmalloc (encode_terminal_dst_size
);
749 coding
->destination
= encode_terminal_dst
;
750 coding
->dst_bytes
= encode_terminal_dst_size
;
751 encode_coding_object (coding
, Qnil
, 0, 0, nchars
, nbytes
, Qnil
);
752 /* coding->destination may have been reallocated. */
753 encode_terminal_dst
= coding
->destination
;
754 encode_terminal_dst_size
= coding
->dst_bytes
;
756 return (encode_terminal_dst
);
761 /* An implementation of write_glyphs for termcap frames. */
764 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
766 unsigned char *conversion_buffer
;
767 struct coding_system
*coding
;
769 struct tty_display_info
*tty
= FRAME_TTY (f
);
771 tty_turn_off_insert (tty
);
772 tty_hide_cursor (tty
);
774 /* Don't dare write in last column of bottom line, if Auto-Wrap,
775 since that would scroll the whole frame on some terminals. */
778 && curY (tty
) + 1 == FRAME_LINES (f
)
779 && (curX (tty
) + len
) == FRAME_COLS (f
))
786 /* If terminal_coding does any conversion, use it, otherwise use
787 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
788 because it always return 1 if the member src_multibyte is 1. */
789 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
790 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
791 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
793 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
797 /* Identify a run of glyphs with the same face. */
798 int face_id
= string
->face_id
;
801 for (n
= 1; n
< len
; ++n
)
802 if (string
[n
].face_id
!= face_id
)
805 /* Turn appearance modes of the face of the run on. */
806 tty_highlight_if_desired (tty
);
807 turn_on_face (f
, face_id
);
810 /* This is the last run. */
811 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
812 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
813 if (coding
->produced
> 0)
816 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
817 if (ferror (tty
->output
))
818 clearerr (tty
->output
);
820 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
826 /* Turn appearance modes off. */
827 turn_off_face (f
, face_id
);
828 tty_turn_off_highlight (tty
);
834 #ifdef HAVE_GPM /* Only used by GPM code. */
837 tty_write_glyphs_with_face (f
, string
, len
, face_id
)
838 register struct frame
*f
;
839 register struct glyph
*string
;
840 register int len
, face_id
;
842 unsigned char *conversion_buffer
;
843 struct coding_system
*coding
;
845 struct tty_display_info
*tty
= FRAME_TTY (f
);
847 tty_turn_off_insert (tty
);
848 tty_hide_cursor (tty
);
850 /* Don't dare write in last column of bottom line, if Auto-Wrap,
851 since that would scroll the whole frame on some terminals. */
854 && curY (tty
) + 1 == FRAME_LINES (f
)
855 && (curX (tty
) + len
) == FRAME_COLS (f
))
862 /* If terminal_coding does any conversion, use it, otherwise use
863 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
864 because it always return 1 if the member src_multibyte is 1. */
865 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
866 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
867 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
869 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
871 /* Turn appearance modes of the face. */
872 tty_highlight_if_desired (tty
);
873 turn_on_face (f
, face_id
);
875 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
876 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
877 if (coding
->produced
> 0)
880 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
881 if (ferror (tty
->output
))
882 clearerr (tty
->output
);
884 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
888 /* Turn appearance modes off. */
889 turn_off_face (f
, face_id
);
890 tty_turn_off_highlight (tty
);
896 /* An implementation of insert_glyphs for termcap frames. */
899 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
902 struct glyph
*glyph
= NULL
;
903 unsigned char *conversion_buffer
;
904 unsigned char space
[1];
905 struct coding_system
*coding
;
907 struct tty_display_info
*tty
= FRAME_TTY (f
);
909 if (tty
->TS_ins_multi_chars
)
911 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
915 write_glyphs (f
, start
, len
);
919 tty_turn_on_insert (tty
);
923 space
[0] = SPACEGLYPH
;
925 /* If terminal_coding does any conversion, use it, otherwise use
926 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
927 because it always return 1 if the member src_multibyte is 1. */
928 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
929 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
930 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
932 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
936 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
939 conversion_buffer
= space
;
940 coding
->produced
= 1;
944 tty_highlight_if_desired (tty
);
945 turn_on_face (f
, start
->face_id
);
948 /* We must open sufficient space for a character which
949 occupies more than one column. */
950 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
952 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
957 /* This is the last glyph. */
958 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
960 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
963 if (coding
->produced
> 0)
966 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
967 if (ferror (tty
->output
))
968 clearerr (tty
->output
);
970 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
974 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
977 turn_off_face (f
, glyph
->face_id
);
978 tty_turn_off_highlight (tty
);
985 /* An implementation of delete_glyphs for termcap frames. */
988 tty_delete_glyphs (struct frame
*f
, int n
)
993 struct tty_display_info
*tty
= FRAME_TTY (f
);
995 if (tty
->delete_in_insert_mode
)
997 tty_turn_on_insert (tty
);
1001 tty_turn_off_insert (tty
);
1002 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
1005 if (tty
->TS_del_multi_chars
)
1007 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
1012 for (i
= 0; i
< n
; i
++)
1013 OUTPUT1 (tty
, tty
->TS_del_char
);
1014 if (!tty
->delete_in_insert_mode
)
1015 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
1018 /* An implementation of ins_del_lines for termcap frames. */
1021 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
1023 struct tty_display_info
*tty
= FRAME_TTY (f
);
1024 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
1025 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
1026 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
1028 register int i
= n
> 0 ? n
: -n
;
1031 /* If the lines below the insertion are being pushed
1032 into the end of the window, this is the same as clearing;
1033 and we know the lines are already clear, since the matching
1034 deletion has already been done. So can ignore this. */
1035 /* If the lines below the deletion are blank lines coming
1036 out of the end of the window, don't bother,
1037 as there will be a matching inslines later that will flush them. */
1038 if (FRAME_SCROLL_REGION_OK (f
)
1039 && vpos
+ i
>= tty
->specified_window
)
1041 if (!FRAME_MEMORY_BELOW_FRAME (f
)
1042 && vpos
+ i
>= FRAME_LINES (f
))
1047 raw_cursor_to (f
, vpos
, 0);
1048 tty_background_highlight (tty
);
1049 buf
= tparam (multi
, 0, 0, i
);
1055 raw_cursor_to (f
, vpos
, 0);
1056 tty_background_highlight (tty
);
1058 OUTPUT (tty
, single
);
1059 if (tty
->TF_teleray
)
1064 tty_set_scroll_region (f
, vpos
, tty
->specified_window
);
1066 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
1068 raw_cursor_to (f
, vpos
, 0);
1069 tty_background_highlight (tty
);
1071 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1072 tty_set_scroll_region (f
, 0, tty
->specified_window
);
1075 if (!FRAME_SCROLL_REGION_OK (f
)
1076 && FRAME_MEMORY_BELOW_FRAME (f
)
1079 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
1084 /* Compute cost of sending "str", in characters,
1085 not counting any line-dependent padding. */
1088 string_cost (char *str
)
1092 tputs (str
, 0, evalcost
);
1096 /* Compute cost of sending "str", in characters,
1097 counting any line-dependent padding at one line. */
1100 string_cost_one_line (char *str
)
1104 tputs (str
, 1, evalcost
);
1108 /* Compute per line amount of line-dependent padding,
1109 in tenths of characters. */
1112 per_line_cost (char *str
)
1116 tputs (str
, 0, evalcost
);
1119 tputs (str
, 10, evalcost
);
1124 /* char_ins_del_cost[n] is cost of inserting N characters.
1125 char_ins_del_cost[-n] is cost of deleting N characters.
1126 The length of this vector is based on max_frame_cols. */
1128 int *char_ins_del_vector
;
1130 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1135 calculate_ins_del_char_costs (struct frame
*f
)
1137 struct tty_display_info
*tty
= FRAME_TTY (f
);
1138 int ins_startup_cost
, del_startup_cost
;
1139 int ins_cost_per_char
, del_cost_per_char
;
1143 if (tty
->TS_ins_multi_chars
)
1145 ins_cost_per_char
= 0;
1146 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1148 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1149 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1151 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1152 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1153 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1154 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1158 ins_startup_cost
= 9999;
1159 ins_cost_per_char
= 0;
1162 if (tty
->TS_del_multi_chars
)
1164 del_cost_per_char
= 0;
1165 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1167 else if (tty
->TS_del_char
)
1169 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1170 + string_cost (tty
->TS_end_delete_mode
));
1171 if (tty
->delete_in_insert_mode
)
1172 del_startup_cost
/= 2;
1173 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1177 del_startup_cost
= 9999;
1178 del_cost_per_char
= 0;
1181 /* Delete costs are at negative offsets */
1182 p
= &char_ins_del_cost (f
)[0];
1183 for (i
= FRAME_COLS (f
); --i
>= 0;)
1184 *--p
= (del_startup_cost
+= del_cost_per_char
);
1186 /* Doing nothing is free */
1187 p
= &char_ins_del_cost (f
)[0];
1190 /* Insert costs are at positive offsets */
1191 for (i
= FRAME_COLS (f
); --i
>= 0;)
1192 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1196 calculate_costs (struct frame
*frame
)
1198 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1200 if (FRAME_TERMCAP_P (frame
))
1202 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1203 register char *f
= (tty
->TS_set_scroll_region
1204 ? tty
->TS_set_scroll_region
1205 : tty
->TS_set_scroll_region_1
);
1207 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1211 /* These variables are only used for terminal stuff. They are
1212 allocated once for the terminal frame of X-windows emacs, but not
1215 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1216 X turns off char_ins_del_ok. */
1218 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1219 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1221 if (char_ins_del_vector
!= 0)
1223 = (int *) xrealloc (char_ins_del_vector
,
1225 + 2 * max_frame_cols
* sizeof (int)));
1228 = (int *) xmalloc (sizeof (int)
1229 + 2 * max_frame_cols
* sizeof (int));
1231 bzero (char_ins_del_vector
, (sizeof (int)
1232 + 2 * max_frame_cols
* sizeof (int)));
1235 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1236 do_line_insertion_deletion_costs (frame
,
1237 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1238 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1241 do_line_insertion_deletion_costs (frame
,
1242 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1243 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1246 calculate_ins_del_char_costs (frame
);
1248 /* Don't use TS_repeat if its padding is worse than sending the chars */
1249 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1250 tty
->RPov
= string_cost (tty
->TS_repeat
);
1252 tty
->RPov
= FRAME_COLS (frame
) * 2;
1254 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1262 /* Termcap capability names that correspond directly to X keysyms.
1263 Some of these (marked "terminfo") aren't supplied by old-style
1264 (Berkeley) termcap entries. They're listed in X keysym order;
1265 except we put the keypad keys first, so that if they clash with
1266 other keys (as on the IBM PC keyboard) they get overridden.
1269 static struct fkey_table keys
[] =
1271 {"kh", "home"}, /* termcap */
1272 {"kl", "left"}, /* termcap */
1273 {"ku", "up"}, /* termcap */
1274 {"kr", "right"}, /* termcap */
1275 {"kd", "down"}, /* termcap */
1276 {"%8", "prior"}, /* terminfo */
1277 {"%5", "next"}, /* terminfo */
1278 {"@7", "end"}, /* terminfo */
1279 {"@1", "begin"}, /* terminfo */
1280 {"*6", "select"}, /* terminfo */
1281 {"%9", "print"}, /* terminfo */
1282 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1284 * "insert" --- see below
1286 {"&8", "undo"}, /* terminfo */
1287 {"%0", "redo"}, /* terminfo */
1288 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1289 {"@0", "find"}, /* terminfo */
1290 {"@2", "cancel"}, /* terminfo */
1291 {"%1", "help"}, /* terminfo */
1293 * "break" goes here, but can't be reliably intercepted with termcap
1295 {"&4", "reset"}, /* terminfo --- actually `restart' */
1297 * "system" and "user" --- no termcaps
1299 {"kE", "clearline"}, /* terminfo */
1300 {"kA", "insertline"}, /* terminfo */
1301 {"kL", "deleteline"}, /* terminfo */
1302 {"kI", "insertchar"}, /* terminfo */
1303 {"kD", "deletechar"}, /* terminfo */
1304 {"kB", "backtab"}, /* terminfo */
1306 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1308 {"@8", "kp-enter"}, /* terminfo */
1310 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1311 * "kp-multiply", "kp-add", "kp-separator",
1312 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1313 * --- no termcaps for any of these.
1315 {"K4", "kp-1"}, /* terminfo */
1317 * "kp-2" --- no termcap
1319 {"K5", "kp-3"}, /* terminfo */
1321 * "kp-4" --- no termcap
1323 {"K2", "kp-5"}, /* terminfo */
1325 * "kp-6" --- no termcap
1327 {"K1", "kp-7"}, /* terminfo */
1329 * "kp-8" --- no termcap
1331 {"K3", "kp-9"}, /* terminfo */
1333 * "kp-equal" --- no termcap
1345 {"&0", "S-cancel"}, /*shifted cancel key*/
1346 {"&9", "S-begin"}, /*shifted begin key*/
1347 {"*0", "S-find"}, /*shifted find key*/
1348 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1349 {"*4", "S-delete"}, /*shifted delete-character key*/
1350 {"*7", "S-end"}, /*shifted end key*/
1351 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1352 {"#1", "S-help"}, /*shifted help key*/
1353 {"#2", "S-home"}, /*shifted home key*/
1354 {"#3", "S-insert"}, /*shifted insert-character key*/
1355 {"#4", "S-left"}, /*shifted left-arrow key*/
1356 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1357 {"%c", "S-next"}, /*shifted next key*/
1358 {"%e", "S-prior"}, /*shifted previous key*/
1359 {"%f", "S-print"}, /*shifted print key*/
1360 {"%g", "S-redo"}, /*shifted redo key*/
1361 {"%i", "S-right"}, /*shifted right-arrow key*/
1362 {"!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 ();
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 (address
, kboard
)
1378 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1379 errors during the call. The only errors should be from Fdefine_key
1380 when given a key sequence containing an invalid prefix key. If the
1381 termcap defines function keys which use a prefix that is already bound
1382 to a command by the default bindings, we should silently ignore that
1383 function key specification, rather than giving the user an error and
1384 refusing to run at all on such a terminal. */
1386 extern Lisp_Object
Fidentity ();
1387 term_get_fkeys_address
= address
;
1388 term_get_fkeys_kboard
= kboard
;
1389 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1397 char **address
= term_get_fkeys_address
;
1398 KBOARD
*kboard
= term_get_fkeys_kboard
;
1400 /* This can happen if CANNOT_DUMP or with strange options. */
1401 if (!KEYMAPP (kboard
->Vinput_decode_map
))
1402 kboard
->Vinput_decode_map
= Fmake_sparse_keymap (Qnil
);
1404 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1406 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1408 Fdefine_key (kboard
->Vinput_decode_map
, build_string (sequence
),
1409 Fmake_vector (make_number (1),
1410 intern (keys
[i
].name
)));
1413 /* The uses of the "k0" capability are inconsistent; sometimes it
1414 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1415 We will attempt to politely accommodate both systems by testing for
1416 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1419 char *k_semi
= tgetstr ("k;", address
);
1420 char *k0
= tgetstr ("k0", address
);
1421 char *k0_name
= "f10";
1426 /* Define f0 first, so that f10 takes precedence in case the
1427 key sequences happens to be the same. */
1428 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k0
),
1429 Fmake_vector (make_number (1), intern ("f0")));
1430 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k_semi
),
1431 Fmake_vector (make_number (1), intern ("f10")));
1434 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k0
),
1435 Fmake_vector (make_number (1), intern (k0_name
)));
1438 /* Set up cookies for numbered function keys above f10. */
1440 char fcap
[3], fkey
[4];
1442 fcap
[0] = 'F'; fcap
[2] = '\0';
1443 for (i
= 11; i
< 64; i
++)
1446 fcap
[1] = '1' + i
- 11;
1448 fcap
[1] = 'A' + i
- 20;
1450 fcap
[1] = 'a' + i
- 46;
1453 char *sequence
= tgetstr (fcap
, address
);
1456 sprintf (fkey
, "f%d", i
);
1457 Fdefine_key (kboard
->Vinput_decode_map
, build_string (sequence
),
1458 Fmake_vector (make_number (1),
1466 * Various mappings to try and get a better fit.
1469 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1470 if (!tgetstr (cap1, address)) \
1472 char *sequence = tgetstr (cap2, address); \
1474 Fdefine_key (kboard->Vinput_decode_map, build_string (sequence), \
1475 Fmake_vector (make_number (1), \
1479 /* if there's no key_next keycap, map key_npage to `next' keysym */
1480 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1481 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1482 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1483 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1484 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1485 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1486 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1488 /* IBM has their own non-standard dialect of terminfo.
1489 If the standard name isn't found, try the IBM name. */
1490 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1491 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1492 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1493 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1494 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1495 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1496 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1497 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1498 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1499 #undef CONDITIONAL_REASSIGN
1506 /***********************************************************************
1507 Character Display Information
1508 ***********************************************************************/
1510 /* Avoid name clash with functions defined in xterm.c */
1512 #define append_glyph append_glyph_term
1513 #define produce_stretch_glyph produce_stretch_glyph_term
1514 #define append_composite_glyph append_composite_glyph_term
1515 #define produce_composite_glyph produce_composite_glyph_term
1518 static void append_glyph
P_ ((struct it
*));
1519 static void produce_stretch_glyph
P_ ((struct it
*));
1520 static void append_composite_glyph
P_ ((struct it
*));
1521 static void produce_composite_glyph
P_ ((struct it
*));
1523 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1524 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1525 the character for which to produce glyphs; IT->face_id contains the
1526 character's face. Padding glyphs are appended if IT->c has a
1527 IT->pixel_width > 1. */
1533 struct glyph
*glyph
, *end
;
1536 xassert (it
->glyph_row
);
1537 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1538 + it
->glyph_row
->used
[it
->area
]);
1539 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1542 i
< it
->pixel_width
&& glyph
< end
;
1545 glyph
->type
= CHAR_GLYPH
;
1546 glyph
->pixel_width
= 1;
1547 glyph
->u
.ch
= it
->char_to_display
;
1548 glyph
->face_id
= it
->face_id
;
1549 glyph
->padding_p
= i
> 0;
1550 glyph
->charpos
= CHARPOS (it
->position
);
1551 glyph
->object
= it
->object
;
1553 ++it
->glyph_row
->used
[it
->area
];
1559 /* Produce glyphs for the display element described by IT. *IT
1560 specifies what we want to produce a glyph for (character, image, ...),
1561 and where in the glyph matrix we currently are (glyph row and hpos).
1562 produce_glyphs fills in output fields of *IT with information such as the
1563 pixel width and height of a character, and maybe output actual glyphs at
1564 the same time if IT->glyph_row is non-null. See the explanation of
1565 struct display_iterator in dispextern.h for an overview.
1567 produce_glyphs also stores the result of glyph width, ascent
1568 etc. computations in *IT.
1570 IT->glyph_row may be null, in which case produce_glyphs does not
1571 actually fill in the glyphs. This is used in the move_* functions
1572 in xdisp.c for text width and height computations.
1574 Callers usually don't call produce_glyphs directly;
1575 instead they use the macro PRODUCE_GLYPHS. */
1581 /* If a hook is installed, let it do the work. */
1583 /* Nothing but characters are supported on terminal frames. */
1584 xassert (it
->what
== IT_CHARACTER
1585 || it
->what
== IT_COMPOSITION
1586 || it
->what
== IT_STRETCH
);
1588 if (it
->what
== IT_STRETCH
)
1590 produce_stretch_glyph (it
);
1594 if (it
->what
== IT_COMPOSITION
)
1596 produce_composite_glyph (it
);
1600 /* Maybe translate single-byte characters to multibyte. */
1601 it
->char_to_display
= it
->c
;
1603 if (it
->c
>= 040 && it
->c
< 0177)
1605 it
->pixel_width
= it
->nglyphs
= 1;
1609 else if (it
->c
== '\n')
1610 it
->pixel_width
= it
->nglyphs
= 0;
1611 else if (it
->c
== '\t')
1613 int absolute_x
= (it
->current_x
1614 + it
->continuation_lines_width
);
1616 = (((1 + absolute_x
+ it
->tab_width
- 1)
1621 /* If part of the TAB has been displayed on the previous line
1622 which is continued now, continuation_lines_width will have
1623 been incremented already by the part that fitted on the
1624 continued line. So, we will get the right number of spaces
1626 nspaces
= next_tab_x
- absolute_x
;
1632 it
->char_to_display
= ' ';
1633 it
->pixel_width
= it
->len
= 1;
1639 it
->pixel_width
= nspaces
;
1640 it
->nglyphs
= nspaces
;
1642 else if (CHAR_BYTE8_P (it
->c
))
1644 if (unibyte_display_via_language_environment
1647 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1648 it
->pixel_width
= CHAR_WIDTH (it
->char_to_display
);
1649 it
->nglyphs
= it
->pixel_width
;
1655 /* Coming here means that it->c is from display table, thus
1656 we must send the raw 8-bit byte as is to the terminal.
1657 Although there's no way to know how many columns it
1658 occupies on a screen, it is a good assumption that a
1659 single byte code has 1-column width. */
1660 it
->pixel_width
= it
->nglyphs
= 1;
1667 it
->pixel_width
= CHAR_WIDTH (it
->c
);
1668 it
->nglyphs
= it
->pixel_width
;
1675 /* Advance current_x by the pixel width as a convenience for
1677 if (it
->area
== TEXT_AREA
)
1678 it
->current_x
+= it
->pixel_width
;
1679 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1680 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1684 /* Produce a stretch glyph for iterator IT. IT->object is the value
1685 of the glyph property displayed. The value must be a list
1686 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1689 1. `:width WIDTH' specifies that the space should be WIDTH *
1690 canonical char width wide. WIDTH may be an integer or floating
1693 2. `:align-to HPOS' specifies that the space should be wide enough
1694 to reach HPOS, a value in canonical character units. */
1697 produce_stretch_glyph (it
)
1700 /* (space :width WIDTH ...) */
1701 Lisp_Object prop
, plist
;
1702 int width
= 0, align_to
= -1;
1703 int zero_width_ok_p
= 0;
1706 /* List should start with `space'. */
1707 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1708 plist
= XCDR (it
->object
);
1710 /* Compute the width of the stretch. */
1711 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1712 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1714 /* Absolute width `:width WIDTH' specified and valid. */
1715 zero_width_ok_p
= 1;
1716 width
= (int)(tem
+ 0.5);
1718 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1719 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1721 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1722 align_to
= (align_to
< 0
1724 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1725 else if (align_to
< 0)
1726 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1727 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1728 zero_width_ok_p
= 1;
1731 /* Nothing specified -> width defaults to canonical char width. */
1732 width
= FRAME_COLUMN_WIDTH (it
->f
);
1734 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1737 if (width
> 0 && it
->glyph_row
)
1739 Lisp_Object o_object
= it
->object
;
1740 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1743 if (!STRINGP (object
))
1744 object
= it
->w
->buffer
;
1745 it
->object
= object
;
1746 it
->char_to_display
= ' ';
1747 it
->pixel_width
= it
->len
= 1;
1750 it
->object
= o_object
;
1752 it
->pixel_width
= width
;
1753 it
->nglyphs
= width
;
1757 /* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
1758 Called from produce_composite_glyph for terminal frames if
1759 IT->glyph_row != NULL. IT->face_id contains the character's
1763 append_composite_glyph (it
)
1766 struct glyph
*glyph
;
1768 xassert (it
->glyph_row
);
1769 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1770 if (glyph
< it
->glyph_row
->glyphs
[1 + it
->area
])
1772 glyph
->type
= COMPOSITE_GLYPH
;
1773 glyph
->pixel_width
= it
->pixel_width
;
1774 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1775 if (it
->cmp_it
.ch
< 0)
1777 glyph
->u
.cmp
.automatic
= 0;
1778 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1782 glyph
->u
.cmp
.automatic
= 1;
1783 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1784 glyph
->u
.cmp
.from
= it
->cmp_it
.from
;
1785 glyph
->u
.cmp
.to
= it
->cmp_it
.to
;
1788 glyph
->face_id
= it
->face_id
;
1789 glyph
->padding_p
= 0;
1790 glyph
->charpos
= CHARPOS (it
->position
);
1791 glyph
->object
= it
->object
;
1793 ++it
->glyph_row
->used
[it
->area
];
1799 /* Produce a composite glyph for iterator IT. IT->cmp_id is the ID of
1800 the composition. We simply produces components of the composition
1801 assuming that that the terminal has a capability to layout/render
1805 produce_composite_glyph (it
)
1810 if (it
->cmp_it
.ch
< 0)
1812 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
1814 c
= COMPOSITION_GLYPH (cmp
, 0);
1815 it
->pixel_width
= CHAR_WIDTH (it
->c
);
1819 Lisp_Object gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
1821 it
->pixel_width
= composition_gstring_width (gstring
, it
->cmp_it
.from
,
1822 it
->cmp_it
.to
, NULL
);
1826 append_composite_glyph (it
);
1830 /* Get information about special display element WHAT in an
1831 environment described by IT. WHAT is one of IT_TRUNCATION or
1832 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1833 non-null glyph_row member. This function ensures that fields like
1834 face_id, c, len of IT are left untouched. */
1837 produce_special_glyphs (it
, what
)
1839 enum display_element_type what
;
1847 temp_it
.what
= IT_CHARACTER
;
1849 temp_it
.object
= make_number (0);
1850 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1852 if (what
== IT_CONTINUATION
)
1854 /* Continuation glyph. */
1855 SET_GLYPH_FROM_CHAR (glyph
, '\\');
1857 && (gc
= DISP_CONTINUE_GLYPH (it
->dp
), GLYPH_CODE_P (gc
))
1858 && GLYPH_CODE_CHAR_VALID_P (gc
))
1860 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
1861 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
1864 else if (what
== IT_TRUNCATION
)
1866 /* Truncation glyph. */
1867 SET_GLYPH_FROM_CHAR (glyph
, '$');
1869 && (gc
= DISP_TRUNC_GLYPH (it
->dp
), GLYPH_CODE_P (gc
))
1870 && GLYPH_CODE_CHAR_VALID_P (gc
))
1872 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
1873 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
1879 temp_it
.c
= GLYPH_CHAR (glyph
);
1880 temp_it
.face_id
= GLYPH_FACE (glyph
);
1881 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1883 produce_glyphs (&temp_it
);
1884 it
->pixel_width
= temp_it
.pixel_width
;
1885 it
->nglyphs
= temp_it
.pixel_width
;
1890 /***********************************************************************
1892 ***********************************************************************/
1894 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1895 one of the enumerators from enum no_color_bit, or a bit set built
1896 from them. Some display attributes may not be used together with
1897 color; the termcap capability `NC' specifies which ones. */
1899 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1900 (tty->TN_max_colors > 0 \
1901 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1904 /* Turn appearances of face FACE_ID on tty frame F on.
1905 FACE_ID is a realized face ID number, in the face cache. */
1908 turn_on_face (f
, face_id
)
1912 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1913 long fg
= face
->foreground
;
1914 long bg
= face
->background
;
1915 struct tty_display_info
*tty
= FRAME_TTY (f
);
1917 /* Do this first because TS_end_standout_mode may be the same
1918 as TS_exit_attribute_mode, which turns all appearances off. */
1919 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1921 if (tty
->TN_max_colors
> 0)
1923 if (fg
>= 0 && bg
>= 0)
1925 /* If the terminal supports colors, we can set them
1926 below without using reverse video. The face's fg
1927 and bg colors are set as they should appear on
1928 the screen, i.e. they take the inverse-video'ness
1929 of the face already into account. */
1931 else if (inverse_video
)
1933 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1934 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1935 tty_toggle_highlight (tty
);
1939 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1940 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1941 tty_toggle_highlight (tty
);
1946 /* If we can't display colors, use reverse video
1947 if the face specifies that. */
1950 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1951 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1952 tty_toggle_highlight (tty
);
1956 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1957 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1958 tty_toggle_highlight (tty
);
1963 if (face
->tty_bold_p
)
1965 if (MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1966 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1968 else if (face
->tty_dim_p
)
1969 if (MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1970 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1972 /* Alternate charset and blinking not yet used. */
1973 if (face
->tty_alt_charset_p
1974 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1975 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1977 if (face
->tty_blinking_p
1978 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1979 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1981 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1982 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1984 if (tty
->TN_max_colors
> 0)
1988 ts
= tty
->standout_mode
? tty
->TS_set_background
: tty
->TS_set_foreground
;
1991 p
= tparam (ts
, NULL
, 0, (int) fg
);
1996 ts
= tty
->standout_mode
? tty
->TS_set_foreground
: tty
->TS_set_background
;
1999 p
= tparam (ts
, NULL
, 0, (int) bg
);
2007 /* Turn off appearances of face FACE_ID on tty frame F. */
2010 turn_off_face (f
, face_id
)
2014 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2015 struct tty_display_info
*tty
= FRAME_TTY (f
);
2017 xassert (face
!= NULL
);
2019 if (tty
->TS_exit_attribute_mode
)
2021 /* Capability "me" will turn off appearance modes double-bright,
2022 half-bright, reverse-video, standout, underline. It may or
2023 may not turn off alt-char-mode. */
2024 if (face
->tty_bold_p
2026 || face
->tty_reverse_p
2027 || face
->tty_alt_charset_p
2028 || face
->tty_blinking_p
2029 || face
->tty_underline_p
)
2031 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
2032 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
2033 tty
->standout_mode
= 0;
2036 if (face
->tty_alt_charset_p
)
2037 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
2041 /* If we don't have "me" we can only have those appearances
2042 that have exit sequences defined. */
2043 if (face
->tty_alt_charset_p
)
2044 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
2046 if (face
->tty_underline_p
)
2047 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
2050 /* Switch back to default colors. */
2051 if (tty
->TN_max_colors
> 0
2052 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2053 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2054 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2055 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2056 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
2060 /* Return non-zero if the terminal on frame F supports all of the
2061 capabilities in CAPS simultaneously, with foreground and background
2062 colors FG and BG. */
2065 tty_capable_p (tty
, caps
, fg
, bg
)
2066 struct tty_display_info
*tty
;
2068 unsigned long fg
, bg
;
2070 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
2071 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
2074 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
2075 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
2076 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
2077 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
2078 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
2079 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
2085 /* Return non-zero if the terminal is capable to display colors. */
2087 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2089 doc
: /* Return non-nil if the tty device TERMINAL can display colors.
2091 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2092 frame's terminal). This function always returns nil if TERMINAL
2093 is not on a tty device. */)
2095 Lisp_Object terminal
;
2097 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2101 return t
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
2104 /* Return the number of supported colors. */
2105 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2106 Stty_display_color_cells
, 0, 1, 0,
2107 doc
: /* Return the number of colors supported by the tty device TERMINAL.
2109 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2110 frame's terminal). This function always returns 0 if TERMINAL
2111 is not on a tty device. */)
2113 Lisp_Object terminal
;
2115 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2117 return make_number (0);
2119 return make_number (t
->display_info
.tty
->TN_max_colors
);
2124 /* Declare here rather than in the function, as in the rest of Emacs,
2125 to work around an HPUX compiler bug (?). See
2126 http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00410.html */
2127 static int default_max_colors
;
2128 static int default_max_pairs
;
2129 static int default_no_color_video
;
2130 static char *default_orig_pair
;
2131 static char *default_set_foreground
;
2132 static char *default_set_background
;
2134 /* Save or restore the default color-related capabilities of this
2137 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
2142 xfree (default_orig_pair
);
2143 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
2145 xfree (default_set_foreground
);
2146 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
2149 xfree (default_set_background
);
2150 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
2153 default_max_colors
= tty
->TN_max_colors
;
2154 default_max_pairs
= tty
->TN_max_pairs
;
2155 default_no_color_video
= tty
->TN_no_color_video
;
2159 tty
->TS_orig_pair
= default_orig_pair
;
2160 tty
->TS_set_foreground
= default_set_foreground
;
2161 tty
->TS_set_background
= default_set_background
;
2162 tty
->TN_max_colors
= default_max_colors
;
2163 tty
->TN_max_pairs
= default_max_pairs
;
2164 tty
->TN_no_color_video
= default_no_color_video
;
2168 /* Setup one of the standard tty color schemes according to MODE.
2169 MODE's value is generally the number of colors which we want to
2170 support; zero means set up for the default capabilities, the ones
2171 we saw at init_tty time; -1 means turn off color support. */
2173 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2175 /* Canonicalize all negative values of MODE. */
2181 case -1: /* no colors at all */
2182 tty
->TN_max_colors
= 0;
2183 tty
->TN_max_pairs
= 0;
2184 tty
->TN_no_color_video
= 0;
2185 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2187 case 0: /* default colors, if any */
2189 tty_default_color_capabilities (tty
, 0);
2191 case 8: /* 8 standard ANSI colors */
2192 tty
->TS_orig_pair
= "\033[0m";
2194 tty
->TS_set_foreground
= "\033[3%p1%dm";
2195 tty
->TS_set_background
= "\033[4%p1%dm";
2197 tty
->TS_set_foreground
= "\033[3%dm";
2198 tty
->TS_set_background
= "\033[4%dm";
2200 tty
->TN_max_colors
= 8;
2201 tty
->TN_max_pairs
= 64;
2202 tty
->TN_no_color_video
= 0;
2208 set_tty_color_mode (tty
, f
)
2209 struct tty_display_info
*tty
;
2212 Lisp_Object tem
, val
, color_mode_spec
;
2213 Lisp_Object color_mode
;
2215 extern Lisp_Object Qtty_color_mode
;
2216 Lisp_Object tty_color_mode_alist
2217 = Fintern_soft (build_string ("tty-color-mode-alist"), Qnil
);
2219 tem
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2220 val
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2226 tem
= (NILP (tty_color_mode_alist
) ? Qnil
2227 : Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
));
2228 color_mode
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2231 mode
= INTEGERP (color_mode
) ? XINT (color_mode
) : 0;
2233 if (mode
!= tty
->previous_color_mode
)
2235 Lisp_Object funsym
= intern ("tty-set-up-initial-frame-faces");
2236 tty
->previous_color_mode
= mode
;
2237 tty_setup_colors (tty
, mode
);
2238 /* This recomputes all the faces given the new color definitions. */
2239 safe_call (1, &funsym
);
2243 #endif /* !DOS_NT */
2247 /* Return the tty display object specified by TERMINAL. */
2250 get_tty_terminal (Lisp_Object terminal
, int throw)
2252 struct terminal
*t
= get_terminal (terminal
, throw);
2254 if (t
&& t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2257 error ("Device %d is not a termcap terminal device", t
->id
);
2265 /* Return an active termcap device that uses the tty device with the
2268 This function ignores suspended devices.
2270 Returns NULL if the named terminal device is not opened. */
2273 get_named_tty (name
)
2281 for (t
= terminal_list
; t
; t
= t
->next_terminal
)
2283 if ((t
->type
== output_termcap
|| t
->type
== output_msdos_raw
)
2284 && !strcmp (t
->display_info
.tty
->name
, name
)
2285 && TERMINAL_ACTIVE_P (t
))
2293 DEFUN ("tty-type", Ftty_type
, Stty_type
, 0, 1, 0,
2294 doc
: /* Return the type of the tty device that TERMINAL uses.
2295 Returns nil if TERMINAL is not on a tty device.
2297 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2298 frame's terminal). */)
2300 Lisp_Object terminal
;
2302 struct terminal
*t
= get_terminal (terminal
, 1);
2304 if (t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2307 if (t
->display_info
.tty
->type
)
2308 return build_string (t
->display_info
.tty
->type
);
2313 DEFUN ("controlling-tty-p", Fcontrolling_tty_p
, Scontrolling_tty_p
, 0, 1, 0,
2314 doc
: /* Return non-nil if TERMINAL is the controlling tty of the Emacs process.
2316 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2317 frame's terminal). This function always returns nil if TERMINAL
2318 is not on a tty device. */)
2320 Lisp_Object terminal
;
2322 struct terminal
*t
= get_terminal (terminal
, 1);
2324 if ((t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2325 || strcmp (t
->display_info
.tty
->name
, DEV_TTY
) != 0)
2331 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 1, 0,
2332 doc
: /* Declare that the tty used by TERMINAL does not handle underlining.
2333 This is used to override the terminfo data, for certain terminals that
2334 do not really do underlining, but say that they do. This function has
2335 no effect if used on a non-tty terminal.
2337 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2338 frame's terminal). This function always returns nil if TERMINAL
2339 is not on a tty device. */)
2341 Lisp_Object terminal
;
2343 struct terminal
*t
= get_terminal (terminal
, 1);
2345 if (t
->type
== output_termcap
)
2346 t
->display_info
.tty
->TS_enter_underline_mode
= 0;
2352 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
2353 doc
: /* Suspend the terminal device TTY.
2355 The device is restored to its default state, and Emacs ceases all
2356 access to the tty device. Frames that use the device are not deleted,
2357 but input is not read from them and if they change, their display is
2360 TTY may be a terminal id, a frame, or nil for the terminal device of
2361 the currently selected frame.
2363 This function runs `suspend-tty-functions' after suspending the
2364 device. The functions are run with one arg, the id of the suspended
2367 `suspend-tty' does nothing if it is called on a device that is already
2370 A suspended tty may be resumed by calling `resume-tty' on it. */)
2374 struct terminal
*t
= get_tty_terminal (tty
, 1);
2378 error ("Unknown tty device");
2380 f
= t
->display_info
.tty
->input
;
2384 /* First run `suspend-tty-functions' and then clean up the tty
2385 state because `suspend-tty-functions' might need to change
2387 if (!NILP (Vrun_hooks
))
2389 Lisp_Object args
[2];
2390 args
[0] = intern ("suspend-tty-functions");
2391 XSETTERMINAL (args
[1], t
);
2392 Frun_hook_with_args (2, args
);
2395 reset_sys_modes (t
->display_info
.tty
);
2398 delete_keyboard_wait_descriptor (fileno (f
));
2403 if (f
!= t
->display_info
.tty
->output
)
2404 fclose (t
->display_info
.tty
->output
);
2407 t
->display_info
.tty
->input
= 0;
2408 t
->display_info
.tty
->output
= 0;
2410 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2411 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 0);
2415 /* Clear display hooks to prevent further output. */
2416 clear_tty_hooks (t
);
2421 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
2422 doc
: /* Resume the previously suspended terminal device TTY.
2423 The terminal is opened and reinitialized. Frames that are on the
2424 suspended terminal are revived.
2426 It is an error to resume a terminal while another terminal is active
2429 This function runs `resume-tty-functions' after resuming the terminal.
2430 The functions are run with one arg, the id of the resumed terminal
2433 `resume-tty' does nothing if it is called on a device that is not
2436 TTY may be a terminal id, a frame, or nil for the terminal device of
2437 the currently selected frame. */)
2441 struct terminal
*t
= get_tty_terminal (tty
, 1);
2445 error ("Unknown tty device");
2447 if (!t
->display_info
.tty
->input
)
2449 if (get_named_tty (t
->display_info
.tty
->name
))
2450 error ("Cannot resume display while another display is active on the same device");
2453 t
->display_info
.tty
->output
= stdout
;
2454 t
->display_info
.tty
->input
= stdin
;
2456 fd
= emacs_open (t
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
2459 error ("Can not reopen tty device %s: %s", t
->display_info
.tty
->name
, strerror (errno
));
2461 if (strcmp (t
->display_info
.tty
->name
, DEV_TTY
))
2462 dissociate_if_controlling_tty (fd
);
2464 t
->display_info
.tty
->output
= fdopen (fd
, "w+");
2465 t
->display_info
.tty
->input
= t
->display_info
.tty
->output
;
2469 add_keyboard_wait_descriptor (fd
);
2472 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2474 struct frame
*f
= XFRAME (t
->display_info
.tty
->top_frame
);
2476 int old_height
= FRAME_COLS (f
);
2477 int old_width
= FRAME_LINES (f
);
2479 /* Check if terminal/window size has changed while the frame
2481 get_tty_size (fileno (t
->display_info
.tty
->input
), &width
, &height
);
2482 if (width
!= old_width
|| height
!= old_height
)
2483 change_frame_size (f
, height
, width
, 0, 0, 0);
2484 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 1);
2487 init_sys_modes (t
->display_info
.tty
);
2489 /* Run `resume-tty-functions'. */
2490 if (!NILP (Vrun_hooks
))
2492 Lisp_Object args
[2];
2493 args
[0] = intern ("resume-tty-functions");
2494 XSETTERMINAL (args
[1], t
);
2495 Frun_hook_with_args (2, args
);
2505 /***********************************************************************
2507 ***********************************************************************/
2511 term_mouse_moveto (int x
, int y
)
2513 /* TODO: how to set mouse position?
2516 name = (const char *) ttyname (0);
2517 fd = open (name, O_WRONLY);
2518 SOME_FUNCTION (x, y, fd);
2521 last_mouse_y = y; */
2525 term_show_mouse_face (enum draw_glyphs_face draw
)
2527 struct window
*w
= XWINDOW (mouse_face_window
);
2531 struct frame
*f
= XFRAME (w
->frame
);
2532 struct tty_display_info
*tty
= FRAME_TTY (f
);
2534 if (/* If window is in the process of being destroyed, don't bother
2536 w
->current_matrix
!= NULL
2537 /* Recognize when we are called to operate on rows that don't exist
2538 anymore. This can happen when a window is split. */
2539 && mouse_face_end_row
< w
->current_matrix
->nrows
)
2541 /* write_glyphs writes at cursor position, so we need to
2542 temporarily move cursor coordinates to the beginning of
2543 the highlight region. */
2545 /* Save current cursor co-ordinates */
2546 save_y
= curY (tty
);
2547 save_x
= curX (tty
);
2549 /* Note that mouse_face_beg_row etc. are window relative. */
2550 for (i
= mouse_face_beg_row
; i
<= mouse_face_end_row
; i
++)
2552 int start_hpos
, end_hpos
, nglyphs
;
2553 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
2555 /* Don't do anything if row doesn't have valid contents. */
2556 if (!row
->enabled_p
)
2559 /* For all but the first row, the highlight starts at column 0. */
2560 if (i
== mouse_face_beg_row
)
2561 start_hpos
= mouse_face_beg_col
;
2565 if (i
== mouse_face_end_row
)
2566 end_hpos
= mouse_face_end_col
;
2569 end_hpos
= row
->used
[TEXT_AREA
];
2570 if (draw
== DRAW_NORMAL_TEXT
)
2571 row
->fill_line_p
= 1; /* Clear to end of line */
2574 if (end_hpos
<= start_hpos
)
2576 /* Record that some glyphs of this row are displayed in
2578 row
->mouse_face_p
= draw
> 0;
2580 nglyphs
= end_hpos
- start_hpos
;
2582 if (end_hpos
>= row
->used
[TEXT_AREA
])
2583 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2585 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2586 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
2587 + WINDOW_LEFT_EDGE_X (w
);
2589 cursor_to (f
, pos_y
, pos_x
);
2591 if (draw
== DRAW_MOUSE_FACE
)
2593 tty_write_glyphs_with_face (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
,
2594 nglyphs
, mouse_face_face_id
);
2596 else /* draw == DRAW_NORMAL_TEXT */
2597 write_glyphs (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2599 cursor_to (f
, save_y
, save_x
);
2604 term_clear_mouse_face ()
2606 if (!NILP (mouse_face_window
))
2607 term_show_mouse_face (DRAW_NORMAL_TEXT
);
2609 mouse_face_beg_row
= mouse_face_beg_col
= -1;
2610 mouse_face_end_row
= mouse_face_end_col
= -1;
2611 mouse_face_window
= Qnil
;
2614 /* Find the glyph matrix position of buffer position POS in window W.
2615 *HPOS and *VPOS are set to the positions found. W's current glyphs
2616 must be up to date. If POS is above window start return (0, 0).
2617 If POS is after end of W, return end of last line in W.
2618 - taken from msdos.c */
2620 fast_find_position (struct window
*w
, int pos
, int *hpos
, int *vpos
)
2622 int i
, lastcol
, line_start_position
, maybe_next_line_p
= 0;
2623 int yb
= window_text_bottom_y (w
);
2624 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0), *best_row
= row
;
2628 if (row
->used
[TEXT_AREA
])
2629 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
2631 line_start_position
= 0;
2633 if (line_start_position
> pos
)
2635 /* If the position sought is the end of the buffer,
2636 don't include the blank lines at the bottom of the window. */
2637 else if (line_start_position
== pos
2638 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
2640 maybe_next_line_p
= 1;
2643 else if (line_start_position
> 0)
2646 /* Don't overstep the last matrix row, lest we get into the
2647 never-never land... */
2648 if (row
->y
+ 1 >= yb
)
2654 /* Find the right column within BEST_ROW. */
2657 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
2659 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + i
;
2662 charpos
= glyph
->charpos
;
2669 else if (charpos
> pos
)
2671 else if (charpos
> 0)
2675 /* If we're looking for the end of the buffer,
2676 and we didn't find it in the line we scanned,
2677 use the start of the following line. */
2678 if (maybe_next_line_p
)
2685 *hpos
= lastcol
+ 1;
2690 term_mouse_highlight (struct frame
*f
, int x
, int y
)
2692 enum window_part part
;
2697 if (NILP (Vmouse_highlight
)
2698 || !f
->glyphs_initialized_p
)
2701 /* Which window is that in? */
2702 window
= window_from_coordinates (f
, x
, y
, &part
, &x
, &y
, 0);
2704 /* Not on a window -> return. */
2705 if (!WINDOWP (window
))
2708 if (!EQ (window
, mouse_face_window
))
2709 term_clear_mouse_face ();
2711 w
= XWINDOW (window
);
2713 /* Are we in a window whose display is up to date?
2714 And verify the buffer's text has not changed. */
2715 b
= XBUFFER (w
->buffer
);
2717 && EQ (w
->window_end_valid
, w
->buffer
)
2718 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
2719 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
2721 int pos
, i
, nrows
= w
->current_matrix
->nrows
;
2722 struct glyph_row
*row
;
2723 struct glyph
*glyph
;
2725 /* Find the glyph under X/Y. */
2727 if (y
>= 0 && y
< nrows
)
2729 row
= MATRIX_ROW (w
->current_matrix
, y
);
2730 /* Give up if some row before the one we are looking for is
2732 for (i
= 0; i
<= y
; i
++)
2733 if (!MATRIX_ROW (w
->current_matrix
, i
)->enabled_p
)
2735 if (i
> y
/* all rows upto and including the one at Y are enabled */
2736 && row
->displays_text_p
2737 && x
< window_box_width (w
, TEXT_AREA
))
2739 glyph
= row
->glyphs
[TEXT_AREA
];
2740 if (x
>= row
->used
[TEXT_AREA
])
2745 if (!BUFFERP (glyph
->object
))
2751 /* Clear mouse face if X/Y not over text. */
2754 term_clear_mouse_face ();
2758 if (!BUFFERP (glyph
->object
))
2760 pos
= glyph
->charpos
;
2762 /* Check for mouse-face. */
2764 extern Lisp_Object Qmouse_face
;
2765 Lisp_Object mouse_face
, overlay
, position
, *overlay_vec
;
2766 int noverlays
, obegv
, ozv
;
2767 struct buffer
*obuf
;
2769 /* If we get an out-of-range value, return now; avoid an error. */
2770 if (pos
> BUF_Z (b
))
2773 /* Make the window's buffer temporarily current for
2774 overlays_at and compute_char_face. */
2775 obuf
= current_buffer
;
2782 /* Is this char mouse-active? */
2783 XSETINT (position
, pos
);
2785 /* Put all the overlays we want in a vector in overlay_vec. */
2786 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
2787 /* Sort overlays into increasing priority order. */
2788 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
2790 /* Check mouse-face highlighting. */
2791 if (!(EQ (window
, mouse_face_window
)
2792 && y
>= mouse_face_beg_row
2793 && y
<= mouse_face_end_row
2794 && (y
> mouse_face_beg_row
2795 || x
>= mouse_face_beg_col
)
2796 && (y
< mouse_face_end_row
2797 || x
< mouse_face_end_col
2798 || mouse_face_past_end
)))
2800 /* Clear the display of the old active region, if any. */
2801 term_clear_mouse_face ();
2803 /* Find the highest priority overlay that has a mouse-face
2806 for (i
= noverlays
- 1; i
>= 0; --i
)
2808 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
2809 if (!NILP (mouse_face
))
2811 overlay
= overlay_vec
[i
];
2816 /* If no overlay applies, get a text property. */
2818 mouse_face
= Fget_text_property (position
, Qmouse_face
,
2821 /* Handle the overlay case. */
2822 if (!NILP (overlay
))
2824 /* Find the range of text around this char that
2825 should be active. */
2826 Lisp_Object before
, after
;
2830 before
= Foverlay_start (overlay
);
2831 after
= Foverlay_end (overlay
);
2832 /* Record this as the current active region. */
2833 fast_find_position (w
, XFASTINT (before
),
2834 &mouse_face_beg_col
,
2835 &mouse_face_beg_row
);
2838 = !fast_find_position (w
, XFASTINT (after
),
2839 &mouse_face_end_col
,
2840 &mouse_face_end_row
);
2841 mouse_face_window
= window
;
2844 = face_at_buffer_position (w
, pos
, 0, 0,
2845 &ignore
, pos
+ 1, 1);
2847 /* Display it as active. */
2848 term_show_mouse_face (DRAW_MOUSE_FACE
);
2850 /* Handle the text property case. */
2851 else if (!NILP (mouse_face
))
2853 /* Find the range of text around this char that
2854 should be active. */
2855 Lisp_Object before
, after
, beginning
, end
;
2858 beginning
= Fmarker_position (w
->start
);
2859 XSETINT (end
, (BUF_Z (b
) - XFASTINT (w
->window_end_pos
)));
2861 = Fprevious_single_property_change (make_number (pos
+ 1),
2863 w
->buffer
, beginning
);
2865 = Fnext_single_property_change (position
, Qmouse_face
,
2868 /* Record this as the current active region. */
2869 fast_find_position (w
, XFASTINT (before
),
2870 &mouse_face_beg_col
,
2871 &mouse_face_beg_row
);
2873 = !fast_find_position (w
, XFASTINT (after
),
2874 &mouse_face_end_col
,
2875 &mouse_face_end_row
);
2876 mouse_face_window
= window
;
2879 = face_at_buffer_position (w
, pos
, 0, 0,
2880 &ignore
, pos
+ 1, 1);
2882 /* Display it as active. */
2883 term_show_mouse_face (DRAW_MOUSE_FACE
);
2887 /* Look for a `help-echo' property. */
2890 extern Lisp_Object Qhelp_echo
;
2892 /* Check overlays first. */
2894 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
2896 overlay
= overlay_vec
[i
];
2897 help
= Foverlay_get (overlay
, Qhelp_echo
);
2902 help_echo_string
= help
;
2903 help_echo_window
= window
;
2904 help_echo_object
= overlay
;
2905 help_echo_pos
= pos
;
2907 /* Try text properties. */
2908 else if (NILP (help
)
2909 && ((STRINGP (glyph
->object
)
2910 && glyph
->charpos
>= 0
2911 && glyph
->charpos
< SCHARS (glyph
->object
))
2912 || (BUFFERP (glyph
->object
)
2913 && glyph
->charpos
>= BEGV
2914 && glyph
->charpos
< ZV
)))
2916 help
= Fget_text_property (make_number (glyph
->charpos
),
2917 Qhelp_echo
, glyph
->object
);
2920 help_echo_string
= help
;
2921 help_echo_window
= window
;
2922 help_echo_object
= glyph
->object
;
2923 help_echo_pos
= glyph
->charpos
;
2930 current_buffer
= obuf
;
2936 term_mouse_movement (FRAME_PTR frame
, Gpm_Event
*event
)
2938 /* Has the mouse moved off the glyph it was on at the last sighting? */
2939 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2941 frame
->mouse_moved
= 1;
2942 term_mouse_highlight (frame
, event
->x
, event
->y
);
2943 /* Remember which glyph we're now on. */
2944 last_mouse_x
= event
->x
;
2945 last_mouse_y
= event
->y
;
2951 /* Return the current position of the mouse.
2953 Set *f to the frame the mouse is in, or zero if the mouse is in no
2954 Emacs frame. If it is set to zero, all the other arguments are
2957 Set *bar_window to Qnil, and *x and *y to the column and
2958 row of the character cell the mouse is over.
2960 Set *time to the time the mouse was at the returned position.
2962 This clears mouse_moved until the next motion
2965 term_mouse_position (FRAME_PTR
*fp
, int insist
, Lisp_Object
*bar_window
,
2966 enum scroll_bar_part
*part
, Lisp_Object
*x
,
2967 Lisp_Object
*y
, unsigned long *time
)
2971 *fp
= SELECTED_FRAME ();
2972 (*fp
)->mouse_moved
= 0;
2977 XSETINT (*x
, last_mouse_x
);
2978 XSETINT (*y
, last_mouse_y
);
2979 gettimeofday(&now
, 0);
2980 *time
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2983 /* Prepare a mouse-event in *RESULT for placement in the input queue.
2985 If the event is a button press, then note that we have grabbed
2989 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
2995 result
->kind
= GPM_CLICK_EVENT
;
2996 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
2998 if (event
->buttons
& j
) {
2999 result
->code
= i
; /* button number */
3003 gettimeofday(&now
, 0);
3004 result
->timestamp
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
3006 if (event
->type
& GPM_UP
)
3007 result
->modifiers
= up_modifier
;
3008 else if (event
->type
& GPM_DOWN
)
3009 result
->modifiers
= down_modifier
;
3011 result
->modifiers
= 0;
3013 if (event
->type
& GPM_SINGLE
)
3014 result
->modifiers
|= click_modifier
;
3016 if (event
->type
& GPM_DOUBLE
)
3017 result
->modifiers
|= double_modifier
;
3019 if (event
->type
& GPM_TRIPLE
)
3020 result
->modifiers
|= triple_modifier
;
3022 if (event
->type
& GPM_DRAG
)
3023 result
->modifiers
|= drag_modifier
;
3025 if (!(event
->type
& (GPM_MOVE
| GPM_DRAG
))) {
3028 if (event
->modifiers
& (1 << 0))
3029 result
->modifiers
|= shift_modifier
;
3032 if (event
->modifiers
& (1 << 2))
3033 result
->modifiers
|= ctrl_modifier
;
3035 /* 1 << KG_ALT || KG_ALTGR */
3036 if (event
->modifiers
& (1 << 3)
3037 || event
->modifiers
& (1 << 1))
3038 result
->modifiers
|= meta_modifier
;
3041 XSETINT (result
->x
, event
->x
);
3042 XSETINT (result
->y
, event
->y
);
3043 XSETFRAME (result
->frame_or_window
, f
);
3049 handle_one_term_event (struct tty_display_info
*tty
, Gpm_Event
*event
, struct input_event
* hold_quit
)
3051 struct frame
*f
= XFRAME (tty
->top_frame
);
3052 struct input_event ie
;
3060 if (event
->type
& (GPM_MOVE
| GPM_DRAG
)) {
3061 previous_help_echo_string
= help_echo_string
;
3062 help_echo_string
= Qnil
;
3064 Gpm_DrawPointer (event
->x
, event
->y
, fileno (tty
->output
));
3066 if (!term_mouse_movement (f
, event
))
3067 help_echo_string
= previous_help_echo_string
;
3069 /* If the contents of the global variable help_echo_string
3070 has changed, generate a HELP_EVENT. */
3071 if (!NILP (help_echo_string
)
3072 || !NILP (previous_help_echo_string
))
3079 term_mouse_click (&ie
, event
, f
);
3083 if (ie
.kind
!= NO_EVENT
)
3085 kbd_buffer_store_event_hold (&ie
, hold_quit
);
3090 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
3095 XSETFRAME (frame
, f
);
3099 gen_help_event (help_echo_string
, frame
, help_echo_window
,
3100 help_echo_object
, help_echo_pos
);
3107 DEFUN ("gpm-mouse-start", Fgpm_mouse_start
, Sgpm_mouse_start
,
3109 doc
: /* Open a connection to Gpm.
3110 Gpm-mouse can only be activated for one tty at a time. */)
3113 struct frame
*f
= SELECTED_FRAME ();
3114 struct tty_display_info
*tty
3115 = ((f
)->output_method
== output_termcap
3116 ? (f
)->terminal
->display_info
.tty
: NULL
);
3117 Gpm_Connect connection
;
3120 error ("Gpm-mouse only works in the GNU/Linux console");
3122 return Qnil
; /* Already activated, nothing to do. */
3124 error ("Gpm-mouse can only be activated for one tty at a time");
3126 connection
.eventMask
= ~0;
3127 connection
.defaultMask
= ~GPM_HARD
;
3128 connection
.maxMod
= ~0;
3129 connection
.minMod
= 0;
3132 if (Gpm_Open (&connection
, 0) < 0)
3133 error ("Gpm-mouse failed to connect to the gpm daemon");
3137 /* `init_sys_modes' arranges for mouse movements sent through gpm_fd
3138 to generate SIGIOs. Apparently we need to call reset_sys_modes
3139 before calling init_sys_modes. */
3140 reset_sys_modes (tty
);
3141 init_sys_modes (tty
);
3142 add_gpm_wait_descriptor (gpm_fd
);
3151 delete_gpm_wait_descriptor (gpm_fd
);
3152 while (Gpm_Close()); /* close all the stack */
3156 DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop
, Sgpm_mouse_stop
,
3158 doc
: /* Close a connection to Gpm. */)
3161 struct frame
*f
= SELECTED_FRAME ();
3162 struct tty_display_info
*tty
3163 = ((f
)->output_method
== output_termcap
3164 ? (f
)->terminal
->display_info
.tty
: NULL
);
3166 if (!tty
|| gpm_tty
!= tty
)
3167 return Qnil
; /* Not activated on this terminal, nothing to do. */
3172 #endif /* HAVE_GPM */
3175 /***********************************************************************
3177 ***********************************************************************/
3179 /* Initialize the tty-dependent part of frame F. The frame must
3180 already have its device initialized. */
3183 create_tty_output (struct frame
*f
)
3185 struct tty_output
*t
;
3187 if (! FRAME_TERMCAP_P (f
))
3190 t
= xmalloc (sizeof (struct tty_output
));
3191 bzero (t
, sizeof (struct tty_output
));
3193 t
->display_info
= FRAME_TERMINAL (f
)->display_info
.tty
;
3195 f
->output_data
.tty
= t
;
3198 /* Delete frame F's face cache, and its tty-dependent part. */
3201 tty_free_frame_resources (struct frame
*f
)
3203 if (! FRAME_TERMCAP_P (f
))
3206 if (FRAME_FACE_CACHE (f
))
3207 free_frame_faces (f
);
3209 xfree (f
->output_data
.tty
);
3213 /* Reset the hooks in TERMINAL. */
3216 clear_tty_hooks (struct terminal
*terminal
)
3219 terminal
->cursor_to_hook
= 0;
3220 terminal
->raw_cursor_to_hook
= 0;
3221 terminal
->clear_to_end_hook
= 0;
3222 terminal
->clear_frame_hook
= 0;
3223 terminal
->clear_end_of_line_hook
= 0;
3224 terminal
->ins_del_lines_hook
= 0;
3225 terminal
->insert_glyphs_hook
= 0;
3226 terminal
->write_glyphs_hook
= 0;
3227 terminal
->delete_glyphs_hook
= 0;
3228 terminal
->ring_bell_hook
= 0;
3229 terminal
->reset_terminal_modes_hook
= 0;
3230 terminal
->set_terminal_modes_hook
= 0;
3231 terminal
->update_begin_hook
= 0;
3232 terminal
->update_end_hook
= 0;
3233 terminal
->set_terminal_window_hook
= 0;
3234 terminal
->mouse_position_hook
= 0;
3235 terminal
->frame_rehighlight_hook
= 0;
3236 terminal
->frame_raise_lower_hook
= 0;
3237 terminal
->fullscreen_hook
= 0;
3238 terminal
->set_vertical_scroll_bar_hook
= 0;
3239 terminal
->condemn_scroll_bars_hook
= 0;
3240 terminal
->redeem_scroll_bar_hook
= 0;
3241 terminal
->judge_scroll_bars_hook
= 0;
3242 terminal
->read_socket_hook
= 0;
3243 terminal
->frame_up_to_date_hook
= 0;
3245 /* Leave these two set, or suspended frames are not deleted
3247 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3248 terminal
->delete_terminal_hook
= &delete_tty
;
3251 /* Initialize hooks in TERMINAL with the values needed for a tty. */
3254 set_tty_hooks (struct terminal
*terminal
)
3256 terminal
->rif
= 0; /* ttys don't support window-based redisplay. */
3258 terminal
->cursor_to_hook
= &tty_cursor_to
;
3259 terminal
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
3261 terminal
->clear_to_end_hook
= &tty_clear_to_end
;
3262 terminal
->clear_frame_hook
= &tty_clear_frame
;
3263 terminal
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
3265 terminal
->ins_del_lines_hook
= &tty_ins_del_lines
;
3267 terminal
->insert_glyphs_hook
= &tty_insert_glyphs
;
3268 terminal
->write_glyphs_hook
= &tty_write_glyphs
;
3269 terminal
->delete_glyphs_hook
= &tty_delete_glyphs
;
3271 terminal
->ring_bell_hook
= &tty_ring_bell
;
3273 terminal
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
3274 terminal
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
3275 terminal
->update_begin_hook
= 0; /* Not needed. */
3276 terminal
->update_end_hook
= &tty_update_end
;
3277 terminal
->set_terminal_window_hook
= &tty_set_terminal_window
;
3279 terminal
->mouse_position_hook
= 0; /* Not needed. */
3280 terminal
->frame_rehighlight_hook
= 0; /* Not needed. */
3281 terminal
->frame_raise_lower_hook
= 0; /* Not needed. */
3283 terminal
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
3284 terminal
->condemn_scroll_bars_hook
= 0; /* Not needed. */
3285 terminal
->redeem_scroll_bar_hook
= 0; /* Not needed. */
3286 terminal
->judge_scroll_bars_hook
= 0; /* Not needed. */
3288 terminal
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
3289 terminal
->frame_up_to_date_hook
= 0; /* Not needed. */
3291 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3292 terminal
->delete_terminal_hook
= &delete_tty
;
3295 /* Drop the controlling terminal if fd is the same device. */
3297 dissociate_if_controlling_tty (int fd
)
3301 EMACS_GET_TTY_PGRP (fd
, &pgid
); /* If tcgetpgrp succeeds, fd is the ctty. */
3304 #if defined (USG) && !defined (BSD_PGRPS)
3306 no_controlling_tty
= 1;
3307 #elif defined (CYGWIN)
3309 no_controlling_tty
= 1;
3311 #ifdef TIOCNOTTY /* Try BSD ioctls. */
3312 sigblock (sigmask (SIGTTOU
));
3313 fd
= emacs_open (DEV_TTY
, O_RDWR
, 0);
3314 if (fd
!= -1 && ioctl (fd
, TIOCNOTTY
, 0) != -1)
3316 no_controlling_tty
= 1;
3320 sigunblock (sigmask (SIGTTOU
));
3322 /* Unknown system. */
3324 #endif /* ! TIOCNOTTY */
3327 #endif /* !DOS_NT */
3330 static void maybe_fatal();
3332 /* Create a termcap display on the tty device with the given name and
3335 If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
3336 Otherwise NAME should be a path to the tty device file,
3339 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
3341 If MUST_SUCCEED is true, then all errors are fatal. */
3344 init_tty (char *name
, char *terminal_type
, int must_succeed
)
3347 char **address
= &area
;
3348 int buffer_size
= 4096;
3349 register char *p
= NULL
;
3351 struct tty_display_info
*tty
= NULL
;
3352 struct terminal
*terminal
= NULL
;
3353 int ctty
= 0; /* 1 if asked to open controlling tty. */
3356 maybe_fatal (must_succeed
, 0,
3357 "Unknown terminal type",
3358 "Unknown terminal type");
3362 if (!strcmp (name
, DEV_TTY
))
3365 /* If we already have a terminal on the given device, use that. If
3366 all such terminals are suspended, create a new one instead. */
3367 /* XXX Perhaps this should be made explicit by having init_tty
3368 always create a new terminal and separating terminal and frame
3369 creation on Lisp level. */
3370 terminal
= get_named_tty (name
);
3374 terminal
= create_terminal ();
3377 maybe_fatal (1, 0, "Attempt to create another terminal %s", "",
3380 tty
= &the_only_display_info
;
3382 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
3384 bzero (tty
, sizeof (struct tty_display_info
));
3385 tty
->next
= tty_list
;
3388 terminal
->type
= output_termcap
;
3389 terminal
->display_info
.tty
= tty
;
3390 tty
->terminal
= terminal
;
3392 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
3396 set_tty_hooks (terminal
);
3402 #ifdef O_IGNORE_CTTY
3404 /* Open the terminal device. Don't recognize it as our
3405 controlling terminal, and don't make it the controlling tty
3406 if we don't have one at the moment. */
3407 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
3410 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
3411 defined on Hurd. On other systems, we need to explicitly
3412 dissociate ourselves from the controlling tty when we want to
3413 open a frame on the same terminal. */
3414 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
3415 #endif /* O_IGNORE_CTTY */
3417 tty
->name
= xstrdup (name
);
3418 terminal
->name
= xstrdup (name
);
3421 maybe_fatal (must_succeed
, terminal
,
3422 "Could not open file: %s",
3423 "Could not open file: %s",
3428 maybe_fatal (must_succeed
, terminal
,
3429 "Not a tty device: %s",
3430 "Not a tty device: %s",
3434 #ifndef O_IGNORE_CTTY
3436 dissociate_if_controlling_tty (fd
);
3439 file
= fdopen (fd
, "w+");
3444 tty
->type
= xstrdup (terminal_type
);
3447 add_keyboard_wait_descriptor (fileno (tty
->input
));
3450 #endif /* !DOS_NT */
3452 encode_terminal_src_size
= 0;
3453 encode_terminal_dst_size
= 0;
3456 terminal
->mouse_position_hook
= term_mouse_position
;
3457 mouse_face_window
= Qnil
;
3462 initialize_w32_display (terminal
);
3464 if (strcmp (terminal_type
, "internal") == 0)
3465 terminal
->type
= output_msdos_raw
;
3466 initialize_msdos_display (terminal
);
3468 tty
->output
= stdout
;
3470 /* The following two are inaccessible from w32console.c. */
3471 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3472 terminal
->delete_terminal_hook
= &delete_tty
;
3474 tty
->name
= xstrdup (name
);
3475 terminal
->name
= xstrdup (name
);
3476 tty
->type
= xstrdup (terminal_type
);
3479 add_keyboard_wait_descriptor (0);
3486 struct frame
*f
= XFRAME (selected_frame
);
3488 FrameRows (tty
) = FRAME_LINES (f
);
3489 FrameCols (tty
) = FRAME_COLS (f
);
3490 tty
->specified_window
= FRAME_LINES (f
);
3492 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
3493 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
3498 get_tty_size (fileno (tty
->input
), &width
, &height
);
3499 FrameCols (tty
) = width
;
3500 FrameRows (tty
) = height
;
3503 tty
->delete_in_insert_mode
= 1;
3506 terminal
->scroll_region_ok
= 0;
3508 /* Seems to insert lines when it's not supposed to, messing up the
3509 display. In doing a trace, it didn't seem to be called much, so I
3510 don't think we're losing anything by turning it off. */
3511 terminal
->line_ins_del_ok
= 0;
3513 terminal
->char_ins_del_ok
= 1;
3516 terminal
->char_ins_del_ok
= 0;
3517 init_baud_rate (fileno (tty
->input
));
3520 tty
->TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
3522 #else /* not DOS_NT */
3526 tty
->termcap_term_buffer
= (char *) xmalloc (buffer_size
);
3528 /* On some systems, tgetent tries to access the controlling
3530 sigblock (sigmask (SIGTTOU
));
3531 status
= tgetent (tty
->termcap_term_buffer
, terminal_type
);
3532 sigunblock (sigmask (SIGTTOU
));
3537 maybe_fatal (must_succeed
, terminal
,
3538 "Cannot open terminfo database file",
3539 "Cannot open terminfo database file");
3541 maybe_fatal (must_succeed
, terminal
,
3542 "Cannot open termcap database file",
3543 "Cannot open termcap database file");
3549 maybe_fatal (must_succeed
, terminal
,
3550 "Terminal type %s is not defined",
3551 "Terminal type %s is not defined.\n\
3552 If that is not the actual type of terminal you have,\n\
3553 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3554 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3555 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3558 maybe_fatal (must_succeed
, terminal
,
3559 "Terminal type %s is not defined",
3560 "Terminal type %s is not defined.\n\
3561 If that is not the actual type of terminal you have,\n\
3562 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3563 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3564 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3570 if (strlen (tty
->termcap_term_buffer
) >= buffer_size
)
3572 buffer_size
= strlen (tty
->termcap_term_buffer
);
3574 tty
->termcap_strings_buffer
= area
= (char *) xmalloc (buffer_size
);
3575 tty
->TS_ins_line
= tgetstr ("al", address
);
3576 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
3577 tty
->TS_bell
= tgetstr ("bl", address
);
3578 BackTab (tty
) = tgetstr ("bt", address
);
3579 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
3580 tty
->TS_clr_line
= tgetstr ("ce", address
);
3581 tty
->TS_clr_frame
= tgetstr ("cl", address
);
3582 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
3583 AbsPosition (tty
) = tgetstr ("cm", address
);
3584 CR (tty
) = tgetstr ("cr", address
);
3585 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
3586 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
3587 RowPosition (tty
) = tgetstr ("cv", address
);
3588 tty
->TS_del_char
= tgetstr ("dc", address
);
3589 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
3590 tty
->TS_del_line
= tgetstr ("dl", address
);
3591 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
3592 tty
->TS_delete_mode
= tgetstr ("dm", address
);
3593 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
3594 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
3595 Home (tty
) = tgetstr ("ho", address
);
3596 tty
->TS_ins_char
= tgetstr ("ic", address
);
3597 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
3598 tty
->TS_insert_mode
= tgetstr ("im", address
);
3599 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
3600 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
3601 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
3602 LastLine (tty
) = tgetstr ("ll", address
);
3603 Right (tty
) = tgetstr ("nd", address
);
3604 Down (tty
) = tgetstr ("do", address
);
3606 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
3607 if (tgetflag ("bs"))
3608 Left (tty
) = "\b"; /* can't possibly be longer! */
3609 else /* (Actually, "bs" is obsolete...) */
3610 Left (tty
) = tgetstr ("le", address
);
3612 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
3613 tty
->TS_pad_char
= tgetstr ("pc", address
);
3614 tty
->TS_repeat
= tgetstr ("rp", address
);
3615 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
3616 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
3617 tty
->TS_standout_mode
= tgetstr ("so", address
);
3618 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
3619 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
3620 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
3621 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
3622 Up (tty
) = tgetstr ("up", address
);
3623 tty
->TS_visible_bell
= tgetstr ("vb", address
);
3624 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
3625 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
3626 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
3627 tty
->TS_set_window
= tgetstr ("wi", address
);
3629 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
3630 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
3631 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
3632 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
3633 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
3634 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
3635 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3636 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3637 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
3639 MultiUp (tty
) = tgetstr ("UP", address
);
3640 MultiDown (tty
) = tgetstr ("DO", address
);
3641 MultiLeft (tty
) = tgetstr ("LE", address
);
3642 MultiRight (tty
) = tgetstr ("RI", address
);
3644 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
3645 color because we can't switch back to the default foreground and
3647 tty
->TS_orig_pair
= tgetstr ("op", address
);
3648 if (tty
->TS_orig_pair
)
3650 tty
->TS_set_foreground
= tgetstr ("AF", address
);
3651 tty
->TS_set_background
= tgetstr ("AB", address
);
3652 if (!tty
->TS_set_foreground
)
3655 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
3656 tty
->TS_set_background
= tgetstr ("Sb", address
);
3659 tty
->TN_max_colors
= tgetnum ("Co");
3660 tty
->TN_max_pairs
= tgetnum ("pa");
3662 tty
->TN_no_color_video
= tgetnum ("NC");
3663 if (tty
->TN_no_color_video
== -1)
3664 tty
->TN_no_color_video
= 0;
3667 tty_default_color_capabilities (tty
, 1);
3669 MagicWrap (tty
) = tgetflag ("xn");
3670 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3671 the former flag imply the latter. */
3672 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
3673 terminal
->memory_below_frame
= tgetflag ("db");
3674 tty
->TF_hazeltine
= tgetflag ("hz");
3675 terminal
->must_write_spaces
= tgetflag ("in");
3676 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
3677 tty
->TF_insmode_motion
= tgetflag ("mi");
3678 tty
->TF_standout_motion
= tgetflag ("ms");
3679 tty
->TF_underscore
= tgetflag ("ul");
3680 tty
->TF_teleray
= tgetflag ("xt");
3682 #endif /* !DOS_NT */
3683 terminal
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
3684 init_kboard (terminal
->kboard
);
3685 terminal
->kboard
->Vwindow_system
= Qnil
;
3686 terminal
->kboard
->next_kboard
= all_kboards
;
3687 all_kboards
= terminal
->kboard
;
3688 terminal
->kboard
->reference_count
++;
3689 /* Don't let the initial kboard remain current longer than necessary.
3690 That would cause problems if a file loaded on startup tries to
3691 prompt in the mini-buffer. */
3692 if (current_kboard
== initial_kboard
)
3693 current_kboard
= terminal
->kboard
;
3695 term_get_fkeys (address
, terminal
->kboard
);
3697 /* Get frame size from system, or else from termcap. */
3700 get_tty_size (fileno (tty
->input
), &width
, &height
);
3701 FrameCols (tty
) = width
;
3702 FrameRows (tty
) = height
;
3705 if (FrameCols (tty
) <= 0)
3706 FrameCols (tty
) = tgetnum ("co");
3707 if (FrameRows (tty
) <= 0)
3708 FrameRows (tty
) = tgetnum ("li");
3710 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
3711 maybe_fatal (must_succeed
, terminal
,
3712 "Screen size %dx%d is too small"
3713 "Screen size %dx%d is too small",
3714 FrameCols (tty
), FrameRows (tty
));
3716 #if 0 /* This is not used anywhere. */
3717 tty
->terminal
->min_padding_speed
= tgetnum ("pb");
3720 TabWidth (tty
) = tgetnum ("tw");
3723 tty
->TS_bell
= "\07";
3725 if (!tty
->TS_fwd_scroll
)
3726 tty
->TS_fwd_scroll
= Down (tty
);
3728 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
3730 if (TabWidth (tty
) < 0)
3733 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3734 and newer termcap doc does not seem to say there is a default.
3735 if (!tty->Wcm->cm_tab)
3736 tty->Wcm->cm_tab = "\t";
3739 /* We don't support standout modes that use `magic cookies', so
3740 turn off any that do. */
3741 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
3743 tty
->TS_standout_mode
= 0;
3744 tty
->TS_end_standout_mode
= 0;
3746 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3748 tty
->TS_enter_underline_mode
= 0;
3749 tty
->TS_exit_underline_mode
= 0;
3752 /* If there's no standout mode, try to use underlining instead. */
3753 if (tty
->TS_standout_mode
== 0)
3755 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
3756 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
3759 /* If no `se' string, try using a `me' string instead.
3760 If that fails, we can't use standout mode at all. */
3761 if (tty
->TS_end_standout_mode
== 0)
3763 char *s
= tgetstr ("me", address
);
3765 tty
->TS_end_standout_mode
= s
;
3767 tty
->TS_standout_mode
= 0;
3770 if (tty
->TF_teleray
)
3772 tty
->Wcm
->cm_tab
= 0;
3773 /* We can't support standout mode, because it uses magic cookies. */
3774 tty
->TS_standout_mode
= 0;
3775 /* But that means we cannot rely on ^M to go to column zero! */
3777 /* LF can't be trusted either -- can alter hpos */
3778 /* if move at column 0 thru a line with TS_standout_mode */
3782 /* Special handling for certain terminal types known to need it */
3784 if (!strcmp (terminal_type
, "supdup"))
3786 terminal
->memory_below_frame
= 1;
3787 tty
->Wcm
->cm_losewrap
= 1;
3789 if (!strncmp (terminal_type
, "c10", 3)
3790 || !strcmp (terminal_type
, "perq"))
3792 /* Supply a makeshift :wi string.
3793 This string is not valid in general since it works only
3794 for windows starting at the upper left corner;
3795 but that is all Emacs uses.
3797 This string works only if the frame is using
3798 the top of the video memory, because addressing is memory-relative.
3799 So first check the :ti string to see if that is true.
3801 It would be simpler if the :wi string could go in the termcap
3802 entry, but it can't because it is not fully valid.
3803 If it were in the termcap entry, it would confuse other programs. */
3804 if (!tty
->TS_set_window
)
3806 p
= tty
->TS_termcap_modes
;
3807 while (*p
&& strcmp (p
, "\033v "))
3810 tty
->TS_set_window
= "\033v%C %C %C %C ";
3812 /* Termcap entry often fails to have :in: flag */
3813 terminal
->must_write_spaces
= 1;
3814 /* :ti string typically fails to have \E^G! in it */
3815 /* This limits scope of insert-char to one line. */
3816 strcpy (area
, tty
->TS_termcap_modes
);
3817 strcat (area
, "\033\007!");
3818 tty
->TS_termcap_modes
= area
;
3819 area
+= strlen (area
) + 1;
3820 p
= AbsPosition (tty
);
3821 /* Change all %+ parameters to %C, to handle
3822 values above 96 correctly for the C100. */
3825 if (p
[0] == '%' && p
[1] == '+')
3831 tty
->specified_window
= FrameRows (tty
);
3833 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
3835 maybe_fatal (must_succeed
, terminal
,
3836 "Terminal type \"%s\" is not powerful enough to run Emacs",
3838 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3839 It lacks the ability to position the cursor.\n\
3840 If that is not the actual type of terminal you have,\n\
3841 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3842 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3843 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3844 # else /* TERMCAP */
3845 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3846 It lacks the ability to position the cursor.\n\
3847 If that is not the actual type of terminal you have,\n\
3848 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3849 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3850 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3851 # endif /* TERMINFO */
3855 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
3856 maybe_fatal (must_succeed
, terminal
,
3857 "Could not determine the frame size",
3858 "Could not determine the frame size");
3860 tty
->delete_in_insert_mode
3861 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
3862 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
3864 tty
->se_is_so
= (tty
->TS_standout_mode
3865 && tty
->TS_end_standout_mode
3866 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
3868 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
3870 terminal
->scroll_region_ok
3872 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
3874 terminal
->line_ins_del_ok
3875 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
3876 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
3877 || (terminal
->scroll_region_ok
3878 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
3880 terminal
->char_ins_del_ok
3881 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
3882 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
3883 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
3885 terminal
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
3887 init_baud_rate (fileno (tty
->input
));
3889 #endif /* not DOS_NT */
3891 /* Init system terminal modes (RAW or CBREAK, etc.). */
3892 init_sys_modes (tty
);
3897 /* Auxiliary error-handling function for init_tty.
3898 Delete TERMINAL, then call error or fatal with str1 or str2,
3899 respectively, according to MUST_SUCCEED. */
3902 maybe_fatal (must_succeed
, terminal
, str1
, str2
, arg1
, arg2
)
3904 struct terminal
*terminal
;
3905 char *str1
, *str2
, *arg1
, *arg2
;
3908 delete_tty (terminal
);
3911 fatal (str2
, arg1
, arg2
);
3913 error (str1
, arg1
, arg2
);
3919 fatal (const char *str
, ...)
3923 fprintf (stderr
, "emacs: ");
3924 vfprintf (stderr
, str
, ap
);
3932 /* Delete the given tty terminal, closing all frames on it. */
3935 delete_tty (struct terminal
*terminal
)
3937 struct tty_display_info
*tty
;
3938 Lisp_Object tail
, frame
;
3941 /* Protect against recursive calls. delete_frame in
3942 delete_terminal calls us back when it deletes our last frame. */
3943 if (!terminal
->name
)
3946 if (terminal
->type
!= output_termcap
)
3949 tty
= terminal
->display_info
.tty
;
3952 FOR_EACH_FRAME (tail
, frame
)
3954 struct frame
*f
= XFRAME (frame
);
3955 if (FRAME_LIVE_P (f
) && (!FRAME_TERMCAP_P (f
) || FRAME_TTY (f
) != tty
))
3962 error ("Attempt to delete the sole terminal device with live frames");
3964 if (tty
== tty_list
)
3965 tty_list
= tty
->next
;
3968 struct tty_display_info
*p
;
3969 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
3973 /* This should not happen. */
3976 p
->next
= tty
->next
;
3980 /* reset_sys_modes needs a valid device, so this call needs to be
3981 before delete_terminal. */
3982 reset_sys_modes (tty
);
3984 delete_terminal (terminal
);
3992 delete_keyboard_wait_descriptor (fileno (tty
->input
));
3994 if (tty
->input
!= stdin
)
3995 fclose (tty
->input
);
3997 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
3998 fclose (tty
->output
);
3999 if (tty
->termscript
)
4000 fclose (tty
->termscript
);
4002 xfree (tty
->old_tty
);
4004 if (tty
->termcap_strings_buffer
)
4005 xfree (tty
->termcap_strings_buffer
);
4006 if (tty
->termcap_term_buffer
)
4007 xfree (tty
->termcap_term_buffer
);
4009 bzero (tty
, sizeof (struct tty_display_info
));
4015 /* Mark the pointers in the tty_display_info objects.
4016 Called by the Fgarbage_collector. */
4021 struct tty_display_info
*tty
;
4023 for (tty
= tty_list
; tty
; tty
= tty
->next
)
4024 mark_object (tty
->top_frame
);
4032 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
4033 doc
: /* Non-nil means the system uses terminfo rather than termcap.
4034 This variable can be used by terminal emulator packages. */);
4036 system_uses_terminfo
= 1;
4038 system_uses_terminfo
= 0;
4041 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions
,
4042 doc
: /* Functions to be run after suspending a tty.
4043 The functions are run with one argument, the terminal id to be suspended.
4044 See `suspend-tty'. */);
4045 Vsuspend_tty_functions
= Qnil
;
4048 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions
,
4049 doc
: /* Functions to be run after resuming a tty.
4050 The functions are run with one argument, the terminal id that was revived.
4051 See `resume-tty'. */);
4052 Vresume_tty_functions
= Qnil
;
4054 DEFVAR_BOOL ("visible-cursor", &visible_cursor
,
4055 doc
: /* Non-nil means to make the cursor very visible.
4056 This only has an effect when running in a text terminal.
4057 What means \"very visible\" is up to your terminal. It may make the cursor
4058 bigger, or it may make it blink, or it may do nothing at all. */);
4061 defsubr (&Stty_display_color_p
);
4062 defsubr (&Stty_display_color_cells
);
4063 defsubr (&Stty_no_underline
);
4064 defsubr (&Stty_type
);
4065 defsubr (&Scontrolling_tty_p
);
4066 defsubr (&Ssuspend_tty
);
4067 defsubr (&Sresume_tty
);
4069 defsubr (&Sgpm_mouse_start
);
4070 defsubr (&Sgpm_mouse_stop
);
4072 staticpro (&mouse_face_window
);
4073 #endif /* HAVE_GPM */
4076 default_orig_pair
= NULL
;
4077 default_set_foreground
= NULL
;
4078 default_set_background
= NULL
;
4079 #endif /* !DOS_NT */
4081 encode_terminal_src
= NULL
;
4082 encode_terminal_dst
= NULL
;
4087 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
4088 (do not change this comment) */