1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 86, 87, 93, 94, 95, 98, 2000, 2001, 2002
3 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 2, 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., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
32 #include "systty.h" /* For emacs_tty in termchar.h */
40 #include "termhooks.h"
41 #include "dispextern.h"
45 /* For now, don't try to include termcap.h. On some systems,
46 configure finds a non-standard termcap.h that the main build
49 #if defined HAVE_TERMCAP_H && 0
52 extern void tputs
P_ ((const char *, int, int (*)(int)));
53 extern int tgetent
P_ ((char *, const char *));
54 extern int tgetflag
P_ ((char *id
));
55 extern int tgetnum
P_ ((char *id
));
70 static void turn_on_face
P_ ((struct frame
*, int face_id
));
71 static void turn_off_face
P_ ((struct frame
*, int face_id
));
72 static void tty_show_cursor
P_ ((struct tty_display_info
*));
73 static void tty_hide_cursor
P_ ((struct tty_display_info
*));
75 void delete_tty
P_ ((struct tty_display_info
*));
76 static void delete_tty_1
P_ ((struct tty_display_info
*));
79 #define OUTPUT(tty, a) \
80 emacs_tputs ((tty), a, \
81 (int) (FRAME_LINES (XFRAME (selected_frame)) \
85 #define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
86 #define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
88 #define OUTPUT_IF(tty, a) \
91 emacs_tputs ((tty), a, \
92 (int) (FRAME_LINES (XFRAME (selected_frame)) \
97 #define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
99 /* Function to use to ring the bell. */
101 Lisp_Object Vring_bell_function
;
103 /* Terminal characteristics that higher levels want to look at. */
105 struct tty_display_info
*tty_list
;
107 /* Nonzero means no need to redraw the entire frame on resuming a
108 suspended Emacs. This is useful on terminals with multiple
109 pages, where one page is used for Emacs and another for all
111 int no_redraw_on_reenter
;
113 Lisp_Object Qframe_tty_name
, Qframe_tty_type
;
115 /* Hook functions that you can set to snap out the functions in this file.
116 These are all extern'd in termhooks.h */
118 void (*cursor_to_hook
) P_ ((int, int));
119 void (*raw_cursor_to_hook
) P_ ((int, int));
120 void (*clear_to_end_hook
) P_ ((void));
121 void (*clear_frame_hook
) P_ ((void));
122 void (*clear_end_of_line_hook
) P_ ((int));
124 void (*ins_del_lines_hook
) P_ ((int, int));
126 void (*delete_glyphs_hook
) P_ ((int));
128 void (*ring_bell_hook
) P_ ((void));
130 void (*reset_terminal_modes_hook
) P_ ((void));
131 void (*set_terminal_modes_hook
) P_ ((void));
132 void (*update_begin_hook
) P_ ((struct frame
*));
133 void (*update_end_hook
) P_ ((struct frame
*));
134 void (*set_terminal_window_hook
) P_ ((int));
135 void (*insert_glyphs_hook
) P_ ((struct glyph
*, int));
136 void (*write_glyphs_hook
) P_ ((struct glyph
*, int));
137 void (*delete_glyphs_hook
) P_ ((int));
139 int (*read_socket_hook
) P_ ((struct input_event
*, int, int));
141 void (*frame_up_to_date_hook
) P_ ((struct frame
*));
143 /* Return the current position of the mouse.
145 Set *f to the frame the mouse is in, or zero if the mouse is in no
146 Emacs frame. If it is set to zero, all the other arguments are
149 If the motion started in a scroll bar, set *bar_window to the
150 scroll bar's window, *part to the part the mouse is currently over,
151 *x to the position of the mouse along the scroll bar, and *y to the
152 overall length of the scroll bar.
154 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
155 row of the character cell the mouse is over.
157 Set *time to the time the mouse was at the returned position.
159 This should clear mouse_moved until the next motion
162 void (*mouse_position_hook
) P_ ((FRAME_PTR
*f
, int insist
,
163 Lisp_Object
*bar_window
,
164 enum scroll_bar_part
*part
,
167 unsigned long *time
));
169 /* When reading from a minibuffer in a different frame, Emacs wants
170 to shift the highlight from the selected frame to the mini-buffer's
171 frame; under X, this means it lies about where the focus is.
172 This hook tells the window system code to re-decide where to put
175 void (*frame_rehighlight_hook
) P_ ((FRAME_PTR f
));
177 /* If we're displaying frames using a window system that can stack
178 frames on top of each other, this hook allows you to bring a frame
179 to the front, or bury it behind all the other windows. If this
180 hook is zero, that means the device we're displaying on doesn't
181 support overlapping frames, so there's no need to raise or lower
184 If RAISE is non-zero, F is brought to the front, before all other
185 windows. If RAISE is zero, F is sent to the back, behind all other
188 void (*frame_raise_lower_hook
) P_ ((FRAME_PTR f
, int raise
));
190 /* Set the vertical scroll bar for WINDOW to have its upper left corner
191 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
192 indicate that we are displaying PORTION characters out of a total
193 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
194 have a scroll bar, create one for it. */
196 void (*set_vertical_scroll_bar_hook
)
197 P_ ((struct window
*window
,
198 int portion
, int whole
, int position
));
201 /* The following three hooks are used when we're doing a thorough
202 redisplay of the frame. We don't explicitly know which scroll bars
203 are going to be deleted, because keeping track of when windows go
204 away is a real pain - can you say set-window-configuration?
205 Instead, we just assert at the beginning of redisplay that *all*
206 scroll bars are to be removed, and then save scroll bars from the
207 fiery pit when we actually redisplay their window. */
209 /* Arrange for all scroll bars on FRAME to be removed at the next call
210 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
211 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
213 This should be applied to each frame each time its window tree is
214 redisplayed, even if it is not displaying scroll bars at the moment;
215 if the HAS_SCROLL_BARS flag has just been turned off, only calling
216 this and the judge_scroll_bars_hook will get rid of them.
218 If non-zero, this hook should be safe to apply to any frame,
219 whether or not it can support scroll bars, and whether or not it is
220 currently displaying them. */
222 void (*condemn_scroll_bars_hook
) P_ ((FRAME_PTR frame
));
224 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
225 Note that it's okay to redeem a scroll bar that is not condemned. */
227 void (*redeem_scroll_bar_hook
) P_ ((struct window
*window
));
229 /* Remove all scroll bars on FRAME that haven't been saved since the
230 last call to `*condemn_scroll_bars_hook'.
232 This should be applied to each frame after each time its window
233 tree is redisplayed, even if it is not displaying scroll bars at the
234 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
235 calling this and condemn_scroll_bars_hook will get rid of them.
237 If non-zero, this hook should be safe to apply to any frame,
238 whether or not it can support scroll bars, and whether or not it is
239 currently displaying them. */
241 void (*judge_scroll_bars_hook
) P_ ((FRAME_PTR FRAME
));
244 /* Meaning of bits in no_color_video. Each bit set means that the
245 corresponding attribute cannot be combined with colors. */
249 NC_STANDOUT
= 1 << 0,
250 NC_UNDERLINE
= 1 << 1,
257 NC_ALT_CHARSET
= 1 << 8
262 /* The largest frame width in any call to calculate_costs. */
266 /* The largest frame height in any call to calculate_costs. */
270 /* Frame currently being redisplayed; 0 if not currently redisplaying.
271 (Direct output does not count). */
273 FRAME_PTR updating_frame
;
275 /* Provided for lisp packages. */
277 static int system_uses_terminfo
;
281 extern char *tgetstr ();
285 /* We aren't X windows, but we aren't termcap either. This makes me
286 uncertain as to what value to use for frame.output_method. For
287 this file, we'll define FRAME_TERMCAP_P to be zero so that our
288 output hooks get called instead of the termcap functions. Probably
289 the best long-term solution is to define an output_windows_nt... */
291 #undef FRAME_TERMCAP_P
292 #define FRAME_TERMCAP_P(_f_) 0
293 #endif /* WINDOWSNT */
298 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
300 if (!NILP (Vring_bell_function
))
302 Lisp_Object function
;
304 /* Temporarily set the global variable to nil
305 so that if we get an error, it stays nil
306 and we don't call it over and over.
308 We don't specbind it, because that would carefully
309 restore the bad value if there's an error
310 and make the loop of errors happen anyway. */
312 function
= Vring_bell_function
;
313 Vring_bell_function
= Qnil
;
317 Vring_bell_function
= function
;
319 else if (!FRAME_TERMCAP_P (f
))
320 (*ring_bell_hook
) ();
322 struct tty_display_info
*tty
= FRAME_TTY (f
);
323 OUTPUT (tty
, tty
->TS_visible_bell
&& visible_bell
? tty
->TS_visible_bell
: tty
->TS_bell
);
327 void tty_set_terminal_modes (struct tty_display_info
*tty
)
329 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
330 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
331 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
336 set_terminal_modes ()
338 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
339 if (FRAME_TERMCAP_P (f
))
340 tty_set_terminal_modes (FRAME_TTY (f
));
342 (*set_terminal_modes_hook
) ();
345 void tty_reset_terminal_modes (struct tty_display_info
*tty
)
347 turn_off_highlight (tty
);
348 turn_off_insert (tty
);
349 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
350 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
351 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
352 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
353 /* Output raw CR so kernel can track the cursor hpos. */
359 reset_terminal_modes ()
361 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
362 if (FRAME_TERMCAP_P (f
))
363 tty_reset_terminal_modes (FRAME_TTY (f
));
364 else if (reset_terminal_modes_hook
)
365 (*reset_terminal_modes_hook
) ();
373 if (!FRAME_TERMCAP_P (f
))
374 update_begin_hook (f
);
381 if (FRAME_TERMCAP_P (f
))
383 struct tty_display_info
*tty
= FRAME_TTY (f
);
384 if (!XWINDOW (selected_window
)->cursor_off_p
)
385 tty_show_cursor (tty
);
386 turn_off_insert (tty
);
387 background_highlight (tty
);
392 updating_frame
= NULL
;
396 set_terminal_window (size
)
399 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
400 if (FRAME_TERMCAP_P (f
))
402 struct tty_display_info
*tty
= FRAME_TTY (f
);
403 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
404 if (TTY_SCROLL_REGION_OK (tty
))
405 set_scroll_region (0, tty
->specified_window
);
408 set_terminal_window_hook (size
);
412 set_scroll_region (start
, stop
)
416 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
417 struct tty_display_info
*tty
= FRAME_TTY (f
);
419 if (tty
->TS_set_scroll_region
)
420 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
421 else if (tty
->TS_set_scroll_region_1
)
422 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
423 FRAME_LINES (f
), start
,
424 FRAME_LINES (f
) - stop
,
427 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
436 turn_on_insert (struct tty_display_info
*tty
)
438 if (!tty
->insert_mode
)
439 OUTPUT (tty
, tty
->TS_insert_mode
);
440 tty
->insert_mode
= 1;
444 turn_off_insert (struct tty_display_info
*tty
)
446 if (tty
->insert_mode
)
447 OUTPUT (tty
, tty
->TS_end_insert_mode
);
448 tty
->insert_mode
= 0;
451 /* Handle highlighting. */
454 turn_off_highlight (struct tty_display_info
*tty
)
456 if (tty
->standout_mode
)
457 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
458 tty
->standout_mode
= 0;
462 turn_on_highlight (struct tty_display_info
*tty
)
464 if (!tty
->standout_mode
)
465 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
466 tty
->standout_mode
= 1;
470 toggle_highlight (struct tty_display_info
*tty
)
472 if (tty
->standout_mode
)
473 turn_off_highlight (tty
);
475 turn_on_highlight (tty
);
479 /* Make cursor invisible. */
482 tty_hide_cursor (struct tty_display_info
*tty
)
484 if (tty
->cursor_hidden
== 0)
486 tty
->cursor_hidden
= 1;
487 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
492 /* Ensure that cursor is visible. */
495 tty_show_cursor (struct tty_display_info
*tty
)
497 if (tty
->cursor_hidden
)
499 tty
->cursor_hidden
= 0;
500 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
501 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
506 /* Set standout mode to the state it should be in for
507 empty space inside windows. What this is,
508 depends on the user option inverse-video. */
511 background_highlight (struct tty_display_info
*tty
)
514 turn_on_highlight (tty
);
516 turn_off_highlight (tty
);
519 /* Set standout mode to the mode specified for the text to be output. */
522 highlight_if_desired (struct tty_display_info
*tty
)
525 turn_on_highlight (tty
);
527 turn_off_highlight (tty
);
531 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
532 frame-relative coordinates. */
535 cursor_to (vpos
, hpos
)
538 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
539 struct tty_display_info
*tty
;
541 if (! FRAME_TERMCAP_P (f
) && cursor_to_hook
)
543 (*cursor_to_hook
) (vpos
, hpos
);
549 /* Detect the case where we are called from reset_sys_modes
550 and the costs have never been calculated. Do nothing. */
551 if (! tty
->costs_set
)
554 if (curY (tty
) == vpos
555 && curX (tty
) == hpos
)
557 if (!tty
->TF_standout_motion
)
558 background_highlight (tty
);
559 if (!tty
->TF_insmode_motion
)
560 turn_off_insert (tty
);
561 cmgoto (tty
, vpos
, hpos
);
564 /* Similar but don't take any account of the wasted characters. */
567 raw_cursor_to (row
, col
)
570 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
571 struct tty_display_info
*tty
;
572 if (! FRAME_TERMCAP_P (f
))
574 (*raw_cursor_to_hook
) (row
, col
);
578 if (curY (tty
) == row
579 && curX (tty
) == col
)
581 if (!tty
->TF_standout_motion
)
582 background_highlight (tty
);
583 if (!tty
->TF_insmode_motion
)
584 turn_off_insert (tty
);
585 cmgoto (tty
, row
, col
);
588 /* Erase operations */
590 /* clear from cursor to end of frame */
596 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
597 struct tty_display_info
*tty
;
599 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (f
))
601 (*clear_to_end_hook
) ();
605 if (tty
->TS_clr_to_bottom
)
607 background_highlight (tty
);
608 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
612 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
615 clear_end_of_line (FRAME_COLS (f
));
620 /* Clear entire frame */
625 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
626 struct tty_display_info
*tty
;
628 if (clear_frame_hook
&& ! FRAME_TERMCAP_P (f
))
630 (*clear_frame_hook
) ();
634 if (tty
->TS_clr_frame
)
636 background_highlight (tty
);
637 OUTPUT (tty
, tty
->TS_clr_frame
);
647 /* Clear from cursor to end of line.
648 Assume that the line is already clear starting at column first_unused_hpos.
650 Note that the cursor may be moved, on terminals lacking a `ce' string. */
653 clear_end_of_line (first_unused_hpos
)
654 int first_unused_hpos
;
656 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
657 struct tty_display_info
*tty
;
659 if (clear_end_of_line_hook
660 && ! FRAME_TERMCAP_P (f
))
662 (*clear_end_of_line_hook
) (first_unused_hpos
);
666 tty_clear_end_of_line (FRAME_TTY (f
), first_unused_hpos
);
670 tty_clear_end_of_line (struct tty_display_info
*tty
, int first_unused_hpos
)
673 /* Detect the case where we are called from reset_sys_modes
674 and the costs have never been calculated. Do nothing. */
675 if (! tty
->costs_set
)
678 if (curX (tty
) >= first_unused_hpos
)
680 background_highlight (tty
);
681 if (tty
->TS_clr_line
)
683 OUTPUT1 (tty
, tty
->TS_clr_line
);
686 { /* have to do it the hard way */
687 turn_off_insert (tty
);
689 /* Do not write in last row last col with Auto-wrap on. */
691 && curY (tty
) == FrameRows (tty
) - 1
692 && first_unused_hpos
== FrameCols (tty
))
695 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
697 if (TTY_TERMSCRIPT (tty
))
698 fputc (' ', TTY_TERMSCRIPT (tty
));
699 fputc (' ', TTY_OUTPUT (tty
));
701 cmplus (tty
, first_unused_hpos
- curX (tty
));
705 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
706 store them at DST. Do not write more than DST_LEN bytes. That may
707 require stopping before all SRC_LEN input glyphs have been
710 We store the number of glyphs actually converted in *CONSUMED. The
711 return value is the number of bytes store in DST. */
714 encode_terminal_code (src
, dst
, src_len
, dst_len
, consumed
)
718 int dst_len
, *consumed
;
720 struct glyph
*src_start
= src
, *src_end
= src
+ src_len
;
721 unsigned char *dst_start
= dst
, *dst_end
= dst
+ dst_len
;
723 unsigned char workbuf
[MAX_MULTIBYTE_LENGTH
];
724 const unsigned char *buf
;
726 register int tlen
= GLYPH_TABLE_LENGTH
;
727 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
729 struct coding_system
*coding
;
731 /* If terminal_coding does any conversion, use it, otherwise use
732 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
733 because it always return 1 if the member src_multibyte is 1. */
734 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
736 : &safe_terminal_coding
);
738 while (src
< src_end
)
740 /* We must skip glyphs to be padded for a wide character. */
741 if (! CHAR_GLYPH_PADDING_P (*src
))
743 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
745 if (g
< 0 || g
>= tlen
)
747 /* This glyph doesn't has an entry in Vglyph_table. */
748 if (! CHAR_VALID_P (src
->u
.ch
, 0))
752 coding
->src_multibyte
= 0;
756 len
= CHAR_STRING (src
->u
.ch
, workbuf
);
758 coding
->src_multibyte
= 1;
763 /* This glyph has an entry in Vglyph_table,
764 so process any alias before testing for simpleness. */
765 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
767 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
769 /* We set the multi-byte form of a character in G
770 (that should be an ASCII character) at
772 workbuf
[0] = FAST_GLYPH_CHAR (g
);
775 coding
->src_multibyte
= 0;
779 /* We have a string in Vglyph_table. */
780 len
= GLYPH_LENGTH (tbase
, g
);
781 buf
= GLYPH_STRING (tbase
, g
);
782 coding
->src_multibyte
= STRING_MULTIBYTE (tbase
[g
]);
786 result
= encode_coding (coding
, buf
, dst
, len
, dst_end
- dst
);
787 len
-= coding
->consumed
;
788 dst
+= coding
->produced
;
789 if (result
== CODING_FINISH_INSUFFICIENT_DST
790 || (result
== CODING_FINISH_INSUFFICIENT_SRC
791 && len
> dst_end
- dst
))
792 /* The remaining output buffer is too short. We must
793 break the loop here without increasing SRC so that the
794 next call of this function starts from the same glyph. */
799 /* This is the case that a code of the range 0200..0237
800 exists in buf. We must just write out such a code. */
801 buf
+= coding
->consumed
;
809 *consumed
= src
- src_start
;
810 return (dst
- dst_start
);
815 write_glyphs (string
, len
)
816 register struct glyph
*string
;
819 int produced
, consumed
;
820 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
821 struct tty_display_info
*tty
;
822 unsigned char conversion_buffer
[1024];
823 int conversion_buffer_size
= sizeof conversion_buffer
;
825 if (write_glyphs_hook
826 && ! FRAME_TERMCAP_P (f
))
828 (*write_glyphs_hook
) (string
, len
);
834 turn_off_insert (tty
);
835 tty_hide_cursor (tty
);
837 /* Don't dare write in last column of bottom line, if Auto-Wrap,
838 since that would scroll the whole frame on some terminals. */
841 && curY (tty
) + 1 == FRAME_LINES (f
)
842 && (curX (tty
) + len
) == FRAME_COLS (f
))
849 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
851 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
855 /* Identify a run of glyphs with the same face. */
856 int face_id
= string
->face_id
;
859 for (n
= 1; n
< len
; ++n
)
860 if (string
[n
].face_id
!= face_id
)
863 /* Turn appearance modes of the face of the run on. */
864 highlight_if_desired (tty
);
865 turn_on_face (f
, face_id
);
869 /* We use a fixed size (1024 bytes) of conversion buffer.
870 Usually it is sufficient, but if not, we just repeat the
872 produced
= encode_terminal_code (string
, conversion_buffer
,
873 n
, conversion_buffer_size
,
877 fwrite (conversion_buffer
, 1, produced
,
879 if (ferror (TTY_OUTPUT (tty
)))
880 clearerr (TTY_OUTPUT (tty
));
881 if (TTY_TERMSCRIPT (tty
))
882 fwrite (conversion_buffer
, 1, produced
,
883 TTY_TERMSCRIPT (tty
));
890 /* Turn appearance modes off. */
891 turn_off_face (f
, face_id
);
892 turn_off_highlight (tty
);
895 /* We may have to output some codes to terminate the writing. */
896 if (CODING_REQUIRE_FLUSHING (&terminal_coding
))
898 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
899 encode_coding (&terminal_coding
, "", conversion_buffer
,
900 0, conversion_buffer_size
);
901 if (terminal_coding
.produced
> 0)
903 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
905 if (ferror (TTY_OUTPUT (tty
)))
906 clearerr (TTY_OUTPUT (tty
));
907 if (TTY_TERMSCRIPT (tty
))
908 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
909 TTY_TERMSCRIPT (tty
));
916 /* If start is zero, insert blanks instead of a string at start */
919 insert_glyphs (start
, len
)
920 register struct glyph
*start
;
924 struct glyph
*glyph
= NULL
;
926 struct tty_display_info
*tty
;
931 if (insert_glyphs_hook
)
933 (*insert_glyphs_hook
) (start
, len
);
937 f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
940 if (tty
->TS_ins_multi_chars
)
942 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
946 write_glyphs (start
, len
);
950 turn_on_insert (tty
);
952 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
953 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
956 int produced
, consumed
;
957 unsigned char conversion_buffer
[1024];
958 int conversion_buffer_size
= sizeof conversion_buffer
;
960 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
963 conversion_buffer
[0] = SPACEGLYPH
;
968 highlight_if_desired (tty
);
969 turn_on_face (f
, start
->face_id
);
972 /* We must open sufficient space for a character which
973 occupies more than one column. */
974 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
976 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
981 /* This is the last glyph. */
982 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
984 /* The size of conversion buffer (1024 bytes) is surely
985 sufficient for just one glyph. */
986 produced
= encode_terminal_code (glyph
, conversion_buffer
, 1,
987 conversion_buffer_size
, &consumed
);
992 fwrite (conversion_buffer
, 1, produced
,
994 if (ferror (TTY_OUTPUT (tty
)))
995 clearerr (TTY_OUTPUT (tty
));
996 if (TTY_TERMSCRIPT (tty
))
997 fwrite (conversion_buffer
, 1, produced
,
998 TTY_TERMSCRIPT (tty
));
1001 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
1004 turn_off_face (f
, glyph
->face_id
);
1005 turn_off_highlight (tty
);
1018 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
1019 struct tty_display_info
*tty
= FRAME_TTY (f
);
1021 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (f
))
1023 (*delete_glyphs_hook
) (n
);
1028 if (tty
->delete_in_insert_mode
)
1030 turn_on_insert (tty
);
1034 turn_off_insert (tty
);
1035 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
1038 if (tty
->TS_del_multi_chars
)
1040 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
1045 for (i
= 0; i
< n
; i
++)
1046 OUTPUT1 (tty
, tty
->TS_del_char
);
1047 if (!tty
->delete_in_insert_mode
)
1048 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
1051 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1054 ins_del_lines (vpos
, n
)
1057 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
1058 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (f
))
1060 (*ins_del_lines_hook
) (vpos
, n
);
1065 struct tty_display_info
*tty
= FRAME_TTY (f
);
1066 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
1067 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
1068 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
1070 register int i
= n
> 0 ? n
: -n
;
1073 /* If the lines below the insertion are being pushed
1074 into the end of the window, this is the same as clearing;
1075 and we know the lines are already clear, since the matching
1076 deletion has already been done. So can ignore this. */
1077 /* If the lines below the deletion are blank lines coming
1078 out of the end of the window, don't bother,
1079 as there will be a matching inslines later that will flush them. */
1080 if (TTY_SCROLL_REGION_OK (tty
)
1081 && vpos
+ i
>= tty
->specified_window
)
1083 if (!TTY_MEMORY_BELOW_FRAME (tty
)
1084 && vpos
+ i
>= FRAME_LINES (f
))
1089 raw_cursor_to (vpos
, 0);
1090 background_highlight (tty
);
1091 buf
= tparam (multi
, 0, 0, i
);
1097 raw_cursor_to (vpos
, 0);
1098 background_highlight (tty
);
1100 OUTPUT (tty
, single
);
1101 if (tty
->TF_teleray
)
1106 set_scroll_region (vpos
, tty
->specified_window
);
1108 raw_cursor_to (tty
->specified_window
- 1, 0);
1110 raw_cursor_to (vpos
, 0);
1111 background_highlight (tty
);
1113 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1114 set_scroll_region (0, tty
->specified_window
);
1117 if (!TTY_SCROLL_REGION_OK (tty
)
1118 && TTY_MEMORY_BELOW_FRAME (tty
)
1121 cursor_to (FRAME_LINES (f
) + n
, 0);
1127 /* Compute cost of sending "str", in characters,
1128 not counting any line-dependent padding. */
1136 tputs (str
, 0, evalcost
);
1140 /* Compute cost of sending "str", in characters,
1141 counting any line-dependent padding at one line. */
1144 string_cost_one_line (str
)
1149 tputs (str
, 1, evalcost
);
1153 /* Compute per line amount of line-dependent padding,
1154 in tenths of characters. */
1162 tputs (str
, 0, evalcost
);
1165 tputs (str
, 10, evalcost
);
1170 /* char_ins_del_cost[n] is cost of inserting N characters.
1171 char_ins_del_cost[-n] is cost of deleting N characters.
1172 The length of this vector is based on max_frame_cols. */
1174 int *char_ins_del_vector
;
1176 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1181 calculate_ins_del_char_costs (f
)
1184 struct tty_display_info
*tty
= FRAME_TTY (f
);
1185 int ins_startup_cost
, del_startup_cost
;
1186 int ins_cost_per_char
, del_cost_per_char
;
1190 if (tty
->TS_ins_multi_chars
)
1192 ins_cost_per_char
= 0;
1193 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1195 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1196 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1198 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1199 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1200 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1201 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1205 ins_startup_cost
= 9999;
1206 ins_cost_per_char
= 0;
1209 if (tty
->TS_del_multi_chars
)
1211 del_cost_per_char
= 0;
1212 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1214 else if (tty
->TS_del_char
)
1216 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1217 + string_cost (tty
->TS_end_delete_mode
));
1218 if (tty
->delete_in_insert_mode
)
1219 del_startup_cost
/= 2;
1220 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1224 del_startup_cost
= 9999;
1225 del_cost_per_char
= 0;
1228 /* Delete costs are at negative offsets */
1229 p
= &char_ins_del_cost (f
)[0];
1230 for (i
= FRAME_COLS (f
); --i
>= 0;)
1231 *--p
= (del_startup_cost
+= del_cost_per_char
);
1233 /* Doing nothing is free */
1234 p
= &char_ins_del_cost (f
)[0];
1237 /* Insert costs are at positive offsets */
1238 for (i
= FRAME_COLS (f
); --i
>= 0;)
1239 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1243 calculate_costs (frame
)
1246 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1247 register char *f
= (tty
->TS_set_scroll_region
1248 ? tty
->TS_set_scroll_region
1249 : tty
->TS_set_scroll_region_1
);
1251 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1253 if (FRAME_TERMCAP_P (frame
))
1254 TTY_SCROLL_REGION_COST (FRAME_TTY (frame
)) = string_cost (f
);
1256 /* These variables are only used for terminal stuff. They are allocated
1257 once for the terminal frame of X-windows emacs, but not used afterwards.
1259 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1260 X turns off char_ins_del_ok. */
1262 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1263 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1267 if (char_ins_del_vector
!= 0)
1269 = (int *) xrealloc (char_ins_del_vector
,
1271 + 2 * max_frame_cols
* sizeof (int)));
1274 = (int *) xmalloc (sizeof (int)
1275 + 2 * max_frame_cols
* sizeof (int));
1277 bzero (char_ins_del_vector
, (sizeof (int)
1278 + 2 * max_frame_cols
* sizeof (int)));
1280 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1281 do_line_insertion_deletion_costs (frame
,
1282 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1283 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1286 do_line_insertion_deletion_costs (frame
,
1287 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1288 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1291 calculate_ins_del_char_costs (frame
);
1293 /* Don't use TS_repeat if its padding is worse than sending the chars */
1294 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1295 tty
->RPov
= string_cost (tty
->TS_repeat
);
1297 tty
->RPov
= FRAME_COLS (frame
) * 2;
1299 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1306 /* Termcap capability names that correspond directly to X keysyms.
1307 Some of these (marked "terminfo") aren't supplied by old-style
1308 (Berkeley) termcap entries. They're listed in X keysym order;
1309 except we put the keypad keys first, so that if they clash with
1310 other keys (as on the IBM PC keyboard) they get overridden.
1313 static struct fkey_table keys
[] =
1315 {"kh", "home"}, /* termcap */
1316 {"kl", "left"}, /* termcap */
1317 {"ku", "up"}, /* termcap */
1318 {"kr", "right"}, /* termcap */
1319 {"kd", "down"}, /* termcap */
1320 {"%8", "prior"}, /* terminfo */
1321 {"%5", "next"}, /* terminfo */
1322 {"@7", "end"}, /* terminfo */
1323 {"@1", "begin"}, /* terminfo */
1324 {"*6", "select"}, /* terminfo */
1325 {"%9", "print"}, /* terminfo */
1326 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1328 * "insert" --- see below
1330 {"&8", "undo"}, /* terminfo */
1331 {"%0", "redo"}, /* terminfo */
1332 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1333 {"@0", "find"}, /* terminfo */
1334 {"@2", "cancel"}, /* terminfo */
1335 {"%1", "help"}, /* terminfo */
1337 * "break" goes here, but can't be reliably intercepted with termcap
1339 {"&4", "reset"}, /* terminfo --- actually `restart' */
1341 * "system" and "user" --- no termcaps
1343 {"kE", "clearline"}, /* terminfo */
1344 {"kA", "insertline"}, /* terminfo */
1345 {"kL", "deleteline"}, /* terminfo */
1346 {"kI", "insertchar"}, /* terminfo */
1347 {"kD", "deletechar"}, /* terminfo */
1348 {"kB", "backtab"}, /* terminfo */
1350 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1352 {"@8", "kp-enter"}, /* terminfo */
1354 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1355 * "kp-multiply", "kp-add", "kp-separator",
1356 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1357 * --- no termcaps for any of these.
1359 {"K4", "kp-1"}, /* terminfo */
1361 * "kp-2" --- no termcap
1363 {"K5", "kp-3"}, /* terminfo */
1365 * "kp-4" --- no termcap
1367 {"K2", "kp-5"}, /* terminfo */
1369 * "kp-6" --- no termcap
1371 {"K1", "kp-7"}, /* terminfo */
1373 * "kp-8" --- no termcap
1375 {"K3", "kp-9"}, /* terminfo */
1377 * "kp-equal" --- no termcap
1390 static char **term_get_fkeys_arg
;
1391 static Lisp_Object
term_get_fkeys_1 ();
1393 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1394 This function scans the termcap function key sequence entries, and
1395 adds entries to Vfunction_key_map for each function key it finds. */
1398 term_get_fkeys (address
)
1401 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1402 errors during the call. The only errors should be from Fdefine_key
1403 when given a key sequence containing an invalid prefix key. If the
1404 termcap defines function keys which use a prefix that is already bound
1405 to a command by the default bindings, we should silently ignore that
1406 function key specification, rather than giving the user an error and
1407 refusing to run at all on such a terminal. */
1409 extern Lisp_Object
Fidentity ();
1410 term_get_fkeys_arg
= address
;
1411 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1419 char **address
= term_get_fkeys_arg
;
1421 /* This can happen if CANNOT_DUMP or with strange options. */
1423 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1425 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1427 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1429 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1430 Fmake_vector (make_number (1),
1431 intern (keys
[i
].name
)));
1434 /* The uses of the "k0" capability are inconsistent; sometimes it
1435 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1436 We will attempt to politely accommodate both systems by testing for
1437 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1440 char *k_semi
= tgetstr ("k;", address
);
1441 char *k0
= tgetstr ("k0", address
);
1442 char *k0_name
= "f10";
1447 /* Define f0 first, so that f10 takes precedence in case the
1448 key sequences happens to be the same. */
1449 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1450 Fmake_vector (make_number (1), intern ("f0")));
1451 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1452 Fmake_vector (make_number (1), intern ("f10")));
1455 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1456 Fmake_vector (make_number (1), intern (k0_name
)));
1459 /* Set up cookies for numbered function keys above f10. */
1461 char fcap
[3], fkey
[4];
1463 fcap
[0] = 'F'; fcap
[2] = '\0';
1464 for (i
= 11; i
< 64; i
++)
1467 fcap
[1] = '1' + i
- 11;
1469 fcap
[1] = 'A' + i
- 20;
1471 fcap
[1] = 'a' + i
- 46;
1474 char *sequence
= tgetstr (fcap
, address
);
1477 sprintf (fkey
, "f%d", i
);
1478 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1479 Fmake_vector (make_number (1),
1487 * Various mappings to try and get a better fit.
1490 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1491 if (!tgetstr (cap1, address)) \
1493 char *sequence = tgetstr (cap2, address); \
1495 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1496 Fmake_vector (make_number (1), \
1500 /* if there's no key_next keycap, map key_npage to `next' keysym */
1501 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1502 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1503 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1504 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1505 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1506 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1507 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1509 /* IBM has their own non-standard dialect of terminfo.
1510 If the standard name isn't found, try the IBM name. */
1511 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1512 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1513 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1514 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1515 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1516 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1517 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1518 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1519 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1520 #undef CONDITIONAL_REASSIGN
1527 /***********************************************************************
1528 Character Display Information
1529 ***********************************************************************/
1531 static void append_glyph
P_ ((struct it
*));
1534 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1535 terminal frames if IT->glyph_row != NULL. IT->c is the character
1536 for which to produce glyphs; IT->face_id contains the character's
1537 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1544 struct glyph
*glyph
, *end
;
1547 xassert (it
->glyph_row
);
1548 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1549 + it
->glyph_row
->used
[it
->area
]);
1550 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1553 i
< it
->pixel_width
&& glyph
< end
;
1556 glyph
->type
= CHAR_GLYPH
;
1557 glyph
->pixel_width
= 1;
1558 glyph
->u
.ch
= it
->c
;
1559 glyph
->face_id
= it
->face_id
;
1560 glyph
->padding_p
= i
> 0;
1561 glyph
->charpos
= CHARPOS (it
->position
);
1562 glyph
->object
= it
->object
;
1564 ++it
->glyph_row
->used
[it
->area
];
1570 /* Produce glyphs for the display element described by IT. *IT
1571 specifies what we want to produce a glyph for (character, image, ...),
1572 and where in the glyph matrix we currently are (glyph row and hpos).
1573 produce_glyphs fills in output fields of *IT with information such as the
1574 pixel width and height of a character, and maybe output actual glyphs at
1575 the same time if IT->glyph_row is non-null. See the explanation of
1576 struct display_iterator in dispextern.h for an overview.
1578 produce_glyphs also stores the result of glyph width, ascent
1579 etc. computations in *IT.
1581 IT->glyph_row may be null, in which case produce_glyphs does not
1582 actually fill in the glyphs. This is used in the move_* functions
1583 in xdisp.c for text width and height computations.
1585 Callers usually don't call produce_glyphs directly;
1586 instead they use the macro PRODUCE_GLYPHS. */
1592 /* If a hook is installed, let it do the work. */
1593 xassert (it
->what
== IT_CHARACTER
1594 || it
->what
== IT_COMPOSITION
1595 || it
->what
== IT_IMAGE
1596 || it
->what
== IT_STRETCH
);
1598 /* Nothing but characters are supported on terminal frames. For a
1599 composition sequence, it->c is the first character of the
1601 xassert (it
->what
== IT_CHARACTER
1602 || it
->what
== IT_COMPOSITION
);
1604 if (it
->c
>= 040 && it
->c
< 0177)
1606 it
->pixel_width
= it
->nglyphs
= 1;
1610 else if (it
->c
== '\n')
1611 it
->pixel_width
= it
->nglyphs
= 0;
1612 else if (it
->c
== '\t')
1614 int absolute_x
= (it
->current_x
1615 + it
->continuation_lines_width
);
1617 = (((1 + absolute_x
+ it
->tab_width
- 1)
1622 /* If part of the TAB has been displayed on the previous line
1623 which is continued now, continuation_lines_width will have
1624 been incremented already by the part that fitted on the
1625 continued line. So, we will get the right number of spaces
1627 nspaces
= next_tab_x
- absolute_x
;
1634 it
->pixel_width
= it
->len
= 1;
1642 it
->pixel_width
= nspaces
;
1643 it
->nglyphs
= nspaces
;
1645 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1647 /* Coming here means that it->c is from display table, thus we
1648 must send the code as is to the terminal. Although there's
1649 no way to know how many columns it occupies on a screen, it
1650 is a good assumption that a single byte code has 1-column
1652 it
->pixel_width
= it
->nglyphs
= 1;
1658 /* A multi-byte character. The display width is fixed for all
1659 characters of the set. Some of the glyphs may have to be
1660 ignored because they are already displayed in a continued
1662 int charset
= CHAR_CHARSET (it
->c
);
1664 it
->pixel_width
= CHARSET_WIDTH (charset
);
1665 it
->nglyphs
= it
->pixel_width
;
1671 /* Advance current_x by the pixel width as a convenience for
1673 if (it
->area
== TEXT_AREA
)
1674 it
->current_x
+= it
->pixel_width
;
1675 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1676 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1680 /* Get information about special display element WHAT in an
1681 environment described by IT. WHAT is one of IT_TRUNCATION or
1682 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1683 non-null glyph_row member. This function ensures that fields like
1684 face_id, c, len of IT are left untouched. */
1687 produce_special_glyphs (it
, what
)
1689 enum display_element_type what
;
1695 temp_it
.what
= IT_CHARACTER
;
1697 temp_it
.object
= make_number (0);
1698 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1700 if (what
== IT_CONTINUATION
)
1702 /* Continuation glyph. */
1704 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1705 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1707 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it
->dp
)));
1708 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1713 produce_glyphs (&temp_it
);
1714 it
->pixel_width
= temp_it
.pixel_width
;
1715 it
->nglyphs
= temp_it
.pixel_width
;
1717 else if (what
== IT_TRUNCATION
)
1719 /* Truncation glyph. */
1721 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1722 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1724 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it
->dp
)));
1725 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1730 produce_glyphs (&temp_it
);
1731 it
->pixel_width
= temp_it
.pixel_width
;
1732 it
->nglyphs
= temp_it
.pixel_width
;
1740 /***********************************************************************
1742 ***********************************************************************/
1744 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1745 one of the enumerators from enum no_color_bit, or a bit set built
1746 from them. Some display attributes may not be used together with
1747 color; the termcap capability `NC' specifies which ones. */
1749 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1750 (tty->TN_max_colors > 0 \
1751 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1754 /* Turn appearances of face FACE_ID on tty frame F on. */
1757 turn_on_face (f
, face_id
)
1761 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1762 long fg
= face
->foreground
;
1763 long bg
= face
->background
;
1764 struct tty_display_info
*tty
= FRAME_TTY (f
);
1766 /* Do this first because TS_end_standout_mode may be the same
1767 as TS_exit_attribute_mode, which turns all appearances off. */
1768 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1770 if (tty
->TN_max_colors
> 0)
1772 if (fg
>= 0 && bg
>= 0)
1774 /* If the terminal supports colors, we can set them
1775 below without using reverse video. The face's fg
1776 and bg colors are set as they should appear on
1777 the screen, i.e. they take the inverse-video'ness
1778 of the face already into account. */
1780 else if (inverse_video
)
1782 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1783 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1784 toggle_highlight (tty
);
1788 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1789 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1790 toggle_highlight (tty
);
1795 /* If we can't display colors, use reverse video
1796 if the face specifies that. */
1799 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1800 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1801 toggle_highlight (tty
);
1805 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1806 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1807 toggle_highlight (tty
);
1812 if (face
->tty_bold_p
)
1814 if (MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1815 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1817 else if (face
->tty_dim_p
)
1818 if (MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1819 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1821 /* Alternate charset and blinking not yet used. */
1822 if (face
->tty_alt_charset_p
1823 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1824 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1826 if (face
->tty_blinking_p
1827 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1828 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1830 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1831 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1833 if (tty
->TN_max_colors
> 0)
1837 if (fg
>= 0 && tty
->TS_set_foreground
)
1839 p
= tparam (tty
->TS_set_foreground
, NULL
, 0, (int) fg
);
1844 if (bg
>= 0 && tty
->TS_set_background
)
1846 p
= tparam (tty
->TS_set_background
, NULL
, 0, (int) bg
);
1854 /* Turn off appearances of face FACE_ID on tty frame F. */
1857 turn_off_face (f
, face_id
)
1861 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1862 struct tty_display_info
*tty
= FRAME_TTY (f
);
1864 xassert (face
!= NULL
);
1866 if (tty
->TS_exit_attribute_mode
)
1868 /* Capability "me" will turn off appearance modes double-bright,
1869 half-bright, reverse-video, standout, underline. It may or
1870 may not turn off alt-char-mode. */
1871 if (face
->tty_bold_p
1873 || face
->tty_reverse_p
1874 || face
->tty_alt_charset_p
1875 || face
->tty_blinking_p
1876 || face
->tty_underline_p
)
1878 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
1879 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
1880 tty
->standout_mode
= 0;
1883 if (face
->tty_alt_charset_p
)
1884 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1888 /* If we don't have "me" we can only have those appearances
1889 that have exit sequences defined. */
1890 if (face
->tty_alt_charset_p
)
1891 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1893 if (face
->tty_underline_p
)
1894 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
1897 /* Switch back to default colors. */
1898 if (tty
->TN_max_colors
> 0
1899 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
1900 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
1901 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
1902 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
1903 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
1907 /* Return non-zero if the terminal on frame F supports all of the
1908 capabilities in CAPS simultaneously, with foreground and background
1909 colors FG and BG. */
1912 tty_capable_p (tty
, caps
, fg
, bg
)
1913 struct tty_display_info
*tty
;
1915 unsigned long fg
, bg
;
1917 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
1918 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
1921 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
1922 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
1923 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
1924 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
1925 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
1926 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
1933 /* Return non-zero if the terminal is capable to display colors. */
1935 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
1937 doc
: /* Return non-nil if TTY can display colors on DISPLAY. */)
1939 Lisp_Object display
;
1941 struct tty_display_info
*tty
= FRAME_TTY (SELECTED_FRAME ());
1942 return tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
1945 /* Return the number of supported colors. */
1946 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
1947 Stty_display_color_cells
, 0, 1, 0,
1948 doc
: /* Return the number of colors supported by TTY on DISPLAY. */)
1950 Lisp_Object display
;
1952 struct tty_display_info
*tty
= FRAME_TTY (SELECTED_FRAME ());
1953 return make_number (tty
->TN_max_colors
);
1958 /* Save or restore the default color-related capabilities of this
1961 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
1964 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
1965 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
1969 if (default_orig_pair
)
1970 xfree (default_orig_pair
);
1971 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
1973 if (default_set_foreground
)
1974 xfree (default_set_foreground
);
1975 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
1978 if (default_set_background
)
1979 xfree (default_set_background
);
1980 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
1983 default_max_colors
= tty
->TN_max_colors
;
1984 default_max_pairs
= tty
->TN_max_pairs
;
1985 default_no_color_video
= tty
->TN_no_color_video
;
1989 tty
->TS_orig_pair
= default_orig_pair
;
1990 tty
->TS_set_foreground
= default_set_foreground
;
1991 tty
->TS_set_background
= default_set_background
;
1992 tty
->TN_max_colors
= default_max_colors
;
1993 tty
->TN_max_pairs
= default_max_pairs
;
1994 tty
->TN_no_color_video
= default_no_color_video
;
1998 /* Setup one of the standard tty color schemes according to MODE.
1999 MODE's value is generally the number of colors which we want to
2000 support; zero means set up for the default capabilities, the ones
2001 we saw at term_init time; -1 means turn off color support. */
2003 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2005 /* Canonicalize all negative values of MODE. */
2011 case -1: /* no colors at all */
2012 tty
->TN_max_colors
= 0;
2013 tty
->TN_max_pairs
= 0;
2014 tty
->TN_no_color_video
= 0;
2015 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2017 case 0: /* default colors, if any */
2019 tty_default_color_capabilities (tty
, 0);
2021 case 8: /* 8 standard ANSI colors */
2022 tty
->TS_orig_pair
= "\033[0m";
2024 tty
->TS_set_foreground
= "\033[3%p1%dm";
2025 tty
->TS_set_background
= "\033[4%p1%dm";
2027 tty
->TS_set_foreground
= "\033[3%dm";
2028 tty
->TS_set_background
= "\033[4%dm";
2030 tty
->TN_max_colors
= 8;
2031 tty
->TN_max_pairs
= 64;
2032 tty
->TN_no_color_video
= 0;
2038 set_tty_color_mode (f
, val
)
2042 Lisp_Object color_mode_spec
, current_mode_spec
;
2043 Lisp_Object color_mode
, current_mode
;
2045 extern Lisp_Object Qtty_color_mode
;
2046 Lisp_Object tty_color_mode_alist
;
2048 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2055 if (NILP (tty_color_mode_alist
))
2056 color_mode_spec
= Qnil
;
2058 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2060 if (CONSP (color_mode_spec
))
2061 color_mode
= XCDR (color_mode_spec
);
2066 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2068 if (CONSP (current_mode_spec
))
2069 current_mode
= XCDR (current_mode_spec
);
2071 current_mode
= Qnil
;
2072 if (INTEGERP (color_mode
))
2073 mode
= XINT (color_mode
);
2075 mode
= 0; /* meaning default */
2076 if (INTEGERP (current_mode
))
2077 old_mode
= XINT (current_mode
);
2081 if (mode
!= old_mode
)
2083 tty_setup_colors (FRAME_TTY (f
), mode
);
2084 /* This recomputes all the faces given the new color
2086 call0 (intern ("tty-set-up-initial-frame-faces"));
2091 #endif /* !WINDOWSNT */
2095 struct tty_display_info
*
2096 get_named_tty (name
)
2099 struct tty_display_info
*tty
= tty_list
;
2102 if ((tty
->name
== 0 && name
== 0)
2103 || (name
&& tty
->name
&& !strcmp (tty
->name
, name
)))
2113 DEFUN ("frame-tty-name", Fframe_tty_name
, Sframe_tty_name
, 0, 1, 0,
2114 doc
: /* Return the name of the TTY device that FRAME is displayed on. */)
2122 f
= XFRAME (selected_frame
);
2126 CHECK_LIVE_FRAME (frame
);
2130 if (f
->output_method
!= output_termcap
)
2131 wrong_type_argument (Qframe_tty_name
, frame
);
2133 if (FRAME_TTY (f
)->name
)
2134 return build_string (FRAME_TTY (f
)->name
);
2139 DEFUN ("frame-tty-type", Fframe_tty_type
, Sframe_tty_type
, 0, 1, 0,
2140 doc
: /* Return the type of the TTY device that FRAME is displayed on. */)
2148 f
= XFRAME (selected_frame
);
2152 CHECK_LIVE_FRAME (frame
);
2156 if (f
->output_method
!= output_termcap
)
2157 wrong_type_argument (Qframe_tty_type
, frame
);
2159 if (FRAME_TTY (f
)->type
)
2160 return build_string (FRAME_TTY (f
)->type
);
2166 /***********************************************************************
2168 ***********************************************************************/
2170 struct tty_display_info
*
2171 term_dummy_init (void)
2173 if (initialized
|| tty_list
)
2174 error ("tty already initialized");
2176 tty_list
= xmalloc (sizeof (struct tty_display_info
));
2177 bzero (tty_list
, sizeof (struct tty_display_info
));
2179 tty_list
->input
= stdin
;
2180 tty_list
->input
= stdout
;
2185 struct tty_display_info
*
2186 term_init (Lisp_Object frame
, char *name
, char *terminal_type
)
2189 char **address
= &area
;
2190 char *buffer
= NULL
;
2191 int buffer_size
= 4096;
2194 struct frame
*f
= XFRAME (frame
);
2195 struct tty_display_info
*tty
;
2197 tty
= get_named_tty (name
);
2200 /* Return the previously initialized terminal, except if it is
2201 the dummy terminal created for the initial frame. */
2207 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
2208 bzero (tty
, sizeof (struct tty_display_info
));
2209 tty
->next
= tty_list
;
2214 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
2216 /* Make sure the frame is live; if an error happens, it must be
2218 f
->output_method
= output_termcap
;
2219 if (! f
->output_data
.tty
)
2221 f
->output_data
.tty
->display_info
= tty
;
2227 fd
= emacs_open (name
, O_RDWR
, 0);
2231 error ("Could not open file: %s", name
);
2233 file
= fdopen (fd
, "w+");
2234 tty
->name
= xstrdup (name
);
2242 tty
->output
= stdout
;
2245 tty
->type
= xstrdup (terminal_type
);
2247 add_keyboard_wait_descriptor (fileno (tty
->input
));
2250 initialize_w32_display ();
2254 area
= (char *) xmalloc (2044);
2256 FrameRows
= FRAME_LINES (f
);
2257 FrameCols
= FRAME_COLS (f
);
2258 specified_window
= FRAME_LINES (f
);
2260 delete_in_insert_mode
= 1;
2263 TTY_SCROLL_REGION_OK (tty
) = 0;
2265 /* Seems to insert lines when it's not supposed to, messing
2266 up the display. In doing a trace, it didn't seem to be
2267 called much, so I don't think we're losing anything by
2269 TTY_LINE_INS_DEL_OK (tty
) = 0;
2271 TTY_CHAR_INS_DEL_OK (tty
) = 1;
2275 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
2276 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
2277 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2280 #else /* not WINDOWSNT */
2284 buffer
= (char *) xmalloc (buffer_size
);
2285 status
= tgetent (buffer
, terminal_type
);
2293 error ("Cannot open terminfo database file");
2296 fatal ("Cannot open terminfo database file");
2302 error ("Cannot open termcap database file");
2305 fatal ("Cannot open termcap database file");
2315 error ("Terminal type %s is not defined", terminal_type
);
2318 fatal ("Terminal type %s is not defined.\n\
2319 If that is not the actual type of terminal you have,\n\
2320 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2321 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2322 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2329 error ("Terminal type %s is not defined", terminal_type
);
2332 fatal ("Terminal type %s is not defined.\n\
2333 If that is not the actual type of terminal you have,\n\
2334 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2335 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2336 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2342 if (strlen (buffer
) >= buffer_size
)
2344 buffer_size
= strlen (buffer
);
2346 area
= (char *) xmalloc (buffer_size
);
2348 tty
->TS_ins_line
= tgetstr ("al", address
);
2349 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
2350 tty
->TS_bell
= tgetstr ("bl", address
);
2351 BackTab (tty
) = tgetstr ("bt", address
);
2352 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
2353 tty
->TS_clr_line
= tgetstr ("ce", address
);
2354 tty
->TS_clr_frame
= tgetstr ("cl", address
);
2355 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
2356 AbsPosition (tty
) = tgetstr ("cm", address
);
2357 CR (tty
) = tgetstr ("cr", address
);
2358 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
2359 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
2360 RowPosition (tty
) = tgetstr ("cv", address
);
2361 tty
->TS_del_char
= tgetstr ("dc", address
);
2362 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
2363 tty
->TS_del_line
= tgetstr ("dl", address
);
2364 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
2365 tty
->TS_delete_mode
= tgetstr ("dm", address
);
2366 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
2367 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
2368 Home (tty
) = tgetstr ("ho", address
);
2369 tty
->TS_ins_char
= tgetstr ("ic", address
);
2370 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
2371 tty
->TS_insert_mode
= tgetstr ("im", address
);
2372 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
2373 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
2374 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
2375 LastLine (tty
) = tgetstr ("ll", address
);
2376 Right (tty
) = tgetstr ("nd", address
);
2377 Down (tty
) = tgetstr ("do", address
);
2379 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
2381 /* VMS puts a carriage return before each linefeed,
2382 so it is not safe to use linefeeds. */
2383 if (Down (tty
) && Down (tty
)[0] == '\n' && Down (tty
)[1] == '\0')
2386 if (tgetflag ("bs"))
2387 Left (tty
) = "\b"; /* can't possibly be longer! */
2388 else /* (Actually, "bs" is obsolete...) */
2389 Left (tty
) = tgetstr ("le", address
);
2391 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
2392 tty
->TS_pad_char
= tgetstr ("pc", address
);
2393 tty
->TS_repeat
= tgetstr ("rp", address
);
2394 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
2395 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
2396 tty
->TS_standout_mode
= tgetstr ("so", address
);
2397 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
2398 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
2399 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
2400 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
2401 Up (tty
) = tgetstr ("up", address
);
2402 tty
->TS_visible_bell
= tgetstr ("vb", address
);
2403 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
2404 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
2405 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
2406 tty
->TS_set_window
= tgetstr ("wi", address
);
2408 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
2409 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
2410 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
2411 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
2412 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
2413 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
2414 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2415 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2416 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
2418 MultiUp (tty
) = tgetstr ("UP", address
);
2419 MultiDown (tty
) = tgetstr ("DO", address
);
2420 MultiLeft (tty
) = tgetstr ("LE", address
);
2421 MultiRight (tty
) = tgetstr ("RI", address
);
2423 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2424 color because we can't switch back to the default foreground and
2426 tty
->TS_orig_pair
= tgetstr ("op", address
);
2427 if (tty
->TS_orig_pair
)
2429 tty
->TS_set_foreground
= tgetstr ("AF", address
);
2430 tty
->TS_set_background
= tgetstr ("AB", address
);
2431 if (!tty
->TS_set_foreground
)
2434 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
2435 tty
->TS_set_background
= tgetstr ("Sb", address
);
2438 tty
->TN_max_colors
= tgetnum ("Co");
2439 tty
->TN_max_pairs
= tgetnum ("pa");
2441 tty
->TN_no_color_video
= tgetnum ("NC");
2442 if (tty
->TN_no_color_video
== -1)
2443 tty
->TN_no_color_video
= 0;
2446 tty_default_color_capabilities (tty
, 1);
2448 MagicWrap (tty
) = tgetflag ("xn");
2449 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2450 the former flag imply the latter. */
2451 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
2452 TTY_MEMORY_BELOW_FRAME (tty
) = tgetflag ("db");
2453 tty
->TF_hazeltine
= tgetflag ("hz");
2454 TTY_MUST_WRITE_SPACES (tty
) = tgetflag ("in");
2455 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
2456 tty
->TF_insmode_motion
= tgetflag ("mi");
2457 tty
->TF_standout_motion
= tgetflag ("ms");
2458 tty
->TF_underscore
= tgetflag ("ul");
2459 tty
->TF_teleray
= tgetflag ("xt");
2461 term_get_fkeys (address
);
2463 /* Get frame size from system, or else from termcap. */
2466 get_tty_size (fileno (TTY_INPUT (tty
)), &width
, &height
);
2467 FrameCols (tty
) = width
;
2468 FrameRows (tty
) = height
;
2471 if (FrameCols (tty
) <= 0)
2472 FrameCols (tty
) = tgetnum ("co");
2473 if (FrameRows (tty
) <= 0)
2474 FrameRows (tty
) = tgetnum ("li");
2476 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
2481 error ("Screen size %dx%d is too small",
2482 FrameCols (tty
), FrameRows (tty
));
2486 fatal ("Screen size %dx%d is too small",
2487 FrameCols (tty
), FrameRows (tty
));
2491 #if 0 /* This is not used anywhere. */
2492 TTY_MIN_PADDING_SPEED (tty
) = tgetnum ("pb");
2495 TabWidth (tty
) = tgetnum ("tw");
2498 /* These capabilities commonly use ^J.
2499 I don't know why, but sending them on VMS does not work;
2500 it causes following spaces to be lost, sometimes.
2501 For now, the simplest fix is to avoid using these capabilities ever. */
2502 if (Down (tty
) && Down (tty
)[0] == '\n')
2507 tty
->TS_bell
= "\07";
2509 if (!tty
->TS_fwd_scroll
)
2510 tty
->TS_fwd_scroll
= Down (tty
);
2512 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
2514 if (TabWidth (tty
) < 0)
2517 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2518 and newer termcap doc does not seem to say there is a default.
2519 if (!tty->Wcm->cm_tab)
2520 tty->Wcm->cm_tab = "\t";
2523 /* We don't support standout modes that use `magic cookies', so
2524 turn off any that do. */
2525 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
2527 tty
->TS_standout_mode
= 0;
2528 tty
->TS_end_standout_mode
= 0;
2530 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
2532 tty
->TS_enter_underline_mode
= 0;
2533 tty
->TS_exit_underline_mode
= 0;
2536 /* If there's no standout mode, try to use underlining instead. */
2537 if (tty
->TS_standout_mode
== 0)
2539 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
2540 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
2543 /* If no `se' string, try using a `me' string instead.
2544 If that fails, we can't use standout mode at all. */
2545 if (tty
->TS_end_standout_mode
== 0)
2547 char *s
= tgetstr ("me", address
);
2549 tty
->TS_end_standout_mode
= s
;
2551 tty
->TS_standout_mode
= 0;
2554 if (tty
->TF_teleray
)
2556 tty
->Wcm
->cm_tab
= 0;
2557 /* We can't support standout mode, because it uses magic cookies. */
2558 tty
->TS_standout_mode
= 0;
2559 /* But that means we cannot rely on ^M to go to column zero! */
2561 /* LF can't be trusted either -- can alter hpos */
2562 /* if move at column 0 thru a line with TS_standout_mode */
2566 /* Special handling for certain terminal types known to need it */
2568 if (!strcmp (terminal_type
, "supdup"))
2570 TTY_MEMORY_BELOW_FRAME (tty
) = 1;
2571 tty
->Wcm
->cm_losewrap
= 1;
2573 if (!strncmp (terminal_type
, "c10", 3)
2574 || !strcmp (terminal_type
, "perq"))
2576 /* Supply a makeshift :wi string.
2577 This string is not valid in general since it works only
2578 for windows starting at the upper left corner;
2579 but that is all Emacs uses.
2581 This string works only if the frame is using
2582 the top of the video memory, because addressing is memory-relative.
2583 So first check the :ti string to see if that is true.
2585 It would be simpler if the :wi string could go in the termcap
2586 entry, but it can't because it is not fully valid.
2587 If it were in the termcap entry, it would confuse other programs. */
2588 if (!tty
->TS_set_window
)
2590 p
= tty
->TS_termcap_modes
;
2591 while (*p
&& strcmp (p
, "\033v "))
2594 tty
->TS_set_window
= "\033v%C %C %C %C ";
2596 /* Termcap entry often fails to have :in: flag */
2597 TTY_MUST_WRITE_SPACES (tty
) = 1;
2598 /* :ti string typically fails to have \E^G! in it */
2599 /* This limits scope of insert-char to one line. */
2600 strcpy (area
, tty
->TS_termcap_modes
);
2601 strcat (area
, "\033\007!");
2602 tty
->TS_termcap_modes
= area
;
2603 area
+= strlen (area
) + 1;
2604 p
= AbsPosition (tty
);
2605 /* Change all %+ parameters to %C, to handle
2606 values above 96 correctly for the C100. */
2609 if (p
[0] == '%' && p
[1] == '+')
2615 tty
->specified_window
= FrameRows (tty
);
2617 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
2621 error ("Terminal type \"%s\" is not powerful enough to run Emacs",
2626 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2627 It lacks the ability to position the cursor.\n\
2628 If that is not the actual type of terminal you have, use either the\n\
2629 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2630 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2634 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2635 It lacks the ability to position the cursor.\n\
2636 If that is not the actual type of terminal you have,\n\
2637 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2638 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2639 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2641 # else /* TERMCAP */
2642 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2643 It lacks the ability to position the cursor.\n\
2644 If that is not the actual type of terminal you have,\n\
2645 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2646 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2647 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2649 # endif /* TERMINFO */
2653 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
2658 error ("The frame size has not been specified");
2661 fatal ("The frame size has not been specified");
2664 tty
->delete_in_insert_mode
2665 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
2666 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
2668 tty
->se_is_so
= (tty
->TS_standout_mode
2669 && tty
->TS_end_standout_mode
2670 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
2672 UseTabs (tty
) = tabs_safe_p (fileno (TTY_INPUT (tty
))) && TabWidth (tty
) == 8;
2674 TTY_SCROLL_REGION_OK (tty
)
2676 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
2678 TTY_LINE_INS_DEL_OK (tty
)
2679 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
2680 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
2681 || (TTY_SCROLL_REGION_OK (tty
)
2682 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
2684 TTY_CHAR_INS_DEL_OK (tty
)
2685 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
2686 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
2687 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
2689 TTY_FAST_CLEAR_END_OF_LINE (tty
) = tty
->TS_clr_line
!= 0;
2691 init_baud_rate (fileno (TTY_INPUT (tty
)));
2692 if (read_socket_hook
) /* Baudrate is somewhat
2693 meaningless in this case */
2696 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
2697 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
2699 /* Don't do this. I think termcap may still need the buffer. */
2700 /* xfree (buffer); */
2702 tty
->top_frame
= frame
;
2704 /* Init system terminal modes (RAW or CBREAK, etc.). */
2705 init_sys_modes (tty
);
2707 tty_set_terminal_modes (tty
);
2710 #endif /* WINDOWSNT */
2715 fatal (str
, arg1
, arg2
)
2716 char *str
, *arg1
, *arg2
;
2718 fprintf (stderr
, "emacs: ");
2719 fprintf (stderr
, str
, arg1
, arg2
);
2720 fprintf (stderr
, "\n");
2727 DEFUN ("delete-tty", Fdelete_tty
, Sdelete_tty
, 0, 1, 0,
2728 doc
: /* Delete all frames on the terminal named TTY, and close the device. */)
2732 struct tty_display_info
*t
;
2737 if (SBYTES (tty
) > 0)
2739 name
= (char *) alloca (SBYTES (tty
) + 1);
2740 strncpy (name
, SDATA (tty
), SBYTES (tty
));
2741 name
[SBYTES (tty
)] = 0;
2744 t
= get_named_tty (name
);
2747 error ("No such tty device: %s", name
);
2752 static int deleting_tty
= 0;
2755 delete_tty (struct tty_display_info
*tty
)
2757 Lisp_Object tail
, frame
;
2760 /* We get a recursive call when we delete the last frame on this
2766 if (tty
== tty_list
)
2767 tty_list
= tty
->next
;
2770 struct tty_display_info
*p
;
2771 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
2775 /* This should not happen. */
2778 p
->next
= tty
->next
;
2782 FOR_EACH_FRAME (tail
, frame
)
2784 struct frame
*f
= XFRAME (frame
);
2785 if (FRAME_LIVE_P (f
) && FRAME_TTY (f
) == tty
)
2787 Fdelete_frame (frame
, Qt
);
2788 f
->output_data
.tty
= 0;
2792 reset_sys_modes (tty
);
2801 delete_keyboard_wait_descriptor (fileno (tty
->input
));
2802 if (tty
->input
!= stdin
)
2803 fclose (tty
->input
);
2805 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
2806 fclose (tty
->output
);
2807 if (tty
->termscript
)
2808 fclose (tty
->termscript
);
2811 xfree (tty
->old_tty
);
2816 bzero (tty
, sizeof (struct tty_display_info
));
2824 /* Mark the pointers in the tty_display_info objects.
2825 Called by the Fgarbage_collector. */
2829 struct tty_display_info
*tty
;
2831 for (tty
= tty_list
; tty
; tty
= tty
->next
)
2834 mark_object (tty
->top_frame
);
2843 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
2844 doc
: /* Non-nil means the system uses terminfo rather than termcap.
2845 This variable can be used by terminal emulator packages. */);
2847 system_uses_terminfo
= 1;
2849 system_uses_terminfo
= 0;
2852 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
2853 doc
: /* Non-nil means call this function to ring the bell.
2854 The function should accept no arguments. */);
2855 Vring_bell_function
= Qnil
;
2857 Qframe_tty_name
= intern ("frame-tty-name");
2858 staticpro (&Qframe_tty_name
);
2860 Qframe_tty_type
= intern ("frame-tty-type");
2861 staticpro (&Qframe_tty_type
);
2863 defsubr (&Stty_display_color_p
);
2864 defsubr (&Stty_display_color_cells
);
2865 defsubr (&Sframe_tty_name
);
2866 defsubr (&Sframe_tty_type
);
2867 defsubr (&Sdelete_tty
);
2869 Fprovide (intern ("multi-tty"), Qnil
);
2874 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
2875 (do not change this comment) */