1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
37 #include <termios.h> /* For TIOCNOTTY. */
47 #include "character.h"
50 #include "composite.h"
54 #include "termhooks.h"
55 #include "dispextern.h"
58 #include "blockinput.h"
59 #include "syssignal.h"
61 #include "intervals.h"
63 /* For now, don't try to include termcap.h. On some systems,
64 configure finds a non-standard termcap.h that the main build
67 #if defined HAVE_TERMCAP_H && 0
70 extern void tputs
P_ ((const char *, int, int (*)(int)));
71 extern int tgetent
P_ ((char *, const char *));
72 extern int tgetflag
P_ ((char *id
));
73 extern int tgetnum
P_ ((char *id
));
92 /* The name of the default console device. */
94 #define DEV_TTY "CONOUT$"
96 #define DEV_TTY "/dev/tty"
99 static void tty_set_scroll_region
P_ ((struct frame
*f
, int start
, int stop
));
100 static void turn_on_face
P_ ((struct frame
*, int face_id
));
101 static void turn_off_face
P_ ((struct frame
*, int face_id
));
102 static void tty_show_cursor
P_ ((struct tty_display_info
*));
103 static void tty_hide_cursor
P_ ((struct tty_display_info
*));
104 static void tty_background_highlight
P_ ((struct tty_display_info
*tty
));
105 static void clear_tty_hooks
P_ ((struct terminal
*terminal
));
106 static void set_tty_hooks
P_ ((struct terminal
*terminal
));
107 static void dissociate_if_controlling_tty
P_ ((int fd
));
108 static void delete_tty
P_ ((struct terminal
*));
110 #define OUTPUT(tty, a) \
111 emacs_tputs ((tty), a, \
112 (int) (FRAME_LINES (XFRAME (selected_frame)) \
116 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
117 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
119 #define OUTPUT_IF(tty, a) \
122 emacs_tputs ((tty), a, \
123 (int) (FRAME_LINES (XFRAME (selected_frame)) \
128 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
130 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */
132 static int visible_cursor
;
134 /* Display space properties */
136 extern Lisp_Object Qspace
, QCalign_to
, QCwidth
;
138 /* Functions to call after suspending a tty. */
139 Lisp_Object Vsuspend_tty_functions
;
141 /* Functions to call after resuming a tty. */
142 Lisp_Object Vresume_tty_functions
;
144 /* Chain of all tty device parameters. */
145 struct tty_display_info
*tty_list
;
147 /* Nonzero means no need to redraw the entire frame on resuming a
148 suspended Emacs. This is useful on terminals with multiple
149 pages, where one page is used for Emacs and another for all
151 int no_redraw_on_reenter
;
153 /* Meaning of bits in no_color_video. Each bit set means that the
154 corresponding attribute cannot be combined with colors. */
158 NC_STANDOUT
= 1 << 0,
159 NC_UNDERLINE
= 1 << 1,
166 NC_ALT_CHARSET
= 1 << 8
171 /* The largest frame width in any call to calculate_costs. */
175 /* The largest frame height in any call to calculate_costs. */
179 /* Non-zero if we have dropped our controlling tty and therefore
180 should not open a frame on stdout. */
181 static int no_controlling_tty
;
183 /* Provided for lisp packages. */
185 static int system_uses_terminfo
;
189 extern char *tgetstr ();
193 #include <sys/fcntl.h>
195 static void term_clear_mouse_face ();
196 static void term_mouse_highlight (struct frame
*f
, int x
, int y
);
198 /* The device for which we have enabled gpm support (or NULL). */
199 struct tty_display_info
*gpm_tty
= NULL
;
201 /* These variables describe the range of text currently shown in its
202 mouse-face, together with the window they apply to. As long as
203 the mouse stays within this range, we need not redraw anything on
204 its account. Rows and columns are glyph matrix positions in
205 MOUSE_FACE_WINDOW. */
206 static int mouse_face_beg_row
, mouse_face_beg_col
;
207 static int mouse_face_end_row
, mouse_face_end_col
;
208 static int mouse_face_past_end
;
209 static Lisp_Object mouse_face_window
;
210 static int mouse_face_face_id
;
212 static int pos_x
, pos_y
;
213 static int last_mouse_x
, last_mouse_y
;
214 #endif /* HAVE_GPM */
216 /* Ring the bell on a tty. */
219 tty_ring_bell (struct frame
*f
)
221 struct tty_display_info
*tty
= FRAME_TTY (f
);
225 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
226 ? tty
->TS_visible_bell
228 fflush (tty
->output
);
232 /* Set up termcap modes for Emacs. */
235 tty_set_terminal_modes (struct terminal
*terminal
)
237 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
241 if (tty
->TS_termcap_modes
)
242 OUTPUT (tty
, tty
->TS_termcap_modes
);
245 /* Output enough newlines to scroll all the old screen contents
246 off the screen, so it won't be overwritten and lost. */
249 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
253 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
254 OUTPUT_IF (tty
, visible_cursor
? tty
->TS_cursor_visible
: tty
->TS_cursor_normal
);
255 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
257 fflush (tty
->output
);
261 /* Reset termcap modes before exiting Emacs. */
264 tty_reset_terminal_modes (struct terminal
*terminal
)
266 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
270 tty_turn_off_highlight (tty
);
271 tty_turn_off_insert (tty
);
272 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
273 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
274 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
275 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
276 /* Output raw CR so kernel can track the cursor hpos. */
279 fflush (tty
->output
);
283 /* Flag the end of a display update on a termcap terminal. */
286 tty_update_end (struct frame
*f
)
288 struct tty_display_info
*tty
= FRAME_TTY (f
);
290 if (!XWINDOW (selected_window
)->cursor_off_p
)
291 tty_show_cursor (tty
);
292 tty_turn_off_insert (tty
);
293 tty_background_highlight (tty
);
296 /* The implementation of set_terminal_window for termcap frames. */
299 tty_set_terminal_window (struct frame
*f
, int size
)
301 struct tty_display_info
*tty
= FRAME_TTY (f
);
303 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
304 if (FRAME_SCROLL_REGION_OK (f
))
305 tty_set_scroll_region (f
, 0, tty
->specified_window
);
309 tty_set_scroll_region (struct frame
*f
, int start
, int stop
)
312 struct tty_display_info
*tty
= FRAME_TTY (f
);
314 if (tty
->TS_set_scroll_region
)
315 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
316 else if (tty
->TS_set_scroll_region_1
)
317 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
318 FRAME_LINES (f
), start
,
319 FRAME_LINES (f
) - stop
,
322 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
331 tty_turn_on_insert (struct tty_display_info
*tty
)
333 if (!tty
->insert_mode
)
334 OUTPUT (tty
, tty
->TS_insert_mode
);
335 tty
->insert_mode
= 1;
339 tty_turn_off_insert (struct tty_display_info
*tty
)
341 if (tty
->insert_mode
)
342 OUTPUT (tty
, tty
->TS_end_insert_mode
);
343 tty
->insert_mode
= 0;
346 /* Handle highlighting. */
349 tty_turn_off_highlight (struct tty_display_info
*tty
)
351 if (tty
->standout_mode
)
352 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
353 tty
->standout_mode
= 0;
357 tty_turn_on_highlight (struct tty_display_info
*tty
)
359 if (!tty
->standout_mode
)
360 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
361 tty
->standout_mode
= 1;
365 tty_toggle_highlight (struct tty_display_info
*tty
)
367 if (tty
->standout_mode
)
368 tty_turn_off_highlight (tty
);
370 tty_turn_on_highlight (tty
);
374 /* Make cursor invisible. */
377 tty_hide_cursor (struct tty_display_info
*tty
)
379 if (tty
->cursor_hidden
== 0)
381 tty
->cursor_hidden
= 1;
382 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
387 /* Ensure that cursor is visible. */
390 tty_show_cursor (struct tty_display_info
*tty
)
392 if (tty
->cursor_hidden
)
394 tty
->cursor_hidden
= 0;
395 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
397 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
402 /* Set standout mode to the state it should be in for
403 empty space inside windows. What this is,
404 depends on the user option inverse-video. */
407 tty_background_highlight (struct tty_display_info
*tty
)
410 tty_turn_on_highlight (tty
);
412 tty_turn_off_highlight (tty
);
415 /* Set standout mode to the mode specified for the text to be output. */
418 tty_highlight_if_desired (struct tty_display_info
*tty
)
421 tty_turn_on_highlight (tty
);
423 tty_turn_off_highlight (tty
);
427 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
428 frame-relative coordinates. */
431 tty_cursor_to (struct frame
*f
, int vpos
, int hpos
)
433 struct tty_display_info
*tty
= FRAME_TTY (f
);
435 /* Detect the case where we are called from reset_sys_modes
436 and the costs have never been calculated. Do nothing. */
437 if (! tty
->costs_set
)
440 if (curY (tty
) == vpos
441 && curX (tty
) == hpos
)
443 if (!tty
->TF_standout_motion
)
444 tty_background_highlight (tty
);
445 if (!tty
->TF_insmode_motion
)
446 tty_turn_off_insert (tty
);
447 cmgoto (tty
, vpos
, hpos
);
450 /* Similar but don't take any account of the wasted characters. */
453 tty_raw_cursor_to (struct frame
*f
, int row
, int col
)
455 struct tty_display_info
*tty
= FRAME_TTY (f
);
457 if (curY (tty
) == row
458 && curX (tty
) == col
)
460 if (!tty
->TF_standout_motion
)
461 tty_background_highlight (tty
);
462 if (!tty
->TF_insmode_motion
)
463 tty_turn_off_insert (tty
);
464 cmgoto (tty
, row
, col
);
467 /* Erase operations */
469 /* Clear from cursor to end of frame on a termcap device. */
472 tty_clear_to_end (struct frame
*f
)
475 struct tty_display_info
*tty
= FRAME_TTY (f
);
477 if (tty
->TS_clr_to_bottom
)
479 tty_background_highlight (tty
);
480 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
484 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
487 clear_end_of_line (f
, FRAME_COLS (f
));
492 /* Clear an entire termcap frame. */
495 tty_clear_frame (struct frame
*f
)
497 struct tty_display_info
*tty
= FRAME_TTY (f
);
499 if (tty
->TS_clr_frame
)
501 tty_background_highlight (tty
);
502 OUTPUT (tty
, tty
->TS_clr_frame
);
512 /* An implementation of clear_end_of_line for termcap frames.
514 Note that the cursor may be moved, on terminals lacking a `ce' string. */
517 tty_clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
520 struct tty_display_info
*tty
= FRAME_TTY (f
);
522 /* Detect the case where we are called from reset_sys_modes
523 and the costs have never been calculated. Do nothing. */
524 if (! tty
->costs_set
)
527 if (curX (tty
) >= first_unused_hpos
)
529 tty_background_highlight (tty
);
530 if (tty
->TS_clr_line
)
532 OUTPUT1 (tty
, tty
->TS_clr_line
);
535 { /* have to do it the hard way */
536 tty_turn_off_insert (tty
);
538 /* Do not write in last row last col with Auto-wrap on. */
540 && curY (tty
) == FrameRows (tty
) - 1
541 && first_unused_hpos
== FrameCols (tty
))
544 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
547 fputc (' ', tty
->termscript
);
548 fputc (' ', tty
->output
);
550 cmplus (tty
, first_unused_hpos
- curX (tty
));
554 /* Buffers to store the source and result of code conversion for terminal. */
555 static unsigned char *encode_terminal_src
;
556 static unsigned char *encode_terminal_dst
;
557 /* Allocated sizes of the above buffers. */
558 static int encode_terminal_src_size
;
559 static int encode_terminal_dst_size
;
561 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
562 Set CODING->produced to the byte-length of the resulting byte
563 sequence, and return a pointer to that byte sequence. */
566 encode_terminal_code (src
, src_len
, coding
)
569 struct coding_system
*coding
;
571 struct glyph
*src_end
= src
+ src_len
;
574 int nchars
, nbytes
, required
;
575 register int tlen
= GLYPH_TABLE_LENGTH
;
576 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
577 Lisp_Object charset_list
;
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 or a composite glyph is
583 required
= MAX_MULTIBYTE_LENGTH
* src_len
;
584 if (encode_terminal_src_size
< required
)
586 if (encode_terminal_src_size
== 0)
587 encode_terminal_src
= xmalloc (required
);
589 encode_terminal_src
= xrealloc (encode_terminal_src
, required
);
590 encode_terminal_src_size
= required
;
593 charset_list
= coding_charset_list (coding
);
595 buf
= encode_terminal_src
;
597 while (src
< src_end
)
599 if (src
->type
== COMPOSITE_GLYPH
)
601 struct composition
*cmp
= composition_table
[src
->u
.cmp_id
];
604 nbytes
= buf
- encode_terminal_src
;
605 required
= MAX_MULTIBYTE_LENGTH
* cmp
->glyph_len
;
607 if (encode_terminal_src_size
< nbytes
+ required
)
609 encode_terminal_src_size
= nbytes
+ required
;
610 encode_terminal_src
= xrealloc (encode_terminal_src
,
611 encode_terminal_src_size
);
612 buf
= encode_terminal_src
+ nbytes
;
615 for (i
= 0; i
< cmp
->glyph_len
; i
++)
617 int c
= COMPOSITION_GLYPH (cmp
, i
);
619 if (! char_charset (c
, charset_list
, NULL
))
621 buf
+= CHAR_STRING (c
, buf
);
626 /* The first character of the composition is not encodable. */
631 /* We must skip glyphs to be padded for a wide character. */
632 else if (! CHAR_GLYPH_PADDING_P (*src
))
638 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
640 if (g
< 0 || g
>= tlen
)
642 /* This glyph doesn't has an entry in Vglyph_table. */
647 /* This glyph has an entry in Vglyph_table,
648 so process any alias before testing for simpleness. */
649 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
651 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
652 /* We set the multi-byte form of a character in G
653 (that should be an ASCII character) at WORKBUF. */
654 c
= FAST_GLYPH_CHAR (g
);
656 /* We have a string in Vglyph_table. */
662 nbytes
= buf
- encode_terminal_src
;
663 if (encode_terminal_src_size
< nbytes
+ MAX_MULTIBYTE_LENGTH
)
665 encode_terminal_src_size
= nbytes
+ MAX_MULTIBYTE_LENGTH
;
666 encode_terminal_src
= xrealloc (encode_terminal_src
,
667 encode_terminal_src_size
);
668 buf
= encode_terminal_src
+ nbytes
;
670 if (char_charset (c
, charset_list
, NULL
))
672 /* Store the multibyte form of C at BUF. */
673 buf
+= CHAR_STRING (c
, buf
);
678 /* C is not encodable. */
681 while (src
+ 1 < src_end
&& CHAR_GLYPH_PADDING_P (src
[1]))
691 unsigned char *p
= SDATA (string
), *pend
= p
+ SBYTES (string
);
693 if (! STRING_MULTIBYTE (string
))
694 string
= string_to_multibyte (string
);
695 nbytes
= buf
- encode_terminal_src
;
696 if (encode_terminal_src_size
< nbytes
+ SBYTES (string
))
698 encode_terminal_src_size
= nbytes
+ SBYTES (string
);
699 encode_terminal_src
= xrealloc (encode_terminal_src
,
700 encode_terminal_src_size
);
701 buf
= encode_terminal_src
+ nbytes
;
703 bcopy (SDATA (string
), buf
, SBYTES (string
));
704 buf
+= SBYTES (string
);
705 nchars
+= SCHARS (string
);
713 coding
->produced
= 0;
717 nbytes
= buf
- encode_terminal_src
;
718 coding
->source
= encode_terminal_src
;
719 if (encode_terminal_dst_size
== 0)
721 encode_terminal_dst_size
= encode_terminal_src_size
;
722 encode_terminal_dst
= xmalloc (encode_terminal_dst_size
);
724 coding
->destination
= encode_terminal_dst
;
725 coding
->dst_bytes
= encode_terminal_dst_size
;
726 encode_coding_object (coding
, Qnil
, 0, 0, nchars
, nbytes
, Qnil
);
727 /* coding->destination may have been reallocated. */
728 encode_terminal_dst
= coding
->destination
;
729 encode_terminal_dst_size
= coding
->dst_bytes
;
731 return (encode_terminal_dst
);
736 /* An implementation of write_glyphs for termcap frames. */
739 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
741 unsigned char *conversion_buffer
;
742 struct coding_system
*coding
;
744 struct tty_display_info
*tty
= FRAME_TTY (f
);
746 tty_turn_off_insert (tty
);
747 tty_hide_cursor (tty
);
749 /* Don't dare write in last column of bottom line, if Auto-Wrap,
750 since that would scroll the whole frame on some terminals. */
753 && curY (tty
) + 1 == FRAME_LINES (f
)
754 && (curX (tty
) + len
) == FRAME_COLS (f
))
761 /* If terminal_coding does any conversion, use it, otherwise use
762 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
763 because it always return 1 if the member src_multibyte is 1. */
764 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
765 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
766 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
768 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
772 /* Identify a run of glyphs with the same face. */
773 int face_id
= string
->face_id
;
776 for (n
= 1; n
< len
; ++n
)
777 if (string
[n
].face_id
!= face_id
)
780 /* Turn appearance modes of the face of the run on. */
781 tty_highlight_if_desired (tty
);
782 turn_on_face (f
, face_id
);
785 /* This is the last run. */
786 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
787 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
788 if (coding
->produced
> 0)
791 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
792 if (ferror (tty
->output
))
793 clearerr (tty
->output
);
795 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 #ifdef HAVE_GPM /* Only used by GPM code. */
812 tty_write_glyphs_with_face (f
, string
, len
, face_id
)
813 register struct frame
*f
;
814 register struct glyph
*string
;
815 register int len
, face_id
;
817 unsigned char *conversion_buffer
;
818 struct coding_system
*coding
;
820 struct tty_display_info
*tty
= FRAME_TTY (f
);
822 tty_turn_off_insert (tty
);
823 tty_hide_cursor (tty
);
825 /* Don't dare write in last column of bottom line, if Auto-Wrap,
826 since that would scroll the whole frame on some terminals. */
829 && curY (tty
) + 1 == FRAME_LINES (f
)
830 && (curX (tty
) + len
) == FRAME_COLS (f
))
837 /* If terminal_coding does any conversion, use it, otherwise use
838 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
839 because it always return 1 if the member src_multibyte is 1. */
840 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
841 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
842 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
844 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
846 /* Turn appearance modes of the face. */
847 tty_highlight_if_desired (tty
);
848 turn_on_face (f
, face_id
);
850 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
851 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
852 if (coding
->produced
> 0)
855 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
856 if (ferror (tty
->output
))
857 clearerr (tty
->output
);
859 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
863 /* Turn appearance modes off. */
864 turn_off_face (f
, face_id
);
865 tty_turn_off_highlight (tty
);
871 /* An implementation of insert_glyphs for termcap frames. */
874 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
877 struct glyph
*glyph
= NULL
;
878 unsigned char *conversion_buffer
;
879 unsigned char space
[1];
880 struct coding_system
*coding
;
882 struct tty_display_info
*tty
= FRAME_TTY (f
);
884 if (tty
->TS_ins_multi_chars
)
886 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
890 write_glyphs (f
, start
, len
);
894 tty_turn_on_insert (tty
);
898 space
[0] = SPACEGLYPH
;
900 /* If terminal_coding does any conversion, use it, otherwise use
901 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
902 because it always return 1 if the member src_multibyte is 1. */
903 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
904 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
905 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
907 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
911 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
914 conversion_buffer
= space
;
915 coding
->produced
= 1;
919 tty_highlight_if_desired (tty
);
920 turn_on_face (f
, start
->face_id
);
923 /* We must open sufficient space for a character which
924 occupies more than one column. */
925 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
927 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
932 /* This is the last glyph. */
933 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
935 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
938 if (coding
->produced
> 0)
941 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
942 if (ferror (tty
->output
))
943 clearerr (tty
->output
);
945 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
949 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
952 turn_off_face (f
, glyph
->face_id
);
953 tty_turn_off_highlight (tty
);
960 /* An implementation of delete_glyphs for termcap frames. */
963 tty_delete_glyphs (struct frame
*f
, int n
)
968 struct tty_display_info
*tty
= FRAME_TTY (f
);
970 if (tty
->delete_in_insert_mode
)
972 tty_turn_on_insert (tty
);
976 tty_turn_off_insert (tty
);
977 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
980 if (tty
->TS_del_multi_chars
)
982 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
987 for (i
= 0; i
< n
; i
++)
988 OUTPUT1 (tty
, tty
->TS_del_char
);
989 if (!tty
->delete_in_insert_mode
)
990 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
993 /* An implementation of ins_del_lines for termcap frames. */
996 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
998 struct tty_display_info
*tty
= FRAME_TTY (f
);
999 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
1000 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
1001 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
1003 register int i
= n
> 0 ? n
: -n
;
1006 /* If the lines below the insertion are being pushed
1007 into the end of the window, this is the same as clearing;
1008 and we know the lines are already clear, since the matching
1009 deletion has already been done. So can ignore this. */
1010 /* If the lines below the deletion are blank lines coming
1011 out of the end of the window, don't bother,
1012 as there will be a matching inslines later that will flush them. */
1013 if (FRAME_SCROLL_REGION_OK (f
)
1014 && vpos
+ i
>= tty
->specified_window
)
1016 if (!FRAME_MEMORY_BELOW_FRAME (f
)
1017 && vpos
+ i
>= FRAME_LINES (f
))
1022 raw_cursor_to (f
, vpos
, 0);
1023 tty_background_highlight (tty
);
1024 buf
= tparam (multi
, 0, 0, i
);
1030 raw_cursor_to (f
, vpos
, 0);
1031 tty_background_highlight (tty
);
1033 OUTPUT (tty
, single
);
1034 if (tty
->TF_teleray
)
1039 tty_set_scroll_region (f
, vpos
, tty
->specified_window
);
1041 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
1043 raw_cursor_to (f
, vpos
, 0);
1044 tty_background_highlight (tty
);
1046 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1047 tty_set_scroll_region (f
, 0, tty
->specified_window
);
1050 if (!FRAME_SCROLL_REGION_OK (f
)
1051 && FRAME_MEMORY_BELOW_FRAME (f
)
1054 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
1059 /* Compute cost of sending "str", in characters,
1060 not counting any line-dependent padding. */
1063 string_cost (char *str
)
1067 tputs (str
, 0, evalcost
);
1071 /* Compute cost of sending "str", in characters,
1072 counting any line-dependent padding at one line. */
1075 string_cost_one_line (char *str
)
1079 tputs (str
, 1, evalcost
);
1083 /* Compute per line amount of line-dependent padding,
1084 in tenths of characters. */
1087 per_line_cost (char *str
)
1091 tputs (str
, 0, evalcost
);
1094 tputs (str
, 10, evalcost
);
1099 /* char_ins_del_cost[n] is cost of inserting N characters.
1100 char_ins_del_cost[-n] is cost of deleting N characters.
1101 The length of this vector is based on max_frame_cols. */
1103 int *char_ins_del_vector
;
1105 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1110 calculate_ins_del_char_costs (struct frame
*f
)
1112 struct tty_display_info
*tty
= FRAME_TTY (f
);
1113 int ins_startup_cost
, del_startup_cost
;
1114 int ins_cost_per_char
, del_cost_per_char
;
1118 if (tty
->TS_ins_multi_chars
)
1120 ins_cost_per_char
= 0;
1121 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1123 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1124 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1126 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1127 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1128 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1129 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1133 ins_startup_cost
= 9999;
1134 ins_cost_per_char
= 0;
1137 if (tty
->TS_del_multi_chars
)
1139 del_cost_per_char
= 0;
1140 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1142 else if (tty
->TS_del_char
)
1144 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1145 + string_cost (tty
->TS_end_delete_mode
));
1146 if (tty
->delete_in_insert_mode
)
1147 del_startup_cost
/= 2;
1148 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1152 del_startup_cost
= 9999;
1153 del_cost_per_char
= 0;
1156 /* Delete costs are at negative offsets */
1157 p
= &char_ins_del_cost (f
)[0];
1158 for (i
= FRAME_COLS (f
); --i
>= 0;)
1159 *--p
= (del_startup_cost
+= del_cost_per_char
);
1161 /* Doing nothing is free */
1162 p
= &char_ins_del_cost (f
)[0];
1165 /* Insert costs are at positive offsets */
1166 for (i
= FRAME_COLS (f
); --i
>= 0;)
1167 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1171 calculate_costs (struct frame
*frame
)
1173 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1175 if (FRAME_TERMCAP_P (frame
))
1177 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1178 register char *f
= (tty
->TS_set_scroll_region
1179 ? tty
->TS_set_scroll_region
1180 : tty
->TS_set_scroll_region_1
);
1182 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1186 /* These variables are only used for terminal stuff. They are
1187 allocated once for the terminal frame of X-windows emacs, but not
1190 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1191 X turns off char_ins_del_ok. */
1193 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1194 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1196 if (char_ins_del_vector
!= 0)
1198 = (int *) xrealloc (char_ins_del_vector
,
1200 + 2 * max_frame_cols
* sizeof (int)));
1203 = (int *) xmalloc (sizeof (int)
1204 + 2 * max_frame_cols
* sizeof (int));
1206 bzero (char_ins_del_vector
, (sizeof (int)
1207 + 2 * max_frame_cols
* sizeof (int)));
1210 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1211 do_line_insertion_deletion_costs (frame
,
1212 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1213 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1216 do_line_insertion_deletion_costs (frame
,
1217 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1218 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1221 calculate_ins_del_char_costs (frame
);
1223 /* Don't use TS_repeat if its padding is worse than sending the chars */
1224 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1225 tty
->RPov
= string_cost (tty
->TS_repeat
);
1227 tty
->RPov
= FRAME_COLS (frame
) * 2;
1229 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1237 /* Termcap capability names that correspond directly to X keysyms.
1238 Some of these (marked "terminfo") aren't supplied by old-style
1239 (Berkeley) termcap entries. They're listed in X keysym order;
1240 except we put the keypad keys first, so that if they clash with
1241 other keys (as on the IBM PC keyboard) they get overridden.
1244 static struct fkey_table keys
[] =
1246 {"kh", "home"}, /* termcap */
1247 {"kl", "left"}, /* termcap */
1248 {"ku", "up"}, /* termcap */
1249 {"kr", "right"}, /* termcap */
1250 {"kd", "down"}, /* termcap */
1251 {"%8", "prior"}, /* terminfo */
1252 {"%5", "next"}, /* terminfo */
1253 {"@7", "end"}, /* terminfo */
1254 {"@1", "begin"}, /* terminfo */
1255 {"*6", "select"}, /* terminfo */
1256 {"%9", "print"}, /* terminfo */
1257 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1259 * "insert" --- see below
1261 {"&8", "undo"}, /* terminfo */
1262 {"%0", "redo"}, /* terminfo */
1263 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1264 {"@0", "find"}, /* terminfo */
1265 {"@2", "cancel"}, /* terminfo */
1266 {"%1", "help"}, /* terminfo */
1268 * "break" goes here, but can't be reliably intercepted with termcap
1270 {"&4", "reset"}, /* terminfo --- actually `restart' */
1272 * "system" and "user" --- no termcaps
1274 {"kE", "clearline"}, /* terminfo */
1275 {"kA", "insertline"}, /* terminfo */
1276 {"kL", "deleteline"}, /* terminfo */
1277 {"kI", "insertchar"}, /* terminfo */
1278 {"kD", "deletechar"}, /* terminfo */
1279 {"kB", "backtab"}, /* terminfo */
1281 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1283 {"@8", "kp-enter"}, /* terminfo */
1285 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1286 * "kp-multiply", "kp-add", "kp-separator",
1287 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1288 * --- no termcaps for any of these.
1290 {"K4", "kp-1"}, /* terminfo */
1292 * "kp-2" --- no termcap
1294 {"K5", "kp-3"}, /* terminfo */
1296 * "kp-4" --- no termcap
1298 {"K2", "kp-5"}, /* terminfo */
1300 * "kp-6" --- no termcap
1302 {"K1", "kp-7"}, /* terminfo */
1304 * "kp-8" --- no termcap
1306 {"K3", "kp-9"}, /* terminfo */
1308 * "kp-equal" --- no termcap
1320 {"&0", "S-cancel"}, /*shifted cancel key*/
1321 {"&9", "S-begin"}, /*shifted begin key*/
1322 {"*0", "S-find"}, /*shifted find key*/
1323 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1324 {"*4", "S-delete"}, /*shifted delete-character key*/
1325 {"*7", "S-end"}, /*shifted end key*/
1326 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1327 {"#1", "S-help"}, /*shifted help key*/
1328 {"#2", "S-home"}, /*shifted home key*/
1329 {"#3", "S-insert"}, /*shifted insert-character key*/
1330 {"#4", "S-left"}, /*shifted left-arrow key*/
1331 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1332 {"%c", "S-next"}, /*shifted next key*/
1333 {"%e", "S-prior"}, /*shifted previous key*/
1334 {"%f", "S-print"}, /*shifted print key*/
1335 {"%g", "S-redo"}, /*shifted redo key*/
1336 {"%i", "S-right"}, /*shifted right-arrow key*/
1337 {"!3", "S-undo"} /*shifted undo key*/
1340 static char **term_get_fkeys_address
;
1341 static KBOARD
*term_get_fkeys_kboard
;
1342 static Lisp_Object
term_get_fkeys_1 ();
1344 /* Find the escape codes sent by the function keys for Vinput_decode_map.
1345 This function scans the termcap function key sequence entries, and
1346 adds entries to Vinput_decode_map for each function key it finds. */
1349 term_get_fkeys (address
, kboard
)
1353 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1354 errors during the call. The only errors should be from Fdefine_key
1355 when given a key sequence containing an invalid prefix key. If the
1356 termcap defines function keys which use a prefix that is already bound
1357 to a command by the default bindings, we should silently ignore that
1358 function key specification, rather than giving the user an error and
1359 refusing to run at all on such a terminal. */
1361 extern Lisp_Object
Fidentity ();
1362 term_get_fkeys_address
= address
;
1363 term_get_fkeys_kboard
= kboard
;
1364 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1372 char **address
= term_get_fkeys_address
;
1373 KBOARD
*kboard
= term_get_fkeys_kboard
;
1375 /* This can happen if CANNOT_DUMP or with strange options. */
1376 if (!KEYMAPP (kboard
->Vinput_decode_map
))
1377 kboard
->Vinput_decode_map
= Fmake_sparse_keymap (Qnil
);
1379 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1381 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1383 Fdefine_key (kboard
->Vinput_decode_map
, build_string (sequence
),
1384 Fmake_vector (make_number (1),
1385 intern (keys
[i
].name
)));
1388 /* The uses of the "k0" capability are inconsistent; sometimes it
1389 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1390 We will attempt to politely accommodate both systems by testing for
1391 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1394 char *k_semi
= tgetstr ("k;", address
);
1395 char *k0
= tgetstr ("k0", address
);
1396 char *k0_name
= "f10";
1401 /* Define f0 first, so that f10 takes precedence in case the
1402 key sequences happens to be the same. */
1403 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k0
),
1404 Fmake_vector (make_number (1), intern ("f0")));
1405 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k_semi
),
1406 Fmake_vector (make_number (1), intern ("f10")));
1409 Fdefine_key (kboard
->Vinput_decode_map
, build_string (k0
),
1410 Fmake_vector (make_number (1), intern (k0_name
)));
1413 /* Set up cookies for numbered function keys above f10. */
1415 char fcap
[3], fkey
[4];
1417 fcap
[0] = 'F'; fcap
[2] = '\0';
1418 for (i
= 11; i
< 64; i
++)
1421 fcap
[1] = '1' + i
- 11;
1423 fcap
[1] = 'A' + i
- 20;
1425 fcap
[1] = 'a' + i
- 46;
1428 char *sequence
= tgetstr (fcap
, address
);
1431 sprintf (fkey
, "f%d", i
);
1432 Fdefine_key (kboard
->Vinput_decode_map
, build_string (sequence
),
1433 Fmake_vector (make_number (1),
1441 * Various mappings to try and get a better fit.
1444 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1445 if (!tgetstr (cap1, address)) \
1447 char *sequence = tgetstr (cap2, address); \
1449 Fdefine_key (kboard->Vinput_decode_map, build_string (sequence), \
1450 Fmake_vector (make_number (1), \
1454 /* if there's no key_next keycap, map key_npage to `next' keysym */
1455 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1456 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1457 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1458 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1459 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1460 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1461 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1463 /* IBM has their own non-standard dialect of terminfo.
1464 If the standard name isn't found, try the IBM name. */
1465 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1466 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1467 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1468 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1469 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1470 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1471 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1472 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1473 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1474 #undef CONDITIONAL_REASSIGN
1481 /***********************************************************************
1482 Character Display Information
1483 ***********************************************************************/
1485 /* Avoid name clash with functions defined in xterm.c */
1487 #define append_glyph append_glyph_term
1488 #define produce_stretch_glyph produce_stretch_glyph_term
1489 #define append_composite_glyph append_composite_glyph_term
1490 #define produce_composite_glyph produce_composite_glyph_term
1493 static void append_glyph
P_ ((struct it
*));
1494 static void produce_stretch_glyph
P_ ((struct it
*));
1495 static void append_composite_glyph
P_ ((struct it
*));
1496 static void produce_composite_glyph
P_ ((struct it
*));
1498 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1499 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1500 the character for which to produce glyphs; IT->face_id contains the
1501 character's face. Padding glyphs are appended if IT->c has a
1502 IT->pixel_width > 1. */
1508 struct glyph
*glyph
, *end
;
1511 xassert (it
->glyph_row
);
1512 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1513 + it
->glyph_row
->used
[it
->area
]);
1514 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1517 i
< it
->pixel_width
&& glyph
< end
;
1520 glyph
->type
= CHAR_GLYPH
;
1521 glyph
->pixel_width
= 1;
1522 glyph
->u
.ch
= it
->char_to_display
;
1523 glyph
->face_id
= it
->face_id
;
1524 glyph
->padding_p
= i
> 0;
1525 glyph
->charpos
= CHARPOS (it
->position
);
1526 glyph
->object
= it
->object
;
1528 ++it
->glyph_row
->used
[it
->area
];
1534 /* Produce glyphs for the display element described by IT. *IT
1535 specifies what we want to produce a glyph for (character, image, ...),
1536 and where in the glyph matrix we currently are (glyph row and hpos).
1537 produce_glyphs fills in output fields of *IT with information such as the
1538 pixel width and height of a character, and maybe output actual glyphs at
1539 the same time if IT->glyph_row is non-null. See the explanation of
1540 struct display_iterator in dispextern.h for an overview.
1542 produce_glyphs also stores the result of glyph width, ascent
1543 etc. computations in *IT.
1545 IT->glyph_row may be null, in which case produce_glyphs does not
1546 actually fill in the glyphs. This is used in the move_* functions
1547 in xdisp.c for text width and height computations.
1549 Callers usually don't call produce_glyphs directly;
1550 instead they use the macro PRODUCE_GLYPHS. */
1556 /* If a hook is installed, let it do the work. */
1558 /* Nothing but characters are supported on terminal frames. */
1559 xassert (it
->what
== IT_CHARACTER
1560 || it
->what
== IT_COMPOSITION
1561 || it
->what
== IT_STRETCH
);
1563 if (it
->what
== IT_STRETCH
)
1565 produce_stretch_glyph (it
);
1569 if (it
->what
== IT_COMPOSITION
)
1571 produce_composite_glyph (it
);
1575 /* Maybe translate single-byte characters to multibyte. */
1576 it
->char_to_display
= it
->c
;
1578 if (it
->c
>= 040 && it
->c
< 0177)
1580 it
->pixel_width
= it
->nglyphs
= 1;
1584 else if (it
->c
== '\n')
1585 it
->pixel_width
= it
->nglyphs
= 0;
1586 else if (it
->c
== '\t')
1588 int absolute_x
= (it
->current_x
1589 + it
->continuation_lines_width
);
1591 = (((1 + absolute_x
+ it
->tab_width
- 1)
1596 /* If part of the TAB has been displayed on the previous line
1597 which is continued now, continuation_lines_width will have
1598 been incremented already by the part that fitted on the
1599 continued line. So, we will get the right number of spaces
1601 nspaces
= next_tab_x
- absolute_x
;
1607 it
->char_to_display
= ' ';
1608 it
->pixel_width
= it
->len
= 1;
1614 it
->pixel_width
= nspaces
;
1615 it
->nglyphs
= nspaces
;
1617 else if (CHAR_BYTE8_P (it
->c
))
1619 if (unibyte_display_via_language_environment
1622 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1623 it
->pixel_width
= CHAR_WIDTH (it
->char_to_display
);
1624 it
->nglyphs
= it
->pixel_width
;
1630 /* Coming here means that it->c is from display table, thus
1631 we must send the raw 8-bit byte as is to the terminal.
1632 Although there's no way to know how many columns it
1633 occupies on a screen, it is a good assumption that a
1634 single byte code has 1-column width. */
1635 it
->pixel_width
= it
->nglyphs
= 1;
1642 it
->pixel_width
= CHAR_WIDTH (it
->c
);
1643 it
->nglyphs
= it
->pixel_width
;
1650 /* Advance current_x by the pixel width as a convenience for
1652 if (it
->area
== TEXT_AREA
)
1653 it
->current_x
+= it
->pixel_width
;
1654 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1655 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1659 /* Produce a stretch glyph for iterator IT. IT->object is the value
1660 of the glyph property displayed. The value must be a list
1661 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1664 1. `:width WIDTH' specifies that the space should be WIDTH *
1665 canonical char width wide. WIDTH may be an integer or floating
1668 2. `:align-to HPOS' specifies that the space should be wide enough
1669 to reach HPOS, a value in canonical character units. */
1672 produce_stretch_glyph (it
)
1675 /* (space :width WIDTH ...) */
1676 Lisp_Object prop
, plist
;
1677 int width
= 0, align_to
= -1;
1678 int zero_width_ok_p
= 0;
1681 /* List should start with `space'. */
1682 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1683 plist
= XCDR (it
->object
);
1685 /* Compute the width of the stretch. */
1686 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1687 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1689 /* Absolute width `:width WIDTH' specified and valid. */
1690 zero_width_ok_p
= 1;
1691 width
= (int)(tem
+ 0.5);
1693 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1694 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1696 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1697 align_to
= (align_to
< 0
1699 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1700 else if (align_to
< 0)
1701 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1702 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1703 zero_width_ok_p
= 1;
1706 /* Nothing specified -> width defaults to canonical char width. */
1707 width
= FRAME_COLUMN_WIDTH (it
->f
);
1709 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1712 if (width
> 0 && it
->glyph_row
)
1714 Lisp_Object o_object
= it
->object
;
1715 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1718 if (!STRINGP (object
))
1719 object
= it
->w
->buffer
;
1720 it
->object
= object
;
1721 it
->char_to_display
= ' ';
1722 it
->pixel_width
= it
->len
= 1;
1725 it
->object
= o_object
;
1727 it
->pixel_width
= width
;
1728 it
->nglyphs
= width
;
1732 /* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
1733 Called from produce_composite_glyph for terminal frames if
1734 IT->glyph_row != NULL. IT->face_id contains the character's
1738 append_composite_glyph (it
)
1741 struct glyph
*glyph
;
1743 xassert (it
->glyph_row
);
1744 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
1745 if (glyph
< it
->glyph_row
->glyphs
[1 + it
->area
])
1747 glyph
->type
= COMPOSITE_GLYPH
;
1748 glyph
->pixel_width
= it
->pixel_width
;
1749 glyph
->u
.cmp_id
= it
->cmp_id
;
1750 glyph
->face_id
= it
->face_id
;
1751 glyph
->padding_p
= 0;
1752 glyph
->charpos
= CHARPOS (it
->position
);
1753 glyph
->object
= it
->object
;
1755 ++it
->glyph_row
->used
[it
->area
];
1761 /* Produce a composite glyph for iterator IT. IT->cmp_id is the ID of
1762 the composition. We simply produces components of the composition
1763 assuming that that the terminal has a capability to layout/render
1767 produce_composite_glyph (it
)
1770 struct composition
*cmp
= composition_table
[it
->cmp_id
];
1773 xassert (cmp
->glyph_len
> 0);
1774 c
= COMPOSITION_GLYPH (cmp
, 0);
1775 it
->pixel_width
= CHAR_WIDTH (it
->c
);
1779 append_composite_glyph (it
);
1783 /* Get information about special display element WHAT in an
1784 environment described by IT. WHAT is one of IT_TRUNCATION or
1785 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1786 non-null glyph_row member. This function ensures that fields like
1787 face_id, c, len of IT are left untouched. */
1790 produce_special_glyphs (it
, what
)
1792 enum display_element_type what
;
1799 temp_it
.what
= IT_CHARACTER
;
1801 temp_it
.object
= make_number (0);
1802 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1804 if (what
== IT_CONTINUATION
)
1806 /* Continuation glyph. */
1808 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1809 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1811 glyph
= XINT (DISP_CONTINUE_GLYPH (it
->dp
));
1812 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
1817 else if (what
== IT_TRUNCATION
)
1819 /* Truncation glyph. */
1821 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1822 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1824 glyph
= XINT (DISP_TRUNC_GLYPH (it
->dp
));
1825 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
1833 temp_it
.c
= FAST_GLYPH_CHAR (glyph
);
1834 temp_it
.face_id
= FAST_GLYPH_FACE (glyph
);
1835 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1837 produce_glyphs (&temp_it
);
1838 it
->pixel_width
= temp_it
.pixel_width
;
1839 it
->nglyphs
= temp_it
.pixel_width
;
1844 /***********************************************************************
1846 ***********************************************************************/
1848 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1849 one of the enumerators from enum no_color_bit, or a bit set built
1850 from them. Some display attributes may not be used together with
1851 color; the termcap capability `NC' specifies which ones. */
1853 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1854 (tty->TN_max_colors > 0 \
1855 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1858 /* Turn appearances of face FACE_ID on tty frame F on.
1859 FACE_ID is a realized face ID number, in the face cache. */
1862 turn_on_face (f
, face_id
)
1866 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1867 long fg
= face
->foreground
;
1868 long bg
= face
->background
;
1869 struct tty_display_info
*tty
= FRAME_TTY (f
);
1871 /* Do this first because TS_end_standout_mode may be the same
1872 as TS_exit_attribute_mode, which turns all appearances off. */
1873 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1875 if (tty
->TN_max_colors
> 0)
1877 if (fg
>= 0 && bg
>= 0)
1879 /* If the terminal supports colors, we can set them
1880 below without using reverse video. The face's fg
1881 and bg colors are set as they should appear on
1882 the screen, i.e. they take the inverse-video'ness
1883 of the face already into account. */
1885 else if (inverse_video
)
1887 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1888 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1889 tty_toggle_highlight (tty
);
1893 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1894 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1895 tty_toggle_highlight (tty
);
1900 /* If we can't display colors, use reverse video
1901 if the face specifies that. */
1904 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1905 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1906 tty_toggle_highlight (tty
);
1910 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1911 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1912 tty_toggle_highlight (tty
);
1917 if (face
->tty_bold_p
)
1919 if (MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1920 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1922 else if (face
->tty_dim_p
)
1923 if (MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1924 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1926 /* Alternate charset and blinking not yet used. */
1927 if (face
->tty_alt_charset_p
1928 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1929 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1931 if (face
->tty_blinking_p
1932 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1933 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1935 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1936 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1938 if (tty
->TN_max_colors
> 0)
1942 ts
= tty
->standout_mode
? tty
->TS_set_background
: tty
->TS_set_foreground
;
1945 p
= tparam (ts
, NULL
, 0, (int) fg
);
1950 ts
= tty
->standout_mode
? tty
->TS_set_foreground
: tty
->TS_set_background
;
1953 p
= tparam (ts
, NULL
, 0, (int) bg
);
1961 /* Turn off appearances of face FACE_ID on tty frame F. */
1964 turn_off_face (f
, face_id
)
1968 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1969 struct tty_display_info
*tty
= FRAME_TTY (f
);
1971 xassert (face
!= NULL
);
1973 if (tty
->TS_exit_attribute_mode
)
1975 /* Capability "me" will turn off appearance modes double-bright,
1976 half-bright, reverse-video, standout, underline. It may or
1977 may not turn off alt-char-mode. */
1978 if (face
->tty_bold_p
1980 || face
->tty_reverse_p
1981 || face
->tty_alt_charset_p
1982 || face
->tty_blinking_p
1983 || face
->tty_underline_p
)
1985 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
1986 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
1987 tty
->standout_mode
= 0;
1990 if (face
->tty_alt_charset_p
)
1991 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1995 /* If we don't have "me" we can only have those appearances
1996 that have exit sequences defined. */
1997 if (face
->tty_alt_charset_p
)
1998 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
2000 if (face
->tty_underline_p
)
2001 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
2004 /* Switch back to default colors. */
2005 if (tty
->TN_max_colors
> 0
2006 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2007 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2008 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2009 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2010 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
2014 /* Return non-zero if the terminal on frame F supports all of the
2015 capabilities in CAPS simultaneously, with foreground and background
2016 colors FG and BG. */
2019 tty_capable_p (tty
, caps
, fg
, bg
)
2020 struct tty_display_info
*tty
;
2022 unsigned long fg
, bg
;
2024 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
2025 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
2028 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
2029 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
2030 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
2031 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
2032 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
2033 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
2039 /* Return non-zero if the terminal is capable to display colors. */
2041 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2043 doc
: /* Return non-nil if the tty device TERMINAL can display colors.
2045 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2046 frame's terminal). This function always returns nil if TERMINAL
2047 is not on a tty device. */)
2049 Lisp_Object terminal
;
2051 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2055 return t
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
2058 /* Return the number of supported colors. */
2059 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2060 Stty_display_color_cells
, 0, 1, 0,
2061 doc
: /* Return the number of colors supported by the tty device TERMINAL.
2063 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2064 frame's terminal). This function always returns 0 if TERMINAL
2065 is not on a tty device. */)
2067 Lisp_Object terminal
;
2069 struct terminal
*t
= get_tty_terminal (terminal
, 0);
2071 return make_number (0);
2073 return make_number (t
->display_info
.tty
->TN_max_colors
);
2078 /* Declare here rather than in the function, as in the rest of Emacs,
2079 to work around an HPUX compiler bug (?). See
2080 http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00410.html */
2081 static int default_max_colors
;
2082 static int default_max_pairs
;
2083 static int default_no_color_video
;
2084 static char *default_orig_pair
;
2085 static char *default_set_foreground
;
2086 static char *default_set_background
;
2088 /* Save or restore the default color-related capabilities of this
2091 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
2096 if (default_orig_pair
)
2097 xfree (default_orig_pair
);
2098 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
2100 if (default_set_foreground
)
2101 xfree (default_set_foreground
);
2102 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
2105 if (default_set_background
)
2106 xfree (default_set_background
);
2107 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
2110 default_max_colors
= tty
->TN_max_colors
;
2111 default_max_pairs
= tty
->TN_max_pairs
;
2112 default_no_color_video
= tty
->TN_no_color_video
;
2116 tty
->TS_orig_pair
= default_orig_pair
;
2117 tty
->TS_set_foreground
= default_set_foreground
;
2118 tty
->TS_set_background
= default_set_background
;
2119 tty
->TN_max_colors
= default_max_colors
;
2120 tty
->TN_max_pairs
= default_max_pairs
;
2121 tty
->TN_no_color_video
= default_no_color_video
;
2125 /* Setup one of the standard tty color schemes according to MODE.
2126 MODE's value is generally the number of colors which we want to
2127 support; zero means set up for the default capabilities, the ones
2128 we saw at init_tty time; -1 means turn off color support. */
2130 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2132 /* Canonicalize all negative values of MODE. */
2138 case -1: /* no colors at all */
2139 tty
->TN_max_colors
= 0;
2140 tty
->TN_max_pairs
= 0;
2141 tty
->TN_no_color_video
= 0;
2142 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2144 case 0: /* default colors, if any */
2146 tty_default_color_capabilities (tty
, 0);
2148 case 8: /* 8 standard ANSI colors */
2149 tty
->TS_orig_pair
= "\033[0m";
2151 tty
->TS_set_foreground
= "\033[3%p1%dm";
2152 tty
->TS_set_background
= "\033[4%p1%dm";
2154 tty
->TS_set_foreground
= "\033[3%dm";
2155 tty
->TS_set_background
= "\033[4%dm";
2157 tty
->TN_max_colors
= 8;
2158 tty
->TN_max_pairs
= 64;
2159 tty
->TN_no_color_video
= 0;
2165 set_tty_color_mode (f
, val
)
2169 Lisp_Object color_mode_spec
, current_mode_spec
;
2170 Lisp_Object color_mode
, current_mode
;
2172 extern Lisp_Object Qtty_color_mode
;
2173 Lisp_Object tty_color_mode_alist
;
2175 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2182 if (NILP (tty_color_mode_alist
))
2183 color_mode_spec
= Qnil
;
2185 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2187 if (CONSP (color_mode_spec
))
2188 color_mode
= XCDR (color_mode_spec
);
2193 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2195 if (CONSP (current_mode_spec
))
2196 current_mode
= XCDR (current_mode_spec
);
2198 current_mode
= Qnil
;
2199 if (INTEGERP (color_mode
))
2200 mode
= XINT (color_mode
);
2202 mode
= 0; /* meaning default */
2203 if (INTEGERP (current_mode
))
2204 old_mode
= XINT (current_mode
);
2208 if (mode
!= old_mode
)
2210 tty_setup_colors (FRAME_TTY (f
), mode
);
2211 /* This recomputes all the faces given the new color
2213 call0 (intern ("tty-set-up-initial-frame-faces"));
2218 #endif /* !WINDOWSNT */
2222 /* Return the tty display object specified by TERMINAL. */
2225 get_tty_terminal (Lisp_Object terminal
, int throw)
2227 struct terminal
*t
= get_terminal (terminal
, throw);
2229 if (t
&& t
->type
!= output_termcap
)
2232 error ("Device %d is not a termcap terminal device", t
->id
);
2240 /* Return an active termcap device that uses the tty device with the
2243 This function ignores suspended devices.
2245 Returns NULL if the named terminal device is not opened. */
2248 get_named_tty (name
)
2256 for (t
= terminal_list
; t
; t
= t
->next_terminal
)
2258 if (t
->type
== output_termcap
2259 && !strcmp (t
->display_info
.tty
->name
, name
)
2260 && TERMINAL_ACTIVE_P (t
))
2268 DEFUN ("tty-type", Ftty_type
, Stty_type
, 0, 1, 0,
2269 doc
: /* Return the type of the tty device that TERMINAL uses.
2270 Returns nil if TERMINAL is not on a tty device.
2272 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2273 frame's terminal). */)
2275 Lisp_Object terminal
;
2277 struct terminal
*t
= get_terminal (terminal
, 1);
2279 if (t
->type
!= output_termcap
)
2282 if (t
->display_info
.tty
->type
)
2283 return build_string (t
->display_info
.tty
->type
);
2288 DEFUN ("controlling-tty-p", Fcontrolling_tty_p
, Scontrolling_tty_p
, 0, 1, 0,
2289 doc
: /* Return non-nil if TERMINAL is on the controlling tty of the Emacs process.
2291 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2292 frame's terminal). This function always returns nil if TERMINAL
2293 is not on a tty device. */)
2295 Lisp_Object terminal
;
2297 struct terminal
*t
= get_terminal (terminal
, 1);
2299 if (t
->type
!= output_termcap
|| strcmp (t
->display_info
.tty
->name
, DEV_TTY
))
2305 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 1, 0,
2306 doc
: /* Declare that the tty used by TERMINAL does not handle underlining.
2307 This is used to override the terminfo data, for certain terminals that
2308 do not really do underlining, but say that they do. This function has
2309 no effect if used on a non-tty terminal.
2311 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2312 frame's terminal). This function always returns nil if TERMINAL
2313 is not on a tty device. */)
2315 Lisp_Object terminal
;
2317 struct terminal
*t
= get_terminal (terminal
, 1);
2319 if (t
->type
== output_termcap
)
2320 t
->display_info
.tty
->TS_enter_underline_mode
= 0;
2326 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
2327 doc
: /* Suspend the terminal device TTY.
2329 The device is restored to its default state, and Emacs ceases all
2330 access to the tty device. Frames that use the device are not deleted,
2331 but input is not read from them and if they change, their display is
2334 TTY may be a terminal id, a frame, or nil for the terminal device of
2335 the currently selected frame.
2337 This function runs `suspend-tty-functions' after suspending the
2338 device. The functions are run with one arg, the id of the suspended
2341 `suspend-tty' does nothing if it is called on a device that is already
2344 A suspended tty may be resumed by calling `resume-tty' on it. */)
2348 struct terminal
*t
= get_tty_terminal (tty
, 1);
2352 error ("Unknown tty device");
2354 f
= t
->display_info
.tty
->input
;
2358 /* First run `suspend-tty-functions' and then clean up the tty
2359 state because `suspend-tty-functions' might need to change
2361 if (!NILP (Vrun_hooks
))
2363 Lisp_Object args
[2];
2364 args
[0] = intern ("suspend-tty-functions");
2365 XSETTERMINAL (args
[1], t
);
2366 Frun_hook_with_args (2, args
);
2369 reset_sys_modes (t
->display_info
.tty
);
2371 delete_keyboard_wait_descriptor (fileno (f
));
2374 if (f
!= t
->display_info
.tty
->output
)
2375 fclose (t
->display_info
.tty
->output
);
2377 t
->display_info
.tty
->input
= 0;
2378 t
->display_info
.tty
->output
= 0;
2380 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2381 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 0);
2385 /* Clear display hooks to prevent further output. */
2386 clear_tty_hooks (t
);
2391 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
2392 doc
: /* Resume the previously suspended terminal device TTY.
2393 The terminal is opened and reinitialized. Frames that are on the
2394 suspended terminal are revived.
2396 It is an error to resume a terminal while another terminal is active
2399 This function runs `resume-tty-functions' after resuming the terminal.
2400 The functions are run with one arg, the id of the resumed terminal
2403 `resume-tty' does nothing if it is called on a device that is not
2406 TTY may be a terminal id, a frame, or nil for the terminal device of
2407 the currently selected frame. */)
2411 struct terminal
*t
= get_tty_terminal (tty
, 1);
2415 error ("Unknown tty device");
2417 if (!t
->display_info
.tty
->input
)
2419 if (get_named_tty (t
->display_info
.tty
->name
))
2420 error ("Cannot resume display while another display is active on the same device");
2422 fd
= emacs_open (t
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
2425 error ("Can not reopen tty device %s: %s", t
->display_info
.tty
->name
, strerror (errno
));
2427 if (strcmp (t
->display_info
.tty
->name
, DEV_TTY
))
2428 dissociate_if_controlling_tty (fd
);
2430 t
->display_info
.tty
->output
= fdopen (fd
, "w+");
2431 t
->display_info
.tty
->input
= t
->display_info
.tty
->output
;
2433 add_keyboard_wait_descriptor (fd
);
2435 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2436 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 1);
2438 init_sys_modes (t
->display_info
.tty
);
2440 /* Run `resume-tty-functions'. */
2441 if (!NILP (Vrun_hooks
))
2443 Lisp_Object args
[2];
2444 args
[0] = intern ("resume-tty-functions");
2445 XSETTERMINAL (args
[1], t
);
2446 Frun_hook_with_args (2, args
);
2456 /***********************************************************************
2458 ***********************************************************************/
2462 term_mouse_moveto (int x
, int y
)
2464 /* TODO: how to set mouse position?
2467 name = (const char *) ttyname (0);
2468 fd = open (name, O_WRONLY);
2469 SOME_FUNCTION (x, y, fd);
2472 last_mouse_y = y; */
2476 term_show_mouse_face (enum draw_glyphs_face draw
)
2478 struct window
*w
= XWINDOW (mouse_face_window
);
2482 struct frame
*f
= XFRAME (w
->frame
);
2483 struct tty_display_info
*tty
= FRAME_TTY (f
);
2485 if (/* If window is in the process of being destroyed, don't bother
2487 w
->current_matrix
!= NULL
2488 /* Recognize when we are called to operate on rows that don't exist
2489 anymore. This can happen when a window is split. */
2490 && mouse_face_end_row
< w
->current_matrix
->nrows
)
2492 /* write_glyphs writes at cursor position, so we need to
2493 temporarily move cursor coordinates to the beginning of
2494 the highlight region. */
2496 /* Save current cursor co-ordinates */
2497 save_y
= curY (tty
);
2498 save_x
= curX (tty
);
2500 /* Note that mouse_face_beg_row etc. are window relative. */
2501 for (i
= mouse_face_beg_row
; i
<= mouse_face_end_row
; i
++)
2503 int start_hpos
, end_hpos
, nglyphs
;
2504 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
2506 /* Don't do anything if row doesn't have valid contents. */
2507 if (!row
->enabled_p
)
2510 /* For all but the first row, the highlight starts at column 0. */
2511 if (i
== mouse_face_beg_row
)
2512 start_hpos
= mouse_face_beg_col
;
2516 if (i
== mouse_face_end_row
)
2517 end_hpos
= mouse_face_end_col
;
2520 end_hpos
= row
->used
[TEXT_AREA
];
2521 if (draw
== DRAW_NORMAL_TEXT
)
2522 row
->fill_line_p
= 1; /* Clear to end of line */
2525 if (end_hpos
<= start_hpos
)
2527 /* Record that some glyphs of this row are displayed in
2529 row
->mouse_face_p
= draw
> 0;
2531 nglyphs
= end_hpos
- start_hpos
;
2533 if (end_hpos
>= row
->used
[TEXT_AREA
])
2534 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2536 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2537 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
2538 + WINDOW_LEFT_EDGE_X (w
);
2540 cursor_to (f
, pos_y
, pos_x
);
2542 if (draw
== DRAW_MOUSE_FACE
)
2544 tty_write_glyphs_with_face (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
,
2545 nglyphs
, mouse_face_face_id
);
2547 else /* draw == DRAW_NORMAL_TEXT */
2548 write_glyphs (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2550 cursor_to (f
, save_y
, save_x
);
2555 term_clear_mouse_face ()
2557 if (!NILP (mouse_face_window
))
2558 term_show_mouse_face (DRAW_NORMAL_TEXT
);
2560 mouse_face_beg_row
= mouse_face_beg_col
= -1;
2561 mouse_face_end_row
= mouse_face_end_col
= -1;
2562 mouse_face_window
= Qnil
;
2565 /* Find the glyph matrix position of buffer position POS in window W.
2566 *HPOS and *VPOS are set to the positions found. W's current glyphs
2567 must be up to date. If POS is above window start return (0, 0).
2568 If POS is after end of W, return end of last line in W.
2569 - taken from msdos.c */
2571 fast_find_position (struct window
*w
, int pos
, int *hpos
, int *vpos
)
2573 int i
, lastcol
, line_start_position
, maybe_next_line_p
= 0;
2574 int yb
= window_text_bottom_y (w
);
2575 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0), *best_row
= row
;
2579 if (row
->used
[TEXT_AREA
])
2580 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
2582 line_start_position
= 0;
2584 if (line_start_position
> pos
)
2586 /* If the position sought is the end of the buffer,
2587 don't include the blank lines at the bottom of the window. */
2588 else if (line_start_position
== pos
2589 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
2591 maybe_next_line_p
= 1;
2594 else if (line_start_position
> 0)
2597 /* Don't overstep the last matrix row, lest we get into the
2598 never-never land... */
2599 if (row
->y
+ 1 >= yb
)
2605 /* Find the right column within BEST_ROW. */
2608 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
2610 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + i
;
2613 charpos
= glyph
->charpos
;
2620 else if (charpos
> pos
)
2622 else if (charpos
> 0)
2626 /* If we're looking for the end of the buffer,
2627 and we didn't find it in the line we scanned,
2628 use the start of the following line. */
2629 if (maybe_next_line_p
)
2636 *hpos
= lastcol
+ 1;
2641 term_mouse_highlight (struct frame
*f
, int x
, int y
)
2643 enum window_part part
;
2648 if (NILP (Vmouse_highlight
)
2649 || !f
->glyphs_initialized_p
)
2652 /* Which window is that in? */
2653 window
= window_from_coordinates (f
, x
, y
, &part
, &x
, &y
, 0);
2655 /* Not on a window -> return. */
2656 if (!WINDOWP (window
))
2659 if (!EQ (window
, mouse_face_window
))
2660 term_clear_mouse_face ();
2662 w
= XWINDOW (window
);
2664 /* Are we in a window whose display is up to date?
2665 And verify the buffer's text has not changed. */
2666 b
= XBUFFER (w
->buffer
);
2668 && EQ (w
->window_end_valid
, w
->buffer
)
2669 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
2670 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
2672 int pos
, i
, nrows
= w
->current_matrix
->nrows
;
2673 struct glyph_row
*row
;
2674 struct glyph
*glyph
;
2676 /* Find the glyph under X/Y. */
2678 if (y
>= 0 && y
< nrows
)
2680 row
= MATRIX_ROW (w
->current_matrix
, y
);
2681 /* Give up if some row before the one we are looking for is
2683 for (i
= 0; i
<= y
; i
++)
2684 if (!MATRIX_ROW (w
->current_matrix
, i
)->enabled_p
)
2686 if (i
> y
/* all rows upto and including the one at Y are enabled */
2687 && row
->displays_text_p
2688 && x
< window_box_width (w
, TEXT_AREA
))
2690 glyph
= row
->glyphs
[TEXT_AREA
];
2691 if (x
>= row
->used
[TEXT_AREA
])
2696 if (!BUFFERP (glyph
->object
))
2702 /* Clear mouse face if X/Y not over text. */
2705 term_clear_mouse_face ();
2709 if (!BUFFERP (glyph
->object
))
2711 pos
= glyph
->charpos
;
2713 /* Check for mouse-face. */
2715 extern Lisp_Object Qmouse_face
;
2716 Lisp_Object mouse_face
, overlay
, position
, *overlay_vec
;
2717 int noverlays
, obegv
, ozv
;
2718 struct buffer
*obuf
;
2720 /* If we get an out-of-range value, return now; avoid an error. */
2721 if (pos
> BUF_Z (b
))
2724 /* Make the window's buffer temporarily current for
2725 overlays_at and compute_char_face. */
2726 obuf
= current_buffer
;
2733 /* Is this char mouse-active? */
2734 XSETINT (position
, pos
);
2736 /* Put all the overlays we want in a vector in overlay_vec. */
2737 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
2738 /* Sort overlays into increasing priority order. */
2739 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
2741 /* Check mouse-face highlighting. */
2742 if (!(EQ (window
, mouse_face_window
)
2743 && y
>= mouse_face_beg_row
2744 && y
<= mouse_face_end_row
2745 && (y
> mouse_face_beg_row
2746 || x
>= mouse_face_beg_col
)
2747 && (y
< mouse_face_end_row
2748 || x
< mouse_face_end_col
2749 || mouse_face_past_end
)))
2751 /* Clear the display of the old active region, if any. */
2752 term_clear_mouse_face ();
2754 /* Find the highest priority overlay that has a mouse-face
2757 for (i
= noverlays
- 1; i
>= 0; --i
)
2759 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
2760 if (!NILP (mouse_face
))
2762 overlay
= overlay_vec
[i
];
2767 /* If no overlay applies, get a text property. */
2769 mouse_face
= Fget_text_property (position
, Qmouse_face
,
2772 /* Handle the overlay case. */
2773 if (!NILP (overlay
))
2775 /* Find the range of text around this char that
2776 should be active. */
2777 Lisp_Object before
, after
;
2781 before
= Foverlay_start (overlay
);
2782 after
= Foverlay_end (overlay
);
2783 /* Record this as the current active region. */
2784 fast_find_position (w
, XFASTINT (before
),
2785 &mouse_face_beg_col
,
2786 &mouse_face_beg_row
);
2789 = !fast_find_position (w
, XFASTINT (after
),
2790 &mouse_face_end_col
,
2791 &mouse_face_end_row
);
2792 mouse_face_window
= window
;
2795 = face_at_buffer_position (w
, pos
, 0, 0,
2796 &ignore
, pos
+ 1, 1);
2798 /* Display it as active. */
2799 term_show_mouse_face (DRAW_MOUSE_FACE
);
2801 /* Handle the text property case. */
2802 else if (!NILP (mouse_face
))
2804 /* Find the range of text around this char that
2805 should be active. */
2806 Lisp_Object before
, after
, beginning
, end
;
2809 beginning
= Fmarker_position (w
->start
);
2810 XSETINT (end
, (BUF_Z (b
) - XFASTINT (w
->window_end_pos
)));
2812 = Fprevious_single_property_change (make_number (pos
+ 1),
2814 w
->buffer
, beginning
);
2816 = Fnext_single_property_change (position
, Qmouse_face
,
2819 /* Record this as the current active region. */
2820 fast_find_position (w
, XFASTINT (before
),
2821 &mouse_face_beg_col
,
2822 &mouse_face_beg_row
);
2824 = !fast_find_position (w
, XFASTINT (after
),
2825 &mouse_face_end_col
,
2826 &mouse_face_end_row
);
2827 mouse_face_window
= window
;
2830 = face_at_buffer_position (w
, pos
, 0, 0,
2831 &ignore
, pos
+ 1, 1);
2833 /* Display it as active. */
2834 term_show_mouse_face (DRAW_MOUSE_FACE
);
2838 /* Look for a `help-echo' property. */
2841 extern Lisp_Object Qhelp_echo
;
2843 /* Check overlays first. */
2845 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
2847 overlay
= overlay_vec
[i
];
2848 help
= Foverlay_get (overlay
, Qhelp_echo
);
2853 help_echo_string
= help
;
2854 help_echo_window
= window
;
2855 help_echo_object
= overlay
;
2856 help_echo_pos
= pos
;
2858 /* Try text properties. */
2859 else if (NILP (help
)
2860 && ((STRINGP (glyph
->object
)
2861 && glyph
->charpos
>= 0
2862 && glyph
->charpos
< SCHARS (glyph
->object
))
2863 || (BUFFERP (glyph
->object
)
2864 && glyph
->charpos
>= BEGV
2865 && glyph
->charpos
< ZV
)))
2867 help
= Fget_text_property (make_number (glyph
->charpos
),
2868 Qhelp_echo
, glyph
->object
);
2871 help_echo_string
= help
;
2872 help_echo_window
= window
;
2873 help_echo_object
= glyph
->object
;
2874 help_echo_pos
= glyph
->charpos
;
2881 current_buffer
= obuf
;
2887 term_mouse_movement (FRAME_PTR frame
, Gpm_Event
*event
)
2889 /* Has the mouse moved off the glyph it was on at the last sighting? */
2890 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2892 frame
->mouse_moved
= 1;
2893 term_mouse_highlight (frame
, event
->x
, event
->y
);
2894 /* Remember which glyph we're now on. */
2895 last_mouse_x
= event
->x
;
2896 last_mouse_y
= event
->y
;
2902 /* Return the current position of the mouse.
2904 Set *f to the frame the mouse is in, or zero if the mouse is in no
2905 Emacs frame. If it is set to zero, all the other arguments are
2908 Set *bar_window to Qnil, and *x and *y to the column and
2909 row of the character cell the mouse is over.
2911 Set *time to the time the mouse was at the returned position.
2913 This clears mouse_moved until the next motion
2916 term_mouse_position (FRAME_PTR
*fp
, int insist
, Lisp_Object
*bar_window
,
2917 enum scroll_bar_part
*part
, Lisp_Object
*x
,
2918 Lisp_Object
*y
, unsigned long *time
)
2922 *fp
= SELECTED_FRAME ();
2923 (*fp
)->mouse_moved
= 0;
2928 XSETINT (*x
, last_mouse_x
);
2929 XSETINT (*y
, last_mouse_y
);
2930 gettimeofday(&now
, 0);
2931 *time
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2934 /* Prepare a mouse-event in *RESULT for placement in the input queue.
2936 If the event is a button press, then note that we have grabbed
2940 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
2946 result
->kind
= GPM_CLICK_EVENT
;
2947 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
2949 if (event
->buttons
& j
) {
2950 result
->code
= i
; /* button number */
2954 gettimeofday(&now
, 0);
2955 result
->timestamp
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2957 if (event
->type
& GPM_UP
)
2958 result
->modifiers
= up_modifier
;
2959 else if (event
->type
& GPM_DOWN
)
2960 result
->modifiers
= down_modifier
;
2962 result
->modifiers
= 0;
2964 if (event
->type
& GPM_SINGLE
)
2965 result
->modifiers
|= click_modifier
;
2967 if (event
->type
& GPM_DOUBLE
)
2968 result
->modifiers
|= double_modifier
;
2970 if (event
->type
& GPM_TRIPLE
)
2971 result
->modifiers
|= triple_modifier
;
2973 if (event
->type
& GPM_DRAG
)
2974 result
->modifiers
|= drag_modifier
;
2976 if (!(event
->type
& (GPM_MOVE
| GPM_DRAG
))) {
2979 if (event
->modifiers
& (1 << 0))
2980 result
->modifiers
|= shift_modifier
;
2983 if (event
->modifiers
& (1 << 2))
2984 result
->modifiers
|= ctrl_modifier
;
2986 /* 1 << KG_ALT || KG_ALTGR */
2987 if (event
->modifiers
& (1 << 3)
2988 || event
->modifiers
& (1 << 1))
2989 result
->modifiers
|= meta_modifier
;
2992 XSETINT (result
->x
, event
->x
);
2993 XSETINT (result
->y
, event
->y
);
2994 XSETFRAME (result
->frame_or_window
, f
);
3000 handle_one_term_event (struct tty_display_info
*tty
, Gpm_Event
*event
, struct input_event
* hold_quit
)
3002 struct frame
*f
= XFRAME (tty
->top_frame
);
3003 struct input_event ie
;
3011 if (event
->type
& (GPM_MOVE
| GPM_DRAG
)) {
3012 previous_help_echo_string
= help_echo_string
;
3013 help_echo_string
= Qnil
;
3015 Gpm_DrawPointer (event
->x
, event
->y
, fileno (tty
->output
));
3017 if (!term_mouse_movement (f
, event
))
3018 help_echo_string
= previous_help_echo_string
;
3020 /* If the contents of the global variable help_echo_string
3021 has changed, generate a HELP_EVENT. */
3022 if (!NILP (help_echo_string
)
3023 || !NILP (previous_help_echo_string
))
3030 term_mouse_click (&ie
, event
, f
);
3034 if (ie
.kind
!= NO_EVENT
)
3036 kbd_buffer_store_event_hold (&ie
, hold_quit
);
3041 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
3046 XSETFRAME (frame
, f
);
3050 gen_help_event (help_echo_string
, frame
, help_echo_window
,
3051 help_echo_object
, help_echo_pos
);
3058 DEFUN ("gpm-mouse-start", Fgpm_mouse_start
, Sgpm_mouse_start
,
3060 doc
: /* Open a connection to Gpm.
3061 Gpm-mouse can only be activated for one tty at a time. */)
3064 struct frame
*f
= SELECTED_FRAME ();
3065 struct tty_display_info
*tty
3066 = ((f
)->output_method
== output_termcap
3067 ? (f
)->terminal
->display_info
.tty
: NULL
);
3068 Gpm_Connect connection
;
3071 error ("Gpm-mouse only works in the GNU/Linux console");
3073 return Qnil
; /* Already activated, nothing to do. */
3075 error ("Gpm-mouse can only be activated for one tty at a time");
3077 connection
.eventMask
= ~0;
3078 connection
.defaultMask
= ~GPM_HARD
;
3079 connection
.maxMod
= ~0;
3080 connection
.minMod
= 0;
3083 if (Gpm_Open (&connection
, 0) < 0)
3084 error ("Gpm-mouse failed to connect to the gpm daemon");
3088 /* `init_sys_modes' arranges for mouse movements sent through gpm_fd
3089 to generate SIGIOs. Apparently we need to call reset_sys_modes
3090 before calling init_sys_modes. */
3091 reset_sys_modes (tty
);
3092 init_sys_modes (tty
);
3093 add_gpm_wait_descriptor (gpm_fd
);
3098 DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop
, Sgpm_mouse_stop
,
3100 doc
: /* Close a connection to Gpm. */)
3103 struct frame
*f
= SELECTED_FRAME ();
3104 struct tty_display_info
*tty
3105 = ((f
)->output_method
== output_termcap
3106 ? (f
)->terminal
->display_info
.tty
: NULL
);
3108 if (!tty
|| gpm_tty
!= tty
)
3109 return Qnil
; /* Not activated on this terminal, nothing to do. */
3112 delete_gpm_wait_descriptor (gpm_fd
);
3113 while (Gpm_Close()); /* close all the stack */
3117 #endif /* HAVE_GPM */
3120 /***********************************************************************
3122 ***********************************************************************/
3124 /* Initialize the tty-dependent part of frame F. The frame must
3125 already have its device initialized. */
3128 create_tty_output (struct frame
*f
)
3130 struct tty_output
*t
;
3132 if (! FRAME_TERMCAP_P (f
))
3135 t
= xmalloc (sizeof (struct tty_output
));
3136 bzero (t
, sizeof (struct tty_output
));
3138 t
->display_info
= FRAME_TERMINAL (f
)->display_info
.tty
;
3140 f
->output_data
.tty
= t
;
3143 /* Delete the tty-dependent part of frame F. */
3146 delete_tty_output (struct frame
*f
)
3148 if (! FRAME_TERMCAP_P (f
))
3151 xfree (f
->output_data
.tty
);
3155 /* Reset the hooks in TERMINAL. */
3158 clear_tty_hooks (struct terminal
*terminal
)
3161 terminal
->cursor_to_hook
= 0;
3162 terminal
->raw_cursor_to_hook
= 0;
3163 terminal
->clear_to_end_hook
= 0;
3164 terminal
->clear_frame_hook
= 0;
3165 terminal
->clear_end_of_line_hook
= 0;
3166 terminal
->ins_del_lines_hook
= 0;
3167 terminal
->insert_glyphs_hook
= 0;
3168 terminal
->write_glyphs_hook
= 0;
3169 terminal
->delete_glyphs_hook
= 0;
3170 terminal
->ring_bell_hook
= 0;
3171 terminal
->reset_terminal_modes_hook
= 0;
3172 terminal
->set_terminal_modes_hook
= 0;
3173 terminal
->update_begin_hook
= 0;
3174 terminal
->update_end_hook
= 0;
3175 terminal
->set_terminal_window_hook
= 0;
3176 terminal
->mouse_position_hook
= 0;
3177 terminal
->frame_rehighlight_hook
= 0;
3178 terminal
->frame_raise_lower_hook
= 0;
3179 terminal
->fullscreen_hook
= 0;
3180 terminal
->set_vertical_scroll_bar_hook
= 0;
3181 terminal
->condemn_scroll_bars_hook
= 0;
3182 terminal
->redeem_scroll_bar_hook
= 0;
3183 terminal
->judge_scroll_bars_hook
= 0;
3184 terminal
->read_socket_hook
= 0;
3185 terminal
->frame_up_to_date_hook
= 0;
3187 /* Leave these two set, or suspended frames are not deleted
3189 terminal
->delete_frame_hook
= &delete_tty_output
;
3190 terminal
->delete_terminal_hook
= &delete_tty
;
3193 /* Initialize hooks in TERMINAL with the values needed for a tty. */
3196 set_tty_hooks (struct terminal
*terminal
)
3198 terminal
->rif
= 0; /* ttys don't support window-based redisplay. */
3200 terminal
->cursor_to_hook
= &tty_cursor_to
;
3201 terminal
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
3203 terminal
->clear_to_end_hook
= &tty_clear_to_end
;
3204 terminal
->clear_frame_hook
= &tty_clear_frame
;
3205 terminal
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
3207 terminal
->ins_del_lines_hook
= &tty_ins_del_lines
;
3209 terminal
->insert_glyphs_hook
= &tty_insert_glyphs
;
3210 terminal
->write_glyphs_hook
= &tty_write_glyphs
;
3211 terminal
->delete_glyphs_hook
= &tty_delete_glyphs
;
3213 terminal
->ring_bell_hook
= &tty_ring_bell
;
3215 terminal
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
3216 terminal
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
3217 terminal
->update_begin_hook
= 0; /* Not needed. */
3218 terminal
->update_end_hook
= &tty_update_end
;
3219 terminal
->set_terminal_window_hook
= &tty_set_terminal_window
;
3221 terminal
->mouse_position_hook
= 0; /* Not needed. */
3222 terminal
->frame_rehighlight_hook
= 0; /* Not needed. */
3223 terminal
->frame_raise_lower_hook
= 0; /* Not needed. */
3225 terminal
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
3226 terminal
->condemn_scroll_bars_hook
= 0; /* Not needed. */
3227 terminal
->redeem_scroll_bar_hook
= 0; /* Not needed. */
3228 terminal
->judge_scroll_bars_hook
= 0; /* Not needed. */
3230 terminal
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
3231 terminal
->frame_up_to_date_hook
= 0; /* Not needed. */
3233 terminal
->delete_frame_hook
= &delete_tty_output
;
3234 terminal
->delete_terminal_hook
= &delete_tty
;
3237 /* Drop the controlling terminal if fd is the same device. */
3239 dissociate_if_controlling_tty (int fd
)
3243 EMACS_GET_TTY_PGRP (fd
, &pgid
); /* If tcgetpgrp succeeds, fd is the ctty. */
3246 #if defined (USG) && !defined (BSD_PGRPS)
3248 no_controlling_tty
= 1;
3249 #elif defined (CYGWIN)
3251 no_controlling_tty
= 1;
3253 #ifdef TIOCNOTTY /* Try BSD ioctls. */
3254 sigblock (sigmask (SIGTTOU
));
3255 fd
= emacs_open (DEV_TTY
, O_RDWR
, 0);
3256 if (fd
!= -1 && ioctl (fd
, TIOCNOTTY
, 0) != -1)
3258 no_controlling_tty
= 1;
3262 sigunblock (sigmask (SIGTTOU
));
3264 /* Unknown system. */
3266 #endif /* ! TIOCNOTTY */
3269 #endif /* !WINDOWSNT */
3272 static void maybe_fatal();
3274 /* Create a termcap display on the tty device with the given name and
3277 If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
3278 Otherwise NAME should be a path to the tty device file,
3281 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
3283 If MUST_SUCCEED is true, then all errors are fatal. */
3286 init_tty (char *name
, char *terminal_type
, int must_succeed
)
3289 char **address
= &area
;
3290 char *buffer
= NULL
;
3291 int buffer_size
= 4096;
3292 register char *p
= NULL
;
3294 struct tty_display_info
*tty
= NULL
;
3295 struct terminal
*terminal
= NULL
;
3296 int ctty
= 0; /* 1 if asked to open controlling tty. */
3299 maybe_fatal (must_succeed
, 0, 0,
3300 "Unknown terminal type",
3301 "Unknown terminal type");
3305 if (!strcmp (name
, DEV_TTY
))
3308 /* If we already have a terminal on the given device, use that. If
3309 all such terminals are suspended, create a new one instead. */
3310 /* XXX Perhaps this should be made explicit by having init_tty
3311 always create a new terminal and separating terminal and frame
3312 creation on Lisp level. */
3313 terminal
= get_named_tty (name
);
3317 terminal
= create_terminal ();
3318 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
3319 bzero (tty
, sizeof (struct tty_display_info
));
3320 tty
->next
= tty_list
;
3323 terminal
->type
= output_termcap
;
3324 terminal
->display_info
.tty
= tty
;
3325 tty
->terminal
= terminal
;
3327 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
3331 set_tty_hooks (terminal
);
3337 #ifdef O_IGNORE_CTTY
3339 /* Open the terminal device. Don't recognize it as our
3340 controlling terminal, and don't make it the controlling tty
3341 if we don't have one at the moment. */
3342 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
3345 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
3346 defined on Hurd. On other systems, we need to explicitly
3347 dissociate ourselves from the controlling tty when we want to
3348 open a frame on the same terminal. */
3349 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
3350 #endif /* O_IGNORE_CTTY */
3353 maybe_fatal (must_succeed
, buffer
, terminal
,
3354 "Could not open file: %s",
3355 "Could not open file: %s",
3360 maybe_fatal (must_succeed
, buffer
, terminal
,
3361 "Not a tty device: %s",
3362 "Not a tty device: %s",
3366 #ifndef O_IGNORE_CTTY
3368 dissociate_if_controlling_tty (fd
);
3371 file
= fdopen (fd
, "w+");
3372 tty
->name
= xstrdup (name
);
3373 terminal
->name
= xstrdup (name
);
3378 tty
->type
= xstrdup (terminal_type
);
3380 add_keyboard_wait_descriptor (fileno (tty
->input
));
3384 encode_terminal_src_size
= 0;
3385 encode_terminal_dst_size
= 0;
3388 terminal
->mouse_position_hook
= term_mouse_position
;
3389 mouse_face_window
= Qnil
;
3393 initialize_w32_display (terminal
);
3394 /* The following two are inaccessible from w32console.c. */
3395 terminal
->delete_frame_hook
= &delete_tty_output
;
3396 terminal
->delete_terminal_hook
= &delete_tty
;
3398 tty
->name
= xstrdup (name
);
3399 terminal
->name
= xstrdup (name
);
3400 tty
->type
= xstrdup (terminal_type
);
3402 tty
->output
= stdout
;
3404 add_keyboard_wait_descriptor (0);
3409 struct frame
*f
= XFRAME (selected_frame
);
3411 FrameRows (tty
) = FRAME_LINES (f
);
3412 FrameCols (tty
) = FRAME_COLS (f
);
3413 tty
->specified_window
= FRAME_LINES (f
);
3415 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
3416 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
3418 tty
->delete_in_insert_mode
= 1;
3421 terminal
->scroll_region_ok
= 0;
3423 /* Seems to insert lines when it's not supposed to, messing up the
3424 display. In doing a trace, it didn't seem to be called much, so I
3425 don't think we're losing anything by turning it off. */
3426 terminal
->line_ins_del_ok
= 0;
3427 terminal
->char_ins_del_ok
= 1;
3431 tty
->TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
3433 #else /* not WINDOWSNT */
3437 buffer
= (char *) xmalloc (buffer_size
);
3439 /* On some systems, tgetent tries to access the controlling
3441 sigblock (sigmask (SIGTTOU
));
3442 status
= tgetent (buffer
, terminal_type
);
3443 sigunblock (sigmask (SIGTTOU
));
3448 maybe_fatal (must_succeed
, buffer
, terminal
,
3449 "Cannot open terminfo database file",
3450 "Cannot open terminfo database file");
3452 maybe_fatal (must_succeed
, buffer
, terminal
,
3453 "Cannot open termcap database file",
3454 "Cannot open termcap database file");
3460 maybe_fatal (must_succeed
, buffer
, terminal
,
3461 "Terminal type %s is not defined",
3462 "Terminal type %s is not defined.\n\
3463 If that is not the actual type of terminal you have,\n\
3464 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3465 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3466 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3469 maybe_fatal (must_succeed
, buffer
, terminal
,
3470 "Terminal type %s is not defined",
3471 "Terminal type %s is not defined.\n\
3472 If that is not the actual type of terminal you have,\n\
3473 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3474 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3475 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3481 if (strlen (buffer
) >= buffer_size
)
3483 buffer_size
= strlen (buffer
);
3485 area
= (char *) xmalloc (buffer_size
);
3487 tty
->TS_ins_line
= tgetstr ("al", address
);
3488 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
3489 tty
->TS_bell
= tgetstr ("bl", address
);
3490 BackTab (tty
) = tgetstr ("bt", address
);
3491 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
3492 tty
->TS_clr_line
= tgetstr ("ce", address
);
3493 tty
->TS_clr_frame
= tgetstr ("cl", address
);
3494 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
3495 AbsPosition (tty
) = tgetstr ("cm", address
);
3496 CR (tty
) = tgetstr ("cr", address
);
3497 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
3498 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
3499 RowPosition (tty
) = tgetstr ("cv", address
);
3500 tty
->TS_del_char
= tgetstr ("dc", address
);
3501 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
3502 tty
->TS_del_line
= tgetstr ("dl", address
);
3503 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
3504 tty
->TS_delete_mode
= tgetstr ("dm", address
);
3505 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
3506 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
3507 Home (tty
) = tgetstr ("ho", address
);
3508 tty
->TS_ins_char
= tgetstr ("ic", address
);
3509 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
3510 tty
->TS_insert_mode
= tgetstr ("im", address
);
3511 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
3512 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
3513 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
3514 LastLine (tty
) = tgetstr ("ll", address
);
3515 Right (tty
) = tgetstr ("nd", address
);
3516 Down (tty
) = tgetstr ("do", address
);
3518 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
3520 /* VMS puts a carriage return before each linefeed,
3521 so it is not safe to use linefeeds. */
3522 if (Down (tty
) && Down (tty
)[0] == '\n' && Down (tty
)[1] == '\0')
3525 if (tgetflag ("bs"))
3526 Left (tty
) = "\b"; /* can't possibly be longer! */
3527 else /* (Actually, "bs" is obsolete...) */
3528 Left (tty
) = tgetstr ("le", address
);
3530 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
3531 tty
->TS_pad_char
= tgetstr ("pc", address
);
3532 tty
->TS_repeat
= tgetstr ("rp", address
);
3533 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
3534 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
3535 tty
->TS_standout_mode
= tgetstr ("so", address
);
3536 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
3537 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
3538 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
3539 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
3540 Up (tty
) = tgetstr ("up", address
);
3541 tty
->TS_visible_bell
= tgetstr ("vb", address
);
3542 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
3543 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
3544 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
3545 tty
->TS_set_window
= tgetstr ("wi", address
);
3547 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
3548 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
3549 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
3550 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
3551 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
3552 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
3553 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3554 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3555 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
3557 MultiUp (tty
) = tgetstr ("UP", address
);
3558 MultiDown (tty
) = tgetstr ("DO", address
);
3559 MultiLeft (tty
) = tgetstr ("LE", address
);
3560 MultiRight (tty
) = tgetstr ("RI", address
);
3562 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
3563 color because we can't switch back to the default foreground and
3565 tty
->TS_orig_pair
= tgetstr ("op", address
);
3566 if (tty
->TS_orig_pair
)
3568 tty
->TS_set_foreground
= tgetstr ("AF", address
);
3569 tty
->TS_set_background
= tgetstr ("AB", address
);
3570 if (!tty
->TS_set_foreground
)
3573 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
3574 tty
->TS_set_background
= tgetstr ("Sb", address
);
3577 tty
->TN_max_colors
= tgetnum ("Co");
3578 tty
->TN_max_pairs
= tgetnum ("pa");
3580 tty
->TN_no_color_video
= tgetnum ("NC");
3581 if (tty
->TN_no_color_video
== -1)
3582 tty
->TN_no_color_video
= 0;
3585 tty_default_color_capabilities (tty
, 1);
3587 MagicWrap (tty
) = tgetflag ("xn");
3588 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3589 the former flag imply the latter. */
3590 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
3591 terminal
->memory_below_frame
= tgetflag ("db");
3592 tty
->TF_hazeltine
= tgetflag ("hz");
3593 terminal
->must_write_spaces
= tgetflag ("in");
3594 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
3595 tty
->TF_insmode_motion
= tgetflag ("mi");
3596 tty
->TF_standout_motion
= tgetflag ("ms");
3597 tty
->TF_underscore
= tgetflag ("ul");
3598 tty
->TF_teleray
= tgetflag ("xt");
3600 #endif /* !WINDOWSNT */
3602 terminal
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
3603 init_kboard (terminal
->kboard
);
3604 terminal
->kboard
->Vwindow_system
= Qnil
;
3605 terminal
->kboard
->next_kboard
= all_kboards
;
3606 all_kboards
= terminal
->kboard
;
3607 terminal
->kboard
->reference_count
++;
3608 /* Don't let the initial kboard remain current longer than necessary.
3609 That would cause problems if a file loaded on startup tries to
3610 prompt in the mini-buffer. */
3611 if (current_kboard
== initial_kboard
)
3612 current_kboard
= terminal
->kboard
;
3614 term_get_fkeys (address
, terminal
->kboard
);
3619 /* Get frame size from system, or else from termcap. */
3622 get_tty_size (fileno (tty
->input
), &width
, &height
);
3623 FrameCols (tty
) = width
;
3624 FrameRows (tty
) = height
;
3627 if (FrameCols (tty
) <= 0)
3628 FrameCols (tty
) = tgetnum ("co");
3629 if (FrameRows (tty
) <= 0)
3630 FrameRows (tty
) = tgetnum ("li");
3632 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
3633 maybe_fatal (must_succeed
, NULL
, terminal
,
3634 "Screen size %dx%d is too small"
3635 "Screen size %dx%d is too small",
3636 FrameCols (tty
), FrameRows (tty
));
3638 #if 0 /* This is not used anywhere. */
3639 tty
->terminal
->min_padding_speed
= tgetnum ("pb");
3642 TabWidth (tty
) = tgetnum ("tw");
3645 /* These capabilities commonly use ^J.
3646 I don't know why, but sending them on VMS does not work;
3647 it causes following spaces to be lost, sometimes.
3648 For now, the simplest fix is to avoid using these capabilities ever. */
3649 if (Down (tty
) && Down (tty
)[0] == '\n')
3654 tty
->TS_bell
= "\07";
3656 if (!tty
->TS_fwd_scroll
)
3657 tty
->TS_fwd_scroll
= Down (tty
);
3659 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
3661 if (TabWidth (tty
) < 0)
3664 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3665 and newer termcap doc does not seem to say there is a default.
3666 if (!tty->Wcm->cm_tab)
3667 tty->Wcm->cm_tab = "\t";
3670 /* We don't support standout modes that use `magic cookies', so
3671 turn off any that do. */
3672 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
3674 tty
->TS_standout_mode
= 0;
3675 tty
->TS_end_standout_mode
= 0;
3677 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3679 tty
->TS_enter_underline_mode
= 0;
3680 tty
->TS_exit_underline_mode
= 0;
3683 /* If there's no standout mode, try to use underlining instead. */
3684 if (tty
->TS_standout_mode
== 0)
3686 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
3687 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
3690 /* If no `se' string, try using a `me' string instead.
3691 If that fails, we can't use standout mode at all. */
3692 if (tty
->TS_end_standout_mode
== 0)
3694 char *s
= tgetstr ("me", address
);
3696 tty
->TS_end_standout_mode
= s
;
3698 tty
->TS_standout_mode
= 0;
3701 if (tty
->TF_teleray
)
3703 tty
->Wcm
->cm_tab
= 0;
3704 /* We can't support standout mode, because it uses magic cookies. */
3705 tty
->TS_standout_mode
= 0;
3706 /* But that means we cannot rely on ^M to go to column zero! */
3708 /* LF can't be trusted either -- can alter hpos */
3709 /* if move at column 0 thru a line with TS_standout_mode */
3713 /* Special handling for certain terminal types known to need it */
3715 if (!strcmp (terminal_type
, "supdup"))
3717 terminal
->memory_below_frame
= 1;
3718 tty
->Wcm
->cm_losewrap
= 1;
3720 if (!strncmp (terminal_type
, "c10", 3)
3721 || !strcmp (terminal_type
, "perq"))
3723 /* Supply a makeshift :wi string.
3724 This string is not valid in general since it works only
3725 for windows starting at the upper left corner;
3726 but that is all Emacs uses.
3728 This string works only if the frame is using
3729 the top of the video memory, because addressing is memory-relative.
3730 So first check the :ti string to see if that is true.
3732 It would be simpler if the :wi string could go in the termcap
3733 entry, but it can't because it is not fully valid.
3734 If it were in the termcap entry, it would confuse other programs. */
3735 if (!tty
->TS_set_window
)
3737 p
= tty
->TS_termcap_modes
;
3738 while (*p
&& strcmp (p
, "\033v "))
3741 tty
->TS_set_window
= "\033v%C %C %C %C ";
3743 /* Termcap entry often fails to have :in: flag */
3744 terminal
->must_write_spaces
= 1;
3745 /* :ti string typically fails to have \E^G! in it */
3746 /* This limits scope of insert-char to one line. */
3747 strcpy (area
, tty
->TS_termcap_modes
);
3748 strcat (area
, "\033\007!");
3749 tty
->TS_termcap_modes
= area
;
3750 area
+= strlen (area
) + 1;
3751 p
= AbsPosition (tty
);
3752 /* Change all %+ parameters to %C, to handle
3753 values above 96 correctly for the C100. */
3756 if (p
[0] == '%' && p
[1] == '+')
3762 tty
->specified_window
= FrameRows (tty
);
3764 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
3766 maybe_fatal (must_succeed
, NULL
, terminal
,
3767 "Terminal type \"%s\" is not powerful enough to run Emacs",
3769 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3770 It lacks the ability to position the cursor.\n\
3771 If that is not the actual type of terminal you have, use either the\n\
3772 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
3773 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
3776 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3777 It lacks the ability to position the cursor.\n\
3778 If that is not the actual type of terminal you have,\n\
3779 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3780 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3781 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3782 # else /* TERMCAP */
3783 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3784 It lacks the ability to position the cursor.\n\
3785 If that is not the actual type of terminal you have,\n\
3786 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3787 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3788 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3789 # endif /* TERMINFO */
3794 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
3795 maybe_fatal (must_succeed
, NULL
, terminal
,
3796 "Could not determine the frame size",
3797 "Could not determine the frame size");
3799 tty
->delete_in_insert_mode
3800 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
3801 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
3803 tty
->se_is_so
= (tty
->TS_standout_mode
3804 && tty
->TS_end_standout_mode
3805 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
3807 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
3809 terminal
->scroll_region_ok
3811 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
3813 terminal
->line_ins_del_ok
3814 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
3815 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
3816 || (terminal
->scroll_region_ok
3817 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
3819 terminal
->char_ins_del_ok
3820 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
3821 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
3822 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
3824 terminal
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
3826 init_baud_rate (fileno (tty
->input
));
3829 /* The HFT system on AIX doesn't optimize for scrolling, so it's
3830 really ugly at times. */
3831 terminal
->line_ins_del_ok
= 0;
3832 terminal
->char_ins_del_ok
= 0;
3835 /* Don't do this. I think termcap may still need the buffer. */
3836 /* xfree (buffer); */
3838 #endif /* not WINDOWSNT */
3840 /* Init system terminal modes (RAW or CBREAK, etc.). */
3841 init_sys_modes (tty
);
3846 /* Auxiliary error-handling function for init_tty.
3847 Free BUFFER and delete TERMINAL, then call error or fatal
3848 with str1 or str2, respectively, according to MUST_SUCCEED. */
3851 maybe_fatal (must_succeed
, buffer
, terminal
, str1
, str2
, arg1
, arg2
)
3854 struct terminal
*terminal
;
3855 char *str1
, *str2
, *arg1
, *arg2
;
3861 delete_tty (terminal
);
3864 fatal (str2
, arg1
, arg2
);
3866 error (str1
, arg1
, arg2
);
3872 fatal (const char *str
, ...)
3876 fprintf (stderr
, "emacs: ");
3877 vfprintf (stderr
, str
, ap
);
3885 /* Delete the given tty terminal, closing all frames on it. */
3888 delete_tty (struct terminal
*terminal
)
3890 struct tty_display_info
*tty
;
3891 Lisp_Object tail
, frame
;
3894 /* Protect against recursive calls. Fdelete_frame in
3895 delete_terminal calls us back when it deletes our last frame. */
3896 if (!terminal
->name
)
3899 if (terminal
->type
!= output_termcap
)
3902 tty
= terminal
->display_info
.tty
;
3905 FOR_EACH_FRAME (tail
, frame
)
3907 struct frame
*f
= XFRAME (frame
);
3908 if (FRAME_LIVE_P (f
) && (!FRAME_TERMCAP_P (f
) || FRAME_TTY (f
) != tty
))
3915 error ("Attempt to delete the sole terminal device with live frames");
3917 if (tty
== tty_list
)
3918 tty_list
= tty
->next
;
3921 struct tty_display_info
*p
;
3922 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
3926 /* This should not happen. */
3929 p
->next
= tty
->next
;
3933 /* reset_sys_modes needs a valid device, so this call needs to be
3934 before delete_terminal. */
3935 reset_sys_modes (tty
);
3937 delete_terminal (terminal
);
3947 delete_keyboard_wait_descriptor (fileno (tty
->input
));
3948 if (tty
->input
!= stdin
)
3949 fclose (tty
->input
);
3951 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
3952 fclose (tty
->output
);
3953 if (tty
->termscript
)
3954 fclose (tty
->termscript
);
3957 xfree (tty
->old_tty
);
3962 bzero (tty
, sizeof (struct tty_display_info
));
3968 /* Mark the pointers in the tty_display_info objects.
3969 Called by the Fgarbage_collector. */
3974 struct tty_display_info
*tty
;
3976 for (tty
= tty_list
; tty
; tty
= tty
->next
)
3977 mark_object (tty
->top_frame
);
3985 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
3986 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3987 This variable can be used by terminal emulator packages. */);
3989 system_uses_terminfo
= 1;
3991 system_uses_terminfo
= 0;
3994 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions
,
3995 doc
: /* Functions to be run after suspending a tty.
3996 The functions are run with one argument, the terminal id to be suspended.
3997 See `suspend-tty'. */);
3998 Vsuspend_tty_functions
= Qnil
;
4001 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions
,
4002 doc
: /* Functions to be run after resuming a tty.
4003 The functions are run with one argument, the terminal id that was revived.
4004 See `resume-tty'. */);
4005 Vresume_tty_functions
= Qnil
;
4007 DEFVAR_BOOL ("visible-cursor", &visible_cursor
,
4008 doc
: /* Non-nil means to make the cursor very visible.
4009 This only has an effect when running in a text terminal.
4010 What means \"very visible\" is up to your terminal. It may make the cursor
4011 bigger, or it may make it blink, or it may do nothing at all. */);
4014 defsubr (&Stty_display_color_p
);
4015 defsubr (&Stty_display_color_cells
);
4016 defsubr (&Stty_no_underline
);
4017 defsubr (&Stty_type
);
4018 defsubr (&Scontrolling_tty_p
);
4019 defsubr (&Ssuspend_tty
);
4020 defsubr (&Sresume_tty
);
4022 defsubr (&Sgpm_mouse_start
);
4023 defsubr (&Sgpm_mouse_stop
);
4025 staticpro (&mouse_face_window
);
4026 #endif /* HAVE_GPM */
4031 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
4032 (do not change this comment) */