1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
35 #include <termios.h> /* For TIOCNOTTY. */
46 #include "character.h"
49 #include "composite.h"
53 #include "termhooks.h"
54 #include "dispextern.h"
57 #include "blockinput.h"
58 #include "syssignal.h"
60 #include "intervals.h"
63 static int been_here
= -1;
66 /* For now, don't try to include termcap.h. On some systems,
67 configure finds a non-standard termcap.h that the main build
70 #if defined HAVE_TERMCAP_H && 0
73 extern void tputs
P_ ((const char *, int, int (*)(int)));
74 extern int tgetent
P_ ((char *, const char *));
75 extern int tgetflag
P_ ((char *id
));
76 extern int tgetnum
P_ ((char *id
));
92 /* The name of the default console device. */
94 #define DEV_TTY "CONOUT$"
96 #define DEV_TTY "/dev/tty"
99 static void tty_set_scroll_region
P_ ((struct frame
*f
, int start
, int stop
));
100 static void turn_on_face
P_ ((struct frame
*, int face_id
));
101 static void turn_off_face
P_ ((struct frame
*, int face_id
));
102 static void tty_show_cursor
P_ ((struct tty_display_info
*));
103 static void tty_hide_cursor
P_ ((struct tty_display_info
*));
104 static void tty_background_highlight
P_ ((struct tty_display_info
*tty
));
105 static void clear_tty_hooks
P_ ((struct terminal
*terminal
));
106 static void set_tty_hooks
P_ ((struct terminal
*terminal
));
107 static void dissociate_if_controlling_tty
P_ ((int fd
));
108 static void delete_tty
P_ ((struct terminal
*));
110 #define OUTPUT(tty, a) \
111 emacs_tputs ((tty), a, \
112 (int) (FRAME_LINES (XFRAME (selected_frame)) \
116 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
117 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
119 #define OUTPUT_IF(tty, a) \
122 emacs_tputs ((tty), a, \
123 (int) (FRAME_LINES (XFRAME (selected_frame)) \
128 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
130 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */
132 static int visible_cursor
;
134 /* Display space properties */
136 extern Lisp_Object Qspace
, QCalign_to
, QCwidth
;
138 /* Functions to call after suspending a tty. */
139 Lisp_Object Vsuspend_tty_functions
;
141 /* Functions to call after resuming a tty. */
142 Lisp_Object Vresume_tty_functions
;
144 /* Chain of all tty device parameters. */
145 struct tty_display_info
*tty_list
;
147 /* Nonzero means no need to redraw the entire frame on resuming a
148 suspended Emacs. This is useful on terminals with multiple
149 pages, where one page is used for Emacs and another for all
151 int no_redraw_on_reenter
;
153 /* Meaning of bits in no_color_video. Each bit set means that the
154 corresponding attribute cannot be combined with colors. */
158 NC_STANDOUT
= 1 << 0,
159 NC_UNDERLINE
= 1 << 1,
166 NC_ALT_CHARSET
= 1 << 8
171 /* The largest frame width in any call to calculate_costs. */
175 /* The largest frame height in any call to calculate_costs. */
179 /* Non-zero if we have dropped our controlling tty and therefore
180 should not open a frame on stdout. */
181 static int no_controlling_tty
;
183 /* Provided for lisp packages. */
185 static int system_uses_terminfo
;
189 extern char *tgetstr ();
193 #include <sys/fcntl.h>
195 static void term_clear_mouse_face ();
196 static void term_mouse_highlight (struct frame
*f
, int x
, int y
);
198 /* The device for which we have enabled gpm support (or NULL). */
199 struct tty_display_info
*gpm_tty
= NULL
;
201 /* These variables describe the range of text currently shown in its
202 mouse-face, together with the window they apply to. As long as
203 the mouse stays within this range, we need not redraw anything on
204 its account. Rows and columns are glyph matrix positions in
205 MOUSE_FACE_WINDOW. */
206 static int mouse_face_beg_row
, mouse_face_beg_col
;
207 static int mouse_face_end_row
, mouse_face_end_col
;
208 static int mouse_face_past_end
;
209 static Lisp_Object mouse_face_window
;
210 static int mouse_face_face_id
;
212 static int pos_x
, pos_y
;
213 static int last_mouse_x
, last_mouse_y
;
214 #endif /* HAVE_GPM */
216 /* Ring the bell on a tty. */
219 tty_ring_bell (struct frame
*f
)
221 struct tty_display_info
*tty
= FRAME_TTY (f
);
225 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
226 ? tty
->TS_visible_bell
228 fflush (tty
->output
);
232 /* Set up termcap modes for Emacs. */
235 tty_set_terminal_modes (struct terminal
*terminal
)
237 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
241 if (tty
->TS_termcap_modes
)
242 OUTPUT (tty
, tty
->TS_termcap_modes
);
245 /* Output enough newlines to scroll all the old screen contents
246 off the screen, so it won't be overwritten and lost. */
249 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
253 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
254 OUTPUT_IF (tty
, visible_cursor
? tty
->TS_cursor_visible
: tty
->TS_cursor_normal
);
255 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
257 fflush (tty
->output
);
261 /* Reset termcap modes before exiting Emacs. */
264 tty_reset_terminal_modes (struct terminal
*terminal
)
266 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
270 tty_turn_off_highlight (tty
);
271 tty_turn_off_insert (tty
);
272 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
273 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
274 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
275 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
276 /* Output raw CR so kernel can track the cursor hpos. */
279 fflush (tty
->output
);
283 /* Flag the end of a display update on a termcap terminal. */
286 tty_update_end (struct frame
*f
)
288 struct tty_display_info
*tty
= FRAME_TTY (f
);
290 if (!XWINDOW (selected_window
)->cursor_off_p
)
291 tty_show_cursor (tty
);
292 tty_turn_off_insert (tty
);
293 tty_background_highlight (tty
);
296 /* The implementation of set_terminal_window for termcap frames. */
299 tty_set_terminal_window (struct frame
*f
, int size
)
301 struct tty_display_info
*tty
= FRAME_TTY (f
);
303 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
304 if (FRAME_SCROLL_REGION_OK (f
))
305 tty_set_scroll_region (f
, 0, tty
->specified_window
);
309 tty_set_scroll_region (struct frame
*f
, int start
, int stop
)
312 struct tty_display_info
*tty
= FRAME_TTY (f
);
314 if (tty
->TS_set_scroll_region
)
315 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
316 else if (tty
->TS_set_scroll_region_1
)
317 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
318 FRAME_LINES (f
), start
,
319 FRAME_LINES (f
) - stop
,
322 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
331 tty_turn_on_insert (struct tty_display_info
*tty
)
333 if (!tty
->insert_mode
)
334 OUTPUT (tty
, tty
->TS_insert_mode
);
335 tty
->insert_mode
= 1;
339 tty_turn_off_insert (struct tty_display_info
*tty
)
341 if (tty
->insert_mode
)
342 OUTPUT (tty
, tty
->TS_end_insert_mode
);
343 tty
->insert_mode
= 0;
346 /* Handle highlighting. */
349 tty_turn_off_highlight (struct tty_display_info
*tty
)
351 if (tty
->standout_mode
)
352 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
353 tty
->standout_mode
= 0;
357 tty_turn_on_highlight (struct tty_display_info
*tty
)
359 if (!tty
->standout_mode
)
360 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
361 tty
->standout_mode
= 1;
365 tty_toggle_highlight (struct tty_display_info
*tty
)
367 if (tty
->standout_mode
)
368 tty_turn_off_highlight (tty
);
370 tty_turn_on_highlight (tty
);
374 /* Make cursor invisible. */
377 tty_hide_cursor (struct tty_display_info
*tty
)
379 if (tty
->cursor_hidden
== 0)
381 tty
->cursor_hidden
= 1;
382 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
387 /* Ensure that cursor is visible. */
390 tty_show_cursor (struct tty_display_info
*tty
)
392 if (tty
->cursor_hidden
)
394 tty
->cursor_hidden
= 0;
395 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
397 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
402 /* Set standout mode to the state it should be in for
403 empty space inside windows. What this is,
404 depends on the user option inverse-video. */
407 tty_background_highlight (struct tty_display_info
*tty
)
410 tty_turn_on_highlight (tty
);
412 tty_turn_off_highlight (tty
);
415 /* Set standout mode to the mode specified for the text to be output. */
418 tty_highlight_if_desired (struct tty_display_info
*tty
)
421 tty_turn_on_highlight (tty
);
423 tty_turn_off_highlight (tty
);
427 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
428 frame-relative coordinates. */
431 tty_cursor_to (struct frame
*f
, int vpos
, int hpos
)
433 struct tty_display_info
*tty
= FRAME_TTY (f
);
435 /* Detect the case where we are called from reset_sys_modes
436 and the costs have never been calculated. Do nothing. */
437 if (! tty
->costs_set
)
440 if (curY (tty
) == vpos
441 && curX (tty
) == hpos
)
443 if (!tty
->TF_standout_motion
)
444 tty_background_highlight (tty
);
445 if (!tty
->TF_insmode_motion
)
446 tty_turn_off_insert (tty
);
447 cmgoto (tty
, vpos
, hpos
);
450 /* Similar but don't take any account of the wasted characters. */
453 tty_raw_cursor_to (struct frame
*f
, int row
, int col
)
455 struct tty_display_info
*tty
= FRAME_TTY (f
);
457 if (curY (tty
) == row
458 && curX (tty
) == col
)
460 if (!tty
->TF_standout_motion
)
461 tty_background_highlight (tty
);
462 if (!tty
->TF_insmode_motion
)
463 tty_turn_off_insert (tty
);
464 cmgoto (tty
, row
, col
);
467 /* Erase operations */
469 /* Clear from cursor to end of frame on a termcap device. */
472 tty_clear_to_end (struct frame
*f
)
475 struct tty_display_info
*tty
= FRAME_TTY (f
);
477 if (tty
->TS_clr_to_bottom
)
479 tty_background_highlight (tty
);
480 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
484 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
487 clear_end_of_line (f
, FRAME_COLS (f
));
492 /* Clear an entire termcap frame. */
495 tty_clear_frame (struct frame
*f
)
497 struct tty_display_info
*tty
= FRAME_TTY (f
);
499 if (tty
->TS_clr_frame
)
501 tty_background_highlight (tty
);
502 OUTPUT (tty
, tty
->TS_clr_frame
);
512 /* An implementation of clear_end_of_line for termcap frames.
514 Note that the cursor may be moved, on terminals lacking a `ce' string. */
517 tty_clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
520 struct tty_display_info
*tty
= FRAME_TTY (f
);
522 /* Detect the case where we are called from reset_sys_modes
523 and the costs have never been calculated. Do nothing. */
524 if (! tty
->costs_set
)
527 if (curX (tty
) >= first_unused_hpos
)
529 tty_background_highlight (tty
);
530 if (tty
->TS_clr_line
)
532 OUTPUT1 (tty
, tty
->TS_clr_line
);
535 { /* have to do it the hard way */
536 tty_turn_off_insert (tty
);
538 /* Do not write in last row last col with Auto-wrap on. */
540 && curY (tty
) == FrameRows (tty
) - 1
541 && first_unused_hpos
== FrameCols (tty
))
544 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
547 fputc (' ', tty
->termscript
);
548 fputc (' ', tty
->output
);
550 cmplus (tty
, first_unused_hpos
- curX (tty
));
554 /* Buffers to store the source and result of code conversion for terminal. */
555 static unsigned char *encode_terminal_src
;
556 static unsigned char *encode_terminal_dst
;
557 /* Allocated sizes of the above buffers. */
558 static int encode_terminal_src_size
;
559 static int encode_terminal_dst_size
;
561 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
562 Set CODING->produced to the byte-length of the resulting byte
563 sequence, and return a pointer to that byte sequence. */
566 encode_terminal_code (src
, src_len
, coding
)
569 struct coding_system
*coding
;
571 struct glyph
*src_end
= src
+ src_len
;
573 int nchars
, nbytes
, required
;
574 register int tlen
= GLYPH_TABLE_LENGTH
;
575 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
576 Lisp_Object charset_list
;
578 /* Allocate sufficient size of buffer to store all characters in
579 multibyte-form. But, it may be enlarged on demand if
580 Vglyph_table contains a string or a composite glyph is
582 required
= MAX_MULTIBYTE_LENGTH
* src_len
;
583 if (encode_terminal_src_size
< required
)
585 if (encode_terminal_src
)
586 encode_terminal_src
= xrealloc (encode_terminal_src
, required
);
588 encode_terminal_src
= xmalloc (required
);
589 encode_terminal_src_size
= required
;
592 charset_list
= coding_charset_list (coding
);
594 buf
= encode_terminal_src
;
596 while (src
< src_end
)
598 if (src
->type
== COMPOSITE_GLYPH
)
600 struct composition
*cmp
;
604 nbytes
= buf
- encode_terminal_src
;
605 if (src
->u
.cmp
.automatic
)
607 gstring
= composition_gstring_from_id (src
->u
.cmp
.id
);
608 required
= src
->u
.cmp
.to
+ 1 - src
->u
.cmp
.from
;
612 cmp
= composition_table
[src
->u
.cmp
.id
];
613 required
= MAX_MULTIBYTE_LENGTH
* cmp
->glyph_len
;
616 if (encode_terminal_src_size
< nbytes
+ required
)
618 encode_terminal_src_size
= nbytes
+ required
;
619 encode_terminal_src
= xrealloc (encode_terminal_src
,
620 encode_terminal_src_size
);
621 buf
= encode_terminal_src
+ nbytes
;
624 if (src
->u
.cmp
.automatic
)
625 for (i
= src
->u
.cmp
.from
; i
<= src
->u
.cmp
.to
; i
++)
627 Lisp_Object g
= LGSTRING_GLYPH (gstring
, i
);
628 int c
= LGLYPH_CHAR (g
);
630 if (! char_charset (c
, charset_list
, NULL
))
632 buf
+= CHAR_STRING (c
, buf
);
636 for (i
= 0; i
< cmp
->glyph_len
; i
++)
638 int c
= COMPOSITION_GLYPH (cmp
, i
);
642 if (char_charset (c
, charset_list
, NULL
))
644 if (CHAR_WIDTH (c
) == 0
645 && i
> 0 && COMPOSITION_GLYPH (cmp
, i
- 1) == '\t')
646 /* Should be left-padded */
648 buf
+= CHAR_STRING (' ', buf
);
654 buf
+= CHAR_STRING (c
, buf
);
658 /* We must skip glyphs to be padded for a wide character. */
659 else if (! CHAR_GLYPH_PADDING_P (*src
))
666 SET_GLYPH_FROM_CHAR_GLYPH (g
, src
[0]);
668 if (GLYPH_INVALID_P (g
) || GLYPH_SIMPLE_P (tbase
, tlen
, g
))
670 /* This glyph doesn't have an entry in Vglyph_table. */
675 /* This glyph has an entry in Vglyph_table,
676 so process any alias before testing for simpleness. */
677 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
679 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
680 /* We set the multi-byte form of a character in G
681 (that should be an ASCII character) at WORKBUF. */
684 /* We have a string in Vglyph_table. */
685 string
= tbase
[GLYPH_CHAR (g
)];
690 nbytes
= buf
- encode_terminal_src
;
691 if (encode_terminal_src_size
< nbytes
+ MAX_MULTIBYTE_LENGTH
)
693 encode_terminal_src_size
= nbytes
+ MAX_MULTIBYTE_LENGTH
;
694 encode_terminal_src
= xrealloc (encode_terminal_src
,
695 encode_terminal_src_size
);
696 buf
= encode_terminal_src
+ nbytes
;
698 if (CHAR_BYTE8_P (c
))
700 *buf
++ = CHAR_TO_BYTE8 (c
);
703 else if (char_charset (c
, charset_list
, NULL
))
705 /* Store the multibyte form of C at BUF. */
706 buf
+= CHAR_STRING (c
, buf
);
711 /* C is not encodable. */
714 while (src
+ 1 < src_end
&& CHAR_GLYPH_PADDING_P (src
[1]))
724 unsigned char *p
= SDATA (string
), *pend
= p
+ SBYTES (string
);
726 if (! STRING_MULTIBYTE (string
))
727 string
= string_to_multibyte (string
);
728 nbytes
= buf
- encode_terminal_src
;
729 if (encode_terminal_src_size
< nbytes
+ SBYTES (string
))
731 encode_terminal_src_size
= nbytes
+ SBYTES (string
);
732 encode_terminal_src
= xrealloc (encode_terminal_src
,
733 encode_terminal_src_size
);
734 buf
= encode_terminal_src
+ nbytes
;
736 bcopy (SDATA (string
), buf
, SBYTES (string
));
737 buf
+= SBYTES (string
);
738 nchars
+= SCHARS (string
);
746 coding
->produced
= 0;
750 nbytes
= buf
- encode_terminal_src
;
751 coding
->source
= encode_terminal_src
;
752 if (encode_terminal_dst_size
== 0)
754 encode_terminal_dst_size
= encode_terminal_src_size
;
755 if (encode_terminal_dst
)
756 encode_terminal_dst
= xrealloc (encode_terminal_dst
,
757 encode_terminal_dst_size
);
759 encode_terminal_dst
= xmalloc (encode_terminal_dst_size
);
761 coding
->destination
= encode_terminal_dst
;
762 coding
->dst_bytes
= encode_terminal_dst_size
;
763 encode_coding_object (coding
, Qnil
, 0, 0, nchars
, nbytes
, Qnil
);
764 /* coding->destination may have been reallocated. */
765 encode_terminal_dst
= coding
->destination
;
766 encode_terminal_dst_size
= coding
->dst_bytes
;
768 return (encode_terminal_dst
);
773 /* An implementation of write_glyphs for termcap frames. */
776 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
778 unsigned char *conversion_buffer
;
779 struct coding_system
*coding
;
781 struct tty_display_info
*tty
= FRAME_TTY (f
);
783 tty_turn_off_insert (tty
);
784 tty_hide_cursor (tty
);
786 /* Don't dare write in last column of bottom line, if Auto-Wrap,
787 since that would scroll the whole frame on some terminals. */
790 && curY (tty
) + 1 == FRAME_LINES (f
)
791 && (curX (tty
) + len
) == FRAME_COLS (f
))
798 /* If terminal_coding does any conversion, use it, otherwise use
799 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
800 because it always return 1 if the member src_multibyte is 1. */
801 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
802 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
803 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
805 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
809 /* Identify a run of glyphs with the same face. */
810 int face_id
= string
->face_id
;
813 for (n
= 1; n
< len
; ++n
)
814 if (string
[n
].face_id
!= face_id
)
817 /* Turn appearance modes of the face of the run on. */
818 tty_highlight_if_desired (tty
);
819 turn_on_face (f
, face_id
);
822 /* This is the last run. */
823 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
824 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
825 if (coding
->produced
> 0)
828 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
829 if (ferror (tty
->output
))
830 clearerr (tty
->output
);
832 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
838 /* Turn appearance modes off. */
839 turn_off_face (f
, face_id
);
840 tty_turn_off_highlight (tty
);
846 #ifdef HAVE_GPM /* Only used by GPM code. */
849 tty_write_glyphs_with_face (f
, string
, len
, face_id
)
850 register struct frame
*f
;
851 register struct glyph
*string
;
852 register int len
, face_id
;
854 unsigned char *conversion_buffer
;
855 struct coding_system
*coding
;
857 struct tty_display_info
*tty
= FRAME_TTY (f
);
859 tty_turn_off_insert (tty
);
860 tty_hide_cursor (tty
);
862 /* Don't dare write in last column of bottom line, if Auto-Wrap,
863 since that would scroll the whole frame on some terminals. */
866 && curY (tty
) + 1 == FRAME_LINES (f
)
867 && (curX (tty
) + len
) == FRAME_COLS (f
))
874 /* If terminal_coding does any conversion, use it, otherwise use
875 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
876 because it always return 1 if the member src_multibyte is 1. */
877 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
878 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
879 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
881 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
883 /* Turn appearance modes of the face. */
884 tty_highlight_if_desired (tty
);
885 turn_on_face (f
, face_id
);
887 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
888 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
889 if (coding
->produced
> 0)
892 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
893 if (ferror (tty
->output
))
894 clearerr (tty
->output
);
896 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
900 /* Turn appearance modes off. */
901 turn_off_face (f
, face_id
);
902 tty_turn_off_highlight (tty
);
908 /* An implementation of insert_glyphs for termcap frames. */
911 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
914 struct glyph
*glyph
= NULL
;
915 unsigned char *conversion_buffer
;
916 unsigned char space
[1];
917 struct coding_system
*coding
;
919 struct tty_display_info
*tty
= FRAME_TTY (f
);
921 if (tty
->TS_ins_multi_chars
)
923 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
927 write_glyphs (f
, start
, len
);
931 tty_turn_on_insert (tty
);
935 space
[0] = SPACEGLYPH
;
937 /* If terminal_coding does any conversion, use it, otherwise use
938 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
939 because it always return 1 if the member src_multibyte is 1. */
940 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
941 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
942 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
944 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
948 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
951 conversion_buffer
= space
;
952 coding
->produced
= 1;
956 tty_highlight_if_desired (tty
);
957 turn_on_face (f
, start
->face_id
);
960 /* We must open sufficient space for a character which
961 occupies more than one column. */
962 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
964 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
969 /* This is the last glyph. */
970 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
972 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
975 if (coding
->produced
> 0)
978 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
979 if (ferror (tty
->output
))
980 clearerr (tty
->output
);
982 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
986 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
989 turn_off_face (f
, glyph
->face_id
);
990 tty_turn_off_highlight (tty
);
997 /* An implementation of delete_glyphs for termcap frames. */
1000 tty_delete_glyphs (struct frame
*f
, int n
)
1005 struct tty_display_info
*tty
= FRAME_TTY (f
);
1007 if (tty
->delete_in_insert_mode
)
1009 tty_turn_on_insert (tty
);
1013 tty_turn_off_insert (tty
);
1014 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
1017 if (tty
->TS_del_multi_chars
)
1019 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
1024 for (i
= 0; i
< n
; i
++)
1025 OUTPUT1 (tty
, tty
->TS_del_char
);
1026 if (!tty
->delete_in_insert_mode
)
1027 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
1030 /* An implementation of ins_del_lines for termcap frames. */
1033 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
1035 struct tty_display_info
*tty
= FRAME_TTY (f
);
1036 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
1037 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
1038 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
1040 register int i
= n
> 0 ? n
: -n
;
1043 /* If the lines below the insertion are being pushed
1044 into the end of the window, this is the same as clearing;
1045 and we know the lines are already clear, since the matching
1046 deletion has already been done. So can ignore this. */
1047 /* If the lines below the deletion are blank lines coming
1048 out of the end of the window, don't bother,
1049 as there will be a matching inslines later that will flush them. */
1050 if (FRAME_SCROLL_REGION_OK (f
)
1051 && vpos
+ i
>= tty
->specified_window
)
1053 if (!FRAME_MEMORY_BELOW_FRAME (f
)
1054 && vpos
+ i
>= FRAME_LINES (f
))
1059 raw_cursor_to (f
, vpos
, 0);
1060 tty_background_highlight (tty
);
1061 buf
= tparam (multi
, 0, 0, i
);
1067 raw_cursor_to (f
, vpos
, 0);
1068 tty_background_highlight (tty
);
1070 OUTPUT (tty
, single
);
1071 if (tty
->TF_teleray
)
1076 tty_set_scroll_region (f
, vpos
, tty
->specified_window
);
1078 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
1080 raw_cursor_to (f
, vpos
, 0);
1081 tty_background_highlight (tty
);
1083 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1084 tty_set_scroll_region (f
, 0, tty
->specified_window
);
1087 if (!FRAME_SCROLL_REGION_OK (f
)
1088 && FRAME_MEMORY_BELOW_FRAME (f
)
1091 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
1096 /* Compute cost of sending "str", in characters,
1097 not counting any line-dependent padding. */
1100 string_cost (char *str
)
1104 tputs (str
, 0, evalcost
);
1108 /* Compute cost of sending "str", in characters,
1109 counting any line-dependent padding at one line. */
1112 string_cost_one_line (char *str
)
1116 tputs (str
, 1, evalcost
);
1120 /* Compute per line amount of line-dependent padding,
1121 in tenths of characters. */
1124 per_line_cost (char *str
)
1128 tputs (str
, 0, evalcost
);
1131 tputs (str
, 10, evalcost
);
1136 /* char_ins_del_cost[n] is cost of inserting N characters.
1137 char_ins_del_cost[-n] is cost of deleting N characters.
1138 The length of this vector is based on max_frame_cols. */
1140 int *char_ins_del_vector
;
1142 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1147 calculate_ins_del_char_costs (struct frame
*f
)
1149 struct tty_display_info
*tty
= FRAME_TTY (f
);
1150 int ins_startup_cost
, del_startup_cost
;
1151 int ins_cost_per_char
, del_cost_per_char
;
1155 if (tty
->TS_ins_multi_chars
)
1157 ins_cost_per_char
= 0;
1158 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1160 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1161 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1163 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1164 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1165 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1166 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1170 ins_startup_cost
= 9999;
1171 ins_cost_per_char
= 0;
1174 if (tty
->TS_del_multi_chars
)
1176 del_cost_per_char
= 0;
1177 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1179 else if (tty
->TS_del_char
)
1181 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1182 + string_cost (tty
->TS_end_delete_mode
));
1183 if (tty
->delete_in_insert_mode
)
1184 del_startup_cost
/= 2;
1185 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1189 del_startup_cost
= 9999;
1190 del_cost_per_char
= 0;
1193 /* Delete costs are at negative offsets */
1194 p
= &char_ins_del_cost (f
)[0];
1195 for (i
= FRAME_COLS (f
); --i
>= 0;)
1196 *--p
= (del_startup_cost
+= del_cost_per_char
);
1198 /* Doing nothing is free */
1199 p
= &char_ins_del_cost (f
)[0];
1202 /* Insert costs are at positive offsets */
1203 for (i
= FRAME_COLS (f
); --i
>= 0;)
1204 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1208 calculate_costs (struct frame
*frame
)
1210 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1212 if (FRAME_TERMCAP_P (frame
))
1214 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1215 register char *f
= (tty
->TS_set_scroll_region
1216 ? tty
->TS_set_scroll_region
1217 : tty
->TS_set_scroll_region_1
);
1219 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1223 /* These variables are only used for terminal stuff. They are
1224 allocated once for the terminal frame of X-windows emacs, but not
1227 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1228 X turns off char_ins_del_ok. */
1230 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1231 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1233 if (char_ins_del_vector
!= 0)
1235 = (int *) xrealloc (char_ins_del_vector
,
1237 + 2 * max_frame_cols
* sizeof (int)));
1240 = (int *) xmalloc (sizeof (int)
1241 + 2 * max_frame_cols
* sizeof (int));
1243 bzero (char_ins_del_vector
, (sizeof (int)
1244 + 2 * max_frame_cols
* sizeof (int)));
1247 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1248 do_line_insertion_deletion_costs (frame
,
1249 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1250 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1253 do_line_insertion_deletion_costs (frame
,
1254 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1255 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1258 calculate_ins_del_char_costs (frame
);
1260 /* Don't use TS_repeat if its padding is worse than sending the chars */
1261 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1262 tty
->RPov
= string_cost (tty
->TS_repeat
);
1264 tty
->RPov
= FRAME_COLS (frame
) * 2;
1266 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1274 /* Termcap capability names that correspond directly to X keysyms.
1275 Some of these (marked "terminfo") aren't supplied by old-style
1276 (Berkeley) termcap entries. They're listed in X keysym order;
1277 except we put the keypad keys first, so that if they clash with
1278 other keys (as on the IBM PC keyboard) they get overridden.
1281 static struct fkey_table keys
[] =
1283 {"kh", "home"}, /* termcap */
1284 {"kl", "left"}, /* termcap */
1285 {"ku", "up"}, /* termcap */
1286 {"kr", "right"}, /* termcap */
1287 {"kd", "down"}, /* termcap */
1288 {"%8", "prior"}, /* terminfo */
1289 {"%5", "next"}, /* terminfo */
1290 {"@7", "end"}, /* terminfo */
1291 {"@1", "begin"}, /* terminfo */
1292 {"*6", "select"}, /* terminfo */
1293 {"%9", "print"}, /* terminfo */
1294 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1296 * "insert" --- see below
1298 {"&8", "undo"}, /* terminfo */
1299 {"%0", "redo"}, /* terminfo */
1300 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1301 {"@0", "find"}, /* terminfo */
1302 {"@2", "cancel"}, /* terminfo */
1303 {"%1", "help"}, /* terminfo */
1305 * "break" goes here, but can't be reliably intercepted with termcap
1307 {"&4", "reset"}, /* terminfo --- actually `restart' */
1309 * "system" and "user" --- no termcaps
1311 {"kE", "clearline"}, /* terminfo */
1312 {"kA", "insertline"}, /* terminfo */
1313 {"kL", "deleteline"}, /* terminfo */
1314 {"kI", "insertchar"}, /* terminfo */
1315 {"kD", "deletechar"}, /* terminfo */
1316 {"kB", "backtab"}, /* terminfo */
1318 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1320 {"@8", "kp-enter"}, /* terminfo */
1322 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1323 * "kp-multiply", "kp-add", "kp-separator",
1324 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1325 * --- no termcaps for any of these.
1327 {"K4", "kp-1"}, /* terminfo */
1329 * "kp-2" --- no termcap
1331 {"K5", "kp-3"}, /* terminfo */
1333 * "kp-4" --- no termcap
1335 {"K2", "kp-5"}, /* terminfo */
1337 * "kp-6" --- no termcap
1339 {"K1", "kp-7"}, /* terminfo */
1341 * "kp-8" --- no termcap
1343 {"K3", "kp-9"}, /* terminfo */
1345 * "kp-equal" --- no termcap
1357 {"&0", "S-cancel"}, /*shifted cancel key*/
1358 {"&9", "S-begin"}, /*shifted begin key*/
1359 {"*0", "S-find"}, /*shifted find key*/
1360 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1361 {"*4", "S-delete"}, /*shifted delete-character key*/
1362 {"*7", "S-end"}, /*shifted end key*/
1363 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1364 {"#1", "S-help"}, /*shifted help key*/
1365 {"#2", "S-home"}, /*shifted home key*/
1366 {"#3", "S-insert"}, /*shifted insert-character key*/
1367 {"#4", "S-left"}, /*shifted left-arrow key*/
1368 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1369 {"%c", "S-next"}, /*shifted next key*/
1370 {"%e", "S-prior"}, /*shifted previous key*/
1371 {"%f", "S-print"}, /*shifted print key*/
1372 {"%g", "S-redo"}, /*shifted redo key*/
1373 {"%i", "S-right"}, /*shifted right-arrow key*/
1374 {"!3", "S-undo"} /*shifted undo key*/
1377 static char **term_get_fkeys_address
;
1378 static KBOARD
*term_get_fkeys_kboard
;
1379 static Lisp_Object
term_get_fkeys_1 ();
1381 /* Find the escape codes sent by the function keys for Vinput_decode_map.
1382 This function scans the termcap function key sequence entries, and
1383 adds entries to Vinput_decode_map for each function key it finds. */
1386 term_get_fkeys (address
, kboard
)
1390 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1391 errors during the call. The only errors should be from Fdefine_key
1392 when given a key sequence containing an invalid prefix key. If the
1393 termcap defines function keys which use a prefix that is already bound
1394 to a command by the default bindings, we should silently ignore that
1395 function key specification, rather than giving the user an error and
1396 refusing to run at all on such a terminal. */
1398 extern Lisp_Object
Fidentity ();
1399 term_get_fkeys_address
= address
;
1400 term_get_fkeys_kboard
= kboard
;
1401 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1409 char **address
= term_get_fkeys_address
;
1410 KBOARD
*kboard
= term_get_fkeys_kboard
;
1412 /* This can happen if CANNOT_DUMP or with strange options. */
1413 if (!KEYMAPP (kboard
->Vinput_decode_map
))
1414 kboard
->Vinput_decode_map
= Fmake_sparse_keymap (Qnil
);
1416 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1418 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1420 Fdefine_key (kboard
->Vinput_decode_map
, build_string (sequence
),
1421 Fmake_vector (make_number (1),
1422 intern (keys
[i
].name
)));
1425 /* The uses of the "k0" capability are inconsistent; sometimes it
1426 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1427 We will attempt to politely accommodate both systems by testing for
1428 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1431 char *k_semi
= tgetstr ("k;", address
);
1432 char *k0
= tgetstr ("k0", address
);
1433 char *k0_name
= "f10";
1438 /* Define f0 first, so that f10 takes precedence in case the
1439 key sequences happens to be the same. */
1440 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k0
),
1441 Fmake_vector (make_number (1), intern ("f0")));
1442 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k_semi
),
1443 Fmake_vector (make_number (1), intern ("f10")));
1446 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k0
),
1447 Fmake_vector (make_number (1), intern (k0_name
)));
1450 /* Set up cookies for numbered function keys above f10. */
1452 char fcap
[3], fkey
[4];
1454 fcap
[0] = 'F'; fcap
[2] = '\0';
1455 for (i
= 11; i
< 64; i
++)
1458 fcap
[1] = '1' + i
- 11;
1460 fcap
[1] = 'A' + i
- 20;
1462 fcap
[1] = 'a' + i
- 46;
1465 char *sequence
= tgetstr (fcap
, address
);
1468 sprintf (fkey
, "f%d", i
);
1469 Fdefine_key (kboard
->Vinput_decode_map
, build_string (sequence
),
1470 Fmake_vector (make_number (1),
1478 * Various mappings to try and get a better fit.
1481 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1482 if (!tgetstr (cap1, address)) \
1484 char *sequence = tgetstr (cap2, address); \
1486 Fdefine_key (kboard->Vinput_decode_map, build_string (sequence), \
1487 Fmake_vector (make_number (1), \
1491 /* if there's no key_next keycap, map key_npage to `next' keysym */
1492 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1493 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1494 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1495 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1496 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1497 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1498 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1500 /* IBM has their own non-standard dialect of terminfo.
1501 If the standard name isn't found, try the IBM name. */
1502 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1503 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1504 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1505 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1506 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1507 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1508 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1509 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1510 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1511 #undef CONDITIONAL_REASSIGN
1518 /***********************************************************************
1519 Character Display Information
1520 ***********************************************************************/
1522 /* Avoid name clash with functions defined in xterm.c */
1524 #define append_glyph append_glyph_term
1525 #define produce_stretch_glyph produce_stretch_glyph_term
1526 #define append_composite_glyph append_composite_glyph_term
1527 #define produce_composite_glyph produce_composite_glyph_term
1530 static void append_glyph
P_ ((struct it
*));
1531 static void produce_stretch_glyph
P_ ((struct it
*));
1532 static void append_composite_glyph
P_ ((struct it
*));
1533 static void produce_composite_glyph
P_ ((struct it
*));
1535 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1536 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1537 the character for which to produce glyphs; IT->face_id contains the
1538 character's face. Padding glyphs are appended if IT->c has a
1539 IT->pixel_width > 1. */
1545 struct glyph
*glyph
, *end
;
1548 xassert (it
->glyph_row
);
1549 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1550 + it
->glyph_row
->used
[it
->area
]);
1551 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1554 i
< it
->pixel_width
&& glyph
< end
;
1557 glyph
->type
= CHAR_GLYPH
;
1558 glyph
->pixel_width
= 1;
1559 glyph
->u
.ch
= it
->char_to_display
;
1560 glyph
->face_id
= it
->face_id
;
1561 glyph
->padding_p
= i
> 0;
1562 glyph
->charpos
= CHARPOS (it
->position
);
1563 glyph
->object
= it
->object
;
1565 ++it
->glyph_row
->used
[it
->area
];
1571 /* Produce glyphs for the display element described by IT. *IT
1572 specifies what we want to produce a glyph for (character, image, ...),
1573 and where in the glyph matrix we currently are (glyph row and hpos).
1574 produce_glyphs fills in output fields of *IT with information such as the
1575 pixel width and height of a character, and maybe output actual glyphs at
1576 the same time if IT->glyph_row is non-null. For an overview, see
1577 the explanation in dispextern.h, before the definition of the
1578 display_element_type enumeration.
1580 produce_glyphs also stores the result of glyph width, ascent
1581 etc. computations in *IT.
1583 IT->glyph_row may be null, in which case produce_glyphs does not
1584 actually fill in the glyphs. This is used in the move_* functions
1585 in xdisp.c for text width and height computations.
1587 Callers usually don't call produce_glyphs directly;
1588 instead they use the macro PRODUCE_GLYPHS. */
1594 /* If a hook is installed, let it do the work. */
1596 /* Nothing but characters are supported on terminal frames. */
1597 xassert (it
->what
== IT_CHARACTER
1598 || it
->what
== IT_COMPOSITION
1599 || it
->what
== IT_STRETCH
);
1601 if (it
->what
== IT_STRETCH
)
1603 produce_stretch_glyph (it
);
1607 if (it
->what
== IT_COMPOSITION
)
1609 produce_composite_glyph (it
);
1613 /* Maybe translate single-byte characters to multibyte. */
1614 it
->char_to_display
= it
->c
;
1616 if (it
->c
>= 040 && it
->c
< 0177)
1618 it
->pixel_width
= it
->nglyphs
= 1;
1622 else if (it
->c
== '\n')
1623 it
->pixel_width
= it
->nglyphs
= 0;
1624 else if (it
->c
== '\t')
1626 int absolute_x
= (it
->current_x
1627 + it
->continuation_lines_width
);
1629 = (((1 + absolute_x
+ it
->tab_width
- 1)
1634 /* If part of the TAB has been displayed on the previous line
1635 which is continued now, continuation_lines_width will have
1636 been incremented already by the part that fitted on the
1637 continued line. So, we will get the right number of spaces
1639 nspaces
= next_tab_x
- absolute_x
;
1645 it
->char_to_display
= ' ';
1646 it
->pixel_width
= it
->len
= 1;
1652 it
->pixel_width
= nspaces
;
1653 it
->nglyphs
= nspaces
;
1655 else if (CHAR_BYTE8_P (it
->c
))
1657 if (unibyte_display_via_language_environment
1660 it
->char_to_display
= BYTE8_TO_CHAR (it
->c
);
1661 it
->pixel_width
= CHAR_WIDTH (it
->char_to_display
);
1662 it
->nglyphs
= it
->pixel_width
;
1668 /* Coming here means that it->c is from display table, thus
1669 we must send the raw 8-bit byte as is to the terminal.
1670 Although there's no way to know how many columns it
1671 occupies on a screen, it is a good assumption that a
1672 single byte code has 1-column width. */
1673 it
->pixel_width
= it
->nglyphs
= 1;
1680 it
->pixel_width
= CHAR_WIDTH (it
->c
);
1681 it
->nglyphs
= it
->pixel_width
;
1688 /* Advance current_x by the pixel width as a convenience for
1690 if (it
->area
== TEXT_AREA
)
1691 it
->current_x
+= it
->pixel_width
;
1692 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1693 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1697 /* Produce a stretch glyph for iterator IT. IT->object is the value
1698 of the glyph property displayed. The value must be a list
1699 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1702 1. `:width WIDTH' specifies that the space should be WIDTH *
1703 canonical char width wide. WIDTH may be an integer or floating
1706 2. `:align-to HPOS' specifies that the space should be wide enough
1707 to reach HPOS, a value in canonical character units. */
1710 produce_stretch_glyph (it
)
1713 /* (space :width WIDTH ...) */
1714 Lisp_Object prop
, plist
;
1715 int width
= 0, align_to
= -1;
1716 int zero_width_ok_p
= 0;
1719 /* List should start with `space'. */
1720 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1721 plist
= XCDR (it
->object
);
1723 /* Compute the width of the stretch. */
1724 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1725 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1727 /* Absolute width `:width WIDTH' specified and valid. */
1728 zero_width_ok_p
= 1;
1729 width
= (int)(tem
+ 0.5);
1731 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1732 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1734 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1735 align_to
= (align_to
< 0
1737 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1738 else if (align_to
< 0)
1739 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1740 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1741 zero_width_ok_p
= 1;
1744 /* Nothing specified -> width defaults to canonical char width. */
1745 width
= FRAME_COLUMN_WIDTH (it
->f
);
1747 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1750 if (width
> 0 && it
->line_wrap
!= TRUNCATE
1751 && it
->current_x
+ width
> it
->last_visible_x
)
1752 width
= it
->last_visible_x
- it
->current_x
- 1;
1754 if (width
> 0 && it
->glyph_row
)
1756 Lisp_Object o_object
= it
->object
;
1757 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1760 if (!STRINGP (object
))
1761 object
= it
->w
->buffer
;
1762 it
->object
= object
;
1763 it
->char_to_display
= ' ';
1764 it
->pixel_width
= it
->len
= 1;
1767 it
->object
= o_object
;
1769 it
->pixel_width
= width
;
1770 it
->nglyphs
= width
;
1774 /* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
1775 Called from produce_composite_glyph for terminal frames if
1776 IT->glyph_row != NULL. IT->face_id contains the character's
1780 append_composite_glyph (it
)
1783 struct glyph
*glyph
;
1785 xassert (it
->glyph_row
);
1786 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1787 if (glyph
< it
->glyph_row
->glyphs
[1 + it
->area
])
1789 glyph
->type
= COMPOSITE_GLYPH
;
1790 glyph
->pixel_width
= it
->pixel_width
;
1791 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1792 if (it
->cmp_it
.ch
< 0)
1794 glyph
->u
.cmp
.automatic
= 0;
1795 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1799 glyph
->u
.cmp
.automatic
= 1;
1800 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1801 glyph
->u
.cmp
.from
= it
->cmp_it
.from
;
1802 glyph
->u
.cmp
.to
= it
->cmp_it
.to
- 1;
1805 glyph
->face_id
= it
->face_id
;
1806 glyph
->padding_p
= 0;
1807 glyph
->charpos
= CHARPOS (it
->position
);
1808 glyph
->object
= it
->object
;
1810 ++it
->glyph_row
->used
[it
->area
];
1816 /* Produce a composite glyph for iterator IT. IT->cmp_id is the ID of
1817 the composition. We simply produces components of the composition
1818 assuming that the terminal has a capability to layout/render it
1822 produce_composite_glyph (it
)
1827 if (it
->cmp_it
.ch
< 0)
1829 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
1831 it
->pixel_width
= cmp
->width
;
1835 Lisp_Object gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
1837 it
->pixel_width
= composition_gstring_width (gstring
, it
->cmp_it
.from
,
1838 it
->cmp_it
.to
, NULL
);
1842 append_composite_glyph (it
);
1846 /* Get information about special display element WHAT in an
1847 environment described by IT. WHAT is one of IT_TRUNCATION or
1848 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1849 non-null glyph_row member. This function ensures that fields like
1850 face_id, c, len of IT are left untouched. */
1853 produce_special_glyphs (it
, what
)
1855 enum display_element_type what
;
1863 temp_it
.what
= IT_CHARACTER
;
1865 temp_it
.object
= make_number (0);
1866 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1868 if (what
== IT_CONTINUATION
)
1870 /* Continuation glyph. */
1871 SET_GLYPH_FROM_CHAR (glyph
, '\\');
1873 && (gc
= DISP_CONTINUE_GLYPH (it
->dp
), GLYPH_CODE_P (gc
))
1874 && GLYPH_CODE_CHAR_VALID_P (gc
))
1876 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
1877 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
1880 else if (what
== IT_TRUNCATION
)
1882 /* Truncation glyph. */
1883 SET_GLYPH_FROM_CHAR (glyph
, '$');
1885 && (gc
= DISP_TRUNC_GLYPH (it
->dp
), GLYPH_CODE_P (gc
))
1886 && GLYPH_CODE_CHAR_VALID_P (gc
))
1888 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
1889 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
1895 temp_it
.c
= GLYPH_CHAR (glyph
);
1896 temp_it
.face_id
= GLYPH_FACE (glyph
);
1897 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1899 produce_glyphs (&temp_it
);
1900 it
->pixel_width
= temp_it
.pixel_width
;
1901 it
->nglyphs
= temp_it
.pixel_width
;
1906 /***********************************************************************
1908 ***********************************************************************/
1910 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1911 one of the enumerators from enum no_color_bit, or a bit set built
1912 from them. Some display attributes may not be used together with
1913 color; the termcap capability `NC' specifies which ones. */
1915 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1916 (tty->TN_max_colors > 0 \
1917 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1920 /* Turn appearances of face FACE_ID on tty frame F on.
1921 FACE_ID is a realized face ID number, in the face cache. */
1924 turn_on_face (f
, face_id
)
1928 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1929 long fg
= face
->foreground
;
1930 long bg
= face
->background
;
1931 struct tty_display_info
*tty
= FRAME_TTY (f
);
1933 /* Do this first because TS_end_standout_mode may be the same
1934 as TS_exit_attribute_mode, which turns all appearances off. */
1935 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1937 if (tty
->TN_max_colors
> 0)
1939 if (fg
>= 0 && bg
>= 0)
1941 /* If the terminal supports colors, we can set them
1942 below without using reverse video. The face's fg
1943 and bg colors are set as they should appear on
1944 the screen, i.e. they take the inverse-video'ness
1945 of the face already into account. */
1947 else if (inverse_video
)
1949 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1950 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1951 tty_toggle_highlight (tty
);
1955 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1956 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1957 tty_toggle_highlight (tty
);
1962 /* If we can't display colors, use reverse video
1963 if the face specifies that. */
1966 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1967 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1968 tty_toggle_highlight (tty
);
1972 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1973 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1974 tty_toggle_highlight (tty
);
1979 if (face
->tty_bold_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1980 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1982 if (face
->tty_dim_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1983 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1985 /* Alternate charset and blinking not yet used. */
1986 if (face
->tty_alt_charset_p
1987 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1988 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1990 if (face
->tty_blinking_p
1991 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1992 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1994 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1995 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1997 if (tty
->TN_max_colors
> 0)
2001 ts
= tty
->standout_mode
? tty
->TS_set_background
: tty
->TS_set_foreground
;
2004 p
= tparam (ts
, NULL
, 0, (int) fg
);
2009 ts
= tty
->standout_mode
? tty
->TS_set_foreground
: tty
->TS_set_background
;
2012 p
= tparam (ts
, NULL
, 0, (int) bg
);
2020 /* Turn off appearances of face FACE_ID on tty frame F. */
2023 turn_off_face (f
, face_id
)
2027 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2028 struct tty_display_info
*tty
= FRAME_TTY (f
);
2030 xassert (face
!= NULL
);
2032 if (tty
->TS_exit_attribute_mode
)
2034 /* Capability "me" will turn off appearance modes double-bright,
2035 half-bright, reverse-video, standout, underline. It may or
2036 may not turn off alt-char-mode. */
2037 if (face
->tty_bold_p
2039 || face
->tty_reverse_p
2040 || face
->tty_alt_charset_p
2041 || face
->tty_blinking_p
2042 || face
->tty_underline_p
)
2044 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
2045 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
2046 tty
->standout_mode
= 0;
2049 if (face
->tty_alt_charset_p
)
2050 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
2054 /* If we don't have "me" we can only have those appearances
2055 that have exit sequences defined. */
2056 if (face
->tty_alt_charset_p
)
2057 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
2059 if (face
->tty_underline_p
)
2060 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
2063 /* Switch back to default colors. */
2064 if (tty
->TN_max_colors
> 0
2065 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2066 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2067 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2068 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2069 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
2073 /* Return non-zero if the terminal on frame F supports all of the
2074 capabilities in CAPS simultaneously, with foreground and background
2075 colors FG and BG. */
2078 tty_capable_p (tty
, caps
, fg
, bg
)
2079 struct tty_display_info
*tty
;
2081 unsigned long fg
, bg
;
2083 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
2084 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
2087 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
2088 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
2089 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
2090 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
2091 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
2092 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
2098 /* Return non-zero if the terminal is capable to display colors. */
2100 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2102 doc
: /* Return non-nil if the tty device TERMINAL can display colors.
2104 TERMINAL can be a terminal object, a frame, or nil (meaning the
2105 selected frame's terminal). This function always returns nil if
2106 TERMINAL does not refer to a text-only terminal. */)
2108 Lisp_Object terminal
;
2110 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2114 return t
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
2117 /* Return the number of supported colors. */
2118 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2119 Stty_display_color_cells
, 0, 1, 0,
2120 doc
: /* Return the number of colors supported by the tty device TERMINAL.
2122 TERMINAL can be a terminal object, a frame, or nil (meaning the
2123 selected frame's terminal). This function always returns 0 if
2124 TERMINAL does not refer to a text-only terminal. */)
2126 Lisp_Object terminal
;
2128 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2130 return make_number (0);
2132 return make_number (t
->display_info
.tty
->TN_max_colors
);
2137 /* Declare here rather than in the function, as in the rest of Emacs,
2138 to work around an HPUX compiler bug (?). See
2139 http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00410.html */
2140 static int default_max_colors
;
2141 static int default_max_pairs
;
2142 static int default_no_color_video
;
2143 static char *default_orig_pair
;
2144 static char *default_set_foreground
;
2145 static char *default_set_background
;
2147 /* Save or restore the default color-related capabilities of this
2150 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
2155 xfree (default_orig_pair
);
2156 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
2158 xfree (default_set_foreground
);
2159 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
2162 xfree (default_set_background
);
2163 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
2166 default_max_colors
= tty
->TN_max_colors
;
2167 default_max_pairs
= tty
->TN_max_pairs
;
2168 default_no_color_video
= tty
->TN_no_color_video
;
2172 tty
->TS_orig_pair
= default_orig_pair
;
2173 tty
->TS_set_foreground
= default_set_foreground
;
2174 tty
->TS_set_background
= default_set_background
;
2175 tty
->TN_max_colors
= default_max_colors
;
2176 tty
->TN_max_pairs
= default_max_pairs
;
2177 tty
->TN_no_color_video
= default_no_color_video
;
2181 /* Setup one of the standard tty color schemes according to MODE.
2182 MODE's value is generally the number of colors which we want to
2183 support; zero means set up for the default capabilities, the ones
2184 we saw at init_tty time; -1 means turn off color support. */
2186 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2188 /* Canonicalize all negative values of MODE. */
2194 case -1: /* no colors at all */
2195 tty
->TN_max_colors
= 0;
2196 tty
->TN_max_pairs
= 0;
2197 tty
->TN_no_color_video
= 0;
2198 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2200 case 0: /* default colors, if any */
2202 tty_default_color_capabilities (tty
, 0);
2204 case 8: /* 8 standard ANSI colors */
2205 tty
->TS_orig_pair
= "\033[0m";
2207 tty
->TS_set_foreground
= "\033[3%p1%dm";
2208 tty
->TS_set_background
= "\033[4%p1%dm";
2210 tty
->TS_set_foreground
= "\033[3%dm";
2211 tty
->TS_set_background
= "\033[4%dm";
2213 tty
->TN_max_colors
= 8;
2214 tty
->TN_max_pairs
= 64;
2215 tty
->TN_no_color_video
= 0;
2221 set_tty_color_mode (tty
, f
)
2222 struct tty_display_info
*tty
;
2225 Lisp_Object tem
, val
, color_mode_spec
;
2226 Lisp_Object color_mode
;
2228 extern Lisp_Object Qtty_color_mode
;
2229 Lisp_Object tty_color_mode_alist
2230 = Fintern_soft (build_string ("tty-color-mode-alist"), Qnil
);
2232 tem
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2233 val
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2239 tem
= (NILP (tty_color_mode_alist
) ? Qnil
2240 : Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
));
2241 color_mode
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2244 mode
= INTEGERP (color_mode
) ? XINT (color_mode
) : 0;
2246 if (mode
!= tty
->previous_color_mode
)
2248 Lisp_Object funsym
= intern ("tty-set-up-initial-frame-faces");
2249 tty
->previous_color_mode
= mode
;
2250 tty_setup_colors (tty
, mode
);
2251 /* This recomputes all the faces given the new color definitions. */
2252 safe_call (1, &funsym
);
2256 #endif /* !DOS_NT */
2260 /* Return the tty display object specified by TERMINAL. */
2263 get_tty_terminal (Lisp_Object terminal
, int throw)
2265 struct terminal
*t
= get_terminal (terminal
, throw);
2267 if (t
&& t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2270 error ("Device %d is not a termcap terminal device", t
->id
);
2278 /* Return an active termcap device that uses the tty device with the
2281 This function ignores suspended devices.
2283 Returns NULL if the named terminal device is not opened. */
2286 get_named_tty (name
)
2294 for (t
= terminal_list
; t
; t
= t
->next_terminal
)
2296 if ((t
->type
== output_termcap
|| t
->type
== output_msdos_raw
)
2297 && !strcmp (t
->display_info
.tty
->name
, name
)
2298 && TERMINAL_ACTIVE_P (t
))
2306 DEFUN ("tty-type", Ftty_type
, Stty_type
, 0, 1, 0,
2307 doc
: /* Return the type of the tty device that TERMINAL uses.
2308 Returns nil if TERMINAL is not on a tty device.
2310 TERMINAL can be a terminal object, a frame, or nil (meaning the
2311 selected frame's terminal). */)
2313 Lisp_Object terminal
;
2315 struct terminal
*t
= get_terminal (terminal
, 1);
2317 if (t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2320 if (t
->display_info
.tty
->type
)
2321 return build_string (t
->display_info
.tty
->type
);
2326 DEFUN ("controlling-tty-p", Fcontrolling_tty_p
, Scontrolling_tty_p
, 0, 1, 0,
2327 doc
: /* Return non-nil if TERMINAL is the controlling tty of the Emacs process.
2329 TERMINAL can be a terminal object, a frame, or nil (meaning the
2330 selected frame's terminal). This function always returns nil if
2331 TERMINAL is not on a tty device. */)
2333 Lisp_Object terminal
;
2335 struct terminal
*t
= get_terminal (terminal
, 1);
2337 if ((t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2338 || strcmp (t
->display_info
.tty
->name
, DEV_TTY
) != 0)
2344 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 1, 0,
2345 doc
: /* Declare that the tty used by TERMINAL does not handle underlining.
2346 This is used to override the terminfo data, for certain terminals that
2347 do not really do underlining, but say that they do. This function has
2348 no effect if used on a non-tty terminal.
2350 TERMINAL can be a terminal object, a frame or nil (meaning the
2351 selected frame's terminal). This function always returns nil if
2352 TERMINAL does not refer to a text-only terminal. */)
2354 Lisp_Object terminal
;
2356 struct terminal
*t
= get_terminal (terminal
, 1);
2358 if (t
->type
== output_termcap
)
2359 t
->display_info
.tty
->TS_enter_underline_mode
= 0;
2365 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
2366 doc
: /* Suspend the terminal device TTY.
2368 The device is restored to its default state, and Emacs ceases all
2369 access to the tty device. Frames that use the device are not deleted,
2370 but input is not read from them and if they change, their display is
2373 TTY may be a terminal object, a frame, or nil for the terminal device
2374 of the currently selected frame.
2376 This function runs `suspend-tty-functions' after suspending the
2377 device. The functions are run with one arg, the id of the suspended
2380 `suspend-tty' does nothing if it is called on a device that is already
2383 A suspended tty may be resumed by calling `resume-tty' on it. */)
2387 struct terminal
*t
= get_tty_terminal (tty
, 1);
2391 error ("Unknown tty device");
2393 f
= t
->display_info
.tty
->input
;
2397 /* First run `suspend-tty-functions' and then clean up the tty
2398 state because `suspend-tty-functions' might need to change
2400 if (!NILP (Vrun_hooks
))
2402 Lisp_Object args
[2];
2403 args
[0] = intern ("suspend-tty-functions");
2404 XSETTERMINAL (args
[1], t
);
2405 Frun_hook_with_args (2, args
);
2408 reset_sys_modes (t
->display_info
.tty
);
2411 delete_keyboard_wait_descriptor (fileno (f
));
2416 if (f
!= t
->display_info
.tty
->output
)
2417 fclose (t
->display_info
.tty
->output
);
2420 t
->display_info
.tty
->input
= 0;
2421 t
->display_info
.tty
->output
= 0;
2423 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2424 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 0);
2428 /* Clear display hooks to prevent further output. */
2429 clear_tty_hooks (t
);
2434 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
2435 doc
: /* Resume the previously suspended terminal device TTY.
2436 The terminal is opened and reinitialized. Frames that are on the
2437 suspended terminal are revived.
2439 It is an error to resume a terminal while another terminal is active
2442 This function runs `resume-tty-functions' after resuming the terminal.
2443 The functions are run with one arg, the id of the resumed terminal
2446 `resume-tty' does nothing if it is called on a device that is not
2449 TTY may be a terminal object, a frame, or nil (meaning the selected
2450 frame's terminal). */)
2454 struct terminal
*t
= get_tty_terminal (tty
, 1);
2458 error ("Unknown tty device");
2460 if (!t
->display_info
.tty
->input
)
2462 if (get_named_tty (t
->display_info
.tty
->name
))
2463 error ("Cannot resume display while another display is active on the same device");
2466 t
->display_info
.tty
->output
= stdout
;
2467 t
->display_info
.tty
->input
= stdin
;
2469 fd
= emacs_open (t
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
2472 error ("Can not reopen tty device %s: %s", t
->display_info
.tty
->name
, strerror (errno
));
2474 if (strcmp (t
->display_info
.tty
->name
, DEV_TTY
))
2475 dissociate_if_controlling_tty (fd
);
2477 t
->display_info
.tty
->output
= fdopen (fd
, "w+");
2478 t
->display_info
.tty
->input
= t
->display_info
.tty
->output
;
2482 add_keyboard_wait_descriptor (fd
);
2485 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2487 struct frame
*f
= XFRAME (t
->display_info
.tty
->top_frame
);
2489 int old_height
= FRAME_COLS (f
);
2490 int old_width
= FRAME_LINES (f
);
2492 /* Check if terminal/window size has changed while the frame
2494 get_tty_size (fileno (t
->display_info
.tty
->input
), &width
, &height
);
2495 if (width
!= old_width
|| height
!= old_height
)
2496 change_frame_size (f
, height
, width
, 0, 0, 0);
2497 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 1);
2500 init_sys_modes (t
->display_info
.tty
);
2502 /* Run `resume-tty-functions'. */
2503 if (!NILP (Vrun_hooks
))
2505 Lisp_Object args
[2];
2506 args
[0] = intern ("resume-tty-functions");
2507 XSETTERMINAL (args
[1], t
);
2508 Frun_hook_with_args (2, args
);
2518 /***********************************************************************
2520 ***********************************************************************/
2524 term_mouse_moveto (int x
, int y
)
2526 /* TODO: how to set mouse position?
2529 name = (const char *) ttyname (0);
2530 fd = open (name, O_WRONLY);
2531 SOME_FUNCTION (x, y, fd);
2534 last_mouse_y = y; */
2538 term_show_mouse_face (enum draw_glyphs_face draw
)
2540 struct window
*w
= XWINDOW (mouse_face_window
);
2544 struct frame
*f
= XFRAME (w
->frame
);
2545 struct tty_display_info
*tty
= FRAME_TTY (f
);
2547 if (/* If window is in the process of being destroyed, don't bother
2549 w
->current_matrix
!= NULL
2550 /* Recognize when we are called to operate on rows that don't exist
2551 anymore. This can happen when a window is split. */
2552 && mouse_face_end_row
< w
->current_matrix
->nrows
)
2554 /* write_glyphs writes at cursor position, so we need to
2555 temporarily move cursor coordinates to the beginning of
2556 the highlight region. */
2558 /* Save current cursor co-ordinates */
2559 save_y
= curY (tty
);
2560 save_x
= curX (tty
);
2562 /* Note that mouse_face_beg_row etc. are window relative. */
2563 for (i
= mouse_face_beg_row
; i
<= mouse_face_end_row
; i
++)
2565 int start_hpos
, end_hpos
, nglyphs
;
2566 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
2568 /* Don't do anything if row doesn't have valid contents. */
2569 if (!row
->enabled_p
)
2572 /* For all but the first row, the highlight starts at column 0. */
2573 if (i
== mouse_face_beg_row
)
2574 start_hpos
= mouse_face_beg_col
;
2578 if (i
== mouse_face_end_row
)
2579 end_hpos
= mouse_face_end_col
;
2582 end_hpos
= row
->used
[TEXT_AREA
];
2583 if (draw
== DRAW_NORMAL_TEXT
)
2584 row
->fill_line_p
= 1; /* Clear to end of line */
2587 if (end_hpos
<= start_hpos
)
2589 /* Record that some glyphs of this row are displayed in
2591 row
->mouse_face_p
= draw
> 0;
2593 nglyphs
= end_hpos
- start_hpos
;
2595 if (end_hpos
>= row
->used
[TEXT_AREA
])
2596 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2598 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2599 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
2600 + WINDOW_LEFT_EDGE_X (w
);
2602 cursor_to (f
, pos_y
, pos_x
);
2604 if (draw
== DRAW_MOUSE_FACE
)
2606 tty_write_glyphs_with_face (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
,
2607 nglyphs
, mouse_face_face_id
);
2609 else /* draw == DRAW_NORMAL_TEXT */
2610 write_glyphs (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2612 cursor_to (f
, save_y
, save_x
);
2617 term_clear_mouse_face ()
2619 if (!NILP (mouse_face_window
))
2620 term_show_mouse_face (DRAW_NORMAL_TEXT
);
2622 mouse_face_beg_row
= mouse_face_beg_col
= -1;
2623 mouse_face_end_row
= mouse_face_end_col
= -1;
2624 mouse_face_window
= Qnil
;
2627 /* Find the glyph matrix position of buffer position POS in window W.
2628 *HPOS and *VPOS are set to the positions found. W's current glyphs
2629 must be up to date. If POS is above window start return (0, 0).
2630 If POS is after end of W, return end of last line in W.
2631 - taken from msdos.c */
2633 fast_find_position (struct window
*w
, int pos
, int *hpos
, int *vpos
)
2635 int i
, lastcol
, line_start_position
, maybe_next_line_p
= 0;
2636 int yb
= window_text_bottom_y (w
);
2637 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0), *best_row
= row
;
2641 if (row
->used
[TEXT_AREA
])
2642 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
2644 line_start_position
= 0;
2646 if (line_start_position
> pos
)
2648 /* If the position sought is the end of the buffer,
2649 don't include the blank lines at the bottom of the window. */
2650 else if (line_start_position
== pos
2651 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
2653 maybe_next_line_p
= 1;
2656 else if (line_start_position
> 0)
2659 /* Don't overstep the last matrix row, lest we get into the
2660 never-never land... */
2661 if (row
->y
+ 1 >= yb
)
2667 /* Find the right column within BEST_ROW. */
2670 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
2672 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + i
;
2675 charpos
= glyph
->charpos
;
2682 else if (charpos
> pos
)
2684 else if (charpos
> 0)
2688 /* If we're looking for the end of the buffer,
2689 and we didn't find it in the line we scanned,
2690 use the start of the following line. */
2691 if (maybe_next_line_p
)
2698 *hpos
= lastcol
+ 1;
2703 term_mouse_highlight (struct frame
*f
, int x
, int y
)
2705 enum window_part part
;
2710 if (NILP (Vmouse_highlight
)
2711 || !f
->glyphs_initialized_p
)
2714 /* Which window is that in? */
2715 window
= window_from_coordinates (f
, x
, y
, &part
, &x
, &y
, 0);
2717 /* Not on a window -> return. */
2718 if (!WINDOWP (window
))
2721 if (!EQ (window
, mouse_face_window
))
2722 term_clear_mouse_face ();
2724 w
= XWINDOW (window
);
2726 /* Are we in a window whose display is up to date?
2727 And verify the buffer's text has not changed. */
2728 b
= XBUFFER (w
->buffer
);
2730 && EQ (w
->window_end_valid
, w
->buffer
)
2731 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
2732 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
2734 int pos
, i
, nrows
= w
->current_matrix
->nrows
;
2735 struct glyph_row
*row
;
2736 struct glyph
*glyph
;
2738 /* Find the glyph under X/Y. */
2740 if (y
>= 0 && y
< nrows
)
2742 row
= MATRIX_ROW (w
->current_matrix
, y
);
2743 /* Give up if some row before the one we are looking for is
2745 for (i
= 0; i
<= y
; i
++)
2746 if (!MATRIX_ROW (w
->current_matrix
, i
)->enabled_p
)
2748 if (i
> y
/* all rows upto and including the one at Y are enabled */
2749 && row
->displays_text_p
2750 && x
< window_box_width (w
, TEXT_AREA
))
2752 glyph
= row
->glyphs
[TEXT_AREA
];
2753 if (x
>= row
->used
[TEXT_AREA
])
2758 if (!BUFFERP (glyph
->object
))
2764 /* Clear mouse face if X/Y not over text. */
2767 term_clear_mouse_face ();
2771 if (!BUFFERP (glyph
->object
))
2773 pos
= glyph
->charpos
;
2775 /* Check for mouse-face. */
2777 extern Lisp_Object Qmouse_face
;
2778 Lisp_Object mouse_face
, overlay
, position
, *overlay_vec
;
2779 int noverlays
, obegv
, ozv
;
2780 struct buffer
*obuf
;
2782 /* If we get an out-of-range value, return now; avoid an error. */
2783 if (pos
> BUF_Z (b
))
2786 /* Make the window's buffer temporarily current for
2787 overlays_at and compute_char_face. */
2788 obuf
= current_buffer
;
2795 /* Is this char mouse-active? */
2796 XSETINT (position
, pos
);
2798 /* Put all the overlays we want in a vector in overlay_vec. */
2799 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
2800 /* Sort overlays into increasing priority order. */
2801 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
2803 /* Check mouse-face highlighting. */
2804 if (!(EQ (window
, mouse_face_window
)
2805 && y
>= mouse_face_beg_row
2806 && y
<= mouse_face_end_row
2807 && (y
> mouse_face_beg_row
2808 || x
>= mouse_face_beg_col
)
2809 && (y
< mouse_face_end_row
2810 || x
< mouse_face_end_col
2811 || mouse_face_past_end
)))
2813 /* Clear the display of the old active region, if any. */
2814 term_clear_mouse_face ();
2816 /* Find the highest priority overlay that has a mouse-face
2819 for (i
= noverlays
- 1; i
>= 0; --i
)
2821 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
2822 if (!NILP (mouse_face
))
2824 overlay
= overlay_vec
[i
];
2829 /* If no overlay applies, get a text property. */
2831 mouse_face
= Fget_text_property (position
, Qmouse_face
,
2834 /* Handle the overlay case. */
2835 if (!NILP (overlay
))
2837 /* Find the range of text around this char that
2838 should be active. */
2839 Lisp_Object before
, after
;
2843 before
= Foverlay_start (overlay
);
2844 after
= Foverlay_end (overlay
);
2845 /* Record this as the current active region. */
2846 fast_find_position (w
, XFASTINT (before
),
2847 &mouse_face_beg_col
,
2848 &mouse_face_beg_row
);
2851 = !fast_find_position (w
, XFASTINT (after
),
2852 &mouse_face_end_col
,
2853 &mouse_face_end_row
);
2854 mouse_face_window
= window
;
2857 = face_at_buffer_position (w
, pos
, 0, 0,
2858 &ignore
, pos
+ 1, 1, -1);
2860 /* Display it as active. */
2861 term_show_mouse_face (DRAW_MOUSE_FACE
);
2863 /* Handle the text property case. */
2864 else if (!NILP (mouse_face
))
2866 /* Find the range of text around this char that
2867 should be active. */
2868 Lisp_Object before
, after
, beginning
, end
;
2871 beginning
= Fmarker_position (w
->start
);
2872 XSETINT (end
, (BUF_Z (b
) - XFASTINT (w
->window_end_pos
)));
2874 = Fprevious_single_property_change (make_number (pos
+ 1),
2876 w
->buffer
, beginning
);
2878 = Fnext_single_property_change (position
, Qmouse_face
,
2881 /* Record this as the current active region. */
2882 fast_find_position (w
, XFASTINT (before
),
2883 &mouse_face_beg_col
,
2884 &mouse_face_beg_row
);
2886 = !fast_find_position (w
, XFASTINT (after
),
2887 &mouse_face_end_col
,
2888 &mouse_face_end_row
);
2889 mouse_face_window
= window
;
2892 = face_at_buffer_position (w
, pos
, 0, 0,
2893 &ignore
, pos
+ 1, 1, -1);
2895 /* Display it as active. */
2896 term_show_mouse_face (DRAW_MOUSE_FACE
);
2900 /* Look for a `help-echo' property. */
2903 extern Lisp_Object Qhelp_echo
;
2905 /* Check overlays first. */
2907 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
2909 overlay
= overlay_vec
[i
];
2910 help
= Foverlay_get (overlay
, Qhelp_echo
);
2915 help_echo_string
= help
;
2916 help_echo_window
= window
;
2917 help_echo_object
= overlay
;
2918 help_echo_pos
= pos
;
2920 /* Try text properties. */
2921 else if (NILP (help
)
2922 && ((STRINGP (glyph
->object
)
2923 && glyph
->charpos
>= 0
2924 && glyph
->charpos
< SCHARS (glyph
->object
))
2925 || (BUFFERP (glyph
->object
)
2926 && glyph
->charpos
>= BEGV
2927 && glyph
->charpos
< ZV
)))
2929 help
= Fget_text_property (make_number (glyph
->charpos
),
2930 Qhelp_echo
, glyph
->object
);
2933 help_echo_string
= help
;
2934 help_echo_window
= window
;
2935 help_echo_object
= glyph
->object
;
2936 help_echo_pos
= glyph
->charpos
;
2943 current_buffer
= obuf
;
2949 term_mouse_movement (FRAME_PTR frame
, Gpm_Event
*event
)
2951 /* Has the mouse moved off the glyph it was on at the last sighting? */
2952 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2954 frame
->mouse_moved
= 1;
2955 term_mouse_highlight (frame
, event
->x
, event
->y
);
2956 /* Remember which glyph we're now on. */
2957 last_mouse_x
= event
->x
;
2958 last_mouse_y
= event
->y
;
2964 /* Return the current position of the mouse.
2966 Set *f to the frame the mouse is in, or zero if the mouse is in no
2967 Emacs frame. If it is set to zero, all the other arguments are
2970 Set *bar_window to Qnil, and *x and *y to the column and
2971 row of the character cell the mouse is over.
2973 Set *time to the time the mouse was at the returned position.
2975 This clears mouse_moved until the next motion
2978 term_mouse_position (FRAME_PTR
*fp
, int insist
, Lisp_Object
*bar_window
,
2979 enum scroll_bar_part
*part
, Lisp_Object
*x
,
2980 Lisp_Object
*y
, unsigned long *time
)
2984 *fp
= SELECTED_FRAME ();
2985 (*fp
)->mouse_moved
= 0;
2990 XSETINT (*x
, last_mouse_x
);
2991 XSETINT (*y
, last_mouse_y
);
2992 gettimeofday(&now
, 0);
2993 *time
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2996 /* Prepare a mouse-event in *RESULT for placement in the input queue.
2998 If the event is a button press, then note that we have grabbed
3002 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
3008 result
->kind
= GPM_CLICK_EVENT
;
3009 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
3011 if (event
->buttons
& j
) {
3012 result
->code
= i
; /* button number */
3016 gettimeofday(&now
, 0);
3017 result
->timestamp
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
3019 if (event
->type
& GPM_UP
)
3020 result
->modifiers
= up_modifier
;
3021 else if (event
->type
& GPM_DOWN
)
3022 result
->modifiers
= down_modifier
;
3024 result
->modifiers
= 0;
3026 if (event
->type
& GPM_SINGLE
)
3027 result
->modifiers
|= click_modifier
;
3029 if (event
->type
& GPM_DOUBLE
)
3030 result
->modifiers
|= double_modifier
;
3032 if (event
->type
& GPM_TRIPLE
)
3033 result
->modifiers
|= triple_modifier
;
3035 if (event
->type
& GPM_DRAG
)
3036 result
->modifiers
|= drag_modifier
;
3038 if (!(event
->type
& (GPM_MOVE
| GPM_DRAG
))) {
3041 if (event
->modifiers
& (1 << 0))
3042 result
->modifiers
|= shift_modifier
;
3045 if (event
->modifiers
& (1 << 2))
3046 result
->modifiers
|= ctrl_modifier
;
3048 /* 1 << KG_ALT || KG_ALTGR */
3049 if (event
->modifiers
& (1 << 3)
3050 || event
->modifiers
& (1 << 1))
3051 result
->modifiers
|= meta_modifier
;
3054 XSETINT (result
->x
, event
->x
);
3055 XSETINT (result
->y
, event
->y
);
3056 XSETFRAME (result
->frame_or_window
, f
);
3062 handle_one_term_event (struct tty_display_info
*tty
, Gpm_Event
*event
, struct input_event
* hold_quit
)
3064 struct frame
*f
= XFRAME (tty
->top_frame
);
3065 struct input_event ie
;
3073 if (event
->type
& (GPM_MOVE
| GPM_DRAG
)) {
3074 previous_help_echo_string
= help_echo_string
;
3075 help_echo_string
= Qnil
;
3077 Gpm_DrawPointer (event
->x
, event
->y
, fileno (tty
->output
));
3079 if (!term_mouse_movement (f
, event
))
3080 help_echo_string
= previous_help_echo_string
;
3082 /* If the contents of the global variable help_echo_string
3083 has changed, generate a HELP_EVENT. */
3084 if (!NILP (help_echo_string
)
3085 || !NILP (previous_help_echo_string
))
3092 term_mouse_click (&ie
, event
, f
);
3096 if (ie
.kind
!= NO_EVENT
)
3098 kbd_buffer_store_event_hold (&ie
, hold_quit
);
3103 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
3108 XSETFRAME (frame
, f
);
3112 gen_help_event (help_echo_string
, frame
, help_echo_window
,
3113 help_echo_object
, help_echo_pos
);
3120 DEFUN ("gpm-mouse-start", Fgpm_mouse_start
, Sgpm_mouse_start
,
3122 doc
: /* Open a connection to Gpm.
3123 Gpm-mouse can only be activated for one tty at a time. */)
3126 struct frame
*f
= SELECTED_FRAME ();
3127 struct tty_display_info
*tty
3128 = ((f
)->output_method
== output_termcap
3129 ? (f
)->terminal
->display_info
.tty
: NULL
);
3130 Gpm_Connect connection
;
3133 error ("Gpm-mouse only works in the GNU/Linux console");
3135 return Qnil
; /* Already activated, nothing to do. */
3137 error ("Gpm-mouse can only be activated for one tty at a time");
3139 connection
.eventMask
= ~0;
3140 connection
.defaultMask
= ~GPM_HARD
;
3141 connection
.maxMod
= ~0;
3142 connection
.minMod
= 0;
3145 if (Gpm_Open (&connection
, 0) < 0)
3146 error ("Gpm-mouse failed to connect to the gpm daemon");
3150 /* `init_sys_modes' arranges for mouse movements sent through gpm_fd
3151 to generate SIGIOs. Apparently we need to call reset_sys_modes
3152 before calling init_sys_modes. */
3153 reset_sys_modes (tty
);
3154 init_sys_modes (tty
);
3155 add_gpm_wait_descriptor (gpm_fd
);
3164 delete_gpm_wait_descriptor (fd
);
3165 while (Gpm_Close()); /* close all the stack */
3169 DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop
, Sgpm_mouse_stop
,
3171 doc
: /* Close a connection to Gpm. */)
3174 struct frame
*f
= SELECTED_FRAME ();
3175 struct tty_display_info
*tty
3176 = ((f
)->output_method
== output_termcap
3177 ? (f
)->terminal
->display_info
.tty
: NULL
);
3179 if (!tty
|| gpm_tty
!= tty
)
3180 return Qnil
; /* Not activated on this terminal, nothing to do. */
3185 #endif /* HAVE_GPM */
3189 /***********************************************************************
3191 ***********************************************************************/
3193 /* Initialize the tty-dependent part of frame F. The frame must
3194 already have its device initialized. */
3197 create_tty_output (struct frame
*f
)
3199 struct tty_output
*t
;
3201 if (! FRAME_TERMCAP_P (f
))
3204 t
= xmalloc (sizeof (struct tty_output
));
3205 bzero (t
, sizeof (struct tty_output
));
3207 t
->display_info
= FRAME_TERMINAL (f
)->display_info
.tty
;
3209 f
->output_data
.tty
= t
;
3212 /* Delete frame F's face cache, and its tty-dependent part. */
3215 tty_free_frame_resources (struct frame
*f
)
3217 if (! FRAME_TERMCAP_P (f
))
3220 if (FRAME_FACE_CACHE (f
))
3221 free_frame_faces (f
);
3223 xfree (f
->output_data
.tty
);
3228 /* Delete frame F's face cache. */
3231 tty_free_frame_resources (struct frame
*f
)
3233 if (! FRAME_TERMCAP_P (f
) && ! FRAME_MSDOS_P (f
))
3236 if (FRAME_FACE_CACHE (f
))
3237 free_frame_faces (f
);
3241 /* Reset the hooks in TERMINAL. */
3244 clear_tty_hooks (struct terminal
*terminal
)
3247 terminal
->cursor_to_hook
= 0;
3248 terminal
->raw_cursor_to_hook
= 0;
3249 terminal
->clear_to_end_hook
= 0;
3250 terminal
->clear_frame_hook
= 0;
3251 terminal
->clear_end_of_line_hook
= 0;
3252 terminal
->ins_del_lines_hook
= 0;
3253 terminal
->insert_glyphs_hook
= 0;
3254 terminal
->write_glyphs_hook
= 0;
3255 terminal
->delete_glyphs_hook
= 0;
3256 terminal
->ring_bell_hook
= 0;
3257 terminal
->reset_terminal_modes_hook
= 0;
3258 terminal
->set_terminal_modes_hook
= 0;
3259 terminal
->update_begin_hook
= 0;
3260 terminal
->update_end_hook
= 0;
3261 terminal
->set_terminal_window_hook
= 0;
3262 terminal
->mouse_position_hook
= 0;
3263 terminal
->frame_rehighlight_hook
= 0;
3264 terminal
->frame_raise_lower_hook
= 0;
3265 terminal
->fullscreen_hook
= 0;
3266 terminal
->set_vertical_scroll_bar_hook
= 0;
3267 terminal
->condemn_scroll_bars_hook
= 0;
3268 terminal
->redeem_scroll_bar_hook
= 0;
3269 terminal
->judge_scroll_bars_hook
= 0;
3270 terminal
->read_socket_hook
= 0;
3271 terminal
->frame_up_to_date_hook
= 0;
3273 /* Leave these two set, or suspended frames are not deleted
3275 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3276 terminal
->delete_terminal_hook
= &delete_tty
;
3279 /* Initialize hooks in TERMINAL with the values needed for a tty. */
3282 set_tty_hooks (struct terminal
*terminal
)
3284 terminal
->rif
= 0; /* ttys don't support window-based redisplay. */
3286 terminal
->cursor_to_hook
= &tty_cursor_to
;
3287 terminal
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
3289 terminal
->clear_to_end_hook
= &tty_clear_to_end
;
3290 terminal
->clear_frame_hook
= &tty_clear_frame
;
3291 terminal
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
3293 terminal
->ins_del_lines_hook
= &tty_ins_del_lines
;
3295 terminal
->insert_glyphs_hook
= &tty_insert_glyphs
;
3296 terminal
->write_glyphs_hook
= &tty_write_glyphs
;
3297 terminal
->delete_glyphs_hook
= &tty_delete_glyphs
;
3299 terminal
->ring_bell_hook
= &tty_ring_bell
;
3301 terminal
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
3302 terminal
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
3303 terminal
->update_begin_hook
= 0; /* Not needed. */
3304 terminal
->update_end_hook
= &tty_update_end
;
3305 terminal
->set_terminal_window_hook
= &tty_set_terminal_window
;
3307 terminal
->mouse_position_hook
= 0; /* Not needed. */
3308 terminal
->frame_rehighlight_hook
= 0; /* Not needed. */
3309 terminal
->frame_raise_lower_hook
= 0; /* Not needed. */
3311 terminal
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
3312 terminal
->condemn_scroll_bars_hook
= 0; /* Not needed. */
3313 terminal
->redeem_scroll_bar_hook
= 0; /* Not needed. */
3314 terminal
->judge_scroll_bars_hook
= 0; /* Not needed. */
3316 terminal
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
3317 terminal
->frame_up_to_date_hook
= 0; /* Not needed. */
3319 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3320 terminal
->delete_terminal_hook
= &delete_tty
;
3323 /* Drop the controlling terminal if fd is the same device. */
3325 dissociate_if_controlling_tty (int fd
)
3329 EMACS_GET_TTY_PGRP (fd
, &pgid
); /* If tcgetpgrp succeeds, fd is the ctty. */
3332 #if defined (USG) && !defined (BSD_PGRPS)
3334 no_controlling_tty
= 1;
3335 #elif defined (CYGWIN)
3337 no_controlling_tty
= 1;
3339 #ifdef TIOCNOTTY /* Try BSD ioctls. */
3340 sigblock (sigmask (SIGTTOU
));
3341 fd
= emacs_open (DEV_TTY
, O_RDWR
, 0);
3342 if (fd
!= -1 && ioctl (fd
, TIOCNOTTY
, 0) != -1)
3344 no_controlling_tty
= 1;
3348 sigunblock (sigmask (SIGTTOU
));
3350 /* Unknown system. */
3352 #endif /* ! TIOCNOTTY */
3355 #endif /* !DOS_NT */
3358 static void maybe_fatal();
3360 /* Create a termcap display on the tty device with the given name and
3363 If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
3364 Otherwise NAME should be a path to the tty device file,
3367 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
3369 If MUST_SUCCEED is true, then all errors are fatal. */
3372 init_tty (char *name
, char *terminal_type
, int must_succeed
)
3375 char **address
= &area
;
3376 int buffer_size
= 4096;
3377 register char *p
= NULL
;
3379 struct tty_display_info
*tty
= NULL
;
3380 struct terminal
*terminal
= NULL
;
3381 int ctty
= 0; /* 1 if asked to open controlling tty. */
3384 maybe_fatal (must_succeed
, 0,
3385 "Unknown terminal type",
3386 "Unknown terminal type");
3390 if (!strcmp (name
, DEV_TTY
))
3393 /* If we already have a terminal on the given device, use that. If
3394 all such terminals are suspended, create a new one instead. */
3395 /* XXX Perhaps this should be made explicit by having init_tty
3396 always create a new terminal and separating terminal and frame
3397 creation on Lisp level. */
3398 terminal
= get_named_tty (name
);
3402 terminal
= create_terminal ();
3405 maybe_fatal (1, 0, "Attempt to create another terminal %s", "",
3408 tty
= &the_only_display_info
;
3410 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
3412 bzero (tty
, sizeof (struct tty_display_info
));
3413 tty
->next
= tty_list
;
3416 terminal
->type
= output_termcap
;
3417 terminal
->display_info
.tty
= tty
;
3418 tty
->terminal
= terminal
;
3420 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
3424 set_tty_hooks (terminal
);
3430 #ifdef O_IGNORE_CTTY
3432 /* Open the terminal device. Don't recognize it as our
3433 controlling terminal, and don't make it the controlling tty
3434 if we don't have one at the moment. */
3435 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
3438 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
3439 defined on Hurd. On other systems, we need to explicitly
3440 dissociate ourselves from the controlling tty when we want to
3441 open a frame on the same terminal. */
3442 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
3443 #endif /* O_IGNORE_CTTY */
3445 tty
->name
= xstrdup (name
);
3446 terminal
->name
= xstrdup (name
);
3449 maybe_fatal (must_succeed
, terminal
,
3450 "Could not open file: %s",
3451 "Could not open file: %s",
3456 maybe_fatal (must_succeed
, terminal
,
3457 "Not a tty device: %s",
3458 "Not a tty device: %s",
3462 #ifndef O_IGNORE_CTTY
3464 dissociate_if_controlling_tty (fd
);
3467 file
= fdopen (fd
, "w+");
3472 tty
->type
= xstrdup (terminal_type
);
3474 add_keyboard_wait_descriptor (fileno (tty
->input
));
3476 #endif /* !DOS_NT */
3478 encode_terminal_src_size
= 0;
3479 encode_terminal_dst_size
= 0;
3482 terminal
->mouse_position_hook
= term_mouse_position
;
3483 mouse_face_window
= Qnil
;
3488 initialize_w32_display (terminal
);
3490 if (strcmp (terminal_type
, "internal") == 0)
3491 terminal
->type
= output_msdos_raw
;
3492 initialize_msdos_display (terminal
);
3494 tty
->output
= stdout
;
3496 /* The following two are inaccessible from w32console.c. */
3497 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3498 terminal
->delete_terminal_hook
= &delete_tty
;
3500 tty
->name
= xstrdup (name
);
3501 terminal
->name
= xstrdup (name
);
3502 tty
->type
= xstrdup (terminal_type
);
3505 add_keyboard_wait_descriptor (0);
3512 struct frame
*f
= XFRAME (selected_frame
);
3514 FrameRows (tty
) = FRAME_LINES (f
);
3515 FrameCols (tty
) = FRAME_COLS (f
);
3516 tty
->specified_window
= FRAME_LINES (f
);
3518 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
3519 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
3524 get_tty_size (fileno (tty
->input
), &width
, &height
);
3525 FrameCols (tty
) = width
;
3526 FrameRows (tty
) = height
;
3529 tty
->delete_in_insert_mode
= 1;
3532 terminal
->scroll_region_ok
= 0;
3534 /* Seems to insert lines when it's not supposed to, messing up the
3535 display. In doing a trace, it didn't seem to be called much, so I
3536 don't think we're losing anything by turning it off. */
3537 terminal
->line_ins_del_ok
= 0;
3539 terminal
->char_ins_del_ok
= 1;
3542 terminal
->char_ins_del_ok
= 0;
3543 init_baud_rate (fileno (tty
->input
));
3546 tty
->TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
3548 #else /* not DOS_NT */
3552 tty
->termcap_term_buffer
= (char *) xmalloc (buffer_size
);
3554 /* On some systems, tgetent tries to access the controlling
3556 sigblock (sigmask (SIGTTOU
));
3557 status
= tgetent (tty
->termcap_term_buffer
, terminal_type
);
3558 sigunblock (sigmask (SIGTTOU
));
3563 maybe_fatal (must_succeed
, terminal
,
3564 "Cannot open terminfo database file",
3565 "Cannot open terminfo database file");
3567 maybe_fatal (must_succeed
, terminal
,
3568 "Cannot open termcap database file",
3569 "Cannot open termcap database file");
3575 maybe_fatal (must_succeed
, terminal
,
3576 "Terminal type %s is not defined",
3577 "Terminal type %s is not defined.\n\
3578 If that is not the actual type of terminal you have,\n\
3579 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3580 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3581 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3584 maybe_fatal (must_succeed
, terminal
,
3585 "Terminal type %s is not defined",
3586 "Terminal type %s is not defined.\n\
3587 If that is not the actual type of terminal you have,\n\
3588 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3589 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3590 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3596 if (strlen (tty
->termcap_term_buffer
) >= buffer_size
)
3598 buffer_size
= strlen (tty
->termcap_term_buffer
);
3600 tty
->termcap_strings_buffer
= area
= (char *) xmalloc (buffer_size
);
3601 tty
->TS_ins_line
= tgetstr ("al", address
);
3602 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
3603 tty
->TS_bell
= tgetstr ("bl", address
);
3604 BackTab (tty
) = tgetstr ("bt", address
);
3605 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
3606 tty
->TS_clr_line
= tgetstr ("ce", address
);
3607 tty
->TS_clr_frame
= tgetstr ("cl", address
);
3608 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
3609 AbsPosition (tty
) = tgetstr ("cm", address
);
3610 CR (tty
) = tgetstr ("cr", address
);
3611 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
3612 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
3613 RowPosition (tty
) = tgetstr ("cv", address
);
3614 tty
->TS_del_char
= tgetstr ("dc", address
);
3615 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
3616 tty
->TS_del_line
= tgetstr ("dl", address
);
3617 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
3618 tty
->TS_delete_mode
= tgetstr ("dm", address
);
3619 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
3620 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
3621 Home (tty
) = tgetstr ("ho", address
);
3622 tty
->TS_ins_char
= tgetstr ("ic", address
);
3623 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
3624 tty
->TS_insert_mode
= tgetstr ("im", address
);
3625 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
3626 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
3627 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
3628 LastLine (tty
) = tgetstr ("ll", address
);
3629 Right (tty
) = tgetstr ("nd", address
);
3630 Down (tty
) = tgetstr ("do", address
);
3632 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
3633 if (tgetflag ("bs"))
3634 Left (tty
) = "\b"; /* can't possibly be longer! */
3635 else /* (Actually, "bs" is obsolete...) */
3636 Left (tty
) = tgetstr ("le", address
);
3638 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
3639 tty
->TS_pad_char
= tgetstr ("pc", address
);
3640 tty
->TS_repeat
= tgetstr ("rp", address
);
3641 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
3642 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
3643 tty
->TS_standout_mode
= tgetstr ("so", address
);
3644 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
3645 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
3646 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
3647 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
3648 Up (tty
) = tgetstr ("up", address
);
3649 tty
->TS_visible_bell
= tgetstr ("vb", address
);
3650 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
3651 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
3652 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
3653 tty
->TS_set_window
= tgetstr ("wi", address
);
3655 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
3656 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
3657 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
3658 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
3659 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
3660 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
3661 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3662 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3663 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
3665 MultiUp (tty
) = tgetstr ("UP", address
);
3666 MultiDown (tty
) = tgetstr ("DO", address
);
3667 MultiLeft (tty
) = tgetstr ("LE", address
);
3668 MultiRight (tty
) = tgetstr ("RI", address
);
3670 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
3671 color because we can't switch back to the default foreground and
3673 tty
->TS_orig_pair
= tgetstr ("op", address
);
3674 if (tty
->TS_orig_pair
)
3676 tty
->TS_set_foreground
= tgetstr ("AF", address
);
3677 tty
->TS_set_background
= tgetstr ("AB", address
);
3678 if (!tty
->TS_set_foreground
)
3681 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
3682 tty
->TS_set_background
= tgetstr ("Sb", address
);
3685 tty
->TN_max_colors
= tgetnum ("Co");
3686 tty
->TN_max_pairs
= tgetnum ("pa");
3688 tty
->TN_no_color_video
= tgetnum ("NC");
3689 if (tty
->TN_no_color_video
== -1)
3690 tty
->TN_no_color_video
= 0;
3693 tty_default_color_capabilities (tty
, 1);
3695 MagicWrap (tty
) = tgetflag ("xn");
3696 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3697 the former flag imply the latter. */
3698 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
3699 terminal
->memory_below_frame
= tgetflag ("db");
3700 tty
->TF_hazeltine
= tgetflag ("hz");
3701 terminal
->must_write_spaces
= tgetflag ("in");
3702 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
3703 tty
->TF_insmode_motion
= tgetflag ("mi");
3704 tty
->TF_standout_motion
= tgetflag ("ms");
3705 tty
->TF_underscore
= tgetflag ("ul");
3706 tty
->TF_teleray
= tgetflag ("xt");
3708 #endif /* !DOS_NT */
3709 terminal
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
3710 init_kboard (terminal
->kboard
);
3711 terminal
->kboard
->Vwindow_system
= Qnil
;
3712 terminal
->kboard
->next_kboard
= all_kboards
;
3713 all_kboards
= terminal
->kboard
;
3714 terminal
->kboard
->reference_count
++;
3715 /* Don't let the initial kboard remain current longer than necessary.
3716 That would cause problems if a file loaded on startup tries to
3717 prompt in the mini-buffer. */
3718 if (current_kboard
== initial_kboard
)
3719 current_kboard
= terminal
->kboard
;
3721 term_get_fkeys (address
, terminal
->kboard
);
3723 /* Get frame size from system, or else from termcap. */
3726 get_tty_size (fileno (tty
->input
), &width
, &height
);
3727 FrameCols (tty
) = width
;
3728 FrameRows (tty
) = height
;
3731 if (FrameCols (tty
) <= 0)
3732 FrameCols (tty
) = tgetnum ("co");
3733 if (FrameRows (tty
) <= 0)
3734 FrameRows (tty
) = tgetnum ("li");
3736 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
3737 maybe_fatal (must_succeed
, terminal
,
3738 "Screen size %dx%d is too small"
3739 "Screen size %dx%d is too small",
3740 FrameCols (tty
), FrameRows (tty
));
3742 TabWidth (tty
) = tgetnum ("tw");
3745 tty
->TS_bell
= "\07";
3747 if (!tty
->TS_fwd_scroll
)
3748 tty
->TS_fwd_scroll
= Down (tty
);
3750 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
3752 if (TabWidth (tty
) < 0)
3755 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3756 and newer termcap doc does not seem to say there is a default.
3757 if (!tty->Wcm->cm_tab)
3758 tty->Wcm->cm_tab = "\t";
3761 /* We don't support standout modes that use `magic cookies', so
3762 turn off any that do. */
3763 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
3765 tty
->TS_standout_mode
= 0;
3766 tty
->TS_end_standout_mode
= 0;
3768 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3770 tty
->TS_enter_underline_mode
= 0;
3771 tty
->TS_exit_underline_mode
= 0;
3774 /* If there's no standout mode, try to use underlining instead. */
3775 if (tty
->TS_standout_mode
== 0)
3777 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
3778 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
3781 /* If no `se' string, try using a `me' string instead.
3782 If that fails, we can't use standout mode at all. */
3783 if (tty
->TS_end_standout_mode
== 0)
3785 char *s
= tgetstr ("me", address
);
3787 tty
->TS_end_standout_mode
= s
;
3789 tty
->TS_standout_mode
= 0;
3792 if (tty
->TF_teleray
)
3794 tty
->Wcm
->cm_tab
= 0;
3795 /* We can't support standout mode, because it uses magic cookies. */
3796 tty
->TS_standout_mode
= 0;
3797 /* But that means we cannot rely on ^M to go to column zero! */
3799 /* LF can't be trusted either -- can alter hpos */
3800 /* if move at column 0 thru a line with TS_standout_mode */
3804 /* Special handling for certain terminal types known to need it */
3806 if (!strcmp (terminal_type
, "supdup"))
3808 terminal
->memory_below_frame
= 1;
3809 tty
->Wcm
->cm_losewrap
= 1;
3811 if (!strncmp (terminal_type
, "c10", 3)
3812 || !strcmp (terminal_type
, "perq"))
3814 /* Supply a makeshift :wi string.
3815 This string is not valid in general since it works only
3816 for windows starting at the upper left corner;
3817 but that is all Emacs uses.
3819 This string works only if the frame is using
3820 the top of the video memory, because addressing is memory-relative.
3821 So first check the :ti string to see if that is true.
3823 It would be simpler if the :wi string could go in the termcap
3824 entry, but it can't because it is not fully valid.
3825 If it were in the termcap entry, it would confuse other programs. */
3826 if (!tty
->TS_set_window
)
3828 p
= tty
->TS_termcap_modes
;
3829 while (*p
&& strcmp (p
, "\033v "))
3832 tty
->TS_set_window
= "\033v%C %C %C %C ";
3834 /* Termcap entry often fails to have :in: flag */
3835 terminal
->must_write_spaces
= 1;
3836 /* :ti string typically fails to have \E^G! in it */
3837 /* This limits scope of insert-char to one line. */
3838 strcpy (area
, tty
->TS_termcap_modes
);
3839 strcat (area
, "\033\007!");
3840 tty
->TS_termcap_modes
= area
;
3841 area
+= strlen (area
) + 1;
3842 p
= AbsPosition (tty
);
3843 /* Change all %+ parameters to %C, to handle
3844 values above 96 correctly for the C100. */
3847 if (p
[0] == '%' && p
[1] == '+')
3853 tty
->specified_window
= FrameRows (tty
);
3855 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
3857 maybe_fatal (must_succeed
, terminal
,
3858 "Terminal type \"%s\" is not powerful enough to run Emacs",
3860 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3861 It lacks the ability to position the cursor.\n\
3862 If that is not the actual type of terminal you have,\n\
3863 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3864 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3865 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3866 # else /* TERMCAP */
3867 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3868 It lacks the ability to position the cursor.\n\
3869 If that is not the actual type of terminal you have,\n\
3870 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3871 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3872 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3873 # endif /* TERMINFO */
3877 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
3878 maybe_fatal (must_succeed
, terminal
,
3879 "Could not determine the frame size",
3880 "Could not determine the frame size");
3882 tty
->delete_in_insert_mode
3883 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
3884 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
3886 tty
->se_is_so
= (tty
->TS_standout_mode
3887 && tty
->TS_end_standout_mode
3888 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
3890 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
3892 terminal
->scroll_region_ok
3894 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
3896 terminal
->line_ins_del_ok
3897 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
3898 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
3899 || (terminal
->scroll_region_ok
3900 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
3902 terminal
->char_ins_del_ok
3903 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
3904 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
3905 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
3907 terminal
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
3909 init_baud_rate (fileno (tty
->input
));
3911 #endif /* not DOS_NT */
3913 /* Init system terminal modes (RAW or CBREAK, etc.). */
3914 init_sys_modes (tty
);
3919 /* Auxiliary error-handling function for init_tty.
3920 Delete TERMINAL, then call error or fatal with str1 or str2,
3921 respectively, according to MUST_SUCCEED. */
3924 maybe_fatal (must_succeed
, terminal
, str1
, str2
, arg1
, arg2
)
3926 struct terminal
*terminal
;
3927 char *str1
, *str2
, *arg1
, *arg2
;
3930 delete_tty (terminal
);
3933 fatal (str2
, arg1
, arg2
);
3935 error (str1
, arg1
, arg2
);
3941 fatal (const char *str
, ...)
3945 fprintf (stderr
, "emacs: ");
3946 vfprintf (stderr
, str
, ap
);
3947 if (!(strlen (str
) > 0 && str
[strlen (str
) - 1] == '\n'))
3948 fprintf (stderr
, "\n");
3956 /* Delete the given tty terminal, closing all frames on it. */
3959 delete_tty (struct terminal
*terminal
)
3961 struct tty_display_info
*tty
;
3963 /* Protect against recursive calls. delete_frame in
3964 delete_terminal calls us back when it deletes our last frame. */
3965 if (!terminal
->name
)
3968 if (terminal
->type
!= output_termcap
)
3971 tty
= terminal
->display_info
.tty
;
3973 if (tty
== tty_list
)
3974 tty_list
= tty
->next
;
3977 struct tty_display_info
*p
;
3978 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
3982 /* This should not happen. */
3985 p
->next
= tty
->next
;
3989 /* reset_sys_modes needs a valid device, so this call needs to be
3990 before delete_terminal. */
3991 reset_sys_modes (tty
);
3993 delete_terminal (terminal
);
4001 delete_keyboard_wait_descriptor (fileno (tty
->input
));
4003 if (tty
->input
!= stdin
)
4004 fclose (tty
->input
);
4006 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
4007 fclose (tty
->output
);
4008 if (tty
->termscript
)
4009 fclose (tty
->termscript
);
4011 xfree (tty
->old_tty
);
4013 xfree (tty
->termcap_strings_buffer
);
4014 xfree (tty
->termcap_term_buffer
);
4016 bzero (tty
, sizeof (struct tty_display_info
));
4022 /* Mark the pointers in the tty_display_info objects.
4023 Called by the Fgarbage_collector. */
4028 struct tty_display_info
*tty
;
4030 for (tty
= tty_list
; tty
; tty
= tty
->next
)
4031 mark_object (tty
->top_frame
);
4039 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
4040 doc
: /* Non-nil means the system uses terminfo rather than termcap.
4041 This variable can be used by terminal emulator packages. */);
4043 system_uses_terminfo
= 1;
4045 system_uses_terminfo
= 0;
4048 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions
,
4049 doc
: /* Functions to be run after suspending a tty.
4050 The functions are run with one argument, the terminal object to be suspended.
4051 See `suspend-tty'. */);
4052 Vsuspend_tty_functions
= Qnil
;
4055 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions
,
4056 doc
: /* Functions to be run after resuming a tty.
4057 The functions are run with one argument, the terminal object that was revived.
4058 See `resume-tty'. */);
4059 Vresume_tty_functions
= Qnil
;
4061 DEFVAR_BOOL ("visible-cursor", &visible_cursor
,
4062 doc
: /* Non-nil means to make the cursor very visible.
4063 This only has an effect when running in a text terminal.
4064 What means \"very visible\" is up to your terminal. It may make the cursor
4065 bigger, or it may make it blink, or it may do nothing at all. */);
4068 defsubr (&Stty_display_color_p
);
4069 defsubr (&Stty_display_color_cells
);
4070 defsubr (&Stty_no_underline
);
4071 defsubr (&Stty_type
);
4072 defsubr (&Scontrolling_tty_p
);
4073 defsubr (&Ssuspend_tty
);
4074 defsubr (&Sresume_tty
);
4076 defsubr (&Sgpm_mouse_start
);
4077 defsubr (&Sgpm_mouse_stop
);
4079 staticpro (&mouse_face_window
);
4080 #endif /* HAVE_GPM */
4083 default_orig_pair
= NULL
;
4084 default_set_foreground
= NULL
;
4085 default_set_background
= NULL
;
4086 #endif /* !DOS_NT */
4088 encode_terminal_src
= NULL
;
4089 encode_terminal_dst
= NULL
;
4094 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
4095 (do not change this comment) */