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
;
699 || char_charset (c
, charset_list
, NULL
))
701 /* Store the multibyte form of C at BUF. */
702 buf
+= CHAR_STRING (c
, buf
);
707 /* C is not encodable. */
710 while (src
+ 1 < src_end
&& CHAR_GLYPH_PADDING_P (src
[1]))
720 unsigned char *p
= SDATA (string
), *pend
= p
+ SBYTES (string
);
722 if (! STRING_MULTIBYTE (string
))
723 string
= string_to_multibyte (string
);
724 nbytes
= buf
- encode_terminal_src
;
725 if (encode_terminal_src_size
< nbytes
+ SBYTES (string
))
727 encode_terminal_src_size
= nbytes
+ SBYTES (string
);
728 encode_terminal_src
= xrealloc (encode_terminal_src
,
729 encode_terminal_src_size
);
730 buf
= encode_terminal_src
+ nbytes
;
732 bcopy (SDATA (string
), buf
, SBYTES (string
));
733 buf
+= SBYTES (string
);
734 nchars
+= SCHARS (string
);
742 coding
->produced
= 0;
746 nbytes
= buf
- encode_terminal_src
;
747 coding
->source
= encode_terminal_src
;
748 if (encode_terminal_dst_size
== 0)
750 encode_terminal_dst_size
= encode_terminal_src_size
;
751 if (encode_terminal_dst
)
752 encode_terminal_dst
= xrealloc (encode_terminal_dst
,
753 encode_terminal_dst_size
);
755 encode_terminal_dst
= xmalloc (encode_terminal_dst_size
);
757 coding
->destination
= encode_terminal_dst
;
758 coding
->dst_bytes
= encode_terminal_dst_size
;
759 encode_coding_object (coding
, Qnil
, 0, 0, nchars
, nbytes
, Qnil
);
760 /* coding->destination may have been reallocated. */
761 encode_terminal_dst
= coding
->destination
;
762 encode_terminal_dst_size
= coding
->dst_bytes
;
764 return (encode_terminal_dst
);
769 /* An implementation of write_glyphs for termcap frames. */
772 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
774 unsigned char *conversion_buffer
;
775 struct coding_system
*coding
;
777 struct tty_display_info
*tty
= FRAME_TTY (f
);
779 tty_turn_off_insert (tty
);
780 tty_hide_cursor (tty
);
782 /* Don't dare write in last column of bottom line, if Auto-Wrap,
783 since that would scroll the whole frame on some terminals. */
786 && curY (tty
) + 1 == FRAME_LINES (f
)
787 && (curX (tty
) + len
) == FRAME_COLS (f
))
794 /* If terminal_coding does any conversion, use it, otherwise use
795 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
796 because it always return 1 if the member src_multibyte is 1. */
797 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
798 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
799 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
801 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
805 /* Identify a run of glyphs with the same face. */
806 int face_id
= string
->face_id
;
809 for (n
= 1; n
< len
; ++n
)
810 if (string
[n
].face_id
!= face_id
)
813 /* Turn appearance modes of the face of the run on. */
814 tty_highlight_if_desired (tty
);
815 turn_on_face (f
, face_id
);
818 /* This is the last run. */
819 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
820 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
821 if (coding
->produced
> 0)
824 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
825 if (ferror (tty
->output
))
826 clearerr (tty
->output
);
828 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
834 /* Turn appearance modes off. */
835 turn_off_face (f
, face_id
);
836 tty_turn_off_highlight (tty
);
842 #ifdef HAVE_GPM /* Only used by GPM code. */
845 tty_write_glyphs_with_face (f
, string
, len
, face_id
)
846 register struct frame
*f
;
847 register struct glyph
*string
;
848 register int len
, face_id
;
850 unsigned char *conversion_buffer
;
851 struct coding_system
*coding
;
853 struct tty_display_info
*tty
= FRAME_TTY (f
);
855 tty_turn_off_insert (tty
);
856 tty_hide_cursor (tty
);
858 /* Don't dare write in last column of bottom line, if Auto-Wrap,
859 since that would scroll the whole frame on some terminals. */
862 && curY (tty
) + 1 == FRAME_LINES (f
)
863 && (curX (tty
) + len
) == FRAME_COLS (f
))
870 /* If terminal_coding does any conversion, use it, otherwise use
871 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
872 because it always return 1 if the member src_multibyte is 1. */
873 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
874 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
875 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
877 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
879 /* Turn appearance modes of the face. */
880 tty_highlight_if_desired (tty
);
881 turn_on_face (f
, face_id
);
883 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
884 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
885 if (coding
->produced
> 0)
888 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
889 if (ferror (tty
->output
))
890 clearerr (tty
->output
);
892 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
896 /* Turn appearance modes off. */
897 turn_off_face (f
, face_id
);
898 tty_turn_off_highlight (tty
);
904 /* An implementation of insert_glyphs for termcap frames. */
907 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
910 struct glyph
*glyph
= NULL
;
911 unsigned char *conversion_buffer
;
912 unsigned char space
[1];
913 struct coding_system
*coding
;
915 struct tty_display_info
*tty
= FRAME_TTY (f
);
917 if (tty
->TS_ins_multi_chars
)
919 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
923 write_glyphs (f
, start
, len
);
927 tty_turn_on_insert (tty
);
931 space
[0] = SPACEGLYPH
;
933 /* If terminal_coding does any conversion, use it, otherwise use
934 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
935 because it always return 1 if the member src_multibyte is 1. */
936 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
937 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
938 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
940 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
944 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
947 conversion_buffer
= space
;
948 coding
->produced
= 1;
952 tty_highlight_if_desired (tty
);
953 turn_on_face (f
, start
->face_id
);
956 /* We must open sufficient space for a character which
957 occupies more than one column. */
958 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
960 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
965 /* This is the last glyph. */
966 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
968 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
971 if (coding
->produced
> 0)
974 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
975 if (ferror (tty
->output
))
976 clearerr (tty
->output
);
978 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
982 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
985 turn_off_face (f
, glyph
->face_id
);
986 tty_turn_off_highlight (tty
);
993 /* An implementation of delete_glyphs for termcap frames. */
996 tty_delete_glyphs (struct frame
*f
, int n
)
1001 struct tty_display_info
*tty
= FRAME_TTY (f
);
1003 if (tty
->delete_in_insert_mode
)
1005 tty_turn_on_insert (tty
);
1009 tty_turn_off_insert (tty
);
1010 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
1013 if (tty
->TS_del_multi_chars
)
1015 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
1020 for (i
= 0; i
< n
; i
++)
1021 OUTPUT1 (tty
, tty
->TS_del_char
);
1022 if (!tty
->delete_in_insert_mode
)
1023 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
1026 /* An implementation of ins_del_lines for termcap frames. */
1029 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
1031 struct tty_display_info
*tty
= FRAME_TTY (f
);
1032 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
1033 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
1034 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
1036 register int i
= n
> 0 ? n
: -n
;
1039 /* If the lines below the insertion are being pushed
1040 into the end of the window, this is the same as clearing;
1041 and we know the lines are already clear, since the matching
1042 deletion has already been done. So can ignore this. */
1043 /* If the lines below the deletion are blank lines coming
1044 out of the end of the window, don't bother,
1045 as there will be a matching inslines later that will flush them. */
1046 if (FRAME_SCROLL_REGION_OK (f
)
1047 && vpos
+ i
>= tty
->specified_window
)
1049 if (!FRAME_MEMORY_BELOW_FRAME (f
)
1050 && vpos
+ i
>= FRAME_LINES (f
))
1055 raw_cursor_to (f
, vpos
, 0);
1056 tty_background_highlight (tty
);
1057 buf
= tparam (multi
, 0, 0, i
);
1063 raw_cursor_to (f
, vpos
, 0);
1064 tty_background_highlight (tty
);
1066 OUTPUT (tty
, single
);
1067 if (tty
->TF_teleray
)
1072 tty_set_scroll_region (f
, vpos
, tty
->specified_window
);
1074 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
1076 raw_cursor_to (f
, vpos
, 0);
1077 tty_background_highlight (tty
);
1079 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1080 tty_set_scroll_region (f
, 0, tty
->specified_window
);
1083 if (!FRAME_SCROLL_REGION_OK (f
)
1084 && FRAME_MEMORY_BELOW_FRAME (f
)
1087 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
1092 /* Compute cost of sending "str", in characters,
1093 not counting any line-dependent padding. */
1096 string_cost (char *str
)
1100 tputs (str
, 0, evalcost
);
1104 /* Compute cost of sending "str", in characters,
1105 counting any line-dependent padding at one line. */
1108 string_cost_one_line (char *str
)
1112 tputs (str
, 1, evalcost
);
1116 /* Compute per line amount of line-dependent padding,
1117 in tenths of characters. */
1120 per_line_cost (char *str
)
1124 tputs (str
, 0, evalcost
);
1127 tputs (str
, 10, evalcost
);
1132 /* char_ins_del_cost[n] is cost of inserting N characters.
1133 char_ins_del_cost[-n] is cost of deleting N characters.
1134 The length of this vector is based on max_frame_cols. */
1136 int *char_ins_del_vector
;
1138 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1143 calculate_ins_del_char_costs (struct frame
*f
)
1145 struct tty_display_info
*tty
= FRAME_TTY (f
);
1146 int ins_startup_cost
, del_startup_cost
;
1147 int ins_cost_per_char
, del_cost_per_char
;
1151 if (tty
->TS_ins_multi_chars
)
1153 ins_cost_per_char
= 0;
1154 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1156 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1157 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1159 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1160 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1161 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1162 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1166 ins_startup_cost
= 9999;
1167 ins_cost_per_char
= 0;
1170 if (tty
->TS_del_multi_chars
)
1172 del_cost_per_char
= 0;
1173 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1175 else if (tty
->TS_del_char
)
1177 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1178 + string_cost (tty
->TS_end_delete_mode
));
1179 if (tty
->delete_in_insert_mode
)
1180 del_startup_cost
/= 2;
1181 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1185 del_startup_cost
= 9999;
1186 del_cost_per_char
= 0;
1189 /* Delete costs are at negative offsets */
1190 p
= &char_ins_del_cost (f
)[0];
1191 for (i
= FRAME_COLS (f
); --i
>= 0;)
1192 *--p
= (del_startup_cost
+= del_cost_per_char
);
1194 /* Doing nothing is free */
1195 p
= &char_ins_del_cost (f
)[0];
1198 /* Insert costs are at positive offsets */
1199 for (i
= FRAME_COLS (f
); --i
>= 0;)
1200 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1204 calculate_costs (struct frame
*frame
)
1206 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1208 if (FRAME_TERMCAP_P (frame
))
1210 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1211 register char *f
= (tty
->TS_set_scroll_region
1212 ? tty
->TS_set_scroll_region
1213 : tty
->TS_set_scroll_region_1
);
1215 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1219 /* These variables are only used for terminal stuff. They are
1220 allocated once for the terminal frame of X-windows emacs, but not
1223 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1224 X turns off char_ins_del_ok. */
1226 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1227 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1229 if (char_ins_del_vector
!= 0)
1231 = (int *) xrealloc (char_ins_del_vector
,
1233 + 2 * max_frame_cols
* sizeof (int)));
1236 = (int *) xmalloc (sizeof (int)
1237 + 2 * max_frame_cols
* sizeof (int));
1239 bzero (char_ins_del_vector
, (sizeof (int)
1240 + 2 * max_frame_cols
* sizeof (int)));
1243 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1244 do_line_insertion_deletion_costs (frame
,
1245 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1246 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1249 do_line_insertion_deletion_costs (frame
,
1250 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1251 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1254 calculate_ins_del_char_costs (frame
);
1256 /* Don't use TS_repeat if its padding is worse than sending the chars */
1257 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1258 tty
->RPov
= string_cost (tty
->TS_repeat
);
1260 tty
->RPov
= FRAME_COLS (frame
) * 2;
1262 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1270 /* Termcap capability names that correspond directly to X keysyms.
1271 Some of these (marked "terminfo") aren't supplied by old-style
1272 (Berkeley) termcap entries. They're listed in X keysym order;
1273 except we put the keypad keys first, so that if they clash with
1274 other keys (as on the IBM PC keyboard) they get overridden.
1277 static struct fkey_table keys
[] =
1279 {"kh", "home"}, /* termcap */
1280 {"kl", "left"}, /* termcap */
1281 {"ku", "up"}, /* termcap */
1282 {"kr", "right"}, /* termcap */
1283 {"kd", "down"}, /* termcap */
1284 {"%8", "prior"}, /* terminfo */
1285 {"%5", "next"}, /* terminfo */
1286 {"@7", "end"}, /* terminfo */
1287 {"@1", "begin"}, /* terminfo */
1288 {"*6", "select"}, /* terminfo */
1289 {"%9", "print"}, /* terminfo */
1290 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1292 * "insert" --- see below
1294 {"&8", "undo"}, /* terminfo */
1295 {"%0", "redo"}, /* terminfo */
1296 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1297 {"@0", "find"}, /* terminfo */
1298 {"@2", "cancel"}, /* terminfo */
1299 {"%1", "help"}, /* terminfo */
1301 * "break" goes here, but can't be reliably intercepted with termcap
1303 {"&4", "reset"}, /* terminfo --- actually `restart' */
1305 * "system" and "user" --- no termcaps
1307 {"kE", "clearline"}, /* terminfo */
1308 {"kA", "insertline"}, /* terminfo */
1309 {"kL", "deleteline"}, /* terminfo */
1310 {"kI", "insertchar"}, /* terminfo */
1311 {"kD", "deletechar"}, /* terminfo */
1312 {"kB", "backtab"}, /* terminfo */
1314 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1316 {"@8", "kp-enter"}, /* terminfo */
1318 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1319 * "kp-multiply", "kp-add", "kp-separator",
1320 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1321 * --- no termcaps for any of these.
1323 {"K4", "kp-1"}, /* terminfo */
1325 * "kp-2" --- no termcap
1327 {"K5", "kp-3"}, /* terminfo */
1329 * "kp-4" --- no termcap
1331 {"K2", "kp-5"}, /* terminfo */
1333 * "kp-6" --- no termcap
1335 {"K1", "kp-7"}, /* terminfo */
1337 * "kp-8" --- no termcap
1339 {"K3", "kp-9"}, /* terminfo */
1341 * "kp-equal" --- no termcap
1353 {"&0", "S-cancel"}, /*shifted cancel key*/
1354 {"&9", "S-begin"}, /*shifted begin key*/
1355 {"*0", "S-find"}, /*shifted find key*/
1356 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1357 {"*4", "S-delete"}, /*shifted delete-character key*/
1358 {"*7", "S-end"}, /*shifted end key*/
1359 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1360 {"#1", "S-help"}, /*shifted help key*/
1361 {"#2", "S-home"}, /*shifted home key*/
1362 {"#3", "S-insert"}, /*shifted insert-character key*/
1363 {"#4", "S-left"}, /*shifted left-arrow key*/
1364 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1365 {"%c", "S-next"}, /*shifted next key*/
1366 {"%e", "S-prior"}, /*shifted previous key*/
1367 {"%f", "S-print"}, /*shifted print key*/
1368 {"%g", "S-redo"}, /*shifted redo key*/
1369 {"%i", "S-right"}, /*shifted right-arrow key*/
1370 {"!3", "S-undo"} /*shifted undo key*/
1373 static char **term_get_fkeys_address
;
1374 static KBOARD
*term_get_fkeys_kboard
;
1375 static Lisp_Object
term_get_fkeys_1 ();
1377 /* Find the escape codes sent by the function keys for Vinput_decode_map.
1378 This function scans the termcap function key sequence entries, and
1379 adds entries to Vinput_decode_map for each function key it finds. */
1382 term_get_fkeys (address
, kboard
)
1386 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1387 errors during the call. The only errors should be from Fdefine_key
1388 when given a key sequence containing an invalid prefix key. If the
1389 termcap defines function keys which use a prefix that is already bound
1390 to a command by the default bindings, we should silently ignore that
1391 function key specification, rather than giving the user an error and
1392 refusing to run at all on such a terminal. */
1394 extern Lisp_Object
Fidentity ();
1395 term_get_fkeys_address
= address
;
1396 term_get_fkeys_kboard
= kboard
;
1397 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1405 char **address
= term_get_fkeys_address
;
1406 KBOARD
*kboard
= term_get_fkeys_kboard
;
1408 /* This can happen if CANNOT_DUMP or with strange options. */
1409 if (!KEYMAPP (kboard
->Vinput_decode_map
))
1410 kboard
->Vinput_decode_map
= Fmake_sparse_keymap (Qnil
);
1412 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1414 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1416 Fdefine_key (kboard
->Vinput_decode_map
, build_string (sequence
),
1417 Fmake_vector (make_number (1),
1418 intern (keys
[i
].name
)));
1421 /* The uses of the "k0" capability are inconsistent; sometimes it
1422 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1423 We will attempt to politely accommodate both systems by testing for
1424 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1427 char *k_semi
= tgetstr ("k;", address
);
1428 char *k0
= tgetstr ("k0", address
);
1429 char *k0_name
= "f10";
1434 /* Define f0 first, so that f10 takes precedence in case the
1435 key sequences happens to be the same. */
1436 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k0
),
1437 Fmake_vector (make_number (1), intern ("f0")));
1438 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k_semi
),
1439 Fmake_vector (make_number (1), intern ("f10")));
1442 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k0
),
1443 Fmake_vector (make_number (1), intern (k0_name
)));
1446 /* Set up cookies for numbered function keys above f10. */
1448 char fcap
[3], fkey
[4];
1450 fcap
[0] = 'F'; fcap
[2] = '\0';
1451 for (i
= 11; i
< 64; i
++)
1454 fcap
[1] = '1' + i
- 11;
1456 fcap
[1] = 'A' + i
- 20;
1458 fcap
[1] = 'a' + i
- 46;
1461 char *sequence
= tgetstr (fcap
, address
);
1464 sprintf (fkey
, "f%d", i
);
1465 Fdefine_key (kboard
->Vinput_decode_map
, build_string (sequence
),
1466 Fmake_vector (make_number (1),
1474 * Various mappings to try and get a better fit.
1477 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1478 if (!tgetstr (cap1, address)) \
1480 char *sequence = tgetstr (cap2, address); \
1482 Fdefine_key (kboard->Vinput_decode_map, build_string (sequence), \
1483 Fmake_vector (make_number (1), \
1487 /* if there's no key_next keycap, map key_npage to `next' keysym */
1488 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1489 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1490 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1491 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1492 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1493 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1494 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1496 /* IBM has their own non-standard dialect of terminfo.
1497 If the standard name isn't found, try the IBM name. */
1498 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1499 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1500 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1501 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1502 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1503 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1504 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1505 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1506 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1507 #undef CONDITIONAL_REASSIGN
1514 /***********************************************************************
1515 Character Display Information
1516 ***********************************************************************/
1518 /* Avoid name clash with functions defined in xterm.c */
1520 #define append_glyph append_glyph_term
1521 #define produce_stretch_glyph produce_stretch_glyph_term
1522 #define append_composite_glyph append_composite_glyph_term
1523 #define produce_composite_glyph produce_composite_glyph_term
1526 static void append_glyph
P_ ((struct it
*));
1527 static void produce_stretch_glyph
P_ ((struct it
*));
1528 static void append_composite_glyph
P_ ((struct it
*));
1529 static void produce_composite_glyph
P_ ((struct it
*));
1531 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1532 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1533 the character for which to produce glyphs; IT->face_id contains the
1534 character's face. Padding glyphs are appended if IT->c has a
1535 IT->pixel_width > 1. */
1541 struct glyph
*glyph
, *end
;
1544 xassert (it
->glyph_row
);
1545 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1546 + it
->glyph_row
->used
[it
->area
]);
1547 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1550 i
< it
->pixel_width
&& glyph
< end
;
1553 glyph
->type
= CHAR_GLYPH
;
1554 glyph
->pixel_width
= 1;
1555 glyph
->u
.ch
= it
->char_to_display
;
1556 glyph
->face_id
= it
->face_id
;
1557 glyph
->padding_p
= i
> 0;
1558 glyph
->charpos
= CHARPOS (it
->position
);
1559 glyph
->object
= it
->object
;
1561 ++it
->glyph_row
->used
[it
->area
];
1567 /* Produce glyphs for the display element described by IT. *IT
1568 specifies what we want to produce a glyph for (character, image, ...),
1569 and where in the glyph matrix we currently are (glyph row and hpos).
1570 produce_glyphs fills in output fields of *IT with information such as the
1571 pixel width and height of a character, and maybe output actual glyphs at
1572 the same time if IT->glyph_row is non-null. For an overview, see
1573 the explanation in dispextern.h, before the definition of the
1574 display_element_type enumeration.
1576 produce_glyphs also stores the result of glyph width, ascent
1577 etc. computations in *IT.
1579 IT->glyph_row may be null, in which case produce_glyphs does not
1580 actually fill in the glyphs. This is used in the move_* functions
1581 in xdisp.c for text width and height computations.
1583 Callers usually don't call produce_glyphs directly;
1584 instead they use the macro PRODUCE_GLYPHS. */
1590 /* If a hook is installed, let it do the work. */
1592 /* Nothing but characters are supported on terminal frames. */
1593 xassert (it
->what
== IT_CHARACTER
1594 || it
->what
== IT_COMPOSITION
1595 || it
->what
== IT_STRETCH
);
1597 if (it
->what
== IT_STRETCH
)
1599 produce_stretch_glyph (it
);
1603 if (it
->what
== IT_COMPOSITION
)
1605 produce_composite_glyph (it
);
1609 if (it
->char_to_display
>= 040 && it
->char_to_display
< 0177)
1611 it
->pixel_width
= it
->nglyphs
= 1;
1615 else if (it
->char_to_display
== '\n')
1616 it
->pixel_width
= it
->nglyphs
= 0;
1617 else if (it
->char_to_display
== '\t')
1619 int absolute_x
= (it
->current_x
1620 + it
->continuation_lines_width
);
1622 = (((1 + absolute_x
+ it
->tab_width
- 1)
1627 /* If part of the TAB has been displayed on the previous line
1628 which is continued now, continuation_lines_width will have
1629 been incremented already by the part that fitted on the
1630 continued line. So, we will get the right number of spaces
1632 nspaces
= next_tab_x
- absolute_x
;
1638 it
->char_to_display
= ' ';
1639 it
->pixel_width
= it
->len
= 1;
1645 it
->pixel_width
= nspaces
;
1646 it
->nglyphs
= nspaces
;
1648 else if (CHAR_BYTE8_P (it
->char_to_display
))
1650 /* Coming here means that we must send the raw 8-bit byte as is
1651 to the terminal. Although there's no way to know how many
1652 columns it occupies on a screen, it is a good assumption that
1653 a single byte code has 1-column width. */
1654 it
->pixel_width
= it
->nglyphs
= 1;
1660 it
->pixel_width
= CHAR_WIDTH (it
->char_to_display
);
1661 it
->nglyphs
= it
->pixel_width
;
1668 /* Advance current_x by the pixel width as a convenience for
1670 if (it
->area
== TEXT_AREA
)
1671 it
->current_x
+= it
->pixel_width
;
1672 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1673 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1677 /* Produce a stretch glyph for iterator IT. IT->object is the value
1678 of the glyph property displayed. The value must be a list
1679 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1682 1. `:width WIDTH' specifies that the space should be WIDTH *
1683 canonical char width wide. WIDTH may be an integer or floating
1686 2. `:align-to HPOS' specifies that the space should be wide enough
1687 to reach HPOS, a value in canonical character units. */
1690 produce_stretch_glyph (it
)
1693 /* (space :width WIDTH ...) */
1694 Lisp_Object prop
, plist
;
1695 int width
= 0, align_to
= -1;
1696 int zero_width_ok_p
= 0;
1699 /* List should start with `space'. */
1700 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1701 plist
= XCDR (it
->object
);
1703 /* Compute the width of the stretch. */
1704 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1705 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1707 /* Absolute width `:width WIDTH' specified and valid. */
1708 zero_width_ok_p
= 1;
1709 width
= (int)(tem
+ 0.5);
1711 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1712 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1714 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1715 align_to
= (align_to
< 0
1717 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1718 else if (align_to
< 0)
1719 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1720 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1721 zero_width_ok_p
= 1;
1724 /* Nothing specified -> width defaults to canonical char width. */
1725 width
= FRAME_COLUMN_WIDTH (it
->f
);
1727 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1730 if (width
> 0 && it
->line_wrap
!= TRUNCATE
1731 && it
->current_x
+ width
> it
->last_visible_x
)
1732 width
= it
->last_visible_x
- it
->current_x
- 1;
1734 if (width
> 0 && it
->glyph_row
)
1736 Lisp_Object o_object
= it
->object
;
1737 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1740 if (!STRINGP (object
))
1741 object
= it
->w
->buffer
;
1742 it
->object
= object
;
1743 it
->char_to_display
= ' ';
1744 it
->pixel_width
= it
->len
= 1;
1747 it
->object
= o_object
;
1749 it
->pixel_width
= width
;
1750 it
->nglyphs
= width
;
1754 /* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
1755 Called from produce_composite_glyph for terminal frames if
1756 IT->glyph_row != NULL. IT->face_id contains the character's
1760 append_composite_glyph (it
)
1763 struct glyph
*glyph
;
1765 xassert (it
->glyph_row
);
1766 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1767 if (glyph
< it
->glyph_row
->glyphs
[1 + it
->area
])
1769 glyph
->type
= COMPOSITE_GLYPH
;
1770 glyph
->pixel_width
= it
->pixel_width
;
1771 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1772 if (it
->cmp_it
.ch
< 0)
1774 glyph
->u
.cmp
.automatic
= 0;
1775 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1779 glyph
->u
.cmp
.automatic
= 1;
1780 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1781 glyph
->u
.cmp
.from
= it
->cmp_it
.from
;
1782 glyph
->u
.cmp
.to
= it
->cmp_it
.to
- 1;
1785 glyph
->face_id
= it
->face_id
;
1786 glyph
->padding_p
= 0;
1787 glyph
->charpos
= CHARPOS (it
->position
);
1788 glyph
->object
= it
->object
;
1790 ++it
->glyph_row
->used
[it
->area
];
1796 /* Produce a composite glyph for iterator IT. IT->cmp_id is the ID of
1797 the composition. We simply produces components of the composition
1798 assuming that the terminal has a capability to layout/render it
1802 produce_composite_glyph (it
)
1807 if (it
->cmp_it
.ch
< 0)
1809 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
1811 it
->pixel_width
= cmp
->width
;
1815 Lisp_Object gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
1817 it
->pixel_width
= composition_gstring_width (gstring
, it
->cmp_it
.from
,
1818 it
->cmp_it
.to
, NULL
);
1822 append_composite_glyph (it
);
1826 /* Get information about special display element WHAT in an
1827 environment described by IT. WHAT is one of IT_TRUNCATION or
1828 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1829 non-null glyph_row member. This function ensures that fields like
1830 face_id, c, len of IT are left untouched. */
1833 produce_special_glyphs (it
, what
)
1835 enum display_element_type what
;
1843 temp_it
.what
= IT_CHARACTER
;
1845 temp_it
.object
= make_number (0);
1846 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1848 if (what
== IT_CONTINUATION
)
1850 /* Continuation glyph. */
1851 SET_GLYPH_FROM_CHAR (glyph
, '\\');
1853 && (gc
= DISP_CONTINUE_GLYPH (it
->dp
), GLYPH_CODE_P (gc
))
1854 && GLYPH_CODE_CHAR_VALID_P (gc
))
1856 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
1857 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
1860 else if (what
== IT_TRUNCATION
)
1862 /* Truncation glyph. */
1863 SET_GLYPH_FROM_CHAR (glyph
, '$');
1865 && (gc
= DISP_TRUNC_GLYPH (it
->dp
), GLYPH_CODE_P (gc
))
1866 && GLYPH_CODE_CHAR_VALID_P (gc
))
1868 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
1869 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
1875 temp_it
.c
= temp_it
.char_to_display
= GLYPH_CHAR (glyph
);
1876 temp_it
.face_id
= GLYPH_FACE (glyph
);
1877 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1879 produce_glyphs (&temp_it
);
1880 it
->pixel_width
= temp_it
.pixel_width
;
1881 it
->nglyphs
= temp_it
.pixel_width
;
1886 /***********************************************************************
1888 ***********************************************************************/
1890 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1891 one of the enumerators from enum no_color_bit, or a bit set built
1892 from them. Some display attributes may not be used together with
1893 color; the termcap capability `NC' specifies which ones. */
1895 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1896 (tty->TN_max_colors > 0 \
1897 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1900 /* Turn appearances of face FACE_ID on tty frame F on.
1901 FACE_ID is a realized face ID number, in the face cache. */
1904 turn_on_face (f
, face_id
)
1908 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1909 long fg
= face
->foreground
;
1910 long bg
= face
->background
;
1911 struct tty_display_info
*tty
= FRAME_TTY (f
);
1913 /* Do this first because TS_end_standout_mode may be the same
1914 as TS_exit_attribute_mode, which turns all appearances off. */
1915 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1917 if (tty
->TN_max_colors
> 0)
1919 if (fg
>= 0 && bg
>= 0)
1921 /* If the terminal supports colors, we can set them
1922 below without using reverse video. The face's fg
1923 and bg colors are set as they should appear on
1924 the screen, i.e. they take the inverse-video'ness
1925 of the face already into account. */
1927 else if (inverse_video
)
1929 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1930 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1931 tty_toggle_highlight (tty
);
1935 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1936 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1937 tty_toggle_highlight (tty
);
1942 /* If we can't display colors, use reverse video
1943 if the face specifies that. */
1946 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1947 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1948 tty_toggle_highlight (tty
);
1952 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1953 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1954 tty_toggle_highlight (tty
);
1959 if (face
->tty_bold_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1960 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1962 if (face
->tty_dim_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1963 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1965 /* Alternate charset and blinking not yet used. */
1966 if (face
->tty_alt_charset_p
1967 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1968 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1970 if (face
->tty_blinking_p
1971 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1972 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1974 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1975 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1977 if (tty
->TN_max_colors
> 0)
1981 ts
= tty
->standout_mode
? tty
->TS_set_background
: tty
->TS_set_foreground
;
1984 p
= tparam (ts
, NULL
, 0, (int) fg
);
1989 ts
= tty
->standout_mode
? tty
->TS_set_foreground
: tty
->TS_set_background
;
1992 p
= tparam (ts
, NULL
, 0, (int) bg
);
2000 /* Turn off appearances of face FACE_ID on tty frame F. */
2003 turn_off_face (f
, face_id
)
2007 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2008 struct tty_display_info
*tty
= FRAME_TTY (f
);
2010 xassert (face
!= NULL
);
2012 if (tty
->TS_exit_attribute_mode
)
2014 /* Capability "me" will turn off appearance modes double-bright,
2015 half-bright, reverse-video, standout, underline. It may or
2016 may not turn off alt-char-mode. */
2017 if (face
->tty_bold_p
2019 || face
->tty_reverse_p
2020 || face
->tty_alt_charset_p
2021 || face
->tty_blinking_p
2022 || face
->tty_underline_p
)
2024 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
2025 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
2026 tty
->standout_mode
= 0;
2029 if (face
->tty_alt_charset_p
)
2030 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
2034 /* If we don't have "me" we can only have those appearances
2035 that have exit sequences defined. */
2036 if (face
->tty_alt_charset_p
)
2037 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
2039 if (face
->tty_underline_p
)
2040 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
2043 /* Switch back to default colors. */
2044 if (tty
->TN_max_colors
> 0
2045 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2046 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2047 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2048 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2049 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
2053 /* Return non-zero if the terminal on frame F supports all of the
2054 capabilities in CAPS simultaneously, with foreground and background
2055 colors FG and BG. */
2058 tty_capable_p (tty
, caps
, fg
, bg
)
2059 struct tty_display_info
*tty
;
2061 unsigned long fg
, bg
;
2063 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
2064 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
2067 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
2068 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
2069 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
2070 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
2071 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
2072 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
2078 /* Return non-zero if the terminal is capable to display colors. */
2080 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2082 doc
: /* Return non-nil if the tty device TERMINAL can display colors.
2084 TERMINAL can be a terminal object, a frame, or nil (meaning the
2085 selected frame's terminal). This function always returns nil if
2086 TERMINAL does not refer to a text-only terminal. */)
2088 Lisp_Object terminal
;
2090 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2094 return t
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
2097 /* Return the number of supported colors. */
2098 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2099 Stty_display_color_cells
, 0, 1, 0,
2100 doc
: /* Return the number of colors supported by the tty device TERMINAL.
2102 TERMINAL can be a terminal object, a frame, or nil (meaning the
2103 selected frame's terminal). This function always returns 0 if
2104 TERMINAL does not refer to a text-only terminal. */)
2106 Lisp_Object terminal
;
2108 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2110 return make_number (0);
2112 return make_number (t
->display_info
.tty
->TN_max_colors
);
2117 /* Declare here rather than in the function, as in the rest of Emacs,
2118 to work around an HPUX compiler bug (?). See
2119 http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00410.html */
2120 static int default_max_colors
;
2121 static int default_max_pairs
;
2122 static int default_no_color_video
;
2123 static char *default_orig_pair
;
2124 static char *default_set_foreground
;
2125 static char *default_set_background
;
2127 /* Save or restore the default color-related capabilities of this
2130 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
2135 xfree (default_orig_pair
);
2136 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
2138 xfree (default_set_foreground
);
2139 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
2142 xfree (default_set_background
);
2143 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
2146 default_max_colors
= tty
->TN_max_colors
;
2147 default_max_pairs
= tty
->TN_max_pairs
;
2148 default_no_color_video
= tty
->TN_no_color_video
;
2152 tty
->TS_orig_pair
= default_orig_pair
;
2153 tty
->TS_set_foreground
= default_set_foreground
;
2154 tty
->TS_set_background
= default_set_background
;
2155 tty
->TN_max_colors
= default_max_colors
;
2156 tty
->TN_max_pairs
= default_max_pairs
;
2157 tty
->TN_no_color_video
= default_no_color_video
;
2161 /* Setup one of the standard tty color schemes according to MODE.
2162 MODE's value is generally the number of colors which we want to
2163 support; zero means set up for the default capabilities, the ones
2164 we saw at init_tty time; -1 means turn off color support. */
2166 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2168 /* Canonicalize all negative values of MODE. */
2174 case -1: /* no colors at all */
2175 tty
->TN_max_colors
= 0;
2176 tty
->TN_max_pairs
= 0;
2177 tty
->TN_no_color_video
= 0;
2178 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2180 case 0: /* default colors, if any */
2182 tty_default_color_capabilities (tty
, 0);
2184 case 8: /* 8 standard ANSI colors */
2185 tty
->TS_orig_pair
= "\033[0m";
2187 tty
->TS_set_foreground
= "\033[3%p1%dm";
2188 tty
->TS_set_background
= "\033[4%p1%dm";
2190 tty
->TS_set_foreground
= "\033[3%dm";
2191 tty
->TS_set_background
= "\033[4%dm";
2193 tty
->TN_max_colors
= 8;
2194 tty
->TN_max_pairs
= 64;
2195 tty
->TN_no_color_video
= 0;
2201 set_tty_color_mode (tty
, f
)
2202 struct tty_display_info
*tty
;
2205 Lisp_Object tem
, val
, color_mode_spec
;
2206 Lisp_Object color_mode
;
2208 extern Lisp_Object Qtty_color_mode
;
2209 Lisp_Object tty_color_mode_alist
2210 = Fintern_soft (build_string ("tty-color-mode-alist"), Qnil
);
2212 tem
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2213 val
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2219 tem
= (NILP (tty_color_mode_alist
) ? Qnil
2220 : Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
));
2221 color_mode
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2224 mode
= INTEGERP (color_mode
) ? XINT (color_mode
) : 0;
2226 if (mode
!= tty
->previous_color_mode
)
2228 Lisp_Object funsym
= intern ("tty-set-up-initial-frame-faces");
2229 tty
->previous_color_mode
= mode
;
2230 tty_setup_colors (tty
, mode
);
2231 /* This recomputes all the faces given the new color definitions. */
2232 safe_call (1, &funsym
);
2236 #endif /* !DOS_NT */
2240 /* Return the tty display object specified by TERMINAL. */
2243 get_tty_terminal (Lisp_Object terminal
, int throw)
2245 struct terminal
*t
= get_terminal (terminal
, throw);
2247 if (t
&& t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2250 error ("Device %d is not a termcap terminal device", t
->id
);
2258 /* Return an active termcap device that uses the tty device with the
2261 This function ignores suspended devices.
2263 Returns NULL if the named terminal device is not opened. */
2266 get_named_tty (name
)
2274 for (t
= terminal_list
; t
; t
= t
->next_terminal
)
2276 if ((t
->type
== output_termcap
|| t
->type
== output_msdos_raw
)
2277 && !strcmp (t
->display_info
.tty
->name
, name
)
2278 && TERMINAL_ACTIVE_P (t
))
2286 DEFUN ("tty-type", Ftty_type
, Stty_type
, 0, 1, 0,
2287 doc
: /* Return the type of the tty device that TERMINAL uses.
2288 Returns nil if TERMINAL is not on a tty device.
2290 TERMINAL can be a terminal object, a frame, or nil (meaning the
2291 selected frame's terminal). */)
2293 Lisp_Object terminal
;
2295 struct terminal
*t
= get_terminal (terminal
, 1);
2297 if (t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2300 if (t
->display_info
.tty
->type
)
2301 return build_string (t
->display_info
.tty
->type
);
2306 DEFUN ("controlling-tty-p", Fcontrolling_tty_p
, Scontrolling_tty_p
, 0, 1, 0,
2307 doc
: /* Return non-nil if TERMINAL is the controlling tty of the Emacs process.
2309 TERMINAL can be a terminal object, a frame, or nil (meaning the
2310 selected frame's terminal). This function always returns nil if
2311 TERMINAL is not on a tty device. */)
2313 Lisp_Object terminal
;
2315 struct terminal
*t
= get_terminal (terminal
, 1);
2317 if ((t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2318 || strcmp (t
->display_info
.tty
->name
, DEV_TTY
) != 0)
2324 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 1, 0,
2325 doc
: /* Declare that the tty used by TERMINAL does not handle underlining.
2326 This is used to override the terminfo data, for certain terminals that
2327 do not really do underlining, but say that they do. This function has
2328 no effect if used on a non-tty terminal.
2330 TERMINAL can be a terminal object, a frame or nil (meaning the
2331 selected frame's terminal). This function always returns nil if
2332 TERMINAL does not refer to a text-only terminal. */)
2334 Lisp_Object terminal
;
2336 struct terminal
*t
= get_terminal (terminal
, 1);
2338 if (t
->type
== output_termcap
)
2339 t
->display_info
.tty
->TS_enter_underline_mode
= 0;
2345 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
2346 doc
: /* Suspend the terminal device TTY.
2348 The device is restored to its default state, and Emacs ceases all
2349 access to the tty device. Frames that use the device are not deleted,
2350 but input is not read from them and if they change, their display is
2353 TTY may be a terminal object, a frame, or nil for the terminal device
2354 of the currently selected frame.
2356 This function runs `suspend-tty-functions' after suspending the
2357 device. The functions are run with one arg, the id of the suspended
2360 `suspend-tty' does nothing if it is called on a device that is already
2363 A suspended tty may be resumed by calling `resume-tty' on it. */)
2367 struct terminal
*t
= get_tty_terminal (tty
, 1);
2371 error ("Unknown tty device");
2373 f
= t
->display_info
.tty
->input
;
2377 /* First run `suspend-tty-functions' and then clean up the tty
2378 state because `suspend-tty-functions' might need to change
2380 if (!NILP (Vrun_hooks
))
2382 Lisp_Object args
[2];
2383 args
[0] = intern ("suspend-tty-functions");
2384 XSETTERMINAL (args
[1], t
);
2385 Frun_hook_with_args (2, args
);
2388 reset_sys_modes (t
->display_info
.tty
);
2391 delete_keyboard_wait_descriptor (fileno (f
));
2396 if (f
!= t
->display_info
.tty
->output
)
2397 fclose (t
->display_info
.tty
->output
);
2400 t
->display_info
.tty
->input
= 0;
2401 t
->display_info
.tty
->output
= 0;
2403 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2404 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 0);
2408 /* Clear display hooks to prevent further output. */
2409 clear_tty_hooks (t
);
2414 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
2415 doc
: /* Resume the previously suspended terminal device TTY.
2416 The terminal is opened and reinitialized. Frames that are on the
2417 suspended terminal are revived.
2419 It is an error to resume a terminal while another terminal is active
2422 This function runs `resume-tty-functions' after resuming the terminal.
2423 The functions are run with one arg, the id of the resumed terminal
2426 `resume-tty' does nothing if it is called on a device that is not
2429 TTY may be a terminal object, a frame, or nil (meaning the selected
2430 frame's terminal). */)
2434 struct terminal
*t
= get_tty_terminal (tty
, 1);
2438 error ("Unknown tty device");
2440 if (!t
->display_info
.tty
->input
)
2442 if (get_named_tty (t
->display_info
.tty
->name
))
2443 error ("Cannot resume display while another display is active on the same device");
2446 t
->display_info
.tty
->output
= stdout
;
2447 t
->display_info
.tty
->input
= stdin
;
2449 fd
= emacs_open (t
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
2452 error ("Can not reopen tty device %s: %s", t
->display_info
.tty
->name
, strerror (errno
));
2454 if (strcmp (t
->display_info
.tty
->name
, DEV_TTY
))
2455 dissociate_if_controlling_tty (fd
);
2457 t
->display_info
.tty
->output
= fdopen (fd
, "w+");
2458 t
->display_info
.tty
->input
= t
->display_info
.tty
->output
;
2462 add_keyboard_wait_descriptor (fd
);
2465 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2467 struct frame
*f
= XFRAME (t
->display_info
.tty
->top_frame
);
2469 int old_height
= FRAME_COLS (f
);
2470 int old_width
= FRAME_LINES (f
);
2472 /* Check if terminal/window size has changed while the frame
2474 get_tty_size (fileno (t
->display_info
.tty
->input
), &width
, &height
);
2475 if (width
!= old_width
|| height
!= old_height
)
2476 change_frame_size (f
, height
, width
, 0, 0, 0);
2477 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 1);
2480 init_sys_modes (t
->display_info
.tty
);
2482 /* Run `resume-tty-functions'. */
2483 if (!NILP (Vrun_hooks
))
2485 Lisp_Object args
[2];
2486 args
[0] = intern ("resume-tty-functions");
2487 XSETTERMINAL (args
[1], t
);
2488 Frun_hook_with_args (2, args
);
2498 /***********************************************************************
2500 ***********************************************************************/
2504 term_mouse_moveto (int x
, int y
)
2506 /* TODO: how to set mouse position?
2509 name = (const char *) ttyname (0);
2510 fd = open (name, O_WRONLY);
2511 SOME_FUNCTION (x, y, fd);
2514 last_mouse_y = y; */
2518 term_show_mouse_face (enum draw_glyphs_face draw
)
2520 struct window
*w
= XWINDOW (mouse_face_window
);
2524 struct frame
*f
= XFRAME (w
->frame
);
2525 struct tty_display_info
*tty
= FRAME_TTY (f
);
2527 if (/* If window is in the process of being destroyed, don't bother
2529 w
->current_matrix
!= NULL
2530 /* Recognize when we are called to operate on rows that don't exist
2531 anymore. This can happen when a window is split. */
2532 && mouse_face_end_row
< w
->current_matrix
->nrows
)
2534 /* write_glyphs writes at cursor position, so we need to
2535 temporarily move cursor coordinates to the beginning of
2536 the highlight region. */
2538 /* Save current cursor co-ordinates */
2539 save_y
= curY (tty
);
2540 save_x
= curX (tty
);
2542 /* Note that mouse_face_beg_row etc. are window relative. */
2543 for (i
= mouse_face_beg_row
; i
<= mouse_face_end_row
; i
++)
2545 int start_hpos
, end_hpos
, nglyphs
;
2546 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
2548 /* Don't do anything if row doesn't have valid contents. */
2549 if (!row
->enabled_p
)
2552 /* For all but the first row, the highlight starts at column 0. */
2553 if (i
== mouse_face_beg_row
)
2554 start_hpos
= mouse_face_beg_col
;
2558 if (i
== mouse_face_end_row
)
2559 end_hpos
= mouse_face_end_col
;
2562 end_hpos
= row
->used
[TEXT_AREA
];
2563 if (draw
== DRAW_NORMAL_TEXT
)
2564 row
->fill_line_p
= 1; /* Clear to end of line */
2567 if (end_hpos
<= start_hpos
)
2569 /* Record that some glyphs of this row are displayed in
2571 row
->mouse_face_p
= draw
> 0;
2573 nglyphs
= end_hpos
- start_hpos
;
2575 if (end_hpos
>= row
->used
[TEXT_AREA
])
2576 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2578 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2579 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
2580 + WINDOW_LEFT_EDGE_X (w
);
2582 cursor_to (f
, pos_y
, pos_x
);
2584 if (draw
== DRAW_MOUSE_FACE
)
2586 tty_write_glyphs_with_face (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
,
2587 nglyphs
, mouse_face_face_id
);
2589 else /* draw == DRAW_NORMAL_TEXT */
2590 write_glyphs (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2592 cursor_to (f
, save_y
, save_x
);
2597 term_clear_mouse_face ()
2599 if (!NILP (mouse_face_window
))
2600 term_show_mouse_face (DRAW_NORMAL_TEXT
);
2602 mouse_face_beg_row
= mouse_face_beg_col
= -1;
2603 mouse_face_end_row
= mouse_face_end_col
= -1;
2604 mouse_face_window
= Qnil
;
2607 /* Find the glyph matrix position of buffer position POS in window W.
2608 *HPOS and *VPOS are set to the positions found. W's current glyphs
2609 must be up to date. If POS is above window start return (0, 0).
2610 If POS is after end of W, return end of last line in W.
2611 - taken from msdos.c */
2613 fast_find_position (struct window
*w
, int pos
, int *hpos
, int *vpos
)
2615 int i
, lastcol
, line_start_position
, maybe_next_line_p
= 0;
2616 int yb
= window_text_bottom_y (w
);
2617 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0), *best_row
= row
;
2621 if (row
->used
[TEXT_AREA
])
2622 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
2624 line_start_position
= 0;
2626 if (line_start_position
> pos
)
2628 /* If the position sought is the end of the buffer,
2629 don't include the blank lines at the bottom of the window. */
2630 else if (line_start_position
== pos
2631 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
2633 maybe_next_line_p
= 1;
2636 else if (line_start_position
> 0)
2639 /* Don't overstep the last matrix row, lest we get into the
2640 never-never land... */
2641 if (row
->y
+ 1 >= yb
)
2647 /* Find the right column within BEST_ROW. */
2650 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
2652 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + i
;
2655 charpos
= glyph
->charpos
;
2662 else if (charpos
> pos
)
2664 else if (charpos
> 0)
2668 /* If we're looking for the end of the buffer,
2669 and we didn't find it in the line we scanned,
2670 use the start of the following line. */
2671 if (maybe_next_line_p
)
2678 *hpos
= lastcol
+ 1;
2683 term_mouse_highlight (struct frame
*f
, int x
, int y
)
2685 enum window_part part
;
2690 if (NILP (Vmouse_highlight
)
2691 || !f
->glyphs_initialized_p
)
2694 /* Which window is that in? */
2695 window
= window_from_coordinates (f
, x
, y
, &part
, &x
, &y
, 0);
2697 /* Not on a window -> return. */
2698 if (!WINDOWP (window
))
2701 if (!EQ (window
, mouse_face_window
))
2702 term_clear_mouse_face ();
2704 w
= XWINDOW (window
);
2706 /* Are we in a window whose display is up to date?
2707 And verify the buffer's text has not changed. */
2708 b
= XBUFFER (w
->buffer
);
2710 && EQ (w
->window_end_valid
, w
->buffer
)
2711 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
2712 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
2714 int pos
, i
, nrows
= w
->current_matrix
->nrows
;
2715 struct glyph_row
*row
;
2716 struct glyph
*glyph
;
2718 /* Find the glyph under X/Y. */
2720 if (y
>= 0 && y
< nrows
)
2722 row
= MATRIX_ROW (w
->current_matrix
, y
);
2723 /* Give up if some row before the one we are looking for is
2725 for (i
= 0; i
<= y
; i
++)
2726 if (!MATRIX_ROW (w
->current_matrix
, i
)->enabled_p
)
2728 if (i
> y
/* all rows upto and including the one at Y are enabled */
2729 && row
->displays_text_p
2730 && x
< window_box_width (w
, TEXT_AREA
))
2732 glyph
= row
->glyphs
[TEXT_AREA
];
2733 if (x
>= row
->used
[TEXT_AREA
])
2738 if (!BUFFERP (glyph
->object
))
2744 /* Clear mouse face if X/Y not over text. */
2747 term_clear_mouse_face ();
2751 if (!BUFFERP (glyph
->object
))
2753 pos
= glyph
->charpos
;
2755 /* Check for mouse-face. */
2757 extern Lisp_Object Qmouse_face
;
2758 Lisp_Object mouse_face
, overlay
, position
, *overlay_vec
;
2759 int noverlays
, obegv
, ozv
;
2760 struct buffer
*obuf
;
2762 /* If we get an out-of-range value, return now; avoid an error. */
2763 if (pos
> BUF_Z (b
))
2766 /* Make the window's buffer temporarily current for
2767 overlays_at and compute_char_face. */
2768 obuf
= current_buffer
;
2775 /* Is this char mouse-active? */
2776 XSETINT (position
, pos
);
2778 /* Put all the overlays we want in a vector in overlay_vec. */
2779 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
2780 /* Sort overlays into increasing priority order. */
2781 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
2783 /* Check mouse-face highlighting. */
2784 if (!(EQ (window
, mouse_face_window
)
2785 && y
>= mouse_face_beg_row
2786 && y
<= mouse_face_end_row
2787 && (y
> mouse_face_beg_row
2788 || x
>= mouse_face_beg_col
)
2789 && (y
< mouse_face_end_row
2790 || x
< mouse_face_end_col
2791 || mouse_face_past_end
)))
2793 /* Clear the display of the old active region, if any. */
2794 term_clear_mouse_face ();
2796 /* Find the highest priority overlay that has a mouse-face
2799 for (i
= noverlays
- 1; i
>= 0; --i
)
2801 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
2802 if (!NILP (mouse_face
))
2804 overlay
= overlay_vec
[i
];
2809 /* If no overlay applies, get a text property. */
2811 mouse_face
= Fget_text_property (position
, Qmouse_face
,
2814 /* Handle the overlay case. */
2815 if (!NILP (overlay
))
2817 /* Find the range of text around this char that
2818 should be active. */
2819 Lisp_Object before
, after
;
2823 before
= Foverlay_start (overlay
);
2824 after
= Foverlay_end (overlay
);
2825 /* Record this as the current active region. */
2826 fast_find_position (w
, XFASTINT (before
),
2827 &mouse_face_beg_col
,
2828 &mouse_face_beg_row
);
2831 = !fast_find_position (w
, XFASTINT (after
),
2832 &mouse_face_end_col
,
2833 &mouse_face_end_row
);
2834 mouse_face_window
= window
;
2837 = face_at_buffer_position (w
, pos
, 0, 0,
2838 &ignore
, pos
+ 1, 1, -1);
2840 /* Display it as active. */
2841 term_show_mouse_face (DRAW_MOUSE_FACE
);
2843 /* Handle the text property case. */
2844 else if (!NILP (mouse_face
))
2846 /* Find the range of text around this char that
2847 should be active. */
2848 Lisp_Object before
, after
, beginning
, end
;
2851 beginning
= Fmarker_position (w
->start
);
2852 XSETINT (end
, (BUF_Z (b
) - XFASTINT (w
->window_end_pos
)));
2854 = Fprevious_single_property_change (make_number (pos
+ 1),
2856 w
->buffer
, beginning
);
2858 = Fnext_single_property_change (position
, Qmouse_face
,
2861 /* Record this as the current active region. */
2862 fast_find_position (w
, XFASTINT (before
),
2863 &mouse_face_beg_col
,
2864 &mouse_face_beg_row
);
2866 = !fast_find_position (w
, XFASTINT (after
),
2867 &mouse_face_end_col
,
2868 &mouse_face_end_row
);
2869 mouse_face_window
= window
;
2872 = face_at_buffer_position (w
, pos
, 0, 0,
2873 &ignore
, pos
+ 1, 1, -1);
2875 /* Display it as active. */
2876 term_show_mouse_face (DRAW_MOUSE_FACE
);
2880 /* Look for a `help-echo' property. */
2883 extern Lisp_Object Qhelp_echo
;
2885 /* Check overlays first. */
2887 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
2889 overlay
= overlay_vec
[i
];
2890 help
= Foverlay_get (overlay
, Qhelp_echo
);
2895 help_echo_string
= help
;
2896 help_echo_window
= window
;
2897 help_echo_object
= overlay
;
2898 help_echo_pos
= pos
;
2900 /* Try text properties. */
2901 else if (NILP (help
)
2902 && ((STRINGP (glyph
->object
)
2903 && glyph
->charpos
>= 0
2904 && glyph
->charpos
< SCHARS (glyph
->object
))
2905 || (BUFFERP (glyph
->object
)
2906 && glyph
->charpos
>= BEGV
2907 && glyph
->charpos
< ZV
)))
2909 help
= Fget_text_property (make_number (glyph
->charpos
),
2910 Qhelp_echo
, glyph
->object
);
2913 help_echo_string
= help
;
2914 help_echo_window
= window
;
2915 help_echo_object
= glyph
->object
;
2916 help_echo_pos
= glyph
->charpos
;
2923 current_buffer
= obuf
;
2929 term_mouse_movement (FRAME_PTR frame
, Gpm_Event
*event
)
2931 /* Has the mouse moved off the glyph it was on at the last sighting? */
2932 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2934 frame
->mouse_moved
= 1;
2935 term_mouse_highlight (frame
, event
->x
, event
->y
);
2936 /* Remember which glyph we're now on. */
2937 last_mouse_x
= event
->x
;
2938 last_mouse_y
= event
->y
;
2944 /* Return the current position of the mouse.
2946 Set *f to the frame the mouse is in, or zero if the mouse is in no
2947 Emacs frame. If it is set to zero, all the other arguments are
2950 Set *bar_window to Qnil, and *x and *y to the column and
2951 row of the character cell the mouse is over.
2953 Set *time to the time the mouse was at the returned position.
2955 This clears mouse_moved until the next motion
2958 term_mouse_position (FRAME_PTR
*fp
, int insist
, Lisp_Object
*bar_window
,
2959 enum scroll_bar_part
*part
, Lisp_Object
*x
,
2960 Lisp_Object
*y
, unsigned long *time
)
2964 *fp
= SELECTED_FRAME ();
2965 (*fp
)->mouse_moved
= 0;
2970 XSETINT (*x
, last_mouse_x
);
2971 XSETINT (*y
, last_mouse_y
);
2972 gettimeofday(&now
, 0);
2973 *time
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2976 /* Prepare a mouse-event in *RESULT for placement in the input queue.
2978 If the event is a button press, then note that we have grabbed
2982 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
2988 result
->kind
= GPM_CLICK_EVENT
;
2989 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
2991 if (event
->buttons
& j
) {
2992 result
->code
= i
; /* button number */
2996 gettimeofday(&now
, 0);
2997 result
->timestamp
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2999 if (event
->type
& GPM_UP
)
3000 result
->modifiers
= up_modifier
;
3001 else if (event
->type
& GPM_DOWN
)
3002 result
->modifiers
= down_modifier
;
3004 result
->modifiers
= 0;
3006 if (event
->type
& GPM_SINGLE
)
3007 result
->modifiers
|= click_modifier
;
3009 if (event
->type
& GPM_DOUBLE
)
3010 result
->modifiers
|= double_modifier
;
3012 if (event
->type
& GPM_TRIPLE
)
3013 result
->modifiers
|= triple_modifier
;
3015 if (event
->type
& GPM_DRAG
)
3016 result
->modifiers
|= drag_modifier
;
3018 if (!(event
->type
& (GPM_MOVE
| GPM_DRAG
))) {
3021 if (event
->modifiers
& (1 << 0))
3022 result
->modifiers
|= shift_modifier
;
3025 if (event
->modifiers
& (1 << 2))
3026 result
->modifiers
|= ctrl_modifier
;
3028 /* 1 << KG_ALT || KG_ALTGR */
3029 if (event
->modifiers
& (1 << 3)
3030 || event
->modifiers
& (1 << 1))
3031 result
->modifiers
|= meta_modifier
;
3034 XSETINT (result
->x
, event
->x
);
3035 XSETINT (result
->y
, event
->y
);
3036 XSETFRAME (result
->frame_or_window
, f
);
3042 handle_one_term_event (struct tty_display_info
*tty
, Gpm_Event
*event
, struct input_event
* hold_quit
)
3044 struct frame
*f
= XFRAME (tty
->top_frame
);
3045 struct input_event ie
;
3053 if (event
->type
& (GPM_MOVE
| GPM_DRAG
)) {
3054 previous_help_echo_string
= help_echo_string
;
3055 help_echo_string
= Qnil
;
3057 Gpm_DrawPointer (event
->x
, event
->y
, fileno (tty
->output
));
3059 if (!term_mouse_movement (f
, event
))
3060 help_echo_string
= previous_help_echo_string
;
3062 /* If the contents of the global variable help_echo_string
3063 has changed, generate a HELP_EVENT. */
3064 if (!NILP (help_echo_string
)
3065 || !NILP (previous_help_echo_string
))
3072 term_mouse_click (&ie
, event
, f
);
3076 if (ie
.kind
!= NO_EVENT
)
3078 kbd_buffer_store_event_hold (&ie
, hold_quit
);
3083 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
3088 XSETFRAME (frame
, f
);
3092 gen_help_event (help_echo_string
, frame
, help_echo_window
,
3093 help_echo_object
, help_echo_pos
);
3100 DEFUN ("gpm-mouse-start", Fgpm_mouse_start
, Sgpm_mouse_start
,
3102 doc
: /* Open a connection to Gpm.
3103 Gpm-mouse can only be activated for one tty at a time. */)
3106 struct frame
*f
= SELECTED_FRAME ();
3107 struct tty_display_info
*tty
3108 = ((f
)->output_method
== output_termcap
3109 ? (f
)->terminal
->display_info
.tty
: NULL
);
3110 Gpm_Connect connection
;
3113 error ("Gpm-mouse only works in the GNU/Linux console");
3115 return Qnil
; /* Already activated, nothing to do. */
3117 error ("Gpm-mouse can only be activated for one tty at a time");
3119 connection
.eventMask
= ~0;
3120 connection
.defaultMask
= ~GPM_HARD
;
3121 connection
.maxMod
= ~0;
3122 connection
.minMod
= 0;
3125 if (Gpm_Open (&connection
, 0) < 0)
3126 error ("Gpm-mouse failed to connect to the gpm daemon");
3130 /* `init_sys_modes' arranges for mouse movements sent through gpm_fd
3131 to generate SIGIOs. Apparently we need to call reset_sys_modes
3132 before calling init_sys_modes. */
3133 reset_sys_modes (tty
);
3134 init_sys_modes (tty
);
3135 add_gpm_wait_descriptor (gpm_fd
);
3144 delete_gpm_wait_descriptor (fd
);
3145 while (Gpm_Close()); /* close all the stack */
3149 DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop
, Sgpm_mouse_stop
,
3151 doc
: /* Close a connection to Gpm. */)
3154 struct frame
*f
= SELECTED_FRAME ();
3155 struct tty_display_info
*tty
3156 = ((f
)->output_method
== output_termcap
3157 ? (f
)->terminal
->display_info
.tty
: NULL
);
3159 if (!tty
|| gpm_tty
!= tty
)
3160 return Qnil
; /* Not activated on this terminal, nothing to do. */
3165 #endif /* HAVE_GPM */
3169 /***********************************************************************
3171 ***********************************************************************/
3173 /* Initialize the tty-dependent part of frame F. The frame must
3174 already have its device initialized. */
3177 create_tty_output (struct frame
*f
)
3179 struct tty_output
*t
;
3181 if (! FRAME_TERMCAP_P (f
))
3184 t
= xmalloc (sizeof (struct tty_output
));
3185 bzero (t
, sizeof (struct tty_output
));
3187 t
->display_info
= FRAME_TERMINAL (f
)->display_info
.tty
;
3189 f
->output_data
.tty
= t
;
3192 /* Delete frame F's face cache, and its tty-dependent part. */
3195 tty_free_frame_resources (struct frame
*f
)
3197 if (! FRAME_TERMCAP_P (f
))
3200 if (FRAME_FACE_CACHE (f
))
3201 free_frame_faces (f
);
3203 xfree (f
->output_data
.tty
);
3208 /* Delete frame F's face cache. */
3211 tty_free_frame_resources (struct frame
*f
)
3213 if (! FRAME_TERMCAP_P (f
) && ! FRAME_MSDOS_P (f
))
3216 if (FRAME_FACE_CACHE (f
))
3217 free_frame_faces (f
);
3221 /* Reset the hooks in TERMINAL. */
3224 clear_tty_hooks (struct terminal
*terminal
)
3227 terminal
->cursor_to_hook
= 0;
3228 terminal
->raw_cursor_to_hook
= 0;
3229 terminal
->clear_to_end_hook
= 0;
3230 terminal
->clear_frame_hook
= 0;
3231 terminal
->clear_end_of_line_hook
= 0;
3232 terminal
->ins_del_lines_hook
= 0;
3233 terminal
->insert_glyphs_hook
= 0;
3234 terminal
->write_glyphs_hook
= 0;
3235 terminal
->delete_glyphs_hook
= 0;
3236 terminal
->ring_bell_hook
= 0;
3237 terminal
->reset_terminal_modes_hook
= 0;
3238 terminal
->set_terminal_modes_hook
= 0;
3239 terminal
->update_begin_hook
= 0;
3240 terminal
->update_end_hook
= 0;
3241 terminal
->set_terminal_window_hook
= 0;
3242 terminal
->mouse_position_hook
= 0;
3243 terminal
->frame_rehighlight_hook
= 0;
3244 terminal
->frame_raise_lower_hook
= 0;
3245 terminal
->fullscreen_hook
= 0;
3246 terminal
->set_vertical_scroll_bar_hook
= 0;
3247 terminal
->condemn_scroll_bars_hook
= 0;
3248 terminal
->redeem_scroll_bar_hook
= 0;
3249 terminal
->judge_scroll_bars_hook
= 0;
3250 terminal
->read_socket_hook
= 0;
3251 terminal
->frame_up_to_date_hook
= 0;
3253 /* Leave these two set, or suspended frames are not deleted
3255 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3256 terminal
->delete_terminal_hook
= &delete_tty
;
3259 /* Initialize hooks in TERMINAL with the values needed for a tty. */
3262 set_tty_hooks (struct terminal
*terminal
)
3264 terminal
->rif
= 0; /* ttys don't support window-based redisplay. */
3266 terminal
->cursor_to_hook
= &tty_cursor_to
;
3267 terminal
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
3269 terminal
->clear_to_end_hook
= &tty_clear_to_end
;
3270 terminal
->clear_frame_hook
= &tty_clear_frame
;
3271 terminal
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
3273 terminal
->ins_del_lines_hook
= &tty_ins_del_lines
;
3275 terminal
->insert_glyphs_hook
= &tty_insert_glyphs
;
3276 terminal
->write_glyphs_hook
= &tty_write_glyphs
;
3277 terminal
->delete_glyphs_hook
= &tty_delete_glyphs
;
3279 terminal
->ring_bell_hook
= &tty_ring_bell
;
3281 terminal
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
3282 terminal
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
3283 terminal
->update_begin_hook
= 0; /* Not needed. */
3284 terminal
->update_end_hook
= &tty_update_end
;
3285 terminal
->set_terminal_window_hook
= &tty_set_terminal_window
;
3287 terminal
->mouse_position_hook
= 0; /* Not needed. */
3288 terminal
->frame_rehighlight_hook
= 0; /* Not needed. */
3289 terminal
->frame_raise_lower_hook
= 0; /* Not needed. */
3291 terminal
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
3292 terminal
->condemn_scroll_bars_hook
= 0; /* Not needed. */
3293 terminal
->redeem_scroll_bar_hook
= 0; /* Not needed. */
3294 terminal
->judge_scroll_bars_hook
= 0; /* Not needed. */
3296 terminal
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
3297 terminal
->frame_up_to_date_hook
= 0; /* Not needed. */
3299 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3300 terminal
->delete_terminal_hook
= &delete_tty
;
3303 /* Drop the controlling terminal if fd is the same device. */
3305 dissociate_if_controlling_tty (int fd
)
3309 EMACS_GET_TTY_PGRP (fd
, &pgid
); /* If tcgetpgrp succeeds, fd is the ctty. */
3312 #if defined (USG) && !defined (BSD_PGRPS)
3314 no_controlling_tty
= 1;
3315 #elif defined (CYGWIN)
3317 no_controlling_tty
= 1;
3319 #ifdef TIOCNOTTY /* Try BSD ioctls. */
3320 sigblock (sigmask (SIGTTOU
));
3321 fd
= emacs_open (DEV_TTY
, O_RDWR
, 0);
3322 if (fd
!= -1 && ioctl (fd
, TIOCNOTTY
, 0) != -1)
3324 no_controlling_tty
= 1;
3328 sigunblock (sigmask (SIGTTOU
));
3330 /* Unknown system. */
3332 #endif /* ! TIOCNOTTY */
3335 #endif /* !DOS_NT */
3338 static void maybe_fatal();
3340 /* Create a termcap display on the tty device with the given name and
3343 If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
3344 Otherwise NAME should be a path to the tty device file,
3347 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
3349 If MUST_SUCCEED is true, then all errors are fatal. */
3352 init_tty (char *name
, char *terminal_type
, int must_succeed
)
3355 char **address
= &area
;
3356 int buffer_size
= 4096;
3357 register char *p
= NULL
;
3359 struct tty_display_info
*tty
= NULL
;
3360 struct terminal
*terminal
= NULL
;
3361 int ctty
= 0; /* 1 if asked to open controlling tty. */
3364 maybe_fatal (must_succeed
, 0,
3365 "Unknown terminal type",
3366 "Unknown terminal type");
3370 if (!strcmp (name
, DEV_TTY
))
3373 /* If we already have a terminal on the given device, use that. If
3374 all such terminals are suspended, create a new one instead. */
3375 /* XXX Perhaps this should be made explicit by having init_tty
3376 always create a new terminal and separating terminal and frame
3377 creation on Lisp level. */
3378 terminal
= get_named_tty (name
);
3382 terminal
= create_terminal ();
3385 maybe_fatal (1, 0, "Attempt to create another terminal %s", "",
3388 tty
= &the_only_display_info
;
3390 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
3392 bzero (tty
, sizeof (struct tty_display_info
));
3393 tty
->next
= tty_list
;
3396 terminal
->type
= output_termcap
;
3397 terminal
->display_info
.tty
= tty
;
3398 tty
->terminal
= terminal
;
3400 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
3404 set_tty_hooks (terminal
);
3410 #ifdef O_IGNORE_CTTY
3412 /* Open the terminal device. Don't recognize it as our
3413 controlling terminal, and don't make it the controlling tty
3414 if we don't have one at the moment. */
3415 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
3418 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
3419 defined on Hurd. On other systems, we need to explicitly
3420 dissociate ourselves from the controlling tty when we want to
3421 open a frame on the same terminal. */
3422 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
3423 #endif /* O_IGNORE_CTTY */
3425 tty
->name
= xstrdup (name
);
3426 terminal
->name
= xstrdup (name
);
3429 maybe_fatal (must_succeed
, terminal
,
3430 "Could not open file: %s",
3431 "Could not open file: %s",
3436 maybe_fatal (must_succeed
, terminal
,
3437 "Not a tty device: %s",
3438 "Not a tty device: %s",
3442 #ifndef O_IGNORE_CTTY
3444 dissociate_if_controlling_tty (fd
);
3447 file
= fdopen (fd
, "w+");
3452 tty
->type
= xstrdup (terminal_type
);
3454 add_keyboard_wait_descriptor (fileno (tty
->input
));
3456 #endif /* !DOS_NT */
3458 encode_terminal_src_size
= 0;
3459 encode_terminal_dst_size
= 0;
3462 terminal
->mouse_position_hook
= term_mouse_position
;
3463 mouse_face_window
= Qnil
;
3468 initialize_w32_display (terminal
);
3470 if (strcmp (terminal_type
, "internal") == 0)
3471 terminal
->type
= output_msdos_raw
;
3472 initialize_msdos_display (terminal
);
3474 tty
->output
= stdout
;
3476 /* The following two are inaccessible from w32console.c. */
3477 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3478 terminal
->delete_terminal_hook
= &delete_tty
;
3480 tty
->name
= xstrdup (name
);
3481 terminal
->name
= xstrdup (name
);
3482 tty
->type
= xstrdup (terminal_type
);
3485 add_keyboard_wait_descriptor (0);
3492 struct frame
*f
= XFRAME (selected_frame
);
3494 FrameRows (tty
) = FRAME_LINES (f
);
3495 FrameCols (tty
) = FRAME_COLS (f
);
3496 tty
->specified_window
= FRAME_LINES (f
);
3498 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
3499 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
3504 get_tty_size (fileno (tty
->input
), &width
, &height
);
3505 FrameCols (tty
) = width
;
3506 FrameRows (tty
) = height
;
3509 tty
->delete_in_insert_mode
= 1;
3512 terminal
->scroll_region_ok
= 0;
3514 /* Seems to insert lines when it's not supposed to, messing up the
3515 display. In doing a trace, it didn't seem to be called much, so I
3516 don't think we're losing anything by turning it off. */
3517 terminal
->line_ins_del_ok
= 0;
3519 terminal
->char_ins_del_ok
= 1;
3522 terminal
->char_ins_del_ok
= 0;
3523 init_baud_rate (fileno (tty
->input
));
3526 tty
->TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
3528 #else /* not DOS_NT */
3532 tty
->termcap_term_buffer
= (char *) xmalloc (buffer_size
);
3534 /* On some systems, tgetent tries to access the controlling
3536 sigblock (sigmask (SIGTTOU
));
3537 status
= tgetent (tty
->termcap_term_buffer
, terminal_type
);
3538 sigunblock (sigmask (SIGTTOU
));
3543 maybe_fatal (must_succeed
, terminal
,
3544 "Cannot open terminfo database file",
3545 "Cannot open terminfo database file");
3547 maybe_fatal (must_succeed
, terminal
,
3548 "Cannot open termcap database file",
3549 "Cannot open termcap database file");
3555 maybe_fatal (must_succeed
, terminal
,
3556 "Terminal type %s is not defined",
3557 "Terminal type %s is not defined.\n\
3558 If that is not the actual type of terminal you have,\n\
3559 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3560 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3561 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3564 maybe_fatal (must_succeed
, terminal
,
3565 "Terminal type %s is not defined",
3566 "Terminal type %s is not defined.\n\
3567 If that is not the actual type of terminal you have,\n\
3568 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3569 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3570 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3576 if (strlen (tty
->termcap_term_buffer
) >= buffer_size
)
3578 buffer_size
= strlen (tty
->termcap_term_buffer
);
3580 tty
->termcap_strings_buffer
= area
= (char *) xmalloc (buffer_size
);
3581 tty
->TS_ins_line
= tgetstr ("al", address
);
3582 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
3583 tty
->TS_bell
= tgetstr ("bl", address
);
3584 BackTab (tty
) = tgetstr ("bt", address
);
3585 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
3586 tty
->TS_clr_line
= tgetstr ("ce", address
);
3587 tty
->TS_clr_frame
= tgetstr ("cl", address
);
3588 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
3589 AbsPosition (tty
) = tgetstr ("cm", address
);
3590 CR (tty
) = tgetstr ("cr", address
);
3591 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
3592 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
3593 RowPosition (tty
) = tgetstr ("cv", address
);
3594 tty
->TS_del_char
= tgetstr ("dc", address
);
3595 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
3596 tty
->TS_del_line
= tgetstr ("dl", address
);
3597 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
3598 tty
->TS_delete_mode
= tgetstr ("dm", address
);
3599 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
3600 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
3601 Home (tty
) = tgetstr ("ho", address
);
3602 tty
->TS_ins_char
= tgetstr ("ic", address
);
3603 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
3604 tty
->TS_insert_mode
= tgetstr ("im", address
);
3605 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
3606 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
3607 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
3608 LastLine (tty
) = tgetstr ("ll", address
);
3609 Right (tty
) = tgetstr ("nd", address
);
3610 Down (tty
) = tgetstr ("do", address
);
3612 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
3613 if (tgetflag ("bs"))
3614 Left (tty
) = "\b"; /* can't possibly be longer! */
3615 else /* (Actually, "bs" is obsolete...) */
3616 Left (tty
) = tgetstr ("le", address
);
3618 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
3619 tty
->TS_pad_char
= tgetstr ("pc", address
);
3620 tty
->TS_repeat
= tgetstr ("rp", address
);
3621 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
3622 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
3623 tty
->TS_standout_mode
= tgetstr ("so", address
);
3624 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
3625 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
3626 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
3627 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
3628 Up (tty
) = tgetstr ("up", address
);
3629 tty
->TS_visible_bell
= tgetstr ("vb", address
);
3630 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
3631 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
3632 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
3633 tty
->TS_set_window
= tgetstr ("wi", address
);
3635 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
3636 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
3637 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
3638 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
3639 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
3640 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
3641 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3642 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3643 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
3645 MultiUp (tty
) = tgetstr ("UP", address
);
3646 MultiDown (tty
) = tgetstr ("DO", address
);
3647 MultiLeft (tty
) = tgetstr ("LE", address
);
3648 MultiRight (tty
) = tgetstr ("RI", address
);
3650 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
3651 color because we can't switch back to the default foreground and
3653 tty
->TS_orig_pair
= tgetstr ("op", address
);
3654 if (tty
->TS_orig_pair
)
3656 tty
->TS_set_foreground
= tgetstr ("AF", address
);
3657 tty
->TS_set_background
= tgetstr ("AB", address
);
3658 if (!tty
->TS_set_foreground
)
3661 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
3662 tty
->TS_set_background
= tgetstr ("Sb", address
);
3665 tty
->TN_max_colors
= tgetnum ("Co");
3666 tty
->TN_max_pairs
= tgetnum ("pa");
3668 tty
->TN_no_color_video
= tgetnum ("NC");
3669 if (tty
->TN_no_color_video
== -1)
3670 tty
->TN_no_color_video
= 0;
3673 tty_default_color_capabilities (tty
, 1);
3675 MagicWrap (tty
) = tgetflag ("xn");
3676 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3677 the former flag imply the latter. */
3678 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
3679 terminal
->memory_below_frame
= tgetflag ("db");
3680 tty
->TF_hazeltine
= tgetflag ("hz");
3681 terminal
->must_write_spaces
= tgetflag ("in");
3682 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
3683 tty
->TF_insmode_motion
= tgetflag ("mi");
3684 tty
->TF_standout_motion
= tgetflag ("ms");
3685 tty
->TF_underscore
= tgetflag ("ul");
3686 tty
->TF_teleray
= tgetflag ("xt");
3688 #endif /* !DOS_NT */
3689 terminal
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
3690 init_kboard (terminal
->kboard
);
3691 terminal
->kboard
->Vwindow_system
= Qnil
;
3692 terminal
->kboard
->next_kboard
= all_kboards
;
3693 all_kboards
= terminal
->kboard
;
3694 terminal
->kboard
->reference_count
++;
3695 /* Don't let the initial kboard remain current longer than necessary.
3696 That would cause problems if a file loaded on startup tries to
3697 prompt in the mini-buffer. */
3698 if (current_kboard
== initial_kboard
)
3699 current_kboard
= terminal
->kboard
;
3701 term_get_fkeys (address
, terminal
->kboard
);
3703 /* Get frame size from system, or else from termcap. */
3706 get_tty_size (fileno (tty
->input
), &width
, &height
);
3707 FrameCols (tty
) = width
;
3708 FrameRows (tty
) = height
;
3711 if (FrameCols (tty
) <= 0)
3712 FrameCols (tty
) = tgetnum ("co");
3713 if (FrameRows (tty
) <= 0)
3714 FrameRows (tty
) = tgetnum ("li");
3716 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
3717 maybe_fatal (must_succeed
, terminal
,
3718 "Screen size %dx%d is too small"
3719 "Screen size %dx%d is too small",
3720 FrameCols (tty
), FrameRows (tty
));
3722 TabWidth (tty
) = tgetnum ("tw");
3725 tty
->TS_bell
= "\07";
3727 if (!tty
->TS_fwd_scroll
)
3728 tty
->TS_fwd_scroll
= Down (tty
);
3730 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
3732 if (TabWidth (tty
) < 0)
3735 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3736 and newer termcap doc does not seem to say there is a default.
3737 if (!tty->Wcm->cm_tab)
3738 tty->Wcm->cm_tab = "\t";
3741 /* We don't support standout modes that use `magic cookies', so
3742 turn off any that do. */
3743 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
3745 tty
->TS_standout_mode
= 0;
3746 tty
->TS_end_standout_mode
= 0;
3748 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3750 tty
->TS_enter_underline_mode
= 0;
3751 tty
->TS_exit_underline_mode
= 0;
3754 /* If there's no standout mode, try to use underlining instead. */
3755 if (tty
->TS_standout_mode
== 0)
3757 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
3758 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
3761 /* If no `se' string, try using a `me' string instead.
3762 If that fails, we can't use standout mode at all. */
3763 if (tty
->TS_end_standout_mode
== 0)
3765 char *s
= tgetstr ("me", address
);
3767 tty
->TS_end_standout_mode
= s
;
3769 tty
->TS_standout_mode
= 0;
3772 if (tty
->TF_teleray
)
3774 tty
->Wcm
->cm_tab
= 0;
3775 /* We can't support standout mode, because it uses magic cookies. */
3776 tty
->TS_standout_mode
= 0;
3777 /* But that means we cannot rely on ^M to go to column zero! */
3779 /* LF can't be trusted either -- can alter hpos */
3780 /* if move at column 0 thru a line with TS_standout_mode */
3784 /* Special handling for certain terminal types known to need it */
3786 if (!strcmp (terminal_type
, "supdup"))
3788 terminal
->memory_below_frame
= 1;
3789 tty
->Wcm
->cm_losewrap
= 1;
3791 if (!strncmp (terminal_type
, "c10", 3)
3792 || !strcmp (terminal_type
, "perq"))
3794 /* Supply a makeshift :wi string.
3795 This string is not valid in general since it works only
3796 for windows starting at the upper left corner;
3797 but that is all Emacs uses.
3799 This string works only if the frame is using
3800 the top of the video memory, because addressing is memory-relative.
3801 So first check the :ti string to see if that is true.
3803 It would be simpler if the :wi string could go in the termcap
3804 entry, but it can't because it is not fully valid.
3805 If it were in the termcap entry, it would confuse other programs. */
3806 if (!tty
->TS_set_window
)
3808 p
= tty
->TS_termcap_modes
;
3809 while (*p
&& strcmp (p
, "\033v "))
3812 tty
->TS_set_window
= "\033v%C %C %C %C ";
3814 /* Termcap entry often fails to have :in: flag */
3815 terminal
->must_write_spaces
= 1;
3816 /* :ti string typically fails to have \E^G! in it */
3817 /* This limits scope of insert-char to one line. */
3818 strcpy (area
, tty
->TS_termcap_modes
);
3819 strcat (area
, "\033\007!");
3820 tty
->TS_termcap_modes
= area
;
3821 area
+= strlen (area
) + 1;
3822 p
= AbsPosition (tty
);
3823 /* Change all %+ parameters to %C, to handle
3824 values above 96 correctly for the C100. */
3827 if (p
[0] == '%' && p
[1] == '+')
3833 tty
->specified_window
= FrameRows (tty
);
3835 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
3837 maybe_fatal (must_succeed
, terminal
,
3838 "Terminal type \"%s\" is not powerful enough to run Emacs",
3840 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3841 It lacks the ability to position the cursor.\n\
3842 If that is not the actual type of terminal you have,\n\
3843 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3844 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3845 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3846 # else /* TERMCAP */
3847 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3848 It lacks the ability to position the cursor.\n\
3849 If that is not the actual type of terminal you have,\n\
3850 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3851 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3852 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3853 # endif /* TERMINFO */
3857 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
3858 maybe_fatal (must_succeed
, terminal
,
3859 "Could not determine the frame size",
3860 "Could not determine the frame size");
3862 tty
->delete_in_insert_mode
3863 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
3864 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
3866 tty
->se_is_so
= (tty
->TS_standout_mode
3867 && tty
->TS_end_standout_mode
3868 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
3870 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
3872 terminal
->scroll_region_ok
3874 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
3876 terminal
->line_ins_del_ok
3877 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
3878 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
3879 || (terminal
->scroll_region_ok
3880 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
3882 terminal
->char_ins_del_ok
3883 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
3884 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
3885 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
3887 terminal
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
3889 init_baud_rate (fileno (tty
->input
));
3891 #endif /* not DOS_NT */
3893 /* Init system terminal modes (RAW or CBREAK, etc.). */
3894 init_sys_modes (tty
);
3899 /* Auxiliary error-handling function for init_tty.
3900 Delete TERMINAL, then call error or fatal with str1 or str2,
3901 respectively, according to MUST_SUCCEED. */
3904 maybe_fatal (must_succeed
, terminal
, str1
, str2
, arg1
, arg2
)
3906 struct terminal
*terminal
;
3907 char *str1
, *str2
, *arg1
, *arg2
;
3910 delete_tty (terminal
);
3913 fatal (str2
, arg1
, arg2
);
3915 error (str1
, arg1
, arg2
);
3921 fatal (const char *str
, ...)
3925 fprintf (stderr
, "emacs: ");
3926 vfprintf (stderr
, str
, ap
);
3927 if (!(strlen (str
) > 0 && str
[strlen (str
) - 1] == '\n'))
3928 fprintf (stderr
, "\n");
3936 /* Delete the given tty terminal, closing all frames on it. */
3939 delete_tty (struct terminal
*terminal
)
3941 struct tty_display_info
*tty
;
3943 /* Protect against recursive calls. delete_frame in
3944 delete_terminal calls us back when it deletes our last frame. */
3945 if (!terminal
->name
)
3948 if (terminal
->type
!= output_termcap
)
3951 tty
= terminal
->display_info
.tty
;
3953 if (tty
== tty_list
)
3954 tty_list
= tty
->next
;
3957 struct tty_display_info
*p
;
3958 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
3962 /* This should not happen. */
3965 p
->next
= tty
->next
;
3969 /* reset_sys_modes needs a valid device, so this call needs to be
3970 before delete_terminal. */
3971 reset_sys_modes (tty
);
3973 delete_terminal (terminal
);
3981 delete_keyboard_wait_descriptor (fileno (tty
->input
));
3983 if (tty
->input
!= stdin
)
3984 fclose (tty
->input
);
3986 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
3987 fclose (tty
->output
);
3988 if (tty
->termscript
)
3989 fclose (tty
->termscript
);
3991 xfree (tty
->old_tty
);
3993 xfree (tty
->termcap_strings_buffer
);
3994 xfree (tty
->termcap_term_buffer
);
3996 bzero (tty
, sizeof (struct tty_display_info
));
4002 /* Mark the pointers in the tty_display_info objects.
4003 Called by the Fgarbage_collector. */
4008 struct tty_display_info
*tty
;
4010 for (tty
= tty_list
; tty
; tty
= tty
->next
)
4011 mark_object (tty
->top_frame
);
4019 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
4020 doc
: /* Non-nil means the system uses terminfo rather than termcap.
4021 This variable can be used by terminal emulator packages. */);
4023 system_uses_terminfo
= 1;
4025 system_uses_terminfo
= 0;
4028 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions
,
4029 doc
: /* Functions to be run after suspending a tty.
4030 The functions are run with one argument, the terminal object to be suspended.
4031 See `suspend-tty'. */);
4032 Vsuspend_tty_functions
= Qnil
;
4035 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions
,
4036 doc
: /* Functions to be run after resuming a tty.
4037 The functions are run with one argument, the terminal object that was revived.
4038 See `resume-tty'. */);
4039 Vresume_tty_functions
= Qnil
;
4041 DEFVAR_BOOL ("visible-cursor", &visible_cursor
,
4042 doc
: /* Non-nil means to make the cursor very visible.
4043 This only has an effect when running in a text terminal.
4044 What means \"very visible\" is up to your terminal. It may make the cursor
4045 bigger, or it may make it blink, or it may do nothing at all. */);
4048 defsubr (&Stty_display_color_p
);
4049 defsubr (&Stty_display_color_cells
);
4050 defsubr (&Stty_no_underline
);
4051 defsubr (&Stty_type
);
4052 defsubr (&Scontrolling_tty_p
);
4053 defsubr (&Ssuspend_tty
);
4054 defsubr (&Sresume_tty
);
4056 defsubr (&Sgpm_mouse_start
);
4057 defsubr (&Sgpm_mouse_stop
);
4059 staticpro (&mouse_face_window
);
4060 #endif /* HAVE_GPM */
4063 default_orig_pair
= NULL
;
4064 default_set_foreground
= NULL
;
4065 default_set_background
= NULL
;
4066 #endif /* !DOS_NT */
4068 encode_terminal_src
= NULL
;
4069 encode_terminal_dst
= NULL
;
4074 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
4075 (do not change this comment) */