1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
36 #include <termios.h> /* For TIOCNOTTY. */
49 #include "termhooks.h"
50 #include "dispextern.h"
53 #include "blockinput.h"
54 #include "syssignal.h"
56 #include "intervals.h"
58 /* For now, don't try to include termcap.h. On some systems,
59 configure finds a non-standard termcap.h that the main build
62 #if defined HAVE_TERMCAP_H && 0
65 extern void tputs
P_ ((const char *, int, int (*)(int)));
66 extern int tgetent
P_ ((char *, const char *));
67 extern int tgetflag
P_ ((char *id
));
68 extern int tgetnum
P_ ((char *id
));
87 static void tty_set_scroll_region
P_ ((struct frame
*f
, int start
, int stop
));
88 static void turn_on_face
P_ ((struct frame
*, int face_id
));
89 static void turn_off_face
P_ ((struct frame
*, int face_id
));
90 static void tty_show_cursor
P_ ((struct tty_display_info
*));
91 static void tty_hide_cursor
P_ ((struct tty_display_info
*));
92 static void tty_background_highlight
P_ ((struct tty_display_info
*tty
));
93 static void clear_tty_hooks
P_ ((struct terminal
*terminal
));
94 static void set_tty_hooks
P_ ((struct terminal
*terminal
));
95 static void dissociate_if_controlling_tty
P_ ((int fd
));
96 static void delete_tty
P_ ((struct terminal
*));
98 #define OUTPUT(tty, a) \
99 emacs_tputs ((tty), a, \
100 (int) (FRAME_LINES (XFRAME (selected_frame)) \
104 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
105 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
107 #define OUTPUT_IF(tty, a) \
110 emacs_tputs ((tty), a, \
111 (int) (FRAME_LINES (XFRAME (selected_frame)) \
116 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
118 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */
120 static int visible_cursor
;
122 /* Display space properties */
124 extern Lisp_Object Qspace
, QCalign_to
, QCwidth
;
126 /* Functions to call after suspending a tty. */
127 Lisp_Object Vsuspend_tty_functions
;
129 /* Functions to call after resuming a tty. */
130 Lisp_Object Vresume_tty_functions
;
132 /* Chain of all tty device parameters. */
133 struct tty_display_info
*tty_list
;
135 /* Nonzero means no need to redraw the entire frame on resuming a
136 suspended Emacs. This is useful on terminals with multiple
137 pages, where one page is used for Emacs and another for all
139 int no_redraw_on_reenter
;
141 /* Meaning of bits in no_color_video. Each bit set means that the
142 corresponding attribute cannot be combined with colors. */
146 NC_STANDOUT
= 1 << 0,
147 NC_UNDERLINE
= 1 << 1,
154 NC_ALT_CHARSET
= 1 << 8
159 /* The largest frame width in any call to calculate_costs. */
163 /* The largest frame height in any call to calculate_costs. */
167 /* Non-zero if we have dropped our controlling tty and therefore
168 should not open a frame on stdout. */
169 static int no_controlling_tty
;
171 /* Provided for lisp packages. */
173 static int system_uses_terminfo
;
177 extern char *tgetstr ();
179 static void term_clear_mouse_face ();
180 static void term_mouse_highlight (struct frame
*f
, int x
, int y
);
184 /* We aren't X windows, but we aren't termcap either. This makes me
185 uncertain as to what value to use for frame.output_method. For
186 this file, we'll define FRAME_TERMCAP_P to be zero so that our
187 output hooks get called instead of the termcap functions. Probably
188 the best long-term solution is to define an output_windows_nt... */
190 #undef FRAME_TERMCAP_P
191 #define FRAME_TERMCAP_P(_f_) 0
192 #endif /* WINDOWSNT */
195 #include <sys/fcntl.h>
198 /* Nonzero means mouse is enabled on Linux console. */
201 /* The id of the terminal device for which we have gpm support. */
204 /* These variables describe the range of text currently shown in its
205 mouse-face, together with the window they apply to. As long as
206 the mouse stays within this range, we need not redraw anything on
207 its account. Rows and columns are glyph matrix positions in
208 MOUSE_FACE_WINDOW. */
209 static int mouse_face_beg_row
, mouse_face_beg_col
;
210 static int mouse_face_end_row
, mouse_face_end_col
;
211 static int mouse_face_past_end
;
212 static Lisp_Object Qmouse_face_window
;
213 static int mouse_face_face_id
;
215 static int pos_x
, pos_y
;
216 static int last_mouse_x
, last_mouse_y
;
217 #endif /* HAVE_GPM */
219 /* Ring the bell on a tty. */
222 tty_ring_bell (struct frame
*f
)
224 struct tty_display_info
*tty
= FRAME_TTY (f
);
228 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
229 ? tty
->TS_visible_bell
231 fflush (tty
->output
);
235 /* Set up termcap modes for Emacs. */
238 tty_set_terminal_modes (struct terminal
*terminal
)
240 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
244 if (tty
->TS_termcap_modes
)
245 OUTPUT (tty
, tty
->TS_termcap_modes
);
248 /* Output enough newlines to scroll all the old screen contents
249 off the screen, so it won't be overwritten and lost. */
252 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
256 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
257 OUTPUT_IF (tty
, visible_cursor
? tty
->TS_cursor_visible
: tty
->TS_cursor_normal
);
258 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
260 fflush (tty
->output
);
264 /* Reset termcap modes before exiting Emacs. */
267 tty_reset_terminal_modes (struct terminal
*terminal
)
269 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
273 tty_turn_off_highlight (tty
);
274 tty_turn_off_insert (tty
);
275 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
276 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
277 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
278 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
279 /* Output raw CR so kernel can track the cursor hpos. */
282 fflush (tty
->output
);
286 /* Flag the end of a display update on a termcap terminal. */
289 tty_update_end (struct frame
*f
)
291 struct tty_display_info
*tty
= FRAME_TTY (f
);
293 if (!XWINDOW (selected_window
)->cursor_off_p
)
294 tty_show_cursor (tty
);
295 tty_turn_off_insert (tty
);
296 tty_background_highlight (tty
);
299 /* The implementation of set_terminal_window for termcap frames. */
302 tty_set_terminal_window (struct frame
*f
, int size
)
304 struct tty_display_info
*tty
= FRAME_TTY (f
);
306 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
307 if (FRAME_SCROLL_REGION_OK (f
))
308 tty_set_scroll_region (f
, 0, tty
->specified_window
);
312 tty_set_scroll_region (struct frame
*f
, int start
, int stop
)
315 struct tty_display_info
*tty
= FRAME_TTY (f
);
317 if (tty
->TS_set_scroll_region
)
318 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
319 else if (tty
->TS_set_scroll_region_1
)
320 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
321 FRAME_LINES (f
), start
,
322 FRAME_LINES (f
) - stop
,
325 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
334 tty_turn_on_insert (struct tty_display_info
*tty
)
336 if (!tty
->insert_mode
)
337 OUTPUT (tty
, tty
->TS_insert_mode
);
338 tty
->insert_mode
= 1;
342 tty_turn_off_insert (struct tty_display_info
*tty
)
344 if (tty
->insert_mode
)
345 OUTPUT (tty
, tty
->TS_end_insert_mode
);
346 tty
->insert_mode
= 0;
349 /* Handle highlighting. */
352 tty_turn_off_highlight (struct tty_display_info
*tty
)
354 if (tty
->standout_mode
)
355 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
356 tty
->standout_mode
= 0;
360 tty_turn_on_highlight (struct tty_display_info
*tty
)
362 if (!tty
->standout_mode
)
363 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
364 tty
->standout_mode
= 1;
368 tty_toggle_highlight (struct tty_display_info
*tty
)
370 if (tty
->standout_mode
)
371 tty_turn_off_highlight (tty
);
373 tty_turn_on_highlight (tty
);
377 /* Make cursor invisible. */
380 tty_hide_cursor (struct tty_display_info
*tty
)
382 if (tty
->cursor_hidden
== 0)
384 tty
->cursor_hidden
= 1;
385 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
390 /* Ensure that cursor is visible. */
393 tty_show_cursor (struct tty_display_info
*tty
)
395 if (tty
->cursor_hidden
)
397 tty
->cursor_hidden
= 0;
398 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
400 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
405 /* Set standout mode to the state it should be in for
406 empty space inside windows. What this is,
407 depends on the user option inverse-video. */
410 tty_background_highlight (struct tty_display_info
*tty
)
413 tty_turn_on_highlight (tty
);
415 tty_turn_off_highlight (tty
);
418 /* Set standout mode to the mode specified for the text to be output. */
421 tty_highlight_if_desired (struct tty_display_info
*tty
)
424 tty_turn_on_highlight (tty
);
426 tty_turn_off_highlight (tty
);
430 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
431 frame-relative coordinates. */
434 tty_cursor_to (struct frame
*f
, int vpos
, int hpos
)
436 struct tty_display_info
*tty
= FRAME_TTY (f
);
438 /* Detect the case where we are called from reset_sys_modes
439 and the costs have never been calculated. Do nothing. */
440 if (! tty
->costs_set
)
443 if (curY (tty
) == vpos
444 && curX (tty
) == hpos
)
446 if (!tty
->TF_standout_motion
)
447 tty_background_highlight (tty
);
448 if (!tty
->TF_insmode_motion
)
449 tty_turn_off_insert (tty
);
450 cmgoto (tty
, vpos
, hpos
);
453 /* Similar but don't take any account of the wasted characters. */
456 tty_raw_cursor_to (struct frame
*f
, int row
, int col
)
458 struct tty_display_info
*tty
= FRAME_TTY (f
);
460 if (curY (tty
) == row
461 && curX (tty
) == col
)
463 if (!tty
->TF_standout_motion
)
464 tty_background_highlight (tty
);
465 if (!tty
->TF_insmode_motion
)
466 tty_turn_off_insert (tty
);
467 cmgoto (tty
, row
, col
);
470 /* Erase operations */
472 /* Clear from cursor to end of frame on a termcap device. */
475 tty_clear_to_end (struct frame
*f
)
478 struct tty_display_info
*tty
= FRAME_TTY (f
);
480 if (tty
->TS_clr_to_bottom
)
482 tty_background_highlight (tty
);
483 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
487 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
490 clear_end_of_line (f
, FRAME_COLS (f
));
495 /* Clear an entire termcap frame. */
498 tty_clear_frame (struct frame
*f
)
500 struct tty_display_info
*tty
= FRAME_TTY (f
);
502 if (tty
->TS_clr_frame
)
504 tty_background_highlight (tty
);
505 OUTPUT (tty
, tty
->TS_clr_frame
);
515 /* An implementation of clear_end_of_line for termcap frames.
517 Note that the cursor may be moved, on terminals lacking a `ce' string. */
520 tty_clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
523 struct tty_display_info
*tty
= FRAME_TTY (f
);
525 /* Detect the case where we are called from reset_sys_modes
526 and the costs have never been calculated. Do nothing. */
527 if (! tty
->costs_set
)
530 if (curX (tty
) >= first_unused_hpos
)
532 tty_background_highlight (tty
);
533 if (tty
->TS_clr_line
)
535 OUTPUT1 (tty
, tty
->TS_clr_line
);
538 { /* have to do it the hard way */
539 tty_turn_off_insert (tty
);
541 /* Do not write in last row last col with Auto-wrap on. */
543 && curY (tty
) == FrameRows (tty
) - 1
544 && first_unused_hpos
== FrameCols (tty
))
547 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
550 fputc (' ', tty
->termscript
);
551 fputc (' ', tty
->output
);
553 cmplus (tty
, first_unused_hpos
- curX (tty
));
557 /* Buffer to store the source and result of code conversion for terminal. */
558 static unsigned char *encode_terminal_buf
;
559 /* Allocated size of the above buffer. */
560 static int encode_terminal_bufsize
;
562 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
563 Set CODING->produced to the byte-length of the resulting byte
564 sequence, and return a pointer to that byte sequence. */
567 encode_terminal_code (src
, src_len
, coding
)
570 struct coding_system
*coding
;
572 struct glyph
*src_end
= src
+ src_len
;
575 int nchars
, nbytes
, required
;
576 register int tlen
= GLYPH_TABLE_LENGTH
;
577 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
579 /* Allocate sufficient size of buffer to store all characters in
580 multibyte-form. But, it may be enlarged on demand if
581 Vglyph_table contains a string. */
582 required
= MAX_MULTIBYTE_LENGTH
* src_len
;
583 if (encode_terminal_bufsize
< required
)
585 if (encode_terminal_bufsize
== 0)
586 encode_terminal_buf
= xmalloc (required
);
588 encode_terminal_buf
= xrealloc (encode_terminal_buf
, required
);
589 encode_terminal_bufsize
= required
;
592 buf
= encode_terminal_buf
;
594 while (src
< src_end
)
596 /* We must skip glyphs to be padded for a wide character. */
597 if (! CHAR_GLYPH_PADDING_P (*src
))
599 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
601 if (g
< 0 || g
>= tlen
)
603 /* This glyph doesn't has an entry in Vglyph_table. */
604 if (CHAR_VALID_P (src
->u
.ch
, 0))
605 buf
+= CHAR_STRING (src
->u
.ch
, buf
);
612 /* This glyph has an entry in Vglyph_table,
613 so process any alias before testing for simpleness. */
614 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
616 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
618 int c
= FAST_GLYPH_CHAR (g
);
620 if (CHAR_VALID_P (c
, 0))
621 buf
+= CHAR_STRING (c
, buf
);
628 /* We have a string in Vglyph_table. */
632 if (! STRING_MULTIBYTE (string
))
633 string
= string_to_multibyte (string
);
634 nbytes
= buf
- encode_terminal_buf
;
635 if (encode_terminal_bufsize
< nbytes
+ SBYTES (string
))
637 encode_terminal_bufsize
= nbytes
+ SBYTES (string
);
638 encode_terminal_buf
= xrealloc (encode_terminal_buf
,
639 encode_terminal_bufsize
);
640 buf
= encode_terminal_buf
+ nbytes
;
642 bcopy (SDATA (string
), buf
, SBYTES (string
));
643 buf
+= SBYTES (string
);
644 nchars
+= SCHARS (string
);
651 nbytes
= buf
- encode_terminal_buf
;
652 coding
->src_multibyte
= 1;
653 coding
->dst_multibyte
= 0;
654 if (SYMBOLP (coding
->pre_write_conversion
)
655 && ! NILP (Ffboundp (coding
->pre_write_conversion
)))
657 run_pre_write_conversin_on_c_str (&encode_terminal_buf
,
658 &encode_terminal_bufsize
,
659 nchars
, nbytes
, coding
);
660 nchars
= coding
->produced_char
;
661 nbytes
= coding
->produced
;
663 required
= nbytes
+ encoding_buffer_size (coding
, nbytes
);
664 if (encode_terminal_bufsize
< required
)
666 encode_terminal_bufsize
= required
;
667 encode_terminal_buf
= xrealloc (encode_terminal_buf
, required
);
670 encode_coding (coding
, encode_terminal_buf
, encode_terminal_buf
+ nbytes
,
671 nbytes
, encode_terminal_bufsize
- nbytes
);
672 return encode_terminal_buf
+ nbytes
;
676 /* An implementation of write_glyphs for termcap frames. */
679 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
681 unsigned char *conversion_buffer
;
682 struct coding_system
*coding
;
684 struct tty_display_info
*tty
= FRAME_TTY (f
);
686 tty_turn_off_insert (tty
);
687 tty_hide_cursor (tty
);
689 /* Don't dare write in last column of bottom line, if Auto-Wrap,
690 since that would scroll the whole frame on some terminals. */
693 && curY (tty
) + 1 == FRAME_LINES (f
)
694 && (curX (tty
) + len
) == FRAME_COLS (f
))
701 /* If terminal_coding does any conversion, use it, otherwise use
702 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
703 because it always return 1 if the member src_multibyte is 1. */
704 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
705 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
706 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
708 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
712 /* Identify a run of glyphs with the same face. */
713 int face_id
= string
->face_id
;
716 for (n
= 1; n
< len
; ++n
)
717 if (string
[n
].face_id
!= face_id
)
720 /* Turn appearance modes of the face of the run on. */
721 tty_highlight_if_desired (tty
);
722 turn_on_face (f
, face_id
);
725 /* This is the last run. */
726 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
727 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
728 if (coding
->produced
> 0)
731 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
732 if (ferror (tty
->output
))
733 clearerr (tty
->output
);
735 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
741 /* Turn appearance modes off. */
742 turn_off_face (f
, face_id
);
743 tty_turn_off_highlight (tty
);
750 tty_write_glyphs_with_face (f
, string
, len
, face_id
)
751 register struct frame
*f
;
752 register struct glyph
*string
;
753 register int len
, face_id
;
755 unsigned char *conversion_buffer
;
756 struct coding_system
*coding
;
758 struct tty_display_info
*tty
= FRAME_TTY (f
);
760 tty_turn_off_insert (tty
);
761 tty_hide_cursor (tty
);
763 /* Don't dare write in last column of bottom line, if Auto-Wrap,
764 since that would scroll the whole frame on some terminals. */
767 && curY (tty
) + 1 == FRAME_LINES (f
)
768 && (curX (tty
) + len
) == FRAME_COLS (f
))
775 /* If terminal_coding does any conversion, use it, otherwise use
776 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
777 because it always return 1 if the member src_multibyte is 1. */
778 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
779 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
780 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
782 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
784 /* Turn appearance modes of the face. */
785 tty_highlight_if_desired (tty
);
786 turn_on_face (f
, face_id
);
788 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
789 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
790 if (coding
->produced
> 0)
793 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
794 if (ferror (tty
->output
))
795 clearerr (tty
->output
);
797 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
801 /* Turn appearance modes off. */
802 turn_off_face (f
, face_id
);
803 tty_turn_off_highlight (tty
);
809 /* An implementation of insert_glyphs for termcap frames. */
812 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
815 struct glyph
*glyph
= NULL
;
816 unsigned char *conversion_buffer
;
817 unsigned char space
[1];
818 struct coding_system
*coding
;
820 struct tty_display_info
*tty
= FRAME_TTY (f
);
822 if (tty
->TS_ins_multi_chars
)
824 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
828 write_glyphs (f
, start
, len
);
832 tty_turn_on_insert (tty
);
836 space
[0] = SPACEGLYPH
;
838 /* If terminal_coding does any conversion, use it, otherwise use
839 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
840 because it always return 1 if the member src_multibyte is 1. */
841 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
842 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
843 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
845 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
849 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
852 conversion_buffer
= space
;
853 coding
->produced
= 1;
857 tty_highlight_if_desired (tty
);
858 turn_on_face (f
, start
->face_id
);
861 /* We must open sufficient space for a character which
862 occupies more than one column. */
863 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
865 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
870 /* This is the last glyph. */
871 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
873 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
876 if (coding
->produced
> 0)
879 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
880 if (ferror (tty
->output
))
881 clearerr (tty
->output
);
883 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
887 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
890 turn_off_face (f
, glyph
->face_id
);
891 tty_turn_off_highlight (tty
);
898 /* An implementation of delete_glyphs for termcap frames. */
901 tty_delete_glyphs (struct frame
*f
, int n
)
906 struct tty_display_info
*tty
= FRAME_TTY (f
);
908 if (tty
->delete_in_insert_mode
)
910 tty_turn_on_insert (tty
);
914 tty_turn_off_insert (tty
);
915 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
918 if (tty
->TS_del_multi_chars
)
920 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
925 for (i
= 0; i
< n
; i
++)
926 OUTPUT1 (tty
, tty
->TS_del_char
);
927 if (!tty
->delete_in_insert_mode
)
928 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
931 /* An implementation of ins_del_lines for termcap frames. */
934 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
936 struct tty_display_info
*tty
= FRAME_TTY (f
);
937 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
938 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
939 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
941 register int i
= n
> 0 ? n
: -n
;
944 /* If the lines below the insertion are being pushed
945 into the end of the window, this is the same as clearing;
946 and we know the lines are already clear, since the matching
947 deletion has already been done. So can ignore this. */
948 /* If the lines below the deletion are blank lines coming
949 out of the end of the window, don't bother,
950 as there will be a matching inslines later that will flush them. */
951 if (FRAME_SCROLL_REGION_OK (f
)
952 && vpos
+ i
>= tty
->specified_window
)
954 if (!FRAME_MEMORY_BELOW_FRAME (f
)
955 && vpos
+ i
>= FRAME_LINES (f
))
960 raw_cursor_to (f
, vpos
, 0);
961 tty_background_highlight (tty
);
962 buf
= tparam (multi
, 0, 0, i
);
968 raw_cursor_to (f
, vpos
, 0);
969 tty_background_highlight (tty
);
971 OUTPUT (tty
, single
);
977 tty_set_scroll_region (f
, vpos
, tty
->specified_window
);
979 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
981 raw_cursor_to (f
, vpos
, 0);
982 tty_background_highlight (tty
);
984 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
985 tty_set_scroll_region (f
, 0, tty
->specified_window
);
988 if (!FRAME_SCROLL_REGION_OK (f
)
989 && FRAME_MEMORY_BELOW_FRAME (f
)
992 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
997 /* Compute cost of sending "str", in characters,
998 not counting any line-dependent padding. */
1001 string_cost (char *str
)
1005 tputs (str
, 0, evalcost
);
1009 /* Compute cost of sending "str", in characters,
1010 counting any line-dependent padding at one line. */
1013 string_cost_one_line (char *str
)
1017 tputs (str
, 1, evalcost
);
1021 /* Compute per line amount of line-dependent padding,
1022 in tenths of characters. */
1025 per_line_cost (char *str
)
1029 tputs (str
, 0, evalcost
);
1032 tputs (str
, 10, evalcost
);
1037 /* char_ins_del_cost[n] is cost of inserting N characters.
1038 char_ins_del_cost[-n] is cost of deleting N characters.
1039 The length of this vector is based on max_frame_cols. */
1041 int *char_ins_del_vector
;
1043 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1048 calculate_ins_del_char_costs (struct frame
*f
)
1050 struct tty_display_info
*tty
= FRAME_TTY (f
);
1051 int ins_startup_cost
, del_startup_cost
;
1052 int ins_cost_per_char
, del_cost_per_char
;
1056 if (tty
->TS_ins_multi_chars
)
1058 ins_cost_per_char
= 0;
1059 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1061 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1062 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1064 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1065 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1066 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1067 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1071 ins_startup_cost
= 9999;
1072 ins_cost_per_char
= 0;
1075 if (tty
->TS_del_multi_chars
)
1077 del_cost_per_char
= 0;
1078 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1080 else if (tty
->TS_del_char
)
1082 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1083 + string_cost (tty
->TS_end_delete_mode
));
1084 if (tty
->delete_in_insert_mode
)
1085 del_startup_cost
/= 2;
1086 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1090 del_startup_cost
= 9999;
1091 del_cost_per_char
= 0;
1094 /* Delete costs are at negative offsets */
1095 p
= &char_ins_del_cost (f
)[0];
1096 for (i
= FRAME_COLS (f
); --i
>= 0;)
1097 *--p
= (del_startup_cost
+= del_cost_per_char
);
1099 /* Doing nothing is free */
1100 p
= &char_ins_del_cost (f
)[0];
1103 /* Insert costs are at positive offsets */
1104 for (i
= FRAME_COLS (f
); --i
>= 0;)
1105 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1109 calculate_costs (struct frame
*frame
)
1111 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1113 if (FRAME_TERMCAP_P (frame
))
1115 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1116 register char *f
= (tty
->TS_set_scroll_region
1117 ? tty
->TS_set_scroll_region
1118 : tty
->TS_set_scroll_region_1
);
1120 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1124 /* These variables are only used for terminal stuff. They are
1125 allocated once for the terminal frame of X-windows emacs, but not
1128 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1129 X turns off char_ins_del_ok. */
1131 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1132 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1134 if (char_ins_del_vector
!= 0)
1136 = (int *) xrealloc (char_ins_del_vector
,
1138 + 2 * max_frame_cols
* sizeof (int)));
1141 = (int *) xmalloc (sizeof (int)
1142 + 2 * max_frame_cols
* sizeof (int));
1144 bzero (char_ins_del_vector
, (sizeof (int)
1145 + 2 * max_frame_cols
* sizeof (int)));
1148 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1149 do_line_insertion_deletion_costs (frame
,
1150 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1151 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1154 do_line_insertion_deletion_costs (frame
,
1155 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1156 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1159 calculate_ins_del_char_costs (frame
);
1161 /* Don't use TS_repeat if its padding is worse than sending the chars */
1162 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1163 tty
->RPov
= string_cost (tty
->TS_repeat
);
1165 tty
->RPov
= FRAME_COLS (frame
) * 2;
1167 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1175 /* Termcap capability names that correspond directly to X keysyms.
1176 Some of these (marked "terminfo") aren't supplied by old-style
1177 (Berkeley) termcap entries. They're listed in X keysym order;
1178 except we put the keypad keys first, so that if they clash with
1179 other keys (as on the IBM PC keyboard) they get overridden.
1182 static struct fkey_table keys
[] =
1184 {"kh", "home"}, /* termcap */
1185 {"kl", "left"}, /* termcap */
1186 {"ku", "up"}, /* termcap */
1187 {"kr", "right"}, /* termcap */
1188 {"kd", "down"}, /* termcap */
1189 {"%8", "prior"}, /* terminfo */
1190 {"%5", "next"}, /* terminfo */
1191 {"@7", "end"}, /* terminfo */
1192 {"@1", "begin"}, /* terminfo */
1193 {"*6", "select"}, /* terminfo */
1194 {"%9", "print"}, /* terminfo */
1195 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1197 * "insert" --- see below
1199 {"&8", "undo"}, /* terminfo */
1200 {"%0", "redo"}, /* terminfo */
1201 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1202 {"@0", "find"}, /* terminfo */
1203 {"@2", "cancel"}, /* terminfo */
1204 {"%1", "help"}, /* terminfo */
1206 * "break" goes here, but can't be reliably intercepted with termcap
1208 {"&4", "reset"}, /* terminfo --- actually `restart' */
1210 * "system" and "user" --- no termcaps
1212 {"kE", "clearline"}, /* terminfo */
1213 {"kA", "insertline"}, /* terminfo */
1214 {"kL", "deleteline"}, /* terminfo */
1215 {"kI", "insertchar"}, /* terminfo */
1216 {"kD", "deletechar"}, /* terminfo */
1217 {"kB", "backtab"}, /* terminfo */
1219 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1221 {"@8", "kp-enter"}, /* terminfo */
1223 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1224 * "kp-multiply", "kp-add", "kp-separator",
1225 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1226 * --- no termcaps for any of these.
1228 {"K4", "kp-1"}, /* terminfo */
1230 * "kp-2" --- no termcap
1232 {"K5", "kp-3"}, /* terminfo */
1234 * "kp-4" --- no termcap
1236 {"K2", "kp-5"}, /* terminfo */
1238 * "kp-6" --- no termcap
1240 {"K1", "kp-7"}, /* terminfo */
1242 * "kp-8" --- no termcap
1244 {"K3", "kp-9"}, /* terminfo */
1246 * "kp-equal" --- no termcap
1258 {"&0", "S-cancel"}, /*shifted cancel key*/
1259 {"&9", "S-begin"}, /*shifted begin key*/
1260 {"*0", "S-find"}, /*shifted find key*/
1261 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1262 {"*4", "S-delete"}, /*shifted delete-character key*/
1263 {"*7", "S-end"}, /*shifted end key*/
1264 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1265 {"#1", "S-help"}, /*shifted help key*/
1266 {"#2", "S-home"}, /*shifted home key*/
1267 {"#3", "S-insert"}, /*shifted insert-character key*/
1268 {"#4", "S-left"}, /*shifted left-arrow key*/
1269 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1270 {"%c", "S-next"}, /*shifted next key*/
1271 {"%e", "S-prior"}, /*shifted previous key*/
1272 {"%f", "S-print"}, /*shifted print key*/
1273 {"%g", "S-redo"}, /*shifted redo key*/
1274 {"%i", "S-right"}, /*shifted right-arrow key*/
1275 {"!3", "S-undo"} /*shifted undo key*/
1278 static char **term_get_fkeys_address
;
1279 static KBOARD
*term_get_fkeys_kboard
;
1280 static Lisp_Object
term_get_fkeys_1 ();
1282 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1283 This function scans the termcap function key sequence entries, and
1284 adds entries to Vfunction_key_map for each function key it finds. */
1287 term_get_fkeys (address
, kboard
)
1291 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1292 errors during the call. The only errors should be from Fdefine_key
1293 when given a key sequence containing an invalid prefix key. If the
1294 termcap defines function keys which use a prefix that is already bound
1295 to a command by the default bindings, we should silently ignore that
1296 function key specification, rather than giving the user an error and
1297 refusing to run at all on such a terminal. */
1299 extern Lisp_Object
Fidentity ();
1300 term_get_fkeys_address
= address
;
1301 term_get_fkeys_kboard
= kboard
;
1302 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1310 char **address
= term_get_fkeys_address
;
1311 KBOARD
*kboard
= term_get_fkeys_kboard
;
1313 /* This can happen if CANNOT_DUMP or with strange options. */
1315 kboard
->Vlocal_function_key_map
= Fmake_sparse_keymap (Qnil
);
1317 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1319 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1321 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (sequence
),
1322 Fmake_vector (make_number (1),
1323 intern (keys
[i
].name
)));
1326 /* The uses of the "k0" capability are inconsistent; sometimes it
1327 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1328 We will attempt to politely accommodate both systems by testing for
1329 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1332 char *k_semi
= tgetstr ("k;", address
);
1333 char *k0
= tgetstr ("k0", address
);
1334 char *k0_name
= "f10";
1339 /* Define f0 first, so that f10 takes precedence in case the
1340 key sequences happens to be the same. */
1341 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (k0
),
1342 Fmake_vector (make_number (1), intern ("f0")));
1343 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (k_semi
),
1344 Fmake_vector (make_number (1), intern ("f10")));
1347 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (k0
),
1348 Fmake_vector (make_number (1), intern (k0_name
)));
1351 /* Set up cookies for numbered function keys above f10. */
1353 char fcap
[3], fkey
[4];
1355 fcap
[0] = 'F'; fcap
[2] = '\0';
1356 for (i
= 11; i
< 64; i
++)
1359 fcap
[1] = '1' + i
- 11;
1361 fcap
[1] = 'A' + i
- 20;
1363 fcap
[1] = 'a' + i
- 46;
1366 char *sequence
= tgetstr (fcap
, address
);
1369 sprintf (fkey
, "f%d", i
);
1370 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (sequence
),
1371 Fmake_vector (make_number (1),
1379 * Various mappings to try and get a better fit.
1382 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1383 if (!tgetstr (cap1, address)) \
1385 char *sequence = tgetstr (cap2, address); \
1387 Fdefine_key (kboard->Vlocal_function_key_map, build_string (sequence), \
1388 Fmake_vector (make_number (1), \
1392 /* if there's no key_next keycap, map key_npage to `next' keysym */
1393 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1394 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1395 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1396 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1397 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1398 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1399 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1401 /* IBM has their own non-standard dialect of terminfo.
1402 If the standard name isn't found, try the IBM name. */
1403 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1404 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1405 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1406 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1407 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1408 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1409 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1410 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1411 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1412 #undef CONDITIONAL_REASSIGN
1419 /***********************************************************************
1420 Character Display Information
1421 ***********************************************************************/
1423 /* Avoid name clash with functions defined in xterm.c */
1425 #define append_glyph append_glyph_term
1426 #define produce_stretch_glyph produce_stretch_glyph_term
1429 static void append_glyph
P_ ((struct it
*));
1430 static void produce_stretch_glyph
P_ ((struct it
*));
1433 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1434 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1435 the character for which to produce glyphs; IT->face_id contains the
1436 character's face. Padding glyphs are appended if IT->c has a
1437 IT->pixel_width > 1. */
1443 struct glyph
*glyph
, *end
;
1446 xassert (it
->glyph_row
);
1447 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1448 + it
->glyph_row
->used
[it
->area
]);
1449 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1452 i
< it
->pixel_width
&& glyph
< end
;
1455 glyph
->type
= CHAR_GLYPH
;
1456 glyph
->pixel_width
= 1;
1457 glyph
->u
.ch
= it
->char_to_display
;
1458 glyph
->face_id
= it
->face_id
;
1459 glyph
->padding_p
= i
> 0;
1460 glyph
->charpos
= CHARPOS (it
->position
);
1461 glyph
->object
= it
->object
;
1463 ++it
->glyph_row
->used
[it
->area
];
1469 /* Produce glyphs for the display element described by IT. *IT
1470 specifies what we want to produce a glyph for (character, image, ...),
1471 and where in the glyph matrix we currently are (glyph row and hpos).
1472 produce_glyphs fills in output fields of *IT with information such as the
1473 pixel width and height of a character, and maybe output actual glyphs at
1474 the same time if IT->glyph_row is non-null. See the explanation of
1475 struct display_iterator in dispextern.h for an overview.
1477 produce_glyphs also stores the result of glyph width, ascent
1478 etc. computations in *IT.
1480 IT->glyph_row may be null, in which case produce_glyphs does not
1481 actually fill in the glyphs. This is used in the move_* functions
1482 in xdisp.c for text width and height computations.
1484 Callers usually don't call produce_glyphs directly;
1485 instead they use the macro PRODUCE_GLYPHS. */
1491 /* If a hook is installed, let it do the work. */
1492 xassert (it
->what
== IT_CHARACTER
1493 || it
->what
== IT_COMPOSITION
1494 || it
->what
== IT_STRETCH
);
1496 if (it
->what
== IT_STRETCH
)
1498 produce_stretch_glyph (it
);
1502 /* Nothing but characters are supported on terminal frames. For a
1503 composition sequence, it->c is the first character of the
1505 xassert (it
->what
== IT_CHARACTER
1506 || it
->what
== IT_COMPOSITION
);
1508 /* Maybe translate single-byte characters to multibyte. */
1509 it
->char_to_display
= it
->c
;
1511 if (it
->c
>= 040 && it
->c
< 0177)
1513 it
->pixel_width
= it
->nglyphs
= 1;
1517 else if (it
->c
== '\n')
1518 it
->pixel_width
= it
->nglyphs
= 0;
1519 else if (it
->c
== '\t')
1521 int absolute_x
= (it
->current_x
1522 + it
->continuation_lines_width
);
1524 = (((1 + absolute_x
+ it
->tab_width
- 1)
1529 /* If part of the TAB has been displayed on the previous line
1530 which is continued now, continuation_lines_width will have
1531 been incremented already by the part that fitted on the
1532 continued line. So, we will get the right number of spaces
1534 nspaces
= next_tab_x
- absolute_x
;
1540 it
->char_to_display
= ' ';
1541 it
->pixel_width
= it
->len
= 1;
1547 it
->pixel_width
= nspaces
;
1548 it
->nglyphs
= nspaces
;
1550 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1552 if (unibyte_display_via_language_environment
1554 || !NILP (Vnonascii_translation_table
)))
1558 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1559 charset
= CHAR_CHARSET (it
->char_to_display
);
1560 it
->pixel_width
= CHARSET_WIDTH (charset
);
1561 it
->nglyphs
= it
->pixel_width
;
1567 /* Coming here means that it->c is from display table, thus we
1568 must send the code as is to the terminal. Although there's
1569 no way to know how many columns it occupies on a screen, it
1570 is a good assumption that a single byte code has 1-column
1572 it
->pixel_width
= it
->nglyphs
= 1;
1579 /* A multi-byte character. The display width is fixed for all
1580 characters of the set. Some of the glyphs may have to be
1581 ignored because they are already displayed in a continued
1583 int charset
= CHAR_CHARSET (it
->c
);
1585 it
->pixel_width
= CHARSET_WIDTH (charset
);
1586 it
->nglyphs
= it
->pixel_width
;
1593 /* Advance current_x by the pixel width as a convenience for
1595 if (it
->area
== TEXT_AREA
)
1596 it
->current_x
+= it
->pixel_width
;
1597 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1598 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1602 /* Produce a stretch glyph for iterator IT. IT->object is the value
1603 of the glyph property displayed. The value must be a list
1604 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1607 1. `:width WIDTH' specifies that the space should be WIDTH *
1608 canonical char width wide. WIDTH may be an integer or floating
1611 2. `:align-to HPOS' specifies that the space should be wide enough
1612 to reach HPOS, a value in canonical character units. */
1615 produce_stretch_glyph (it
)
1618 /* (space :width WIDTH ...) */
1619 Lisp_Object prop
, plist
;
1620 int width
= 0, align_to
= -1;
1621 int zero_width_ok_p
= 0;
1624 /* List should start with `space'. */
1625 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1626 plist
= XCDR (it
->object
);
1628 /* Compute the width of the stretch. */
1629 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1630 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1632 /* Absolute width `:width WIDTH' specified and valid. */
1633 zero_width_ok_p
= 1;
1634 width
= (int)(tem
+ 0.5);
1636 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1637 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1639 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1640 align_to
= (align_to
< 0
1642 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1643 else if (align_to
< 0)
1644 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1645 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1646 zero_width_ok_p
= 1;
1649 /* Nothing specified -> width defaults to canonical char width. */
1650 width
= FRAME_COLUMN_WIDTH (it
->f
);
1652 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1655 if (width
> 0 && it
->glyph_row
)
1657 Lisp_Object o_object
= it
->object
;
1658 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1661 if (!STRINGP (object
))
1662 object
= it
->w
->buffer
;
1663 it
->object
= object
;
1664 it
->char_to_display
= ' ';
1665 it
->pixel_width
= it
->len
= 1;
1668 it
->object
= o_object
;
1670 it
->pixel_width
= width
;
1671 it
->nglyphs
= width
;
1675 /* Get information about special display element WHAT in an
1676 environment described by IT. WHAT is one of IT_TRUNCATION or
1677 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1678 non-null glyph_row member. This function ensures that fields like
1679 face_id, c, len of IT are left untouched. */
1682 produce_special_glyphs (it
, what
)
1684 enum display_element_type what
;
1691 temp_it
.what
= IT_CHARACTER
;
1693 temp_it
.object
= make_number (0);
1694 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1696 if (what
== IT_CONTINUATION
)
1698 /* Continuation glyph. */
1700 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1701 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1703 glyph
= XINT (DISP_CONTINUE_GLYPH (it
->dp
));
1704 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
1709 else if (what
== IT_TRUNCATION
)
1711 /* Truncation glyph. */
1713 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1714 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1716 glyph
= XINT (DISP_TRUNC_GLYPH (it
->dp
));
1717 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
1725 temp_it
.c
= FAST_GLYPH_CHAR (glyph
);
1726 temp_it
.face_id
= FAST_GLYPH_FACE (glyph
);
1727 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1729 produce_glyphs (&temp_it
);
1730 it
->pixel_width
= temp_it
.pixel_width
;
1731 it
->nglyphs
= temp_it
.pixel_width
;
1736 /***********************************************************************
1738 ***********************************************************************/
1740 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1741 one of the enumerators from enum no_color_bit, or a bit set built
1742 from them. Some display attributes may not be used together with
1743 color; the termcap capability `NC' specifies which ones. */
1745 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1746 (tty->TN_max_colors > 0 \
1747 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1750 /* Turn appearances of face FACE_ID on tty frame F on.
1751 FACE_ID is a realized face ID number, in the face cache. */
1754 turn_on_face (f
, face_id
)
1758 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1759 long fg
= face
->foreground
;
1760 long bg
= face
->background
;
1761 struct tty_display_info
*tty
= FRAME_TTY (f
);
1763 /* Do this first because TS_end_standout_mode may be the same
1764 as TS_exit_attribute_mode, which turns all appearances off. */
1765 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1767 if (tty
->TN_max_colors
> 0)
1769 if (fg
>= 0 && bg
>= 0)
1771 /* If the terminal supports colors, we can set them
1772 below without using reverse video. The face's fg
1773 and bg colors are set as they should appear on
1774 the screen, i.e. they take the inverse-video'ness
1775 of the face already into account. */
1777 else if (inverse_video
)
1779 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1780 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1781 tty_toggle_highlight (tty
);
1785 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1786 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1787 tty_toggle_highlight (tty
);
1792 /* If we can't display colors, use reverse video
1793 if the face specifies that. */
1796 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1797 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1798 tty_toggle_highlight (tty
);
1802 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1803 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1804 tty_toggle_highlight (tty
);
1809 if (face
->tty_bold_p
)
1811 if (MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1812 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1814 else if (face
->tty_dim_p
)
1815 if (MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1816 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1818 /* Alternate charset and blinking not yet used. */
1819 if (face
->tty_alt_charset_p
1820 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1821 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1823 if (face
->tty_blinking_p
1824 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1825 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1827 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1828 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1830 if (tty
->TN_max_colors
> 0)
1834 ts
= tty
->standout_mode
? tty
->TS_set_background
: tty
->TS_set_foreground
;
1837 p
= tparam (ts
, NULL
, 0, (int) fg
);
1842 ts
= tty
->standout_mode
? tty
->TS_set_foreground
: tty
->TS_set_background
;
1845 p
= tparam (ts
, NULL
, 0, (int) bg
);
1853 /* Turn off appearances of face FACE_ID on tty frame F. */
1856 turn_off_face (f
, face_id
)
1860 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1861 struct tty_display_info
*tty
= FRAME_TTY (f
);
1863 xassert (face
!= NULL
);
1865 if (tty
->TS_exit_attribute_mode
)
1867 /* Capability "me" will turn off appearance modes double-bright,
1868 half-bright, reverse-video, standout, underline. It may or
1869 may not turn off alt-char-mode. */
1870 if (face
->tty_bold_p
1872 || face
->tty_reverse_p
1873 || face
->tty_alt_charset_p
1874 || face
->tty_blinking_p
1875 || face
->tty_underline_p
)
1877 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
1878 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
1879 tty
->standout_mode
= 0;
1882 if (face
->tty_alt_charset_p
)
1883 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1887 /* If we don't have "me" we can only have those appearances
1888 that have exit sequences defined. */
1889 if (face
->tty_alt_charset_p
)
1890 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1892 if (face
->tty_underline_p
)
1893 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
1896 /* Switch back to default colors. */
1897 if (tty
->TN_max_colors
> 0
1898 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
1899 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
1900 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
1901 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
1902 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
1906 /* Return non-zero if the terminal on frame F supports all of the
1907 capabilities in CAPS simultaneously, with foreground and background
1908 colors FG and BG. */
1911 tty_capable_p (tty
, caps
, fg
, bg
)
1912 struct tty_display_info
*tty
;
1914 unsigned long fg
, bg
;
1916 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
1917 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
1920 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
1921 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
1922 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
1923 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
1924 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
1925 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
1931 /* Return non-zero if the terminal is capable to display colors. */
1933 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
1935 doc
: /* Return non-nil if the tty device TERMINAL can display colors.
1937 TERMINAL can be a terminal id, a frame or nil (meaning the selected
1938 frame's terminal). This function always returns nil if TERMINAL
1939 is not on a tty device. */)
1941 Lisp_Object terminal
;
1943 struct terminal
*t
= get_tty_terminal (terminal
, 0);
1947 return t
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
1950 /* Return the number of supported colors. */
1951 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
1952 Stty_display_color_cells
, 0, 1, 0,
1953 doc
: /* Return the number of colors supported by the tty device TERMINAL.
1955 TERMINAL can be a terminal id, a frame or nil (meaning the selected
1956 frame's terminal). This function always returns 0 if TERMINAL
1957 is not on a tty device. */)
1959 Lisp_Object terminal
;
1961 struct terminal
*t
= get_tty_terminal (terminal
, 0);
1963 return make_number (0);
1965 return make_number (t
->display_info
.tty
->TN_max_colors
);
1970 /* Declare here rather than in the function, as in the rest of Emacs,
1971 to work around an HPUX compiler bug (?). See
1972 http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00410.html */
1973 static int default_max_colors
;
1974 static int default_max_pairs
;
1975 static int default_no_color_video
;
1976 static char *default_orig_pair
;
1977 static char *default_set_foreground
;
1978 static char *default_set_background
;
1980 /* Save or restore the default color-related capabilities of this
1983 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
1988 if (default_orig_pair
)
1989 xfree (default_orig_pair
);
1990 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
1992 if (default_set_foreground
)
1993 xfree (default_set_foreground
);
1994 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
1997 if (default_set_background
)
1998 xfree (default_set_background
);
1999 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
2002 default_max_colors
= tty
->TN_max_colors
;
2003 default_max_pairs
= tty
->TN_max_pairs
;
2004 default_no_color_video
= tty
->TN_no_color_video
;
2008 tty
->TS_orig_pair
= default_orig_pair
;
2009 tty
->TS_set_foreground
= default_set_foreground
;
2010 tty
->TS_set_background
= default_set_background
;
2011 tty
->TN_max_colors
= default_max_colors
;
2012 tty
->TN_max_pairs
= default_max_pairs
;
2013 tty
->TN_no_color_video
= default_no_color_video
;
2017 /* Setup one of the standard tty color schemes according to MODE.
2018 MODE's value is generally the number of colors which we want to
2019 support; zero means set up for the default capabilities, the ones
2020 we saw at init_tty time; -1 means turn off color support. */
2022 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2024 /* Canonicalize all negative values of MODE. */
2030 case -1: /* no colors at all */
2031 tty
->TN_max_colors
= 0;
2032 tty
->TN_max_pairs
= 0;
2033 tty
->TN_no_color_video
= 0;
2034 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2036 case 0: /* default colors, if any */
2038 tty_default_color_capabilities (tty
, 0);
2040 case 8: /* 8 standard ANSI colors */
2041 tty
->TS_orig_pair
= "\033[0m";
2043 tty
->TS_set_foreground
= "\033[3%p1%dm";
2044 tty
->TS_set_background
= "\033[4%p1%dm";
2046 tty
->TS_set_foreground
= "\033[3%dm";
2047 tty
->TS_set_background
= "\033[4%dm";
2049 tty
->TN_max_colors
= 8;
2050 tty
->TN_max_pairs
= 64;
2051 tty
->TN_no_color_video
= 0;
2057 set_tty_color_mode (f
, val
)
2061 Lisp_Object color_mode_spec
, current_mode_spec
;
2062 Lisp_Object color_mode
, current_mode
;
2064 extern Lisp_Object Qtty_color_mode
;
2065 Lisp_Object tty_color_mode_alist
;
2067 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2074 if (NILP (tty_color_mode_alist
))
2075 color_mode_spec
= Qnil
;
2077 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2079 if (CONSP (color_mode_spec
))
2080 color_mode
= XCDR (color_mode_spec
);
2085 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2087 if (CONSP (current_mode_spec
))
2088 current_mode
= XCDR (current_mode_spec
);
2090 current_mode
= Qnil
;
2091 if (INTEGERP (color_mode
))
2092 mode
= XINT (color_mode
);
2094 mode
= 0; /* meaning default */
2095 if (INTEGERP (current_mode
))
2096 old_mode
= XINT (current_mode
);
2100 if (mode
!= old_mode
)
2102 tty_setup_colors (FRAME_TTY (f
), mode
);
2103 /* This recomputes all the faces given the new color
2105 call0 (intern ("tty-set-up-initial-frame-faces"));
2110 #endif /* !WINDOWSNT */
2114 /* Return the tty display object specified by TERMINAL. */
2117 get_tty_terminal (Lisp_Object terminal
, int throw)
2119 struct terminal
*t
= get_terminal (terminal
, throw);
2121 if (t
&& t
->type
== output_initial
)
2124 if (t
&& t
->type
!= output_termcap
)
2127 error ("Device %d is not a termcap terminal device", t
->id
);
2135 /* Return an active termcap device that uses the tty device with the
2138 This function ignores suspended devices.
2140 Returns NULL if the named terminal device is not opened. */
2143 get_named_tty (name
)
2151 for (t
= terminal_list
; t
; t
= t
->next_terminal
)
2153 if (t
->type
== output_termcap
2154 && !strcmp (t
->display_info
.tty
->name
, name
)
2155 && TERMINAL_ACTIVE_P (t
))
2163 DEFUN ("tty-type", Ftty_type
, Stty_type
, 0, 1, 0,
2164 doc
: /* Return the type of the tty device that TERMINAL uses.
2165 Returns nil if TERMINAL is not on a tty device.
2167 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2168 frame's terminal). */)
2170 Lisp_Object terminal
;
2172 struct terminal
*t
= get_terminal (terminal
, 1);
2174 if (t
->type
!= output_termcap
)
2177 if (t
->display_info
.tty
->type
)
2178 return build_string (t
->display_info
.tty
->type
);
2183 DEFUN ("controlling-tty-p", Fcontrolling_tty_p
, Scontrolling_tty_p
, 0, 1, 0,
2184 doc
: /* Return non-nil if TERMINAL is on the controlling tty of the Emacs process.
2186 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2187 frame's terminal). This function always returns nil if TERMINAL
2188 is not on a tty device. */)
2190 Lisp_Object terminal
;
2192 struct terminal
*t
= get_terminal (terminal
, 1);
2194 if (t
->type
!= output_termcap
|| strcmp (t
->display_info
.tty
->name
, "/dev/tty"))
2200 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 1, 0,
2201 doc
: /* Declare that the tty used by TERMINAL does not handle underlining.
2202 This is used to override the terminfo data, for certain terminals that
2203 do not really do underlining, but say that they do. This function has
2204 no effect if used on a non-tty terminal.
2206 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2207 frame's terminal). This function always returns nil if TERMINAL
2208 is not on a tty device. */)
2210 Lisp_Object terminal
;
2212 struct terminal
*t
= get_terminal (terminal
, 1);
2214 if (t
->type
== output_termcap
)
2215 t
->display_info
.tty
->TS_enter_underline_mode
= 0;
2221 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
2222 doc
: /* Suspend the terminal device TTY.
2224 The device is restored to its default state, and Emacs ceases all
2225 access to the tty device. Frames that use the device are not deleted,
2226 but input is not read from them and if they change, their display is
2229 TTY may be a terminal id, a frame, or nil for the terminal device of
2230 the currently selected frame.
2232 This function runs `suspend-tty-functions' after suspending the
2233 device. The functions are run with one arg, the id of the suspended
2236 `suspend-tty' does nothing if it is called on a device that is already
2239 A suspended tty may be resumed by calling `resume-tty' on it. */)
2243 struct terminal
*t
= get_tty_terminal (tty
, 1);
2247 error ("Unknown tty device");
2249 f
= t
->display_info
.tty
->input
;
2253 reset_sys_modes (t
->display_info
.tty
);
2255 delete_keyboard_wait_descriptor (fileno (f
));
2258 if (f
!= t
->display_info
.tty
->output
)
2259 fclose (t
->display_info
.tty
->output
);
2261 t
->display_info
.tty
->input
= 0;
2262 t
->display_info
.tty
->output
= 0;
2264 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2265 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 0);
2267 /* Run `suspend-tty-functions'. */
2268 if (!NILP (Vrun_hooks
))
2270 Lisp_Object args
[2];
2271 args
[0] = intern ("suspend-tty-functions");
2272 args
[1] = make_number (t
->id
);
2273 Frun_hook_with_args (2, args
);
2277 /* Clear display hooks to prevent further output. */
2278 clear_tty_hooks (t
);
2283 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
2284 doc
: /* Resume the previously suspended terminal device TTY.
2285 The terminal is opened and reinitialized. Frames that are on the
2286 suspended terminal are revived.
2288 It is an error to resume a terminal while another terminal is active
2291 This function runs `resume-tty-functions' after resuming the terminal.
2292 The functions are run with one arg, the id of the resumed terminal
2295 `resume-tty' does nothing if it is called on a device that is not
2298 TTY may be a terminal id, a frame, or nil for the terminal device of
2299 the currently selected frame. */)
2303 struct terminal
*t
= get_tty_terminal (tty
, 1);
2307 error ("Unknown tty device");
2309 if (!t
->display_info
.tty
->input
)
2311 if (get_named_tty (t
->display_info
.tty
->name
))
2312 error ("Cannot resume display while another display is active on the same device");
2314 fd
= emacs_open (t
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
2317 error ("Can not reopen tty device %s: %s", t
->display_info
.tty
->name
, strerror (errno
));
2319 if (strcmp (t
->display_info
.tty
->name
, "/dev/tty"))
2320 dissociate_if_controlling_tty (fd
);
2322 t
->display_info
.tty
->output
= fdopen (fd
, "w+");
2323 t
->display_info
.tty
->input
= t
->display_info
.tty
->output
;
2325 add_keyboard_wait_descriptor (fd
);
2327 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2328 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 1);
2330 init_sys_modes (t
->display_info
.tty
);
2332 /* Run `suspend-tty-functions'. */
2333 if (!NILP (Vrun_hooks
))
2335 Lisp_Object args
[2];
2336 args
[0] = intern ("resume-tty-functions");
2337 args
[1] = make_number (t
->id
);
2338 Frun_hook_with_args (2, args
);
2348 /***********************************************************************
2350 ***********************************************************************/
2354 term_mouse_moveto (int x
, int y
)
2356 /* TODO: how to set mouse position?
2359 name = (const char *) ttyname (0);
2360 fd = open (name, O_WRONLY);
2361 SOME_FUNCTION (x, y, fd);
2364 last_mouse_y = y; */
2368 term_show_mouse_face (enum draw_glyphs_face draw
)
2370 struct window
*w
= XWINDOW (Qmouse_face_window
);
2374 struct frame
*f
= XFRAME (w
->frame
);
2375 struct tty_display_info
*tty
= FRAME_TTY (f
);
2377 if (/* If window is in the process of being destroyed, don't bother
2379 w
->current_matrix
!= NULL
2380 /* Recognize when we are called to operate on rows that don't exist
2381 anymore. This can happen when a window is split. */
2382 && mouse_face_end_row
< w
->current_matrix
->nrows
)
2384 /* write_glyphs writes at cursor position, so we need to
2385 temporarily move cursor coordinates to the beginning of
2386 the highlight region. */
2388 /* Save current cursor co-ordinates */
2389 save_y
= curY (tty
);
2390 save_x
= curX (tty
);
2392 /* Note that mouse_face_beg_row etc. are window relative. */
2393 for (i
= mouse_face_beg_row
; i
<= mouse_face_end_row
; i
++)
2395 int start_hpos
, end_hpos
, nglyphs
;
2396 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
2398 /* Don't do anything if row doesn't have valid contents. */
2399 if (!row
->enabled_p
)
2402 /* For all but the first row, the highlight starts at column 0. */
2403 if (i
== mouse_face_beg_row
)
2404 start_hpos
= mouse_face_beg_col
;
2408 if (i
== mouse_face_end_row
)
2409 end_hpos
= mouse_face_end_col
;
2412 end_hpos
= row
->used
[TEXT_AREA
];
2413 if (draw
== DRAW_NORMAL_TEXT
)
2414 row
->fill_line_p
= 1; /* Clear to end of line */
2417 if (end_hpos
<= start_hpos
)
2419 /* Record that some glyphs of this row are displayed in
2421 row
->mouse_face_p
= draw
> 0;
2423 nglyphs
= end_hpos
- start_hpos
;
2425 if (end_hpos
>= row
->used
[TEXT_AREA
])
2426 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2428 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2429 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
2430 + WINDOW_LEFT_EDGE_X (w
);
2432 cursor_to (f
, pos_y
, pos_x
);
2434 if (draw
== DRAW_MOUSE_FACE
)
2436 tty_write_glyphs_with_face (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
,
2437 nglyphs
, mouse_face_face_id
);
2439 else /* draw == DRAW_NORMAL_TEXT */
2440 write_glyphs (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2442 cursor_to (f
, save_y
, save_x
);
2447 term_clear_mouse_face ()
2449 if (!NILP (Qmouse_face_window
))
2450 term_show_mouse_face (DRAW_NORMAL_TEXT
);
2452 mouse_face_beg_row
= mouse_face_beg_col
= -1;
2453 mouse_face_end_row
= mouse_face_end_col
= -1;
2454 Qmouse_face_window
= Qnil
;
2457 /* Find the glyph matrix position of buffer position POS in window W.
2458 *HPOS and *VPOS are set to the positions found. W's current glyphs
2459 must be up to date. If POS is above window start return (0, 0).
2460 If POS is after end of W, return end of last line in W.
2461 - taken from msdos.c */
2463 fast_find_position (struct window
*w
, int pos
, int *hpos
, int *vpos
)
2465 int i
, lastcol
, line_start_position
, maybe_next_line_p
= 0;
2466 int yb
= window_text_bottom_y (w
);
2467 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0), *best_row
= row
;
2471 if (row
->used
[TEXT_AREA
])
2472 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
2474 line_start_position
= 0;
2476 if (line_start_position
> pos
)
2478 /* If the position sought is the end of the buffer,
2479 don't include the blank lines at the bottom of the window. */
2480 else if (line_start_position
== pos
2481 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
2483 maybe_next_line_p
= 1;
2486 else if (line_start_position
> 0)
2489 /* Don't overstep the last matrix row, lest we get into the
2490 never-never land... */
2491 if (row
->y
+ 1 >= yb
)
2497 /* Find the right column within BEST_ROW. */
2500 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
2502 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + i
;
2505 charpos
= glyph
->charpos
;
2512 else if (charpos
> pos
)
2514 else if (charpos
> 0)
2518 /* If we're looking for the end of the buffer,
2519 and we didn't find it in the line we scanned,
2520 use the start of the following line. */
2521 if (maybe_next_line_p
)
2528 *hpos
= lastcol
+ 1;
2533 term_mouse_highlight (struct frame
*f
, int x
, int y
)
2535 enum window_part part
;
2540 if (NILP (Vmouse_highlight
)
2541 || !f
->glyphs_initialized_p
)
2544 /* Which window is that in? */
2545 window
= window_from_coordinates (f
, x
, y
, &part
, &x
, &y
, 0);
2547 /* Not on a window -> return. */
2548 if (!WINDOWP (window
))
2551 if (!EQ (window
, Qmouse_face_window
))
2552 term_clear_mouse_face ();
2554 w
= XWINDOW (window
);
2556 /* Are we in a window whose display is up to date?
2557 And verify the buffer's text has not changed. */
2558 b
= XBUFFER (w
->buffer
);
2560 && EQ (w
->window_end_valid
, w
->buffer
)
2561 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
2562 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
2564 int pos
, i
, nrows
= w
->current_matrix
->nrows
;
2565 struct glyph_row
*row
;
2566 struct glyph
*glyph
;
2568 /* Find the glyph under X/Y. */
2570 if (y
>= 0 && y
< nrows
)
2572 row
= MATRIX_ROW (w
->current_matrix
, y
);
2573 /* Give up if some row before the one we are looking for is
2575 for (i
= 0; i
<= y
; i
++)
2576 if (!MATRIX_ROW (w
->current_matrix
, i
)->enabled_p
)
2578 if (i
> y
/* all rows upto and including the one at Y are enabled */
2579 && row
->displays_text_p
2580 && x
< window_box_width (w
, TEXT_AREA
))
2582 glyph
= row
->glyphs
[TEXT_AREA
];
2583 if (x
>= row
->used
[TEXT_AREA
])
2588 if (!BUFFERP (glyph
->object
))
2594 /* Clear mouse face if X/Y not over text. */
2597 term_clear_mouse_face ();
2601 if (!BUFFERP (glyph
->object
))
2603 pos
= glyph
->charpos
;
2605 /* Check for mouse-face. */
2607 extern Lisp_Object Qmouse_face
;
2608 Lisp_Object mouse_face
, overlay
, position
, *overlay_vec
;
2609 int noverlays
, obegv
, ozv
;
2610 struct buffer
*obuf
;
2612 /* If we get an out-of-range value, return now; avoid an error. */
2613 if (pos
> BUF_Z (b
))
2616 /* Make the window's buffer temporarily current for
2617 overlays_at and compute_char_face. */
2618 obuf
= current_buffer
;
2625 /* Is this char mouse-active? */
2626 XSETINT (position
, pos
);
2628 /* Put all the overlays we want in a vector in overlay_vec. */
2629 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
2630 /* Sort overlays into increasing priority order. */
2631 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
2633 /* Check mouse-face highlighting. */
2634 if (!(EQ (window
, Qmouse_face_window
)
2635 && y
>= mouse_face_beg_row
2636 && y
<= mouse_face_end_row
2637 && (y
> mouse_face_beg_row
2638 || x
>= mouse_face_beg_col
)
2639 && (y
< mouse_face_end_row
2640 || x
< mouse_face_end_col
2641 || mouse_face_past_end
)))
2643 /* Clear the display of the old active region, if any. */
2644 term_clear_mouse_face ();
2646 /* Find the highest priority overlay that has a mouse-face
2649 for (i
= noverlays
- 1; i
>= 0; --i
)
2651 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
2652 if (!NILP (mouse_face
))
2654 overlay
= overlay_vec
[i
];
2659 /* If no overlay applies, get a text property. */
2661 mouse_face
= Fget_text_property (position
, Qmouse_face
,
2664 /* Handle the overlay case. */
2665 if (!NILP (overlay
))
2667 /* Find the range of text around this char that
2668 should be active. */
2669 Lisp_Object before
, after
;
2673 before
= Foverlay_start (overlay
);
2674 after
= Foverlay_end (overlay
);
2675 /* Record this as the current active region. */
2676 fast_find_position (w
, XFASTINT (before
),
2677 &mouse_face_beg_col
,
2678 &mouse_face_beg_row
);
2681 = !fast_find_position (w
, XFASTINT (after
),
2682 &mouse_face_end_col
,
2683 &mouse_face_end_row
);
2684 Qmouse_face_window
= window
;
2687 = face_at_buffer_position (w
, pos
, 0, 0,
2688 &ignore
, pos
+ 1, 1);
2690 /* Display it as active. */
2691 term_show_mouse_face (DRAW_MOUSE_FACE
);
2693 /* Handle the text property case. */
2694 else if (!NILP (mouse_face
))
2696 /* Find the range of text around this char that
2697 should be active. */
2698 Lisp_Object before
, after
, beginning
, end
;
2701 beginning
= Fmarker_position (w
->start
);
2702 XSETINT (end
, (BUF_Z (b
) - XFASTINT (w
->window_end_pos
)));
2704 = Fprevious_single_property_change (make_number (pos
+ 1),
2706 w
->buffer
, beginning
);
2708 = Fnext_single_property_change (position
, Qmouse_face
,
2711 /* Record this as the current active region. */
2712 fast_find_position (w
, XFASTINT (before
),
2713 &mouse_face_beg_col
,
2714 &mouse_face_beg_row
);
2716 = !fast_find_position (w
, XFASTINT (after
),
2717 &mouse_face_end_col
,
2718 &mouse_face_end_row
);
2719 Qmouse_face_window
= window
;
2722 = face_at_buffer_position (w
, pos
, 0, 0,
2723 &ignore
, pos
+ 1, 1);
2725 /* Display it as active. */
2726 term_show_mouse_face (DRAW_MOUSE_FACE
);
2730 /* Look for a `help-echo' property. */
2733 extern Lisp_Object Qhelp_echo
;
2735 /* Check overlays first. */
2737 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
2739 overlay
= overlay_vec
[i
];
2740 help
= Foverlay_get (overlay
, Qhelp_echo
);
2745 help_echo_string
= help
;
2746 help_echo_window
= window
;
2747 help_echo_object
= overlay
;
2748 help_echo_pos
= pos
;
2750 /* Try text properties. */
2751 else if (NILP (help
)
2752 && ((STRINGP (glyph
->object
)
2753 && glyph
->charpos
>= 0
2754 && glyph
->charpos
< SCHARS (glyph
->object
))
2755 || (BUFFERP (glyph
->object
)
2756 && glyph
->charpos
>= BEGV
2757 && glyph
->charpos
< ZV
)))
2759 help
= Fget_text_property (make_number (glyph
->charpos
),
2760 Qhelp_echo
, glyph
->object
);
2763 help_echo_string
= help
;
2764 help_echo_window
= window
;
2765 help_echo_object
= glyph
->object
;
2766 help_echo_pos
= glyph
->charpos
;
2773 current_buffer
= obuf
;
2779 term_mouse_movement (FRAME_PTR frame
, Gpm_Event
*event
)
2781 /* Has the mouse moved off the glyph it was on at the last sighting? */
2782 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2784 frame
->mouse_moved
= 1;
2785 term_mouse_highlight (frame
, event
->x
, event
->y
);
2786 /* Remember which glyph we're now on. */
2787 last_mouse_x
= event
->x
;
2788 last_mouse_y
= event
->y
;
2794 /* Return the current position of the mouse.
2796 Set *f to the frame the mouse is in, or zero if the mouse is in no
2797 Emacs frame. If it is set to zero, all the other arguments are
2800 Set *bar_window to Qnil, and *x and *y to the column and
2801 row of the character cell the mouse is over.
2803 Set *time to the time the mouse was at the returned position.
2805 This clears mouse_moved until the next motion
2808 term_mouse_position (FRAME_PTR
*fp
, int insist
, Lisp_Object
*bar_window
,
2809 enum scroll_bar_part
*part
, Lisp_Object
*x
,
2810 Lisp_Object
*y
, unsigned long *time
)
2814 *fp
= SELECTED_FRAME ();
2815 (*fp
)->mouse_moved
= 0;
2820 XSETINT (*x
, last_mouse_x
);
2821 XSETINT (*y
, last_mouse_y
);
2822 gettimeofday(&now
, 0);
2823 *time
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2826 /* Prepare a mouse-event in *RESULT for placement in the input queue.
2828 If the event is a button press, then note that we have grabbed
2832 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
2838 result
->kind
= GPM_CLICK_EVENT
;
2839 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
2841 if (event
->buttons
& j
) {
2842 result
->code
= i
; /* button number */
2846 gettimeofday(&now
, 0);
2847 result
->timestamp
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2849 if (event
->type
& GPM_UP
)
2850 result
->modifiers
= up_modifier
;
2851 else if (event
->type
& GPM_DOWN
)
2852 result
->modifiers
= down_modifier
;
2854 result
->modifiers
= 0;
2856 if (event
->type
& GPM_SINGLE
)
2857 result
->modifiers
|= click_modifier
;
2859 if (event
->type
& GPM_DOUBLE
)
2860 result
->modifiers
|= double_modifier
;
2862 if (event
->type
& GPM_TRIPLE
)
2863 result
->modifiers
|= triple_modifier
;
2865 if (event
->type
& GPM_DRAG
)
2866 result
->modifiers
|= drag_modifier
;
2868 if (!(event
->type
& (GPM_MOVE
| GPM_DRAG
))) {
2871 if (event
->modifiers
& (1 << 0))
2872 result
->modifiers
|= shift_modifier
;
2875 if (event
->modifiers
& (1 << 2))
2876 result
->modifiers
|= ctrl_modifier
;
2878 /* 1 << KG_ALT || KG_ALTGR */
2879 if (event
->modifiers
& (1 << 3)
2880 || event
->modifiers
& (1 << 1))
2881 result
->modifiers
|= meta_modifier
;
2884 XSETINT (result
->x
, event
->x
);
2885 XSETINT (result
->y
, event
->y
);
2886 XSETFRAME (result
->frame_or_window
, f
);
2892 handle_one_term_event (struct tty_display_info
*tty
, Gpm_Event
*event
, struct input_event
* hold_quit
)
2894 struct frame
*f
= XFRAME (tty
->top_frame
);
2896 struct input_event ie
;
2904 if (event
->type
& (GPM_MOVE
| GPM_DRAG
)) {
2905 unsigned char buf
[6 * sizeof (short)];
2906 unsigned short *arg
= (unsigned short *) buf
+ 1;
2909 previous_help_echo_string
= help_echo_string
;
2910 help_echo_string
= Qnil
;
2912 /* Display mouse pointer */
2913 buf
[sizeof(short) - 1] = 2; /* set selection */
2915 arg
[0] = arg
[2] = (unsigned short) event
->x
+ gpm_zerobased
;
2916 arg
[1] = arg
[3] = (unsigned short) event
->y
+ gpm_zerobased
;
2917 arg
[4] = (unsigned short) 3;
2920 fd
= open (name
, O_WRONLY
);
2921 ioctl (fd
, TIOCLINUX
, buf
+ sizeof (short) - 1);
2924 if (!term_mouse_movement (f
, event
))
2925 help_echo_string
= previous_help_echo_string
;
2927 /* If the contents of the global variable help_echo_string
2928 has changed, generate a HELP_EVENT. */
2929 if (!NILP (help_echo_string
)
2930 || !NILP (previous_help_echo_string
))
2937 term_mouse_click (&ie
, event
, f
);
2941 if (ie
.kind
!= NO_EVENT
)
2943 kbd_buffer_store_event_hold (&ie
, hold_quit
);
2948 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
2953 XSETFRAME (frame
, f
);
2957 gen_help_event (help_echo_string
, frame
, help_echo_window
,
2958 help_echo_object
, help_echo_pos
);
2965 DEFUN ("term-open-connection", Fterm_open_connection
, Sterm_open_connection
,
2967 doc
: /* Open a connection to Gpm. */)
2970 struct tty_display_info
*tty
= FRAME_TTY (SELECTED_FRAME ());
2971 Gpm_Connect connection
;
2973 connection
.eventMask
= ~0;
2974 connection
.defaultMask
= ~GPM_HARD
;
2975 connection
.maxMod
= ~0;
2976 connection
.minMod
= 0;
2979 /* We only support GPM on the controlling tty. */
2980 if (term_gpm
|| tty
->terminal
->id
> 1
2981 || Gpm_Open (&connection
, 0) < 0)
2986 gpm_tty
= tty
->terminal
->id
;
2987 reset_sys_modes (tty
);
2988 init_sys_modes (tty
);
2989 add_gpm_wait_descriptor (gpm_fd
);
2994 DEFUN ("term-close-connection", Fterm_close_connection
, Sterm_close_connection
,
2996 doc
: /* Close a connection to Gpm. */)
2999 delete_gpm_wait_descriptor (gpm_fd
);
3000 while (Gpm_Close()); /* close all the stack */
3004 #endif /* HAVE_GPM */
3007 /***********************************************************************
3009 ***********************************************************************/
3011 /* Initialize the tty-dependent part of frame F. The frame must
3012 already have its device initialized. */
3015 create_tty_output (struct frame
*f
)
3017 struct tty_output
*t
;
3019 if (! FRAME_TERMCAP_P (f
))
3022 t
= xmalloc (sizeof (struct tty_output
));
3023 bzero (t
, sizeof (struct tty_output
));
3025 t
->display_info
= FRAME_TERMINAL (f
)->display_info
.tty
;
3027 f
->output_data
.tty
= t
;
3030 /* Delete the tty-dependent part of frame F. */
3033 delete_tty_output (struct frame
*f
)
3035 if (! FRAME_TERMCAP_P (f
))
3038 xfree (f
->output_data
.tty
);
3044 clear_tty_hooks (struct terminal
*terminal
)
3047 terminal
->cursor_to_hook
= 0;
3048 terminal
->raw_cursor_to_hook
= 0;
3049 terminal
->clear_to_end_hook
= 0;
3050 terminal
->clear_frame_hook
= 0;
3051 terminal
->clear_end_of_line_hook
= 0;
3052 terminal
->ins_del_lines_hook
= 0;
3053 terminal
->insert_glyphs_hook
= 0;
3054 terminal
->write_glyphs_hook
= 0;
3055 terminal
->delete_glyphs_hook
= 0;
3056 terminal
->ring_bell_hook
= 0;
3057 terminal
->reset_terminal_modes_hook
= 0;
3058 terminal
->set_terminal_modes_hook
= 0;
3059 terminal
->update_begin_hook
= 0;
3060 terminal
->update_end_hook
= 0;
3061 terminal
->set_terminal_window_hook
= 0;
3062 terminal
->mouse_position_hook
= 0;
3063 terminal
->frame_rehighlight_hook
= 0;
3064 terminal
->frame_raise_lower_hook
= 0;
3065 terminal
->fullscreen_hook
= 0;
3066 terminal
->set_vertical_scroll_bar_hook
= 0;
3067 terminal
->condemn_scroll_bars_hook
= 0;
3068 terminal
->redeem_scroll_bar_hook
= 0;
3069 terminal
->judge_scroll_bars_hook
= 0;
3070 terminal
->read_socket_hook
= 0;
3071 terminal
->frame_up_to_date_hook
= 0;
3073 /* Leave these two set, or suspended frames are not deleted
3075 terminal
->delete_frame_hook
= &delete_tty_output
;
3076 terminal
->delete_terminal_hook
= &delete_tty
;
3080 set_tty_hooks (struct terminal
*terminal
)
3082 terminal
->rif
= 0; /* ttys don't support window-based redisplay. */
3084 terminal
->cursor_to_hook
= &tty_cursor_to
;
3085 terminal
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
3087 terminal
->clear_to_end_hook
= &tty_clear_to_end
;
3088 terminal
->clear_frame_hook
= &tty_clear_frame
;
3089 terminal
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
3091 terminal
->ins_del_lines_hook
= &tty_ins_del_lines
;
3093 terminal
->insert_glyphs_hook
= &tty_insert_glyphs
;
3094 terminal
->write_glyphs_hook
= &tty_write_glyphs
;
3095 terminal
->delete_glyphs_hook
= &tty_delete_glyphs
;
3097 terminal
->ring_bell_hook
= &tty_ring_bell
;
3099 terminal
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
3100 terminal
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
3101 terminal
->update_begin_hook
= 0; /* Not needed. */
3102 terminal
->update_end_hook
= &tty_update_end
;
3103 terminal
->set_terminal_window_hook
= &tty_set_terminal_window
;
3105 terminal
->mouse_position_hook
= 0; /* Not needed. */
3106 terminal
->frame_rehighlight_hook
= 0; /* Not needed. */
3107 terminal
->frame_raise_lower_hook
= 0; /* Not needed. */
3109 terminal
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
3110 terminal
->condemn_scroll_bars_hook
= 0; /* Not needed. */
3111 terminal
->redeem_scroll_bar_hook
= 0; /* Not needed. */
3112 terminal
->judge_scroll_bars_hook
= 0; /* Not needed. */
3114 terminal
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
3115 terminal
->frame_up_to_date_hook
= 0; /* Not needed. */
3117 terminal
->delete_frame_hook
= &delete_tty_output
;
3118 terminal
->delete_terminal_hook
= &delete_tty
;
3121 /* Drop the controlling terminal if fd is the same device. */
3123 dissociate_if_controlling_tty (int fd
)
3127 EMACS_GET_TTY_PGRP (fd
, &pgid
); /* If tcgetpgrp succeeds, fd is the ctty. */
3130 #if defined (USG) && !defined (BSD_PGRPS)
3132 no_controlling_tty
= 1;
3134 #ifdef TIOCNOTTY /* Try BSD ioctls. */
3135 sigblock (sigmask (SIGTTOU
));
3136 fd
= emacs_open ("/dev/tty", O_RDWR
, 0);
3137 if (fd
!= -1 && ioctl (fd
, TIOCNOTTY
, 0) != -1)
3139 no_controlling_tty
= 1;
3143 sigunblock (sigmask (SIGTTOU
));
3145 /* Unknown system. */
3147 #endif /* ! TIOCNOTTY */
3153 static void maybe_fatal();
3155 /* Create a termcap display on the tty device with the given name and
3158 If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
3159 Otherwise NAME should be a path to the tty device file,
3162 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
3164 If MUST_SUCCEED is true, then all errors are fatal. */
3167 init_tty (char *name
, char *terminal_type
, int must_succeed
)
3170 char **address
= &area
;
3171 char *buffer
= NULL
;
3172 int buffer_size
= 4096;
3173 register char *p
= NULL
;
3175 struct tty_display_info
*tty
= NULL
;
3176 struct terminal
*terminal
= NULL
;
3177 int ctty
= 0; /* 1 if asked to open controlling tty. */
3180 maybe_fatal (must_succeed
, 0, 0,
3181 "Unknown terminal type",
3182 "Unknown terminal type");
3187 if (!strcmp (name
, "/dev/tty"))
3190 /* If we already have a terminal on the given device, use that. If
3191 all such terminals are suspended, create a new one instead. */
3192 /* XXX Perhaps this should be made explicit by having init_tty
3193 always create a new terminal and separating terminal and frame
3194 creation on Lisp level. */
3195 terminal
= get_named_tty (name
);
3200 terminal
= create_terminal ();
3201 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
3202 bzero (tty
, sizeof (struct tty_display_info
));
3203 tty
->next
= tty_list
;
3206 terminal
->type
= output_termcap
;
3207 terminal
->display_info
.tty
= tty
;
3208 tty
->terminal
= terminal
;
3210 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
3214 set_tty_hooks (terminal
);
3220 #ifdef O_IGNORE_CTTY
3222 /* Open the terminal device. Don't recognize it as our
3223 controlling terminal, and don't make it the controlling tty
3224 if we don't have one at the moment. */
3225 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
3228 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
3229 defined on Hurd. On other systems, we need to explicitly
3230 dissociate ourselves from the controlling tty when we want to
3231 open a frame on the same terminal. */
3232 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
3233 #endif /* O_IGNORE_CTTY */
3236 maybe_fatal (must_succeed
, buffer
, terminal
,
3237 "Could not open file: %s",
3238 "Could not open file: %s",
3243 maybe_fatal (must_succeed
, buffer
, terminal
,
3244 "Not a tty device: %s",
3245 "Not a tty device: %s",
3249 #ifndef O_IGNORE_CTTY
3251 dissociate_if_controlling_tty (fd
);
3254 file
= fdopen (fd
, "w+");
3255 tty
->name
= xstrdup (name
);
3256 terminal
->name
= xstrdup (name
);
3261 tty
->type
= xstrdup (terminal_type
);
3263 add_keyboard_wait_descriptor (fileno (tty
->input
));
3267 encode_terminal_bufsize
= 0;
3270 terminal
->mouse_position_hook
= term_mouse_position
;
3271 Qmouse_face_window
= Qnil
;
3275 initialize_w32_display ();
3277 /* XXX Can this be non-null? */
3280 tty
->name
= xstrdup (name
);
3281 terminal
->name
= xstrdup (name
);
3283 tty
->type
= xstrdup (terminal_type
);
3285 /* XXX not sure if this line is correct. If it is not set then we
3286 crash in update_display_1. */
3287 tty
->output
= stdout
;
3291 area
= (char *) xmalloc (2044); /* XXX this seems unused. */
3294 struct frame
*f
= XFRAME (selected_frame
);
3296 FrameRows (tty
) = FRAME_LINES (f
); /* XXX */
3297 FrameCols (tty
) = FRAME_COLS (f
); /* XXX */
3298 tty
->specified_window
= FRAME_LINES (f
); /* XXX */
3300 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0; /* XXX */
3301 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
; /* XXX */
3303 tty
->delete_in_insert_mode
= 1;
3306 terminal
->scroll_region_ok
= 0;
3308 /* Seems to insert lines when it's not supposed to, messing up the
3309 display. In doing a trace, it didn't seem to be called much, so I
3310 don't think we're losing anything by turning it off. */
3311 terminal
->line_ins_del_ok
= 0;
3312 terminal
->char_ins_del_ok
= 1;
3316 tty
->TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
3319 #else /* not WINDOWSNT */
3323 buffer
= (char *) xmalloc (buffer_size
);
3325 /* On some systems, tgetent tries to access the controlling
3327 sigblock (sigmask (SIGTTOU
));
3328 status
= tgetent (buffer
, terminal_type
);
3329 sigunblock (sigmask (SIGTTOU
));
3334 maybe_fatal (must_succeed
, buffer
, terminal
,
3335 "Cannot open terminfo database file",
3336 "Cannot open terminfo database file");
3338 maybe_fatal (must_succeed
, buffer
, terminal
,
3339 "Cannot open termcap database file",
3340 "Cannot open termcap database file");
3346 maybe_fatal (must_succeed
, buffer
, terminal
,
3347 "Terminal type %s is not defined",
3348 "Terminal type %s is not defined.\n\
3349 If that is not the actual type of terminal you have,\n\
3350 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3351 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3352 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3355 maybe_fatal (must_succeed
, buffer
, terminal
,
3356 "Terminal type %s is not defined",
3357 "Terminal type %s is not defined.\n\
3358 If that is not the actual type of terminal you have,\n\
3359 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3360 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3361 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3367 if (strlen (buffer
) >= buffer_size
)
3369 buffer_size
= strlen (buffer
);
3371 area
= (char *) xmalloc (buffer_size
);
3373 tty
->TS_ins_line
= tgetstr ("al", address
);
3374 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
3375 tty
->TS_bell
= tgetstr ("bl", address
);
3376 BackTab (tty
) = tgetstr ("bt", address
);
3377 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
3378 tty
->TS_clr_line
= tgetstr ("ce", address
);
3379 tty
->TS_clr_frame
= tgetstr ("cl", address
);
3380 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
3381 AbsPosition (tty
) = tgetstr ("cm", address
);
3382 CR (tty
) = tgetstr ("cr", address
);
3383 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
3384 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
3385 RowPosition (tty
) = tgetstr ("cv", address
);
3386 tty
->TS_del_char
= tgetstr ("dc", address
);
3387 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
3388 tty
->TS_del_line
= tgetstr ("dl", address
);
3389 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
3390 tty
->TS_delete_mode
= tgetstr ("dm", address
);
3391 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
3392 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
3393 Home (tty
) = tgetstr ("ho", address
);
3394 tty
->TS_ins_char
= tgetstr ("ic", address
);
3395 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
3396 tty
->TS_insert_mode
= tgetstr ("im", address
);
3397 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
3398 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
3399 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
3400 LastLine (tty
) = tgetstr ("ll", address
);
3401 Right (tty
) = tgetstr ("nd", address
);
3402 Down (tty
) = tgetstr ("do", address
);
3404 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
3406 /* VMS puts a carriage return before each linefeed,
3407 so it is not safe to use linefeeds. */
3408 if (Down (tty
) && Down (tty
)[0] == '\n' && Down (tty
)[1] == '\0')
3411 if (tgetflag ("bs"))
3412 Left (tty
) = "\b"; /* can't possibly be longer! */
3413 else /* (Actually, "bs" is obsolete...) */
3414 Left (tty
) = tgetstr ("le", address
);
3416 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
3417 tty
->TS_pad_char
= tgetstr ("pc", address
);
3418 tty
->TS_repeat
= tgetstr ("rp", address
);
3419 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
3420 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
3421 tty
->TS_standout_mode
= tgetstr ("so", address
);
3422 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
3423 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
3424 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
3425 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
3426 Up (tty
) = tgetstr ("up", address
);
3427 tty
->TS_visible_bell
= tgetstr ("vb", address
);
3428 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
3429 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
3430 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
3431 tty
->TS_set_window
= tgetstr ("wi", address
);
3433 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
3434 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
3435 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
3436 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
3437 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
3438 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
3439 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3440 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3441 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
3443 MultiUp (tty
) = tgetstr ("UP", address
);
3444 MultiDown (tty
) = tgetstr ("DO", address
);
3445 MultiLeft (tty
) = tgetstr ("LE", address
);
3446 MultiRight (tty
) = tgetstr ("RI", address
);
3448 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
3449 color because we can't switch back to the default foreground and
3451 tty
->TS_orig_pair
= tgetstr ("op", address
);
3452 if (tty
->TS_orig_pair
)
3454 tty
->TS_set_foreground
= tgetstr ("AF", address
);
3455 tty
->TS_set_background
= tgetstr ("AB", address
);
3456 if (!tty
->TS_set_foreground
)
3459 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
3460 tty
->TS_set_background
= tgetstr ("Sb", address
);
3463 tty
->TN_max_colors
= tgetnum ("Co");
3464 tty
->TN_max_pairs
= tgetnum ("pa");
3466 tty
->TN_no_color_video
= tgetnum ("NC");
3467 if (tty
->TN_no_color_video
== -1)
3468 tty
->TN_no_color_video
= 0;
3471 tty_default_color_capabilities (tty
, 1);
3473 MagicWrap (tty
) = tgetflag ("xn");
3474 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3475 the former flag imply the latter. */
3476 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
3477 terminal
->memory_below_frame
= tgetflag ("db");
3478 tty
->TF_hazeltine
= tgetflag ("hz");
3479 terminal
->must_write_spaces
= tgetflag ("in");
3480 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
3481 tty
->TF_insmode_motion
= tgetflag ("mi");
3482 tty
->TF_standout_motion
= tgetflag ("ms");
3483 tty
->TF_underscore
= tgetflag ("ul");
3484 tty
->TF_teleray
= tgetflag ("xt");
3487 terminal
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
3488 init_kboard (terminal
->kboard
);
3489 terminal
->kboard
->next_kboard
= all_kboards
;
3490 all_kboards
= terminal
->kboard
;
3491 terminal
->kboard
->reference_count
++;
3492 /* Don't let the initial kboard remain current longer than necessary.
3493 That would cause problems if a file loaded on startup tries to
3494 prompt in the mini-buffer. */
3495 if (current_kboard
== initial_kboard
)
3496 current_kboard
= terminal
->kboard
;
3497 term_get_fkeys (address
, terminal
->kboard
);
3500 /* Get frame size from system, or else from termcap. */
3503 get_tty_size (fileno (tty
->input
), &width
, &height
);
3504 FrameCols (tty
) = width
;
3505 FrameRows (tty
) = height
;
3508 if (FrameCols (tty
) <= 0)
3509 FrameCols (tty
) = tgetnum ("co");
3510 if (FrameRows (tty
) <= 0)
3511 FrameRows (tty
) = tgetnum ("li");
3513 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
3514 maybe_fatal (must_succeed
, NULL
, terminal
,
3515 "Screen size %dx%d is too small"
3516 "Screen size %dx%d is too small",
3517 FrameCols (tty
), FrameRows (tty
));
3519 #if 0 /* This is not used anywhere. */
3520 tty
->terminal
->min_padding_speed
= tgetnum ("pb");
3523 TabWidth (tty
) = tgetnum ("tw");
3526 /* These capabilities commonly use ^J.
3527 I don't know why, but sending them on VMS does not work;
3528 it causes following spaces to be lost, sometimes.
3529 For now, the simplest fix is to avoid using these capabilities ever. */
3530 if (Down (tty
) && Down (tty
)[0] == '\n')
3535 tty
->TS_bell
= "\07";
3537 if (!tty
->TS_fwd_scroll
)
3538 tty
->TS_fwd_scroll
= Down (tty
);
3540 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
3542 if (TabWidth (tty
) < 0)
3545 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3546 and newer termcap doc does not seem to say there is a default.
3547 if (!tty->Wcm->cm_tab)
3548 tty->Wcm->cm_tab = "\t";
3551 /* We don't support standout modes that use `magic cookies', so
3552 turn off any that do. */
3553 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
3555 tty
->TS_standout_mode
= 0;
3556 tty
->TS_end_standout_mode
= 0;
3558 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3560 tty
->TS_enter_underline_mode
= 0;
3561 tty
->TS_exit_underline_mode
= 0;
3564 /* If there's no standout mode, try to use underlining instead. */
3565 if (tty
->TS_standout_mode
== 0)
3567 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
3568 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
3571 /* If no `se' string, try using a `me' string instead.
3572 If that fails, we can't use standout mode at all. */
3573 if (tty
->TS_end_standout_mode
== 0)
3575 char *s
= tgetstr ("me", address
);
3577 tty
->TS_end_standout_mode
= s
;
3579 tty
->TS_standout_mode
= 0;
3582 if (tty
->TF_teleray
)
3584 tty
->Wcm
->cm_tab
= 0;
3585 /* We can't support standout mode, because it uses magic cookies. */
3586 tty
->TS_standout_mode
= 0;
3587 /* But that means we cannot rely on ^M to go to column zero! */
3589 /* LF can't be trusted either -- can alter hpos */
3590 /* if move at column 0 thru a line with TS_standout_mode */
3594 /* Special handling for certain terminal types known to need it */
3596 if (!strcmp (terminal_type
, "supdup"))
3598 terminal
->memory_below_frame
= 1;
3599 tty
->Wcm
->cm_losewrap
= 1;
3601 if (!strncmp (terminal_type
, "c10", 3)
3602 || !strcmp (terminal_type
, "perq"))
3604 /* Supply a makeshift :wi string.
3605 This string is not valid in general since it works only
3606 for windows starting at the upper left corner;
3607 but that is all Emacs uses.
3609 This string works only if the frame is using
3610 the top of the video memory, because addressing is memory-relative.
3611 So first check the :ti string to see if that is true.
3613 It would be simpler if the :wi string could go in the termcap
3614 entry, but it can't because it is not fully valid.
3615 If it were in the termcap entry, it would confuse other programs. */
3616 if (!tty
->TS_set_window
)
3618 p
= tty
->TS_termcap_modes
;
3619 while (*p
&& strcmp (p
, "\033v "))
3622 tty
->TS_set_window
= "\033v%C %C %C %C ";
3624 /* Termcap entry often fails to have :in: flag */
3625 terminal
->must_write_spaces
= 1;
3626 /* :ti string typically fails to have \E^G! in it */
3627 /* This limits scope of insert-char to one line. */
3628 strcpy (area
, tty
->TS_termcap_modes
);
3629 strcat (area
, "\033\007!");
3630 tty
->TS_termcap_modes
= area
;
3631 area
+= strlen (area
) + 1;
3632 p
= AbsPosition (tty
);
3633 /* Change all %+ parameters to %C, to handle
3634 values above 96 correctly for the C100. */
3637 if (p
[0] == '%' && p
[1] == '+')
3643 tty
->specified_window
= FrameRows (tty
);
3645 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
3647 maybe_fatal (must_succeed
, NULL
, terminal
,
3648 "Terminal type \"%s\" is not powerful enough to run Emacs",
3650 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3651 It lacks the ability to position the cursor.\n\
3652 If that is not the actual type of terminal you have, use either the\n\
3653 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
3654 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
3657 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3658 It lacks the ability to position the cursor.\n\
3659 If that is not the actual type of terminal you have,\n\
3660 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3661 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3662 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3663 # else /* TERMCAP */
3664 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3665 It lacks the ability to position the cursor.\n\
3666 If that is not the actual type of terminal you have,\n\
3667 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3668 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3669 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3670 # endif /* TERMINFO */
3675 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
3676 maybe_fatal (must_succeed
, NULL
, terminal
,
3677 "Could not determine the frame size",
3678 "Could not determine the frame size");
3680 tty
->delete_in_insert_mode
3681 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
3682 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
3684 tty
->se_is_so
= (tty
->TS_standout_mode
3685 && tty
->TS_end_standout_mode
3686 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
3688 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
3690 terminal
->scroll_region_ok
3692 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
3694 terminal
->line_ins_del_ok
3695 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
3696 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
3697 || (terminal
->scroll_region_ok
3698 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
3700 terminal
->char_ins_del_ok
3701 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
3702 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
3703 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
3705 terminal
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
3707 init_baud_rate (fileno (tty
->input
));
3710 /* The HFT system on AIX doesn't optimize for scrolling, so it's
3711 really ugly at times. */
3712 terminal
->line_ins_del_ok
= 0;
3713 terminal
->char_ins_del_ok
= 0;
3716 /* Don't do this. I think termcap may still need the buffer. */
3717 /* xfree (buffer); */
3719 /* Init system terminal modes (RAW or CBREAK, etc.). */
3720 init_sys_modes (tty
);
3723 #endif /* not WINDOWSNT */
3726 /* Auxiliary error-handling function for init_tty.
3727 Free BUFFER and delete TERMINAL, then call error or fatal
3728 with str1 or str2, respectively, according to MUST_SUCCEED. */
3731 maybe_fatal (must_succeed
, buffer
, terminal
, str1
, str2
, arg1
, arg2
)
3734 struct terminal
*terminal
;
3735 char *str1
, *str2
, *arg1
, *arg2
;
3741 delete_tty (terminal
);
3744 fatal (str2
, arg1
, arg2
);
3746 error (str1
, arg1
, arg2
);
3753 fatal (str
, arg1
, arg2
)
3754 char *str
, *arg1
, *arg2
;
3756 fprintf (stderr
, "emacs: ");
3757 fprintf (stderr
, str
, arg1
, arg2
);
3758 fprintf (stderr
, "\n");
3765 /* Delete the given tty terminal, closing all frames on it. */
3768 delete_tty (struct terminal
*terminal
)
3770 struct tty_display_info
*tty
;
3771 Lisp_Object tail
, frame
;
3774 /* Protect against recursive calls. Fdelete_frame in
3775 delete_terminal calls us back when it deletes our last frame. */
3776 if (terminal
->deleted
)
3779 if (terminal
->type
!= output_termcap
)
3782 tty
= terminal
->display_info
.tty
;
3785 FOR_EACH_FRAME (tail
, frame
)
3787 struct frame
*f
= XFRAME (frame
);
3788 if (FRAME_LIVE_P (f
) && (!FRAME_TERMCAP_P (f
) || FRAME_TTY (f
) != tty
))
3795 error ("Attempt to delete the sole terminal device with live frames");
3797 if (tty
== tty_list
)
3798 tty_list
= tty
->next
;
3801 struct tty_display_info
*p
;
3802 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
3806 /* This should not happen. */
3809 p
->next
= tty
->next
;
3813 /* reset_sys_modes needs a valid device, so this call needs to be
3814 before delete_terminal. */
3815 reset_sys_modes (tty
);
3817 delete_terminal (terminal
);
3827 delete_keyboard_wait_descriptor (fileno (tty
->input
));
3828 if (tty
->input
!= stdin
)
3829 fclose (tty
->input
);
3831 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
3832 fclose (tty
->output
);
3833 if (tty
->termscript
)
3834 fclose (tty
->termscript
);
3837 xfree (tty
->old_tty
);
3842 bzero (tty
, sizeof (struct tty_display_info
));
3848 /* Mark the pointers in the tty_display_info objects.
3849 Called by the Fgarbage_collector. */
3854 struct tty_display_info
*tty
;
3856 for (tty
= tty_list
; tty
; tty
= tty
->next
)
3859 mark_object (tty
->top_frame
);
3868 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
3869 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3870 This variable can be used by terminal emulator packages. */);
3872 system_uses_terminfo
= 1;
3874 system_uses_terminfo
= 0;
3877 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions
,
3878 doc
: /* Functions to be run after suspending a tty.
3879 The functions are run with one argument, the terminal id to be suspended.
3880 See `suspend-tty'. */);
3881 Vsuspend_tty_functions
= Qnil
;
3884 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions
,
3885 doc
: /* Functions to be run after resuming a tty.
3886 The functions are run with one argument, the terminal id that was revived.
3887 See `resume-tty'. */);
3888 Vresume_tty_functions
= Qnil
;
3890 DEFVAR_BOOL ("visible-cursor", &visible_cursor
,
3891 doc
: /* Non-nil means to make the cursor very visible.
3892 This only has an effect when running in a text terminal.
3893 What means \"very visible\" is up to your terminal. It may make the cursor
3894 bigger, or it may make it blink, or it may do nothing at all. */);
3897 defsubr (&Stty_display_color_p
);
3898 defsubr (&Stty_display_color_cells
);
3899 defsubr (&Stty_no_underline
);
3900 defsubr (&Stty_type
);
3901 defsubr (&Scontrolling_tty_p
);
3902 defsubr (&Ssuspend_tty
);
3903 defsubr (&Sresume_tty
);
3905 defsubr (&Sterm_open_connection
);
3906 defsubr (&Sterm_close_connection
);
3908 staticpro (&Qmouse_face_window
);
3909 #endif /* HAVE_GPM */
3914 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
3915 (do not change this comment) */