1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
36 #include <termios.h> /* For TIOCNOTTY. */
49 #include "termhooks.h"
50 #include "dispextern.h"
53 #include "blockinput.h"
54 #include "syssignal.h"
56 #include "intervals.h"
58 /* For now, don't try to include termcap.h. On some systems,
59 configure finds a non-standard termcap.h that the main build
62 #if defined HAVE_TERMCAP_H && 0
65 extern void tputs
P_ ((const char *, int, int (*)(int)));
66 extern int tgetent
P_ ((char *, const char *));
67 extern int tgetflag
P_ ((char *id
));
68 extern int tgetnum
P_ ((char *id
));
87 /* The name of the default console device. */
89 #define DEV_TTY "CONOUT$"
91 #define DEV_TTY "/dev/tty"
94 static void tty_set_scroll_region
P_ ((struct frame
*f
, int start
, int stop
));
95 static void turn_on_face
P_ ((struct frame
*, int face_id
));
96 static void turn_off_face
P_ ((struct frame
*, int face_id
));
97 static void tty_show_cursor
P_ ((struct tty_display_info
*));
98 static void tty_hide_cursor
P_ ((struct tty_display_info
*));
99 static void tty_background_highlight
P_ ((struct tty_display_info
*tty
));
100 static void clear_tty_hooks
P_ ((struct terminal
*terminal
));
101 static void set_tty_hooks
P_ ((struct terminal
*terminal
));
102 static void dissociate_if_controlling_tty
P_ ((int fd
));
103 static void delete_tty
P_ ((struct terminal
*));
105 #define OUTPUT(tty, a) \
106 emacs_tputs ((tty), a, \
107 (int) (FRAME_LINES (XFRAME (selected_frame)) \
111 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
112 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
114 #define OUTPUT_IF(tty, a) \
117 emacs_tputs ((tty), a, \
118 (int) (FRAME_LINES (XFRAME (selected_frame)) \
123 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
125 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */
127 static int visible_cursor
;
129 /* Display space properties */
131 extern Lisp_Object Qspace
, QCalign_to
, QCwidth
;
133 /* Functions to call after suspending a tty. */
134 Lisp_Object Vsuspend_tty_functions
;
136 /* Functions to call after resuming a tty. */
137 Lisp_Object Vresume_tty_functions
;
139 /* Chain of all tty device parameters. */
140 struct tty_display_info
*tty_list
;
142 /* Nonzero means no need to redraw the entire frame on resuming a
143 suspended Emacs. This is useful on terminals with multiple
144 pages, where one page is used for Emacs and another for all
146 int no_redraw_on_reenter
;
148 /* Meaning of bits in no_color_video. Each bit set means that the
149 corresponding attribute cannot be combined with colors. */
153 NC_STANDOUT
= 1 << 0,
154 NC_UNDERLINE
= 1 << 1,
161 NC_ALT_CHARSET
= 1 << 8
166 /* The largest frame width in any call to calculate_costs. */
170 /* The largest frame height in any call to calculate_costs. */
174 /* Non-zero if we have dropped our controlling tty and therefore
175 should not open a frame on stdout. */
176 static int no_controlling_tty
;
178 /* Provided for lisp packages. */
180 static int system_uses_terminfo
;
184 extern char *tgetstr ();
186 static void term_clear_mouse_face ();
187 static void term_mouse_highlight (struct frame
*f
, int x
, int y
);
191 #include <sys/fcntl.h>
194 /* The device for which we have enabled gpm support (or NULL). */
195 struct tty_display_info
*gpm_tty
= NULL
;
197 /* These variables describe the range of text currently shown in its
198 mouse-face, together with the window they apply to. As long as
199 the mouse stays within this range, we need not redraw anything on
200 its account. Rows and columns are glyph matrix positions in
201 MOUSE_FACE_WINDOW. */
202 static int mouse_face_beg_row
, mouse_face_beg_col
;
203 static int mouse_face_end_row
, mouse_face_end_col
;
204 static int mouse_face_past_end
;
205 static Lisp_Object mouse_face_window
;
206 static int mouse_face_face_id
;
208 static int pos_x
, pos_y
;
209 static int last_mouse_x
, last_mouse_y
;
210 #endif /* HAVE_GPM */
212 /* Ring the bell on a tty. */
215 tty_ring_bell (struct frame
*f
)
217 struct tty_display_info
*tty
= FRAME_TTY (f
);
221 OUTPUT (tty
, (tty
->TS_visible_bell
&& visible_bell
222 ? tty
->TS_visible_bell
224 fflush (tty
->output
);
228 /* Set up termcap modes for Emacs. */
231 tty_set_terminal_modes (struct terminal
*terminal
)
233 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
237 if (tty
->TS_termcap_modes
)
238 OUTPUT (tty
, tty
->TS_termcap_modes
);
241 /* Output enough newlines to scroll all the old screen contents
242 off the screen, so it won't be overwritten and lost. */
245 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
249 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
250 OUTPUT_IF (tty
, visible_cursor
? tty
->TS_cursor_visible
: tty
->TS_cursor_normal
);
251 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
253 fflush (tty
->output
);
257 /* Reset termcap modes before exiting Emacs. */
260 tty_reset_terminal_modes (struct terminal
*terminal
)
262 struct tty_display_info
*tty
= terminal
->display_info
.tty
;
266 tty_turn_off_highlight (tty
);
267 tty_turn_off_insert (tty
);
268 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
269 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
270 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
271 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
272 /* Output raw CR so kernel can track the cursor hpos. */
275 fflush (tty
->output
);
279 /* Flag the end of a display update on a termcap terminal. */
282 tty_update_end (struct frame
*f
)
284 struct tty_display_info
*tty
= FRAME_TTY (f
);
286 if (!XWINDOW (selected_window
)->cursor_off_p
)
287 tty_show_cursor (tty
);
288 tty_turn_off_insert (tty
);
289 tty_background_highlight (tty
);
292 /* The implementation of set_terminal_window for termcap frames. */
295 tty_set_terminal_window (struct frame
*f
, int size
)
297 struct tty_display_info
*tty
= FRAME_TTY (f
);
299 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
300 if (FRAME_SCROLL_REGION_OK (f
))
301 tty_set_scroll_region (f
, 0, tty
->specified_window
);
305 tty_set_scroll_region (struct frame
*f
, int start
, int stop
)
308 struct tty_display_info
*tty
= FRAME_TTY (f
);
310 if (tty
->TS_set_scroll_region
)
311 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
312 else if (tty
->TS_set_scroll_region_1
)
313 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
314 FRAME_LINES (f
), start
,
315 FRAME_LINES (f
) - stop
,
318 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
327 tty_turn_on_insert (struct tty_display_info
*tty
)
329 if (!tty
->insert_mode
)
330 OUTPUT (tty
, tty
->TS_insert_mode
);
331 tty
->insert_mode
= 1;
335 tty_turn_off_insert (struct tty_display_info
*tty
)
337 if (tty
->insert_mode
)
338 OUTPUT (tty
, tty
->TS_end_insert_mode
);
339 tty
->insert_mode
= 0;
342 /* Handle highlighting. */
345 tty_turn_off_highlight (struct tty_display_info
*tty
)
347 if (tty
->standout_mode
)
348 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
349 tty
->standout_mode
= 0;
353 tty_turn_on_highlight (struct tty_display_info
*tty
)
355 if (!tty
->standout_mode
)
356 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
357 tty
->standout_mode
= 1;
361 tty_toggle_highlight (struct tty_display_info
*tty
)
363 if (tty
->standout_mode
)
364 tty_turn_off_highlight (tty
);
366 tty_turn_on_highlight (tty
);
370 /* Make cursor invisible. */
373 tty_hide_cursor (struct tty_display_info
*tty
)
375 if (tty
->cursor_hidden
== 0)
377 tty
->cursor_hidden
= 1;
378 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
383 /* Ensure that cursor is visible. */
386 tty_show_cursor (struct tty_display_info
*tty
)
388 if (tty
->cursor_hidden
)
390 tty
->cursor_hidden
= 0;
391 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
393 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
398 /* Set standout mode to the state it should be in for
399 empty space inside windows. What this is,
400 depends on the user option inverse-video. */
403 tty_background_highlight (struct tty_display_info
*tty
)
406 tty_turn_on_highlight (tty
);
408 tty_turn_off_highlight (tty
);
411 /* Set standout mode to the mode specified for the text to be output. */
414 tty_highlight_if_desired (struct tty_display_info
*tty
)
417 tty_turn_on_highlight (tty
);
419 tty_turn_off_highlight (tty
);
423 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
424 frame-relative coordinates. */
427 tty_cursor_to (struct frame
*f
, int vpos
, int hpos
)
429 struct tty_display_info
*tty
= FRAME_TTY (f
);
431 /* Detect the case where we are called from reset_sys_modes
432 and the costs have never been calculated. Do nothing. */
433 if (! tty
->costs_set
)
436 if (curY (tty
) == vpos
437 && curX (tty
) == hpos
)
439 if (!tty
->TF_standout_motion
)
440 tty_background_highlight (tty
);
441 if (!tty
->TF_insmode_motion
)
442 tty_turn_off_insert (tty
);
443 cmgoto (tty
, vpos
, hpos
);
446 /* Similar but don't take any account of the wasted characters. */
449 tty_raw_cursor_to (struct frame
*f
, int row
, int col
)
451 struct tty_display_info
*tty
= FRAME_TTY (f
);
453 if (curY (tty
) == row
454 && curX (tty
) == col
)
456 if (!tty
->TF_standout_motion
)
457 tty_background_highlight (tty
);
458 if (!tty
->TF_insmode_motion
)
459 tty_turn_off_insert (tty
);
460 cmgoto (tty
, row
, col
);
463 /* Erase operations */
465 /* Clear from cursor to end of frame on a termcap device. */
468 tty_clear_to_end (struct frame
*f
)
471 struct tty_display_info
*tty
= FRAME_TTY (f
);
473 if (tty
->TS_clr_to_bottom
)
475 tty_background_highlight (tty
);
476 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
480 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
483 clear_end_of_line (f
, FRAME_COLS (f
));
488 /* Clear an entire termcap frame. */
491 tty_clear_frame (struct frame
*f
)
493 struct tty_display_info
*tty
= FRAME_TTY (f
);
495 if (tty
->TS_clr_frame
)
497 tty_background_highlight (tty
);
498 OUTPUT (tty
, tty
->TS_clr_frame
);
508 /* An implementation of clear_end_of_line for termcap frames.
510 Note that the cursor may be moved, on terminals lacking a `ce' string. */
513 tty_clear_end_of_line (struct frame
*f
, int first_unused_hpos
)
516 struct tty_display_info
*tty
= FRAME_TTY (f
);
518 /* Detect the case where we are called from reset_sys_modes
519 and the costs have never been calculated. Do nothing. */
520 if (! tty
->costs_set
)
523 if (curX (tty
) >= first_unused_hpos
)
525 tty_background_highlight (tty
);
526 if (tty
->TS_clr_line
)
528 OUTPUT1 (tty
, tty
->TS_clr_line
);
531 { /* have to do it the hard way */
532 tty_turn_off_insert (tty
);
534 /* Do not write in last row last col with Auto-wrap on. */
536 && curY (tty
) == FrameRows (tty
) - 1
537 && first_unused_hpos
== FrameCols (tty
))
540 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
543 fputc (' ', tty
->termscript
);
544 fputc (' ', tty
->output
);
546 cmplus (tty
, first_unused_hpos
- curX (tty
));
550 /* Buffer to store the source and result of code conversion for terminal. */
551 static unsigned char *encode_terminal_buf
;
552 /* Allocated size of the above buffer. */
553 static int encode_terminal_bufsize
;
555 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
556 Set CODING->produced to the byte-length of the resulting byte
557 sequence, and return a pointer to that byte sequence. */
560 encode_terminal_code (src
, src_len
, coding
)
563 struct coding_system
*coding
;
565 struct glyph
*src_end
= src
+ src_len
;
568 int nchars
, nbytes
, required
;
569 register int tlen
= GLYPH_TABLE_LENGTH
;
570 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
572 /* Allocate sufficient size of buffer to store all characters in
573 multibyte-form. But, it may be enlarged on demand if
574 Vglyph_table contains a string. */
575 required
= MAX_MULTIBYTE_LENGTH
* src_len
;
576 if (encode_terminal_bufsize
< required
)
578 if (encode_terminal_bufsize
== 0)
579 encode_terminal_buf
= xmalloc (required
);
581 encode_terminal_buf
= xrealloc (encode_terminal_buf
, required
);
582 encode_terminal_bufsize
= required
;
585 buf
= encode_terminal_buf
;
587 while (src
< src_end
)
589 /* We must skip glyphs to be padded for a wide character. */
590 if (! CHAR_GLYPH_PADDING_P (*src
))
592 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
594 if (g
< 0 || g
>= tlen
)
596 /* This glyph doesn't has an entry in Vglyph_table. */
597 if (CHAR_VALID_P (src
->u
.ch
, 0))
598 buf
+= CHAR_STRING (src
->u
.ch
, buf
);
605 /* This glyph has an entry in Vglyph_table,
606 so process any alias before testing for simpleness. */
607 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
609 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
611 int c
= FAST_GLYPH_CHAR (g
);
613 if (CHAR_VALID_P (c
, 0))
614 buf
+= CHAR_STRING (c
, buf
);
621 /* We have a string in Vglyph_table. */
625 if (! STRING_MULTIBYTE (string
))
626 string
= string_to_multibyte (string
);
627 nbytes
= buf
- encode_terminal_buf
;
628 if (encode_terminal_bufsize
< nbytes
+ SBYTES (string
))
630 encode_terminal_bufsize
= nbytes
+ SBYTES (string
);
631 encode_terminal_buf
= xrealloc (encode_terminal_buf
,
632 encode_terminal_bufsize
);
633 buf
= encode_terminal_buf
+ nbytes
;
635 bcopy (SDATA (string
), buf
, SBYTES (string
));
636 buf
+= SBYTES (string
);
637 nchars
+= SCHARS (string
);
644 nbytes
= buf
- encode_terminal_buf
;
645 coding
->src_multibyte
= 1;
646 coding
->dst_multibyte
= 0;
647 if (SYMBOLP (coding
->pre_write_conversion
)
648 && ! NILP (Ffboundp (coding
->pre_write_conversion
)))
650 run_pre_write_conversin_on_c_str (&encode_terminal_buf
,
651 &encode_terminal_bufsize
,
652 nchars
, nbytes
, coding
);
653 nchars
= coding
->produced_char
;
654 nbytes
= coding
->produced
;
656 required
= nbytes
+ encoding_buffer_size (coding
, nbytes
);
657 if (encode_terminal_bufsize
< required
)
659 encode_terminal_bufsize
= required
;
660 encode_terminal_buf
= xrealloc (encode_terminal_buf
, required
);
663 encode_coding (coding
, encode_terminal_buf
, encode_terminal_buf
+ nbytes
,
664 nbytes
, encode_terminal_bufsize
- nbytes
);
665 return encode_terminal_buf
+ nbytes
;
669 /* An implementation of write_glyphs for termcap frames. */
672 tty_write_glyphs (struct frame
*f
, struct glyph
*string
, int len
)
674 unsigned char *conversion_buffer
;
675 struct coding_system
*coding
;
677 struct tty_display_info
*tty
= FRAME_TTY (f
);
679 tty_turn_off_insert (tty
);
680 tty_hide_cursor (tty
);
682 /* Don't dare write in last column of bottom line, if Auto-Wrap,
683 since that would scroll the whole frame on some terminals. */
686 && curY (tty
) + 1 == FRAME_LINES (f
)
687 && (curX (tty
) + len
) == FRAME_COLS (f
))
694 /* If terminal_coding does any conversion, use it, otherwise use
695 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
696 because it always return 1 if the member src_multibyte is 1. */
697 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
698 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
699 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
701 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
705 /* Identify a run of glyphs with the same face. */
706 int face_id
= string
->face_id
;
709 for (n
= 1; n
< len
; ++n
)
710 if (string
[n
].face_id
!= face_id
)
713 /* Turn appearance modes of the face of the run on. */
714 tty_highlight_if_desired (tty
);
715 turn_on_face (f
, face_id
);
718 /* This is the last run. */
719 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
720 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
721 if (coding
->produced
> 0)
724 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
725 if (ferror (tty
->output
))
726 clearerr (tty
->output
);
728 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
734 /* Turn appearance modes off. */
735 turn_off_face (f
, face_id
);
736 tty_turn_off_highlight (tty
);
743 tty_write_glyphs_with_face (f
, string
, len
, face_id
)
744 register struct frame
*f
;
745 register struct glyph
*string
;
746 register int len
, face_id
;
748 unsigned char *conversion_buffer
;
749 struct coding_system
*coding
;
751 struct tty_display_info
*tty
= FRAME_TTY (f
);
753 tty_turn_off_insert (tty
);
754 tty_hide_cursor (tty
);
756 /* Don't dare write in last column of bottom line, if Auto-Wrap,
757 since that would scroll the whole frame on some terminals. */
760 && curY (tty
) + 1 == FRAME_LINES (f
)
761 && (curX (tty
) + len
) == FRAME_COLS (f
))
768 /* If terminal_coding does any conversion, use it, otherwise use
769 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
770 because it always return 1 if the member src_multibyte is 1. */
771 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
772 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
773 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
775 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
777 /* Turn appearance modes of the face. */
778 tty_highlight_if_desired (tty
);
779 turn_on_face (f
, face_id
);
781 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
782 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
783 if (coding
->produced
> 0)
786 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
787 if (ferror (tty
->output
))
788 clearerr (tty
->output
);
790 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
794 /* Turn appearance modes off. */
795 turn_off_face (f
, face_id
);
796 tty_turn_off_highlight (tty
);
802 /* An implementation of insert_glyphs for termcap frames. */
805 tty_insert_glyphs (struct frame
*f
, struct glyph
*start
, int len
)
808 struct glyph
*glyph
= NULL
;
809 unsigned char *conversion_buffer
;
810 unsigned char space
[1];
811 struct coding_system
*coding
;
813 struct tty_display_info
*tty
= FRAME_TTY (f
);
815 if (tty
->TS_ins_multi_chars
)
817 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
821 write_glyphs (f
, start
, len
);
825 tty_turn_on_insert (tty
);
829 space
[0] = SPACEGLYPH
;
831 /* If terminal_coding does any conversion, use it, otherwise use
832 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
833 because it always return 1 if the member src_multibyte is 1. */
834 coding
= (FRAME_TERMINAL_CODING (f
)->common_flags
& CODING_REQUIRE_ENCODING_MASK
835 ? FRAME_TERMINAL_CODING (f
) : &safe_terminal_coding
);
836 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
838 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
842 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
845 conversion_buffer
= space
;
846 coding
->produced
= 1;
850 tty_highlight_if_desired (tty
);
851 turn_on_face (f
, start
->face_id
);
854 /* We must open sufficient space for a character which
855 occupies more than one column. */
856 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
858 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
863 /* This is the last glyph. */
864 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
866 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
869 if (coding
->produced
> 0)
872 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->output
);
873 if (ferror (tty
->output
))
874 clearerr (tty
->output
);
876 fwrite (conversion_buffer
, 1, coding
->produced
, tty
->termscript
);
880 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
883 turn_off_face (f
, glyph
->face_id
);
884 tty_turn_off_highlight (tty
);
891 /* An implementation of delete_glyphs for termcap frames. */
894 tty_delete_glyphs (struct frame
*f
, int n
)
899 struct tty_display_info
*tty
= FRAME_TTY (f
);
901 if (tty
->delete_in_insert_mode
)
903 tty_turn_on_insert (tty
);
907 tty_turn_off_insert (tty
);
908 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
911 if (tty
->TS_del_multi_chars
)
913 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
918 for (i
= 0; i
< n
; i
++)
919 OUTPUT1 (tty
, tty
->TS_del_char
);
920 if (!tty
->delete_in_insert_mode
)
921 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
924 /* An implementation of ins_del_lines for termcap frames. */
927 tty_ins_del_lines (struct frame
*f
, int vpos
, int n
)
929 struct tty_display_info
*tty
= FRAME_TTY (f
);
930 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
931 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
932 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
934 register int i
= n
> 0 ? n
: -n
;
937 /* If the lines below the insertion are being pushed
938 into the end of the window, this is the same as clearing;
939 and we know the lines are already clear, since the matching
940 deletion has already been done. So can ignore this. */
941 /* If the lines below the deletion are blank lines coming
942 out of the end of the window, don't bother,
943 as there will be a matching inslines later that will flush them. */
944 if (FRAME_SCROLL_REGION_OK (f
)
945 && vpos
+ i
>= tty
->specified_window
)
947 if (!FRAME_MEMORY_BELOW_FRAME (f
)
948 && vpos
+ i
>= FRAME_LINES (f
))
953 raw_cursor_to (f
, vpos
, 0);
954 tty_background_highlight (tty
);
955 buf
= tparam (multi
, 0, 0, i
);
961 raw_cursor_to (f
, vpos
, 0);
962 tty_background_highlight (tty
);
964 OUTPUT (tty
, single
);
970 tty_set_scroll_region (f
, vpos
, tty
->specified_window
);
972 raw_cursor_to (f
, tty
->specified_window
- 1, 0);
974 raw_cursor_to (f
, vpos
, 0);
975 tty_background_highlight (tty
);
977 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
978 tty_set_scroll_region (f
, 0, tty
->specified_window
);
981 if (!FRAME_SCROLL_REGION_OK (f
)
982 && FRAME_MEMORY_BELOW_FRAME (f
)
985 cursor_to (f
, FRAME_LINES (f
) + n
, 0);
990 /* Compute cost of sending "str", in characters,
991 not counting any line-dependent padding. */
994 string_cost (char *str
)
998 tputs (str
, 0, evalcost
);
1002 /* Compute cost of sending "str", in characters,
1003 counting any line-dependent padding at one line. */
1006 string_cost_one_line (char *str
)
1010 tputs (str
, 1, evalcost
);
1014 /* Compute per line amount of line-dependent padding,
1015 in tenths of characters. */
1018 per_line_cost (char *str
)
1022 tputs (str
, 0, evalcost
);
1025 tputs (str
, 10, evalcost
);
1030 /* char_ins_del_cost[n] is cost of inserting N characters.
1031 char_ins_del_cost[-n] is cost of deleting N characters.
1032 The length of this vector is based on max_frame_cols. */
1034 int *char_ins_del_vector
;
1036 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1041 calculate_ins_del_char_costs (struct frame
*f
)
1043 struct tty_display_info
*tty
= FRAME_TTY (f
);
1044 int ins_startup_cost
, del_startup_cost
;
1045 int ins_cost_per_char
, del_cost_per_char
;
1049 if (tty
->TS_ins_multi_chars
)
1051 ins_cost_per_char
= 0;
1052 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1054 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1055 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1057 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1058 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1059 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1060 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1064 ins_startup_cost
= 9999;
1065 ins_cost_per_char
= 0;
1068 if (tty
->TS_del_multi_chars
)
1070 del_cost_per_char
= 0;
1071 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1073 else if (tty
->TS_del_char
)
1075 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1076 + string_cost (tty
->TS_end_delete_mode
));
1077 if (tty
->delete_in_insert_mode
)
1078 del_startup_cost
/= 2;
1079 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1083 del_startup_cost
= 9999;
1084 del_cost_per_char
= 0;
1087 /* Delete costs are at negative offsets */
1088 p
= &char_ins_del_cost (f
)[0];
1089 for (i
= FRAME_COLS (f
); --i
>= 0;)
1090 *--p
= (del_startup_cost
+= del_cost_per_char
);
1092 /* Doing nothing is free */
1093 p
= &char_ins_del_cost (f
)[0];
1096 /* Insert costs are at positive offsets */
1097 for (i
= FRAME_COLS (f
); --i
>= 0;)
1098 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1102 calculate_costs (struct frame
*frame
)
1104 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1106 if (FRAME_TERMCAP_P (frame
))
1108 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1109 register char *f
= (tty
->TS_set_scroll_region
1110 ? tty
->TS_set_scroll_region
1111 : tty
->TS_set_scroll_region_1
);
1113 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1117 /* These variables are only used for terminal stuff. They are
1118 allocated once for the terminal frame of X-windows emacs, but not
1121 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1122 X turns off char_ins_del_ok. */
1124 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1125 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1127 if (char_ins_del_vector
!= 0)
1129 = (int *) xrealloc (char_ins_del_vector
,
1131 + 2 * max_frame_cols
* sizeof (int)));
1134 = (int *) xmalloc (sizeof (int)
1135 + 2 * max_frame_cols
* sizeof (int));
1137 bzero (char_ins_del_vector
, (sizeof (int)
1138 + 2 * max_frame_cols
* sizeof (int)));
1141 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1142 do_line_insertion_deletion_costs (frame
,
1143 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1144 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1147 do_line_insertion_deletion_costs (frame
,
1148 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1149 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1152 calculate_ins_del_char_costs (frame
);
1154 /* Don't use TS_repeat if its padding is worse than sending the chars */
1155 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1156 tty
->RPov
= string_cost (tty
->TS_repeat
);
1158 tty
->RPov
= FRAME_COLS (frame
) * 2;
1160 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1168 /* Termcap capability names that correspond directly to X keysyms.
1169 Some of these (marked "terminfo") aren't supplied by old-style
1170 (Berkeley) termcap entries. They're listed in X keysym order;
1171 except we put the keypad keys first, so that if they clash with
1172 other keys (as on the IBM PC keyboard) they get overridden.
1175 static struct fkey_table keys
[] =
1177 {"kh", "home"}, /* termcap */
1178 {"kl", "left"}, /* termcap */
1179 {"ku", "up"}, /* termcap */
1180 {"kr", "right"}, /* termcap */
1181 {"kd", "down"}, /* termcap */
1182 {"%8", "prior"}, /* terminfo */
1183 {"%5", "next"}, /* terminfo */
1184 {"@7", "end"}, /* terminfo */
1185 {"@1", "begin"}, /* terminfo */
1186 {"*6", "select"}, /* terminfo */
1187 {"%9", "print"}, /* terminfo */
1188 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1190 * "insert" --- see below
1192 {"&8", "undo"}, /* terminfo */
1193 {"%0", "redo"}, /* terminfo */
1194 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1195 {"@0", "find"}, /* terminfo */
1196 {"@2", "cancel"}, /* terminfo */
1197 {"%1", "help"}, /* terminfo */
1199 * "break" goes here, but can't be reliably intercepted with termcap
1201 {"&4", "reset"}, /* terminfo --- actually `restart' */
1203 * "system" and "user" --- no termcaps
1205 {"kE", "clearline"}, /* terminfo */
1206 {"kA", "insertline"}, /* terminfo */
1207 {"kL", "deleteline"}, /* terminfo */
1208 {"kI", "insertchar"}, /* terminfo */
1209 {"kD", "deletechar"}, /* terminfo */
1210 {"kB", "backtab"}, /* terminfo */
1212 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1214 {"@8", "kp-enter"}, /* terminfo */
1216 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1217 * "kp-multiply", "kp-add", "kp-separator",
1218 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1219 * --- no termcaps for any of these.
1221 {"K4", "kp-1"}, /* terminfo */
1223 * "kp-2" --- no termcap
1225 {"K5", "kp-3"}, /* terminfo */
1227 * "kp-4" --- no termcap
1229 {"K2", "kp-5"}, /* terminfo */
1231 * "kp-6" --- no termcap
1233 {"K1", "kp-7"}, /* terminfo */
1235 * "kp-8" --- no termcap
1237 {"K3", "kp-9"}, /* terminfo */
1239 * "kp-equal" --- no termcap
1251 {"&0", "S-cancel"}, /*shifted cancel key*/
1252 {"&9", "S-begin"}, /*shifted begin key*/
1253 {"*0", "S-find"}, /*shifted find key*/
1254 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1255 {"*4", "S-delete"}, /*shifted delete-character key*/
1256 {"*7", "S-end"}, /*shifted end key*/
1257 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1258 {"#1", "S-help"}, /*shifted help key*/
1259 {"#2", "S-home"}, /*shifted home key*/
1260 {"#3", "S-insert"}, /*shifted insert-character key*/
1261 {"#4", "S-left"}, /*shifted left-arrow key*/
1262 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1263 {"%c", "S-next"}, /*shifted next key*/
1264 {"%e", "S-prior"}, /*shifted previous key*/
1265 {"%f", "S-print"}, /*shifted print key*/
1266 {"%g", "S-redo"}, /*shifted redo key*/
1267 {"%i", "S-right"}, /*shifted right-arrow key*/
1268 {"!3", "S-undo"} /*shifted undo key*/
1271 static char **term_get_fkeys_address
;
1272 static KBOARD
*term_get_fkeys_kboard
;
1273 static Lisp_Object
term_get_fkeys_1 ();
1275 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1276 This function scans the termcap function key sequence entries, and
1277 adds entries to Vfunction_key_map for each function key it finds. */
1280 term_get_fkeys (address
, kboard
)
1284 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1285 errors during the call. The only errors should be from Fdefine_key
1286 when given a key sequence containing an invalid prefix key. If the
1287 termcap defines function keys which use a prefix that is already bound
1288 to a command by the default bindings, we should silently ignore that
1289 function key specification, rather than giving the user an error and
1290 refusing to run at all on such a terminal. */
1292 extern Lisp_Object
Fidentity ();
1293 term_get_fkeys_address
= address
;
1294 term_get_fkeys_kboard
= kboard
;
1295 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1303 char **address
= term_get_fkeys_address
;
1304 KBOARD
*kboard
= term_get_fkeys_kboard
;
1306 /* This can happen if CANNOT_DUMP or with strange options. */
1308 kboard
->Vlocal_function_key_map
= Fmake_sparse_keymap (Qnil
);
1310 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1312 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1314 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (sequence
),
1315 Fmake_vector (make_number (1),
1316 intern (keys
[i
].name
)));
1319 /* The uses of the "k0" capability are inconsistent; sometimes it
1320 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1321 We will attempt to politely accommodate both systems by testing for
1322 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1325 char *k_semi
= tgetstr ("k;", address
);
1326 char *k0
= tgetstr ("k0", address
);
1327 char *k0_name
= "f10";
1332 /* Define f0 first, so that f10 takes precedence in case the
1333 key sequences happens to be the same. */
1334 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (k0
),
1335 Fmake_vector (make_number (1), intern ("f0")));
1336 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (k_semi
),
1337 Fmake_vector (make_number (1), intern ("f10")));
1340 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (k0
),
1341 Fmake_vector (make_number (1), intern (k0_name
)));
1344 /* Set up cookies for numbered function keys above f10. */
1346 char fcap
[3], fkey
[4];
1348 fcap
[0] = 'F'; fcap
[2] = '\0';
1349 for (i
= 11; i
< 64; i
++)
1352 fcap
[1] = '1' + i
- 11;
1354 fcap
[1] = 'A' + i
- 20;
1356 fcap
[1] = 'a' + i
- 46;
1359 char *sequence
= tgetstr (fcap
, address
);
1362 sprintf (fkey
, "f%d", i
);
1363 Fdefine_key (kboard
->Vlocal_function_key_map
, build_string (sequence
),
1364 Fmake_vector (make_number (1),
1372 * Various mappings to try and get a better fit.
1375 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1376 if (!tgetstr (cap1, address)) \
1378 char *sequence = tgetstr (cap2, address); \
1380 Fdefine_key (kboard->Vlocal_function_key_map, build_string (sequence), \
1381 Fmake_vector (make_number (1), \
1385 /* if there's no key_next keycap, map key_npage to `next' keysym */
1386 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1387 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1388 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1389 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1390 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1391 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1392 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1394 /* IBM has their own non-standard dialect of terminfo.
1395 If the standard name isn't found, try the IBM name. */
1396 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1397 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1398 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1399 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1400 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1401 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1402 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1403 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1404 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1405 #undef CONDITIONAL_REASSIGN
1412 /***********************************************************************
1413 Character Display Information
1414 ***********************************************************************/
1416 /* Avoid name clash with functions defined in xterm.c */
1418 #define append_glyph append_glyph_term
1419 #define produce_stretch_glyph produce_stretch_glyph_term
1422 static void append_glyph
P_ ((struct it
*));
1423 static void produce_stretch_glyph
P_ ((struct it
*));
1426 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1427 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1428 the character for which to produce glyphs; IT->face_id contains the
1429 character's face. Padding glyphs are appended if IT->c has a
1430 IT->pixel_width > 1. */
1436 struct glyph
*glyph
, *end
;
1439 xassert (it
->glyph_row
);
1440 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1441 + it
->glyph_row
->used
[it
->area
]);
1442 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1445 i
< it
->pixel_width
&& glyph
< end
;
1448 glyph
->type
= CHAR_GLYPH
;
1449 glyph
->pixel_width
= 1;
1450 glyph
->u
.ch
= it
->char_to_display
;
1451 glyph
->face_id
= it
->face_id
;
1452 glyph
->padding_p
= i
> 0;
1453 glyph
->charpos
= CHARPOS (it
->position
);
1454 glyph
->object
= it
->object
;
1456 ++it
->glyph_row
->used
[it
->area
];
1462 /* Produce glyphs for the display element described by IT. *IT
1463 specifies what we want to produce a glyph for (character, image, ...),
1464 and where in the glyph matrix we currently are (glyph row and hpos).
1465 produce_glyphs fills in output fields of *IT with information such as the
1466 pixel width and height of a character, and maybe output actual glyphs at
1467 the same time if IT->glyph_row is non-null. See the explanation of
1468 struct display_iterator in dispextern.h for an overview.
1470 produce_glyphs also stores the result of glyph width, ascent
1471 etc. computations in *IT.
1473 IT->glyph_row may be null, in which case produce_glyphs does not
1474 actually fill in the glyphs. This is used in the move_* functions
1475 in xdisp.c for text width and height computations.
1477 Callers usually don't call produce_glyphs directly;
1478 instead they use the macro PRODUCE_GLYPHS. */
1484 /* If a hook is installed, let it do the work. */
1485 xassert (it
->what
== IT_CHARACTER
1486 || it
->what
== IT_COMPOSITION
1487 || it
->what
== IT_STRETCH
);
1489 if (it
->what
== IT_STRETCH
)
1491 produce_stretch_glyph (it
);
1495 /* Nothing but characters are supported on terminal frames. For a
1496 composition sequence, it->c is the first character of the
1498 xassert (it
->what
== IT_CHARACTER
1499 || it
->what
== IT_COMPOSITION
);
1501 /* Maybe translate single-byte characters to multibyte. */
1502 it
->char_to_display
= it
->c
;
1504 if (it
->c
>= 040 && it
->c
< 0177)
1506 it
->pixel_width
= it
->nglyphs
= 1;
1510 else if (it
->c
== '\n')
1511 it
->pixel_width
= it
->nglyphs
= 0;
1512 else if (it
->c
== '\t')
1514 int absolute_x
= (it
->current_x
1515 + it
->continuation_lines_width
);
1517 = (((1 + absolute_x
+ it
->tab_width
- 1)
1522 /* If part of the TAB has been displayed on the previous line
1523 which is continued now, continuation_lines_width will have
1524 been incremented already by the part that fitted on the
1525 continued line. So, we will get the right number of spaces
1527 nspaces
= next_tab_x
- absolute_x
;
1533 it
->char_to_display
= ' ';
1534 it
->pixel_width
= it
->len
= 1;
1540 it
->pixel_width
= nspaces
;
1541 it
->nglyphs
= nspaces
;
1543 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1545 if (unibyte_display_via_language_environment
1547 || !NILP (Vnonascii_translation_table
)))
1551 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1552 charset
= CHAR_CHARSET (it
->char_to_display
);
1553 it
->pixel_width
= CHARSET_WIDTH (charset
);
1554 it
->nglyphs
= it
->pixel_width
;
1560 /* Coming here means that it->c is from display table, thus we
1561 must send the code as is to the terminal. Although there's
1562 no way to know how many columns it occupies on a screen, it
1563 is a good assumption that a single byte code has 1-column
1565 it
->pixel_width
= it
->nglyphs
= 1;
1572 /* A multi-byte character. The display width is fixed for all
1573 characters of the set. Some of the glyphs may have to be
1574 ignored because they are already displayed in a continued
1576 int charset
= CHAR_CHARSET (it
->c
);
1578 it
->pixel_width
= CHARSET_WIDTH (charset
);
1579 it
->nglyphs
= it
->pixel_width
;
1586 /* Advance current_x by the pixel width as a convenience for
1588 if (it
->area
== TEXT_AREA
)
1589 it
->current_x
+= it
->pixel_width
;
1590 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1591 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1595 /* Produce a stretch glyph for iterator IT. IT->object is the value
1596 of the glyph property displayed. The value must be a list
1597 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1600 1. `:width WIDTH' specifies that the space should be WIDTH *
1601 canonical char width wide. WIDTH may be an integer or floating
1604 2. `:align-to HPOS' specifies that the space should be wide enough
1605 to reach HPOS, a value in canonical character units. */
1608 produce_stretch_glyph (it
)
1611 /* (space :width WIDTH ...) */
1612 Lisp_Object prop
, plist
;
1613 int width
= 0, align_to
= -1;
1614 int zero_width_ok_p
= 0;
1617 /* List should start with `space'. */
1618 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1619 plist
= XCDR (it
->object
);
1621 /* Compute the width of the stretch. */
1622 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1623 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1625 /* Absolute width `:width WIDTH' specified and valid. */
1626 zero_width_ok_p
= 1;
1627 width
= (int)(tem
+ 0.5);
1629 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1630 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1632 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1633 align_to
= (align_to
< 0
1635 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1636 else if (align_to
< 0)
1637 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1638 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1639 zero_width_ok_p
= 1;
1642 /* Nothing specified -> width defaults to canonical char width. */
1643 width
= FRAME_COLUMN_WIDTH (it
->f
);
1645 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1648 if (width
> 0 && it
->glyph_row
)
1650 Lisp_Object o_object
= it
->object
;
1651 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1654 if (!STRINGP (object
))
1655 object
= it
->w
->buffer
;
1656 it
->object
= object
;
1657 it
->char_to_display
= ' ';
1658 it
->pixel_width
= it
->len
= 1;
1661 it
->object
= o_object
;
1663 it
->pixel_width
= width
;
1664 it
->nglyphs
= width
;
1668 /* Get information about special display element WHAT in an
1669 environment described by IT. WHAT is one of IT_TRUNCATION or
1670 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1671 non-null glyph_row member. This function ensures that fields like
1672 face_id, c, len of IT are left untouched. */
1675 produce_special_glyphs (it
, what
)
1677 enum display_element_type what
;
1684 temp_it
.what
= IT_CHARACTER
;
1686 temp_it
.object
= make_number (0);
1687 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1689 if (what
== IT_CONTINUATION
)
1691 /* Continuation glyph. */
1693 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1694 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1696 glyph
= XINT (DISP_CONTINUE_GLYPH (it
->dp
));
1697 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
1702 else if (what
== IT_TRUNCATION
)
1704 /* Truncation glyph. */
1706 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1707 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1709 glyph
= XINT (DISP_TRUNC_GLYPH (it
->dp
));
1710 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
1718 temp_it
.c
= FAST_GLYPH_CHAR (glyph
);
1719 temp_it
.face_id
= FAST_GLYPH_FACE (glyph
);
1720 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1722 produce_glyphs (&temp_it
);
1723 it
->pixel_width
= temp_it
.pixel_width
;
1724 it
->nglyphs
= temp_it
.pixel_width
;
1729 /***********************************************************************
1731 ***********************************************************************/
1733 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1734 one of the enumerators from enum no_color_bit, or a bit set built
1735 from them. Some display attributes may not be used together with
1736 color; the termcap capability `NC' specifies which ones. */
1738 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1739 (tty->TN_max_colors > 0 \
1740 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1743 /* Turn appearances of face FACE_ID on tty frame F on.
1744 FACE_ID is a realized face ID number, in the face cache. */
1747 turn_on_face (f
, face_id
)
1751 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1752 long fg
= face
->foreground
;
1753 long bg
= face
->background
;
1754 struct tty_display_info
*tty
= FRAME_TTY (f
);
1756 /* Do this first because TS_end_standout_mode may be the same
1757 as TS_exit_attribute_mode, which turns all appearances off. */
1758 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1760 if (tty
->TN_max_colors
> 0)
1762 if (fg
>= 0 && bg
>= 0)
1764 /* If the terminal supports colors, we can set them
1765 below without using reverse video. The face's fg
1766 and bg colors are set as they should appear on
1767 the screen, i.e. they take the inverse-video'ness
1768 of the face already into account. */
1770 else if (inverse_video
)
1772 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1773 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1774 tty_toggle_highlight (tty
);
1778 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1779 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1780 tty_toggle_highlight (tty
);
1785 /* If we can't display colors, use reverse video
1786 if the face specifies that. */
1789 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1790 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1791 tty_toggle_highlight (tty
);
1795 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1796 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1797 tty_toggle_highlight (tty
);
1802 if (face
->tty_bold_p
)
1804 if (MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1805 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1807 else if (face
->tty_dim_p
)
1808 if (MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1809 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1811 /* Alternate charset and blinking not yet used. */
1812 if (face
->tty_alt_charset_p
1813 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1814 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1816 if (face
->tty_blinking_p
1817 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1818 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1820 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1821 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1823 if (tty
->TN_max_colors
> 0)
1827 ts
= tty
->standout_mode
? tty
->TS_set_background
: tty
->TS_set_foreground
;
1830 p
= tparam (ts
, NULL
, 0, (int) fg
);
1835 ts
= tty
->standout_mode
? tty
->TS_set_foreground
: tty
->TS_set_background
;
1838 p
= tparam (ts
, NULL
, 0, (int) bg
);
1846 /* Turn off appearances of face FACE_ID on tty frame F. */
1849 turn_off_face (f
, face_id
)
1853 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1854 struct tty_display_info
*tty
= FRAME_TTY (f
);
1856 xassert (face
!= NULL
);
1858 if (tty
->TS_exit_attribute_mode
)
1860 /* Capability "me" will turn off appearance modes double-bright,
1861 half-bright, reverse-video, standout, underline. It may or
1862 may not turn off alt-char-mode. */
1863 if (face
->tty_bold_p
1865 || face
->tty_reverse_p
1866 || face
->tty_alt_charset_p
1867 || face
->tty_blinking_p
1868 || face
->tty_underline_p
)
1870 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
1871 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
1872 tty
->standout_mode
= 0;
1875 if (face
->tty_alt_charset_p
)
1876 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1880 /* If we don't have "me" we can only have those appearances
1881 that have exit sequences defined. */
1882 if (face
->tty_alt_charset_p
)
1883 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1885 if (face
->tty_underline_p
)
1886 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
1889 /* Switch back to default colors. */
1890 if (tty
->TN_max_colors
> 0
1891 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
1892 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
1893 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
1894 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
1895 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
1899 /* Return non-zero if the terminal on frame F supports all of the
1900 capabilities in CAPS simultaneously, with foreground and background
1901 colors FG and BG. */
1904 tty_capable_p (tty
, caps
, fg
, bg
)
1905 struct tty_display_info
*tty
;
1907 unsigned long fg
, bg
;
1909 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
1910 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
1913 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
1914 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
1915 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
1916 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
1917 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
1918 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
1924 /* Return non-zero if the terminal is capable to display colors. */
1926 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
1928 doc
: /* Return non-nil if the tty device TERMINAL can display colors.
1930 TERMINAL can be a terminal id, a frame or nil (meaning the selected
1931 frame's terminal). This function always returns nil if TERMINAL
1932 is not on a tty device. */)
1934 Lisp_Object terminal
;
1936 struct terminal
*t
= get_tty_terminal (terminal
, 0);
1940 return t
->display_info
.tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
1943 /* Return the number of supported colors. */
1944 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
1945 Stty_display_color_cells
, 0, 1, 0,
1946 doc
: /* Return the number of colors supported by the tty device TERMINAL.
1948 TERMINAL can be a terminal id, a frame or nil (meaning the selected
1949 frame's terminal). This function always returns 0 if TERMINAL
1950 is not on a tty device. */)
1952 Lisp_Object terminal
;
1954 struct terminal
*t
= get_tty_terminal (terminal
, 0);
1956 return make_number (0);
1958 return make_number (t
->display_info
.tty
->TN_max_colors
);
1963 /* Declare here rather than in the function, as in the rest of Emacs,
1964 to work around an HPUX compiler bug (?). See
1965 http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00410.html */
1966 static int default_max_colors
;
1967 static int default_max_pairs
;
1968 static int default_no_color_video
;
1969 static char *default_orig_pair
;
1970 static char *default_set_foreground
;
1971 static char *default_set_background
;
1973 /* Save or restore the default color-related capabilities of this
1976 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
1981 if (default_orig_pair
)
1982 xfree (default_orig_pair
);
1983 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
1985 if (default_set_foreground
)
1986 xfree (default_set_foreground
);
1987 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
1990 if (default_set_background
)
1991 xfree (default_set_background
);
1992 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
1995 default_max_colors
= tty
->TN_max_colors
;
1996 default_max_pairs
= tty
->TN_max_pairs
;
1997 default_no_color_video
= tty
->TN_no_color_video
;
2001 tty
->TS_orig_pair
= default_orig_pair
;
2002 tty
->TS_set_foreground
= default_set_foreground
;
2003 tty
->TS_set_background
= default_set_background
;
2004 tty
->TN_max_colors
= default_max_colors
;
2005 tty
->TN_max_pairs
= default_max_pairs
;
2006 tty
->TN_no_color_video
= default_no_color_video
;
2010 /* Setup one of the standard tty color schemes according to MODE.
2011 MODE's value is generally the number of colors which we want to
2012 support; zero means set up for the default capabilities, the ones
2013 we saw at init_tty time; -1 means turn off color support. */
2015 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2017 /* Canonicalize all negative values of MODE. */
2023 case -1: /* no colors at all */
2024 tty
->TN_max_colors
= 0;
2025 tty
->TN_max_pairs
= 0;
2026 tty
->TN_no_color_video
= 0;
2027 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2029 case 0: /* default colors, if any */
2031 tty_default_color_capabilities (tty
, 0);
2033 case 8: /* 8 standard ANSI colors */
2034 tty
->TS_orig_pair
= "\033[0m";
2036 tty
->TS_set_foreground
= "\033[3%p1%dm";
2037 tty
->TS_set_background
= "\033[4%p1%dm";
2039 tty
->TS_set_foreground
= "\033[3%dm";
2040 tty
->TS_set_background
= "\033[4%dm";
2042 tty
->TN_max_colors
= 8;
2043 tty
->TN_max_pairs
= 64;
2044 tty
->TN_no_color_video
= 0;
2050 set_tty_color_mode (f
, val
)
2054 Lisp_Object color_mode_spec
, current_mode_spec
;
2055 Lisp_Object color_mode
, current_mode
;
2057 extern Lisp_Object Qtty_color_mode
;
2058 Lisp_Object tty_color_mode_alist
;
2060 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2067 if (NILP (tty_color_mode_alist
))
2068 color_mode_spec
= Qnil
;
2070 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2072 if (CONSP (color_mode_spec
))
2073 color_mode
= XCDR (color_mode_spec
);
2078 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2080 if (CONSP (current_mode_spec
))
2081 current_mode
= XCDR (current_mode_spec
);
2083 current_mode
= Qnil
;
2084 if (INTEGERP (color_mode
))
2085 mode
= XINT (color_mode
);
2087 mode
= 0; /* meaning default */
2088 if (INTEGERP (current_mode
))
2089 old_mode
= XINT (current_mode
);
2093 if (mode
!= old_mode
)
2095 tty_setup_colors (FRAME_TTY (f
), mode
);
2096 /* This recomputes all the faces given the new color
2098 call0 (intern ("tty-set-up-initial-frame-faces"));
2103 #endif /* !WINDOWSNT */
2107 /* Return the tty display object specified by TERMINAL. */
2110 get_tty_terminal (Lisp_Object terminal
, int throw)
2112 struct terminal
*t
= get_terminal (terminal
, throw);
2114 if (t
&& t
->type
!= output_termcap
)
2117 error ("Device %d is not a termcap terminal device", t
->id
);
2125 /* Return an active termcap device that uses the tty device with the
2128 This function ignores suspended devices.
2130 Returns NULL if the named terminal device is not opened. */
2133 get_named_tty (name
)
2141 for (t
= terminal_list
; t
; t
= t
->next_terminal
)
2143 if (t
->type
== output_termcap
2144 && !strcmp (t
->display_info
.tty
->name
, name
)
2145 && TERMINAL_ACTIVE_P (t
))
2153 DEFUN ("tty-type", Ftty_type
, Stty_type
, 0, 1, 0,
2154 doc
: /* Return the type of the tty device that TERMINAL uses.
2155 Returns nil if TERMINAL is not on a tty device.
2157 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2158 frame's terminal). */)
2160 Lisp_Object terminal
;
2162 struct terminal
*t
= get_terminal (terminal
, 1);
2164 if (t
->type
!= output_termcap
)
2167 if (t
->display_info
.tty
->type
)
2168 return build_string (t
->display_info
.tty
->type
);
2173 DEFUN ("controlling-tty-p", Fcontrolling_tty_p
, Scontrolling_tty_p
, 0, 1, 0,
2174 doc
: /* Return non-nil if TERMINAL is on the controlling tty of the Emacs process.
2176 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2177 frame's terminal). This function always returns nil if TERMINAL
2178 is not on a tty device. */)
2180 Lisp_Object terminal
;
2182 struct terminal
*t
= get_terminal (terminal
, 1);
2184 if (t
->type
!= output_termcap
|| strcmp (t
->display_info
.tty
->name
, DEV_TTY
))
2190 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 1, 0,
2191 doc
: /* Declare that the tty used by TERMINAL does not handle underlining.
2192 This is used to override the terminfo data, for certain terminals that
2193 do not really do underlining, but say that they do. This function has
2194 no effect if used on a non-tty terminal.
2196 TERMINAL can be a terminal id, a frame or nil (meaning the selected
2197 frame's terminal). This function always returns nil if TERMINAL
2198 is not on a tty device. */)
2200 Lisp_Object terminal
;
2202 struct terminal
*t
= get_terminal (terminal
, 1);
2204 if (t
->type
== output_termcap
)
2205 t
->display_info
.tty
->TS_enter_underline_mode
= 0;
2211 DEFUN ("suspend-tty", Fsuspend_tty
, Ssuspend_tty
, 0, 1, 0,
2212 doc
: /* Suspend the terminal device TTY.
2214 The device is restored to its default state, and Emacs ceases all
2215 access to the tty device. Frames that use the device are not deleted,
2216 but input is not read from them and if they change, their display is
2219 TTY may be a terminal id, a frame, or nil for the terminal device of
2220 the currently selected frame.
2222 This function runs `suspend-tty-functions' after suspending the
2223 device. The functions are run with one arg, the id of the suspended
2226 `suspend-tty' does nothing if it is called on a device that is already
2229 A suspended tty may be resumed by calling `resume-tty' on it. */)
2233 struct terminal
*t
= get_tty_terminal (tty
, 1);
2237 error ("Unknown tty device");
2239 f
= t
->display_info
.tty
->input
;
2243 /* First run `suspend-tty-functions' and then clean up the tty
2244 state because `suspend-tty-functions' might need to change
2246 if (!NILP (Vrun_hooks
))
2248 Lisp_Object args
[2];
2249 args
[0] = intern ("suspend-tty-functions");
2250 XSETTERMINAL (args
[1], t
);
2251 Frun_hook_with_args (2, args
);
2254 reset_sys_modes (t
->display_info
.tty
);
2256 delete_keyboard_wait_descriptor (fileno (f
));
2259 if (f
!= t
->display_info
.tty
->output
)
2260 fclose (t
->display_info
.tty
->output
);
2262 t
->display_info
.tty
->input
= 0;
2263 t
->display_info
.tty
->output
= 0;
2265 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2266 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 0);
2270 /* Clear display hooks to prevent further output. */
2271 clear_tty_hooks (t
);
2276 DEFUN ("resume-tty", Fresume_tty
, Sresume_tty
, 0, 1, 0,
2277 doc
: /* Resume the previously suspended terminal device TTY.
2278 The terminal is opened and reinitialized. Frames that are on the
2279 suspended terminal are revived.
2281 It is an error to resume a terminal while another terminal is active
2284 This function runs `resume-tty-functions' after resuming the terminal.
2285 The functions are run with one arg, the id of the resumed terminal
2288 `resume-tty' does nothing if it is called on a device that is not
2291 TTY may be a terminal id, a frame, or nil for the terminal device of
2292 the currently selected frame. */)
2296 struct terminal
*t
= get_tty_terminal (tty
, 1);
2300 error ("Unknown tty device");
2302 if (!t
->display_info
.tty
->input
)
2304 if (get_named_tty (t
->display_info
.tty
->name
))
2305 error ("Cannot resume display while another display is active on the same device");
2307 fd
= emacs_open (t
->display_info
.tty
->name
, O_RDWR
| O_NOCTTY
, 0);
2310 error ("Can not reopen tty device %s: %s", t
->display_info
.tty
->name
, strerror (errno
));
2312 if (strcmp (t
->display_info
.tty
->name
, DEV_TTY
))
2313 dissociate_if_controlling_tty (fd
);
2315 t
->display_info
.tty
->output
= fdopen (fd
, "w+");
2316 t
->display_info
.tty
->input
= t
->display_info
.tty
->output
;
2318 add_keyboard_wait_descriptor (fd
);
2320 if (FRAMEP (t
->display_info
.tty
->top_frame
))
2321 FRAME_SET_VISIBLE (XFRAME (t
->display_info
.tty
->top_frame
), 1);
2323 init_sys_modes (t
->display_info
.tty
);
2325 /* Run `resume-tty-functions'. */
2326 if (!NILP (Vrun_hooks
))
2328 Lisp_Object args
[2];
2329 args
[0] = intern ("resume-tty-functions");
2330 XSETTERMINAL (args
[1], t
);
2331 Frun_hook_with_args (2, args
);
2341 /***********************************************************************
2343 ***********************************************************************/
2347 term_mouse_moveto (int x
, int y
)
2349 /* TODO: how to set mouse position?
2352 name = (const char *) ttyname (0);
2353 fd = open (name, O_WRONLY);
2354 SOME_FUNCTION (x, y, fd);
2357 last_mouse_y = y; */
2361 term_show_mouse_face (enum draw_glyphs_face draw
)
2363 struct window
*w
= XWINDOW (mouse_face_window
);
2367 struct frame
*f
= XFRAME (w
->frame
);
2368 struct tty_display_info
*tty
= FRAME_TTY (f
);
2370 if (/* If window is in the process of being destroyed, don't bother
2372 w
->current_matrix
!= NULL
2373 /* Recognize when we are called to operate on rows that don't exist
2374 anymore. This can happen when a window is split. */
2375 && mouse_face_end_row
< w
->current_matrix
->nrows
)
2377 /* write_glyphs writes at cursor position, so we need to
2378 temporarily move cursor coordinates to the beginning of
2379 the highlight region. */
2381 /* Save current cursor co-ordinates */
2382 save_y
= curY (tty
);
2383 save_x
= curX (tty
);
2385 /* Note that mouse_face_beg_row etc. are window relative. */
2386 for (i
= mouse_face_beg_row
; i
<= mouse_face_end_row
; i
++)
2388 int start_hpos
, end_hpos
, nglyphs
;
2389 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
2391 /* Don't do anything if row doesn't have valid contents. */
2392 if (!row
->enabled_p
)
2395 /* For all but the first row, the highlight starts at column 0. */
2396 if (i
== mouse_face_beg_row
)
2397 start_hpos
= mouse_face_beg_col
;
2401 if (i
== mouse_face_end_row
)
2402 end_hpos
= mouse_face_end_col
;
2405 end_hpos
= row
->used
[TEXT_AREA
];
2406 if (draw
== DRAW_NORMAL_TEXT
)
2407 row
->fill_line_p
= 1; /* Clear to end of line */
2410 if (end_hpos
<= start_hpos
)
2412 /* Record that some glyphs of this row are displayed in
2414 row
->mouse_face_p
= draw
> 0;
2416 nglyphs
= end_hpos
- start_hpos
;
2418 if (end_hpos
>= row
->used
[TEXT_AREA
])
2419 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2421 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2422 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
2423 + WINDOW_LEFT_EDGE_X (w
);
2425 cursor_to (f
, pos_y
, pos_x
);
2427 if (draw
== DRAW_MOUSE_FACE
)
2429 tty_write_glyphs_with_face (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
,
2430 nglyphs
, mouse_face_face_id
);
2432 else /* draw == DRAW_NORMAL_TEXT */
2433 write_glyphs (f
, row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2435 cursor_to (f
, save_y
, save_x
);
2440 term_clear_mouse_face ()
2442 if (!NILP (mouse_face_window
))
2443 term_show_mouse_face (DRAW_NORMAL_TEXT
);
2445 mouse_face_beg_row
= mouse_face_beg_col
= -1;
2446 mouse_face_end_row
= mouse_face_end_col
= -1;
2447 mouse_face_window
= Qnil
;
2450 /* Find the glyph matrix position of buffer position POS in window W.
2451 *HPOS and *VPOS are set to the positions found. W's current glyphs
2452 must be up to date. If POS is above window start return (0, 0).
2453 If POS is after end of W, return end of last line in W.
2454 - taken from msdos.c */
2456 fast_find_position (struct window
*w
, int pos
, int *hpos
, int *vpos
)
2458 int i
, lastcol
, line_start_position
, maybe_next_line_p
= 0;
2459 int yb
= window_text_bottom_y (w
);
2460 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0), *best_row
= row
;
2464 if (row
->used
[TEXT_AREA
])
2465 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
2467 line_start_position
= 0;
2469 if (line_start_position
> pos
)
2471 /* If the position sought is the end of the buffer,
2472 don't include the blank lines at the bottom of the window. */
2473 else if (line_start_position
== pos
2474 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
2476 maybe_next_line_p
= 1;
2479 else if (line_start_position
> 0)
2482 /* Don't overstep the last matrix row, lest we get into the
2483 never-never land... */
2484 if (row
->y
+ 1 >= yb
)
2490 /* Find the right column within BEST_ROW. */
2493 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
2495 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + i
;
2498 charpos
= glyph
->charpos
;
2505 else if (charpos
> pos
)
2507 else if (charpos
> 0)
2511 /* If we're looking for the end of the buffer,
2512 and we didn't find it in the line we scanned,
2513 use the start of the following line. */
2514 if (maybe_next_line_p
)
2521 *hpos
= lastcol
+ 1;
2526 term_mouse_highlight (struct frame
*f
, int x
, int y
)
2528 enum window_part part
;
2533 if (NILP (Vmouse_highlight
)
2534 || !f
->glyphs_initialized_p
)
2537 /* Which window is that in? */
2538 window
= window_from_coordinates (f
, x
, y
, &part
, &x
, &y
, 0);
2540 /* Not on a window -> return. */
2541 if (!WINDOWP (window
))
2544 if (!EQ (window
, mouse_face_window
))
2545 term_clear_mouse_face ();
2547 w
= XWINDOW (window
);
2549 /* Are we in a window whose display is up to date?
2550 And verify the buffer's text has not changed. */
2551 b
= XBUFFER (w
->buffer
);
2553 && EQ (w
->window_end_valid
, w
->buffer
)
2554 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
2555 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
2557 int pos
, i
, nrows
= w
->current_matrix
->nrows
;
2558 struct glyph_row
*row
;
2559 struct glyph
*glyph
;
2561 /* Find the glyph under X/Y. */
2563 if (y
>= 0 && y
< nrows
)
2565 row
= MATRIX_ROW (w
->current_matrix
, y
);
2566 /* Give up if some row before the one we are looking for is
2568 for (i
= 0; i
<= y
; i
++)
2569 if (!MATRIX_ROW (w
->current_matrix
, i
)->enabled_p
)
2571 if (i
> y
/* all rows upto and including the one at Y are enabled */
2572 && row
->displays_text_p
2573 && x
< window_box_width (w
, TEXT_AREA
))
2575 glyph
= row
->glyphs
[TEXT_AREA
];
2576 if (x
>= row
->used
[TEXT_AREA
])
2581 if (!BUFFERP (glyph
->object
))
2587 /* Clear mouse face if X/Y not over text. */
2590 term_clear_mouse_face ();
2594 if (!BUFFERP (glyph
->object
))
2596 pos
= glyph
->charpos
;
2598 /* Check for mouse-face. */
2600 extern Lisp_Object Qmouse_face
;
2601 Lisp_Object mouse_face
, overlay
, position
, *overlay_vec
;
2602 int noverlays
, obegv
, ozv
;
2603 struct buffer
*obuf
;
2605 /* If we get an out-of-range value, return now; avoid an error. */
2606 if (pos
> BUF_Z (b
))
2609 /* Make the window's buffer temporarily current for
2610 overlays_at and compute_char_face. */
2611 obuf
= current_buffer
;
2618 /* Is this char mouse-active? */
2619 XSETINT (position
, pos
);
2621 /* Put all the overlays we want in a vector in overlay_vec. */
2622 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
2623 /* Sort overlays into increasing priority order. */
2624 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
2626 /* Check mouse-face highlighting. */
2627 if (!(EQ (window
, mouse_face_window
)
2628 && y
>= mouse_face_beg_row
2629 && y
<= mouse_face_end_row
2630 && (y
> mouse_face_beg_row
2631 || x
>= mouse_face_beg_col
)
2632 && (y
< mouse_face_end_row
2633 || x
< mouse_face_end_col
2634 || mouse_face_past_end
)))
2636 /* Clear the display of the old active region, if any. */
2637 term_clear_mouse_face ();
2639 /* Find the highest priority overlay that has a mouse-face
2642 for (i
= noverlays
- 1; i
>= 0; --i
)
2644 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
2645 if (!NILP (mouse_face
))
2647 overlay
= overlay_vec
[i
];
2652 /* If no overlay applies, get a text property. */
2654 mouse_face
= Fget_text_property (position
, Qmouse_face
,
2657 /* Handle the overlay case. */
2658 if (!NILP (overlay
))
2660 /* Find the range of text around this char that
2661 should be active. */
2662 Lisp_Object before
, after
;
2666 before
= Foverlay_start (overlay
);
2667 after
= Foverlay_end (overlay
);
2668 /* Record this as the current active region. */
2669 fast_find_position (w
, XFASTINT (before
),
2670 &mouse_face_beg_col
,
2671 &mouse_face_beg_row
);
2674 = !fast_find_position (w
, XFASTINT (after
),
2675 &mouse_face_end_col
,
2676 &mouse_face_end_row
);
2677 mouse_face_window
= window
;
2680 = face_at_buffer_position (w
, pos
, 0, 0,
2681 &ignore
, pos
+ 1, 1);
2683 /* Display it as active. */
2684 term_show_mouse_face (DRAW_MOUSE_FACE
);
2686 /* Handle the text property case. */
2687 else if (!NILP (mouse_face
))
2689 /* Find the range of text around this char that
2690 should be active. */
2691 Lisp_Object before
, after
, beginning
, end
;
2694 beginning
= Fmarker_position (w
->start
);
2695 XSETINT (end
, (BUF_Z (b
) - XFASTINT (w
->window_end_pos
)));
2697 = Fprevious_single_property_change (make_number (pos
+ 1),
2699 w
->buffer
, beginning
);
2701 = Fnext_single_property_change (position
, Qmouse_face
,
2704 /* Record this as the current active region. */
2705 fast_find_position (w
, XFASTINT (before
),
2706 &mouse_face_beg_col
,
2707 &mouse_face_beg_row
);
2709 = !fast_find_position (w
, XFASTINT (after
),
2710 &mouse_face_end_col
,
2711 &mouse_face_end_row
);
2712 mouse_face_window
= window
;
2715 = face_at_buffer_position (w
, pos
, 0, 0,
2716 &ignore
, pos
+ 1, 1);
2718 /* Display it as active. */
2719 term_show_mouse_face (DRAW_MOUSE_FACE
);
2723 /* Look for a `help-echo' property. */
2726 extern Lisp_Object Qhelp_echo
;
2728 /* Check overlays first. */
2730 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
2732 overlay
= overlay_vec
[i
];
2733 help
= Foverlay_get (overlay
, Qhelp_echo
);
2738 help_echo_string
= help
;
2739 help_echo_window
= window
;
2740 help_echo_object
= overlay
;
2741 help_echo_pos
= pos
;
2743 /* Try text properties. */
2744 else if (NILP (help
)
2745 && ((STRINGP (glyph
->object
)
2746 && glyph
->charpos
>= 0
2747 && glyph
->charpos
< SCHARS (glyph
->object
))
2748 || (BUFFERP (glyph
->object
)
2749 && glyph
->charpos
>= BEGV
2750 && glyph
->charpos
< ZV
)))
2752 help
= Fget_text_property (make_number (glyph
->charpos
),
2753 Qhelp_echo
, glyph
->object
);
2756 help_echo_string
= help
;
2757 help_echo_window
= window
;
2758 help_echo_object
= glyph
->object
;
2759 help_echo_pos
= glyph
->charpos
;
2766 current_buffer
= obuf
;
2772 term_mouse_movement (FRAME_PTR frame
, Gpm_Event
*event
)
2774 /* Has the mouse moved off the glyph it was on at the last sighting? */
2775 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2777 frame
->mouse_moved
= 1;
2778 term_mouse_highlight (frame
, event
->x
, event
->y
);
2779 /* Remember which glyph we're now on. */
2780 last_mouse_x
= event
->x
;
2781 last_mouse_y
= event
->y
;
2787 /* Return the current position of the mouse.
2789 Set *f to the frame the mouse is in, or zero if the mouse is in no
2790 Emacs frame. If it is set to zero, all the other arguments are
2793 Set *bar_window to Qnil, and *x and *y to the column and
2794 row of the character cell the mouse is over.
2796 Set *time to the time the mouse was at the returned position.
2798 This clears mouse_moved until the next motion
2801 term_mouse_position (FRAME_PTR
*fp
, int insist
, Lisp_Object
*bar_window
,
2802 enum scroll_bar_part
*part
, Lisp_Object
*x
,
2803 Lisp_Object
*y
, unsigned long *time
)
2807 *fp
= SELECTED_FRAME ();
2808 (*fp
)->mouse_moved
= 0;
2813 XSETINT (*x
, last_mouse_x
);
2814 XSETINT (*y
, last_mouse_y
);
2815 gettimeofday(&now
, 0);
2816 *time
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2819 /* Prepare a mouse-event in *RESULT for placement in the input queue.
2821 If the event is a button press, then note that we have grabbed
2825 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
2831 result
->kind
= GPM_CLICK_EVENT
;
2832 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
2834 if (event
->buttons
& j
) {
2835 result
->code
= i
; /* button number */
2839 gettimeofday(&now
, 0);
2840 result
->timestamp
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2842 if (event
->type
& GPM_UP
)
2843 result
->modifiers
= up_modifier
;
2844 else if (event
->type
& GPM_DOWN
)
2845 result
->modifiers
= down_modifier
;
2847 result
->modifiers
= 0;
2849 if (event
->type
& GPM_SINGLE
)
2850 result
->modifiers
|= click_modifier
;
2852 if (event
->type
& GPM_DOUBLE
)
2853 result
->modifiers
|= double_modifier
;
2855 if (event
->type
& GPM_TRIPLE
)
2856 result
->modifiers
|= triple_modifier
;
2858 if (event
->type
& GPM_DRAG
)
2859 result
->modifiers
|= drag_modifier
;
2861 if (!(event
->type
& (GPM_MOVE
| GPM_DRAG
))) {
2864 if (event
->modifiers
& (1 << 0))
2865 result
->modifiers
|= shift_modifier
;
2868 if (event
->modifiers
& (1 << 2))
2869 result
->modifiers
|= ctrl_modifier
;
2871 /* 1 << KG_ALT || KG_ALTGR */
2872 if (event
->modifiers
& (1 << 3)
2873 || event
->modifiers
& (1 << 1))
2874 result
->modifiers
|= meta_modifier
;
2877 XSETINT (result
->x
, event
->x
);
2878 XSETINT (result
->y
, event
->y
);
2879 XSETFRAME (result
->frame_or_window
, f
);
2885 handle_one_term_event (struct tty_display_info
*tty
, Gpm_Event
*event
, struct input_event
* hold_quit
)
2887 struct frame
*f
= XFRAME (tty
->top_frame
);
2888 struct input_event ie
;
2896 if (event
->type
& (GPM_MOVE
| GPM_DRAG
)) {
2897 previous_help_echo_string
= help_echo_string
;
2898 help_echo_string
= Qnil
;
2900 Gpm_DrawPointer (event
->x
, event
->y
, fileno (tty
->output
));
2902 if (!term_mouse_movement (f
, event
))
2903 help_echo_string
= previous_help_echo_string
;
2905 /* If the contents of the global variable help_echo_string
2906 has changed, generate a HELP_EVENT. */
2907 if (!NILP (help_echo_string
)
2908 || !NILP (previous_help_echo_string
))
2915 term_mouse_click (&ie
, event
, f
);
2919 if (ie
.kind
!= NO_EVENT
)
2921 kbd_buffer_store_event_hold (&ie
, hold_quit
);
2926 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
2931 XSETFRAME (frame
, f
);
2935 gen_help_event (help_echo_string
, frame
, help_echo_window
,
2936 help_echo_object
, help_echo_pos
);
2943 DEFUN ("gpm-mouse-start", Fgpm_mouse_start
, Sgpm_mouse_start
,
2945 doc
: /* Open a connection to Gpm.
2946 Gpm-mouse can only be activated for one tty at a time. */)
2949 struct frame
*f
= SELECTED_FRAME ();
2950 struct tty_display_info
*tty
2951 = ((f
)->output_method
== output_termcap
2952 ? (f
)->terminal
->display_info
.tty
: NULL
);
2953 Gpm_Connect connection
;
2956 error ("Gpm-mouse can only be activated for one tty at a time");
2958 error ("Gpm-mouse only works in the GNU/Linux console");
2960 connection
.eventMask
= ~0;
2961 connection
.defaultMask
= ~GPM_HARD
;
2962 connection
.maxMod
= ~0;
2963 connection
.minMod
= 0;
2966 if (Gpm_Open (&connection
, 0) < 0)
2967 error ("Gpm-mouse failed to connect to the gpm daemon");
2971 /* `init_sys_modes' arranges for mouse movements sent through gpm_fd
2972 to generate SIGIOs. Apparently we need to call reset_sys_modes
2973 before calling init_sys_modes. */
2974 reset_sys_modes (tty
);
2975 init_sys_modes (tty
);
2976 add_gpm_wait_descriptor (gpm_fd
);
2981 DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop
, Sgpm_mouse_stop
,
2983 doc
: /* Close a connection to Gpm. */)
2987 delete_gpm_wait_descriptor (gpm_fd
);
2988 while (Gpm_Close()); /* close all the stack */
2992 #endif /* HAVE_GPM */
2995 /***********************************************************************
2997 ***********************************************************************/
2999 /* Initialize the tty-dependent part of frame F. The frame must
3000 already have its device initialized. */
3003 create_tty_output (struct frame
*f
)
3005 struct tty_output
*t
;
3007 if (! FRAME_TERMCAP_P (f
))
3010 t
= xmalloc (sizeof (struct tty_output
));
3011 bzero (t
, sizeof (struct tty_output
));
3013 t
->display_info
= FRAME_TERMINAL (f
)->display_info
.tty
;
3015 f
->output_data
.tty
= t
;
3018 /* Delete the tty-dependent part of frame F. */
3021 delete_tty_output (struct frame
*f
)
3023 if (! FRAME_TERMCAP_P (f
))
3026 xfree (f
->output_data
.tty
);
3030 /* Reset the hooks in TERMINAL. */
3033 clear_tty_hooks (struct terminal
*terminal
)
3036 terminal
->cursor_to_hook
= 0;
3037 terminal
->raw_cursor_to_hook
= 0;
3038 terminal
->clear_to_end_hook
= 0;
3039 terminal
->clear_frame_hook
= 0;
3040 terminal
->clear_end_of_line_hook
= 0;
3041 terminal
->ins_del_lines_hook
= 0;
3042 terminal
->insert_glyphs_hook
= 0;
3043 terminal
->write_glyphs_hook
= 0;
3044 terminal
->delete_glyphs_hook
= 0;
3045 terminal
->ring_bell_hook
= 0;
3046 terminal
->reset_terminal_modes_hook
= 0;
3047 terminal
->set_terminal_modes_hook
= 0;
3048 terminal
->update_begin_hook
= 0;
3049 terminal
->update_end_hook
= 0;
3050 terminal
->set_terminal_window_hook
= 0;
3051 terminal
->mouse_position_hook
= 0;
3052 terminal
->frame_rehighlight_hook
= 0;
3053 terminal
->frame_raise_lower_hook
= 0;
3054 terminal
->fullscreen_hook
= 0;
3055 terminal
->set_vertical_scroll_bar_hook
= 0;
3056 terminal
->condemn_scroll_bars_hook
= 0;
3057 terminal
->redeem_scroll_bar_hook
= 0;
3058 terminal
->judge_scroll_bars_hook
= 0;
3059 terminal
->read_socket_hook
= 0;
3060 terminal
->frame_up_to_date_hook
= 0;
3062 /* Leave these two set, or suspended frames are not deleted
3064 terminal
->delete_frame_hook
= &delete_tty_output
;
3065 terminal
->delete_terminal_hook
= &delete_tty
;
3068 /* Initialize hooks in TERMINAL with the values needed for a tty. */
3071 set_tty_hooks (struct terminal
*terminal
)
3073 terminal
->rif
= 0; /* ttys don't support window-based redisplay. */
3075 terminal
->cursor_to_hook
= &tty_cursor_to
;
3076 terminal
->raw_cursor_to_hook
= &tty_raw_cursor_to
;
3078 terminal
->clear_to_end_hook
= &tty_clear_to_end
;
3079 terminal
->clear_frame_hook
= &tty_clear_frame
;
3080 terminal
->clear_end_of_line_hook
= &tty_clear_end_of_line
;
3082 terminal
->ins_del_lines_hook
= &tty_ins_del_lines
;
3084 terminal
->insert_glyphs_hook
= &tty_insert_glyphs
;
3085 terminal
->write_glyphs_hook
= &tty_write_glyphs
;
3086 terminal
->delete_glyphs_hook
= &tty_delete_glyphs
;
3088 terminal
->ring_bell_hook
= &tty_ring_bell
;
3090 terminal
->reset_terminal_modes_hook
= &tty_reset_terminal_modes
;
3091 terminal
->set_terminal_modes_hook
= &tty_set_terminal_modes
;
3092 terminal
->update_begin_hook
= 0; /* Not needed. */
3093 terminal
->update_end_hook
= &tty_update_end
;
3094 terminal
->set_terminal_window_hook
= &tty_set_terminal_window
;
3096 terminal
->mouse_position_hook
= 0; /* Not needed. */
3097 terminal
->frame_rehighlight_hook
= 0; /* Not needed. */
3098 terminal
->frame_raise_lower_hook
= 0; /* Not needed. */
3100 terminal
->set_vertical_scroll_bar_hook
= 0; /* Not needed. */
3101 terminal
->condemn_scroll_bars_hook
= 0; /* Not needed. */
3102 terminal
->redeem_scroll_bar_hook
= 0; /* Not needed. */
3103 terminal
->judge_scroll_bars_hook
= 0; /* Not needed. */
3105 terminal
->read_socket_hook
= &tty_read_avail_input
; /* keyboard.c */
3106 terminal
->frame_up_to_date_hook
= 0; /* Not needed. */
3108 terminal
->delete_frame_hook
= &delete_tty_output
;
3109 terminal
->delete_terminal_hook
= &delete_tty
;
3112 /* Drop the controlling terminal if fd is the same device. */
3114 dissociate_if_controlling_tty (int fd
)
3118 EMACS_GET_TTY_PGRP (fd
, &pgid
); /* If tcgetpgrp succeeds, fd is the ctty. */
3121 #if defined (USG) && !defined (BSD_PGRPS)
3123 no_controlling_tty
= 1;
3124 #elif defined (CYGWIN)
3126 no_controlling_tty
= 1;
3128 #ifdef TIOCNOTTY /* Try BSD ioctls. */
3129 sigblock (sigmask (SIGTTOU
));
3130 fd
= emacs_open (DEV_TTY
, O_RDWR
, 0);
3131 if (fd
!= -1 && ioctl (fd
, TIOCNOTTY
, 0) != -1)
3133 no_controlling_tty
= 1;
3137 sigunblock (sigmask (SIGTTOU
));
3139 /* Unknown system. */
3141 #endif /* ! TIOCNOTTY */
3144 #endif /* !WINDOWSNT */
3147 static void maybe_fatal();
3149 /* Create a termcap display on the tty device with the given name and
3152 If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
3153 Otherwise NAME should be a path to the tty device file,
3156 TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
3158 If MUST_SUCCEED is true, then all errors are fatal. */
3161 init_tty (char *name
, char *terminal_type
, int must_succeed
)
3164 char **address
= &area
;
3165 char *buffer
= NULL
;
3166 int buffer_size
= 4096;
3167 register char *p
= NULL
;
3169 struct tty_display_info
*tty
= NULL
;
3170 struct terminal
*terminal
= NULL
;
3171 int ctty
= 0; /* 1 if asked to open controlling tty. */
3174 maybe_fatal (must_succeed
, 0, 0,
3175 "Unknown terminal type",
3176 "Unknown terminal type");
3180 if (!strcmp (name
, DEV_TTY
))
3183 /* If we already have a terminal on the given device, use that. If
3184 all such terminals are suspended, create a new one instead. */
3185 /* XXX Perhaps this should be made explicit by having init_tty
3186 always create a new terminal and separating terminal and frame
3187 creation on Lisp level. */
3188 terminal
= get_named_tty (name
);
3192 terminal
= create_terminal ();
3193 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
3194 bzero (tty
, sizeof (struct tty_display_info
));
3195 tty
->next
= tty_list
;
3198 terminal
->type
= output_termcap
;
3199 terminal
->display_info
.tty
= tty
;
3200 tty
->terminal
= terminal
;
3202 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
3206 set_tty_hooks (terminal
);
3212 #ifdef O_IGNORE_CTTY
3214 /* Open the terminal device. Don't recognize it as our
3215 controlling terminal, and don't make it the controlling tty
3216 if we don't have one at the moment. */
3217 fd
= emacs_open (name
, O_RDWR
| O_IGNORE_CTTY
| O_NOCTTY
, 0);
3220 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
3221 defined on Hurd. On other systems, we need to explicitly
3222 dissociate ourselves from the controlling tty when we want to
3223 open a frame on the same terminal. */
3224 fd
= emacs_open (name
, O_RDWR
| O_NOCTTY
, 0);
3225 #endif /* O_IGNORE_CTTY */
3228 maybe_fatal (must_succeed
, buffer
, terminal
,
3229 "Could not open file: %s",
3230 "Could not open file: %s",
3235 maybe_fatal (must_succeed
, buffer
, terminal
,
3236 "Not a tty device: %s",
3237 "Not a tty device: %s",
3241 #ifndef O_IGNORE_CTTY
3243 dissociate_if_controlling_tty (fd
);
3246 file
= fdopen (fd
, "w+");
3247 tty
->name
= xstrdup (name
);
3248 terminal
->name
= xstrdup (name
);
3253 tty
->type
= xstrdup (terminal_type
);
3255 add_keyboard_wait_descriptor (fileno (tty
->input
));
3259 encode_terminal_bufsize
= 0;
3262 terminal
->mouse_position_hook
= term_mouse_position
;
3263 mouse_face_window
= Qnil
;
3267 initialize_w32_display (terminal
);
3268 /* The following two are inaccessible from w32console.c. */
3269 terminal
->delete_frame_hook
= &delete_tty_output
;
3270 terminal
->delete_terminal_hook
= &delete_tty
;
3272 tty
->name
= xstrdup (name
);
3273 terminal
->name
= xstrdup (name
);
3274 tty
->type
= xstrdup (terminal_type
);
3276 tty
->output
= stdout
;
3278 add_keyboard_wait_descriptor (0);
3283 struct frame
*f
= XFRAME (selected_frame
);
3285 FrameRows (tty
) = FRAME_LINES (f
);
3286 FrameCols (tty
) = FRAME_COLS (f
);
3287 tty
->specified_window
= FRAME_LINES (f
);
3289 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
3290 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
3292 tty
->delete_in_insert_mode
= 1;
3295 terminal
->scroll_region_ok
= 0;
3297 /* Seems to insert lines when it's not supposed to, messing up the
3298 display. In doing a trace, it didn't seem to be called much, so I
3299 don't think we're losing anything by turning it off. */
3300 terminal
->line_ins_del_ok
= 0;
3301 terminal
->char_ins_del_ok
= 1;
3305 tty
->TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
3307 #else /* not WINDOWSNT */
3311 buffer
= (char *) xmalloc (buffer_size
);
3313 /* On some systems, tgetent tries to access the controlling
3315 sigblock (sigmask (SIGTTOU
));
3316 status
= tgetent (buffer
, terminal_type
);
3317 sigunblock (sigmask (SIGTTOU
));
3322 maybe_fatal (must_succeed
, buffer
, terminal
,
3323 "Cannot open terminfo database file",
3324 "Cannot open terminfo database file");
3326 maybe_fatal (must_succeed
, buffer
, terminal
,
3327 "Cannot open termcap database file",
3328 "Cannot open termcap database file");
3334 maybe_fatal (must_succeed
, buffer
, terminal
,
3335 "Terminal type %s is not defined",
3336 "Terminal type %s is not defined.\n\
3337 If that is not the actual type of terminal you have,\n\
3338 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3339 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3340 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3343 maybe_fatal (must_succeed
, buffer
, terminal
,
3344 "Terminal type %s is not defined",
3345 "Terminal type %s is not defined.\n\
3346 If that is not the actual type of terminal you have,\n\
3347 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3348 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3349 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3355 if (strlen (buffer
) >= buffer_size
)
3357 buffer_size
= strlen (buffer
);
3359 area
= (char *) xmalloc (buffer_size
);
3361 tty
->TS_ins_line
= tgetstr ("al", address
);
3362 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
3363 tty
->TS_bell
= tgetstr ("bl", address
);
3364 BackTab (tty
) = tgetstr ("bt", address
);
3365 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
3366 tty
->TS_clr_line
= tgetstr ("ce", address
);
3367 tty
->TS_clr_frame
= tgetstr ("cl", address
);
3368 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
3369 AbsPosition (tty
) = tgetstr ("cm", address
);
3370 CR (tty
) = tgetstr ("cr", address
);
3371 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
3372 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
3373 RowPosition (tty
) = tgetstr ("cv", address
);
3374 tty
->TS_del_char
= tgetstr ("dc", address
);
3375 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
3376 tty
->TS_del_line
= tgetstr ("dl", address
);
3377 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
3378 tty
->TS_delete_mode
= tgetstr ("dm", address
);
3379 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
3380 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
3381 Home (tty
) = tgetstr ("ho", address
);
3382 tty
->TS_ins_char
= tgetstr ("ic", address
);
3383 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
3384 tty
->TS_insert_mode
= tgetstr ("im", address
);
3385 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
3386 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
3387 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
3388 LastLine (tty
) = tgetstr ("ll", address
);
3389 Right (tty
) = tgetstr ("nd", address
);
3390 Down (tty
) = tgetstr ("do", address
);
3392 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
3394 /* VMS puts a carriage return before each linefeed,
3395 so it is not safe to use linefeeds. */
3396 if (Down (tty
) && Down (tty
)[0] == '\n' && Down (tty
)[1] == '\0')
3399 if (tgetflag ("bs"))
3400 Left (tty
) = "\b"; /* can't possibly be longer! */
3401 else /* (Actually, "bs" is obsolete...) */
3402 Left (tty
) = tgetstr ("le", address
);
3404 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
3405 tty
->TS_pad_char
= tgetstr ("pc", address
);
3406 tty
->TS_repeat
= tgetstr ("rp", address
);
3407 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
3408 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
3409 tty
->TS_standout_mode
= tgetstr ("so", address
);
3410 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
3411 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
3412 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
3413 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
3414 Up (tty
) = tgetstr ("up", address
);
3415 tty
->TS_visible_bell
= tgetstr ("vb", address
);
3416 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
3417 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
3418 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
3419 tty
->TS_set_window
= tgetstr ("wi", address
);
3421 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
3422 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
3423 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
3424 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
3425 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
3426 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
3427 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3428 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3429 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
3431 MultiUp (tty
) = tgetstr ("UP", address
);
3432 MultiDown (tty
) = tgetstr ("DO", address
);
3433 MultiLeft (tty
) = tgetstr ("LE", address
);
3434 MultiRight (tty
) = tgetstr ("RI", address
);
3436 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
3437 color because we can't switch back to the default foreground and
3439 tty
->TS_orig_pair
= tgetstr ("op", address
);
3440 if (tty
->TS_orig_pair
)
3442 tty
->TS_set_foreground
= tgetstr ("AF", address
);
3443 tty
->TS_set_background
= tgetstr ("AB", address
);
3444 if (!tty
->TS_set_foreground
)
3447 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
3448 tty
->TS_set_background
= tgetstr ("Sb", address
);
3451 tty
->TN_max_colors
= tgetnum ("Co");
3452 tty
->TN_max_pairs
= tgetnum ("pa");
3454 tty
->TN_no_color_video
= tgetnum ("NC");
3455 if (tty
->TN_no_color_video
== -1)
3456 tty
->TN_no_color_video
= 0;
3459 tty_default_color_capabilities (tty
, 1);
3461 MagicWrap (tty
) = tgetflag ("xn");
3462 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3463 the former flag imply the latter. */
3464 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
3465 terminal
->memory_below_frame
= tgetflag ("db");
3466 tty
->TF_hazeltine
= tgetflag ("hz");
3467 terminal
->must_write_spaces
= tgetflag ("in");
3468 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
3469 tty
->TF_insmode_motion
= tgetflag ("mi");
3470 tty
->TF_standout_motion
= tgetflag ("ms");
3471 tty
->TF_underscore
= tgetflag ("ul");
3472 tty
->TF_teleray
= tgetflag ("xt");
3474 #endif /* !WINDOWSNT */
3476 terminal
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
3477 init_kboard (terminal
->kboard
);
3478 terminal
->kboard
->next_kboard
= all_kboards
;
3479 all_kboards
= terminal
->kboard
;
3480 terminal
->kboard
->reference_count
++;
3481 /* Don't let the initial kboard remain current longer than necessary.
3482 That would cause problems if a file loaded on startup tries to
3483 prompt in the mini-buffer. */
3484 if (current_kboard
== initial_kboard
)
3485 current_kboard
= terminal
->kboard
;
3487 term_get_fkeys (address
, terminal
->kboard
);
3492 /* Get frame size from system, or else from termcap. */
3495 get_tty_size (fileno (tty
->input
), &width
, &height
);
3496 FrameCols (tty
) = width
;
3497 FrameRows (tty
) = height
;
3500 if (FrameCols (tty
) <= 0)
3501 FrameCols (tty
) = tgetnum ("co");
3502 if (FrameRows (tty
) <= 0)
3503 FrameRows (tty
) = tgetnum ("li");
3505 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
3506 maybe_fatal (must_succeed
, NULL
, terminal
,
3507 "Screen size %dx%d is too small"
3508 "Screen size %dx%d is too small",
3509 FrameCols (tty
), FrameRows (tty
));
3511 #if 0 /* This is not used anywhere. */
3512 tty
->terminal
->min_padding_speed
= tgetnum ("pb");
3515 TabWidth (tty
) = tgetnum ("tw");
3518 /* These capabilities commonly use ^J.
3519 I don't know why, but sending them on VMS does not work;
3520 it causes following spaces to be lost, sometimes.
3521 For now, the simplest fix is to avoid using these capabilities ever. */
3522 if (Down (tty
) && Down (tty
)[0] == '\n')
3527 tty
->TS_bell
= "\07";
3529 if (!tty
->TS_fwd_scroll
)
3530 tty
->TS_fwd_scroll
= Down (tty
);
3532 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
3534 if (TabWidth (tty
) < 0)
3537 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3538 and newer termcap doc does not seem to say there is a default.
3539 if (!tty->Wcm->cm_tab)
3540 tty->Wcm->cm_tab = "\t";
3543 /* We don't support standout modes that use `magic cookies', so
3544 turn off any that do. */
3545 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
3547 tty
->TS_standout_mode
= 0;
3548 tty
->TS_end_standout_mode
= 0;
3550 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3552 tty
->TS_enter_underline_mode
= 0;
3553 tty
->TS_exit_underline_mode
= 0;
3556 /* If there's no standout mode, try to use underlining instead. */
3557 if (tty
->TS_standout_mode
== 0)
3559 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
3560 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
3563 /* If no `se' string, try using a `me' string instead.
3564 If that fails, we can't use standout mode at all. */
3565 if (tty
->TS_end_standout_mode
== 0)
3567 char *s
= tgetstr ("me", address
);
3569 tty
->TS_end_standout_mode
= s
;
3571 tty
->TS_standout_mode
= 0;
3574 if (tty
->TF_teleray
)
3576 tty
->Wcm
->cm_tab
= 0;
3577 /* We can't support standout mode, because it uses magic cookies. */
3578 tty
->TS_standout_mode
= 0;
3579 /* But that means we cannot rely on ^M to go to column zero! */
3581 /* LF can't be trusted either -- can alter hpos */
3582 /* if move at column 0 thru a line with TS_standout_mode */
3586 /* Special handling for certain terminal types known to need it */
3588 if (!strcmp (terminal_type
, "supdup"))
3590 terminal
->memory_below_frame
= 1;
3591 tty
->Wcm
->cm_losewrap
= 1;
3593 if (!strncmp (terminal_type
, "c10", 3)
3594 || !strcmp (terminal_type
, "perq"))
3596 /* Supply a makeshift :wi string.
3597 This string is not valid in general since it works only
3598 for windows starting at the upper left corner;
3599 but that is all Emacs uses.
3601 This string works only if the frame is using
3602 the top of the video memory, because addressing is memory-relative.
3603 So first check the :ti string to see if that is true.
3605 It would be simpler if the :wi string could go in the termcap
3606 entry, but it can't because it is not fully valid.
3607 If it were in the termcap entry, it would confuse other programs. */
3608 if (!tty
->TS_set_window
)
3610 p
= tty
->TS_termcap_modes
;
3611 while (*p
&& strcmp (p
, "\033v "))
3614 tty
->TS_set_window
= "\033v%C %C %C %C ";
3616 /* Termcap entry often fails to have :in: flag */
3617 terminal
->must_write_spaces
= 1;
3618 /* :ti string typically fails to have \E^G! in it */
3619 /* This limits scope of insert-char to one line. */
3620 strcpy (area
, tty
->TS_termcap_modes
);
3621 strcat (area
, "\033\007!");
3622 tty
->TS_termcap_modes
= area
;
3623 area
+= strlen (area
) + 1;
3624 p
= AbsPosition (tty
);
3625 /* Change all %+ parameters to %C, to handle
3626 values above 96 correctly for the C100. */
3629 if (p
[0] == '%' && p
[1] == '+')
3635 tty
->specified_window
= FrameRows (tty
);
3637 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
3639 maybe_fatal (must_succeed
, NULL
, terminal
,
3640 "Terminal type \"%s\" is not powerful enough to run Emacs",
3642 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3643 It lacks the ability to position the cursor.\n\
3644 If that is not the actual type of terminal you have, use either the\n\
3645 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
3646 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
3649 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3650 It lacks the ability to position the cursor.\n\
3651 If that is not the actual type of terminal you have,\n\
3652 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3653 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3654 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3655 # else /* TERMCAP */
3656 "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3657 It lacks the ability to position the cursor.\n\
3658 If that is not the actual type of terminal you have,\n\
3659 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3660 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3661 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3662 # endif /* TERMINFO */
3667 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
3668 maybe_fatal (must_succeed
, NULL
, terminal
,
3669 "Could not determine the frame size",
3670 "Could not determine the frame size");
3672 tty
->delete_in_insert_mode
3673 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
3674 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
3676 tty
->se_is_so
= (tty
->TS_standout_mode
3677 && tty
->TS_end_standout_mode
3678 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
3680 UseTabs (tty
) = tabs_safe_p (fileno (tty
->input
)) && TabWidth (tty
) == 8;
3682 terminal
->scroll_region_ok
3684 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
3686 terminal
->line_ins_del_ok
3687 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
3688 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
3689 || (terminal
->scroll_region_ok
3690 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
3692 terminal
->char_ins_del_ok
3693 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
3694 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
3695 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
3697 terminal
->fast_clear_end_of_line
= tty
->TS_clr_line
!= 0;
3699 init_baud_rate (fileno (tty
->input
));
3702 /* The HFT system on AIX doesn't optimize for scrolling, so it's
3703 really ugly at times. */
3704 terminal
->line_ins_del_ok
= 0;
3705 terminal
->char_ins_del_ok
= 0;
3708 /* Don't do this. I think termcap may still need the buffer. */
3709 /* xfree (buffer); */
3711 #endif /* not WINDOWSNT */
3713 /* Init system terminal modes (RAW or CBREAK, etc.). */
3714 init_sys_modes (tty
);
3719 /* Auxiliary error-handling function for init_tty.
3720 Free BUFFER and delete TERMINAL, then call error or fatal
3721 with str1 or str2, respectively, according to MUST_SUCCEED. */
3724 maybe_fatal (must_succeed
, buffer
, terminal
, str1
, str2
, arg1
, arg2
)
3727 struct terminal
*terminal
;
3728 char *str1
, *str2
, *arg1
, *arg2
;
3734 delete_tty (terminal
);
3737 fatal (str2
, arg1
, arg2
);
3739 error (str1
, arg1
, arg2
);
3746 fatal (str
, arg1
, arg2
)
3747 char *str
, *arg1
, *arg2
;
3749 fprintf (stderr
, "emacs: ");
3750 fprintf (stderr
, str
, arg1
, arg2
);
3751 fprintf (stderr
, "\n");
3758 /* Delete the given tty terminal, closing all frames on it. */
3761 delete_tty (struct terminal
*terminal
)
3763 struct tty_display_info
*tty
;
3764 Lisp_Object tail
, frame
;
3767 /* Protect against recursive calls. Fdelete_frame in
3768 delete_terminal calls us back when it deletes our last frame. */
3769 if (!terminal
->name
)
3772 if (terminal
->type
!= output_termcap
)
3775 tty
= terminal
->display_info
.tty
;
3778 FOR_EACH_FRAME (tail
, frame
)
3780 struct frame
*f
= XFRAME (frame
);
3781 if (FRAME_LIVE_P (f
) && (!FRAME_TERMCAP_P (f
) || FRAME_TTY (f
) != tty
))
3788 error ("Attempt to delete the sole terminal device with live frames");
3790 if (tty
== tty_list
)
3791 tty_list
= tty
->next
;
3794 struct tty_display_info
*p
;
3795 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
3799 /* This should not happen. */
3802 p
->next
= tty
->next
;
3806 /* reset_sys_modes needs a valid device, so this call needs to be
3807 before delete_terminal. */
3808 reset_sys_modes (tty
);
3810 delete_terminal (terminal
);
3820 delete_keyboard_wait_descriptor (fileno (tty
->input
));
3821 if (tty
->input
!= stdin
)
3822 fclose (tty
->input
);
3824 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
3825 fclose (tty
->output
);
3826 if (tty
->termscript
)
3827 fclose (tty
->termscript
);
3830 xfree (tty
->old_tty
);
3835 bzero (tty
, sizeof (struct tty_display_info
));
3841 /* Mark the pointers in the tty_display_info objects.
3842 Called by the Fgarbage_collector. */
3847 struct tty_display_info
*tty
;
3849 for (tty
= tty_list
; tty
; tty
= tty
->next
)
3850 mark_object (tty
->top_frame
);
3858 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
3859 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3860 This variable can be used by terminal emulator packages. */);
3862 system_uses_terminfo
= 1;
3864 system_uses_terminfo
= 0;
3867 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions
,
3868 doc
: /* Functions to be run after suspending a tty.
3869 The functions are run with one argument, the terminal id to be suspended.
3870 See `suspend-tty'. */);
3871 Vsuspend_tty_functions
= Qnil
;
3874 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions
,
3875 doc
: /* Functions to be run after resuming a tty.
3876 The functions are run with one argument, the terminal id that was revived.
3877 See `resume-tty'. */);
3878 Vresume_tty_functions
= Qnil
;
3880 DEFVAR_BOOL ("visible-cursor", &visible_cursor
,
3881 doc
: /* Non-nil means to make the cursor very visible.
3882 This only has an effect when running in a text terminal.
3883 What means \"very visible\" is up to your terminal. It may make the cursor
3884 bigger, or it may make it blink, or it may do nothing at all. */);
3887 defsubr (&Stty_display_color_p
);
3888 defsubr (&Stty_display_color_cells
);
3889 defsubr (&Stty_no_underline
);
3890 defsubr (&Stty_type
);
3891 defsubr (&Scontrolling_tty_p
);
3892 defsubr (&Ssuspend_tty
);
3893 defsubr (&Sresume_tty
);
3895 defsubr (&Sgpm_mouse_start
);
3896 defsubr (&Sgpm_mouse_stop
);
3898 staticpro (&mouse_face_window
);
3899 #endif /* HAVE_GPM */
3904 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
3905 (do not change this comment) */