1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
35 #include <termios.h> /* For TIOCNOTTY. */
37 #ifdef HAVE_SYS_IOCTL_H
38 #include <sys/ioctl.h>
49 #include "character.h"
52 #include "composite.h"
56 #include "termhooks.h"
57 #include "dispextern.h"
60 #include "blockinput.h"
61 #include "syssignal.h"
63 #include "intervals.h"
66 static int been_here
= -1;
69 /* For now, don't try to include termcap.h. On some systems,
70 configure finds a non-standard termcap.h that the main build
72 extern void tputs (const char *, int, int (*)(int));
73 extern int tgetent (char *, const char *);
74 extern int tgetflag (char *id
);
75 extern int tgetnum (char *id
);
90 /* The name of the default console device. */
92 #define DEV_TTY "CONOUT$"
94 #define DEV_TTY "/dev/tty"
97 static void tty_set_scroll_region (struct frame
*f
, int start
, int stop
);
98 static void turn_on_face (struct frame
*, int face_id
);
99 static void turn_off_face (struct frame
*, int face_id
);
100 static void tty_show_cursor (struct tty_display_info
*);
101 static void tty_hide_cursor (struct tty_display_info
*);
102 static void tty_background_highlight (struct tty_display_info
*tty
);
103 static void clear_tty_hooks (struct terminal
*terminal
);
104 static void set_tty_hooks (struct terminal
*terminal
);
105 static void dissociate_if_controlling_tty (int fd
);
106 static void delete_tty (struct terminal
*);
107 static void maybe_fatal (int must_succeed
, struct terminal
*terminal
,
108 const char *str1
, const char *str2
, ...) NO_RETURN
;
109 static void vfatal (const char *str
, va_list ap
) NO_RETURN
;
112 #define OUTPUT(tty, a) \
113 emacs_tputs ((tty), a, \
114 (int) (FRAME_LINES (XFRAME (selected_frame)) \
118 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
119 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
121 #define OUTPUT_IF(tty, a) \
124 emacs_tputs ((tty), a, \
125 (int) (FRAME_LINES (XFRAME (selected_frame)) \
130 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
132 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */
134 static int visible_cursor
;
136 /* Display space properties */
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
;
187 char *tparam (char *, char *, int, int, ...);
189 extern char *tgetstr (char *, char **);
193 #include <sys/fcntl.h>
195 static void term_clear_mouse_face (void);
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 (struct glyph
*src
, int src_len
, struct coding_system
*coding
)
568 struct glyph
*src_end
= src
+ src_len
;
570 int nchars
, nbytes
, required
;
571 register int tlen
= GLYPH_TABLE_LENGTH
;
572 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
573 Lisp_Object charset_list
;
575 /* Allocate sufficient size of buffer to store all characters in
576 multibyte-form. But, it may be enlarged on demand if
577 Vglyph_table contains a string or a composite glyph is
579 required
= MAX_MULTIBYTE_LENGTH
* src_len
;
580 if (encode_terminal_src_size
< required
)
582 if (encode_terminal_src
)
583 encode_terminal_src
= xrealloc (encode_terminal_src
, required
);
585 encode_terminal_src
= xmalloc (required
);
586 encode_terminal_src_size
= required
;
589 charset_list
= coding_charset_list (coding
);
591 buf
= encode_terminal_src
;
593 while (src
< src_end
)
595 if (src
->type
== COMPOSITE_GLYPH
)
597 struct composition
*cmp
;
601 nbytes
= buf
- encode_terminal_src
;
602 if (src
->u
.cmp
.automatic
)
604 gstring
= composition_gstring_from_id (src
->u
.cmp
.id
);
605 required
= src
->u
.cmp
.to
+ 1 - src
->u
.cmp
.from
;
609 cmp
= composition_table
[src
->u
.cmp
.id
];
610 required
= MAX_MULTIBYTE_LENGTH
* cmp
->glyph_len
;
613 if (encode_terminal_src_size
< nbytes
+ required
)
615 encode_terminal_src_size
= nbytes
+ required
;
616 encode_terminal_src
= xrealloc (encode_terminal_src
,
617 encode_terminal_src_size
);
618 buf
= encode_terminal_src
+ nbytes
;
621 if (src
->u
.cmp
.automatic
)
622 for (i
= src
->u
.cmp
.from
; i
<= src
->u
.cmp
.to
; i
++)
624 Lisp_Object g
= LGSTRING_GLYPH (gstring
, i
);
625 int c
= LGLYPH_CHAR (g
);
627 if (! char_charset (c
, charset_list
, NULL
))
629 buf
+= CHAR_STRING (c
, buf
);
633 for (i
= 0; i
< cmp
->glyph_len
; i
++)
635 int c
= COMPOSITION_GLYPH (cmp
, i
);
639 if (char_charset (c
, charset_list
, NULL
))
641 if (CHAR_WIDTH (c
) == 0
642 && i
> 0 && COMPOSITION_GLYPH (cmp
, i
- 1) == '\t')
643 /* Should be left-padded */
645 buf
+= CHAR_STRING (' ', buf
);
651 buf
+= CHAR_STRING (c
, buf
);
655 /* We must skip glyphs to be padded for a wide character. */
656 else if (! CHAR_GLYPH_PADDING_P (*src
))
663 SET_GLYPH_FROM_CHAR_GLYPH (g
, src
[0]);
665 if (GLYPH_INVALID_P (g
) || GLYPH_SIMPLE_P (tbase
, tlen
, g
))
667 /* This glyph doesn't have an entry in Vglyph_table. */
672 /* This glyph has an entry in Vglyph_table,
673 so process any alias before testing for simpleness. */
674 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
676 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
677 /* We set the multi-byte form of a character in G
678 (that should be an ASCII character) at WORKBUF. */
681 /* We have a string in Vglyph_table. */
682 string
= tbase
[GLYPH_CHAR (g
)];
687 nbytes
= buf
- encode_terminal_src
;
688 if (encode_terminal_src_size
< nbytes
+ MAX_MULTIBYTE_LENGTH
)
690 encode_terminal_src_size
= nbytes
+ MAX_MULTIBYTE_LENGTH
;
691 encode_terminal_src
= xrealloc (encode_terminal_src
,
692 encode_terminal_src_size
);
693 buf
= encode_terminal_src
+ nbytes
;
695 if (char_charset (c
, charset_list
, NULL
))
697 /* Store the multibyte form of C at BUF. */
698 buf
+= CHAR_STRING (c
, buf
);
703 /* C is not encodable. */
706 while (src
+ 1 < src_end
&& CHAR_GLYPH_PADDING_P (src
[1]))
716 unsigned char *p
= SDATA (string
);
718 if (! STRING_MULTIBYTE (string
))
719 string
= string_to_multibyte (string
);
720 nbytes
= buf
- encode_terminal_src
;
721 if (encode_terminal_src_size
< nbytes
+ SBYTES (string
))
723 encode_terminal_src_size
= nbytes
+ SBYTES (string
);
724 encode_terminal_src
= xrealloc (encode_terminal_src
,
725 encode_terminal_src_size
);
726 buf
= encode_terminal_src
+ nbytes
;
728 memcpy (buf
, SDATA (string
), SBYTES (string
));
729 buf
+= SBYTES (string
);
730 nchars
+= SCHARS (string
);
738 coding
->produced
= 0;
742 nbytes
= buf
- encode_terminal_src
;
743 coding
->source
= encode_terminal_src
;
744 if (encode_terminal_dst_size
== 0)
746 encode_terminal_dst_size
= encode_terminal_src_size
;
747 if (encode_terminal_dst
)
748 encode_terminal_dst
= xrealloc (encode_terminal_dst
,
749 encode_terminal_dst_size
);
751 encode_terminal_dst
= xmalloc (encode_terminal_dst_size
);
753 coding
->destination
= encode_terminal_dst
;
754 coding
->dst_bytes
= encode_terminal_dst_size
;
755 encode_coding_object (coding
, Qnil
, 0, 0, nchars
, nbytes
, Qnil
);
756 /* coding->destination may have been reallocated. */
757 encode_terminal_dst
= coding
->destination
;
758 encode_terminal_dst_size
= coding
->dst_bytes
;
760 return (encode_terminal_dst
);
765 /* An implementation of write_glyphs for termcap frames. */
768 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
770 unsigned char *conversion_buffer
;
771 struct coding_system
*coding
;
773 struct tty_display_info
*tty
= FRAME_TTY (f
);
775 tty_turn_off_insert (tty
);
776 tty_hide_cursor (tty
);
778 /* Don't dare write in last column of bottom line, if Auto-Wrap,
779 since that would scroll the whole frame on some terminals. */
782 && curY (tty
) + 1 == FRAME_LINES (f
)
783 && (curX (tty
) + len
) == FRAME_COLS (f
))
790 /* If terminal_coding does any conversion, use it, otherwise use
791 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
792 because it always return 1 if the member src_multibyte is 1. */
793 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
794 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
795 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
797 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
801 /* Identify a run of glyphs with the same face. */
802 int face_id
= string
->face_id
;
805 for (n
= 1; n
< len
; ++n
)
806 if (string
[n
].face_id
!= face_id
)
809 /* Turn appearance modes of the face of the run on. */
810 tty_highlight_if_desired (tty
);
811 turn_on_face (f
, face_id
);
814 /* This is the last run. */
815 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
816 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
817 if (coding
->produced
> 0)
820 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
821 if (ferror (tty
->output
))
822 clearerr (tty
->output
);
824 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
830 /* Turn appearance modes off. */
831 turn_off_face (f
, face_id
);
832 tty_turn_off_highlight (tty
);
838 #ifdef HAVE_GPM /* Only used by GPM code. */
841 tty_write_glyphs_with_face (register struct frame
*f
, register struct glyph
*string
,
842 register int len
, register int face_id
)
844 unsigned char *conversion_buffer
;
845 struct coding_system
*coding
;
847 struct tty_display_info
*tty
= FRAME_TTY (f
);
849 tty_turn_off_insert (tty
);
850 tty_hide_cursor (tty
);
852 /* Don't dare write in last column of bottom line, if Auto-Wrap,
853 since that would scroll the whole frame on some terminals. */
856 && curY (tty
) + 1 == FRAME_LINES (f
)
857 && (curX (tty
) + len
) == FRAME_COLS (f
))
864 /* If terminal_coding does any conversion, use it, otherwise use
865 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
866 because it always return 1 if the member src_multibyte is 1. */
867 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
868 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
869 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
871 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
873 /* Turn appearance modes of the face. */
874 tty_highlight_if_desired (tty
);
875 turn_on_face (f
, face_id
);
877 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
878 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
879 if (coding
->produced
> 0)
882 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
883 if (ferror (tty
->output
))
884 clearerr (tty
->output
);
886 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
890 /* Turn appearance modes off. */
891 turn_off_face (f
, face_id
);
892 tty_turn_off_highlight (tty
);
898 /* An implementation of insert_glyphs for termcap frames. */
901 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
904 struct glyph
*glyph
= NULL
;
905 unsigned char *conversion_buffer
;
906 unsigned char space
[1];
907 struct coding_system
*coding
;
909 struct tty_display_info
*tty
= FRAME_TTY (f
);
911 if (tty
->TS_ins_multi_chars
)
913 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
917 write_glyphs (f
, start
, len
);
921 tty_turn_on_insert (tty
);
925 space
[0] = SPACEGLYPH
;
927 /* If terminal_coding does any conversion, use it, otherwise use
928 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
929 because it always return 1 if the member src_multibyte is 1. */
930 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
931 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
932 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
934 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
938 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
941 conversion_buffer
= space
;
942 coding
->produced
= 1;
946 tty_highlight_if_desired (tty
);
947 turn_on_face (f
, start
->face_id
);
950 /* We must open sufficient space for a character which
951 occupies more than one column. */
952 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
954 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
959 /* This is the last glyph. */
960 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
962 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
965 if (coding
->produced
> 0)
968 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
969 if (ferror (tty
->output
))
970 clearerr (tty
->output
);
972 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
976 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
979 turn_off_face (f
, glyph
->face_id
);
980 tty_turn_off_highlight (tty
);
987 /* An implementation of delete_glyphs for termcap frames. */
990 tty_delete_glyphs (struct frame
*f
, int n
)
995 struct tty_display_info
*tty
= FRAME_TTY (f
);
997 if (tty
->delete_in_insert_mode
)
999 tty_turn_on_insert (tty
);
1003 tty_turn_off_insert (tty
);
1004 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
1007 if (tty
->TS_del_multi_chars
)
1009 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
1014 for (i
= 0; i
< n
; i
++)
1015 OUTPUT1 (tty
, tty
->TS_del_char
);
1016 if (!tty
->delete_in_insert_mode
)
1017 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
1020 /* An implementation of ins_del_lines for termcap frames. */
1023 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
1025 struct tty_display_info
*tty
= FRAME_TTY (f
);
1026 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
1027 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
1028 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
1030 register int i
= n
> 0 ? n
: -n
;
1033 /* If the lines below the insertion are being pushed
1034 into the end of the window, this is the same as clearing;
1035 and we know the lines are already clear, since the matching
1036 deletion has already been done. So can ignore this. */
1037 /* If the lines below the deletion are blank lines coming
1038 out of the end of the window, don't bother,
1039 as there will be a matching inslines later that will flush them. */
1040 if (FRAME_SCROLL_REGION_OK (f
)
1041 && vpos
+ i
>= tty
->specified_window
)
1043 if (!FRAME_MEMORY_BELOW_FRAME (f
)
1044 && vpos
+ i
>= FRAME_LINES (f
))
1049 raw_cursor_to (f
, vpos
, 0);
1050 tty_background_highlight (tty
);
1051 buf
= tparam (multi
, 0, 0, i
);
1057 raw_cursor_to (f
, vpos
, 0);
1058 tty_background_highlight (tty
);
1060 OUTPUT (tty
, single
);
1061 if (tty
->TF_teleray
)
1066 tty_set_scroll_region (f
, vpos
, tty
->specified_window
);
1068 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
1070 raw_cursor_to (f
, vpos
, 0);
1071 tty_background_highlight (tty
);
1073 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1074 tty_set_scroll_region (f
, 0, tty
->specified_window
);
1077 if (!FRAME_SCROLL_REGION_OK (f
)
1078 && FRAME_MEMORY_BELOW_FRAME (f
)
1081 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
1086 /* Compute cost of sending "str", in characters,
1087 not counting any line-dependent padding. */
1090 string_cost (const char *str
)
1094 tputs (str
, 0, evalcost
);
1098 /* Compute cost of sending "str", in characters,
1099 counting any line-dependent padding at one line. */
1102 string_cost_one_line (const char *str
)
1106 tputs (str
, 1, evalcost
);
1110 /* Compute per line amount of line-dependent padding,
1111 in tenths of characters. */
1114 per_line_cost (const char *str
)
1118 tputs (str
, 0, evalcost
);
1121 tputs (str
, 10, evalcost
);
1125 /* char_ins_del_cost[n] is cost of inserting N characters.
1126 char_ins_del_cost[-n] is cost of deleting N characters.
1127 The length of this vector is based on max_frame_cols. */
1129 int *char_ins_del_vector
;
1131 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1135 calculate_ins_del_char_costs (struct frame
*f
)
1137 struct tty_display_info
*tty
= FRAME_TTY (f
);
1138 int ins_startup_cost
, del_startup_cost
;
1139 int ins_cost_per_char
, del_cost_per_char
;
1143 if (tty
->TS_ins_multi_chars
)
1145 ins_cost_per_char
= 0;
1146 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1148 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1149 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1151 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1152 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1153 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1154 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1158 ins_startup_cost
= 9999;
1159 ins_cost_per_char
= 0;
1162 if (tty
->TS_del_multi_chars
)
1164 del_cost_per_char
= 0;
1165 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1167 else if (tty
->TS_del_char
)
1169 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1170 + string_cost (tty
->TS_end_delete_mode
));
1171 if (tty
->delete_in_insert_mode
)
1172 del_startup_cost
/= 2;
1173 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1177 del_startup_cost
= 9999;
1178 del_cost_per_char
= 0;
1181 /* Delete costs are at negative offsets */
1182 p
= &char_ins_del_cost (f
)[0];
1183 for (i
= FRAME_COLS (f
); --i
>= 0;)
1184 *--p
= (del_startup_cost
+= del_cost_per_char
);
1186 /* Doing nothing is free */
1187 p
= &char_ins_del_cost (f
)[0];
1190 /* Insert costs are at positive offsets */
1191 for (i
= FRAME_COLS (f
); --i
>= 0;)
1192 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1196 calculate_costs (struct frame
*frame
)
1198 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1200 if (FRAME_TERMCAP_P (frame
))
1202 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1203 register char *f
= (tty
->TS_set_scroll_region
1204 ? tty
->TS_set_scroll_region
1205 : tty
->TS_set_scroll_region_1
);
1207 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1211 /* These variables are only used for terminal stuff. They are
1212 allocated once for the terminal frame of X-windows emacs, but not
1215 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1216 X turns off char_ins_del_ok. */
1218 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1219 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1221 if (char_ins_del_vector
!= 0)
1223 = (int *) xrealloc (char_ins_del_vector
,
1225 + 2 * max_frame_cols
* sizeof (int)));
1228 = (int *) xmalloc (sizeof (int)
1229 + 2 * max_frame_cols
* sizeof (int));
1231 memset (char_ins_del_vector
, 0,
1232 (sizeof (int) + 2 * max_frame_cols
* sizeof (int)));
1235 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1236 do_line_insertion_deletion_costs (frame
,
1237 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1238 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1241 do_line_insertion_deletion_costs (frame
,
1242 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1243 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1246 calculate_ins_del_char_costs (frame
);
1248 /* Don't use TS_repeat if its padding is worse than sending the chars */
1249 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1250 tty
->RPov
= string_cost (tty
->TS_repeat
);
1252 tty
->RPov
= FRAME_COLS (frame
) * 2;
1254 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1262 /* Termcap capability names that correspond directly to X keysyms.
1263 Some of these (marked "terminfo") aren't supplied by old-style
1264 (Berkeley) termcap entries. They're listed in X keysym order;
1265 except we put the keypad keys first, so that if they clash with
1266 other keys (as on the IBM PC keyboard) they get overridden.
1269 static const struct fkey_table keys
[] =
1271 {"kh", "home"}, /* termcap */
1272 {"kl", "left"}, /* termcap */
1273 {"ku", "up"}, /* termcap */
1274 {"kr", "right"}, /* termcap */
1275 {"kd", "down"}, /* termcap */
1276 {"%8", "prior"}, /* terminfo */
1277 {"%5", "next"}, /* terminfo */
1278 {"@7", "end"}, /* terminfo */
1279 {"@1", "begin"}, /* terminfo */
1280 {"*6", "select"}, /* terminfo */
1281 {"%9", "print"}, /* terminfo */
1282 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1284 * "insert" --- see below
1286 {"&8", "undo"}, /* terminfo */
1287 {"%0", "redo"}, /* terminfo */
1288 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1289 {"@0", "find"}, /* terminfo */
1290 {"@2", "cancel"}, /* terminfo */
1291 {"%1", "help"}, /* terminfo */
1293 * "break" goes here, but can't be reliably intercepted with termcap
1295 {"&4", "reset"}, /* terminfo --- actually `restart' */
1297 * "system" and "user" --- no termcaps
1299 {"kE", "clearline"}, /* terminfo */
1300 {"kA", "insertline"}, /* terminfo */
1301 {"kL", "deleteline"}, /* terminfo */
1302 {"kI", "insertchar"}, /* terminfo */
1303 {"kD", "deletechar"}, /* terminfo */
1304 {"kB", "backtab"}, /* terminfo */
1306 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1308 {"@8", "kp-enter"}, /* terminfo */
1310 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1311 * "kp-multiply", "kp-add", "kp-separator",
1312 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1313 * --- no termcaps for any of these.
1315 {"K4", "kp-1"}, /* terminfo */
1317 * "kp-2" --- no termcap
1319 {"K5", "kp-3"}, /* terminfo */
1321 * "kp-4" --- no termcap
1323 {"K2", "kp-5"}, /* terminfo */
1325 * "kp-6" --- no termcap
1327 {"K1", "kp-7"}, /* terminfo */
1329 * "kp-8" --- no termcap
1331 {"K3", "kp-9"}, /* terminfo */
1333 * "kp-equal" --- no termcap
1345 {"&0", "S-cancel"}, /*shifted cancel key*/
1346 {"&9", "S-begin"}, /*shifted begin key*/
1347 {"*0", "S-find"}, /*shifted find key*/
1348 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1349 {"*4", "S-delete"}, /*shifted delete-character key*/
1350 {"*7", "S-end"}, /*shifted end key*/
1351 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1352 {"#1", "S-help"}, /*shifted help key*/
1353 {"#2", "S-home"}, /*shifted home key*/
1354 {"#3", "S-insert"}, /*shifted insert-character key*/
1355 {"#4", "S-left"}, /*shifted left-arrow key*/
1356 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1357 {"%c", "S-next"}, /*shifted next key*/
1358 {"%e", "S-prior"}, /*shifted previous key*/
1359 {"%f", "S-print"}, /*shifted print key*/
1360 {"%g", "S-redo"}, /*shifted redo key*/
1361 {"%i", "S-right"}, /*shifted right-arrow key*/
1362 {"!3", "S-undo"} /*shifted undo key*/
1366 static char **term_get_fkeys_address
;
1367 static KBOARD
*term_get_fkeys_kboard
;
1368 static Lisp_Object
term_get_fkeys_1 (void);
1370 /* Find the escape codes sent by the function keys for Vinput_decode_map.
1371 This function scans the termcap function key sequence entries, and
1372 adds entries to Vinput_decode_map for each function key it finds. */
1375 term_get_fkeys (char **address
, KBOARD
*kboard
)
1377 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1378 errors during the call. The only errors should be from Fdefine_key
1379 when given a key sequence containing an invalid prefix key. If the
1380 termcap defines function keys which use a prefix that is already bound
1381 to a command by the default bindings, we should silently ignore that
1382 function key specification, rather than giving the user an error and
1383 refusing to run at all on such a terminal. */
1385 term_get_fkeys_address
= address
;
1386 term_get_fkeys_kboard
= kboard
;
1387 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1391 term_get_fkeys_1 (void)
1395 char **address
= term_get_fkeys_address
;
1396 KBOARD
*kboard
= term_get_fkeys_kboard
;
1398 /* This can happen if CANNOT_DUMP or with strange options. */
1399 if (!KEYMAPP (kboard
->Vinput_decode_map
))
1400 kboard
->Vinput_decode_map
= Fmake_sparse_keymap (Qnil
);
1402 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1404 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1406 Fdefine_key (kboard
->Vinput_decode_map
, build_string (sequence
),
1407 Fmake_vector (make_number (1),
1408 intern (keys
[i
].name
)));
1411 /* The uses of the "k0" capability are inconsistent; sometimes it
1412 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1413 We will attempt to politely accommodate both systems by testing for
1414 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1417 char *k_semi
= tgetstr ("k;", address
);
1418 char *k0
= tgetstr ("k0", address
);
1419 char *k0_name
= "f10";
1424 /* Define f0 first, so that f10 takes precedence in case the
1425 key sequences happens to be the same. */
1426 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k0
),
1427 Fmake_vector (make_number (1), intern ("f0")));
1428 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k_semi
),
1429 Fmake_vector (make_number (1), intern ("f10")));
1432 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k0
),
1433 Fmake_vector (make_number (1), intern (k0_name
)));
1436 /* Set up cookies for numbered function keys above f10. */
1438 char fcap
[3], fkey
[4];
1440 fcap
[0] = 'F'; fcap
[2] = '\0';
1441 for (i
= 11; i
< 64; i
++)
1444 fcap
[1] = '1' + i
- 11;
1446 fcap
[1] = 'A' + i
- 20;
1448 fcap
[1] = 'a' + i
- 46;
1451 char *sequence
= tgetstr (fcap
, address
);
1454 sprintf (fkey
, "f%d", i
);
1455 Fdefine_key (kboard
->Vinput_decode_map
, build_string (sequence
),
1456 Fmake_vector (make_number (1),
1464 * Various mappings to try and get a better fit.
1467 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1468 if (!tgetstr (cap1, address)) \
1470 char *sequence = tgetstr (cap2, address); \
1472 Fdefine_key (kboard->Vinput_decode_map, build_string (sequence), \
1473 Fmake_vector (make_number (1), \
1477 /* if there's no key_next keycap, map key_npage to `next' keysym */
1478 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1479 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1480 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1481 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1482 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1483 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1484 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1486 /* IBM has their own non-standard dialect of terminfo.
1487 If the standard name isn't found, try the IBM name. */
1488 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1489 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1490 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1491 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1492 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1493 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1494 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1495 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1496 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1497 #undef CONDITIONAL_REASSIGN
1502 #endif /* not DOS_NT */
1505 /***********************************************************************
1506 Character Display Information
1507 ***********************************************************************/
1508 static void append_glyph (struct it
*);
1509 static void produce_stretch_glyph (struct it
*);
1510 static void append_composite_glyph (struct it
*);
1511 static void produce_composite_glyph (struct it
*);
1513 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1514 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1515 the character for which to produce glyphs; IT->face_id contains the
1516 character's face. Padding glyphs are appended if IT->c has a
1517 IT->pixel_width > 1. */
1520 append_glyph (struct it
*it
)
1522 struct glyph
*glyph
, *end
;
1525 xassert (it
->glyph_row
);
1526 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1527 + it
->glyph_row
->used
[it
->area
]);
1528 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1530 /* If the glyph row is reversed, we need to prepend the glyph rather
1532 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1535 int move_by
= it
->pixel_width
;
1537 /* Make room for the new glyphs. */
1538 if (move_by
> end
- glyph
) /* don't overstep end of this area */
1539 move_by
= end
- glyph
;
1540 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1542 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1543 end
= glyph
+ move_by
;
1546 /* BIDI Note: we put the glyphs of a "multi-pixel" character left to
1547 right, even in the REVERSED_P case, since (a) all of its u.ch are
1548 identical, and (b) the PADDING_P flag needs to be set for the
1549 leftmost one, because we write to the terminal left-to-right. */
1551 i
< it
->pixel_width
&& glyph
< end
;
1554 glyph
->type
= CHAR_GLYPH
;
1555 glyph
->pixel_width
= 1;
1556 glyph
->u
.ch
= it
->char_to_display
;
1557 glyph
->face_id
= it
->face_id
;
1558 glyph
->padding_p
= i
> 0;
1559 glyph
->charpos
= CHARPOS (it
->position
);
1560 glyph
->object
= it
->object
;
1563 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1564 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1566 glyph
->bidi_type
= it
->bidi_it
.type
;
1570 glyph
->resolved_level
= 0;
1571 glyph
->bidi_type
= UNKNOWN_BT
;
1574 ++it
->glyph_row
->used
[it
->area
];
1579 /* Produce glyphs for the display element described by IT. *IT
1580 specifies what we want to produce a glyph for (character, image, ...),
1581 and where in the glyph matrix we currently are (glyph row and hpos).
1582 produce_glyphs fills in output fields of *IT with information such as the
1583 pixel width and height of a character, and maybe output actual glyphs at
1584 the same time if IT->glyph_row is non-null. For an overview, see
1585 the explanation in dispextern.h, before the definition of the
1586 display_element_type enumeration.
1588 produce_glyphs also stores the result of glyph width, ascent
1589 etc. computations in *IT.
1591 IT->glyph_row may be null, in which case produce_glyphs does not
1592 actually fill in the glyphs. This is used in the move_* functions
1593 in xdisp.c for text width and height computations.
1595 Callers usually don't call produce_glyphs directly;
1596 instead they use the macro PRODUCE_GLYPHS. */
1599 produce_glyphs (struct it
*it
)
1601 /* If a hook is installed, let it do the work. */
1603 /* Nothing but characters are supported on terminal frames. */
1604 xassert (it
->what
== IT_CHARACTER
1605 || it
->what
== IT_COMPOSITION
1606 || it
->what
== IT_STRETCH
);
1608 if (it
->what
== IT_STRETCH
)
1610 produce_stretch_glyph (it
);
1614 if (it
->what
== IT_COMPOSITION
)
1616 produce_composite_glyph (it
);
1620 /* Maybe translate single-byte characters to multibyte. */
1621 it
->char_to_display
= it
->c
;
1623 if (it
->c
>= 040 && it
->c
< 0177)
1625 it
->pixel_width
= it
->nglyphs
= 1;
1629 else if (it
->c
== '\n')
1630 it
->pixel_width
= it
->nglyphs
= 0;
1631 else if (it
->c
== '\t')
1633 int absolute_x
= (it
->current_x
1634 + it
->continuation_lines_width
);
1636 = (((1 + absolute_x
+ it
->tab_width
- 1)
1641 /* If part of the TAB has been displayed on the previous line
1642 which is continued now, continuation_lines_width will have
1643 been incremented already by the part that fitted on the
1644 continued line. So, we will get the right number of spaces
1646 nspaces
= next_tab_x
- absolute_x
;
1652 it
->char_to_display
= ' ';
1653 it
->pixel_width
= it
->len
= 1;
1659 it
->pixel_width
= nspaces
;
1660 it
->nglyphs
= nspaces
;
1662 else if (CHAR_BYTE8_P (it
->c
))
1664 if (unibyte_display_via_language_environment
1667 it
->char_to_display
= BYTE8_TO_CHAR (it
->c
);
1668 it
->pixel_width
= CHAR_WIDTH (it
->char_to_display
);
1669 it
->nglyphs
= it
->pixel_width
;
1675 /* Coming here means that it->c is from display table, thus
1676 we must send the raw 8-bit byte as is to the terminal.
1677 Although there's no way to know how many columns it
1678 occupies on a screen, it is a good assumption that a
1679 single byte code has 1-column width. */
1680 it
->pixel_width
= it
->nglyphs
= 1;
1687 it
->pixel_width
= CHAR_WIDTH (it
->c
);
1688 it
->nglyphs
= it
->pixel_width
;
1695 /* Advance current_x by the pixel width as a convenience for
1697 if (it
->area
== TEXT_AREA
)
1698 it
->current_x
+= it
->pixel_width
;
1699 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1700 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1704 /* Produce a stretch glyph for iterator IT. IT->object is the value
1705 of the glyph property displayed. The value must be a list
1706 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1709 1. `:width WIDTH' specifies that the space should be WIDTH *
1710 canonical char width wide. WIDTH may be an integer or floating
1713 2. `:align-to HPOS' specifies that the space should be wide enough
1714 to reach HPOS, a value in canonical character units. */
1717 produce_stretch_glyph (struct it
*it
)
1719 /* (space :width WIDTH ...) */
1720 Lisp_Object prop
, plist
;
1721 int width
= 0, align_to
= -1;
1722 int zero_width_ok_p
= 0;
1725 /* List should start with `space'. */
1726 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1727 plist
= XCDR (it
->object
);
1729 /* Compute the width of the stretch. */
1730 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1731 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1733 /* Absolute width `:width WIDTH' specified and valid. */
1734 zero_width_ok_p
= 1;
1735 width
= (int)(tem
+ 0.5);
1737 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1738 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1740 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1741 align_to
= (align_to
< 0
1743 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1744 else if (align_to
< 0)
1745 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1746 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1747 zero_width_ok_p
= 1;
1750 /* Nothing specified -> width defaults to canonical char width. */
1751 width
= FRAME_COLUMN_WIDTH (it
->f
);
1753 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1756 if (width
> 0 && it
->line_wrap
!= TRUNCATE
1757 && it
->current_x
+ width
> it
->last_visible_x
)
1758 width
= it
->last_visible_x
- it
->current_x
- 1;
1760 if (width
> 0 && it
->glyph_row
)
1762 Lisp_Object o_object
= it
->object
;
1763 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1766 if (!STRINGP (object
))
1767 object
= it
->w
->buffer
;
1768 it
->object
= object
;
1769 it
->char_to_display
= ' ';
1770 it
->pixel_width
= it
->len
= 1;
1773 it
->object
= o_object
;
1775 it
->pixel_width
= width
;
1776 it
->nglyphs
= width
;
1780 /* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
1781 Called from produce_composite_glyph for terminal frames if
1782 IT->glyph_row != NULL. IT->face_id contains the character's
1786 append_composite_glyph (struct it
*it
)
1788 struct glyph
*glyph
;
1790 xassert (it
->glyph_row
);
1791 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1792 if (glyph
< it
->glyph_row
->glyphs
[1 + it
->area
])
1794 /* If the glyph row is reversed, we need to prepend the glyph
1795 rather than append it. */
1796 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
1800 /* Make room for the new glyph. */
1801 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
1803 glyph
= it
->glyph_row
->glyphs
[it
->area
];
1805 glyph
->type
= COMPOSITE_GLYPH
;
1806 glyph
->pixel_width
= it
->pixel_width
;
1807 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1808 if (it
->cmp_it
.ch
< 0)
1810 glyph
->u
.cmp
.automatic
= 0;
1811 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1815 glyph
->u
.cmp
.automatic
= 1;
1816 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
1817 glyph
->u
.cmp
.from
= it
->cmp_it
.from
;
1818 glyph
->u
.cmp
.to
= it
->cmp_it
.to
- 1;
1821 glyph
->face_id
= it
->face_id
;
1822 glyph
->padding_p
= 0;
1823 glyph
->charpos
= CHARPOS (it
->position
);
1824 glyph
->object
= it
->object
;
1827 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
1828 if ((it
->bidi_it
.type
& 7) != it
->bidi_it
.type
)
1830 glyph
->bidi_type
= it
->bidi_it
.type
;
1834 glyph
->resolved_level
= 0;
1835 glyph
->bidi_type
= UNKNOWN_BT
;
1838 ++it
->glyph_row
->used
[it
->area
];
1844 /* Produce a composite glyph for iterator IT. IT->cmp_id is the ID of
1845 the composition. We simply produces components of the composition
1846 assuming that the terminal has a capability to layout/render it
1850 produce_composite_glyph (struct it
*it
)
1852 if (it
->cmp_it
.ch
< 0)
1854 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
1856 it
->pixel_width
= cmp
->width
;
1860 Lisp_Object gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
1862 it
->pixel_width
= composition_gstring_width (gstring
, it
->cmp_it
.from
,
1863 it
->cmp_it
.to
, NULL
);
1867 append_composite_glyph (it
);
1871 /* Get information about special display element WHAT in an
1872 environment described by IT. WHAT is one of IT_TRUNCATION or
1873 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1874 non-null glyph_row member. This function ensures that fields like
1875 face_id, c, len of IT are left untouched. */
1878 produce_special_glyphs (struct it
*it
, enum display_element_type what
)
1886 temp_it
.what
= IT_CHARACTER
;
1888 temp_it
.object
= make_number (0);
1889 memset (&temp_it
.current
, 0, sizeof temp_it
.current
);
1891 if (what
== IT_CONTINUATION
)
1893 /* Continuation glyph. For R2L lines, we mirror it by hand. */
1894 if (it
->bidi_it
.paragraph_dir
== R2L
)
1895 SET_GLYPH_FROM_CHAR (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 /* FIXME: Should we mirror GC for R2L lines? */
1903 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
1904 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
1907 else if (what
== IT_TRUNCATION
)
1909 /* Truncation glyph. */
1910 SET_GLYPH_FROM_CHAR (glyph
, '$');
1912 && (gc
= DISP_TRUNC_GLYPH (it
->dp
), GLYPH_CODE_P (gc
))
1913 && GLYPH_CODE_CHAR_VALID_P (gc
))
1915 /* FIXME: Should we mirror GC for R2L lines? */
1916 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
1917 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
1923 temp_it
.c
= GLYPH_CHAR (glyph
);
1924 temp_it
.face_id
= GLYPH_FACE (glyph
);
1925 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1927 produce_glyphs (&temp_it
);
1928 it
->pixel_width
= temp_it
.pixel_width
;
1929 it
->nglyphs
= temp_it
.pixel_width
;
1934 /***********************************************************************
1936 ***********************************************************************/
1938 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1939 one of the enumerators from enum no_color_bit, or a bit set built
1940 from them. Some display attributes may not be used together with
1941 color; the termcap capability `NC' specifies which ones. */
1943 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1944 (tty->TN_max_colors > 0 \
1945 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1948 /* Turn appearances of face FACE_ID on tty frame F on.
1949 FACE_ID is a realized face ID number, in the face cache. */
1952 turn_on_face (struct frame
*f
, int 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 (struct frame
*f
, int face_id
)
2051 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2052 struct tty_display_info
*tty
= FRAME_TTY (f
);
2054 xassert (face
!= NULL
);
2056 if (tty
->TS_exit_attribute_mode
)
2058 /* Capability "me" will turn off appearance modes double-bright,
2059 half-bright, reverse-video, standout, underline. It may or
2060 may not turn off alt-char-mode. */
2061 if (face
->tty_bold_p
2063 || face
->tty_reverse_p
2064 || face
->tty_alt_charset_p
2065 || face
->tty_blinking_p
2066 || face
->tty_underline_p
)
2068 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
2069 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
2070 tty
->standout_mode
= 0;
2073 if (face
->tty_alt_charset_p
)
2074 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
2078 /* If we don't have "me" we can only have those appearances
2079 that have exit sequences defined. */
2080 if (face
->tty_alt_charset_p
)
2081 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
2083 if (face
->tty_underline_p
)
2084 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
2087 /* Switch back to default colors. */
2088 if (tty
->TN_max_colors
> 0
2089 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2090 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2091 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2092 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2093 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
2097 /* Return non-zero if the terminal on frame F supports all of the
2098 capabilities in CAPS simultaneously, with foreground and background
2099 colors FG and BG. */
2102 tty_capable_p (struct tty_display_info
*tty
, unsigned int caps
,
2103 unsigned long fg
, unsigned long bg
)
2105 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
2106 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
2109 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
2110 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
2111 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
2112 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
2113 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
2114 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
2120 /* Return non-zero if the terminal is capable to display colors. */
2122 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2124 doc
: /* Return non-nil if the tty device TERMINAL can display colors.
2126 TERMINAL can be a terminal object, a frame, or nil (meaning the
2127 selected frame's terminal). This function always returns nil if
2128 TERMINAL does not refer to a text-only terminal. */)
2129 (Lisp_Object terminal
)
2131 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2135 return t
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
2138 /* Return the number of supported colors. */
2139 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2140 Stty_display_color_cells
, 0, 1, 0,
2141 doc
: /* Return the number of colors supported by the tty device TERMINAL.
2143 TERMINAL can be a terminal object, a frame, or nil (meaning the
2144 selected frame's terminal). This function always returns 0 if
2145 TERMINAL does not refer to a text-only terminal. */)
2146 (Lisp_Object terminal
)
2148 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2150 return make_number (0);
2152 return make_number (t
->display_info
.tty
->TN_max_colors
);
2157 /* Declare here rather than in the function, as in the rest of Emacs,
2158 to work around an HPUX compiler bug (?). See
2159 http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00410.html */
2160 static int default_max_colors
;
2161 static int default_max_pairs
;
2162 static int default_no_color_video
;
2163 static char *default_orig_pair
;
2164 static char *default_set_foreground
;
2165 static char *default_set_background
;
2167 /* Save or restore the default color-related capabilities of this
2170 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
2175 xfree (default_orig_pair
);
2176 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
2178 xfree (default_set_foreground
);
2179 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
2182 xfree (default_set_background
);
2183 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
2186 default_max_colors
= tty
->TN_max_colors
;
2187 default_max_pairs
= tty
->TN_max_pairs
;
2188 default_no_color_video
= tty
->TN_no_color_video
;
2192 tty
->TS_orig_pair
= default_orig_pair
;
2193 tty
->TS_set_foreground
= default_set_foreground
;
2194 tty
->TS_set_background
= default_set_background
;
2195 tty
->TN_max_colors
= default_max_colors
;
2196 tty
->TN_max_pairs
= default_max_pairs
;
2197 tty
->TN_no_color_video
= default_no_color_video
;
2201 /* Setup one of the standard tty color schemes according to MODE.
2202 MODE's value is generally the number of colors which we want to
2203 support; zero means set up for the default capabilities, the ones
2204 we saw at init_tty time; -1 means turn off color support. */
2206 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2208 /* Canonicalize all negative values of MODE. */
2214 case -1: /* no colors at all */
2215 tty
->TN_max_colors
= 0;
2216 tty
->TN_max_pairs
= 0;
2217 tty
->TN_no_color_video
= 0;
2218 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2220 case 0: /* default colors, if any */
2222 tty_default_color_capabilities (tty
, 0);
2224 case 8: /* 8 standard ANSI colors */
2225 tty
->TS_orig_pair
= "\033[0m";
2227 tty
->TS_set_foreground
= "\033[3%p1%dm";
2228 tty
->TS_set_background
= "\033[4%p1%dm";
2230 tty
->TS_set_foreground
= "\033[3%dm";
2231 tty
->TS_set_background
= "\033[4%dm";
2233 tty
->TN_max_colors
= 8;
2234 tty
->TN_max_pairs
= 64;
2235 tty
->TN_no_color_video
= 0;
2241 set_tty_color_mode (struct tty_display_info
*tty
, struct frame
*f
)
2243 Lisp_Object tem
, val
;
2244 Lisp_Object color_mode
;
2246 Lisp_Object tty_color_mode_alist
2247 = Fintern_soft (build_string ("tty-color-mode-alist"), Qnil
);
2249 tem
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2250 val
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2254 else if (SYMBOLP (tty_color_mode_alist
))
2256 tem
= Fassq (val
, Fsymbol_value (tty_color_mode_alist
));
2257 color_mode
= CONSP (tem
) ? XCDR (tem
) : Qnil
;
2262 mode
= INTEGERP (color_mode
) ? XINT (color_mode
) : 0;
2264 if (mode
!= tty
->previous_color_mode
)
2266 Lisp_Object funsym
= intern ("tty-set-up-initial-frame-faces");
2267 tty
->previous_color_mode
= mode
;
2268 tty_setup_colors (tty
, mode
);
2269 /* This recomputes all the faces given the new color definitions. */
2270 safe_call (1, &funsym
);
2274 #endif /* !DOS_NT */
2278 /* Return the tty display object specified by TERMINAL. */
2281 get_tty_terminal (Lisp_Object terminal
, int throw)
2283 struct terminal
*t
= get_terminal (terminal
, throw);
2285 if (t
&& t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2288 error ("Device %d is not a termcap terminal device", t
->id
);
2296 /* Return an active termcap device that uses the tty device with the
2299 This function ignores suspended devices.
2301 Returns NULL if the named terminal device is not opened. */
2304 get_named_tty (const char *name
)
2311 for (t
= terminal_list
; t
; t
= t
->next_terminal
)
2313 if ((t
->type
== output_termcap
|| t
->type
== output_msdos_raw
)
2314 && !strcmp (t
->display_info
.tty
->name
, name
)
2315 && TERMINAL_ACTIVE_P (t
))
2323 DEFUN ("tty-type", Ftty_type
, Stty_type
, 0, 1, 0,
2324 doc
: /* Return the type of the tty device that TERMINAL uses.
2325 Returns nil if TERMINAL is not on a tty device.
2327 TERMINAL can be a terminal object, a frame, or nil (meaning the
2328 selected frame's terminal). */)
2329 (Lisp_Object terminal
)
2331 struct terminal
*t
= get_terminal (terminal
, 1);
2333 if (t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2336 if (t
->display_info
.tty
->type
)
2337 return build_string (t
->display_info
.tty
->type
);
2342 DEFUN ("controlling-tty-p", Fcontrolling_tty_p
, Scontrolling_tty_p
, 0, 1, 0,
2343 doc
: /* Return non-nil if TERMINAL is the controlling tty of the Emacs process.
2345 TERMINAL can be a terminal object, a frame, or nil (meaning the
2346 selected frame's terminal). This function always returns nil if
2347 TERMINAL is not on a tty device. */)
2348 (Lisp_Object terminal
)
2350 struct terminal
*t
= get_terminal (terminal
, 1);
2352 if ((t
->type
!= output_termcap
&& t
->type
!= output_msdos_raw
)
2353 || strcmp (t
->display_info
.tty
->name
, DEV_TTY
) != 0)
2359 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 1, 0,
2360 doc
: /* Declare that the tty used by TERMINAL does not handle underlining.
2361 This is used to override the terminfo data, for certain terminals that
2362 do not really do underlining, but say that they do. This function has
2363 no effect if used on a non-tty terminal.
2365 TERMINAL can be a terminal object, a frame or nil (meaning the
2366 selected frame's terminal). This function always returns nil if
2367 TERMINAL does not refer to a text-only terminal. */)
2368 (Lisp_Object terminal
)
2370 struct terminal
*t
= get_terminal (terminal
, 1);
2372 if (t
->type
== output_termcap
)
2373 t
->display_info
.tty
->TS_enter_underline_mode
= 0;
2379 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
2380 doc
: /* Suspend the terminal device TTY.
2382 The device is restored to its default state, and Emacs ceases all
2383 access to the tty device. Frames that use the device are not deleted,
2384 but input is not read from them and if they change, their display is
2387 TTY may be a terminal object, a frame, or nil for the terminal device
2388 of the currently selected frame.
2390 This function runs `suspend-tty-functions' after suspending the
2391 device. The functions are run with one arg, the id of the suspended
2394 `suspend-tty' does nothing if it is called on a device that is already
2397 A suspended tty may be resumed by calling `resume-tty' on it. */)
2400 struct terminal
*t
= get_tty_terminal (tty
, 1);
2404 error ("Unknown tty device");
2406 f
= t
->display_info
.tty
->input
;
2410 /* First run `suspend-tty-functions' and then clean up the tty
2411 state because `suspend-tty-functions' might need to change
2413 if (!NILP (Vrun_hooks
))
2415 Lisp_Object args
[2];
2416 args
[0] = intern ("suspend-tty-functions");
2417 XSETTERMINAL (args
[1], t
);
2418 Frun_hook_with_args (2, args
);
2421 reset_sys_modes (t
->display_info
.tty
);
2422 delete_keyboard_wait_descriptor (fileno (f
));
2426 if (f
!= t
->display_info
.tty
->output
)
2427 fclose (t
->display_info
.tty
->output
);
2430 t
->display_info
.tty
->input
= 0;
2431 t
->display_info
.tty
->output
= 0;
2433 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2434 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 0);
2438 /* Clear display hooks to prevent further output. */
2439 clear_tty_hooks (t
);
2444 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
2445 doc
: /* Resume the previously suspended terminal device TTY.
2446 The terminal is opened and reinitialized. Frames that are on the
2447 suspended terminal are revived.
2449 It is an error to resume a terminal while another terminal is active
2452 This function runs `resume-tty-functions' after resuming the terminal.
2453 The functions are run with one arg, the id of the resumed terminal
2456 `resume-tty' does nothing if it is called on a device that is not
2459 TTY may be a terminal object, a frame, or nil (meaning the selected
2460 frame's terminal). */)
2463 struct terminal
*t
= get_tty_terminal (tty
, 1);
2467 error ("Unknown tty device");
2469 if (!t
->display_info
.tty
->input
)
2471 if (get_named_tty (t
->display_info
.tty
->name
))
2472 error ("Cannot resume display while another display is active on the same device");
2475 t
->display_info
.tty
->output
= stdout
;
2476 t
->display_info
.tty
->input
= stdin
;
2478 fd
= emacs_open (t
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
2481 error ("Can not reopen tty device %s: %s", t
->display_info
.tty
->name
, strerror (errno
));
2483 if (strcmp (t
->display_info
.tty
->name
, DEV_TTY
))
2484 dissociate_if_controlling_tty (fd
);
2486 t
->display_info
.tty
->output
= fdopen (fd
, "w+");
2487 t
->display_info
.tty
->input
= t
->display_info
.tty
->output
;
2490 add_keyboard_wait_descriptor (fd
);
2492 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2494 struct frame
*f
= XFRAME (t
->display_info
.tty
->top_frame
);
2496 int old_height
= FRAME_COLS (f
);
2497 int old_width
= FRAME_LINES (f
);
2499 /* Check if terminal/window size has changed while the frame
2501 get_tty_size (fileno (t
->display_info
.tty
->input
), &width
, &height
);
2502 if (width
!= old_width
|| height
!= old_height
)
2503 change_frame_size (f
, height
, width
, 0, 0, 0);
2504 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 1);
2507 init_sys_modes (t
->display_info
.tty
);
2509 /* Run `resume-tty-functions'. */
2510 if (!NILP (Vrun_hooks
))
2512 Lisp_Object args
[2];
2513 args
[0] = intern ("resume-tty-functions");
2514 XSETTERMINAL (args
[1], t
);
2515 Frun_hook_with_args (2, args
);
2525 /***********************************************************************
2527 ***********************************************************************/
2531 term_mouse_moveto (int x
, int y
)
2533 /* TODO: how to set mouse position?
2536 name = (const char *) ttyname (0);
2537 fd = open (name, O_WRONLY);
2538 SOME_FUNCTION (x, y, fd);
2541 last_mouse_y = y; */
2545 term_show_mouse_face (enum draw_glyphs_face draw
)
2547 struct window
*w
= XWINDOW (mouse_face_window
);
2551 struct frame
*f
= XFRAME (w
->frame
);
2552 struct tty_display_info
*tty
= FRAME_TTY (f
);
2554 if (/* If window is in the process of being destroyed, don't bother
2556 w
->current_matrix
!= NULL
2557 /* Recognize when we are called to operate on rows that don't exist
2558 anymore. This can happen when a window is split. */
2559 && mouse_face_end_row
< w
->current_matrix
->nrows
)
2561 /* write_glyphs writes at cursor position, so we need to
2562 temporarily move cursor coordinates to the beginning of
2563 the highlight region. */
2565 /* Save current cursor co-ordinates */
2566 save_y
= curY (tty
);
2567 save_x
= curX (tty
);
2569 /* Note that mouse_face_beg_row etc. are window relative. */
2570 for (i
= mouse_face_beg_row
; i
<= mouse_face_end_row
; i
++)
2572 int start_hpos
, end_hpos
, nglyphs
;
2573 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
2575 /* Don't do anything if row doesn't have valid contents. */
2576 if (!row
->enabled_p
)
2579 /* For all but the first row, the highlight starts at column 0. */
2580 if (i
== mouse_face_beg_row
)
2581 start_hpos
= mouse_face_beg_col
;
2585 if (i
== mouse_face_end_row
)
2586 end_hpos
= mouse_face_end_col
;
2589 end_hpos
= row
->used
[TEXT_AREA
];
2590 if (draw
== DRAW_NORMAL_TEXT
)
2591 row
->fill_line_p
= 1; /* Clear to end of line */
2594 if (end_hpos
<= start_hpos
)
2596 /* Record that some glyphs of this row are displayed in
2598 row
->mouse_face_p
= draw
> 0;
2600 nglyphs
= end_hpos
- start_hpos
;
2602 if (end_hpos
>= row
->used
[TEXT_AREA
])
2603 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2605 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2606 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
2607 + WINDOW_LEFT_EDGE_X (w
);
2609 cursor_to (f
, pos_y
, pos_x
);
2611 if (draw
== DRAW_MOUSE_FACE
)
2613 tty_write_glyphs_with_face (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
,
2614 nglyphs
, mouse_face_face_id
);
2616 else /* draw == DRAW_NORMAL_TEXT */
2617 write_glyphs (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2619 cursor_to (f
, save_y
, save_x
);
2624 term_clear_mouse_face (void)
2626 if (!NILP (mouse_face_window
))
2627 term_show_mouse_face (DRAW_NORMAL_TEXT
);
2629 mouse_face_beg_row
= mouse_face_beg_col
= -1;
2630 mouse_face_end_row
= mouse_face_end_col
= -1;
2631 mouse_face_window
= Qnil
;
2634 /* Find the glyph matrix position of buffer position POS in window W.
2635 *HPOS and *VPOS are set to the positions found. W's current glyphs
2636 must be up to date. If POS is above window start return (0, 0).
2637 If POS is after end of W, return end of last line in W.
2638 - taken from msdos.c */
2640 fast_find_position (struct window
*w
, int pos
, int *hpos
, int *vpos
)
2642 int i
, lastcol
, line_start_position
, maybe_next_line_p
= 0;
2643 int yb
= window_text_bottom_y (w
);
2644 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0), *best_row
= row
;
2648 if (row
->used
[TEXT_AREA
])
2649 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
2651 line_start_position
= 0;
2653 if (line_start_position
> pos
)
2655 /* If the position sought is the end of the buffer,
2656 don't include the blank lines at the bottom of the window. */
2657 else if (line_start_position
== pos
2658 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
2660 maybe_next_line_p
= 1;
2663 else if (line_start_position
> 0)
2666 /* Don't overstep the last matrix row, lest we get into the
2667 never-never land... */
2668 if (row
->y
+ 1 >= yb
)
2674 /* Find the right column within BEST_ROW. */
2677 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
2679 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + i
;
2682 charpos
= glyph
->charpos
;
2689 else if (charpos
> pos
)
2691 else if (charpos
> 0)
2695 /* If we're looking for the end of the buffer,
2696 and we didn't find it in the line we scanned,
2697 use the start of the following line. */
2698 if (maybe_next_line_p
)
2705 *hpos
= lastcol
+ 1;
2710 term_mouse_highlight (struct frame
*f
, int x
, int y
)
2712 enum window_part part
;
2717 if (NILP (Vmouse_highlight
)
2718 || !f
->glyphs_initialized_p
)
2721 /* Which window is that in? */
2722 window
= window_from_coordinates (f
, x
, y
, &part
, &x
, &y
, 0);
2724 /* Not on a window -> return. */
2725 if (!WINDOWP (window
))
2728 if (!EQ (window
, mouse_face_window
))
2729 term_clear_mouse_face ();
2731 w
= XWINDOW (window
);
2733 /* Are we in a window whose display is up to date?
2734 And verify the buffer's text has not changed. */
2735 b
= XBUFFER (w
->buffer
);
2737 && EQ (w
->window_end_valid
, w
->buffer
)
2738 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
2739 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
2741 int pos
, i
, nrows
= w
->current_matrix
->nrows
;
2742 struct glyph_row
*row
;
2743 struct glyph
*glyph
;
2745 /* Find the glyph under X/Y. */
2747 if (y
>= 0 && y
< nrows
)
2749 row
= MATRIX_ROW (w
->current_matrix
, y
);
2750 /* Give up if some row before the one we are looking for is
2752 for (i
= 0; i
<= y
; i
++)
2753 if (!MATRIX_ROW (w
->current_matrix
, i
)->enabled_p
)
2755 if (i
> y
/* all rows upto and including the one at Y are enabled */
2756 && row
->displays_text_p
2757 && x
< window_box_width (w
, TEXT_AREA
))
2759 glyph
= row
->glyphs
[TEXT_AREA
];
2760 if (x
>= row
->used
[TEXT_AREA
])
2765 if (!BUFFERP (glyph
->object
))
2771 /* Clear mouse face if X/Y not over text. */
2774 term_clear_mouse_face ();
2778 if (!BUFFERP (glyph
->object
))
2780 pos
= glyph
->charpos
;
2782 /* Check for mouse-face. */
2784 Lisp_Object mouse_face
, overlay
, position
, *overlay_vec
;
2785 int noverlays
, obegv
, ozv
;
2786 struct buffer
*obuf
;
2788 /* If we get an out-of-range value, return now; avoid an error. */
2789 if (pos
> BUF_Z (b
))
2792 /* Make the window's buffer temporarily current for
2793 overlays_at and compute_char_face. */
2794 obuf
= current_buffer
;
2801 /* Is this char mouse-active? */
2802 XSETINT (position
, pos
);
2804 /* Put all the overlays we want in a vector in overlay_vec. */
2805 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
2806 /* Sort overlays into increasing priority order. */
2807 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
2809 /* Check mouse-face highlighting. */
2810 if (!(EQ (window
, mouse_face_window
)
2811 && y
>= mouse_face_beg_row
2812 && y
<= mouse_face_end_row
2813 && (y
> mouse_face_beg_row
2814 || x
>= mouse_face_beg_col
)
2815 && (y
< mouse_face_end_row
2816 || x
< mouse_face_end_col
2817 || mouse_face_past_end
)))
2819 /* Clear the display of the old active region, if any. */
2820 term_clear_mouse_face ();
2822 /* Find the highest priority overlay that has a mouse-face
2825 for (i
= noverlays
- 1; i
>= 0; --i
)
2827 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
2828 if (!NILP (mouse_face
))
2830 overlay
= overlay_vec
[i
];
2835 /* If no overlay applies, get a text property. */
2837 mouse_face
= Fget_text_property (position
, Qmouse_face
,
2840 /* Handle the overlay case. */
2841 if (!NILP (overlay
))
2843 /* Find the range of text around this char that
2844 should be active. */
2845 Lisp_Object before
, after
;
2849 before
= Foverlay_start (overlay
);
2850 after
= Foverlay_end (overlay
);
2851 /* Record this as the current active region. */
2852 fast_find_position (w
, XFASTINT (before
),
2853 &mouse_face_beg_col
,
2854 &mouse_face_beg_row
);
2857 = !fast_find_position (w
, XFASTINT (after
),
2858 &mouse_face_end_col
,
2859 &mouse_face_end_row
);
2860 mouse_face_window
= window
;
2863 = face_at_buffer_position (w
, pos
, 0, 0,
2864 &ignore
, pos
+ 1, 1, -1);
2866 /* Display it as active. */
2867 term_show_mouse_face (DRAW_MOUSE_FACE
);
2869 /* Handle the text property case. */
2870 else if (!NILP (mouse_face
))
2872 /* Find the range of text around this char that
2873 should be active. */
2874 Lisp_Object before
, after
, beginning
, end
;
2877 beginning
= Fmarker_position (w
->start
);
2878 XSETINT (end
, (BUF_Z (b
) - XFASTINT (w
->window_end_pos
)));
2880 = Fprevious_single_property_change (make_number (pos
+ 1),
2882 w
->buffer
, beginning
);
2884 = Fnext_single_property_change (position
, Qmouse_face
,
2887 /* Record this as the current active region. */
2888 fast_find_position (w
, XFASTINT (before
),
2889 &mouse_face_beg_col
,
2890 &mouse_face_beg_row
);
2892 = !fast_find_position (w
, XFASTINT (after
),
2893 &mouse_face_end_col
,
2894 &mouse_face_end_row
);
2895 mouse_face_window
= window
;
2898 = face_at_buffer_position (w
, pos
, 0, 0,
2899 &ignore
, pos
+ 1, 1, -1);
2901 /* Display it as active. */
2902 term_show_mouse_face (DRAW_MOUSE_FACE
);
2906 /* Look for a `help-echo' property. */
2910 /* Check overlays first. */
2912 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
2914 overlay
= overlay_vec
[i
];
2915 help
= Foverlay_get (overlay
, Qhelp_echo
);
2920 help_echo_string
= help
;
2921 help_echo_window
= window
;
2922 help_echo_object
= overlay
;
2923 help_echo_pos
= pos
;
2925 /* Try text properties. */
2926 else if (NILP (help
)
2927 && ((STRINGP (glyph
->object
)
2928 && glyph
->charpos
>= 0
2929 && glyph
->charpos
< SCHARS (glyph
->object
))
2930 || (BUFFERP (glyph
->object
)
2931 && glyph
->charpos
>= BEGV
2932 && glyph
->charpos
< ZV
)))
2934 help
= Fget_text_property (make_number (glyph
->charpos
),
2935 Qhelp_echo
, glyph
->object
);
2938 help_echo_string
= help
;
2939 help_echo_window
= window
;
2940 help_echo_object
= glyph
->object
;
2941 help_echo_pos
= glyph
->charpos
;
2948 current_buffer
= obuf
;
2954 term_mouse_movement (FRAME_PTR frame
, Gpm_Event
*event
)
2956 /* Has the mouse moved off the glyph it was on at the last sighting? */
2957 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2959 frame
->mouse_moved
= 1;
2960 term_mouse_highlight (frame
, event
->x
, event
->y
);
2961 /* Remember which glyph we're now on. */
2962 last_mouse_x
= event
->x
;
2963 last_mouse_y
= event
->y
;
2969 /* Return the current position of the mouse.
2971 Set *f to the frame the mouse is in, or zero if the mouse is in no
2972 Emacs frame. If it is set to zero, all the other arguments are
2975 Set *bar_window to Qnil, and *x and *y to the column and
2976 row of the character cell the mouse is over.
2978 Set *time to the time the mouse was at the returned position.
2980 This clears mouse_moved until the next motion
2983 term_mouse_position (FRAME_PTR
*fp
, int insist
, Lisp_Object
*bar_window
,
2984 enum scroll_bar_part
*part
, Lisp_Object
*x
,
2985 Lisp_Object
*y
, unsigned long *time
)
2989 *fp
= SELECTED_FRAME ();
2990 (*fp
)->mouse_moved
= 0;
2995 XSETINT (*x
, last_mouse_x
);
2996 XSETINT (*y
, last_mouse_y
);
2997 gettimeofday(&now
, 0);
2998 *time
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
3001 /* Prepare a mouse-event in *RESULT for placement in the input queue.
3003 If the event is a button press, then note that we have grabbed
3007 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
3013 result
->kind
= GPM_CLICK_EVENT
;
3014 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
3016 if (event
->buttons
& j
) {
3017 result
->code
= i
; /* button number */
3021 gettimeofday(&now
, 0);
3022 result
->timestamp
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
3024 if (event
->type
& GPM_UP
)
3025 result
->modifiers
= up_modifier
;
3026 else if (event
->type
& GPM_DOWN
)
3027 result
->modifiers
= down_modifier
;
3029 result
->modifiers
= 0;
3031 if (event
->type
& GPM_SINGLE
)
3032 result
->modifiers
|= click_modifier
;
3034 if (event
->type
& GPM_DOUBLE
)
3035 result
->modifiers
|= double_modifier
;
3037 if (event
->type
& GPM_TRIPLE
)
3038 result
->modifiers
|= triple_modifier
;
3040 if (event
->type
& GPM_DRAG
)
3041 result
->modifiers
|= drag_modifier
;
3043 if (!(event
->type
& (GPM_MOVE
| GPM_DRAG
))) {
3046 if (event
->modifiers
& (1 << 0))
3047 result
->modifiers
|= shift_modifier
;
3050 if (event
->modifiers
& (1 << 2))
3051 result
->modifiers
|= ctrl_modifier
;
3053 /* 1 << KG_ALT || KG_ALTGR */
3054 if (event
->modifiers
& (1 << 3)
3055 || event
->modifiers
& (1 << 1))
3056 result
->modifiers
|= meta_modifier
;
3059 XSETINT (result
->x
, event
->x
);
3060 XSETINT (result
->y
, event
->y
);
3061 XSETFRAME (result
->frame_or_window
, f
);
3067 handle_one_term_event (struct tty_display_info
*tty
, Gpm_Event
*event
, struct input_event
* hold_quit
)
3069 struct frame
*f
= XFRAME (tty
->top_frame
);
3070 struct input_event ie
;
3078 if (event
->type
& (GPM_MOVE
| GPM_DRAG
)) {
3079 previous_help_echo_string
= help_echo_string
;
3080 help_echo_string
= Qnil
;
3082 Gpm_DrawPointer (event
->x
, event
->y
, fileno (tty
->output
));
3084 if (!term_mouse_movement (f
, event
))
3085 help_echo_string
= previous_help_echo_string
;
3087 /* If the contents of the global variable help_echo_string
3088 has changed, generate a HELP_EVENT. */
3089 if (!NILP (help_echo_string
)
3090 || !NILP (previous_help_echo_string
))
3097 term_mouse_click (&ie
, event
, f
);
3101 if (ie
.kind
!= NO_EVENT
)
3103 kbd_buffer_store_event_hold (&ie
, hold_quit
);
3108 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
3113 XSETFRAME (frame
, f
);
3117 gen_help_event (help_echo_string
, frame
, help_echo_window
,
3118 help_echo_object
, help_echo_pos
);
3125 DEFUN ("gpm-mouse-start", Fgpm_mouse_start
, Sgpm_mouse_start
,
3127 doc
: /* Open a connection to Gpm.
3128 Gpm-mouse can only be activated for one tty at a time. */)
3131 struct frame
*f
= SELECTED_FRAME ();
3132 struct tty_display_info
*tty
3133 = ((f
)->output_method
== output_termcap
3134 ? (f
)->terminal
->display_info
.tty
: NULL
);
3135 Gpm_Connect connection
;
3138 error ("Gpm-mouse only works in the GNU/Linux console");
3140 return Qnil
; /* Already activated, nothing to do. */
3142 error ("Gpm-mouse can only be activated for one tty at a time");
3144 connection
.eventMask
= ~0;
3145 connection
.defaultMask
= ~GPM_HARD
;
3146 connection
.maxMod
= ~0;
3147 connection
.minMod
= 0;
3150 if (Gpm_Open (&connection
, 0) < 0)
3151 error ("Gpm-mouse failed to connect to the gpm daemon");
3155 /* `init_sys_modes' arranges for mouse movements sent through gpm_fd
3156 to generate SIGIOs. Apparently we need to call reset_sys_modes
3157 before calling init_sys_modes. */
3158 reset_sys_modes (tty
);
3159 init_sys_modes (tty
);
3160 add_gpm_wait_descriptor (gpm_fd
);
3169 delete_gpm_wait_descriptor (fd
);
3170 while (Gpm_Close()); /* close all the stack */
3174 DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop
, Sgpm_mouse_stop
,
3176 doc
: /* Close a connection to Gpm. */)
3179 struct frame
*f
= SELECTED_FRAME ();
3180 struct tty_display_info
*tty
3181 = ((f
)->output_method
== output_termcap
3182 ? (f
)->terminal
->display_info
.tty
: NULL
);
3184 if (!tty
|| gpm_tty
!= tty
)
3185 return Qnil
; /* Not activated on this terminal, nothing to do. */
3190 #endif /* HAVE_GPM */
3194 /***********************************************************************
3196 ***********************************************************************/
3198 /* Initialize the tty-dependent part of frame F. The frame must
3199 already have its device initialized. */
3202 create_tty_output (struct frame
*f
)
3204 struct tty_output
*t
;
3206 if (! FRAME_TERMCAP_P (f
))
3209 t
= xmalloc (sizeof (struct tty_output
));
3210 memset (t
, 0, sizeof (struct tty_output
));
3212 t
->display_info
= FRAME_TERMINAL (f
)->display_info
.tty
;
3214 f
->output_data
.tty
= t
;
3217 /* Delete frame F's face cache, and its tty-dependent part. */
3220 tty_free_frame_resources (struct frame
*f
)
3222 if (! FRAME_TERMCAP_P (f
))
3225 if (FRAME_FACE_CACHE (f
))
3226 free_frame_faces (f
);
3228 xfree (f
->output_data
.tty
);
3233 /* Delete frame F's face cache. */
3236 tty_free_frame_resources (struct frame
*f
)
3238 if (! FRAME_TERMCAP_P (f
) && ! FRAME_MSDOS_P (f
))
3241 if (FRAME_FACE_CACHE (f
))
3242 free_frame_faces (f
);
3246 /* Reset the hooks in TERMINAL. */
3249 clear_tty_hooks (struct terminal
*terminal
)
3252 terminal
->cursor_to_hook
= 0;
3253 terminal
->raw_cursor_to_hook
= 0;
3254 terminal
->clear_to_end_hook
= 0;
3255 terminal
->clear_frame_hook
= 0;
3256 terminal
->clear_end_of_line_hook
= 0;
3257 terminal
->ins_del_lines_hook
= 0;
3258 terminal
->insert_glyphs_hook
= 0;
3259 terminal
->write_glyphs_hook
= 0;
3260 terminal
->delete_glyphs_hook
= 0;
3261 terminal
->ring_bell_hook
= 0;
3262 terminal
->reset_terminal_modes_hook
= 0;
3263 terminal
->set_terminal_modes_hook
= 0;
3264 terminal
->update_begin_hook
= 0;
3265 terminal
->update_end_hook
= 0;
3266 terminal
->set_terminal_window_hook
= 0;
3267 terminal
->mouse_position_hook
= 0;
3268 terminal
->frame_rehighlight_hook
= 0;
3269 terminal
->frame_raise_lower_hook
= 0;
3270 terminal
->fullscreen_hook
= 0;
3271 terminal
->set_vertical_scroll_bar_hook
= 0;
3272 terminal
->condemn_scroll_bars_hook
= 0;
3273 terminal
->redeem_scroll_bar_hook
= 0;
3274 terminal
->judge_scroll_bars_hook
= 0;
3275 terminal
->read_socket_hook
= 0;
3276 terminal
->frame_up_to_date_hook
= 0;
3278 /* Leave these two set, or suspended frames are not deleted
3280 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3281 terminal
->delete_terminal_hook
= &delete_tty
;
3284 /* Initialize hooks in TERMINAL with the values needed for a tty. */
3287 set_tty_hooks (struct terminal
*terminal
)
3289 terminal
->rif
= 0; /* ttys don't support window-based redisplay. */
3291 terminal
->cursor_to_hook
= &tty_cursor_to
;
3292 terminal
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
3294 terminal
->clear_to_end_hook
= &tty_clear_to_end
;
3295 terminal
->clear_frame_hook
= &tty_clear_frame
;
3296 terminal
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
3298 terminal
->ins_del_lines_hook
= &tty_ins_del_lines
;
3300 terminal
->insert_glyphs_hook
= &tty_insert_glyphs
;
3301 terminal
->write_glyphs_hook
= &tty_write_glyphs
;
3302 terminal
->delete_glyphs_hook
= &tty_delete_glyphs
;
3304 terminal
->ring_bell_hook
= &tty_ring_bell
;
3306 terminal
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
3307 terminal
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
3308 terminal
->update_begin_hook
= 0; /* Not needed. */
3309 terminal
->update_end_hook
= &tty_update_end
;
3310 terminal
->set_terminal_window_hook
= &tty_set_terminal_window
;
3312 terminal
->mouse_position_hook
= 0; /* Not needed. */
3313 terminal
->frame_rehighlight_hook
= 0; /* Not needed. */
3314 terminal
->frame_raise_lower_hook
= 0; /* Not needed. */
3316 terminal
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
3317 terminal
->condemn_scroll_bars_hook
= 0; /* Not needed. */
3318 terminal
->redeem_scroll_bar_hook
= 0; /* Not needed. */
3319 terminal
->judge_scroll_bars_hook
= 0; /* Not needed. */
3321 terminal
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
3322 terminal
->frame_up_to_date_hook
= 0; /* Not needed. */
3324 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3325 terminal
->delete_terminal_hook
= &delete_tty
;
3328 /* Drop the controlling terminal if fd is the same device. */
3330 dissociate_if_controlling_tty (int fd
)
3334 EMACS_GET_TTY_PGRP (fd
, &pgid
); /* If tcgetpgrp succeeds, fd is the ctty. */
3339 no_controlling_tty
= 1;
3340 #elif defined (CYGWIN)
3342 no_controlling_tty
= 1;
3344 #ifdef TIOCNOTTY /* Try BSD ioctls. */
3345 sigblock (sigmask (SIGTTOU
));
3346 fd
= emacs_open (DEV_TTY
, O_RDWR
, 0);
3347 if (fd
!= -1 && ioctl (fd
, TIOCNOTTY
, 0) != -1)
3349 no_controlling_tty
= 1;
3353 sigunblock (sigmask (SIGTTOU
));
3355 /* Unknown system. */
3357 #endif /* ! TIOCNOTTY */
3360 #endif /* !DOS_NT */
3363 /* Create a termcap display on the tty device with the given name and
3366 If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
3367 Otherwise NAME should be a path to the tty device file,
3370 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
3372 If MUST_SUCCEED is true, then all errors are fatal. */
3375 init_tty (const char *name
, const char *terminal_type
, int must_succeed
)
3378 char **address
= &area
;
3379 int buffer_size
= 4096;
3380 register char *p
= NULL
;
3382 struct tty_display_info
*tty
= NULL
;
3383 struct terminal
*terminal
= NULL
;
3384 int ctty
= 0; /* 1 if asked to open controlling tty. */
3387 maybe_fatal (must_succeed
, 0,
3388 "Unknown terminal type",
3389 "Unknown terminal type");
3393 if (!strcmp (name
, DEV_TTY
))
3396 /* If we already have a terminal on the given device, use that. If
3397 all such terminals are suspended, create a new one instead. */
3398 /* XXX Perhaps this should be made explicit by having init_tty
3399 always create a new terminal and separating terminal and frame
3400 creation on Lisp level. */
3401 terminal
= get_named_tty (name
);
3405 terminal
= create_terminal ();
3408 maybe_fatal (1, 0, "Attempt to create another terminal %s", "",
3411 tty
= &the_only_display_info
;
3413 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
3415 memset (tty
, 0, sizeof (struct tty_display_info
));
3416 tty
->next
= tty_list
;
3419 terminal
->type
= output_termcap
;
3420 terminal
->display_info
.tty
= tty
;
3421 tty
->terminal
= terminal
;
3423 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
3427 set_tty_hooks (terminal
);
3433 #ifdef O_IGNORE_CTTY
3435 /* Open the terminal device. Don't recognize it as our
3436 controlling terminal, and don't make it the controlling tty
3437 if we don't have one at the moment. */
3438 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
3441 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
3442 defined on Hurd. On other systems, we need to explicitly
3443 dissociate ourselves from the controlling tty when we want to
3444 open a frame on the same terminal. */
3445 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
3446 #endif /* O_IGNORE_CTTY */
3448 tty
->name
= xstrdup (name
);
3449 terminal
->name
= xstrdup (name
);
3452 maybe_fatal (must_succeed
, terminal
,
3453 "Could not open file: %s",
3454 "Could not open file: %s",
3459 maybe_fatal (must_succeed
, terminal
,
3460 "Not a tty device: %s",
3461 "Not a tty device: %s",
3465 #ifndef O_IGNORE_CTTY
3467 dissociate_if_controlling_tty (fd
);
3470 file
= fdopen (fd
, "w+");
3475 tty
->type
= xstrdup (terminal_type
);
3477 add_keyboard_wait_descriptor (fileno (tty
->input
));
3479 #endif /* !DOS_NT */
3481 encode_terminal_src_size
= 0;
3482 encode_terminal_dst_size
= 0;
3485 terminal
->mouse_position_hook
= term_mouse_position
;
3486 mouse_face_window
= Qnil
;
3491 initialize_w32_display (terminal
);
3493 if (strcmp (terminal_type
, "internal") == 0)
3494 terminal
->type
= output_msdos_raw
;
3495 initialize_msdos_display (terminal
);
3497 tty
->output
= stdout
;
3499 /* The following two are inaccessible from w32console.c. */
3500 terminal
->delete_frame_hook
= &tty_free_frame_resources
;
3501 terminal
->delete_terminal_hook
= &delete_tty
;
3503 tty
->name
= xstrdup (name
);
3504 terminal
->name
= xstrdup (name
);
3505 tty
->type
= xstrdup (terminal_type
);
3507 add_keyboard_wait_descriptor (0);
3513 struct frame
*f
= XFRAME (selected_frame
);
3515 FrameRows (tty
) = FRAME_LINES (f
);
3516 FrameCols (tty
) = FRAME_COLS (f
);
3517 tty
->specified_window
= FRAME_LINES (f
);
3519 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
3520 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
3525 get_tty_size (fileno (tty
->input
), &width
, &height
);
3526 FrameCols (tty
) = width
;
3527 FrameRows (tty
) = height
;
3530 tty
->delete_in_insert_mode
= 1;
3533 terminal
->scroll_region_ok
= 0;
3535 /* Seems to insert lines when it's not supposed to, messing up the
3536 display. In doing a trace, it didn't seem to be called much, so I
3537 don't think we're losing anything by turning it off. */
3538 terminal
->line_ins_del_ok
= 0;
3540 terminal
->char_ins_del_ok
= 1;
3543 terminal
->char_ins_del_ok
= 0;
3544 init_baud_rate (fileno (tty
->input
));
3547 tty
->TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
3549 #else /* not DOS_NT */
3553 tty
->termcap_term_buffer
= (char *) xmalloc (buffer_size
);
3555 /* On some systems, tgetent tries to access the controlling
3557 sigblock (sigmask (SIGTTOU
));
3558 status
= tgetent (tty
->termcap_term_buffer
, terminal_type
);
3559 sigunblock (sigmask (SIGTTOU
));
3564 maybe_fatal (must_succeed
, terminal
,
3565 "Cannot open terminfo database file",
3566 "Cannot open terminfo database file");
3568 maybe_fatal (must_succeed
, terminal
,
3569 "Cannot open termcap database file",
3570 "Cannot open termcap database file");
3575 maybe_fatal (must_succeed
, terminal
,
3576 "Terminal type %s is not defined",
3577 "Terminal type %s is not defined.\n\
3578 If that is not the actual type of terminal you have,\n\
3579 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3580 `setenv TERM ...') to specify the correct type. It may be necessary\n"
3582 "to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3584 "to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3590 if (strlen (tty
->termcap_term_buffer
) >= buffer_size
)
3592 buffer_size
= strlen (tty
->termcap_term_buffer
);
3594 tty
->termcap_strings_buffer
= area
= (char *) xmalloc (buffer_size
);
3595 tty
->TS_ins_line
= tgetstr ("al", address
);
3596 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
3597 tty
->TS_bell
= tgetstr ("bl", address
);
3598 BackTab (tty
) = tgetstr ("bt", address
);
3599 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
3600 tty
->TS_clr_line
= tgetstr ("ce", address
);
3601 tty
->TS_clr_frame
= tgetstr ("cl", address
);
3602 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
3603 AbsPosition (tty
) = tgetstr ("cm", address
);
3604 CR (tty
) = tgetstr ("cr", address
);
3605 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
3606 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
3607 RowPosition (tty
) = tgetstr ("cv", address
);
3608 tty
->TS_del_char
= tgetstr ("dc", address
);
3609 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
3610 tty
->TS_del_line
= tgetstr ("dl", address
);
3611 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
3612 tty
->TS_delete_mode
= tgetstr ("dm", address
);
3613 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
3614 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
3615 Home (tty
) = tgetstr ("ho", address
);
3616 tty
->TS_ins_char
= tgetstr ("ic", address
);
3617 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
3618 tty
->TS_insert_mode
= tgetstr ("im", address
);
3619 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
3620 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
3621 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
3622 LastLine (tty
) = tgetstr ("ll", address
);
3623 Right (tty
) = tgetstr ("nd", address
);
3624 Down (tty
) = tgetstr ("do", address
);
3626 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
3627 if (tgetflag ("bs"))
3628 Left (tty
) = "\b"; /* can't possibly be longer! */
3629 else /* (Actually, "bs" is obsolete...) */
3630 Left (tty
) = tgetstr ("le", address
);
3632 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
3633 tty
->TS_pad_char
= tgetstr ("pc", address
);
3634 tty
->TS_repeat
= tgetstr ("rp", address
);
3635 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
3636 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
3637 tty
->TS_standout_mode
= tgetstr ("so", address
);
3638 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
3639 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
3640 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
3641 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
3642 Up (tty
) = tgetstr ("up", address
);
3643 tty
->TS_visible_bell
= tgetstr ("vb", address
);
3644 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
3645 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
3646 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
3647 tty
->TS_set_window
= tgetstr ("wi", address
);
3649 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
3650 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
3651 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
3652 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
3653 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
3654 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
3655 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3656 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3657 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
3659 MultiUp (tty
) = tgetstr ("UP", address
);
3660 MultiDown (tty
) = tgetstr ("DO", address
);
3661 MultiLeft (tty
) = tgetstr ("LE", address
);
3662 MultiRight (tty
) = tgetstr ("RI", address
);
3664 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
3665 color because we can't switch back to the default foreground and
3667 tty
->TS_orig_pair
= tgetstr ("op", address
);
3668 if (tty
->TS_orig_pair
)
3670 tty
->TS_set_foreground
= tgetstr ("AF", address
);
3671 tty
->TS_set_background
= tgetstr ("AB", address
);
3672 if (!tty
->TS_set_foreground
)
3675 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
3676 tty
->TS_set_background
= tgetstr ("Sb", address
);
3679 tty
->TN_max_colors
= tgetnum ("Co");
3680 tty
->TN_max_pairs
= tgetnum ("pa");
3682 tty
->TN_no_color_video
= tgetnum ("NC");
3683 if (tty
->TN_no_color_video
== -1)
3684 tty
->TN_no_color_video
= 0;
3687 tty_default_color_capabilities (tty
, 1);
3689 MagicWrap (tty
) = tgetflag ("xn");
3690 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3691 the former flag imply the latter. */
3692 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
3693 terminal
->memory_below_frame
= tgetflag ("db");
3694 tty
->TF_hazeltine
= tgetflag ("hz");
3695 terminal
->must_write_spaces
= tgetflag ("in");
3696 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
3697 tty
->TF_insmode_motion
= tgetflag ("mi");
3698 tty
->TF_standout_motion
= tgetflag ("ms");
3699 tty
->TF_underscore
= tgetflag ("ul");
3700 tty
->TF_teleray
= tgetflag ("xt");
3702 #endif /* !DOS_NT */
3703 terminal
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
3704 init_kboard (terminal
->kboard
);
3705 terminal
->kboard
->Vwindow_system
= Qnil
;
3706 terminal
->kboard
->next_kboard
= all_kboards
;
3707 all_kboards
= terminal
->kboard
;
3708 terminal
->kboard
->reference_count
++;
3709 /* Don't let the initial kboard remain current longer than necessary.
3710 That would cause problems if a file loaded on startup tries to
3711 prompt in the mini-buffer. */
3712 if (current_kboard
== initial_kboard
)
3713 current_kboard
= terminal
->kboard
;
3715 term_get_fkeys (address
, terminal
->kboard
);
3717 /* Get frame size from system, or else from termcap. */
3720 get_tty_size (fileno (tty
->input
), &width
, &height
);
3721 FrameCols (tty
) = width
;
3722 FrameRows (tty
) = height
;
3725 if (FrameCols (tty
) <= 0)
3726 FrameCols (tty
) = tgetnum ("co");
3727 if (FrameRows (tty
) <= 0)
3728 FrameRows (tty
) = tgetnum ("li");
3730 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
3731 maybe_fatal (must_succeed
, terminal
,
3732 "Screen size %dx%d is too small",
3733 "Screen size %dx%d is too small",
3734 FrameCols (tty
), FrameRows (tty
));
3736 TabWidth (tty
) = tgetnum ("tw");
3739 tty
->TS_bell
= "\07";
3741 if (!tty
->TS_fwd_scroll
)
3742 tty
->TS_fwd_scroll
= Down (tty
);
3744 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
3746 if (TabWidth (tty
) < 0)
3749 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3750 and newer termcap doc does not seem to say there is a default.
3751 if (!tty->Wcm->cm_tab)
3752 tty->Wcm->cm_tab = "\t";
3755 /* We don't support standout modes that use `magic cookies', so
3756 turn off any that do. */
3757 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
3759 tty
->TS_standout_mode
= 0;
3760 tty
->TS_end_standout_mode
= 0;
3762 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3764 tty
->TS_enter_underline_mode
= 0;
3765 tty
->TS_exit_underline_mode
= 0;
3768 /* If there's no standout mode, try to use underlining instead. */
3769 if (tty
->TS_standout_mode
== 0)
3771 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
3772 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
3775 /* If no `se' string, try using a `me' string instead.
3776 If that fails, we can't use standout mode at all. */
3777 if (tty
->TS_end_standout_mode
== 0)
3779 char *s
= tgetstr ("me", address
);
3781 tty
->TS_end_standout_mode
= s
;
3783 tty
->TS_standout_mode
= 0;
3786 if (tty
->TF_teleray
)
3788 tty
->Wcm
->cm_tab
= 0;
3789 /* We can't support standout mode, because it uses magic cookies. */
3790 tty
->TS_standout_mode
= 0;
3791 /* But that means we cannot rely on ^M to go to column zero! */
3793 /* LF can't be trusted either -- can alter hpos */
3794 /* if move at column 0 thru a line with TS_standout_mode */
3798 /* Special handling for certain terminal types known to need it */
3800 if (!strcmp (terminal_type
, "supdup"))
3802 terminal
->memory_below_frame
= 1;
3803 tty
->Wcm
->cm_losewrap
= 1;
3805 if (!strncmp (terminal_type
, "c10", 3)
3806 || !strcmp (terminal_type
, "perq"))
3808 /* Supply a makeshift :wi string.
3809 This string is not valid in general since it works only
3810 for windows starting at the upper left corner;
3811 but that is all Emacs uses.
3813 This string works only if the frame is using
3814 the top of the video memory, because addressing is memory-relative.
3815 So first check the :ti string to see if that is true.
3817 It would be simpler if the :wi string could go in the termcap
3818 entry, but it can't because it is not fully valid.
3819 If it were in the termcap entry, it would confuse other programs. */
3820 if (!tty
->TS_set_window
)
3822 p
= tty
->TS_termcap_modes
;
3823 while (*p
&& strcmp (p
, "\033v "))
3826 tty
->TS_set_window
= "\033v%C %C %C %C ";
3828 /* Termcap entry often fails to have :in: flag */
3829 terminal
->must_write_spaces
= 1;
3830 /* :ti string typically fails to have \E^G! in it */
3831 /* This limits scope of insert-char to one line. */
3832 strcpy (area
, tty
->TS_termcap_modes
);
3833 strcat (area
, "\033\007!");
3834 tty
->TS_termcap_modes
= area
;
3835 area
+= strlen (area
) + 1;
3836 p
= AbsPosition (tty
);
3837 /* Change all %+ parameters to %C, to handle
3838 values above 96 correctly for the C100. */
3841 if (p
[0] == '%' && p
[1] == '+')
3847 tty
->specified_window
= FrameRows (tty
);
3849 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
3851 maybe_fatal (must_succeed
, terminal
,
3852 "Terminal type \"%s\" is not powerful enough to run Emacs",
3853 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3854 It lacks the ability to position the cursor.\n\
3855 If that is not the actual type of terminal you have,\n\
3856 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3857 `setenv TERM ...') to specify the correct type. It may be necessary\n"
3859 "to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3860 # else /* TERMCAP */
3861 "to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3862 # endif /* TERMINFO */
3866 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
3867 maybe_fatal (must_succeed
, terminal
,
3868 "Could not determine the frame size",
3869 "Could not determine the frame size");
3871 tty
->delete_in_insert_mode
3872 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
3873 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
3875 tty
->se_is_so
= (tty
->TS_standout_mode
3876 && tty
->TS_end_standout_mode
3877 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
3879 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
3881 terminal
->scroll_region_ok
3883 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
3885 terminal
->line_ins_del_ok
3886 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
3887 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
3888 || (terminal
->scroll_region_ok
3889 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
3891 terminal
->char_ins_del_ok
3892 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
3893 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
3894 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
3896 terminal
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
3898 init_baud_rate (fileno (tty
->input
));
3900 #endif /* not DOS_NT */
3902 /* Init system terminal modes (RAW or CBREAK, etc.). */
3903 init_sys_modes (tty
);
3910 vfatal (const char *str
, va_list ap
)
3912 fprintf (stderr
, "emacs: ");
3913 vfprintf (stderr
, str
, ap
);
3914 if (!(strlen (str
) > 0 && str
[strlen (str
) - 1] == '\n'))
3915 fprintf (stderr
, "\n");
3922 /* Auxiliary error-handling function for init_tty.
3923 Delete TERMINAL, then call error or fatal with str1 or str2,
3924 respectively, according to MUST_SUCCEED. */
3927 maybe_fatal (int must_succeed
, struct terminal
*terminal
,
3928 const char *str1
, const char *str2
, ...)
3931 va_start (ap
, str2
);
3933 delete_tty (terminal
);
3945 fatal (const char *str
, ...)
3955 /* Delete the given tty terminal, closing all frames on it. */
3958 delete_tty (struct terminal
*terminal
)
3960 struct tty_display_info
*tty
;
3962 /* Protect against recursive calls. delete_frame in
3963 delete_terminal calls us back when it deletes our last frame. */
3964 if (!terminal
->name
)
3967 if (terminal
->type
!= output_termcap
)
3970 tty
= terminal
->display_info
.tty
;
3972 if (tty
== tty_list
)
3973 tty_list
= tty
->next
;
3976 struct tty_display_info
*p
;
3977 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
3981 /* This should not happen. */
3984 p
->next
= tty
->next
;
3988 /* reset_sys_modes needs a valid device, so this call needs to be
3989 before delete_terminal. */
3990 reset_sys_modes (tty
);
3992 delete_terminal (terminal
);
3999 delete_keyboard_wait_descriptor (fileno (tty
->input
));
4000 if (tty
->input
!= stdin
)
4001 fclose (tty
->input
);
4003 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
4004 fclose (tty
->output
);
4005 if (tty
->termscript
)
4006 fclose (tty
->termscript
);
4008 xfree (tty
->old_tty
);
4010 xfree (tty
->termcap_strings_buffer
);
4011 xfree (tty
->termcap_term_buffer
);
4013 memset (tty
, 0, sizeof (struct tty_display_info
));
4019 /* Mark the pointers in the tty_display_info objects.
4020 Called by the Fgarbage_collector. */
4025 struct tty_display_info
*tty
;
4027 for (tty
= tty_list
; tty
; tty
= tty
->next
)
4028 mark_object (tty
->top_frame
);
4036 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
4037 doc
: /* Non-nil means the system uses terminfo rather than termcap.
4038 This variable can be used by terminal emulator packages. */);
4040 system_uses_terminfo
= 1;
4042 system_uses_terminfo
= 0;
4045 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions
,
4046 doc
: /* Functions to be run after suspending a tty.
4047 The functions are run with one argument, the terminal object to be suspended.
4048 See `suspend-tty'. */);
4049 Vsuspend_tty_functions
= Qnil
;
4052 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions
,
4053 doc
: /* Functions to be run after resuming a tty.
4054 The functions are run with one argument, the terminal object that was revived.
4055 See `resume-tty'. */);
4056 Vresume_tty_functions
= Qnil
;
4058 DEFVAR_BOOL ("visible-cursor", &visible_cursor
,
4059 doc
: /* Non-nil means to make the cursor very visible.
4060 This only has an effect when running in a text terminal.
4061 What means \"very visible\" is up to your terminal. It may make the cursor
4062 bigger, or it may make it blink, or it may do nothing at all. */);
4065 defsubr (&Stty_display_color_p
);
4066 defsubr (&Stty_display_color_cells
);
4067 defsubr (&Stty_no_underline
);
4068 defsubr (&Stty_type
);
4069 defsubr (&Scontrolling_tty_p
);
4070 defsubr (&Ssuspend_tty
);
4071 defsubr (&Sresume_tty
);
4073 defsubr (&Sgpm_mouse_start
);
4074 defsubr (&Sgpm_mouse_stop
);
4076 staticpro (&mouse_face_window
);
4077 #endif /* HAVE_GPM */
4080 default_orig_pair
= NULL
;
4081 default_set_foreground
= NULL
;
4082 default_set_background
= NULL
;
4083 #endif /* !DOS_NT */
4085 encode_terminal_src
= NULL
;
4086 encode_terminal_dst
= NULL
;
4091 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
4092 (do not change this comment) */