1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
35 #include <termios.h> /* For TIOCNOTTY. */
46 #include "character.h"
49 #include "composite.h"
53 #include "termhooks.h"
54 #include "dispextern.h"
57 #include "blockinput.h"
58 #include "syssignal.h"
60 #include "intervals.h"
63 static int been_here
= -1;
66 /* For now, don't try to include termcap.h. On some systems,
67 configure finds a non-standard termcap.h that the main build
70 #if defined HAVE_TERMCAP_H && 0
73 extern void tputs
P_ ((const char *, int, int (*)(int)));
74 extern int tgetent
P_ ((char *, const char *));
75 extern int tgetflag
P_ ((char *id
));
76 extern int tgetnum
P_ ((char *id
));
92 /* The name of the default console device. */
94 #define DEV_TTY "CONOUT$"
96 #define DEV_TTY "/dev/tty"
99 static void tty_set_scroll_region
P_ ((struct frame
*f
, int start
, int stop
));
100 static void turn_on_face
P_ ((struct frame
*, int face_id
));
101 static void turn_off_face
P_ ((struct frame
*, int face_id
));
102 static void tty_show_cursor
P_ ((struct tty_display_info
*));
103 static void tty_hide_cursor
P_ ((struct tty_display_info
*));
104 static void tty_background_highlight
P_ ((struct tty_display_info
*tty
));
105 static void clear_tty_hooks
P_ ((struct terminal
*terminal
));
106 static void set_tty_hooks
P_ ((struct terminal
*terminal
));
107 static void dissociate_if_controlling_tty
P_ ((int fd
));
108 static void delete_tty
P_ ((struct terminal
*));
110 #define OUTPUT(tty, a) \
111 emacs_tputs ((tty), a, \
112 (int) (FRAME_LINES (XFRAME (selected_frame)) \
116 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
117 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
119 #define OUTPUT_IF(tty, a) \
122 emacs_tputs ((tty), a, \
123 (int) (FRAME_LINES (XFRAME (selected_frame)) \
128 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
130 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */
132 static int visible_cursor
;
134 /* Display space properties */
136 extern Lisp_Object Qspace
, QCalign_to
, QCwidth
;
138 /* Functions to call after suspending a tty. */
139 Lisp_Object Vsuspend_tty_functions
;
141 /* Functions to call after resuming a tty. */
142 Lisp_Object Vresume_tty_functions
;
144 /* Chain of all tty device parameters. */
145 struct tty_display_info
*tty_list
;
147 /* Nonzero means no need to redraw the entire frame on resuming a
148 suspended Emacs. This is useful on terminals with multiple
149 pages, where one page is used for Emacs and another for all
151 int no_redraw_on_reenter
;
153 /* Meaning of bits in no_color_video. Each bit set means that the
154 corresponding attribute cannot be combined with colors. */
158 NC_STANDOUT
= 1 << 0,
159 NC_UNDERLINE
= 1 << 1,
166 NC_ALT_CHARSET
= 1 << 8
171 /* The largest frame width in any call to calculate_costs. */
175 /* The largest frame height in any call to calculate_costs. */
179 /* Non-zero if we have dropped our controlling tty and therefore
180 should not open a frame on stdout. */
181 static int no_controlling_tty
;
183 /* Provided for lisp packages. */
185 static int system_uses_terminfo
;
189 extern char *tgetstr ();
193 #include <sys/fcntl.h>
195 static void term_clear_mouse_face ();
196 static void term_mouse_highlight (struct frame
*f
, int x
, int y
);
198 /* The device for which we have enabled gpm support (or NULL). */
199 struct tty_display_info
*gpm_tty
= NULL
;
201 /* These variables describe the range of text currently shown in its
202 mouse-face, together with the window they apply to. As long as
203 the mouse stays within this range, we need not redraw anything on
204 its account. Rows and columns are glyph matrix positions in
205 MOUSE_FACE_WINDOW. */
206 static int mouse_face_beg_row
, mouse_face_beg_col
;
207 static int mouse_face_end_row
, mouse_face_end_col
;
208 static int mouse_face_past_end
;
209 static Lisp_Object mouse_face_window
;
210 static int mouse_face_face_id
;
212 static int pos_x
, pos_y
;
213 static int last_mouse_x
, last_mouse_y
;
214 #endif /* HAVE_GPM */
216 /* Ring the bell on a tty. */
219 tty_ring_bell (struct frame
*f
)
221 struct tty_display_info
*tty
= FRAME_TTY (f
);
225 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
226 ? tty
->TS_visible_bell
228 fflush (tty
->output
);
232 /* Set up termcap modes for Emacs. */
235 tty_set_terminal_modes (struct terminal
*terminal
)
237 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
241 if (tty
->TS_termcap_modes
)
242 OUTPUT (tty
, tty
->TS_termcap_modes
);
245 /* Output enough newlines to scroll all the old screen contents
246 off the screen, so it won't be overwritten and lost. */
249 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
253 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
254 OUTPUT_IF (tty
, visible_cursor
? tty
->TS_cursor_visible
: tty
->TS_cursor_normal
);
255 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
257 fflush (tty
->output
);
261 /* Reset termcap modes before exiting Emacs. */
264 tty_reset_terminal_modes (struct terminal
*terminal
)
266 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
270 tty_turn_off_highlight (tty
);
271 tty_turn_off_insert (tty
);
272 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
273 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
274 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
275 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
276 /* Output raw CR so kernel can track the cursor hpos. */
279 fflush (tty
->output
);
283 /* Flag the end of a display update on a termcap terminal. */
286 tty_update_end (struct frame
*f
)
288 struct tty_display_info
*tty
= FRAME_TTY (f
);
290 if (!XWINDOW (selected_window
)->cursor_off_p
)
291 tty_show_cursor (tty
);
292 tty_turn_off_insert (tty
);
293 tty_background_highlight (tty
);
296 /* The implementation of set_terminal_window for termcap frames. */
299 tty_set_terminal_window (struct frame
*f
, int size
)
301 struct tty_display_info
*tty
= FRAME_TTY (f
);
303 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
304 if (FRAME_SCROLL_REGION_OK (f
))
305 tty_set_scroll_region (f
, 0, tty
->specified_window
);
309 tty_set_scroll_region (struct frame
*f
, int start
, int stop
)
312 struct tty_display_info
*tty
= FRAME_TTY (f
);
314 if (tty
->TS_set_scroll_region
)
315 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
316 else if (tty
->TS_set_scroll_region_1
)
317 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
318 FRAME_LINES (f
), start
,
319 FRAME_LINES (f
) - stop
,
322 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
331 tty_turn_on_insert (struct tty_display_info
*tty
)
333 if (!tty
->insert_mode
)
334 OUTPUT (tty
, tty
->TS_insert_mode
);
335 tty
->insert_mode
= 1;
339 tty_turn_off_insert (struct tty_display_info
*tty
)
341 if (tty
->insert_mode
)
342 OUTPUT (tty
, tty
->TS_end_insert_mode
);
343 tty
->insert_mode
= 0;
346 /* Handle highlighting. */
349 tty_turn_off_highlight (struct tty_display_info
*tty
)
351 if (tty
->standout_mode
)
352 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
353 tty
->standout_mode
= 0;
357 tty_turn_on_highlight (struct tty_display_info
*tty
)
359 if (!tty
->standout_mode
)
360 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
361 tty
->standout_mode
= 1;
365 tty_toggle_highlight (struct tty_display_info
*tty
)
367 if (tty
->standout_mode
)
368 tty_turn_off_highlight (tty
);
370 tty_turn_on_highlight (tty
);
374 /* Make cursor invisible. */
377 tty_hide_cursor (struct tty_display_info
*tty
)
379 if (tty
->cursor_hidden
== 0)
381 tty
->cursor_hidden
= 1;
382 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
387 /* Ensure that cursor is visible. */
390 tty_show_cursor (struct tty_display_info
*tty
)
392 if (tty
->cursor_hidden
)
394 tty
->cursor_hidden
= 0;
395 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
397 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
402 /* Set standout mode to the state it should be in for
403 empty space inside windows. What this is,
404 depends on the user option inverse-video. */
407 tty_background_highlight (struct tty_display_info
*tty
)
410 tty_turn_on_highlight (tty
);
412 tty_turn_off_highlight (tty
);
415 /* Set standout mode to the mode specified for the text to be output. */
418 tty_highlight_if_desired (struct tty_display_info
*tty
)
421 tty_turn_on_highlight (tty
);
423 tty_turn_off_highlight (tty
);
427 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
428 frame-relative coordinates. */
431 tty_cursor_to (struct frame
*f
, int vpos
, int hpos
)
433 struct tty_display_info
*tty
= FRAME_TTY (f
);
435 /* Detect the case where we are called from reset_sys_modes
436 and the costs have never been calculated. Do nothing. */
437 if (! tty
->costs_set
)
440 if (curY (tty
) == vpos
441 && curX (tty
) == hpos
)
443 if (!tty
->TF_standout_motion
)
444 tty_background_highlight (tty
);
445 if (!tty
->TF_insmode_motion
)
446 tty_turn_off_insert (tty
);
447 cmgoto (tty
, vpos
, hpos
);
450 /* Similar but don't take any account of the wasted characters. */
453 tty_raw_cursor_to (struct frame
*f
, int row
, int col
)
455 struct tty_display_info
*tty
= FRAME_TTY (f
);
457 if (curY (tty
) == row
458 && curX (tty
) == col
)
460 if (!tty
->TF_standout_motion
)
461 tty_background_highlight (tty
);
462 if (!tty
->TF_insmode_motion
)
463 tty_turn_off_insert (tty
);
464 cmgoto (tty
, row
, col
);
467 /* Erase operations */
469 /* Clear from cursor to end of frame on a termcap device. */
472 tty_clear_to_end (struct frame
*f
)
475 struct tty_display_info
*tty
= FRAME_TTY (f
);
477 if (tty
->TS_clr_to_bottom
)
479 tty_background_highlight (tty
);
480 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
484 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
487 clear_end_of_line (f
, FRAME_COLS (f
));
492 /* Clear an entire termcap frame. */
495 tty_clear_frame (struct frame
*f
)
497 struct tty_display_info
*tty
= FRAME_TTY (f
);
499 if (tty
->TS_clr_frame
)
501 tty_background_highlight (tty
);
502 OUTPUT (tty
, tty
->TS_clr_frame
);
512 /* An implementation of clear_end_of_line for termcap frames.
514 Note that the cursor may be moved, on terminals lacking a `ce' string. */
517 tty_clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
520 struct tty_display_info
*tty
= FRAME_TTY (f
);
522 /* Detect the case where we are called from reset_sys_modes
523 and the costs have never been calculated. Do nothing. */
524 if (! tty
->costs_set
)
527 if (curX (tty
) >= first_unused_hpos
)
529 tty_background_highlight (tty
);
530 if (tty
->TS_clr_line
)
532 OUTPUT1 (tty
, tty
->TS_clr_line
);
535 { /* have to do it the hard way */
536 tty_turn_off_insert (tty
);
538 /* Do not write in last row last col with Auto-wrap on. */
540 && curY (tty
) == FrameRows (tty
) - 1
541 && first_unused_hpos
== FrameCols (tty
))
544 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
547 fputc (' ', tty
->termscript
);
548 fputc (' ', tty
->output
);
550 cmplus (tty
, first_unused_hpos
- curX (tty
));
554 /* Buffers to store the source and result of code conversion for terminal. */
555 static unsigned char *encode_terminal_src
;
556 static unsigned char *encode_terminal_dst
;
557 /* Allocated sizes of the above buffers. */
558 static int encode_terminal_src_size
;
559 static int encode_terminal_dst_size
;
561 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
562 Set CODING->produced to the byte-length of the resulting byte
563 sequence, and return a pointer to that byte sequence. */
566 encode_terminal_code (src
, src_len
, coding
)
569 struct coding_system
*coding
;
571 struct glyph
*src_end
= src
+ src_len
;
573 int nchars
, nbytes
, required
;
574 register int tlen
= GLYPH_TABLE_LENGTH
;
575 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
576 Lisp_Object charset_list
;
578 /* Allocate sufficient size of buffer to store all characters in
579 multibyte-form. But, it may be enlarged on demand if
580 Vglyph_table contains a string or a composite glyph is
582 required
= MAX_MULTIBYTE_LENGTH
* src_len
;
583 if (encode_terminal_src_size
< required
)
585 if (encode_terminal_src
)
586 encode_terminal_src
= xrealloc (encode_terminal_src
, required
);
588 encode_terminal_src
= xmalloc (required
);
589 encode_terminal_src_size
= required
;
592 charset_list
= coding_charset_list (coding
);
594 buf
= encode_terminal_src
;
596 while (src
< src_end
)
598 if (src
->type
== COMPOSITE_GLYPH
)
600 struct composition
*cmp
;
604 nbytes
= buf
- encode_terminal_src
;
605 if (src
->u
.cmp
.automatic
)
607 gstring
= composition_gstring_from_id (src
->u
.cmp
.id
);
608 required
= src
->u
.cmp
.to
+ 1 - src
->u
.cmp
.from
;
612 cmp
= composition_table
[src
->u
.cmp
.id
];
613 required
= MAX_MULTIBYTE_LENGTH
* cmp
->glyph_len
;
616 if (encode_terminal_src_size
< nbytes
+ required
)
618 encode_terminal_src_size
= nbytes
+ required
;
619 encode_terminal_src
= xrealloc (encode_terminal_src
,
620 encode_terminal_src_size
);
621 buf
= encode_terminal_src
+ nbytes
;
624 if (src
->u
.cmp
.automatic
)
625 for (i
= src
->u
.cmp
.from
; i
<= src
->u
.cmp
.to
; i
++)
627 Lisp_Object g
= LGSTRING_GLYPH (gstring
, i
);
628 int c
= LGLYPH_CHAR (g
);
630 if (! char_charset (c
, charset_list
, NULL
))
632 buf
+= CHAR_STRING (c
, buf
);
636 for (i
= 0; i
< cmp
->glyph_len
; i
++)
638 int c
= COMPOSITION_GLYPH (cmp
, i
);
642 if (char_charset (c
, charset_list
, NULL
))
644 if (CHAR_WIDTH (c
) == 0
645 && i
> 0 && COMPOSITION_GLYPH (cmp
, i
- 1) == '\t')
646 /* Should be left-padded */
648 buf
+= CHAR_STRING (' ', buf
);
654 buf
+= CHAR_STRING (c
, buf
);
658 /* We must skip glyphs to be padded for a wide character. */
659 else if (! CHAR_GLYPH_PADDING_P (*src
))
666 SET_GLYPH_FROM_CHAR_GLYPH (g
, src
[0]);
668 if (GLYPH_INVALID_P (g
) || GLYPH_SIMPLE_P (tbase
, tlen
, g
))
670 /* This glyph doesn't have an entry in Vglyph_table. */
675 /* This glyph has an entry in Vglyph_table,
676 so process any alias before testing for simpleness. */
677 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
679 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
680 /* We set the multi-byte form of a character in G
681 (that should be an ASCII character) at WORKBUF. */
684 /* We have a string in Vglyph_table. */
685 string
= tbase
[GLYPH_CHAR (g
)];
690 nbytes
= buf
- encode_terminal_src
;
691 if (encode_terminal_src_size
< nbytes
+ MAX_MULTIBYTE_LENGTH
)
693 encode_terminal_src_size
= nbytes
+ MAX_MULTIBYTE_LENGTH
;
694 encode_terminal_src
= xrealloc (encode_terminal_src
,
695 encode_terminal_src_size
);
696 buf
= encode_terminal_src
+ nbytes
;
698 if (char_charset (c
, charset_list
, NULL
))
700 /* Store the multibyte form of C at BUF. */
701 buf
+= CHAR_STRING (c
, buf
);
706 /* C is not encodable. */
709 while (src
+ 1 < src_end
&& CHAR_GLYPH_PADDING_P (src
[1]))
719 unsigned char *p
= SDATA (string
), *pend
= p
+ SBYTES (string
);
721 if (! STRING_MULTIBYTE (string
))
722 string
= string_to_multibyte (string
);
723 nbytes
= buf
- encode_terminal_src
;
724 if (encode_terminal_src_size
< nbytes
+ SBYTES (string
))
726 encode_terminal_src_size
= nbytes
+ SBYTES (string
);
727 encode_terminal_src
= xrealloc (encode_terminal_src
,
728 encode_terminal_src_size
);
729 buf
= encode_terminal_src
+ nbytes
;
731 bcopy (SDATA (string
), buf
, SBYTES (string
));
732 buf
+= SBYTES (string
);
733 nchars
+= SCHARS (string
);
741 coding
->produced
= 0;
745 nbytes
= buf
- encode_terminal_src
;
746 coding
->source
= encode_terminal_src
;
747 if (encode_terminal_dst_size
== 0)
749 encode_terminal_dst_size
= encode_terminal_src_size
;
750 if (encode_terminal_dst
)
751 encode_terminal_dst
= xrealloc (encode_terminal_dst
,
752 encode_terminal_dst_size
);
754 encode_terminal_dst
= xmalloc (encode_terminal_dst_size
);
756 coding
->destination
= encode_terminal_dst
;
757 coding
->dst_bytes
= encode_terminal_dst_size
;
758 encode_coding_object (coding
, Qnil
, 0, 0, nchars
, nbytes
, Qnil
);
759 /* coding->destination may have been reallocated. */
760 encode_terminal_dst
= coding
->destination
;
761 encode_terminal_dst_size
= coding
->dst_bytes
;
763 return (encode_terminal_dst
);
768 /* An implementation of write_glyphs for termcap frames. */
771 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
773 unsigned char *conversion_buffer
;
774 struct coding_system
*coding
;
776 struct tty_display_info
*tty
= FRAME_TTY (f
);
778 tty_turn_off_insert (tty
);
779 tty_hide_cursor (tty
);
781 /* Don't dare write in last column of bottom line, if Auto-Wrap,
782 since that would scroll the whole frame on some terminals. */
785 && curY (tty
) + 1 == FRAME_LINES (f
)
786 && (curX (tty
) + len
) == FRAME_COLS (f
))
793 /* If terminal_coding does any conversion, use it, otherwise use
794 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
795 because it always return 1 if the member src_multibyte is 1. */
796 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
797 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
798 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
800 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
804 /* Identify a run of glyphs with the same face. */
805 int face_id
= string
->face_id
;
808 for (n
= 1; n
< len
; ++n
)
809 if (string
[n
].face_id
!= face_id
)
812 /* Turn appearance modes of the face of the run on. */
813 tty_highlight_if_desired (tty
);
814 turn_on_face (f
, face_id
);
817 /* This is the last run. */
818 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
819 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
820 if (coding
->produced
> 0)
823 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
824 if (ferror (tty
->output
))
825 clearerr (tty
->output
);
827 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
833 /* Turn appearance modes off. */
834 turn_off_face (f
, face_id
);
835 tty_turn_off_highlight (tty
);
841 #ifdef HAVE_GPM /* Only used by GPM code. */
844 tty_write_glyphs_with_face (f
, string
, len
, face_id
)
845 register struct frame
*f
;
846 register struct glyph
*string
;
847 register int len
, face_id
;
849 unsigned char *conversion_buffer
;
850 struct coding_system
*coding
;
852 struct tty_display_info
*tty
= FRAME_TTY (f
);
854 tty_turn_off_insert (tty
);
855 tty_hide_cursor (tty
);
857 /* Don't dare write in last column of bottom line, if Auto-Wrap,
858 since that would scroll the whole frame on some terminals. */
861 && curY (tty
) + 1 == FRAME_LINES (f
)
862 && (curX (tty
) + len
) == FRAME_COLS (f
))
869 /* If terminal_coding does any conversion, use it, otherwise use
870 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
871 because it always return 1 if the member src_multibyte is 1. */
872 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
873 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
874 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
876 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
878 /* Turn appearance modes of the face. */
879 tty_highlight_if_desired (tty
);
880 turn_on_face (f
, face_id
);
882 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
883 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
884 if (coding
->produced
> 0)
887 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
888 if (ferror (tty
->output
))
889 clearerr (tty
->output
);
891 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
895 /* Turn appearance modes off. */
896 turn_off_face (f
, face_id
);
897 tty_turn_off_highlight (tty
);
903 /* An implementation of insert_glyphs for termcap frames. */
906 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
909 struct glyph
*glyph
= NULL
;
910 unsigned char *conversion_buffer
;
911 unsigned char space
[1];
912 struct coding_system
*coding
;
914 struct tty_display_info
*tty
= FRAME_TTY (f
);
916 if (tty
->TS_ins_multi_chars
)
918 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
922 write_glyphs (f
, start
, len
);
926 tty_turn_on_insert (tty
);
930 space
[0] = SPACEGLYPH
;
932 /* If terminal_coding does any conversion, use it, otherwise use
933 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
934 because it always return 1 if the member src_multibyte is 1. */
935 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
936 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
937 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
939 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
943 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
946 conversion_buffer
= space
;
947 coding
->produced
= 1;
951 tty_highlight_if_desired (tty
);
952 turn_on_face (f
, start
->face_id
);
955 /* We must open sufficient space for a character which
956 occupies more than one column. */
957 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
959 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
964 /* This is the last glyph. */
965 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
967 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
970 if (coding
->produced
> 0)
973 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
974 if (ferror (tty
->output
))
975 clearerr (tty
->output
);
977 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
981 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
984 turn_off_face (f
, glyph
->face_id
);
985 tty_turn_off_highlight (tty
);
992 /* An implementation of delete_glyphs for termcap frames. */
995 tty_delete_glyphs (struct frame
*f
, int n
)
1000 struct tty_display_info
*tty
= FRAME_TTY (f
);
1002 if (tty
->delete_in_insert_mode
)
1004 tty_turn_on_insert (tty
);
1008 tty_turn_off_insert (tty
);
1009 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
1012 if (tty
->TS_del_multi_chars
)
1014 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
1019 for (i
= 0; i
< n
; i
++)
1020 OUTPUT1 (tty
, tty
->TS_del_char
);
1021 if (!tty
->delete_in_insert_mode
)
1022 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
1025 /* An implementation of ins_del_lines for termcap frames. */
1028 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
1030 struct tty_display_info
*tty
= FRAME_TTY (f
);
1031 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
1032 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
1033 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
1035 register int i
= n
> 0 ? n
: -n
;
1038 /* If the lines below the insertion are being pushed
1039 into the end of the window, this is the same as clearing;
1040 and we know the lines are already clear, since the matching
1041 deletion has already been done. So can ignore this. */
1042 /* If the lines below the deletion are blank lines coming
1043 out of the end of the window, don't bother,
1044 as there will be a matching inslines later that will flush them. */
1045 if (FRAME_SCROLL_REGION_OK (f
)
1046 && vpos
+ i
>= tty
->specified_window
)
1048 if (!FRAME_MEMORY_BELOW_FRAME (f
)
1049 && vpos
+ i
>= FRAME_LINES (f
))
1054 raw_cursor_to (f
, vpos
, 0);
1055 tty_background_highlight (tty
);
1056 buf
= tparam (multi
, 0, 0, i
);
1062 raw_cursor_to (f
, vpos
, 0);
1063 tty_background_highlight (tty
);
1065 OUTPUT (tty
, single
);
1066 if (tty
->TF_teleray
)
1071 tty_set_scroll_region (f
, vpos
, tty
->specified_window
);
1073 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
1075 raw_cursor_to (f
, vpos
, 0);
1076 tty_background_highlight (tty
);
1078 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1079 tty_set_scroll_region (f
, 0, tty
->specified_window
);
1082 if (!FRAME_SCROLL_REGION_OK (f
)
1083 && FRAME_MEMORY_BELOW_FRAME (f
)
1086 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
1091 /* Compute cost of sending "str", in characters,
1092 not counting any line-dependent padding. */
1095 string_cost (char *str
)
1099 tputs (str
, 0, evalcost
);
1103 /* Compute cost of sending "str", in characters,
1104 counting any line-dependent padding at one line. */
1107 string_cost_one_line (char *str
)
1111 tputs (str
, 1, evalcost
);
1115 /* Compute per line amount of line-dependent padding,
1116 in tenths of characters. */
1119 per_line_cost (char *str
)
1123 tputs (str
, 0, evalcost
);
1126 tputs (str
, 10, evalcost
);
1131 /* char_ins_del_cost[n] is cost of inserting N characters.
1132 char_ins_del_cost[-n] is cost of deleting N characters.
1133 The length of this vector is based on max_frame_cols. */
1135 int *char_ins_del_vector
;
1137 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1142 calculate_ins_del_char_costs (struct frame
*f
)
1144 struct tty_display_info
*tty
= FRAME_TTY (f
);
1145 int ins_startup_cost
, del_startup_cost
;
1146 int ins_cost_per_char
, del_cost_per_char
;
1150 if (tty
->TS_ins_multi_chars
)
1152 ins_cost_per_char
= 0;
1153 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1155 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1156 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1158 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1159 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1160 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1161 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1165 ins_startup_cost
= 9999;
1166 ins_cost_per_char
= 0;
1169 if (tty
->TS_del_multi_chars
)
1171 del_cost_per_char
= 0;
1172 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1174 else if (tty
->TS_del_char
)
1176 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1177 + string_cost (tty
->TS_end_delete_mode
));
1178 if (tty
->delete_in_insert_mode
)
1179 del_startup_cost
/= 2;
1180 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1184 del_startup_cost
= 9999;
1185 del_cost_per_char
= 0;
1188 /* Delete costs are at negative offsets */
1189 p
= &char_ins_del_cost (f
)[0];
1190 for (i
= FRAME_COLS (f
); --i
>= 0;)
1191 *--p
= (del_startup_cost
+= del_cost_per_char
);
1193 /* Doing nothing is free */
1194 p
= &char_ins_del_cost (f
)[0];
1197 /* Insert costs are at positive offsets */
1198 for (i
= FRAME_COLS (f
); --i
>= 0;)
1199 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1203 calculate_costs (struct frame
*frame
)
1205 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1207 if (FRAME_TERMCAP_P (frame
))
1209 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1210 register char *f
= (tty
->TS_set_scroll_region
1211 ? tty
->TS_set_scroll_region
1212 : tty
->TS_set_scroll_region_1
);
1214 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1218 /* These variables are only used for terminal stuff. They are
1219 allocated once for the terminal frame of X-windows emacs, but not
1222 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1223 X turns off char_ins_del_ok. */
1225 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1226 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1228 if (char_ins_del_vector
!= 0)
1230 = (int *) xrealloc (char_ins_del_vector
,
1232 + 2 * max_frame_cols
* sizeof (int)));
1235 = (int *) xmalloc (sizeof (int)
1236 + 2 * max_frame_cols
* sizeof (int));
1238 bzero (char_ins_del_vector
, (sizeof (int)
1239 + 2 * max_frame_cols
* sizeof (int)));
1242 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1243 do_line_insertion_deletion_costs (frame
,
1244 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1245 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1248 do_line_insertion_deletion_costs (frame
,
1249 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1250 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1253 calculate_ins_del_char_costs (frame
);
1255 /* Don't use TS_repeat if its padding is worse than sending the chars */
1256 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1257 tty
->RPov
= string_cost (tty
->TS_repeat
);
1259 tty
->RPov
= FRAME_COLS (frame
) * 2;
1261 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1269 /* Termcap capability names that correspond directly to X keysyms.
1270 Some of these (marked "terminfo") aren't supplied by old-style
1271 (Berkeley) termcap entries. They're listed in X keysym order;
1272 except we put the keypad keys first, so that if they clash with
1273 other keys (as on the IBM PC keyboard) they get overridden.
1276 static struct fkey_table keys
[] =
1278 {"kh", "home"}, /* termcap */
1279 {"kl", "left"}, /* termcap */
1280 {"ku", "up"}, /* termcap */
1281 {"kr", "right"}, /* termcap */
1282 {"kd", "down"}, /* termcap */
1283 {"%8", "prior"}, /* terminfo */
1284 {"%5", "next"}, /* terminfo */
1285 {"@7", "end"}, /* terminfo */
1286 {"@1", "begin"}, /* terminfo */
1287 {"*6", "select"}, /* terminfo */
1288 {"%9", "print"}, /* terminfo */
1289 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1291 * "insert" --- see below
1293 {"&8", "undo"}, /* terminfo */
1294 {"%0", "redo"}, /* terminfo */
1295 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1296 {"@0", "find"}, /* terminfo */
1297 {"@2", "cancel"}, /* terminfo */
1298 {"%1", "help"}, /* terminfo */
1300 * "break" goes here, but can't be reliably intercepted with termcap
1302 {"&4", "reset"}, /* terminfo --- actually `restart' */
1304 * "system" and "user" --- no termcaps
1306 {"kE", "clearline"}, /* terminfo */
1307 {"kA", "insertline"}, /* terminfo */
1308 {"kL", "deleteline"}, /* terminfo */
1309 {"kI", "insertchar"}, /* terminfo */
1310 {"kD", "deletechar"}, /* terminfo */
1311 {"kB", "backtab"}, /* terminfo */
1313 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1315 {"@8", "kp-enter"}, /* terminfo */
1317 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1318 * "kp-multiply", "kp-add", "kp-separator",
1319 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1320 * --- no termcaps for any of these.
1322 {"K4", "kp-1"}, /* terminfo */
1324 * "kp-2" --- no termcap
1326 {"K5", "kp-3"}, /* terminfo */
1328 * "kp-4" --- no termcap
1330 {"K2", "kp-5"}, /* terminfo */
1332 * "kp-6" --- no termcap
1334 {"K1", "kp-7"}, /* terminfo */
1336 * "kp-8" --- no termcap
1338 {"K3", "kp-9"}, /* terminfo */
1340 * "kp-equal" --- no termcap
1352 {"&0", "S-cancel"}, /*shifted cancel key*/
1353 {"&9", "S-begin"}, /*shifted begin key*/
1354 {"*0", "S-find"}, /*shifted find key*/
1355 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1356 {"*4", "S-delete"}, /*shifted delete-character key*/
1357 {"*7", "S-end"}, /*shifted end key*/
1358 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1359 {"#1", "S-help"}, /*shifted help key*/
1360 {"#2", "S-home"}, /*shifted home key*/
1361 {"#3", "S-insert"}, /*shifted insert-character key*/
1362 {"#4", "S-left"}, /*shifted left-arrow key*/
1363 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1364 {"%c", "S-next"}, /*shifted next key*/
1365 {"%e", "S-prior"}, /*shifted previous key*/
1366 {"%f", "S-print"}, /*shifted print key*/
1367 {"%g", "S-redo"}, /*shifted redo key*/
1368 {"%i", "S-right"}, /*shifted right-arrow key*/
1369 {"!3", "S-undo"} /*shifted undo key*/
1372 static char **term_get_fkeys_address
;
1373 static KBOARD
*term_get_fkeys_kboard
;
1374 static Lisp_Object
term_get_fkeys_1 ();
1376 /* Find the escape codes sent by the function keys for Vinput_decode_map.
1377 This function scans the termcap function key sequence entries, and
1378 adds entries to Vinput_decode_map for each function key it finds. */
1381 term_get_fkeys (address
, kboard
)
1385 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1386 errors during the call. The only errors should be from Fdefine_key
1387 when given a key sequence containing an invalid prefix key. If the
1388 termcap defines function keys which use a prefix that is already bound
1389 to a command by the default bindings, we should silently ignore that
1390 function key specification, rather than giving the user an error and
1391 refusing to run at all on such a terminal. */
1393 extern Lisp_Object
Fidentity ();
1394 term_get_fkeys_address
= address
;
1395 term_get_fkeys_kboard
= kboard
;
1396 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1404 char **address
= term_get_fkeys_address
;
1405 KBOARD
*kboard
= term_get_fkeys_kboard
;
1407 /* This can happen if CANNOT_DUMP or with strange options. */
1408 if (!KEYMAPP (kboard
->Vinput_decode_map
))
1409 kboard
->Vinput_decode_map
= Fmake_sparse_keymap (Qnil
);
1411 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1413 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1415 Fdefine_key (kboard
->Vinput_decode_map
, build_string (sequence
),
1416 Fmake_vector (make_number (1),
1417 intern (keys
[i
].name
)));
1420 /* The uses of the "k0" capability are inconsistent; sometimes it
1421 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1422 We will attempt to politely accommodate both systems by testing for
1423 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1426 char *k_semi
= tgetstr ("k;", address
);
1427 char *k0
= tgetstr ("k0", address
);
1428 char *k0_name
= "f10";
1433 /* Define f0 first, so that f10 takes precedence in case the
1434 key sequences happens to be the same. */
1435 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k0
),
1436 Fmake_vector (make_number (1), intern ("f0")));
1437 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k_semi
),
1438 Fmake_vector (make_number (1), intern ("f10")));
1441 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k0
),
1442 Fmake_vector (make_number (1), intern (k0_name
)));
1445 /* Set up cookies for numbered function keys above f10. */
1447 char fcap
[3], fkey
[4];
1449 fcap
[0] = 'F'; fcap
[2] = '\0';
1450 for (i
= 11; i
< 64; i
++)
1453 fcap
[1] = '1' + i
- 11;
1455 fcap
[1] = 'A' + i
- 20;
1457 fcap
[1] = 'a' + i
- 46;
1460 char *sequence
= tgetstr (fcap
, address
);
1463 sprintf (fkey
, "f%d", i
);
1464 Fdefine_key (kboard
->Vinput_decode_map
, build_string (sequence
),
1465 Fmake_vector (make_number (1),
1473 * Various mappings to try and get a better fit.
1476 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1477 if (!tgetstr (cap1, address)) \
1479 char *sequence = tgetstr (cap2, address); \
1481 Fdefine_key (kboard->Vinput_decode_map, build_string (sequence), \
1482 Fmake_vector (make_number (1), \
1486 /* if there's no key_next keycap, map key_npage to `next' keysym */
1487 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1488 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1489 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1490 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1491 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1492 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1493 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1495 /* IBM has their own non-standard dialect of terminfo.
1496 If the standard name isn't found, try the IBM name. */
1497 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1498 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1499 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1500 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1501 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1502 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1503 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1504 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1505 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1506 #undef CONDITIONAL_REASSIGN
1513 /***********************************************************************
1514 Character Display Information
1515 ***********************************************************************/
1517 /* Avoid name clash with functions defined in xterm.c */
1519 #define append_glyph append_glyph_term
1520 #define produce_stretch_glyph produce_stretch_glyph_term
1521 #define append_composite_glyph append_composite_glyph_term
1522 #define produce_composite_glyph produce_composite_glyph_term
1525 static void append_glyph
P_ ((struct it
*));
1526 static void produce_stretch_glyph
P_ ((struct it
*));
1527 static void append_composite_glyph
P_ ((struct it
*));
1528 static void produce_composite_glyph
P_ ((struct it
*));
1530 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1531 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1532 the character for which to produce glyphs; IT->face_id contains the
1533 character's face. Padding glyphs are appended if IT->c has a
1534 IT->pixel_width > 1. */
1540 struct glyph
*glyph
, *end
;
1543 xassert (it
->glyph_row
);
1544 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1545 + it
->glyph_row
->used
[it
->area
]);
1546 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1548 /* If the glyph row is reversed, we need to prepend the glyph rather
1550 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1553 int move_by
= it
->pixel_width
;
1555 /* Make room for the new glyphs. */
1556 if (move_by
> end
- glyph
) /* don't overstep end of this area */
1557 move_by
= end
- glyph
;
1558 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1560 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1561 end
= glyph
+ move_by
;
1564 /* BIDI Note: we put the glyphs of a "multi-pixel" character left to
1565 right, even in the REVERSED_P case, since (a) all of its u.ch are
1566 identical, and (b) the PADDING_P flag needs to be set for the
1567 leftmost one, because we write to the terminal left-to-right. */
1569 i
< it
->pixel_width
&& glyph
< end
;
1572 glyph
->type
= CHAR_GLYPH
;
1573 glyph
->pixel_width
= 1;
1574 glyph
->u
.ch
= it
->char_to_display
;
1575 glyph
->face_id
= it
->face_id
;
1576 glyph
->padding_p
= i
> 0;
1577 glyph
->charpos
= CHARPOS (it
->position
);
1578 glyph
->object
= it
->object
;
1581 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1582 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1584 glyph
->bidi_type
= it
->bidi_it
.type
;
1588 glyph
->resolved_level
= 0;
1589 glyph
->bidi_type
= UNKNOWN_BT
;
1592 ++it
->glyph_row
->used
[it
->area
];
1598 /* Produce glyphs for the display element described by IT. *IT
1599 specifies what we want to produce a glyph for (character, image, ...),
1600 and where in the glyph matrix we currently are (glyph row and hpos).
1601 produce_glyphs fills in output fields of *IT with information such as the
1602 pixel width and height of a character, and maybe output actual glyphs at
1603 the same time if IT->glyph_row is non-null. See the explanation of
1604 struct display_iterator in dispextern.h for an overview.
1606 produce_glyphs also stores the result of glyph width, ascent
1607 etc. computations in *IT.
1609 IT->glyph_row may be null, in which case produce_glyphs does not
1610 actually fill in the glyphs. This is used in the move_* functions
1611 in xdisp.c for text width and height computations.
1613 Callers usually don't call produce_glyphs directly;
1614 instead they use the macro PRODUCE_GLYPHS. */
1620 /* If a hook is installed, let it do the work. */
1622 /* Nothing but characters are supported on terminal frames. */
1623 xassert (it
->what
== IT_CHARACTER
1624 || it
->what
== IT_COMPOSITION
1625 || it
->what
== IT_STRETCH
);
1627 if (it
->what
== IT_STRETCH
)
1629 produce_stretch_glyph (it
);
1633 if (it
->what
== IT_COMPOSITION
)
1635 produce_composite_glyph (it
);
1639 /* Maybe translate single-byte characters to multibyte. */
1640 it
->char_to_display
= it
->c
;
1642 if (it
->c
>= 040 && it
->c
< 0177)
1644 it
->pixel_width
= it
->nglyphs
= 1;
1648 else if (it
->c
== '\n')
1649 it
->pixel_width
= it
->nglyphs
= 0;
1650 else if (it
->c
== '\t')
1652 int absolute_x
= (it
->current_x
1653 + it
->continuation_lines_width
);
1655 = (((1 + absolute_x
+ it
->tab_width
- 1)
1660 /* If part of the TAB has been displayed on the previous line
1661 which is continued now, continuation_lines_width will have
1662 been incremented already by the part that fitted on the
1663 continued line. So, we will get the right number of spaces
1665 nspaces
= next_tab_x
- absolute_x
;
1671 it
->char_to_display
= ' ';
1672 it
->pixel_width
= it
->len
= 1;
1678 it
->pixel_width
= nspaces
;
1679 it
->nglyphs
= nspaces
;
1681 else if (CHAR_BYTE8_P (it
->c
))
1683 if (unibyte_display_via_language_environment
1686 it
->char_to_display
= BYTE8_TO_CHAR (it
->c
);
1687 it
->pixel_width
= CHAR_WIDTH (it
->char_to_display
);
1688 it
->nglyphs
= it
->pixel_width
;
1694 /* Coming here means that it->c is from display table, thus
1695 we must send the raw 8-bit byte as is to the terminal.
1696 Although there's no way to know how many columns it
1697 occupies on a screen, it is a good assumption that a
1698 single byte code has 1-column width. */
1699 it
->pixel_width
= it
->nglyphs
= 1;
1706 it
->pixel_width
= CHAR_WIDTH (it
->c
);
1707 it
->nglyphs
= it
->pixel_width
;
1714 /* Advance current_x by the pixel width as a convenience for
1716 if (it
->area
== TEXT_AREA
)
1717 it
->current_x
+= it
->pixel_width
;
1718 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1719 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1723 /* Produce a stretch glyph for iterator IT. IT->object is the value
1724 of the glyph property displayed. The value must be a list
1725 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1728 1. `:width WIDTH' specifies that the space should be WIDTH *
1729 canonical char width wide. WIDTH may be an integer or floating
1732 2. `:align-to HPOS' specifies that the space should be wide enough
1733 to reach HPOS, a value in canonical character units. */
1736 produce_stretch_glyph (it
)
1739 /* (space :width WIDTH ...) */
1740 Lisp_Object prop
, plist
;
1741 int width
= 0, align_to
= -1;
1742 int zero_width_ok_p
= 0;
1745 /* List should start with `space'. */
1746 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1747 plist
= XCDR (it
->object
);
1749 /* Compute the width of the stretch. */
1750 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1751 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1753 /* Absolute width `:width WIDTH' specified and valid. */
1754 zero_width_ok_p
= 1;
1755 width
= (int)(tem
+ 0.5);
1757 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1758 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1760 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1761 align_to
= (align_to
< 0
1763 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1764 else if (align_to
< 0)
1765 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1766 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1767 zero_width_ok_p
= 1;
1770 /* Nothing specified -> width defaults to canonical char width. */
1771 width
= FRAME_COLUMN_WIDTH (it
->f
);
1773 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1776 if (width
> 0 && it
->line_wrap
!= TRUNCATE
1777 && it
->current_x
+ width
> it
->last_visible_x
)
1778 width
= it
->last_visible_x
- it
->current_x
- 1;
1780 if (width
> 0 && it
->glyph_row
)
1782 Lisp_Object o_object
= it
->object
;
1783 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1786 if (!STRINGP (object
))
1787 object
= it
->w
->buffer
;
1788 it
->object
= object
;
1789 it
->char_to_display
= ' ';
1790 it
->pixel_width
= it
->len
= 1;
1793 it
->object
= o_object
;
1795 it
->pixel_width
= width
;
1796 it
->nglyphs
= width
;
1800 /* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
1801 Called from produce_composite_glyph for terminal frames if
1802 IT->glyph_row != NULL. IT->face_id contains the character's
1806 append_composite_glyph (it
)
1809 struct glyph
*glyph
;
1811 xassert (it
->glyph_row
);
1812 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1813 if (glyph
< it
->glyph_row
->glyphs
[1 + it
->area
])
1815 glyph
->type
= COMPOSITE_GLYPH
;
1816 glyph
->pixel_width
= it
->pixel_width
;
1817 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1818 if (it
->cmp_it
.ch
< 0)
1820 glyph
->u
.cmp
.automatic
= 0;
1821 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1825 glyph
->u
.cmp
.automatic
= 1;
1826 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1827 glyph
->u
.cmp
.from
= it
->cmp_it
.from
;
1828 glyph
->u
.cmp
.to
= it
->cmp_it
.to
- 1;
1831 glyph
->face_id
= it
->face_id
;
1832 glyph
->padding_p
= 0;
1833 glyph
->charpos
= CHARPOS (it
->position
);
1834 glyph
->object
= it
->object
;
1836 ++it
->glyph_row
->used
[it
->area
];
1842 /* Produce a composite glyph for iterator IT. IT->cmp_id is the ID of
1843 the composition. We simply produces components of the composition
1844 assuming that the terminal has a capability to layout/render it
1848 produce_composite_glyph (it
)
1853 if (it
->cmp_it
.ch
< 0)
1855 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
1857 it
->pixel_width
= cmp
->width
;
1861 Lisp_Object gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
1863 it
->pixel_width
= composition_gstring_width (gstring
, it
->cmp_it
.from
,
1864 it
->cmp_it
.to
, NULL
);
1868 append_composite_glyph (it
);
1872 /* Get information about special display element WHAT in an
1873 environment described by IT. WHAT is one of IT_TRUNCATION or
1874 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1875 non-null glyph_row member. This function ensures that fields like
1876 face_id, c, len of IT are left untouched. */
1879 produce_special_glyphs (it
, what
)
1881 enum display_element_type what
;
1889 temp_it
.what
= IT_CHARACTER
;
1891 temp_it
.object
= make_number (0);
1892 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1894 if (what
== IT_CONTINUATION
)
1896 /* Continuation glyph. */
1897 SET_GLYPH_FROM_CHAR (glyph
, '\\');
1899 && (gc
= DISP_CONTINUE_GLYPH (it
->dp
), GLYPH_CODE_P (gc
))
1900 && GLYPH_CODE_CHAR_VALID_P (gc
))
1902 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
1903 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
1906 else if (what
== IT_TRUNCATION
)
1908 /* Truncation glyph. */
1909 SET_GLYPH_FROM_CHAR (glyph
, '$');
1911 && (gc
= DISP_TRUNC_GLYPH (it
->dp
), GLYPH_CODE_P (gc
))
1912 && GLYPH_CODE_CHAR_VALID_P (gc
))
1914 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
1915 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
1921 temp_it
.c
= GLYPH_CHAR (glyph
);
1922 temp_it
.face_id
= GLYPH_FACE (glyph
);
1923 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1925 produce_glyphs (&temp_it
);
1926 it
->pixel_width
= temp_it
.pixel_width
;
1927 it
->nglyphs
= temp_it
.pixel_width
;
1932 /***********************************************************************
1934 ***********************************************************************/
1936 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1937 one of the enumerators from enum no_color_bit, or a bit set built
1938 from them. Some display attributes may not be used together with
1939 color; the termcap capability `NC' specifies which ones. */
1941 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1942 (tty->TN_max_colors > 0 \
1943 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1946 /* Turn appearances of face FACE_ID on tty frame F on.
1947 FACE_ID is a realized face ID number, in the face cache. */
1950 turn_on_face (f
, face_id
)
1954 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1955 long fg
= face
->foreground
;
1956 long bg
= face
->background
;
1957 struct tty_display_info
*tty
= FRAME_TTY (f
);
1959 /* Do this first because TS_end_standout_mode may be the same
1960 as TS_exit_attribute_mode, which turns all appearances off. */
1961 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1963 if (tty
->TN_max_colors
> 0)
1965 if (fg
>= 0 && bg
>= 0)
1967 /* If the terminal supports colors, we can set them
1968 below without using reverse video. The face's fg
1969 and bg colors are set as they should appear on
1970 the screen, i.e. they take the inverse-video'ness
1971 of the face already into account. */
1973 else if (inverse_video
)
1975 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1976 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1977 tty_toggle_highlight (tty
);
1981 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1982 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1983 tty_toggle_highlight (tty
);
1988 /* If we can't display colors, use reverse video
1989 if the face specifies that. */
1992 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1993 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1994 tty_toggle_highlight (tty
);
1998 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1999 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
2000 tty_toggle_highlight (tty
);
2005 if (face
->tty_bold_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
2006 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
2008 if (face
->tty_dim_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
2009 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
2011 /* Alternate charset and blinking not yet used. */
2012 if (face
->tty_alt_charset_p
2013 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
2014 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
2016 if (face
->tty_blinking_p
2017 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
2018 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
2020 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
2021 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
2023 if (tty
->TN_max_colors
> 0)
2027 ts
= tty
->standout_mode
? tty
->TS_set_background
: tty
->TS_set_foreground
;
2030 p
= tparam (ts
, NULL
, 0, (int) fg
);
2035 ts
= tty
->standout_mode
? tty
->TS_set_foreground
: tty
->TS_set_background
;
2038 p
= tparam (ts
, NULL
, 0, (int) bg
);
2046 /* Turn off appearances of face FACE_ID on tty frame F. */
2049 turn_off_face (f
, face_id
)
2053 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2054 struct tty_display_info
*tty
= FRAME_TTY (f
);
2056 xassert (face
!= NULL
);
2058 if (tty
->TS_exit_attribute_mode
)
2060 /* Capability "me" will turn off appearance modes double-bright,
2061 half-bright, reverse-video, standout, underline. It may or
2062 may not turn off alt-char-mode. */
2063 if (face
->tty_bold_p
2065 || face
->tty_reverse_p
2066 || face
->tty_alt_charset_p
2067 || face
->tty_blinking_p
2068 || face
->tty_underline_p
)
2070 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
2071 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
2072 tty
->standout_mode
= 0;
2075 if (face
->tty_alt_charset_p
)
2076 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
2080 /* If we don't have "me" we can only have those appearances
2081 that have exit sequences defined. */
2082 if (face
->tty_alt_charset_p
)
2083 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
2085 if (face
->tty_underline_p
)
2086 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
2089 /* Switch back to default colors. */
2090 if (tty
->TN_max_colors
> 0
2091 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2092 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2093 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2094 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2095 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
2099 /* Return non-zero if the terminal on frame F supports all of the
2100 capabilities in CAPS simultaneously, with foreground and background
2101 colors FG and BG. */
2104 tty_capable_p (tty
, caps
, fg
, bg
)
2105 struct tty_display_info
*tty
;
2107 unsigned long fg
, bg
;
2109 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
2110 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
2113 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
2114 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
2115 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
2116 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
2117 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
2118 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
2124 /* Return non-zero if the terminal is capable to display colors. */
2126 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2128 doc
: /* Return non-nil if the tty device TERMINAL can display colors.
2130 TERMINAL can be a terminal object, a frame, or nil (meaning the
2131 selected frame's terminal). This function always returns nil if
2132 TERMINAL does not refer to a text-only terminal. */)
2134 Lisp_Object terminal
;
2136 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2140 return t
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
2143 /* Return the number of supported colors. */
2144 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2145 Stty_display_color_cells
, 0, 1, 0,
2146 doc
: /* Return the number of colors supported by the tty device TERMINAL.
2148 TERMINAL can be a terminal object, a frame, or nil (meaning the
2149 selected frame's terminal). This function always returns 0 if
2150 TERMINAL does not refer to a text-only terminal. */)
2152 Lisp_Object terminal
;
2154 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2156 return make_number (0);
2158 return make_number (t
->display_info
.tty
->TN_max_colors
);
2163 /* Declare here rather than in the function, as in the rest of Emacs,
2164 to work around an HPUX compiler bug (?). See
2165 http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00410.html */
2166 static int default_max_colors
;
2167 static int default_max_pairs
;
2168 static int default_no_color_video
;
2169 static char *default_orig_pair
;
2170 static char *default_set_foreground
;
2171 static char *default_set_background
;
2173 /* Save or restore the default color-related capabilities of this
2176 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
2181 xfree (default_orig_pair
);
2182 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
2184 xfree (default_set_foreground
);
2185 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
2188 xfree (default_set_background
);
2189 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
2192 default_max_colors
= tty
->TN_max_colors
;
2193 default_max_pairs
= tty
->TN_max_pairs
;
2194 default_no_color_video
= tty
->TN_no_color_video
;
2198 tty
->TS_orig_pair
= default_orig_pair
;
2199 tty
->TS_set_foreground
= default_set_foreground
;
2200 tty
->TS_set_background
= default_set_background
;
2201 tty
->TN_max_colors
= default_max_colors
;
2202 tty
->TN_max_pairs
= default_max_pairs
;
2203 tty
->TN_no_color_video
= default_no_color_video
;
2207 /* Setup one of the standard tty color schemes according to MODE.
2208 MODE's value is generally the number of colors which we want to
2209 support; zero means set up for the default capabilities, the ones
2210 we saw at init_tty time; -1 means turn off color support. */
2212 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2214 /* Canonicalize all negative values of MODE. */
2220 case -1: /* no colors at all */
2221 tty
->TN_max_colors
= 0;
2222 tty
->TN_max_pairs
= 0;
2223 tty
->TN_no_color_video
= 0;
2224 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2226 case 0: /* default colors, if any */
2228 tty_default_color_capabilities (tty
, 0);
2230 case 8: /* 8 standard ANSI colors */
2231 tty
->TS_orig_pair
= "\033[0m";
2233 tty
->TS_set_foreground
= "\033[3%p1%dm";
2234 tty
->TS_set_background
= "\033[4%p1%dm";
2236 tty
->TS_set_foreground
= "\033[3%dm";
2237 tty
->TS_set_background
= "\033[4%dm";
2239 tty
->TN_max_colors
= 8;
2240 tty
->TN_max_pairs
= 64;
2241 tty
->TN_no_color_video
= 0;
2247 set_tty_color_mode (tty
, f
)
2248 struct tty_display_info
*tty
;
2251 Lisp_Object tem
, val
, color_mode_spec
;
2252 Lisp_Object color_mode
;
2254 extern Lisp_Object Qtty_color_mode
;
2255 Lisp_Object tty_color_mode_alist
2256 = Fintern_soft (build_string ("tty-color-mode-alist"), Qnil
);
2258 tem
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2259 val
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2265 tem
= (NILP (tty_color_mode_alist
) ? Qnil
2266 : Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
));
2267 color_mode
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2270 mode
= INTEGERP (color_mode
) ? XINT (color_mode
) : 0;
2272 if (mode
!= tty
->previous_color_mode
)
2274 Lisp_Object funsym
= intern ("tty-set-up-initial-frame-faces");
2275 tty
->previous_color_mode
= mode
;
2276 tty_setup_colors (tty
, mode
);
2277 /* This recomputes all the faces given the new color definitions. */
2278 safe_call (1, &funsym
);
2282 #endif /* !DOS_NT */
2286 /* Return the tty display object specified by TERMINAL. */
2289 get_tty_terminal (Lisp_Object terminal
, int throw)
2291 struct terminal
*t
= get_terminal (terminal
, throw);
2293 if (t
&& t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2296 error ("Device %d is not a termcap terminal device", t
->id
);
2304 /* Return an active termcap device that uses the tty device with the
2307 This function ignores suspended devices.
2309 Returns NULL if the named terminal device is not opened. */
2312 get_named_tty (name
)
2320 for (t
= terminal_list
; t
; t
= t
->next_terminal
)
2322 if ((t
->type
== output_termcap
|| t
->type
== output_msdos_raw
)
2323 && !strcmp (t
->display_info
.tty
->name
, name
)
2324 && TERMINAL_ACTIVE_P (t
))
2332 DEFUN ("tty-type", Ftty_type
, Stty_type
, 0, 1, 0,
2333 doc
: /* Return the type of the tty device that TERMINAL uses.
2334 Returns nil if TERMINAL is not on a tty device.
2336 TERMINAL can be a terminal object, a frame, or nil (meaning the
2337 selected frame's terminal). */)
2339 Lisp_Object terminal
;
2341 struct terminal
*t
= get_terminal (terminal
, 1);
2343 if (t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2346 if (t
->display_info
.tty
->type
)
2347 return build_string (t
->display_info
.tty
->type
);
2352 DEFUN ("controlling-tty-p", Fcontrolling_tty_p
, Scontrolling_tty_p
, 0, 1, 0,
2353 doc
: /* Return non-nil if TERMINAL is the controlling tty of the Emacs process.
2355 TERMINAL can be a terminal object, a frame, or nil (meaning the
2356 selected frame's terminal). This function always returns nil if
2357 TERMINAL is not on a tty device. */)
2359 Lisp_Object terminal
;
2361 struct terminal
*t
= get_terminal (terminal
, 1);
2363 if ((t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2364 || strcmp (t
->display_info
.tty
->name
, DEV_TTY
) != 0)
2370 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 1, 0,
2371 doc
: /* Declare that the tty used by TERMINAL does not handle underlining.
2372 This is used to override the terminfo data, for certain terminals that
2373 do not really do underlining, but say that they do. This function has
2374 no effect if used on a non-tty terminal.
2376 TERMINAL can be a terminal object, a frame or nil (meaning the
2377 selected frame's terminal). This function always returns nil if
2378 TERMINAL does not refer to a text-only terminal. */)
2380 Lisp_Object terminal
;
2382 struct terminal
*t
= get_terminal (terminal
, 1);
2384 if (t
->type
== output_termcap
)
2385 t
->display_info
.tty
->TS_enter_underline_mode
= 0;
2391 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
2392 doc
: /* Suspend the terminal device TTY.
2394 The device is restored to its default state, and Emacs ceases all
2395 access to the tty device. Frames that use the device are not deleted,
2396 but input is not read from them and if they change, their display is
2399 TTY may be a terminal object, a frame, or nil for the terminal device
2400 of the currently selected frame.
2402 This function runs `suspend-tty-functions' after suspending the
2403 device. The functions are run with one arg, the id of the suspended
2406 `suspend-tty' does nothing if it is called on a device that is already
2409 A suspended tty may be resumed by calling `resume-tty' on it. */)
2413 struct terminal
*t
= get_tty_terminal (tty
, 1);
2417 error ("Unknown tty device");
2419 f
= t
->display_info
.tty
->input
;
2423 /* First run `suspend-tty-functions' and then clean up the tty
2424 state because `suspend-tty-functions' might need to change
2426 if (!NILP (Vrun_hooks
))
2428 Lisp_Object args
[2];
2429 args
[0] = intern ("suspend-tty-functions");
2430 XSETTERMINAL (args
[1], t
);
2431 Frun_hook_with_args (2, args
);
2434 reset_sys_modes (t
->display_info
.tty
);
2437 delete_keyboard_wait_descriptor (fileno (f
));
2442 if (f
!= t
->display_info
.tty
->output
)
2443 fclose (t
->display_info
.tty
->output
);
2446 t
->display_info
.tty
->input
= 0;
2447 t
->display_info
.tty
->output
= 0;
2449 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2450 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 0);
2454 /* Clear display hooks to prevent further output. */
2455 clear_tty_hooks (t
);
2460 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
2461 doc
: /* Resume the previously suspended terminal device TTY.
2462 The terminal is opened and reinitialized. Frames that are on the
2463 suspended terminal are revived.
2465 It is an error to resume a terminal while another terminal is active
2468 This function runs `resume-tty-functions' after resuming the terminal.
2469 The functions are run with one arg, the id of the resumed terminal
2472 `resume-tty' does nothing if it is called on a device that is not
2475 TTY may be a terminal object, a frame, or nil (meaning the selected
2476 frame's terminal). */)
2480 struct terminal
*t
= get_tty_terminal (tty
, 1);
2484 error ("Unknown tty device");
2486 if (!t
->display_info
.tty
->input
)
2488 if (get_named_tty (t
->display_info
.tty
->name
))
2489 error ("Cannot resume display while another display is active on the same device");
2492 t
->display_info
.tty
->output
= stdout
;
2493 t
->display_info
.tty
->input
= stdin
;
2495 fd
= emacs_open (t
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
2498 error ("Can not reopen tty device %s: %s", t
->display_info
.tty
->name
, strerror (errno
));
2500 if (strcmp (t
->display_info
.tty
->name
, DEV_TTY
))
2501 dissociate_if_controlling_tty (fd
);
2503 t
->display_info
.tty
->output
= fdopen (fd
, "w+");
2504 t
->display_info
.tty
->input
= t
->display_info
.tty
->output
;
2508 add_keyboard_wait_descriptor (fd
);
2511 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2513 struct frame
*f
= XFRAME (t
->display_info
.tty
->top_frame
);
2515 int old_height
= FRAME_COLS (f
);
2516 int old_width
= FRAME_LINES (f
);
2518 /* Check if terminal/window size has changed while the frame
2520 get_tty_size (fileno (t
->display_info
.tty
->input
), &width
, &height
);
2521 if (width
!= old_width
|| height
!= old_height
)
2522 change_frame_size (f
, height
, width
, 0, 0, 0);
2523 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 1);
2526 init_sys_modes (t
->display_info
.tty
);
2528 /* Run `resume-tty-functions'. */
2529 if (!NILP (Vrun_hooks
))
2531 Lisp_Object args
[2];
2532 args
[0] = intern ("resume-tty-functions");
2533 XSETTERMINAL (args
[1], t
);
2534 Frun_hook_with_args (2, args
);
2544 /***********************************************************************
2546 ***********************************************************************/
2550 term_mouse_moveto (int x
, int y
)
2552 /* TODO: how to set mouse position?
2555 name = (const char *) ttyname (0);
2556 fd = open (name, O_WRONLY);
2557 SOME_FUNCTION (x, y, fd);
2560 last_mouse_y = y; */
2564 term_show_mouse_face (enum draw_glyphs_face draw
)
2566 struct window
*w
= XWINDOW (mouse_face_window
);
2570 struct frame
*f
= XFRAME (w
->frame
);
2571 struct tty_display_info
*tty
= FRAME_TTY (f
);
2573 if (/* If window is in the process of being destroyed, don't bother
2575 w
->current_matrix
!= NULL
2576 /* Recognize when we are called to operate on rows that don't exist
2577 anymore. This can happen when a window is split. */
2578 && mouse_face_end_row
< w
->current_matrix
->nrows
)
2580 /* write_glyphs writes at cursor position, so we need to
2581 temporarily move cursor coordinates to the beginning of
2582 the highlight region. */
2584 /* Save current cursor co-ordinates */
2585 save_y
= curY (tty
);
2586 save_x
= curX (tty
);
2588 /* Note that mouse_face_beg_row etc. are window relative. */
2589 for (i
= mouse_face_beg_row
; i
<= mouse_face_end_row
; i
++)
2591 int start_hpos
, end_hpos
, nglyphs
;
2592 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
2594 /* Don't do anything if row doesn't have valid contents. */
2595 if (!row
->enabled_p
)
2598 /* For all but the first row, the highlight starts at column 0. */
2599 if (i
== mouse_face_beg_row
)
2600 start_hpos
= mouse_face_beg_col
;
2604 if (i
== mouse_face_end_row
)
2605 end_hpos
= mouse_face_end_col
;
2608 end_hpos
= row
->used
[TEXT_AREA
];
2609 if (draw
== DRAW_NORMAL_TEXT
)
2610 row
->fill_line_p
= 1; /* Clear to end of line */
2613 if (end_hpos
<= start_hpos
)
2615 /* Record that some glyphs of this row are displayed in
2617 row
->mouse_face_p
= draw
> 0;
2619 nglyphs
= end_hpos
- start_hpos
;
2621 if (end_hpos
>= row
->used
[TEXT_AREA
])
2622 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2624 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2625 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
2626 + WINDOW_LEFT_EDGE_X (w
);
2628 cursor_to (f
, pos_y
, pos_x
);
2630 if (draw
== DRAW_MOUSE_FACE
)
2632 tty_write_glyphs_with_face (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
,
2633 nglyphs
, mouse_face_face_id
);
2635 else /* draw == DRAW_NORMAL_TEXT */
2636 write_glyphs (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2638 cursor_to (f
, save_y
, save_x
);
2643 term_clear_mouse_face ()
2645 if (!NILP (mouse_face_window
))
2646 term_show_mouse_face (DRAW_NORMAL_TEXT
);
2648 mouse_face_beg_row
= mouse_face_beg_col
= -1;
2649 mouse_face_end_row
= mouse_face_end_col
= -1;
2650 mouse_face_window
= Qnil
;
2653 /* Find the glyph matrix position of buffer position POS in window W.
2654 *HPOS and *VPOS are set to the positions found. W's current glyphs
2655 must be up to date. If POS is above window start return (0, 0).
2656 If POS is after end of W, return end of last line in W.
2657 - taken from msdos.c */
2659 fast_find_position (struct window
*w
, int pos
, int *hpos
, int *vpos
)
2661 int i
, lastcol
, line_start_position
, maybe_next_line_p
= 0;
2662 int yb
= window_text_bottom_y (w
);
2663 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0), *best_row
= row
;
2667 if (row
->used
[TEXT_AREA
])
2668 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
2670 line_start_position
= 0;
2672 if (line_start_position
> pos
)
2674 /* If the position sought is the end of the buffer,
2675 don't include the blank lines at the bottom of the window. */
2676 else if (line_start_position
== pos
2677 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
2679 maybe_next_line_p
= 1;
2682 else if (line_start_position
> 0)
2685 /* Don't overstep the last matrix row, lest we get into the
2686 never-never land... */
2687 if (row
->y
+ 1 >= yb
)
2693 /* Find the right column within BEST_ROW. */
2696 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
2698 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + i
;
2701 charpos
= glyph
->charpos
;
2708 else if (charpos
> pos
)
2710 else if (charpos
> 0)
2714 /* If we're looking for the end of the buffer,
2715 and we didn't find it in the line we scanned,
2716 use the start of the following line. */
2717 if (maybe_next_line_p
)
2724 *hpos
= lastcol
+ 1;
2729 term_mouse_highlight (struct frame
*f
, int x
, int y
)
2731 enum window_part part
;
2736 if (NILP (Vmouse_highlight
)
2737 || !f
->glyphs_initialized_p
)
2740 /* Which window is that in? */
2741 window
= window_from_coordinates (f
, x
, y
, &part
, &x
, &y
, 0);
2743 /* Not on a window -> return. */
2744 if (!WINDOWP (window
))
2747 if (!EQ (window
, mouse_face_window
))
2748 term_clear_mouse_face ();
2750 w
= XWINDOW (window
);
2752 /* Are we in a window whose display is up to date?
2753 And verify the buffer's text has not changed. */
2754 b
= XBUFFER (w
->buffer
);
2756 && EQ (w
->window_end_valid
, w
->buffer
)
2757 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
2758 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
2760 int pos
, i
, nrows
= w
->current_matrix
->nrows
;
2761 struct glyph_row
*row
;
2762 struct glyph
*glyph
;
2764 /* Find the glyph under X/Y. */
2766 if (y
>= 0 && y
< nrows
)
2768 row
= MATRIX_ROW (w
->current_matrix
, y
);
2769 /* Give up if some row before the one we are looking for is
2771 for (i
= 0; i
<= y
; i
++)
2772 if (!MATRIX_ROW (w
->current_matrix
, i
)->enabled_p
)
2774 if (i
> y
/* all rows upto and including the one at Y are enabled */
2775 && row
->displays_text_p
2776 && x
< window_box_width (w
, TEXT_AREA
))
2778 glyph
= row
->glyphs
[TEXT_AREA
];
2779 if (x
>= row
->used
[TEXT_AREA
])
2784 if (!BUFFERP (glyph
->object
))
2790 /* Clear mouse face if X/Y not over text. */
2793 term_clear_mouse_face ();
2797 if (!BUFFERP (glyph
->object
))
2799 pos
= glyph
->charpos
;
2801 /* Check for mouse-face. */
2803 extern Lisp_Object Qmouse_face
;
2804 Lisp_Object mouse_face
, overlay
, position
, *overlay_vec
;
2805 int noverlays
, obegv
, ozv
;
2806 struct buffer
*obuf
;
2808 /* If we get an out-of-range value, return now; avoid an error. */
2809 if (pos
> BUF_Z (b
))
2812 /* Make the window's buffer temporarily current for
2813 overlays_at and compute_char_face. */
2814 obuf
= current_buffer
;
2821 /* Is this char mouse-active? */
2822 XSETINT (position
, pos
);
2824 /* Put all the overlays we want in a vector in overlay_vec. */
2825 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
2826 /* Sort overlays into increasing priority order. */
2827 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
2829 /* Check mouse-face highlighting. */
2830 if (!(EQ (window
, mouse_face_window
)
2831 && y
>= mouse_face_beg_row
2832 && y
<= mouse_face_end_row
2833 && (y
> mouse_face_beg_row
2834 || x
>= mouse_face_beg_col
)
2835 && (y
< mouse_face_end_row
2836 || x
< mouse_face_end_col
2837 || mouse_face_past_end
)))
2839 /* Clear the display of the old active region, if any. */
2840 term_clear_mouse_face ();
2842 /* Find the highest priority overlay that has a mouse-face
2845 for (i
= noverlays
- 1; i
>= 0; --i
)
2847 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
2848 if (!NILP (mouse_face
))
2850 overlay
= overlay_vec
[i
];
2855 /* If no overlay applies, get a text property. */
2857 mouse_face
= Fget_text_property (position
, Qmouse_face
,
2860 /* Handle the overlay case. */
2861 if (!NILP (overlay
))
2863 /* Find the range of text around this char that
2864 should be active. */
2865 Lisp_Object before
, after
;
2869 before
= Foverlay_start (overlay
);
2870 after
= Foverlay_end (overlay
);
2871 /* Record this as the current active region. */
2872 fast_find_position (w
, XFASTINT (before
),
2873 &mouse_face_beg_col
,
2874 &mouse_face_beg_row
);
2877 = !fast_find_position (w
, XFASTINT (after
),
2878 &mouse_face_end_col
,
2879 &mouse_face_end_row
);
2880 mouse_face_window
= window
;
2883 = face_at_buffer_position (w
, pos
, 0, 0,
2884 &ignore
, pos
+ 1, 1, -1);
2886 /* Display it as active. */
2887 term_show_mouse_face (DRAW_MOUSE_FACE
);
2889 /* Handle the text property case. */
2890 else if (!NILP (mouse_face
))
2892 /* Find the range of text around this char that
2893 should be active. */
2894 Lisp_Object before
, after
, beginning
, end
;
2897 beginning
= Fmarker_position (w
->start
);
2898 XSETINT (end
, (BUF_Z (b
) - XFASTINT (w
->window_end_pos
)));
2900 = Fprevious_single_property_change (make_number (pos
+ 1),
2902 w
->buffer
, beginning
);
2904 = Fnext_single_property_change (position
, Qmouse_face
,
2907 /* Record this as the current active region. */
2908 fast_find_position (w
, XFASTINT (before
),
2909 &mouse_face_beg_col
,
2910 &mouse_face_beg_row
);
2912 = !fast_find_position (w
, XFASTINT (after
),
2913 &mouse_face_end_col
,
2914 &mouse_face_end_row
);
2915 mouse_face_window
= window
;
2918 = face_at_buffer_position (w
, pos
, 0, 0,
2919 &ignore
, pos
+ 1, 1, -1);
2921 /* Display it as active. */
2922 term_show_mouse_face (DRAW_MOUSE_FACE
);
2926 /* Look for a `help-echo' property. */
2929 extern Lisp_Object Qhelp_echo
;
2931 /* Check overlays first. */
2933 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
2935 overlay
= overlay_vec
[i
];
2936 help
= Foverlay_get (overlay
, Qhelp_echo
);
2941 help_echo_string
= help
;
2942 help_echo_window
= window
;
2943 help_echo_object
= overlay
;
2944 help_echo_pos
= pos
;
2946 /* Try text properties. */
2947 else if (NILP (help
)
2948 && ((STRINGP (glyph
->object
)
2949 && glyph
->charpos
>= 0
2950 && glyph
->charpos
< SCHARS (glyph
->object
))
2951 || (BUFFERP (glyph
->object
)
2952 && glyph
->charpos
>= BEGV
2953 && glyph
->charpos
< ZV
)))
2955 help
= Fget_text_property (make_number (glyph
->charpos
),
2956 Qhelp_echo
, glyph
->object
);
2959 help_echo_string
= help
;
2960 help_echo_window
= window
;
2961 help_echo_object
= glyph
->object
;
2962 help_echo_pos
= glyph
->charpos
;
2969 current_buffer
= obuf
;
2975 term_mouse_movement (FRAME_PTR frame
, Gpm_Event
*event
)
2977 /* Has the mouse moved off the glyph it was on at the last sighting? */
2978 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2980 frame
->mouse_moved
= 1;
2981 term_mouse_highlight (frame
, event
->x
, event
->y
);
2982 /* Remember which glyph we're now on. */
2983 last_mouse_x
= event
->x
;
2984 last_mouse_y
= event
->y
;
2990 /* Return the current position of the mouse.
2992 Set *f to the frame the mouse is in, or zero if the mouse is in no
2993 Emacs frame. If it is set to zero, all the other arguments are
2996 Set *bar_window to Qnil, and *x and *y to the column and
2997 row of the character cell the mouse is over.
2999 Set *time to the time the mouse was at the returned position.
3001 This clears mouse_moved until the next motion
3004 term_mouse_position (FRAME_PTR
*fp
, int insist
, Lisp_Object
*bar_window
,
3005 enum scroll_bar_part
*part
, Lisp_Object
*x
,
3006 Lisp_Object
*y
, unsigned long *time
)
3010 *fp
= SELECTED_FRAME ();
3011 (*fp
)->mouse_moved
= 0;
3016 XSETINT (*x
, last_mouse_x
);
3017 XSETINT (*y
, last_mouse_y
);
3018 gettimeofday(&now
, 0);
3019 *time
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
3022 /* Prepare a mouse-event in *RESULT for placement in the input queue.
3024 If the event is a button press, then note that we have grabbed
3028 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
3034 result
->kind
= GPM_CLICK_EVENT
;
3035 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
3037 if (event
->buttons
& j
) {
3038 result
->code
= i
; /* button number */
3042 gettimeofday(&now
, 0);
3043 result
->timestamp
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
3045 if (event
->type
& GPM_UP
)
3046 result
->modifiers
= up_modifier
;
3047 else if (event
->type
& GPM_DOWN
)
3048 result
->modifiers
= down_modifier
;
3050 result
->modifiers
= 0;
3052 if (event
->type
& GPM_SINGLE
)
3053 result
->modifiers
|= click_modifier
;
3055 if (event
->type
& GPM_DOUBLE
)
3056 result
->modifiers
|= double_modifier
;
3058 if (event
->type
& GPM_TRIPLE
)
3059 result
->modifiers
|= triple_modifier
;
3061 if (event
->type
& GPM_DRAG
)
3062 result
->modifiers
|= drag_modifier
;
3064 if (!(event
->type
& (GPM_MOVE
| GPM_DRAG
))) {
3067 if (event
->modifiers
& (1 << 0))
3068 result
->modifiers
|= shift_modifier
;
3071 if (event
->modifiers
& (1 << 2))
3072 result
->modifiers
|= ctrl_modifier
;
3074 /* 1 << KG_ALT || KG_ALTGR */
3075 if (event
->modifiers
& (1 << 3)
3076 || event
->modifiers
& (1 << 1))
3077 result
->modifiers
|= meta_modifier
;
3080 XSETINT (result
->x
, event
->x
);
3081 XSETINT (result
->y
, event
->y
);
3082 XSETFRAME (result
->frame_or_window
, f
);
3088 handle_one_term_event (struct tty_display_info
*tty
, Gpm_Event
*event
, struct input_event
* hold_quit
)
3090 struct frame
*f
= XFRAME (tty
->top_frame
);
3091 struct input_event ie
;
3099 if (event
->type
& (GPM_MOVE
| GPM_DRAG
)) {
3100 previous_help_echo_string
= help_echo_string
;
3101 help_echo_string
= Qnil
;
3103 Gpm_DrawPointer (event
->x
, event
->y
, fileno (tty
->output
));
3105 if (!term_mouse_movement (f
, event
))
3106 help_echo_string
= previous_help_echo_string
;
3108 /* If the contents of the global variable help_echo_string
3109 has changed, generate a HELP_EVENT. */
3110 if (!NILP (help_echo_string
)
3111 || !NILP (previous_help_echo_string
))
3118 term_mouse_click (&ie
, event
, f
);
3122 if (ie
.kind
!= NO_EVENT
)
3124 kbd_buffer_store_event_hold (&ie
, hold_quit
);
3129 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
3134 XSETFRAME (frame
, f
);
3138 gen_help_event (help_echo_string
, frame
, help_echo_window
,
3139 help_echo_object
, help_echo_pos
);
3146 DEFUN ("gpm-mouse-start", Fgpm_mouse_start
, Sgpm_mouse_start
,
3148 doc
: /* Open a connection to Gpm.
3149 Gpm-mouse can only be activated for one tty at a time. */)
3152 struct frame
*f
= SELECTED_FRAME ();
3153 struct tty_display_info
*tty
3154 = ((f
)->output_method
== output_termcap
3155 ? (f
)->terminal
->display_info
.tty
: NULL
);
3156 Gpm_Connect connection
;
3159 error ("Gpm-mouse only works in the GNU/Linux console");
3161 return Qnil
; /* Already activated, nothing to do. */
3163 error ("Gpm-mouse can only be activated for one tty at a time");
3165 connection
.eventMask
= ~0;
3166 connection
.defaultMask
= ~GPM_HARD
;
3167 connection
.maxMod
= ~0;
3168 connection
.minMod
= 0;
3171 if (Gpm_Open (&connection
, 0) < 0)
3172 error ("Gpm-mouse failed to connect to the gpm daemon");
3176 /* `init_sys_modes' arranges for mouse movements sent through gpm_fd
3177 to generate SIGIOs. Apparently we need to call reset_sys_modes
3178 before calling init_sys_modes. */
3179 reset_sys_modes (tty
);
3180 init_sys_modes (tty
);
3181 add_gpm_wait_descriptor (gpm_fd
);
3190 delete_gpm_wait_descriptor (fd
);
3191 while (Gpm_Close()); /* close all the stack */
3195 DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop
, Sgpm_mouse_stop
,
3197 doc
: /* Close a connection to Gpm. */)
3200 struct frame
*f
= SELECTED_FRAME ();
3201 struct tty_display_info
*tty
3202 = ((f
)->output_method
== output_termcap
3203 ? (f
)->terminal
->display_info
.tty
: NULL
);
3205 if (!tty
|| gpm_tty
!= tty
)
3206 return Qnil
; /* Not activated on this terminal, nothing to do. */
3211 #endif /* HAVE_GPM */
3215 /***********************************************************************
3217 ***********************************************************************/
3219 /* Initialize the tty-dependent part of frame F. The frame must
3220 already have its device initialized. */
3223 create_tty_output (struct frame
*f
)
3225 struct tty_output
*t
;
3227 if (! FRAME_TERMCAP_P (f
))
3230 t
= xmalloc (sizeof (struct tty_output
));
3231 bzero (t
, sizeof (struct tty_output
));
3233 t
->display_info
= FRAME_TERMINAL (f
)->display_info
.tty
;
3235 f
->output_data
.tty
= t
;
3238 /* Delete frame F's face cache, and its tty-dependent part. */
3241 tty_free_frame_resources (struct frame
*f
)
3243 if (! FRAME_TERMCAP_P (f
))
3246 if (FRAME_FACE_CACHE (f
))
3247 free_frame_faces (f
);
3249 xfree (f
->output_data
.tty
);
3254 /* Delete frame F's face cache. */
3257 tty_free_frame_resources (struct frame
*f
)
3259 if (! FRAME_TERMCAP_P (f
) && ! FRAME_MSDOS_P (f
))
3262 if (FRAME_FACE_CACHE (f
))
3263 free_frame_faces (f
);
3267 /* Reset the hooks in TERMINAL. */
3270 clear_tty_hooks (struct terminal
*terminal
)
3273 terminal
->cursor_to_hook
= 0;
3274 terminal
->raw_cursor_to_hook
= 0;
3275 terminal
->clear_to_end_hook
= 0;
3276 terminal
->clear_frame_hook
= 0;
3277 terminal
->clear_end_of_line_hook
= 0;
3278 terminal
->ins_del_lines_hook
= 0;
3279 terminal
->insert_glyphs_hook
= 0;
3280 terminal
->write_glyphs_hook
= 0;
3281 terminal
->delete_glyphs_hook
= 0;
3282 terminal
->ring_bell_hook
= 0;
3283 terminal
->reset_terminal_modes_hook
= 0;
3284 terminal
->set_terminal_modes_hook
= 0;
3285 terminal
->update_begin_hook
= 0;
3286 terminal
->update_end_hook
= 0;
3287 terminal
->set_terminal_window_hook
= 0;
3288 terminal
->mouse_position_hook
= 0;
3289 terminal
->frame_rehighlight_hook
= 0;
3290 terminal
->frame_raise_lower_hook
= 0;
3291 terminal
->fullscreen_hook
= 0;
3292 terminal
->set_vertical_scroll_bar_hook
= 0;
3293 terminal
->condemn_scroll_bars_hook
= 0;
3294 terminal
->redeem_scroll_bar_hook
= 0;
3295 terminal
->judge_scroll_bars_hook
= 0;
3296 terminal
->read_socket_hook
= 0;
3297 terminal
->frame_up_to_date_hook
= 0;
3299 /* Leave these two set, or suspended frames are not deleted
3301 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3302 terminal
->delete_terminal_hook
= &delete_tty
;
3305 /* Initialize hooks in TERMINAL with the values needed for a tty. */
3308 set_tty_hooks (struct terminal
*terminal
)
3310 terminal
->rif
= 0; /* ttys don't support window-based redisplay. */
3312 terminal
->cursor_to_hook
= &tty_cursor_to
;
3313 terminal
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
3315 terminal
->clear_to_end_hook
= &tty_clear_to_end
;
3316 terminal
->clear_frame_hook
= &tty_clear_frame
;
3317 terminal
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
3319 terminal
->ins_del_lines_hook
= &tty_ins_del_lines
;
3321 terminal
->insert_glyphs_hook
= &tty_insert_glyphs
;
3322 terminal
->write_glyphs_hook
= &tty_write_glyphs
;
3323 terminal
->delete_glyphs_hook
= &tty_delete_glyphs
;
3325 terminal
->ring_bell_hook
= &tty_ring_bell
;
3327 terminal
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
3328 terminal
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
3329 terminal
->update_begin_hook
= 0; /* Not needed. */
3330 terminal
->update_end_hook
= &tty_update_end
;
3331 terminal
->set_terminal_window_hook
= &tty_set_terminal_window
;
3333 terminal
->mouse_position_hook
= 0; /* Not needed. */
3334 terminal
->frame_rehighlight_hook
= 0; /* Not needed. */
3335 terminal
->frame_raise_lower_hook
= 0; /* Not needed. */
3337 terminal
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
3338 terminal
->condemn_scroll_bars_hook
= 0; /* Not needed. */
3339 terminal
->redeem_scroll_bar_hook
= 0; /* Not needed. */
3340 terminal
->judge_scroll_bars_hook
= 0; /* Not needed. */
3342 terminal
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
3343 terminal
->frame_up_to_date_hook
= 0; /* Not needed. */
3345 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3346 terminal
->delete_terminal_hook
= &delete_tty
;
3349 /* Drop the controlling terminal if fd is the same device. */
3351 dissociate_if_controlling_tty (int fd
)
3355 EMACS_GET_TTY_PGRP (fd
, &pgid
); /* If tcgetpgrp succeeds, fd is the ctty. */
3358 #if defined (USG) && !defined (BSD_PGRPS)
3360 no_controlling_tty
= 1;
3361 #elif defined (CYGWIN)
3363 no_controlling_tty
= 1;
3365 #ifdef TIOCNOTTY /* Try BSD ioctls. */
3366 sigblock (sigmask (SIGTTOU
));
3367 fd
= emacs_open (DEV_TTY
, O_RDWR
, 0);
3368 if (fd
!= -1 && ioctl (fd
, TIOCNOTTY
, 0) != -1)
3370 no_controlling_tty
= 1;
3374 sigunblock (sigmask (SIGTTOU
));
3376 /* Unknown system. */
3378 #endif /* ! TIOCNOTTY */
3381 #endif /* !DOS_NT */
3384 static void maybe_fatal();
3386 /* Create a termcap display on the tty device with the given name and
3389 If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
3390 Otherwise NAME should be a path to the tty device file,
3393 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
3395 If MUST_SUCCEED is true, then all errors are fatal. */
3398 init_tty (char *name
, char *terminal_type
, int must_succeed
)
3401 char **address
= &area
;
3402 int buffer_size
= 4096;
3403 register char *p
= NULL
;
3405 struct tty_display_info
*tty
= NULL
;
3406 struct terminal
*terminal
= NULL
;
3407 int ctty
= 0; /* 1 if asked to open controlling tty. */
3410 maybe_fatal (must_succeed
, 0,
3411 "Unknown terminal type",
3412 "Unknown terminal type");
3416 if (!strcmp (name
, DEV_TTY
))
3419 /* If we already have a terminal on the given device, use that. If
3420 all such terminals are suspended, create a new one instead. */
3421 /* XXX Perhaps this should be made explicit by having init_tty
3422 always create a new terminal and separating terminal and frame
3423 creation on Lisp level. */
3424 terminal
= get_named_tty (name
);
3428 terminal
= create_terminal ();
3431 maybe_fatal (1, 0, "Attempt to create another terminal %s", "",
3434 tty
= &the_only_display_info
;
3436 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
3438 bzero (tty
, sizeof (struct tty_display_info
));
3439 tty
->next
= tty_list
;
3442 terminal
->type
= output_termcap
;
3443 terminal
->display_info
.tty
= tty
;
3444 tty
->terminal
= terminal
;
3446 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
3450 set_tty_hooks (terminal
);
3456 #ifdef O_IGNORE_CTTY
3458 /* Open the terminal device. Don't recognize it as our
3459 controlling terminal, and don't make it the controlling tty
3460 if we don't have one at the moment. */
3461 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
3464 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
3465 defined on Hurd. On other systems, we need to explicitly
3466 dissociate ourselves from the controlling tty when we want to
3467 open a frame on the same terminal. */
3468 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
3469 #endif /* O_IGNORE_CTTY */
3471 tty
->name
= xstrdup (name
);
3472 terminal
->name
= xstrdup (name
);
3475 maybe_fatal (must_succeed
, terminal
,
3476 "Could not open file: %s",
3477 "Could not open file: %s",
3482 maybe_fatal (must_succeed
, terminal
,
3483 "Not a tty device: %s",
3484 "Not a tty device: %s",
3488 #ifndef O_IGNORE_CTTY
3490 dissociate_if_controlling_tty (fd
);
3493 file
= fdopen (fd
, "w+");
3498 tty
->type
= xstrdup (terminal_type
);
3500 add_keyboard_wait_descriptor (fileno (tty
->input
));
3502 #endif /* !DOS_NT */
3504 encode_terminal_src_size
= 0;
3505 encode_terminal_dst_size
= 0;
3508 terminal
->mouse_position_hook
= term_mouse_position
;
3509 mouse_face_window
= Qnil
;
3514 initialize_w32_display (terminal
);
3516 if (strcmp (terminal_type
, "internal") == 0)
3517 terminal
->type
= output_msdos_raw
;
3518 initialize_msdos_display (terminal
);
3520 tty
->output
= stdout
;
3522 /* The following two are inaccessible from w32console.c. */
3523 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3524 terminal
->delete_terminal_hook
= &delete_tty
;
3526 tty
->name
= xstrdup (name
);
3527 terminal
->name
= xstrdup (name
);
3528 tty
->type
= xstrdup (terminal_type
);
3531 add_keyboard_wait_descriptor (0);
3538 struct frame
*f
= XFRAME (selected_frame
);
3540 FrameRows (tty
) = FRAME_LINES (f
);
3541 FrameCols (tty
) = FRAME_COLS (f
);
3542 tty
->specified_window
= FRAME_LINES (f
);
3544 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
3545 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
3550 get_tty_size (fileno (tty
->input
), &width
, &height
);
3551 FrameCols (tty
) = width
;
3552 FrameRows (tty
) = height
;
3555 tty
->delete_in_insert_mode
= 1;
3558 terminal
->scroll_region_ok
= 0;
3560 /* Seems to insert lines when it's not supposed to, messing up the
3561 display. In doing a trace, it didn't seem to be called much, so I
3562 don't think we're losing anything by turning it off. */
3563 terminal
->line_ins_del_ok
= 0;
3565 terminal
->char_ins_del_ok
= 1;
3568 terminal
->char_ins_del_ok
= 0;
3569 init_baud_rate (fileno (tty
->input
));
3572 tty
->TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
3574 #else /* not DOS_NT */
3578 tty
->termcap_term_buffer
= (char *) xmalloc (buffer_size
);
3580 /* On some systems, tgetent tries to access the controlling
3582 sigblock (sigmask (SIGTTOU
));
3583 status
= tgetent (tty
->termcap_term_buffer
, terminal_type
);
3584 sigunblock (sigmask (SIGTTOU
));
3589 maybe_fatal (must_succeed
, terminal
,
3590 "Cannot open terminfo database file",
3591 "Cannot open terminfo database file");
3593 maybe_fatal (must_succeed
, terminal
,
3594 "Cannot open termcap database file",
3595 "Cannot open termcap database file");
3601 maybe_fatal (must_succeed
, terminal
,
3602 "Terminal type %s is not defined",
3603 "Terminal type %s is not defined.\n\
3604 If that is not the actual type of terminal you have,\n\
3605 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3606 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3607 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3610 maybe_fatal (must_succeed
, terminal
,
3611 "Terminal type %s is not defined",
3612 "Terminal type %s is not defined.\n\
3613 If that is not the actual type of terminal you have,\n\
3614 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3615 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3616 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3622 if (strlen (tty
->termcap_term_buffer
) >= buffer_size
)
3624 buffer_size
= strlen (tty
->termcap_term_buffer
);
3626 tty
->termcap_strings_buffer
= area
= (char *) xmalloc (buffer_size
);
3627 tty
->TS_ins_line
= tgetstr ("al", address
);
3628 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
3629 tty
->TS_bell
= tgetstr ("bl", address
);
3630 BackTab (tty
) = tgetstr ("bt", address
);
3631 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
3632 tty
->TS_clr_line
= tgetstr ("ce", address
);
3633 tty
->TS_clr_frame
= tgetstr ("cl", address
);
3634 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
3635 AbsPosition (tty
) = tgetstr ("cm", address
);
3636 CR (tty
) = tgetstr ("cr", address
);
3637 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
3638 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
3639 RowPosition (tty
) = tgetstr ("cv", address
);
3640 tty
->TS_del_char
= tgetstr ("dc", address
);
3641 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
3642 tty
->TS_del_line
= tgetstr ("dl", address
);
3643 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
3644 tty
->TS_delete_mode
= tgetstr ("dm", address
);
3645 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
3646 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
3647 Home (tty
) = tgetstr ("ho", address
);
3648 tty
->TS_ins_char
= tgetstr ("ic", address
);
3649 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
3650 tty
->TS_insert_mode
= tgetstr ("im", address
);
3651 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
3652 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
3653 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
3654 LastLine (tty
) = tgetstr ("ll", address
);
3655 Right (tty
) = tgetstr ("nd", address
);
3656 Down (tty
) = tgetstr ("do", address
);
3658 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
3659 if (tgetflag ("bs"))
3660 Left (tty
) = "\b"; /* can't possibly be longer! */
3661 else /* (Actually, "bs" is obsolete...) */
3662 Left (tty
) = tgetstr ("le", address
);
3664 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
3665 tty
->TS_pad_char
= tgetstr ("pc", address
);
3666 tty
->TS_repeat
= tgetstr ("rp", address
);
3667 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
3668 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
3669 tty
->TS_standout_mode
= tgetstr ("so", address
);
3670 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
3671 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
3672 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
3673 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
3674 Up (tty
) = tgetstr ("up", address
);
3675 tty
->TS_visible_bell
= tgetstr ("vb", address
);
3676 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
3677 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
3678 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
3679 tty
->TS_set_window
= tgetstr ("wi", address
);
3681 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
3682 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
3683 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
3684 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
3685 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
3686 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
3687 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3688 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3689 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
3691 MultiUp (tty
) = tgetstr ("UP", address
);
3692 MultiDown (tty
) = tgetstr ("DO", address
);
3693 MultiLeft (tty
) = tgetstr ("LE", address
);
3694 MultiRight (tty
) = tgetstr ("RI", address
);
3696 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
3697 color because we can't switch back to the default foreground and
3699 tty
->TS_orig_pair
= tgetstr ("op", address
);
3700 if (tty
->TS_orig_pair
)
3702 tty
->TS_set_foreground
= tgetstr ("AF", address
);
3703 tty
->TS_set_background
= tgetstr ("AB", address
);
3704 if (!tty
->TS_set_foreground
)
3707 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
3708 tty
->TS_set_background
= tgetstr ("Sb", address
);
3711 tty
->TN_max_colors
= tgetnum ("Co");
3712 tty
->TN_max_pairs
= tgetnum ("pa");
3714 tty
->TN_no_color_video
= tgetnum ("NC");
3715 if (tty
->TN_no_color_video
== -1)
3716 tty
->TN_no_color_video
= 0;
3719 tty_default_color_capabilities (tty
, 1);
3721 MagicWrap (tty
) = tgetflag ("xn");
3722 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3723 the former flag imply the latter. */
3724 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
3725 terminal
->memory_below_frame
= tgetflag ("db");
3726 tty
->TF_hazeltine
= tgetflag ("hz");
3727 terminal
->must_write_spaces
= tgetflag ("in");
3728 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
3729 tty
->TF_insmode_motion
= tgetflag ("mi");
3730 tty
->TF_standout_motion
= tgetflag ("ms");
3731 tty
->TF_underscore
= tgetflag ("ul");
3732 tty
->TF_teleray
= tgetflag ("xt");
3734 #endif /* !DOS_NT */
3735 terminal
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
3736 init_kboard (terminal
->kboard
);
3737 terminal
->kboard
->Vwindow_system
= Qnil
;
3738 terminal
->kboard
->next_kboard
= all_kboards
;
3739 all_kboards
= terminal
->kboard
;
3740 terminal
->kboard
->reference_count
++;
3741 /* Don't let the initial kboard remain current longer than necessary.
3742 That would cause problems if a file loaded on startup tries to
3743 prompt in the mini-buffer. */
3744 if (current_kboard
== initial_kboard
)
3745 current_kboard
= terminal
->kboard
;
3747 term_get_fkeys (address
, terminal
->kboard
);
3749 /* Get frame size from system, or else from termcap. */
3752 get_tty_size (fileno (tty
->input
), &width
, &height
);
3753 FrameCols (tty
) = width
;
3754 FrameRows (tty
) = height
;
3757 if (FrameCols (tty
) <= 0)
3758 FrameCols (tty
) = tgetnum ("co");
3759 if (FrameRows (tty
) <= 0)
3760 FrameRows (tty
) = tgetnum ("li");
3762 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
3763 maybe_fatal (must_succeed
, terminal
,
3764 "Screen size %dx%d is too small"
3765 "Screen size %dx%d is too small",
3766 FrameCols (tty
), FrameRows (tty
));
3768 TabWidth (tty
) = tgetnum ("tw");
3771 tty
->TS_bell
= "\07";
3773 if (!tty
->TS_fwd_scroll
)
3774 tty
->TS_fwd_scroll
= Down (tty
);
3776 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
3778 if (TabWidth (tty
) < 0)
3781 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3782 and newer termcap doc does not seem to say there is a default.
3783 if (!tty->Wcm->cm_tab)
3784 tty->Wcm->cm_tab = "\t";
3787 /* We don't support standout modes that use `magic cookies', so
3788 turn off any that do. */
3789 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
3791 tty
->TS_standout_mode
= 0;
3792 tty
->TS_end_standout_mode
= 0;
3794 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3796 tty
->TS_enter_underline_mode
= 0;
3797 tty
->TS_exit_underline_mode
= 0;
3800 /* If there's no standout mode, try to use underlining instead. */
3801 if (tty
->TS_standout_mode
== 0)
3803 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
3804 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
3807 /* If no `se' string, try using a `me' string instead.
3808 If that fails, we can't use standout mode at all. */
3809 if (tty
->TS_end_standout_mode
== 0)
3811 char *s
= tgetstr ("me", address
);
3813 tty
->TS_end_standout_mode
= s
;
3815 tty
->TS_standout_mode
= 0;
3818 if (tty
->TF_teleray
)
3820 tty
->Wcm
->cm_tab
= 0;
3821 /* We can't support standout mode, because it uses magic cookies. */
3822 tty
->TS_standout_mode
= 0;
3823 /* But that means we cannot rely on ^M to go to column zero! */
3825 /* LF can't be trusted either -- can alter hpos */
3826 /* if move at column 0 thru a line with TS_standout_mode */
3830 /* Special handling for certain terminal types known to need it */
3832 if (!strcmp (terminal_type
, "supdup"))
3834 terminal
->memory_below_frame
= 1;
3835 tty
->Wcm
->cm_losewrap
= 1;
3837 if (!strncmp (terminal_type
, "c10", 3)
3838 || !strcmp (terminal_type
, "perq"))
3840 /* Supply a makeshift :wi string.
3841 This string is not valid in general since it works only
3842 for windows starting at the upper left corner;
3843 but that is all Emacs uses.
3845 This string works only if the frame is using
3846 the top of the video memory, because addressing is memory-relative.
3847 So first check the :ti string to see if that is true.
3849 It would be simpler if the :wi string could go in the termcap
3850 entry, but it can't because it is not fully valid.
3851 If it were in the termcap entry, it would confuse other programs. */
3852 if (!tty
->TS_set_window
)
3854 p
= tty
->TS_termcap_modes
;
3855 while (*p
&& strcmp (p
, "\033v "))
3858 tty
->TS_set_window
= "\033v%C %C %C %C ";
3860 /* Termcap entry often fails to have :in: flag */
3861 terminal
->must_write_spaces
= 1;
3862 /* :ti string typically fails to have \E^G! in it */
3863 /* This limits scope of insert-char to one line. */
3864 strcpy (area
, tty
->TS_termcap_modes
);
3865 strcat (area
, "\033\007!");
3866 tty
->TS_termcap_modes
= area
;
3867 area
+= strlen (area
) + 1;
3868 p
= AbsPosition (tty
);
3869 /* Change all %+ parameters to %C, to handle
3870 values above 96 correctly for the C100. */
3873 if (p
[0] == '%' && p
[1] == '+')
3879 tty
->specified_window
= FrameRows (tty
);
3881 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
3883 maybe_fatal (must_succeed
, terminal
,
3884 "Terminal type \"%s\" is not powerful enough to run Emacs",
3886 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3887 It lacks the ability to position the cursor.\n\
3888 If that is not the actual type of terminal you have,\n\
3889 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3890 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3891 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3892 # else /* TERMCAP */
3893 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3894 It lacks the ability to position the cursor.\n\
3895 If that is not the actual type of terminal you have,\n\
3896 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3897 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3898 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3899 # endif /* TERMINFO */
3903 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
3904 maybe_fatal (must_succeed
, terminal
,
3905 "Could not determine the frame size",
3906 "Could not determine the frame size");
3908 tty
->delete_in_insert_mode
3909 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
3910 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
3912 tty
->se_is_so
= (tty
->TS_standout_mode
3913 && tty
->TS_end_standout_mode
3914 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
3916 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
3918 terminal
->scroll_region_ok
3920 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
3922 terminal
->line_ins_del_ok
3923 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
3924 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
3925 || (terminal
->scroll_region_ok
3926 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
3928 terminal
->char_ins_del_ok
3929 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
3930 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
3931 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
3933 terminal
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
3935 init_baud_rate (fileno (tty
->input
));
3937 #endif /* not DOS_NT */
3939 /* Init system terminal modes (RAW or CBREAK, etc.). */
3940 init_sys_modes (tty
);
3945 /* Auxiliary error-handling function for init_tty.
3946 Delete TERMINAL, then call error or fatal with str1 or str2,
3947 respectively, according to MUST_SUCCEED. */
3950 maybe_fatal (must_succeed
, terminal
, str1
, str2
, arg1
, arg2
)
3952 struct terminal
*terminal
;
3953 char *str1
, *str2
, *arg1
, *arg2
;
3956 delete_tty (terminal
);
3959 fatal (str2
, arg1
, arg2
);
3961 error (str1
, arg1
, arg2
);
3967 fatal (const char *str
, ...)
3971 fprintf (stderr
, "emacs: ");
3972 vfprintf (stderr
, str
, ap
);
3980 /* Delete the given tty terminal, closing all frames on it. */
3983 delete_tty (struct terminal
*terminal
)
3985 struct tty_display_info
*tty
;
3987 /* Protect against recursive calls. delete_frame in
3988 delete_terminal calls us back when it deletes our last frame. */
3989 if (!terminal
->name
)
3992 if (terminal
->type
!= output_termcap
)
3995 tty
= terminal
->display_info
.tty
;
3997 if (tty
== tty_list
)
3998 tty_list
= tty
->next
;
4001 struct tty_display_info
*p
;
4002 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
4006 /* This should not happen. */
4009 p
->next
= tty
->next
;
4013 /* reset_sys_modes needs a valid device, so this call needs to be
4014 before delete_terminal. */
4015 reset_sys_modes (tty
);
4017 delete_terminal (terminal
);
4025 delete_keyboard_wait_descriptor (fileno (tty
->input
));
4027 if (tty
->input
!= stdin
)
4028 fclose (tty
->input
);
4030 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
4031 fclose (tty
->output
);
4032 if (tty
->termscript
)
4033 fclose (tty
->termscript
);
4035 xfree (tty
->old_tty
);
4037 xfree (tty
->termcap_strings_buffer
);
4038 xfree (tty
->termcap_term_buffer
);
4040 bzero (tty
, sizeof (struct tty_display_info
));
4046 /* Mark the pointers in the tty_display_info objects.
4047 Called by the Fgarbage_collector. */
4052 struct tty_display_info
*tty
;
4054 for (tty
= tty_list
; tty
; tty
= tty
->next
)
4055 mark_object (tty
->top_frame
);
4063 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
4064 doc
: /* Non-nil means the system uses terminfo rather than termcap.
4065 This variable can be used by terminal emulator packages. */);
4067 system_uses_terminfo
= 1;
4069 system_uses_terminfo
= 0;
4072 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions
,
4073 doc
: /* Functions to be run after suspending a tty.
4074 The functions are run with one argument, the terminal object to be suspended.
4075 See `suspend-tty'. */);
4076 Vsuspend_tty_functions
= Qnil
;
4079 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions
,
4080 doc
: /* Functions to be run after resuming a tty.
4081 The functions are run with one argument, the terminal object that was revived.
4082 See `resume-tty'. */);
4083 Vresume_tty_functions
= Qnil
;
4085 DEFVAR_BOOL ("visible-cursor", &visible_cursor
,
4086 doc
: /* Non-nil means to make the cursor very visible.
4087 This only has an effect when running in a text terminal.
4088 What means \"very visible\" is up to your terminal. It may make the cursor
4089 bigger, or it may make it blink, or it may do nothing at all. */);
4092 defsubr (&Stty_display_color_p
);
4093 defsubr (&Stty_display_color_cells
);
4094 defsubr (&Stty_no_underline
);
4095 defsubr (&Stty_type
);
4096 defsubr (&Scontrolling_tty_p
);
4097 defsubr (&Ssuspend_tty
);
4098 defsubr (&Sresume_tty
);
4100 defsubr (&Sgpm_mouse_start
);
4101 defsubr (&Sgpm_mouse_stop
);
4103 staticpro (&mouse_face_window
);
4104 #endif /* HAVE_GPM */
4107 default_orig_pair
= NULL
;
4108 default_set_foreground
= NULL
;
4109 default_set_background
= NULL
;
4110 #endif /* !DOS_NT */
4112 encode_terminal_src
= NULL
;
4113 encode_terminal_dst
= NULL
;
4118 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
4119 (do not change this comment) */