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 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
36 #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"
61 /* For now, don't try to include termcap.h. On some systems,
62 configure finds a non-standard termcap.h that the main build
65 #if defined HAVE_TERMCAP_H && 0
68 extern void tputs
P_ ((const char *, int, int (*)(int)));
69 extern int tgetent
P_ ((char *, const char *));
70 extern int tgetflag
P_ ((char *id
));
71 extern int tgetnum
P_ ((char *id
));
90 /* The name of the default console device. */
92 #define DEV_TTY "CONOUT$"
94 #define DEV_TTY "/dev/tty"
97 static void tty_set_scroll_region
P_ ((struct frame
*f
, int start
, int stop
));
98 static void turn_on_face
P_ ((struct frame
*, int face_id
));
99 static void turn_off_face
P_ ((struct frame
*, int face_id
));
100 static void tty_show_cursor
P_ ((struct tty_display_info
*));
101 static void tty_hide_cursor
P_ ((struct tty_display_info
*));
102 static void tty_background_highlight
P_ ((struct tty_display_info
*tty
));
103 static void clear_tty_hooks
P_ ((struct terminal
*terminal
));
104 static void set_tty_hooks
P_ ((struct terminal
*terminal
));
105 static void dissociate_if_controlling_tty
P_ ((int fd
));
106 static void delete_tty
P_ ((struct terminal
*));
108 #define OUTPUT(tty, a) \
109 emacs_tputs ((tty), a, \
110 (int) (FRAME_LINES (XFRAME (selected_frame)) \
114 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
115 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
117 #define OUTPUT_IF(tty, a) \
120 emacs_tputs ((tty), a, \
121 (int) (FRAME_LINES (XFRAME (selected_frame)) \
126 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
128 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */
130 static int visible_cursor
;
132 /* Display space properties */
134 extern Lisp_Object Qspace
, QCalign_to
, QCwidth
;
136 /* Functions to call after suspending a tty. */
137 Lisp_Object Vsuspend_tty_functions
;
139 /* Functions to call after resuming a tty. */
140 Lisp_Object Vresume_tty_functions
;
142 /* Chain of all tty device parameters. */
143 struct tty_display_info
*tty_list
;
145 /* Nonzero means no need to redraw the entire frame on resuming a
146 suspended Emacs. This is useful on terminals with multiple
147 pages, where one page is used for Emacs and another for all
149 int no_redraw_on_reenter
;
151 /* Meaning of bits in no_color_video. Each bit set means that the
152 corresponding attribute cannot be combined with colors. */
156 NC_STANDOUT
= 1 << 0,
157 NC_UNDERLINE
= 1 << 1,
164 NC_ALT_CHARSET
= 1 << 8
169 /* The largest frame width in any call to calculate_costs. */
173 /* The largest frame height in any call to calculate_costs. */
177 /* Non-zero if we have dropped our controlling tty and therefore
178 should not open a frame on stdout. */
179 static int no_controlling_tty
;
181 /* Provided for lisp packages. */
183 static int system_uses_terminfo
;
187 extern char *tgetstr ();
191 #include <sys/fcntl.h>
193 static void term_clear_mouse_face ();
194 static void term_mouse_highlight (struct frame
*f
, int x
, int y
);
196 /* The device for which we have enabled gpm support (or NULL). */
197 struct tty_display_info
*gpm_tty
= NULL
;
199 /* These variables describe the range of text currently shown in its
200 mouse-face, together with the window they apply to. As long as
201 the mouse stays within this range, we need not redraw anything on
202 its account. Rows and columns are glyph matrix positions in
203 MOUSE_FACE_WINDOW. */
204 static int mouse_face_beg_row
, mouse_face_beg_col
;
205 static int mouse_face_end_row
, mouse_face_end_col
;
206 static int mouse_face_past_end
;
207 static Lisp_Object mouse_face_window
;
208 static int mouse_face_face_id
;
210 static int pos_x
, pos_y
;
211 static int last_mouse_x
, last_mouse_y
;
212 #endif /* HAVE_GPM */
214 /* Ring the bell on a tty. */
217 tty_ring_bell (struct frame
*f
)
219 struct tty_display_info
*tty
= FRAME_TTY (f
);
223 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
224 ? tty
->TS_visible_bell
226 fflush (tty
->output
);
230 /* Set up termcap modes for Emacs. */
233 tty_set_terminal_modes (struct terminal
*terminal
)
235 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
239 if (tty
->TS_termcap_modes
)
240 OUTPUT (tty
, tty
->TS_termcap_modes
);
243 /* Output enough newlines to scroll all the old screen contents
244 off the screen, so it won't be overwritten and lost. */
247 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
251 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
252 OUTPUT_IF (tty
, visible_cursor
? tty
->TS_cursor_visible
: tty
->TS_cursor_normal
);
253 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
255 fflush (tty
->output
);
259 /* Reset termcap modes before exiting Emacs. */
262 tty_reset_terminal_modes (struct terminal
*terminal
)
264 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
268 tty_turn_off_highlight (tty
);
269 tty_turn_off_insert (tty
);
270 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
271 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
272 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
273 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
274 /* Output raw CR so kernel can track the cursor hpos. */
277 fflush (tty
->output
);
281 /* Flag the end of a display update on a termcap terminal. */
284 tty_update_end (struct frame
*f
)
286 struct tty_display_info
*tty
= FRAME_TTY (f
);
288 if (!XWINDOW (selected_window
)->cursor_off_p
)
289 tty_show_cursor (tty
);
290 tty_turn_off_insert (tty
);
291 tty_background_highlight (tty
);
294 /* The implementation of set_terminal_window for termcap frames. */
297 tty_set_terminal_window (struct frame
*f
, int size
)
299 struct tty_display_info
*tty
= FRAME_TTY (f
);
301 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
302 if (FRAME_SCROLL_REGION_OK (f
))
303 tty_set_scroll_region (f
, 0, tty
->specified_window
);
307 tty_set_scroll_region (struct frame
*f
, int start
, int stop
)
310 struct tty_display_info
*tty
= FRAME_TTY (f
);
312 if (tty
->TS_set_scroll_region
)
313 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
314 else if (tty
->TS_set_scroll_region_1
)
315 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
316 FRAME_LINES (f
), start
,
317 FRAME_LINES (f
) - stop
,
320 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
329 tty_turn_on_insert (struct tty_display_info
*tty
)
331 if (!tty
->insert_mode
)
332 OUTPUT (tty
, tty
->TS_insert_mode
);
333 tty
->insert_mode
= 1;
337 tty_turn_off_insert (struct tty_display_info
*tty
)
339 if (tty
->insert_mode
)
340 OUTPUT (tty
, tty
->TS_end_insert_mode
);
341 tty
->insert_mode
= 0;
344 /* Handle highlighting. */
347 tty_turn_off_highlight (struct tty_display_info
*tty
)
349 if (tty
->standout_mode
)
350 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
351 tty
->standout_mode
= 0;
355 tty_turn_on_highlight (struct tty_display_info
*tty
)
357 if (!tty
->standout_mode
)
358 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
359 tty
->standout_mode
= 1;
363 tty_toggle_highlight (struct tty_display_info
*tty
)
365 if (tty
->standout_mode
)
366 tty_turn_off_highlight (tty
);
368 tty_turn_on_highlight (tty
);
372 /* Make cursor invisible. */
375 tty_hide_cursor (struct tty_display_info
*tty
)
377 if (tty
->cursor_hidden
== 0)
379 tty
->cursor_hidden
= 1;
380 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
385 /* Ensure that cursor is visible. */
388 tty_show_cursor (struct tty_display_info
*tty
)
390 if (tty
->cursor_hidden
)
392 tty
->cursor_hidden
= 0;
393 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
395 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
400 /* Set standout mode to the state it should be in for
401 empty space inside windows. What this is,
402 depends on the user option inverse-video. */
405 tty_background_highlight (struct tty_display_info
*tty
)
408 tty_turn_on_highlight (tty
);
410 tty_turn_off_highlight (tty
);
413 /* Set standout mode to the mode specified for the text to be output. */
416 tty_highlight_if_desired (struct tty_display_info
*tty
)
419 tty_turn_on_highlight (tty
);
421 tty_turn_off_highlight (tty
);
425 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
426 frame-relative coordinates. */
429 tty_cursor_to (struct frame
*f
, int vpos
, int hpos
)
431 struct tty_display_info
*tty
= FRAME_TTY (f
);
433 /* Detect the case where we are called from reset_sys_modes
434 and the costs have never been calculated. Do nothing. */
435 if (! tty
->costs_set
)
438 if (curY (tty
) == vpos
439 && curX (tty
) == hpos
)
441 if (!tty
->TF_standout_motion
)
442 tty_background_highlight (tty
);
443 if (!tty
->TF_insmode_motion
)
444 tty_turn_off_insert (tty
);
445 cmgoto (tty
, vpos
, hpos
);
448 /* Similar but don't take any account of the wasted characters. */
451 tty_raw_cursor_to (struct frame
*f
, int row
, int col
)
453 struct tty_display_info
*tty
= FRAME_TTY (f
);
455 if (curY (tty
) == row
456 && curX (tty
) == col
)
458 if (!tty
->TF_standout_motion
)
459 tty_background_highlight (tty
);
460 if (!tty
->TF_insmode_motion
)
461 tty_turn_off_insert (tty
);
462 cmgoto (tty
, row
, col
);
465 /* Erase operations */
467 /* Clear from cursor to end of frame on a termcap device. */
470 tty_clear_to_end (struct frame
*f
)
473 struct tty_display_info
*tty
= FRAME_TTY (f
);
475 if (tty
->TS_clr_to_bottom
)
477 tty_background_highlight (tty
);
478 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
482 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
485 clear_end_of_line (f
, FRAME_COLS (f
));
490 /* Clear an entire termcap frame. */
493 tty_clear_frame (struct frame
*f
)
495 struct tty_display_info
*tty
= FRAME_TTY (f
);
497 if (tty
->TS_clr_frame
)
499 tty_background_highlight (tty
);
500 OUTPUT (tty
, tty
->TS_clr_frame
);
510 /* An implementation of clear_end_of_line for termcap frames.
512 Note that the cursor may be moved, on terminals lacking a `ce' string. */
515 tty_clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
518 struct tty_display_info
*tty
= FRAME_TTY (f
);
520 /* Detect the case where we are called from reset_sys_modes
521 and the costs have never been calculated. Do nothing. */
522 if (! tty
->costs_set
)
525 if (curX (tty
) >= first_unused_hpos
)
527 tty_background_highlight (tty
);
528 if (tty
->TS_clr_line
)
530 OUTPUT1 (tty
, tty
->TS_clr_line
);
533 { /* have to do it the hard way */
534 tty_turn_off_insert (tty
);
536 /* Do not write in last row last col with Auto-wrap on. */
538 && curY (tty
) == FrameRows (tty
) - 1
539 && first_unused_hpos
== FrameCols (tty
))
542 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
545 fputc (' ', tty
->termscript
);
546 fputc (' ', tty
->output
);
548 cmplus (tty
, first_unused_hpos
- curX (tty
));
552 /* Buffers to store the source and result of code conversion for terminal. */
553 static unsigned char *encode_terminal_src
;
554 static unsigned char *encode_terminal_dst
;
555 /* Allocated sizes of the above buffers. */
556 static int encode_terminal_src_size
;
557 static int encode_terminal_dst_size
;
559 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
560 Set CODING->produced to the byte-length of the resulting byte
561 sequence, and return a pointer to that byte sequence. */
564 encode_terminal_code (src
, src_len
, coding
)
567 struct coding_system
*coding
;
569 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_size
== 0)
585 encode_terminal_src
= xmalloc (required
);
587 encode_terminal_src
= xrealloc (encode_terminal_src
, 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
= composition_table
[src
->u
.cmp_id
];
602 nbytes
= buf
- encode_terminal_src
;
603 required
= MAX_MULTIBYTE_LENGTH
* cmp
->glyph_len
;
605 if (encode_terminal_src_size
< nbytes
+ required
)
607 encode_terminal_src_size
= nbytes
+ required
;
608 encode_terminal_src
= xrealloc (encode_terminal_src
,
609 encode_terminal_src_size
);
610 buf
= encode_terminal_src
+ nbytes
;
613 for (i
= 0; i
< cmp
->glyph_len
; i
++)
615 int c
= COMPOSITION_GLYPH (cmp
, i
);
617 if (! char_charset (c
, charset_list
, NULL
))
619 buf
+= CHAR_STRING (c
, buf
);
624 /* The first character of the composition is not encodable. */
629 /* We must skip glyphs to be padded for a wide character. */
630 else if (! CHAR_GLYPH_PADDING_P (*src
))
636 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
638 if (g
< 0 || g
>= tlen
)
640 /* This glyph doesn't has an entry in Vglyph_table. */
645 /* This glyph has an entry in Vglyph_table,
646 so process any alias before testing for simpleness. */
647 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
649 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
650 /* We set the multi-byte form of a character in G
651 (that should be an ASCII character) at WORKBUF. */
652 c
= FAST_GLYPH_CHAR (g
);
654 /* We have a string in Vglyph_table. */
660 nbytes
= buf
- encode_terminal_src
;
661 if (encode_terminal_src_size
< nbytes
+ MAX_MULTIBYTE_LENGTH
)
663 encode_terminal_src_size
= nbytes
+ MAX_MULTIBYTE_LENGTH
;
664 encode_terminal_src
= xrealloc (encode_terminal_src
,
665 encode_terminal_src_size
);
666 buf
= encode_terminal_src
+ nbytes
;
668 if (char_charset (c
, charset_list
, NULL
))
670 /* Store the multibyte form of C at BUF. */
671 buf
+= CHAR_STRING (c
, buf
);
676 /* C is not encodable. */
679 while (src
+ 1 < src_end
&& CHAR_GLYPH_PADDING_P (src
[1]))
689 unsigned char *p
= SDATA (string
), *pend
= p
+ SBYTES (string
);
691 if (! STRING_MULTIBYTE (string
))
692 string
= string_to_multibyte (string
);
693 nbytes
= buf
- encode_terminal_src
;
694 if (encode_terminal_src_size
< nbytes
+ SBYTES (string
))
696 encode_terminal_src_size
= nbytes
+ SBYTES (string
);
697 encode_terminal_src
= xrealloc (encode_terminal_src
,
698 encode_terminal_src_size
);
699 buf
= encode_terminal_src
+ nbytes
;
701 bcopy (SDATA (string
), buf
, SBYTES (string
));
702 buf
+= SBYTES (string
);
703 nchars
+= SCHARS (string
);
711 coding
->produced
= 0;
715 nbytes
= buf
- encode_terminal_src
;
716 coding
->source
= encode_terminal_src
;
717 if (encode_terminal_dst_size
== 0)
719 encode_terminal_dst_size
= encode_terminal_src_size
;
720 encode_terminal_dst
= xmalloc (encode_terminal_dst_size
);
722 coding
->destination
= encode_terminal_dst
;
723 coding
->dst_bytes
= encode_terminal_dst_size
;
724 encode_coding_object (coding
, Qnil
, 0, 0, nchars
, nbytes
, Qnil
);
725 /* coding->destination may have been reallocated. */
726 encode_terminal_dst
= coding
->destination
;
727 encode_terminal_dst_size
= coding
->dst_bytes
;
729 return (encode_terminal_dst
);
734 /* An implementation of write_glyphs for termcap frames. */
737 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
739 unsigned char *conversion_buffer
;
740 struct coding_system
*coding
;
742 struct tty_display_info
*tty
= FRAME_TTY (f
);
744 tty_turn_off_insert (tty
);
745 tty_hide_cursor (tty
);
747 /* Don't dare write in last column of bottom line, if Auto-Wrap,
748 since that would scroll the whole frame on some terminals. */
751 && curY (tty
) + 1 == FRAME_LINES (f
)
752 && (curX (tty
) + len
) == FRAME_COLS (f
))
759 /* If terminal_coding does any conversion, use it, otherwise use
760 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
761 because it always return 1 if the member src_multibyte is 1. */
762 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
763 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
764 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
766 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
770 /* Identify a run of glyphs with the same face. */
771 int face_id
= string
->face_id
;
774 for (n
= 1; n
< len
; ++n
)
775 if (string
[n
].face_id
!= face_id
)
778 /* Turn appearance modes of the face of the run on. */
779 tty_highlight_if_desired (tty
);
780 turn_on_face (f
, face_id
);
783 /* This is the last run. */
784 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
785 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
786 if (coding
->produced
> 0)
789 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
790 if (ferror (tty
->output
))
791 clearerr (tty
->output
);
793 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
799 /* Turn appearance modes off. */
800 turn_off_face (f
, face_id
);
801 tty_turn_off_highlight (tty
);
807 #ifdef HAVE_GPM /* Only used by GPM code. */
810 tty_write_glyphs_with_face (f
, string
, len
, face_id
)
811 register struct frame
*f
;
812 register struct glyph
*string
;
813 register int len
, face_id
;
815 unsigned char *conversion_buffer
;
816 struct coding_system
*coding
;
818 struct tty_display_info
*tty
= FRAME_TTY (f
);
820 tty_turn_off_insert (tty
);
821 tty_hide_cursor (tty
);
823 /* Don't dare write in last column of bottom line, if Auto-Wrap,
824 since that would scroll the whole frame on some terminals. */
827 && curY (tty
) + 1 == FRAME_LINES (f
)
828 && (curX (tty
) + len
) == FRAME_COLS (f
))
835 /* If terminal_coding does any conversion, use it, otherwise use
836 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
837 because it always return 1 if the member src_multibyte is 1. */
838 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
839 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
840 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
842 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
844 /* Turn appearance modes of the face. */
845 tty_highlight_if_desired (tty
);
846 turn_on_face (f
, face_id
);
848 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
849 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
850 if (coding
->produced
> 0)
853 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
854 if (ferror (tty
->output
))
855 clearerr (tty
->output
);
857 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
861 /* Turn appearance modes off. */
862 turn_off_face (f
, face_id
);
863 tty_turn_off_highlight (tty
);
869 /* An implementation of insert_glyphs for termcap frames. */
872 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
875 struct glyph
*glyph
= NULL
;
876 unsigned char *conversion_buffer
;
877 unsigned char space
[1];
878 struct coding_system
*coding
;
880 struct tty_display_info
*tty
= FRAME_TTY (f
);
882 if (tty
->TS_ins_multi_chars
)
884 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
888 write_glyphs (f
, start
, len
);
892 tty_turn_on_insert (tty
);
896 space
[0] = SPACEGLYPH
;
898 /* If terminal_coding does any conversion, use it, otherwise use
899 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
900 because it always return 1 if the member src_multibyte is 1. */
901 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
902 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
903 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
905 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
909 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
912 conversion_buffer
= space
;
913 coding
->produced
= 1;
917 tty_highlight_if_desired (tty
);
918 turn_on_face (f
, start
->face_id
);
921 /* We must open sufficient space for a character which
922 occupies more than one column. */
923 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
925 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
930 /* This is the last glyph. */
931 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
933 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
936 if (coding
->produced
> 0)
939 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
940 if (ferror (tty
->output
))
941 clearerr (tty
->output
);
943 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
947 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
950 turn_off_face (f
, glyph
->face_id
);
951 tty_turn_off_highlight (tty
);
958 /* An implementation of delete_glyphs for termcap frames. */
961 tty_delete_glyphs (struct frame
*f
, int n
)
966 struct tty_display_info
*tty
= FRAME_TTY (f
);
968 if (tty
->delete_in_insert_mode
)
970 tty_turn_on_insert (tty
);
974 tty_turn_off_insert (tty
);
975 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
978 if (tty
->TS_del_multi_chars
)
980 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
985 for (i
= 0; i
< n
; i
++)
986 OUTPUT1 (tty
, tty
->TS_del_char
);
987 if (!tty
->delete_in_insert_mode
)
988 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
991 /* An implementation of ins_del_lines for termcap frames. */
994 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
996 struct tty_display_info
*tty
= FRAME_TTY (f
);
997 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
998 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
999 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
1001 register int i
= n
> 0 ? n
: -n
;
1004 /* If the lines below the insertion are being pushed
1005 into the end of the window, this is the same as clearing;
1006 and we know the lines are already clear, since the matching
1007 deletion has already been done. So can ignore this. */
1008 /* If the lines below the deletion are blank lines coming
1009 out of the end of the window, don't bother,
1010 as there will be a matching inslines later that will flush them. */
1011 if (FRAME_SCROLL_REGION_OK (f
)
1012 && vpos
+ i
>= tty
->specified_window
)
1014 if (!FRAME_MEMORY_BELOW_FRAME (f
)
1015 && vpos
+ i
>= FRAME_LINES (f
))
1020 raw_cursor_to (f
, vpos
, 0);
1021 tty_background_highlight (tty
);
1022 buf
= tparam (multi
, 0, 0, i
);
1028 raw_cursor_to (f
, vpos
, 0);
1029 tty_background_highlight (tty
);
1031 OUTPUT (tty
, single
);
1032 if (tty
->TF_teleray
)
1037 tty_set_scroll_region (f
, vpos
, tty
->specified_window
);
1039 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
1041 raw_cursor_to (f
, vpos
, 0);
1042 tty_background_highlight (tty
);
1044 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1045 tty_set_scroll_region (f
, 0, tty
->specified_window
);
1048 if (!FRAME_SCROLL_REGION_OK (f
)
1049 && FRAME_MEMORY_BELOW_FRAME (f
)
1052 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
1057 /* Compute cost of sending "str", in characters,
1058 not counting any line-dependent padding. */
1061 string_cost (char *str
)
1065 tputs (str
, 0, evalcost
);
1069 /* Compute cost of sending "str", in characters,
1070 counting any line-dependent padding at one line. */
1073 string_cost_one_line (char *str
)
1077 tputs (str
, 1, evalcost
);
1081 /* Compute per line amount of line-dependent padding,
1082 in tenths of characters. */
1085 per_line_cost (char *str
)
1089 tputs (str
, 0, evalcost
);
1092 tputs (str
, 10, evalcost
);
1097 /* char_ins_del_cost[n] is cost of inserting N characters.
1098 char_ins_del_cost[-n] is cost of deleting N characters.
1099 The length of this vector is based on max_frame_cols. */
1101 int *char_ins_del_vector
;
1103 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1108 calculate_ins_del_char_costs (struct frame
*f
)
1110 struct tty_display_info
*tty
= FRAME_TTY (f
);
1111 int ins_startup_cost
, del_startup_cost
;
1112 int ins_cost_per_char
, del_cost_per_char
;
1116 if (tty
->TS_ins_multi_chars
)
1118 ins_cost_per_char
= 0;
1119 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1121 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1122 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1124 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1125 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1126 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1127 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1131 ins_startup_cost
= 9999;
1132 ins_cost_per_char
= 0;
1135 if (tty
->TS_del_multi_chars
)
1137 del_cost_per_char
= 0;
1138 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1140 else if (tty
->TS_del_char
)
1142 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1143 + string_cost (tty
->TS_end_delete_mode
));
1144 if (tty
->delete_in_insert_mode
)
1145 del_startup_cost
/= 2;
1146 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1150 del_startup_cost
= 9999;
1151 del_cost_per_char
= 0;
1154 /* Delete costs are at negative offsets */
1155 p
= &char_ins_del_cost (f
)[0];
1156 for (i
= FRAME_COLS (f
); --i
>= 0;)
1157 *--p
= (del_startup_cost
+= del_cost_per_char
);
1159 /* Doing nothing is free */
1160 p
= &char_ins_del_cost (f
)[0];
1163 /* Insert costs are at positive offsets */
1164 for (i
= FRAME_COLS (f
); --i
>= 0;)
1165 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1169 calculate_costs (struct frame
*frame
)
1171 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1173 if (FRAME_TERMCAP_P (frame
))
1175 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1176 register char *f
= (tty
->TS_set_scroll_region
1177 ? tty
->TS_set_scroll_region
1178 : tty
->TS_set_scroll_region_1
);
1180 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1184 /* These variables are only used for terminal stuff. They are
1185 allocated once for the terminal frame of X-windows emacs, but not
1188 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1189 X turns off char_ins_del_ok. */
1191 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1192 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1194 if (char_ins_del_vector
!= 0)
1196 = (int *) xrealloc (char_ins_del_vector
,
1198 + 2 * max_frame_cols
* sizeof (int)));
1201 = (int *) xmalloc (sizeof (int)
1202 + 2 * max_frame_cols
* sizeof (int));
1204 bzero (char_ins_del_vector
, (sizeof (int)
1205 + 2 * max_frame_cols
* sizeof (int)));
1208 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1209 do_line_insertion_deletion_costs (frame
,
1210 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1211 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1214 do_line_insertion_deletion_costs (frame
,
1215 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1216 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1219 calculate_ins_del_char_costs (frame
);
1221 /* Don't use TS_repeat if its padding is worse than sending the chars */
1222 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1223 tty
->RPov
= string_cost (tty
->TS_repeat
);
1225 tty
->RPov
= FRAME_COLS (frame
) * 2;
1227 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1235 /* Termcap capability names that correspond directly to X keysyms.
1236 Some of these (marked "terminfo") aren't supplied by old-style
1237 (Berkeley) termcap entries. They're listed in X keysym order;
1238 except we put the keypad keys first, so that if they clash with
1239 other keys (as on the IBM PC keyboard) they get overridden.
1242 static struct fkey_table keys
[] =
1244 {"kh", "home"}, /* termcap */
1245 {"kl", "left"}, /* termcap */
1246 {"ku", "up"}, /* termcap */
1247 {"kr", "right"}, /* termcap */
1248 {"kd", "down"}, /* termcap */
1249 {"%8", "prior"}, /* terminfo */
1250 {"%5", "next"}, /* terminfo */
1251 {"@7", "end"}, /* terminfo */
1252 {"@1", "begin"}, /* terminfo */
1253 {"*6", "select"}, /* terminfo */
1254 {"%9", "print"}, /* terminfo */
1255 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1257 * "insert" --- see below
1259 {"&8", "undo"}, /* terminfo */
1260 {"%0", "redo"}, /* terminfo */
1261 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1262 {"@0", "find"}, /* terminfo */
1263 {"@2", "cancel"}, /* terminfo */
1264 {"%1", "help"}, /* terminfo */
1266 * "break" goes here, but can't be reliably intercepted with termcap
1268 {"&4", "reset"}, /* terminfo --- actually `restart' */
1270 * "system" and "user" --- no termcaps
1272 {"kE", "clearline"}, /* terminfo */
1273 {"kA", "insertline"}, /* terminfo */
1274 {"kL", "deleteline"}, /* terminfo */
1275 {"kI", "insertchar"}, /* terminfo */
1276 {"kD", "deletechar"}, /* terminfo */
1277 {"kB", "backtab"}, /* terminfo */
1279 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1281 {"@8", "kp-enter"}, /* terminfo */
1283 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1284 * "kp-multiply", "kp-add", "kp-separator",
1285 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1286 * --- no termcaps for any of these.
1288 {"K4", "kp-1"}, /* terminfo */
1290 * "kp-2" --- no termcap
1292 {"K5", "kp-3"}, /* terminfo */
1294 * "kp-4" --- no termcap
1296 {"K2", "kp-5"}, /* terminfo */
1298 * "kp-6" --- no termcap
1300 {"K1", "kp-7"}, /* terminfo */
1302 * "kp-8" --- no termcap
1304 {"K3", "kp-9"}, /* terminfo */
1306 * "kp-equal" --- no termcap
1318 {"&0", "S-cancel"}, /*shifted cancel key*/
1319 {"&9", "S-begin"}, /*shifted begin key*/
1320 {"*0", "S-find"}, /*shifted find key*/
1321 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1322 {"*4", "S-delete"}, /*shifted delete-character key*/
1323 {"*7", "S-end"}, /*shifted end key*/
1324 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1325 {"#1", "S-help"}, /*shifted help key*/
1326 {"#2", "S-home"}, /*shifted home key*/
1327 {"#3", "S-insert"}, /*shifted insert-character key*/
1328 {"#4", "S-left"}, /*shifted left-arrow key*/
1329 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1330 {"%c", "S-next"}, /*shifted next key*/
1331 {"%e", "S-prior"}, /*shifted previous key*/
1332 {"%f", "S-print"}, /*shifted print key*/
1333 {"%g", "S-redo"}, /*shifted redo key*/
1334 {"%i", "S-right"}, /*shifted right-arrow key*/
1335 {"!3", "S-undo"} /*shifted undo key*/
1338 static char **term_get_fkeys_address
;
1339 static KBOARD
*term_get_fkeys_kboard
;
1340 static Lisp_Object
term_get_fkeys_1 ();
1342 /* Find the escape codes sent by the function keys for Vinput_decode_map.
1343 This function scans the termcap function key sequence entries, and
1344 adds entries to Vinput_decode_map for each function key it finds. */
1347 term_get_fkeys (address
, kboard
)
1351 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1352 errors during the call. The only errors should be from Fdefine_key
1353 when given a key sequence containing an invalid prefix key. If the
1354 termcap defines function keys which use a prefix that is already bound
1355 to a command by the default bindings, we should silently ignore that
1356 function key specification, rather than giving the user an error and
1357 refusing to run at all on such a terminal. */
1359 extern Lisp_Object
Fidentity ();
1360 term_get_fkeys_address
= address
;
1361 term_get_fkeys_kboard
= kboard
;
1362 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1370 char **address
= term_get_fkeys_address
;
1371 KBOARD
*kboard
= term_get_fkeys_kboard
;
1373 /* This can happen if CANNOT_DUMP or with strange options. */
1374 if (!KEYMAPP (kboard
->Vinput_decode_map
))
1375 kboard
->Vinput_decode_map
= Fmake_sparse_keymap (Qnil
);
1377 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1379 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1381 Fdefine_key (kboard
->Vinput_decode_map
, build_string (sequence
),
1382 Fmake_vector (make_number (1),
1383 intern (keys
[i
].name
)));
1386 /* The uses of the "k0" capability are inconsistent; sometimes it
1387 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1388 We will attempt to politely accommodate both systems by testing for
1389 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1392 char *k_semi
= tgetstr ("k;", address
);
1393 char *k0
= tgetstr ("k0", address
);
1394 char *k0_name
= "f10";
1399 /* Define f0 first, so that f10 takes precedence in case the
1400 key sequences happens to be the same. */
1401 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k0
),
1402 Fmake_vector (make_number (1), intern ("f0")));
1403 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k_semi
),
1404 Fmake_vector (make_number (1), intern ("f10")));
1407 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k0
),
1408 Fmake_vector (make_number (1), intern (k0_name
)));
1411 /* Set up cookies for numbered function keys above f10. */
1413 char fcap
[3], fkey
[4];
1415 fcap
[0] = 'F'; fcap
[2] = '\0';
1416 for (i
= 11; i
< 64; i
++)
1419 fcap
[1] = '1' + i
- 11;
1421 fcap
[1] = 'A' + i
- 20;
1423 fcap
[1] = 'a' + i
- 46;
1426 char *sequence
= tgetstr (fcap
, address
);
1429 sprintf (fkey
, "f%d", i
);
1430 Fdefine_key (kboard
->Vinput_decode_map
, build_string (sequence
),
1431 Fmake_vector (make_number (1),
1439 * Various mappings to try and get a better fit.
1442 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1443 if (!tgetstr (cap1, address)) \
1445 char *sequence = tgetstr (cap2, address); \
1447 Fdefine_key (kboard->Vinput_decode_map, build_string (sequence), \
1448 Fmake_vector (make_number (1), \
1452 /* if there's no key_next keycap, map key_npage to `next' keysym */
1453 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1454 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1455 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1456 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1457 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1458 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1459 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1461 /* IBM has their own non-standard dialect of terminfo.
1462 If the standard name isn't found, try the IBM name. */
1463 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1464 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1465 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1466 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1467 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1468 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1469 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1470 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1471 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1472 #undef CONDITIONAL_REASSIGN
1479 /***********************************************************************
1480 Character Display Information
1481 ***********************************************************************/
1483 /* Avoid name clash with functions defined in xterm.c */
1485 #define append_glyph append_glyph_term
1486 #define produce_stretch_glyph produce_stretch_glyph_term
1487 #define append_composite_glyph append_composite_glyph_term
1488 #define produce_composite_glyph produce_composite_glyph_term
1491 static void append_glyph
P_ ((struct it
*));
1492 static void produce_stretch_glyph
P_ ((struct it
*));
1493 static void append_composite_glyph
P_ ((struct it
*));
1494 static void produce_composite_glyph
P_ ((struct it
*));
1496 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1497 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1498 the character for which to produce glyphs; IT->face_id contains the
1499 character's face. Padding glyphs are appended if IT->c has a
1500 IT->pixel_width > 1. */
1506 struct glyph
*glyph
, *end
;
1509 xassert (it
->glyph_row
);
1510 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1511 + it
->glyph_row
->used
[it
->area
]);
1512 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1515 i
< it
->pixel_width
&& glyph
< end
;
1518 glyph
->type
= CHAR_GLYPH
;
1519 glyph
->pixel_width
= 1;
1520 glyph
->u
.ch
= it
->char_to_display
;
1521 glyph
->face_id
= it
->face_id
;
1522 glyph
->padding_p
= i
> 0;
1523 glyph
->charpos
= CHARPOS (it
->position
);
1524 glyph
->object
= it
->object
;
1526 ++it
->glyph_row
->used
[it
->area
];
1532 /* Produce glyphs for the display element described by IT. *IT
1533 specifies what we want to produce a glyph for (character, image, ...),
1534 and where in the glyph matrix we currently are (glyph row and hpos).
1535 produce_glyphs fills in output fields of *IT with information such as the
1536 pixel width and height of a character, and maybe output actual glyphs at
1537 the same time if IT->glyph_row is non-null. See the explanation of
1538 struct display_iterator in dispextern.h for an overview.
1540 produce_glyphs also stores the result of glyph width, ascent
1541 etc. computations in *IT.
1543 IT->glyph_row may be null, in which case produce_glyphs does not
1544 actually fill in the glyphs. This is used in the move_* functions
1545 in xdisp.c for text width and height computations.
1547 Callers usually don't call produce_glyphs directly;
1548 instead they use the macro PRODUCE_GLYPHS. */
1554 /* If a hook is installed, let it do the work. */
1556 /* Nothing but characters are supported on terminal frames. */
1557 xassert (it
->what
== IT_CHARACTER
1558 || it
->what
== IT_COMPOSITION
1559 || it
->what
== IT_STRETCH
);
1561 if (it
->what
== IT_STRETCH
)
1563 produce_stretch_glyph (it
);
1567 if (it
->what
== IT_COMPOSITION
)
1569 produce_composite_glyph (it
);
1573 /* Maybe translate single-byte characters to multibyte. */
1574 it
->char_to_display
= it
->c
;
1576 if (it
->c
>= 040 && it
->c
< 0177)
1578 it
->pixel_width
= it
->nglyphs
= 1;
1582 else if (it
->c
== '\n')
1583 it
->pixel_width
= it
->nglyphs
= 0;
1584 else if (it
->c
== '\t')
1586 int absolute_x
= (it
->current_x
1587 + it
->continuation_lines_width
);
1589 = (((1 + absolute_x
+ it
->tab_width
- 1)
1594 /* If part of the TAB has been displayed on the previous line
1595 which is continued now, continuation_lines_width will have
1596 been incremented already by the part that fitted on the
1597 continued line. So, we will get the right number of spaces
1599 nspaces
= next_tab_x
- absolute_x
;
1605 it
->char_to_display
= ' ';
1606 it
->pixel_width
= it
->len
= 1;
1612 it
->pixel_width
= nspaces
;
1613 it
->nglyphs
= nspaces
;
1615 else if (CHAR_BYTE8_P (it
->c
))
1617 if (unibyte_display_via_language_environment
1620 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1621 it
->pixel_width
= CHAR_WIDTH (it
->char_to_display
);
1622 it
->nglyphs
= it
->pixel_width
;
1628 /* Coming here means that it->c is from display table, thus
1629 we must send the raw 8-bit byte as is to the terminal.
1630 Although there's no way to know how many columns it
1631 occupies on a screen, it is a good assumption that a
1632 single byte code has 1-column width. */
1633 it
->pixel_width
= it
->nglyphs
= 1;
1640 it
->pixel_width
= CHAR_WIDTH (it
->c
);
1641 it
->nglyphs
= it
->pixel_width
;
1648 /* Advance current_x by the pixel width as a convenience for
1650 if (it
->area
== TEXT_AREA
)
1651 it
->current_x
+= it
->pixel_width
;
1652 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1653 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1657 /* Produce a stretch glyph for iterator IT. IT->object is the value
1658 of the glyph property displayed. The value must be a list
1659 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1662 1. `:width WIDTH' specifies that the space should be WIDTH *
1663 canonical char width wide. WIDTH may be an integer or floating
1666 2. `:align-to HPOS' specifies that the space should be wide enough
1667 to reach HPOS, a value in canonical character units. */
1670 produce_stretch_glyph (it
)
1673 /* (space :width WIDTH ...) */
1674 Lisp_Object prop
, plist
;
1675 int width
= 0, align_to
= -1;
1676 int zero_width_ok_p
= 0;
1679 /* List should start with `space'. */
1680 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1681 plist
= XCDR (it
->object
);
1683 /* Compute the width of the stretch. */
1684 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1685 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1687 /* Absolute width `:width WIDTH' specified and valid. */
1688 zero_width_ok_p
= 1;
1689 width
= (int)(tem
+ 0.5);
1691 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1692 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1694 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1695 align_to
= (align_to
< 0
1697 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1698 else if (align_to
< 0)
1699 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1700 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1701 zero_width_ok_p
= 1;
1704 /* Nothing specified -> width defaults to canonical char width. */
1705 width
= FRAME_COLUMN_WIDTH (it
->f
);
1707 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1710 if (width
> 0 && it
->glyph_row
)
1712 Lisp_Object o_object
= it
->object
;
1713 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1716 if (!STRINGP (object
))
1717 object
= it
->w
->buffer
;
1718 it
->object
= object
;
1719 it
->char_to_display
= ' ';
1720 it
->pixel_width
= it
->len
= 1;
1723 it
->object
= o_object
;
1725 it
->pixel_width
= width
;
1726 it
->nglyphs
= width
;
1730 /* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
1731 Called from produce_composite_glyph for terminal frames if
1732 IT->glyph_row != NULL. IT->face_id contains the character's
1736 append_composite_glyph (it
)
1739 struct glyph
*glyph
;
1741 xassert (it
->glyph_row
);
1742 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1743 if (glyph
< it
->glyph_row
->glyphs
[1 + it
->area
])
1745 glyph
->type
= COMPOSITE_GLYPH
;
1746 glyph
->pixel_width
= it
->pixel_width
;
1747 glyph
->u
.cmp_id
= it
->cmp_id
;
1748 glyph
->face_id
= it
->face_id
;
1749 glyph
->padding_p
= 0;
1750 glyph
->charpos
= CHARPOS (it
->position
);
1751 glyph
->object
= it
->object
;
1753 ++it
->glyph_row
->used
[it
->area
];
1759 /* Produce a composite glyph for iterator IT. IT->cmp_id is the ID of
1760 the composition. We simply produces components of the composition
1761 assuming that that the terminal has a capability to layout/render
1765 produce_composite_glyph (it
)
1768 struct composition
*cmp
= composition_table
[it
->cmp_id
];
1771 xassert (cmp
->glyph_len
> 0);
1772 c
= COMPOSITION_GLYPH (cmp
, 0);
1773 it
->pixel_width
= CHAR_WIDTH (it
->c
);
1777 append_composite_glyph (it
);
1781 /* Get information about special display element WHAT in an
1782 environment described by IT. WHAT is one of IT_TRUNCATION or
1783 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1784 non-null glyph_row member. This function ensures that fields like
1785 face_id, c, len of IT are left untouched. */
1788 produce_special_glyphs (it
, what
)
1790 enum display_element_type what
;
1797 temp_it
.what
= IT_CHARACTER
;
1799 temp_it
.object
= make_number (0);
1800 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1802 if (what
== IT_CONTINUATION
)
1804 /* Continuation glyph. */
1806 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1807 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1809 glyph
= XINT (DISP_CONTINUE_GLYPH (it
->dp
));
1810 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
1815 else if (what
== IT_TRUNCATION
)
1817 /* Truncation glyph. */
1819 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1820 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1822 glyph
= XINT (DISP_TRUNC_GLYPH (it
->dp
));
1823 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
1831 temp_it
.c
= FAST_GLYPH_CHAR (glyph
);
1832 temp_it
.face_id
= FAST_GLYPH_FACE (glyph
);
1833 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1835 produce_glyphs (&temp_it
);
1836 it
->pixel_width
= temp_it
.pixel_width
;
1837 it
->nglyphs
= temp_it
.pixel_width
;
1842 /***********************************************************************
1844 ***********************************************************************/
1846 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1847 one of the enumerators from enum no_color_bit, or a bit set built
1848 from them. Some display attributes may not be used together with
1849 color; the termcap capability `NC' specifies which ones. */
1851 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1852 (tty->TN_max_colors > 0 \
1853 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1856 /* Turn appearances of face FACE_ID on tty frame F on.
1857 FACE_ID is a realized face ID number, in the face cache. */
1860 turn_on_face (f
, face_id
)
1864 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1865 long fg
= face
->foreground
;
1866 long bg
= face
->background
;
1867 struct tty_display_info
*tty
= FRAME_TTY (f
);
1869 /* Do this first because TS_end_standout_mode may be the same
1870 as TS_exit_attribute_mode, which turns all appearances off. */
1871 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1873 if (tty
->TN_max_colors
> 0)
1875 if (fg
>= 0 && bg
>= 0)
1877 /* If the terminal supports colors, we can set them
1878 below without using reverse video. The face's fg
1879 and bg colors are set as they should appear on
1880 the screen, i.e. they take the inverse-video'ness
1881 of the face already into account. */
1883 else if (inverse_video
)
1885 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1886 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1887 tty_toggle_highlight (tty
);
1891 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1892 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1893 tty_toggle_highlight (tty
);
1898 /* If we can't display colors, use reverse video
1899 if the face specifies that. */
1902 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1903 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1904 tty_toggle_highlight (tty
);
1908 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1909 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1910 tty_toggle_highlight (tty
);
1915 if (face
->tty_bold_p
)
1917 if (MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1918 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1920 else if (face
->tty_dim_p
)
1921 if (MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1922 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1924 /* Alternate charset and blinking not yet used. */
1925 if (face
->tty_alt_charset_p
1926 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1927 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1929 if (face
->tty_blinking_p
1930 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1931 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1933 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1934 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1936 if (tty
->TN_max_colors
> 0)
1940 ts
= tty
->standout_mode
? tty
->TS_set_background
: tty
->TS_set_foreground
;
1943 p
= tparam (ts
, NULL
, 0, (int) fg
);
1948 ts
= tty
->standout_mode
? tty
->TS_set_foreground
: tty
->TS_set_background
;
1951 p
= tparam (ts
, NULL
, 0, (int) bg
);
1959 /* Turn off appearances of face FACE_ID on tty frame F. */
1962 turn_off_face (f
, face_id
)
1966 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1967 struct tty_display_info
*tty
= FRAME_TTY (f
);
1969 xassert (face
!= NULL
);
1971 if (tty
->TS_exit_attribute_mode
)
1973 /* Capability "me" will turn off appearance modes double-bright,
1974 half-bright, reverse-video, standout, underline. It may or
1975 may not turn off alt-char-mode. */
1976 if (face
->tty_bold_p
1978 || face
->tty_reverse_p
1979 || face
->tty_alt_charset_p
1980 || face
->tty_blinking_p
1981 || face
->tty_underline_p
)
1983 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
1984 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
1985 tty
->standout_mode
= 0;
1988 if (face
->tty_alt_charset_p
)
1989 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1993 /* If we don't have "me" we can only have those appearances
1994 that have exit sequences defined. */
1995 if (face
->tty_alt_charset_p
)
1996 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1998 if (face
->tty_underline_p
)
1999 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
2002 /* Switch back to default colors. */
2003 if (tty
->TN_max_colors
> 0
2004 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2005 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2006 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2007 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2008 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
2012 /* Return non-zero if the terminal on frame F supports all of the
2013 capabilities in CAPS simultaneously, with foreground and background
2014 colors FG and BG. */
2017 tty_capable_p (tty
, caps
, fg
, bg
)
2018 struct tty_display_info
*tty
;
2020 unsigned long fg
, bg
;
2022 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
2023 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
2026 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
2027 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
2028 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
2029 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
2030 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
2031 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
2037 /* Return non-zero if the terminal is capable to display colors. */
2039 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2041 doc
: /* Return non-nil if the tty device TERMINAL can display colors.
2043 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2044 frame's terminal). This function always returns nil if TERMINAL
2045 is not on a tty device. */)
2047 Lisp_Object terminal
;
2049 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2053 return t
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
2056 /* Return the number of supported colors. */
2057 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2058 Stty_display_color_cells
, 0, 1, 0,
2059 doc
: /* Return the number of colors supported by the tty device TERMINAL.
2061 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2062 frame's terminal). This function always returns 0 if TERMINAL
2063 is not on a tty device. */)
2065 Lisp_Object terminal
;
2067 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2069 return make_number (0);
2071 return make_number (t
->display_info
.tty
->TN_max_colors
);
2076 /* Declare here rather than in the function, as in the rest of Emacs,
2077 to work around an HPUX compiler bug (?). See
2078 http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00410.html */
2079 static int default_max_colors
;
2080 static int default_max_pairs
;
2081 static int default_no_color_video
;
2082 static char *default_orig_pair
;
2083 static char *default_set_foreground
;
2084 static char *default_set_background
;
2086 /* Save or restore the default color-related capabilities of this
2089 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
2094 if (default_orig_pair
)
2095 xfree (default_orig_pair
);
2096 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
2098 if (default_set_foreground
)
2099 xfree (default_set_foreground
);
2100 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
2103 if (default_set_background
)
2104 xfree (default_set_background
);
2105 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
2108 default_max_colors
= tty
->TN_max_colors
;
2109 default_max_pairs
= tty
->TN_max_pairs
;
2110 default_no_color_video
= tty
->TN_no_color_video
;
2114 tty
->TS_orig_pair
= default_orig_pair
;
2115 tty
->TS_set_foreground
= default_set_foreground
;
2116 tty
->TS_set_background
= default_set_background
;
2117 tty
->TN_max_colors
= default_max_colors
;
2118 tty
->TN_max_pairs
= default_max_pairs
;
2119 tty
->TN_no_color_video
= default_no_color_video
;
2123 /* Setup one of the standard tty color schemes according to MODE.
2124 MODE's value is generally the number of colors which we want to
2125 support; zero means set up for the default capabilities, the ones
2126 we saw at init_tty time; -1 means turn off color support. */
2128 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2130 /* Canonicalize all negative values of MODE. */
2136 case -1: /* no colors at all */
2137 tty
->TN_max_colors
= 0;
2138 tty
->TN_max_pairs
= 0;
2139 tty
->TN_no_color_video
= 0;
2140 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2142 case 0: /* default colors, if any */
2144 tty_default_color_capabilities (tty
, 0);
2146 case 8: /* 8 standard ANSI colors */
2147 tty
->TS_orig_pair
= "\033[0m";
2149 tty
->TS_set_foreground
= "\033[3%p1%dm";
2150 tty
->TS_set_background
= "\033[4%p1%dm";
2152 tty
->TS_set_foreground
= "\033[3%dm";
2153 tty
->TS_set_background
= "\033[4%dm";
2155 tty
->TN_max_colors
= 8;
2156 tty
->TN_max_pairs
= 64;
2157 tty
->TN_no_color_video
= 0;
2163 set_tty_color_mode (f
, val
)
2167 Lisp_Object color_mode_spec
, current_mode_spec
;
2168 Lisp_Object color_mode
, current_mode
;
2170 extern Lisp_Object Qtty_color_mode
;
2171 Lisp_Object tty_color_mode_alist
;
2173 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2180 if (NILP (tty_color_mode_alist
))
2181 color_mode_spec
= Qnil
;
2183 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2185 if (CONSP (color_mode_spec
))
2186 color_mode
= XCDR (color_mode_spec
);
2191 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2193 if (CONSP (current_mode_spec
))
2194 current_mode
= XCDR (current_mode_spec
);
2196 current_mode
= Qnil
;
2197 if (INTEGERP (color_mode
))
2198 mode
= XINT (color_mode
);
2200 mode
= 0; /* meaning default */
2201 if (INTEGERP (current_mode
))
2202 old_mode
= XINT (current_mode
);
2206 if (mode
!= old_mode
)
2208 tty_setup_colors (FRAME_TTY (f
), mode
);
2209 /* This recomputes all the faces given the new color
2211 call0 (intern ("tty-set-up-initial-frame-faces"));
2216 #endif /* !WINDOWSNT */
2220 /* Return the tty display object specified by TERMINAL. */
2223 get_tty_terminal (Lisp_Object terminal
, int throw)
2225 struct terminal
*t
= get_terminal (terminal
, throw);
2227 if (t
&& t
->type
!= output_termcap
)
2230 error ("Device %d is not a termcap terminal device", t
->id
);
2238 /* Return an active termcap device that uses the tty device with the
2241 This function ignores suspended devices.
2243 Returns NULL if the named terminal device is not opened. */
2246 get_named_tty (name
)
2254 for (t
= terminal_list
; t
; t
= t
->next_terminal
)
2256 if (t
->type
== output_termcap
2257 && !strcmp (t
->display_info
.tty
->name
, name
)
2258 && TERMINAL_ACTIVE_P (t
))
2266 DEFUN ("tty-type", Ftty_type
, Stty_type
, 0, 1, 0,
2267 doc
: /* Return the type of the tty device that TERMINAL uses.
2268 Returns nil if TERMINAL is not on a tty device.
2270 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2271 frame's terminal). */)
2273 Lisp_Object terminal
;
2275 struct terminal
*t
= get_terminal (terminal
, 1);
2277 if (t
->type
!= output_termcap
)
2280 if (t
->display_info
.tty
->type
)
2281 return build_string (t
->display_info
.tty
->type
);
2286 DEFUN ("controlling-tty-p", Fcontrolling_tty_p
, Scontrolling_tty_p
, 0, 1, 0,
2287 doc
: /* Return non-nil if TERMINAL is on the controlling tty of the Emacs process.
2289 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2290 frame's terminal). This function always returns nil if TERMINAL
2291 is not on a tty device. */)
2293 Lisp_Object terminal
;
2295 struct terminal
*t
= get_terminal (terminal
, 1);
2297 if (t
->type
!= output_termcap
|| strcmp (t
->display_info
.tty
->name
, DEV_TTY
))
2303 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 1, 0,
2304 doc
: /* Declare that the tty used by TERMINAL does not handle underlining.
2305 This is used to override the terminfo data, for certain terminals that
2306 do not really do underlining, but say that they do. This function has
2307 no effect if used on a non-tty terminal.
2309 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2310 frame's terminal). This function always returns nil if TERMINAL
2311 is not on a tty device. */)
2313 Lisp_Object terminal
;
2315 struct terminal
*t
= get_terminal (terminal
, 1);
2317 if (t
->type
== output_termcap
)
2318 t
->display_info
.tty
->TS_enter_underline_mode
= 0;
2324 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
2325 doc
: /* Suspend the terminal device TTY.
2327 The device is restored to its default state, and Emacs ceases all
2328 access to the tty device. Frames that use the device are not deleted,
2329 but input is not read from them and if they change, their display is
2332 TTY may be a terminal id, a frame, or nil for the terminal device of
2333 the currently selected frame.
2335 This function runs `suspend-tty-functions' after suspending the
2336 device. The functions are run with one arg, the id of the suspended
2339 `suspend-tty' does nothing if it is called on a device that is already
2342 A suspended tty may be resumed by calling `resume-tty' on it. */)
2346 struct terminal
*t
= get_tty_terminal (tty
, 1);
2350 error ("Unknown tty device");
2352 f
= t
->display_info
.tty
->input
;
2356 /* First run `suspend-tty-functions' and then clean up the tty
2357 state because `suspend-tty-functions' might need to change
2359 if (!NILP (Vrun_hooks
))
2361 Lisp_Object args
[2];
2362 args
[0] = intern ("suspend-tty-functions");
2363 XSETTERMINAL (args
[1], t
);
2364 Frun_hook_with_args (2, args
);
2367 reset_sys_modes (t
->display_info
.tty
);
2369 delete_keyboard_wait_descriptor (fileno (f
));
2372 if (f
!= t
->display_info
.tty
->output
)
2373 fclose (t
->display_info
.tty
->output
);
2375 t
->display_info
.tty
->input
= 0;
2376 t
->display_info
.tty
->output
= 0;
2378 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2379 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 0);
2383 /* Clear display hooks to prevent further output. */
2384 clear_tty_hooks (t
);
2389 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
2390 doc
: /* Resume the previously suspended terminal device TTY.
2391 The terminal is opened and reinitialized. Frames that are on the
2392 suspended terminal are revived.
2394 It is an error to resume a terminal while another terminal is active
2397 This function runs `resume-tty-functions' after resuming the terminal.
2398 The functions are run with one arg, the id of the resumed terminal
2401 `resume-tty' does nothing if it is called on a device that is not
2404 TTY may be a terminal id, a frame, or nil for the terminal device of
2405 the currently selected frame. */)
2409 struct terminal
*t
= get_tty_terminal (tty
, 1);
2413 error ("Unknown tty device");
2415 if (!t
->display_info
.tty
->input
)
2417 if (get_named_tty (t
->display_info
.tty
->name
))
2418 error ("Cannot resume display while another display is active on the same device");
2420 fd
= emacs_open (t
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
2423 error ("Can not reopen tty device %s: %s", t
->display_info
.tty
->name
, strerror (errno
));
2425 if (strcmp (t
->display_info
.tty
->name
, DEV_TTY
))
2426 dissociate_if_controlling_tty (fd
);
2428 t
->display_info
.tty
->output
= fdopen (fd
, "w+");
2429 t
->display_info
.tty
->input
= t
->display_info
.tty
->output
;
2431 add_keyboard_wait_descriptor (fd
);
2433 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2434 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 1);
2436 init_sys_modes (t
->display_info
.tty
);
2438 /* Run `resume-tty-functions'. */
2439 if (!NILP (Vrun_hooks
))
2441 Lisp_Object args
[2];
2442 args
[0] = intern ("resume-tty-functions");
2443 XSETTERMINAL (args
[1], t
);
2444 Frun_hook_with_args (2, args
);
2454 /***********************************************************************
2456 ***********************************************************************/
2460 term_mouse_moveto (int x
, int y
)
2462 /* TODO: how to set mouse position?
2465 name = (const char *) ttyname (0);
2466 fd = open (name, O_WRONLY);
2467 SOME_FUNCTION (x, y, fd);
2470 last_mouse_y = y; */
2474 term_show_mouse_face (enum draw_glyphs_face draw
)
2476 struct window
*w
= XWINDOW (mouse_face_window
);
2480 struct frame
*f
= XFRAME (w
->frame
);
2481 struct tty_display_info
*tty
= FRAME_TTY (f
);
2483 if (/* If window is in the process of being destroyed, don't bother
2485 w
->current_matrix
!= NULL
2486 /* Recognize when we are called to operate on rows that don't exist
2487 anymore. This can happen when a window is split. */
2488 && mouse_face_end_row
< w
->current_matrix
->nrows
)
2490 /* write_glyphs writes at cursor position, so we need to
2491 temporarily move cursor coordinates to the beginning of
2492 the highlight region. */
2494 /* Save current cursor co-ordinates */
2495 save_y
= curY (tty
);
2496 save_x
= curX (tty
);
2498 /* Note that mouse_face_beg_row etc. are window relative. */
2499 for (i
= mouse_face_beg_row
; i
<= mouse_face_end_row
; i
++)
2501 int start_hpos
, end_hpos
, nglyphs
;
2502 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
2504 /* Don't do anything if row doesn't have valid contents. */
2505 if (!row
->enabled_p
)
2508 /* For all but the first row, the highlight starts at column 0. */
2509 if (i
== mouse_face_beg_row
)
2510 start_hpos
= mouse_face_beg_col
;
2514 if (i
== mouse_face_end_row
)
2515 end_hpos
= mouse_face_end_col
;
2518 end_hpos
= row
->used
[TEXT_AREA
];
2519 if (draw
== DRAW_NORMAL_TEXT
)
2520 row
->fill_line_p
= 1; /* Clear to end of line */
2523 if (end_hpos
<= start_hpos
)
2525 /* Record that some glyphs of this row are displayed in
2527 row
->mouse_face_p
= draw
> 0;
2529 nglyphs
= end_hpos
- start_hpos
;
2531 if (end_hpos
>= row
->used
[TEXT_AREA
])
2532 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2534 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2535 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
2536 + WINDOW_LEFT_EDGE_X (w
);
2538 cursor_to (f
, pos_y
, pos_x
);
2540 if (draw
== DRAW_MOUSE_FACE
)
2542 tty_write_glyphs_with_face (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
,
2543 nglyphs
, mouse_face_face_id
);
2545 else /* draw == DRAW_NORMAL_TEXT */
2546 write_glyphs (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2548 cursor_to (f
, save_y
, save_x
);
2553 term_clear_mouse_face ()
2555 if (!NILP (mouse_face_window
))
2556 term_show_mouse_face (DRAW_NORMAL_TEXT
);
2558 mouse_face_beg_row
= mouse_face_beg_col
= -1;
2559 mouse_face_end_row
= mouse_face_end_col
= -1;
2560 mouse_face_window
= Qnil
;
2563 /* Find the glyph matrix position of buffer position POS in window W.
2564 *HPOS and *VPOS are set to the positions found. W's current glyphs
2565 must be up to date. If POS is above window start return (0, 0).
2566 If POS is after end of W, return end of last line in W.
2567 - taken from msdos.c */
2569 fast_find_position (struct window
*w
, int pos
, int *hpos
, int *vpos
)
2571 int i
, lastcol
, line_start_position
, maybe_next_line_p
= 0;
2572 int yb
= window_text_bottom_y (w
);
2573 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0), *best_row
= row
;
2577 if (row
->used
[TEXT_AREA
])
2578 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
2580 line_start_position
= 0;
2582 if (line_start_position
> pos
)
2584 /* If the position sought is the end of the buffer,
2585 don't include the blank lines at the bottom of the window. */
2586 else if (line_start_position
== pos
2587 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
2589 maybe_next_line_p
= 1;
2592 else if (line_start_position
> 0)
2595 /* Don't overstep the last matrix row, lest we get into the
2596 never-never land... */
2597 if (row
->y
+ 1 >= yb
)
2603 /* Find the right column within BEST_ROW. */
2606 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
2608 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + i
;
2611 charpos
= glyph
->charpos
;
2618 else if (charpos
> pos
)
2620 else if (charpos
> 0)
2624 /* If we're looking for the end of the buffer,
2625 and we didn't find it in the line we scanned,
2626 use the start of the following line. */
2627 if (maybe_next_line_p
)
2634 *hpos
= lastcol
+ 1;
2639 term_mouse_highlight (struct frame
*f
, int x
, int y
)
2641 enum window_part part
;
2646 if (NILP (Vmouse_highlight
)
2647 || !f
->glyphs_initialized_p
)
2650 /* Which window is that in? */
2651 window
= window_from_coordinates (f
, x
, y
, &part
, &x
, &y
, 0);
2653 /* Not on a window -> return. */
2654 if (!WINDOWP (window
))
2657 if (!EQ (window
, mouse_face_window
))
2658 term_clear_mouse_face ();
2660 w
= XWINDOW (window
);
2662 /* Are we in a window whose display is up to date?
2663 And verify the buffer's text has not changed. */
2664 b
= XBUFFER (w
->buffer
);
2666 && EQ (w
->window_end_valid
, w
->buffer
)
2667 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
2668 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
2670 int pos
, i
, nrows
= w
->current_matrix
->nrows
;
2671 struct glyph_row
*row
;
2672 struct glyph
*glyph
;
2674 /* Find the glyph under X/Y. */
2676 if (y
>= 0 && y
< nrows
)
2678 row
= MATRIX_ROW (w
->current_matrix
, y
);
2679 /* Give up if some row before the one we are looking for is
2681 for (i
= 0; i
<= y
; i
++)
2682 if (!MATRIX_ROW (w
->current_matrix
, i
)->enabled_p
)
2684 if (i
> y
/* all rows upto and including the one at Y are enabled */
2685 && row
->displays_text_p
2686 && x
< window_box_width (w
, TEXT_AREA
))
2688 glyph
= row
->glyphs
[TEXT_AREA
];
2689 if (x
>= row
->used
[TEXT_AREA
])
2694 if (!BUFFERP (glyph
->object
))
2700 /* Clear mouse face if X/Y not over text. */
2703 term_clear_mouse_face ();
2707 if (!BUFFERP (glyph
->object
))
2709 pos
= glyph
->charpos
;
2711 /* Check for mouse-face. */
2713 extern Lisp_Object Qmouse_face
;
2714 Lisp_Object mouse_face
, overlay
, position
, *overlay_vec
;
2715 int noverlays
, obegv
, ozv
;
2716 struct buffer
*obuf
;
2718 /* If we get an out-of-range value, return now; avoid an error. */
2719 if (pos
> BUF_Z (b
))
2722 /* Make the window's buffer temporarily current for
2723 overlays_at and compute_char_face. */
2724 obuf
= current_buffer
;
2731 /* Is this char mouse-active? */
2732 XSETINT (position
, pos
);
2734 /* Put all the overlays we want in a vector in overlay_vec. */
2735 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
2736 /* Sort overlays into increasing priority order. */
2737 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
2739 /* Check mouse-face highlighting. */
2740 if (!(EQ (window
, mouse_face_window
)
2741 && y
>= mouse_face_beg_row
2742 && y
<= mouse_face_end_row
2743 && (y
> mouse_face_beg_row
2744 || x
>= mouse_face_beg_col
)
2745 && (y
< mouse_face_end_row
2746 || x
< mouse_face_end_col
2747 || mouse_face_past_end
)))
2749 /* Clear the display of the old active region, if any. */
2750 term_clear_mouse_face ();
2752 /* Find the highest priority overlay that has a mouse-face
2755 for (i
= noverlays
- 1; i
>= 0; --i
)
2757 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
2758 if (!NILP (mouse_face
))
2760 overlay
= overlay_vec
[i
];
2765 /* If no overlay applies, get a text property. */
2767 mouse_face
= Fget_text_property (position
, Qmouse_face
,
2770 /* Handle the overlay case. */
2771 if (!NILP (overlay
))
2773 /* Find the range of text around this char that
2774 should be active. */
2775 Lisp_Object before
, after
;
2779 before
= Foverlay_start (overlay
);
2780 after
= Foverlay_end (overlay
);
2781 /* Record this as the current active region. */
2782 fast_find_position (w
, XFASTINT (before
),
2783 &mouse_face_beg_col
,
2784 &mouse_face_beg_row
);
2787 = !fast_find_position (w
, XFASTINT (after
),
2788 &mouse_face_end_col
,
2789 &mouse_face_end_row
);
2790 mouse_face_window
= window
;
2793 = face_at_buffer_position (w
, pos
, 0, 0,
2794 &ignore
, pos
+ 1, 1);
2796 /* Display it as active. */
2797 term_show_mouse_face (DRAW_MOUSE_FACE
);
2799 /* Handle the text property case. */
2800 else if (!NILP (mouse_face
))
2802 /* Find the range of text around this char that
2803 should be active. */
2804 Lisp_Object before
, after
, beginning
, end
;
2807 beginning
= Fmarker_position (w
->start
);
2808 XSETINT (end
, (BUF_Z (b
) - XFASTINT (w
->window_end_pos
)));
2810 = Fprevious_single_property_change (make_number (pos
+ 1),
2812 w
->buffer
, beginning
);
2814 = Fnext_single_property_change (position
, Qmouse_face
,
2817 /* Record this as the current active region. */
2818 fast_find_position (w
, XFASTINT (before
),
2819 &mouse_face_beg_col
,
2820 &mouse_face_beg_row
);
2822 = !fast_find_position (w
, XFASTINT (after
),
2823 &mouse_face_end_col
,
2824 &mouse_face_end_row
);
2825 mouse_face_window
= window
;
2828 = face_at_buffer_position (w
, pos
, 0, 0,
2829 &ignore
, pos
+ 1, 1);
2831 /* Display it as active. */
2832 term_show_mouse_face (DRAW_MOUSE_FACE
);
2836 /* Look for a `help-echo' property. */
2839 extern Lisp_Object Qhelp_echo
;
2841 /* Check overlays first. */
2843 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
2845 overlay
= overlay_vec
[i
];
2846 help
= Foverlay_get (overlay
, Qhelp_echo
);
2851 help_echo_string
= help
;
2852 help_echo_window
= window
;
2853 help_echo_object
= overlay
;
2854 help_echo_pos
= pos
;
2856 /* Try text properties. */
2857 else if (NILP (help
)
2858 && ((STRINGP (glyph
->object
)
2859 && glyph
->charpos
>= 0
2860 && glyph
->charpos
< SCHARS (glyph
->object
))
2861 || (BUFFERP (glyph
->object
)
2862 && glyph
->charpos
>= BEGV
2863 && glyph
->charpos
< ZV
)))
2865 help
= Fget_text_property (make_number (glyph
->charpos
),
2866 Qhelp_echo
, glyph
->object
);
2869 help_echo_string
= help
;
2870 help_echo_window
= window
;
2871 help_echo_object
= glyph
->object
;
2872 help_echo_pos
= glyph
->charpos
;
2879 current_buffer
= obuf
;
2885 term_mouse_movement (FRAME_PTR frame
, Gpm_Event
*event
)
2887 /* Has the mouse moved off the glyph it was on at the last sighting? */
2888 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2890 frame
->mouse_moved
= 1;
2891 term_mouse_highlight (frame
, event
->x
, event
->y
);
2892 /* Remember which glyph we're now on. */
2893 last_mouse_x
= event
->x
;
2894 last_mouse_y
= event
->y
;
2900 /* Return the current position of the mouse.
2902 Set *f to the frame the mouse is in, or zero if the mouse is in no
2903 Emacs frame. If it is set to zero, all the other arguments are
2906 Set *bar_window to Qnil, and *x and *y to the column and
2907 row of the character cell the mouse is over.
2909 Set *time to the time the mouse was at the returned position.
2911 This clears mouse_moved until the next motion
2914 term_mouse_position (FRAME_PTR
*fp
, int insist
, Lisp_Object
*bar_window
,
2915 enum scroll_bar_part
*part
, Lisp_Object
*x
,
2916 Lisp_Object
*y
, unsigned long *time
)
2920 *fp
= SELECTED_FRAME ();
2921 (*fp
)->mouse_moved
= 0;
2926 XSETINT (*x
, last_mouse_x
);
2927 XSETINT (*y
, last_mouse_y
);
2928 gettimeofday(&now
, 0);
2929 *time
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2932 /* Prepare a mouse-event in *RESULT for placement in the input queue.
2934 If the event is a button press, then note that we have grabbed
2938 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
2944 result
->kind
= GPM_CLICK_EVENT
;
2945 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
2947 if (event
->buttons
& j
) {
2948 result
->code
= i
; /* button number */
2952 gettimeofday(&now
, 0);
2953 result
->timestamp
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2955 if (event
->type
& GPM_UP
)
2956 result
->modifiers
= up_modifier
;
2957 else if (event
->type
& GPM_DOWN
)
2958 result
->modifiers
= down_modifier
;
2960 result
->modifiers
= 0;
2962 if (event
->type
& GPM_SINGLE
)
2963 result
->modifiers
|= click_modifier
;
2965 if (event
->type
& GPM_DOUBLE
)
2966 result
->modifiers
|= double_modifier
;
2968 if (event
->type
& GPM_TRIPLE
)
2969 result
->modifiers
|= triple_modifier
;
2971 if (event
->type
& GPM_DRAG
)
2972 result
->modifiers
|= drag_modifier
;
2974 if (!(event
->type
& (GPM_MOVE
| GPM_DRAG
))) {
2977 if (event
->modifiers
& (1 << 0))
2978 result
->modifiers
|= shift_modifier
;
2981 if (event
->modifiers
& (1 << 2))
2982 result
->modifiers
|= ctrl_modifier
;
2984 /* 1 << KG_ALT || KG_ALTGR */
2985 if (event
->modifiers
& (1 << 3)
2986 || event
->modifiers
& (1 << 1))
2987 result
->modifiers
|= meta_modifier
;
2990 XSETINT (result
->x
, event
->x
);
2991 XSETINT (result
->y
, event
->y
);
2992 XSETFRAME (result
->frame_or_window
, f
);
2998 handle_one_term_event (struct tty_display_info
*tty
, Gpm_Event
*event
, struct input_event
* hold_quit
)
3000 struct frame
*f
= XFRAME (tty
->top_frame
);
3001 struct input_event ie
;
3009 if (event
->type
& (GPM_MOVE
| GPM_DRAG
)) {
3010 previous_help_echo_string
= help_echo_string
;
3011 help_echo_string
= Qnil
;
3013 Gpm_DrawPointer (event
->x
, event
->y
, fileno (tty
->output
));
3015 if (!term_mouse_movement (f
, event
))
3016 help_echo_string
= previous_help_echo_string
;
3018 /* If the contents of the global variable help_echo_string
3019 has changed, generate a HELP_EVENT. */
3020 if (!NILP (help_echo_string
)
3021 || !NILP (previous_help_echo_string
))
3028 term_mouse_click (&ie
, event
, f
);
3032 if (ie
.kind
!= NO_EVENT
)
3034 kbd_buffer_store_event_hold (&ie
, hold_quit
);
3039 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
3044 XSETFRAME (frame
, f
);
3048 gen_help_event (help_echo_string
, frame
, help_echo_window
,
3049 help_echo_object
, help_echo_pos
);
3056 DEFUN ("gpm-mouse-start", Fgpm_mouse_start
, Sgpm_mouse_start
,
3058 doc
: /* Open a connection to Gpm.
3059 Gpm-mouse can only be activated for one tty at a time. */)
3062 struct frame
*f
= SELECTED_FRAME ();
3063 struct tty_display_info
*tty
3064 = ((f
)->output_method
== output_termcap
3065 ? (f
)->terminal
->display_info
.tty
: NULL
);
3066 Gpm_Connect connection
;
3069 error ("Gpm-mouse only works in the GNU/Linux console");
3071 return Qnil
; /* Already activated, nothing to do. */
3073 error ("Gpm-mouse can only be activated for one tty at a time");
3075 connection
.eventMask
= ~0;
3076 connection
.defaultMask
= ~GPM_HARD
;
3077 connection
.maxMod
= ~0;
3078 connection
.minMod
= 0;
3081 if (Gpm_Open (&connection
, 0) < 0)
3082 error ("Gpm-mouse failed to connect to the gpm daemon");
3086 /* `init_sys_modes' arranges for mouse movements sent through gpm_fd
3087 to generate SIGIOs. Apparently we need to call reset_sys_modes
3088 before calling init_sys_modes. */
3089 reset_sys_modes (tty
);
3090 init_sys_modes (tty
);
3091 add_gpm_wait_descriptor (gpm_fd
);
3096 DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop
, Sgpm_mouse_stop
,
3098 doc
: /* Close a connection to Gpm. */)
3101 struct frame
*f
= SELECTED_FRAME ();
3102 struct tty_display_info
*tty
3103 = ((f
)->output_method
== output_termcap
3104 ? (f
)->terminal
->display_info
.tty
: NULL
);
3106 if (!tty
|| gpm_tty
!= tty
)
3107 return Qnil
; /* Not activated on this terminal, nothing to do. */
3110 delete_gpm_wait_descriptor (gpm_fd
);
3111 while (Gpm_Close()); /* close all the stack */
3115 #endif /* HAVE_GPM */
3118 /***********************************************************************
3120 ***********************************************************************/
3122 /* Initialize the tty-dependent part of frame F. The frame must
3123 already have its device initialized. */
3126 create_tty_output (struct frame
*f
)
3128 struct tty_output
*t
;
3130 if (! FRAME_TERMCAP_P (f
))
3133 t
= xmalloc (sizeof (struct tty_output
));
3134 bzero (t
, sizeof (struct tty_output
));
3136 t
->display_info
= FRAME_TERMINAL (f
)->display_info
.tty
;
3138 f
->output_data
.tty
= t
;
3141 /* Delete the tty-dependent part of frame F. */
3144 delete_tty_output (struct frame
*f
)
3146 if (! FRAME_TERMCAP_P (f
))
3149 xfree (f
->output_data
.tty
);
3153 /* Reset the hooks in TERMINAL. */
3156 clear_tty_hooks (struct terminal
*terminal
)
3159 terminal
->cursor_to_hook
= 0;
3160 terminal
->raw_cursor_to_hook
= 0;
3161 terminal
->clear_to_end_hook
= 0;
3162 terminal
->clear_frame_hook
= 0;
3163 terminal
->clear_end_of_line_hook
= 0;
3164 terminal
->ins_del_lines_hook
= 0;
3165 terminal
->insert_glyphs_hook
= 0;
3166 terminal
->write_glyphs_hook
= 0;
3167 terminal
->delete_glyphs_hook
= 0;
3168 terminal
->ring_bell_hook
= 0;
3169 terminal
->reset_terminal_modes_hook
= 0;
3170 terminal
->set_terminal_modes_hook
= 0;
3171 terminal
->update_begin_hook
= 0;
3172 terminal
->update_end_hook
= 0;
3173 terminal
->set_terminal_window_hook
= 0;
3174 terminal
->mouse_position_hook
= 0;
3175 terminal
->frame_rehighlight_hook
= 0;
3176 terminal
->frame_raise_lower_hook
= 0;
3177 terminal
->fullscreen_hook
= 0;
3178 terminal
->set_vertical_scroll_bar_hook
= 0;
3179 terminal
->condemn_scroll_bars_hook
= 0;
3180 terminal
->redeem_scroll_bar_hook
= 0;
3181 terminal
->judge_scroll_bars_hook
= 0;
3182 terminal
->read_socket_hook
= 0;
3183 terminal
->frame_up_to_date_hook
= 0;
3185 /* Leave these two set, or suspended frames are not deleted
3187 terminal
->delete_frame_hook
= &delete_tty_output
;
3188 terminal
->delete_terminal_hook
= &delete_tty
;
3191 /* Initialize hooks in TERMINAL with the values needed for a tty. */
3194 set_tty_hooks (struct terminal
*terminal
)
3196 terminal
->rif
= 0; /* ttys don't support window-based redisplay. */
3198 terminal
->cursor_to_hook
= &tty_cursor_to
;
3199 terminal
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
3201 terminal
->clear_to_end_hook
= &tty_clear_to_end
;
3202 terminal
->clear_frame_hook
= &tty_clear_frame
;
3203 terminal
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
3205 terminal
->ins_del_lines_hook
= &tty_ins_del_lines
;
3207 terminal
->insert_glyphs_hook
= &tty_insert_glyphs
;
3208 terminal
->write_glyphs_hook
= &tty_write_glyphs
;
3209 terminal
->delete_glyphs_hook
= &tty_delete_glyphs
;
3211 terminal
->ring_bell_hook
= &tty_ring_bell
;
3213 terminal
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
3214 terminal
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
3215 terminal
->update_begin_hook
= 0; /* Not needed. */
3216 terminal
->update_end_hook
= &tty_update_end
;
3217 terminal
->set_terminal_window_hook
= &tty_set_terminal_window
;
3219 terminal
->mouse_position_hook
= 0; /* Not needed. */
3220 terminal
->frame_rehighlight_hook
= 0; /* Not needed. */
3221 terminal
->frame_raise_lower_hook
= 0; /* Not needed. */
3223 terminal
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
3224 terminal
->condemn_scroll_bars_hook
= 0; /* Not needed. */
3225 terminal
->redeem_scroll_bar_hook
= 0; /* Not needed. */
3226 terminal
->judge_scroll_bars_hook
= 0; /* Not needed. */
3228 terminal
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
3229 terminal
->frame_up_to_date_hook
= 0; /* Not needed. */
3231 terminal
->delete_frame_hook
= &delete_tty_output
;
3232 terminal
->delete_terminal_hook
= &delete_tty
;
3235 /* Drop the controlling terminal if fd is the same device. */
3237 dissociate_if_controlling_tty (int fd
)
3241 EMACS_GET_TTY_PGRP (fd
, &pgid
); /* If tcgetpgrp succeeds, fd is the ctty. */
3244 #if defined (USG) && !defined (BSD_PGRPS)
3246 no_controlling_tty
= 1;
3247 #elif defined (CYGWIN)
3249 no_controlling_tty
= 1;
3251 #ifdef TIOCNOTTY /* Try BSD ioctls. */
3252 sigblock (sigmask (SIGTTOU
));
3253 fd
= emacs_open (DEV_TTY
, O_RDWR
, 0);
3254 if (fd
!= -1 && ioctl (fd
, TIOCNOTTY
, 0) != -1)
3256 no_controlling_tty
= 1;
3260 sigunblock (sigmask (SIGTTOU
));
3262 /* Unknown system. */
3264 #endif /* ! TIOCNOTTY */
3267 #endif /* !WINDOWSNT */
3270 static void maybe_fatal();
3272 /* Create a termcap display on the tty device with the given name and
3275 If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
3276 Otherwise NAME should be a path to the tty device file,
3279 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
3281 If MUST_SUCCEED is true, then all errors are fatal. */
3284 init_tty (char *name
, char *terminal_type
, int must_succeed
)
3287 char **address
= &area
;
3288 char *buffer
= NULL
;
3289 int buffer_size
= 4096;
3290 register char *p
= NULL
;
3292 struct tty_display_info
*tty
= NULL
;
3293 struct terminal
*terminal
= NULL
;
3294 int ctty
= 0; /* 1 if asked to open controlling tty. */
3297 maybe_fatal (must_succeed
, 0, 0,
3298 "Unknown terminal type",
3299 "Unknown terminal type");
3303 if (!strcmp (name
, DEV_TTY
))
3306 /* If we already have a terminal on the given device, use that. If
3307 all such terminals are suspended, create a new one instead. */
3308 /* XXX Perhaps this should be made explicit by having init_tty
3309 always create a new terminal and separating terminal and frame
3310 creation on Lisp level. */
3311 terminal
= get_named_tty (name
);
3315 terminal
= create_terminal ();
3316 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
3317 bzero (tty
, sizeof (struct tty_display_info
));
3318 tty
->next
= tty_list
;
3321 terminal
->type
= output_termcap
;
3322 terminal
->display_info
.tty
= tty
;
3323 tty
->terminal
= terminal
;
3325 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
3329 set_tty_hooks (terminal
);
3335 #ifdef O_IGNORE_CTTY
3337 /* Open the terminal device. Don't recognize it as our
3338 controlling terminal, and don't make it the controlling tty
3339 if we don't have one at the moment. */
3340 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
3343 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
3344 defined on Hurd. On other systems, we need to explicitly
3345 dissociate ourselves from the controlling tty when we want to
3346 open a frame on the same terminal. */
3347 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
3348 #endif /* O_IGNORE_CTTY */
3351 maybe_fatal (must_succeed
, buffer
, terminal
,
3352 "Could not open file: %s",
3353 "Could not open file: %s",
3358 maybe_fatal (must_succeed
, buffer
, terminal
,
3359 "Not a tty device: %s",
3360 "Not a tty device: %s",
3364 #ifndef O_IGNORE_CTTY
3366 dissociate_if_controlling_tty (fd
);
3369 file
= fdopen (fd
, "w+");
3370 tty
->name
= xstrdup (name
);
3371 terminal
->name
= xstrdup (name
);
3376 tty
->type
= xstrdup (terminal_type
);
3378 add_keyboard_wait_descriptor (fileno (tty
->input
));
3382 encode_terminal_src_size
= 0;
3383 encode_terminal_dst_size
= 0;
3386 terminal
->mouse_position_hook
= term_mouse_position
;
3387 mouse_face_window
= Qnil
;
3391 initialize_w32_display (terminal
);
3392 /* The following two are inaccessible from w32console.c. */
3393 terminal
->delete_frame_hook
= &delete_tty_output
;
3394 terminal
->delete_terminal_hook
= &delete_tty
;
3396 tty
->name
= xstrdup (name
);
3397 terminal
->name
= xstrdup (name
);
3398 tty
->type
= xstrdup (terminal_type
);
3400 tty
->output
= stdout
;
3402 add_keyboard_wait_descriptor (0);
3407 struct frame
*f
= XFRAME (selected_frame
);
3409 FrameRows (tty
) = FRAME_LINES (f
);
3410 FrameCols (tty
) = FRAME_COLS (f
);
3411 tty
->specified_window
= FRAME_LINES (f
);
3413 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
3414 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
3416 tty
->delete_in_insert_mode
= 1;
3419 terminal
->scroll_region_ok
= 0;
3421 /* Seems to insert lines when it's not supposed to, messing up the
3422 display. In doing a trace, it didn't seem to be called much, so I
3423 don't think we're losing anything by turning it off. */
3424 terminal
->line_ins_del_ok
= 0;
3425 terminal
->char_ins_del_ok
= 1;
3429 tty
->TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
3431 #else /* not WINDOWSNT */
3435 buffer
= (char *) xmalloc (buffer_size
);
3437 /* On some systems, tgetent tries to access the controlling
3439 sigblock (sigmask (SIGTTOU
));
3440 status
= tgetent (buffer
, terminal_type
);
3441 sigunblock (sigmask (SIGTTOU
));
3446 maybe_fatal (must_succeed
, buffer
, terminal
,
3447 "Cannot open terminfo database file",
3448 "Cannot open terminfo database file");
3450 maybe_fatal (must_succeed
, buffer
, terminal
,
3451 "Cannot open termcap database file",
3452 "Cannot open termcap database file");
3458 maybe_fatal (must_succeed
, buffer
, terminal
,
3459 "Terminal type %s is not defined",
3460 "Terminal type %s is not defined.\n\
3461 If that is not the actual type of terminal you have,\n\
3462 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3463 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3464 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3467 maybe_fatal (must_succeed
, buffer
, terminal
,
3468 "Terminal type %s is not defined",
3469 "Terminal type %s is not defined.\n\
3470 If that is not the actual type of terminal you have,\n\
3471 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3472 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3473 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3479 if (strlen (buffer
) >= buffer_size
)
3481 buffer_size
= strlen (buffer
);
3483 area
= (char *) xmalloc (buffer_size
);
3485 tty
->TS_ins_line
= tgetstr ("al", address
);
3486 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
3487 tty
->TS_bell
= tgetstr ("bl", address
);
3488 BackTab (tty
) = tgetstr ("bt", address
);
3489 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
3490 tty
->TS_clr_line
= tgetstr ("ce", address
);
3491 tty
->TS_clr_frame
= tgetstr ("cl", address
);
3492 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
3493 AbsPosition (tty
) = tgetstr ("cm", address
);
3494 CR (tty
) = tgetstr ("cr", address
);
3495 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
3496 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
3497 RowPosition (tty
) = tgetstr ("cv", address
);
3498 tty
->TS_del_char
= tgetstr ("dc", address
);
3499 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
3500 tty
->TS_del_line
= tgetstr ("dl", address
);
3501 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
3502 tty
->TS_delete_mode
= tgetstr ("dm", address
);
3503 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
3504 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
3505 Home (tty
) = tgetstr ("ho", address
);
3506 tty
->TS_ins_char
= tgetstr ("ic", address
);
3507 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
3508 tty
->TS_insert_mode
= tgetstr ("im", address
);
3509 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
3510 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
3511 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
3512 LastLine (tty
) = tgetstr ("ll", address
);
3513 Right (tty
) = tgetstr ("nd", address
);
3514 Down (tty
) = tgetstr ("do", address
);
3516 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
3518 /* VMS puts a carriage return before each linefeed,
3519 so it is not safe to use linefeeds. */
3520 if (Down (tty
) && Down (tty
)[0] == '\n' && Down (tty
)[1] == '\0')
3523 if (tgetflag ("bs"))
3524 Left (tty
) = "\b"; /* can't possibly be longer! */
3525 else /* (Actually, "bs" is obsolete...) */
3526 Left (tty
) = tgetstr ("le", address
);
3528 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
3529 tty
->TS_pad_char
= tgetstr ("pc", address
);
3530 tty
->TS_repeat
= tgetstr ("rp", address
);
3531 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
3532 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
3533 tty
->TS_standout_mode
= tgetstr ("so", address
);
3534 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
3535 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
3536 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
3537 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
3538 Up (tty
) = tgetstr ("up", address
);
3539 tty
->TS_visible_bell
= tgetstr ("vb", address
);
3540 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
3541 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
3542 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
3543 tty
->TS_set_window
= tgetstr ("wi", address
);
3545 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
3546 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
3547 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
3548 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
3549 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
3550 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
3551 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3552 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3553 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
3555 MultiUp (tty
) = tgetstr ("UP", address
);
3556 MultiDown (tty
) = tgetstr ("DO", address
);
3557 MultiLeft (tty
) = tgetstr ("LE", address
);
3558 MultiRight (tty
) = tgetstr ("RI", address
);
3560 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
3561 color because we can't switch back to the default foreground and
3563 tty
->TS_orig_pair
= tgetstr ("op", address
);
3564 if (tty
->TS_orig_pair
)
3566 tty
->TS_set_foreground
= tgetstr ("AF", address
);
3567 tty
->TS_set_background
= tgetstr ("AB", address
);
3568 if (!tty
->TS_set_foreground
)
3571 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
3572 tty
->TS_set_background
= tgetstr ("Sb", address
);
3575 tty
->TN_max_colors
= tgetnum ("Co");
3576 tty
->TN_max_pairs
= tgetnum ("pa");
3578 tty
->TN_no_color_video
= tgetnum ("NC");
3579 if (tty
->TN_no_color_video
== -1)
3580 tty
->TN_no_color_video
= 0;
3583 tty_default_color_capabilities (tty
, 1);
3585 MagicWrap (tty
) = tgetflag ("xn");
3586 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3587 the former flag imply the latter. */
3588 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
3589 terminal
->memory_below_frame
= tgetflag ("db");
3590 tty
->TF_hazeltine
= tgetflag ("hz");
3591 terminal
->must_write_spaces
= tgetflag ("in");
3592 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
3593 tty
->TF_insmode_motion
= tgetflag ("mi");
3594 tty
->TF_standout_motion
= tgetflag ("ms");
3595 tty
->TF_underscore
= tgetflag ("ul");
3596 tty
->TF_teleray
= tgetflag ("xt");
3598 #endif /* !WINDOWSNT */
3600 terminal
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
3601 init_kboard (terminal
->kboard
);
3602 terminal
->kboard
->Vwindow_system
= Qnil
;
3603 terminal
->kboard
->next_kboard
= all_kboards
;
3604 all_kboards
= terminal
->kboard
;
3605 terminal
->kboard
->reference_count
++;
3606 /* Don't let the initial kboard remain current longer than necessary.
3607 That would cause problems if a file loaded on startup tries to
3608 prompt in the mini-buffer. */
3609 if (current_kboard
== initial_kboard
)
3610 current_kboard
= terminal
->kboard
;
3612 term_get_fkeys (address
, terminal
->kboard
);
3617 /* Get frame size from system, or else from termcap. */
3620 get_tty_size (fileno (tty
->input
), &width
, &height
);
3621 FrameCols (tty
) = width
;
3622 FrameRows (tty
) = height
;
3625 if (FrameCols (tty
) <= 0)
3626 FrameCols (tty
) = tgetnum ("co");
3627 if (FrameRows (tty
) <= 0)
3628 FrameRows (tty
) = tgetnum ("li");
3630 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
3631 maybe_fatal (must_succeed
, NULL
, terminal
,
3632 "Screen size %dx%d is too small"
3633 "Screen size %dx%d is too small",
3634 FrameCols (tty
), FrameRows (tty
));
3636 #if 0 /* This is not used anywhere. */
3637 tty
->terminal
->min_padding_speed
= tgetnum ("pb");
3640 TabWidth (tty
) = tgetnum ("tw");
3643 /* These capabilities commonly use ^J.
3644 I don't know why, but sending them on VMS does not work;
3645 it causes following spaces to be lost, sometimes.
3646 For now, the simplest fix is to avoid using these capabilities ever. */
3647 if (Down (tty
) && Down (tty
)[0] == '\n')
3652 tty
->TS_bell
= "\07";
3654 if (!tty
->TS_fwd_scroll
)
3655 tty
->TS_fwd_scroll
= Down (tty
);
3657 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
3659 if (TabWidth (tty
) < 0)
3662 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3663 and newer termcap doc does not seem to say there is a default.
3664 if (!tty->Wcm->cm_tab)
3665 tty->Wcm->cm_tab = "\t";
3668 /* We don't support standout modes that use `magic cookies', so
3669 turn off any that do. */
3670 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
3672 tty
->TS_standout_mode
= 0;
3673 tty
->TS_end_standout_mode
= 0;
3675 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3677 tty
->TS_enter_underline_mode
= 0;
3678 tty
->TS_exit_underline_mode
= 0;
3681 /* If there's no standout mode, try to use underlining instead. */
3682 if (tty
->TS_standout_mode
== 0)
3684 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
3685 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
3688 /* If no `se' string, try using a `me' string instead.
3689 If that fails, we can't use standout mode at all. */
3690 if (tty
->TS_end_standout_mode
== 0)
3692 char *s
= tgetstr ("me", address
);
3694 tty
->TS_end_standout_mode
= s
;
3696 tty
->TS_standout_mode
= 0;
3699 if (tty
->TF_teleray
)
3701 tty
->Wcm
->cm_tab
= 0;
3702 /* We can't support standout mode, because it uses magic cookies. */
3703 tty
->TS_standout_mode
= 0;
3704 /* But that means we cannot rely on ^M to go to column zero! */
3706 /* LF can't be trusted either -- can alter hpos */
3707 /* if move at column 0 thru a line with TS_standout_mode */
3711 /* Special handling for certain terminal types known to need it */
3713 if (!strcmp (terminal_type
, "supdup"))
3715 terminal
->memory_below_frame
= 1;
3716 tty
->Wcm
->cm_losewrap
= 1;
3718 if (!strncmp (terminal_type
, "c10", 3)
3719 || !strcmp (terminal_type
, "perq"))
3721 /* Supply a makeshift :wi string.
3722 This string is not valid in general since it works only
3723 for windows starting at the upper left corner;
3724 but that is all Emacs uses.
3726 This string works only if the frame is using
3727 the top of the video memory, because addressing is memory-relative.
3728 So first check the :ti string to see if that is true.
3730 It would be simpler if the :wi string could go in the termcap
3731 entry, but it can't because it is not fully valid.
3732 If it were in the termcap entry, it would confuse other programs. */
3733 if (!tty
->TS_set_window
)
3735 p
= tty
->TS_termcap_modes
;
3736 while (*p
&& strcmp (p
, "\033v "))
3739 tty
->TS_set_window
= "\033v%C %C %C %C ";
3741 /* Termcap entry often fails to have :in: flag */
3742 terminal
->must_write_spaces
= 1;
3743 /* :ti string typically fails to have \E^G! in it */
3744 /* This limits scope of insert-char to one line. */
3745 strcpy (area
, tty
->TS_termcap_modes
);
3746 strcat (area
, "\033\007!");
3747 tty
->TS_termcap_modes
= area
;
3748 area
+= strlen (area
) + 1;
3749 p
= AbsPosition (tty
);
3750 /* Change all %+ parameters to %C, to handle
3751 values above 96 correctly for the C100. */
3754 if (p
[0] == '%' && p
[1] == '+')
3760 tty
->specified_window
= FrameRows (tty
);
3762 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
3764 maybe_fatal (must_succeed
, NULL
, terminal
,
3765 "Terminal type \"%s\" is not powerful enough to run Emacs",
3767 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3768 It lacks the ability to position the cursor.\n\
3769 If that is not the actual type of terminal you have, use either the\n\
3770 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
3771 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
3774 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3775 It lacks the ability to position the cursor.\n\
3776 If that is not the actual type of terminal you have,\n\
3777 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3778 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3779 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3780 # else /* TERMCAP */
3781 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3782 It lacks the ability to position the cursor.\n\
3783 If that is not the actual type of terminal you have,\n\
3784 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3785 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3786 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3787 # endif /* TERMINFO */
3792 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
3793 maybe_fatal (must_succeed
, NULL
, terminal
,
3794 "Could not determine the frame size",
3795 "Could not determine the frame size");
3797 tty
->delete_in_insert_mode
3798 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
3799 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
3801 tty
->se_is_so
= (tty
->TS_standout_mode
3802 && tty
->TS_end_standout_mode
3803 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
3805 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
3807 terminal
->scroll_region_ok
3809 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
3811 terminal
->line_ins_del_ok
3812 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
3813 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
3814 || (terminal
->scroll_region_ok
3815 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
3817 terminal
->char_ins_del_ok
3818 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
3819 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
3820 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
3822 terminal
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
3824 init_baud_rate (fileno (tty
->input
));
3827 /* The HFT system on AIX doesn't optimize for scrolling, so it's
3828 really ugly at times. */
3829 terminal
->line_ins_del_ok
= 0;
3830 terminal
->char_ins_del_ok
= 0;
3833 /* Don't do this. I think termcap may still need the buffer. */
3834 /* xfree (buffer); */
3836 #endif /* not WINDOWSNT */
3838 /* Init system terminal modes (RAW or CBREAK, etc.). */
3839 init_sys_modes (tty
);
3844 /* Auxiliary error-handling function for init_tty.
3845 Free BUFFER and delete TERMINAL, then call error or fatal
3846 with str1 or str2, respectively, according to MUST_SUCCEED. */
3849 maybe_fatal (must_succeed
, buffer
, terminal
, str1
, str2
, arg1
, arg2
)
3852 struct terminal
*terminal
;
3853 char *str1
, *str2
, *arg1
, *arg2
;
3859 delete_tty (terminal
);
3862 fatal (str2
, arg1
, arg2
);
3864 error (str1
, arg1
, arg2
);
3871 fatal (str
, arg1
, arg2
)
3872 char *str
, *arg1
, *arg2
;
3874 fprintf (stderr
, "emacs: ");
3875 fprintf (stderr
, str
, arg1
, arg2
);
3876 fprintf (stderr
, "\n");
3883 /* Delete the given tty terminal, closing all frames on it. */
3886 delete_tty (struct terminal
*terminal
)
3888 struct tty_display_info
*tty
;
3889 Lisp_Object tail
, frame
;
3892 /* Protect against recursive calls. Fdelete_frame in
3893 delete_terminal calls us back when it deletes our last frame. */
3894 if (!terminal
->name
)
3897 if (terminal
->type
!= output_termcap
)
3900 tty
= terminal
->display_info
.tty
;
3903 FOR_EACH_FRAME (tail
, frame
)
3905 struct frame
*f
= XFRAME (frame
);
3906 if (FRAME_LIVE_P (f
) && (!FRAME_TERMCAP_P (f
) || FRAME_TTY (f
) != tty
))
3913 error ("Attempt to delete the sole terminal device with live frames");
3915 if (tty
== tty_list
)
3916 tty_list
= tty
->next
;
3919 struct tty_display_info
*p
;
3920 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
3924 /* This should not happen. */
3927 p
->next
= tty
->next
;
3931 /* reset_sys_modes needs a valid device, so this call needs to be
3932 before delete_terminal. */
3933 reset_sys_modes (tty
);
3935 delete_terminal (terminal
);
3945 delete_keyboard_wait_descriptor (fileno (tty
->input
));
3946 if (tty
->input
!= stdin
)
3947 fclose (tty
->input
);
3949 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
3950 fclose (tty
->output
);
3951 if (tty
->termscript
)
3952 fclose (tty
->termscript
);
3955 xfree (tty
->old_tty
);
3960 bzero (tty
, sizeof (struct tty_display_info
));
3966 /* Mark the pointers in the tty_display_info objects.
3967 Called by the Fgarbage_collector. */
3972 struct tty_display_info
*tty
;
3974 for (tty
= tty_list
; tty
; tty
= tty
->next
)
3975 mark_object (tty
->top_frame
);
3983 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
3984 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3985 This variable can be used by terminal emulator packages. */);
3987 system_uses_terminfo
= 1;
3989 system_uses_terminfo
= 0;
3992 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions
,
3993 doc
: /* Functions to be run after suspending a tty.
3994 The functions are run with one argument, the terminal id to be suspended.
3995 See `suspend-tty'. */);
3996 Vsuspend_tty_functions
= Qnil
;
3999 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions
,
4000 doc
: /* Functions to be run after resuming a tty.
4001 The functions are run with one argument, the terminal id that was revived.
4002 See `resume-tty'. */);
4003 Vresume_tty_functions
= Qnil
;
4005 DEFVAR_BOOL ("visible-cursor", &visible_cursor
,
4006 doc
: /* Non-nil means to make the cursor very visible.
4007 This only has an effect when running in a text terminal.
4008 What means \"very visible\" is up to your terminal. It may make the cursor
4009 bigger, or it may make it blink, or it may do nothing at all. */);
4012 defsubr (&Stty_display_color_p
);
4013 defsubr (&Stty_display_color_cells
);
4014 defsubr (&Stty_no_underline
);
4015 defsubr (&Stty_type
);
4016 defsubr (&Scontrolling_tty_p
);
4017 defsubr (&Ssuspend_tty
);
4018 defsubr (&Sresume_tty
);
4020 defsubr (&Sgpm_mouse_start
);
4021 defsubr (&Sgpm_mouse_stop
);
4023 staticpro (&mouse_face_window
);
4024 #endif /* HAVE_GPM */
4029 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
4030 (do not change this comment) */