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 /* Functions to call after a tty was deleted. */
104 Lisp_Object Vdelete_tty_after_functions
;
106 /* Terminal characteristics that higher levels want to look at. */
108 struct tty_display_info
*tty_list
;
110 /* Nonzero means no need to redraw the entire frame on resuming a
111 suspended Emacs. This is useful on terminals with multiple
112 pages, where one page is used for Emacs and another for all
114 int no_redraw_on_reenter
;
116 Lisp_Object Qframe_tty_name
, Qframe_tty_type
;
118 /* Hook functions that you can set to snap out the functions in this file.
119 These are all extern'd in termhooks.h */
121 void (*cursor_to_hook
) P_ ((int, int));
122 void (*raw_cursor_to_hook
) P_ ((int, int));
123 void (*clear_to_end_hook
) P_ ((void));
124 void (*clear_frame_hook
) P_ ((void));
125 void (*clear_end_of_line_hook
) P_ ((int));
127 void (*ins_del_lines_hook
) P_ ((int, int));
129 void (*delete_glyphs_hook
) P_ ((int));
131 void (*ring_bell_hook
) P_ ((void));
133 void (*reset_terminal_modes_hook
) P_ ((void));
134 void (*set_terminal_modes_hook
) P_ ((void));
135 void (*update_begin_hook
) P_ ((struct frame
*));
136 void (*update_end_hook
) P_ ((struct frame
*));
137 void (*set_terminal_window_hook
) P_ ((int));
138 void (*insert_glyphs_hook
) P_ ((struct glyph
*, int));
139 void (*write_glyphs_hook
) P_ ((struct glyph
*, int));
140 void (*delete_glyphs_hook
) P_ ((int));
142 int (*read_socket_hook
) P_ ((struct input_event
*, int, int));
144 void (*frame_up_to_date_hook
) P_ ((struct frame
*));
146 /* Return the current position of the mouse.
148 Set *f to the frame the mouse is in, or zero if the mouse is in no
149 Emacs frame. If it is set to zero, all the other arguments are
152 If the motion started in a scroll bar, set *bar_window to the
153 scroll bar's window, *part to the part the mouse is currently over,
154 *x to the position of the mouse along the scroll bar, and *y to the
155 overall length of the scroll bar.
157 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
158 row of the character cell the mouse is over.
160 Set *time to the time the mouse was at the returned position.
162 This should clear mouse_moved until the next motion
165 void (*mouse_position_hook
) P_ ((FRAME_PTR
*f
, int insist
,
166 Lisp_Object
*bar_window
,
167 enum scroll_bar_part
*part
,
170 unsigned long *time
));
172 /* When reading from a minibuffer in a different frame, Emacs wants
173 to shift the highlight from the selected frame to the mini-buffer's
174 frame; under X, this means it lies about where the focus is.
175 This hook tells the window system code to re-decide where to put
178 void (*frame_rehighlight_hook
) P_ ((FRAME_PTR f
));
180 /* If we're displaying frames using a window system that can stack
181 frames on top of each other, this hook allows you to bring a frame
182 to the front, or bury it behind all the other windows. If this
183 hook is zero, that means the device we're displaying on doesn't
184 support overlapping frames, so there's no need to raise or lower
187 If RAISE is non-zero, F is brought to the front, before all other
188 windows. If RAISE is zero, F is sent to the back, behind all other
191 void (*frame_raise_lower_hook
) P_ ((FRAME_PTR f
, int raise
));
193 /* Set the vertical scroll bar for WINDOW to have its upper left corner
194 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
195 indicate that we are displaying PORTION characters out of a total
196 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
197 have a scroll bar, create one for it. */
199 void (*set_vertical_scroll_bar_hook
)
200 P_ ((struct window
*window
,
201 int portion
, int whole
, int position
));
204 /* The following three hooks are used when we're doing a thorough
205 redisplay of the frame. We don't explicitly know which scroll bars
206 are going to be deleted, because keeping track of when windows go
207 away is a real pain - can you say set-window-configuration?
208 Instead, we just assert at the beginning of redisplay that *all*
209 scroll bars are to be removed, and then save scroll bars from the
210 fiery pit when we actually redisplay their window. */
212 /* Arrange for all scroll bars on FRAME to be removed at the next call
213 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
214 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
216 This should be applied to each frame each time its window tree is
217 redisplayed, even if it is not displaying scroll bars at the moment;
218 if the HAS_SCROLL_BARS flag has just been turned off, only calling
219 this and the judge_scroll_bars_hook will get rid of them.
221 If non-zero, this hook should be safe to apply to any frame,
222 whether or not it can support scroll bars, and whether or not it is
223 currently displaying them. */
225 void (*condemn_scroll_bars_hook
) P_ ((FRAME_PTR frame
));
227 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
228 Note that it's okay to redeem a scroll bar that is not condemned. */
230 void (*redeem_scroll_bar_hook
) P_ ((struct window
*window
));
232 /* Remove all scroll bars on FRAME that haven't been saved since the
233 last call to `*condemn_scroll_bars_hook'.
235 This should be applied to each frame after each time its window
236 tree is redisplayed, even if it is not displaying scroll bars at the
237 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
238 calling this and condemn_scroll_bars_hook will get rid of them.
240 If non-zero, this hook should be safe to apply to any frame,
241 whether or not it can support scroll bars, and whether or not it is
242 currently displaying them. */
244 void (*judge_scroll_bars_hook
) P_ ((FRAME_PTR FRAME
));
247 /* Meaning of bits in no_color_video. Each bit set means that the
248 corresponding attribute cannot be combined with colors. */
252 NC_STANDOUT
= 1 << 0,
253 NC_UNDERLINE
= 1 << 1,
260 NC_ALT_CHARSET
= 1 << 8
265 /* The largest frame width in any call to calculate_costs. */
269 /* The largest frame height in any call to calculate_costs. */
273 /* A template for tty display methods, with common values
275 static struct display_method tty_display_method_template
;
277 /* Frame currently being redisplayed; 0 if not currently redisplaying.
278 (Direct output does not count). */
280 FRAME_PTR updating_frame
;
282 /* Provided for lisp packages. */
284 static int system_uses_terminfo
;
288 extern char *tgetstr ();
292 /* We aren't X windows, but we aren't termcap either. This makes me
293 uncertain as to what value to use for frame.output_method. For
294 this file, we'll define FRAME_TERMCAP_P to be zero so that our
295 output hooks get called instead of the termcap functions. Probably
296 the best long-term solution is to define an output_windows_nt... */
298 #undef FRAME_TERMCAP_P
299 #define FRAME_TERMCAP_P(_f_) 0
300 #endif /* WINDOWSNT */
305 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
307 if (!NILP (Vring_bell_function
))
309 Lisp_Object function
;
311 /* Temporarily set the global variable to nil
312 so that if we get an error, it stays nil
313 and we don't call it over and over.
315 We don't specbind it, because that would carefully
316 restore the bad value if there's an error
317 and make the loop of errors happen anyway. */
319 function
= Vring_bell_function
;
320 Vring_bell_function
= Qnil
;
324 Vring_bell_function
= function
;
326 else if (!FRAME_TERMCAP_P (f
))
327 (*ring_bell_hook
) ();
329 struct tty_display_info
*tty
= FRAME_TTY (f
);
330 OUTPUT (tty
, tty
->TS_visible_bell
&& visible_bell
? tty
->TS_visible_bell
: tty
->TS_bell
);
334 void tty_set_terminal_modes (struct tty_display_info
*tty
)
336 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
337 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
338 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
343 set_terminal_modes ()
345 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
346 if (FRAME_TERMCAP_P (f
))
347 tty_set_terminal_modes (FRAME_TTY (f
));
349 (*set_terminal_modes_hook
) ();
352 void tty_reset_terminal_modes (struct tty_display_info
*tty
)
354 turn_off_highlight (tty
);
355 turn_off_insert (tty
);
356 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
357 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
358 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
359 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
360 /* Output raw CR so kernel can track the cursor hpos. */
366 reset_terminal_modes ()
368 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
369 if (FRAME_TERMCAP_P (f
))
370 tty_reset_terminal_modes (FRAME_TTY (f
));
371 else if (reset_terminal_modes_hook
)
372 (*reset_terminal_modes_hook
) ();
380 if (!FRAME_TERMCAP_P (f
))
381 update_begin_hook (f
);
388 if (FRAME_TERMCAP_P (f
))
390 struct tty_display_info
*tty
= FRAME_TTY (f
);
391 if (!XWINDOW (selected_window
)->cursor_off_p
)
392 tty_show_cursor (tty
);
393 turn_off_insert (tty
);
394 background_highlight (tty
);
399 updating_frame
= NULL
;
403 set_terminal_window (size
)
406 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
407 if (FRAME_TERMCAP_P (f
))
409 struct tty_display_info
*tty
= FRAME_TTY (f
);
410 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
411 if (FRAME_SCROLL_REGION_OK (f
))
412 set_scroll_region (0, tty
->specified_window
);
415 set_terminal_window_hook (size
);
419 set_scroll_region (start
, stop
)
423 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
424 struct tty_display_info
*tty
= FRAME_TTY (f
);
426 if (tty
->TS_set_scroll_region
)
427 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
428 else if (tty
->TS_set_scroll_region_1
)
429 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
430 FRAME_LINES (f
), start
,
431 FRAME_LINES (f
) - stop
,
434 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
443 turn_on_insert (struct tty_display_info
*tty
)
445 if (!tty
->insert_mode
)
446 OUTPUT (tty
, tty
->TS_insert_mode
);
447 tty
->insert_mode
= 1;
451 turn_off_insert (struct tty_display_info
*tty
)
453 if (tty
->insert_mode
)
454 OUTPUT (tty
, tty
->TS_end_insert_mode
);
455 tty
->insert_mode
= 0;
458 /* Handle highlighting. */
461 turn_off_highlight (struct tty_display_info
*tty
)
463 if (tty
->standout_mode
)
464 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
465 tty
->standout_mode
= 0;
469 turn_on_highlight (struct tty_display_info
*tty
)
471 if (!tty
->standout_mode
)
472 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
473 tty
->standout_mode
= 1;
477 toggle_highlight (struct tty_display_info
*tty
)
479 if (tty
->standout_mode
)
480 turn_off_highlight (tty
);
482 turn_on_highlight (tty
);
486 /* Make cursor invisible. */
489 tty_hide_cursor (struct tty_display_info
*tty
)
491 if (tty
->cursor_hidden
== 0)
493 tty
->cursor_hidden
= 1;
494 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
499 /* Ensure that cursor is visible. */
502 tty_show_cursor (struct tty_display_info
*tty
)
504 if (tty
->cursor_hidden
)
506 tty
->cursor_hidden
= 0;
507 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
508 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
513 /* Set standout mode to the state it should be in for
514 empty space inside windows. What this is,
515 depends on the user option inverse-video. */
518 background_highlight (struct tty_display_info
*tty
)
521 turn_on_highlight (tty
);
523 turn_off_highlight (tty
);
526 /* Set standout mode to the mode specified for the text to be output. */
529 highlight_if_desired (struct tty_display_info
*tty
)
532 turn_on_highlight (tty
);
534 turn_off_highlight (tty
);
538 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
539 frame-relative coordinates. */
542 cursor_to (vpos
, hpos
)
545 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
546 struct tty_display_info
*tty
;
548 if (! FRAME_TERMCAP_P (f
) && cursor_to_hook
)
550 (*cursor_to_hook
) (vpos
, hpos
);
556 /* Detect the case where we are called from reset_sys_modes
557 and the costs have never been calculated. Do nothing. */
558 if (! tty
->costs_set
)
561 if (curY (tty
) == vpos
562 && curX (tty
) == hpos
)
564 if (!tty
->TF_standout_motion
)
565 background_highlight (tty
);
566 if (!tty
->TF_insmode_motion
)
567 turn_off_insert (tty
);
568 cmgoto (tty
, vpos
, hpos
);
571 /* Similar but don't take any account of the wasted characters. */
574 raw_cursor_to (row
, col
)
577 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
578 struct tty_display_info
*tty
;
579 if (! FRAME_TERMCAP_P (f
))
581 (*raw_cursor_to_hook
) (row
, col
);
585 if (curY (tty
) == row
586 && curX (tty
) == col
)
588 if (!tty
->TF_standout_motion
)
589 background_highlight (tty
);
590 if (!tty
->TF_insmode_motion
)
591 turn_off_insert (tty
);
592 cmgoto (tty
, row
, col
);
595 /* Erase operations */
597 /* clear from cursor to end of frame */
603 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
604 struct tty_display_info
*tty
;
606 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (f
))
608 (*clear_to_end_hook
) ();
612 if (tty
->TS_clr_to_bottom
)
614 background_highlight (tty
);
615 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
619 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
622 clear_end_of_line (FRAME_COLS (f
));
627 /* Clear entire frame */
632 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
633 struct tty_display_info
*tty
;
635 if (clear_frame_hook
&& ! FRAME_TERMCAP_P (f
))
637 (*clear_frame_hook
) ();
641 if (tty
->TS_clr_frame
)
643 background_highlight (tty
);
644 OUTPUT (tty
, tty
->TS_clr_frame
);
654 /* Clear from cursor to end of line.
655 Assume that the line is already clear starting at column first_unused_hpos.
657 Note that the cursor may be moved, on terminals lacking a `ce' string. */
660 clear_end_of_line (first_unused_hpos
)
661 int first_unused_hpos
;
663 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
664 struct tty_display_info
*tty
;
666 if (clear_end_of_line_hook
&& ! FRAME_TERMCAP_P (f
))
668 (*clear_end_of_line_hook
) (first_unused_hpos
);
672 tty_clear_end_of_line (FRAME_TTY (f
), first_unused_hpos
);
676 tty_clear_end_of_line (struct tty_display_info
*tty
, int first_unused_hpos
)
679 /* Detect the case where we are called from reset_sys_modes
680 and the costs have never been calculated. Do nothing. */
681 if (! tty
->costs_set
)
684 if (curX (tty
) >= first_unused_hpos
)
686 background_highlight (tty
);
687 if (tty
->TS_clr_line
)
689 OUTPUT1 (tty
, tty
->TS_clr_line
);
692 { /* have to do it the hard way */
693 turn_off_insert (tty
);
695 /* Do not write in last row last col with Auto-wrap on. */
697 && curY (tty
) == FrameRows (tty
) - 1
698 && first_unused_hpos
== FrameCols (tty
))
701 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
703 if (TTY_TERMSCRIPT (tty
))
704 fputc (' ', TTY_TERMSCRIPT (tty
));
705 fputc (' ', TTY_OUTPUT (tty
));
707 cmplus (tty
, first_unused_hpos
- curX (tty
));
711 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
712 store them at DST. Do not write more than DST_LEN bytes. That may
713 require stopping before all SRC_LEN input glyphs have been
716 We store the number of glyphs actually converted in *CONSUMED. The
717 return value is the number of bytes store in DST. */
720 encode_terminal_code (src
, dst
, src_len
, dst_len
, consumed
)
724 int dst_len
, *consumed
;
726 struct glyph
*src_start
= src
, *src_end
= src
+ src_len
;
727 unsigned char *dst_start
= dst
, *dst_end
= dst
+ dst_len
;
729 unsigned char workbuf
[MAX_MULTIBYTE_LENGTH
];
730 const unsigned char *buf
;
732 register int tlen
= GLYPH_TABLE_LENGTH
;
733 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
735 struct coding_system
*coding
;
737 /* If terminal_coding does any conversion, use it, otherwise use
738 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
739 because it always return 1 if the member src_multibyte is 1. */
740 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
742 : &safe_terminal_coding
);
744 while (src
< src_end
)
746 /* We must skip glyphs to be padded for a wide character. */
747 if (! CHAR_GLYPH_PADDING_P (*src
))
749 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
751 if (g
< 0 || g
>= tlen
)
753 /* This glyph doesn't has an entry in Vglyph_table. */
754 if (! CHAR_VALID_P (src
->u
.ch
, 0))
758 coding
->src_multibyte
= 0;
762 len
= CHAR_STRING (src
->u
.ch
, workbuf
);
764 coding
->src_multibyte
= 1;
769 /* This glyph has an entry in Vglyph_table,
770 so process any alias before testing for simpleness. */
771 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
773 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
775 /* We set the multi-byte form of a character in G
776 (that should be an ASCII character) at
778 workbuf
[0] = FAST_GLYPH_CHAR (g
);
781 coding
->src_multibyte
= 0;
785 /* We have a string in Vglyph_table. */
786 len
= GLYPH_LENGTH (tbase
, g
);
787 buf
= GLYPH_STRING (tbase
, g
);
788 coding
->src_multibyte
= STRING_MULTIBYTE (tbase
[g
]);
792 result
= encode_coding (coding
, buf
, dst
, len
, dst_end
- dst
);
793 len
-= coding
->consumed
;
794 dst
+= coding
->produced
;
795 if (result
== CODING_FINISH_INSUFFICIENT_DST
796 || (result
== CODING_FINISH_INSUFFICIENT_SRC
797 && len
> dst_end
- dst
))
798 /* The remaining output buffer is too short. We must
799 break the loop here without increasing SRC so that the
800 next call of this function starts from the same glyph. */
805 /* This is the case that a code of the range 0200..0237
806 exists in buf. We must just write out such a code. */
807 buf
+= coding
->consumed
;
815 *consumed
= src
- src_start
;
816 return (dst
- dst_start
);
821 write_glyphs (string
, len
)
822 register struct glyph
*string
;
825 int produced
, consumed
;
826 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
827 struct tty_display_info
*tty
;
828 unsigned char conversion_buffer
[1024];
829 int conversion_buffer_size
= sizeof conversion_buffer
;
831 if (write_glyphs_hook
&& ! FRAME_TERMCAP_P (f
))
833 (*write_glyphs_hook
) (string
, len
);
839 turn_off_insert (tty
);
840 tty_hide_cursor (tty
);
842 /* Don't dare write in last column of bottom line, if Auto-Wrap,
843 since that would scroll the whole frame on some terminals. */
846 && curY (tty
) + 1 == FRAME_LINES (f
)
847 && (curX (tty
) + len
) == FRAME_COLS (f
))
854 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
856 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
860 /* Identify a run of glyphs with the same face. */
861 int face_id
= string
->face_id
;
864 for (n
= 1; n
< len
; ++n
)
865 if (string
[n
].face_id
!= face_id
)
868 /* Turn appearance modes of the face of the run on. */
869 highlight_if_desired (tty
);
870 turn_on_face (f
, face_id
);
874 /* We use a fixed size (1024 bytes) of conversion buffer.
875 Usually it is sufficient, but if not, we just repeat the
877 produced
= encode_terminal_code (string
, conversion_buffer
,
878 n
, conversion_buffer_size
,
882 fwrite (conversion_buffer
, 1, produced
,
884 if (ferror (TTY_OUTPUT (tty
)))
885 clearerr (TTY_OUTPUT (tty
));
886 if (TTY_TERMSCRIPT (tty
))
887 fwrite (conversion_buffer
, 1, produced
,
888 TTY_TERMSCRIPT (tty
));
895 /* Turn appearance modes off. */
896 turn_off_face (f
, face_id
);
897 turn_off_highlight (tty
);
900 /* We may have to output some codes to terminate the writing. */
901 if (CODING_REQUIRE_FLUSHING (&terminal_coding
))
903 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
904 encode_coding (&terminal_coding
, "", conversion_buffer
,
905 0, conversion_buffer_size
);
906 if (terminal_coding
.produced
> 0)
908 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
910 if (ferror (TTY_OUTPUT (tty
)))
911 clearerr (TTY_OUTPUT (tty
));
912 if (TTY_TERMSCRIPT (tty
))
913 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
914 TTY_TERMSCRIPT (tty
));
921 /* If start is zero, insert blanks instead of a string at start */
924 insert_glyphs (start
, len
)
925 register struct glyph
*start
;
929 struct glyph
*glyph
= NULL
;
931 struct tty_display_info
*tty
;
936 f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
938 if (insert_glyphs_hook
&& ! FRAME_TERMCAP_P (f
))
940 (*insert_glyphs_hook
) (start
, len
);
946 if (tty
->TS_ins_multi_chars
)
948 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
952 write_glyphs (start
, len
);
956 turn_on_insert (tty
);
958 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
959 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
962 int produced
, consumed
;
963 unsigned char conversion_buffer
[1024];
964 int conversion_buffer_size
= sizeof conversion_buffer
;
966 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
969 conversion_buffer
[0] = SPACEGLYPH
;
974 highlight_if_desired (tty
);
975 turn_on_face (f
, start
->face_id
);
978 /* We must open sufficient space for a character which
979 occupies more than one column. */
980 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
982 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
987 /* This is the last glyph. */
988 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
990 /* The size of conversion buffer (1024 bytes) is surely
991 sufficient for just one glyph. */
992 produced
= encode_terminal_code (glyph
, conversion_buffer
, 1,
993 conversion_buffer_size
, &consumed
);
998 fwrite (conversion_buffer
, 1, produced
,
1000 if (ferror (TTY_OUTPUT (tty
)))
1001 clearerr (TTY_OUTPUT (tty
));
1002 if (TTY_TERMSCRIPT (tty
))
1003 fwrite (conversion_buffer
, 1, produced
,
1004 TTY_TERMSCRIPT (tty
));
1007 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
1010 turn_off_face (f
, glyph
->face_id
);
1011 turn_off_highlight (tty
);
1024 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
1025 struct tty_display_info
*tty
= FRAME_TTY (f
);
1027 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (f
))
1029 (*delete_glyphs_hook
) (n
);
1034 if (tty
->delete_in_insert_mode
)
1036 turn_on_insert (tty
);
1040 turn_off_insert (tty
);
1041 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
1044 if (tty
->TS_del_multi_chars
)
1046 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
1051 for (i
= 0; i
< n
; i
++)
1052 OUTPUT1 (tty
, tty
->TS_del_char
);
1053 if (!tty
->delete_in_insert_mode
)
1054 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
1057 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1060 ins_del_lines (vpos
, n
)
1063 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
1064 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (f
))
1066 (*ins_del_lines_hook
) (vpos
, n
);
1071 struct tty_display_info
*tty
= FRAME_TTY (f
);
1072 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
1073 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
1074 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
1076 register int i
= n
> 0 ? n
: -n
;
1079 /* If the lines below the insertion are being pushed
1080 into the end of the window, this is the same as clearing;
1081 and we know the lines are already clear, since the matching
1082 deletion has already been done. So can ignore this. */
1083 /* If the lines below the deletion are blank lines coming
1084 out of the end of the window, don't bother,
1085 as there will be a matching inslines later that will flush them. */
1086 if (FRAME_SCROLL_REGION_OK (f
)
1087 && vpos
+ i
>= tty
->specified_window
)
1089 if (!FRAME_MEMORY_BELOW_FRAME (f
)
1090 && vpos
+ i
>= FRAME_LINES (f
))
1095 raw_cursor_to (vpos
, 0);
1096 background_highlight (tty
);
1097 buf
= tparam (multi
, 0, 0, i
);
1103 raw_cursor_to (vpos
, 0);
1104 background_highlight (tty
);
1106 OUTPUT (tty
, single
);
1107 if (tty
->TF_teleray
)
1112 set_scroll_region (vpos
, tty
->specified_window
);
1114 raw_cursor_to (tty
->specified_window
- 1, 0);
1116 raw_cursor_to (vpos
, 0);
1117 background_highlight (tty
);
1119 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1120 set_scroll_region (0, tty
->specified_window
);
1123 if (!FRAME_SCROLL_REGION_OK (f
)
1124 && FRAME_MEMORY_BELOW_FRAME (f
)
1127 cursor_to (FRAME_LINES (f
) + n
, 0);
1133 /* Compute cost of sending "str", in characters,
1134 not counting any line-dependent padding. */
1142 tputs (str
, 0, evalcost
);
1146 /* Compute cost of sending "str", in characters,
1147 counting any line-dependent padding at one line. */
1150 string_cost_one_line (str
)
1155 tputs (str
, 1, evalcost
);
1159 /* Compute per line amount of line-dependent padding,
1160 in tenths of characters. */
1168 tputs (str
, 0, evalcost
);
1171 tputs (str
, 10, evalcost
);
1176 /* char_ins_del_cost[n] is cost of inserting N characters.
1177 char_ins_del_cost[-n] is cost of deleting N characters.
1178 The length of this vector is based on max_frame_cols. */
1180 int *char_ins_del_vector
;
1182 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1187 calculate_ins_del_char_costs (f
)
1190 struct tty_display_info
*tty
= FRAME_TTY (f
);
1191 int ins_startup_cost
, del_startup_cost
;
1192 int ins_cost_per_char
, del_cost_per_char
;
1196 if (tty
->TS_ins_multi_chars
)
1198 ins_cost_per_char
= 0;
1199 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1201 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1202 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1204 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1205 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1206 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1207 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1211 ins_startup_cost
= 9999;
1212 ins_cost_per_char
= 0;
1215 if (tty
->TS_del_multi_chars
)
1217 del_cost_per_char
= 0;
1218 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1220 else if (tty
->TS_del_char
)
1222 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1223 + string_cost (tty
->TS_end_delete_mode
));
1224 if (tty
->delete_in_insert_mode
)
1225 del_startup_cost
/= 2;
1226 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1230 del_startup_cost
= 9999;
1231 del_cost_per_char
= 0;
1234 /* Delete costs are at negative offsets */
1235 p
= &char_ins_del_cost (f
)[0];
1236 for (i
= FRAME_COLS (f
); --i
>= 0;)
1237 *--p
= (del_startup_cost
+= del_cost_per_char
);
1239 /* Doing nothing is free */
1240 p
= &char_ins_del_cost (f
)[0];
1243 /* Insert costs are at positive offsets */
1244 for (i
= FRAME_COLS (f
); --i
>= 0;)
1245 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1249 calculate_costs (frame
)
1252 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1254 if (FRAME_TERMCAP_P (frame
))
1256 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1257 register char *f
= (tty
->TS_set_scroll_region
1258 ? tty
->TS_set_scroll_region
1259 : tty
->TS_set_scroll_region_1
);
1261 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1265 /* These variables are only used for terminal stuff. They are
1266 allocated once for the terminal frame of X-windows emacs, but not
1269 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1270 X turns off char_ins_del_ok. */
1272 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1273 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1275 if (char_ins_del_vector
!= 0)
1277 = (int *) xrealloc (char_ins_del_vector
,
1279 + 2 * max_frame_cols
* sizeof (int)));
1282 = (int *) xmalloc (sizeof (int)
1283 + 2 * max_frame_cols
* sizeof (int));
1285 bzero (char_ins_del_vector
, (sizeof (int)
1286 + 2 * max_frame_cols
* sizeof (int)));
1289 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1290 do_line_insertion_deletion_costs (frame
,
1291 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1292 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1295 do_line_insertion_deletion_costs (frame
,
1296 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1297 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1300 calculate_ins_del_char_costs (frame
);
1302 /* Don't use TS_repeat if its padding is worse than sending the chars */
1303 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1304 tty
->RPov
= string_cost (tty
->TS_repeat
);
1306 tty
->RPov
= FRAME_COLS (frame
) * 2;
1308 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1316 /* Termcap capability names that correspond directly to X keysyms.
1317 Some of these (marked "terminfo") aren't supplied by old-style
1318 (Berkeley) termcap entries. They're listed in X keysym order;
1319 except we put the keypad keys first, so that if they clash with
1320 other keys (as on the IBM PC keyboard) they get overridden.
1323 static struct fkey_table keys
[] =
1325 {"kh", "home"}, /* termcap */
1326 {"kl", "left"}, /* termcap */
1327 {"ku", "up"}, /* termcap */
1328 {"kr", "right"}, /* termcap */
1329 {"kd", "down"}, /* termcap */
1330 {"%8", "prior"}, /* terminfo */
1331 {"%5", "next"}, /* terminfo */
1332 {"@7", "end"}, /* terminfo */
1333 {"@1", "begin"}, /* terminfo */
1334 {"*6", "select"}, /* terminfo */
1335 {"%9", "print"}, /* terminfo */
1336 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1338 * "insert" --- see below
1340 {"&8", "undo"}, /* terminfo */
1341 {"%0", "redo"}, /* terminfo */
1342 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1343 {"@0", "find"}, /* terminfo */
1344 {"@2", "cancel"}, /* terminfo */
1345 {"%1", "help"}, /* terminfo */
1347 * "break" goes here, but can't be reliably intercepted with termcap
1349 {"&4", "reset"}, /* terminfo --- actually `restart' */
1351 * "system" and "user" --- no termcaps
1353 {"kE", "clearline"}, /* terminfo */
1354 {"kA", "insertline"}, /* terminfo */
1355 {"kL", "deleteline"}, /* terminfo */
1356 {"kI", "insertchar"}, /* terminfo */
1357 {"kD", "deletechar"}, /* terminfo */
1358 {"kB", "backtab"}, /* terminfo */
1360 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1362 {"@8", "kp-enter"}, /* terminfo */
1364 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1365 * "kp-multiply", "kp-add", "kp-separator",
1366 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1367 * --- no termcaps for any of these.
1369 {"K4", "kp-1"}, /* terminfo */
1371 * "kp-2" --- no termcap
1373 {"K5", "kp-3"}, /* terminfo */
1375 * "kp-4" --- no termcap
1377 {"K2", "kp-5"}, /* terminfo */
1379 * "kp-6" --- no termcap
1381 {"K1", "kp-7"}, /* terminfo */
1383 * "kp-8" --- no termcap
1385 {"K3", "kp-9"}, /* terminfo */
1387 * "kp-equal" --- no termcap
1400 static char **term_get_fkeys_arg
;
1401 static Lisp_Object
term_get_fkeys_1 ();
1403 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1404 This function scans the termcap function key sequence entries, and
1405 adds entries to Vfunction_key_map for each function key it finds. */
1408 term_get_fkeys (address
)
1411 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1412 errors during the call. The only errors should be from Fdefine_key
1413 when given a key sequence containing an invalid prefix key. If the
1414 termcap defines function keys which use a prefix that is already bound
1415 to a command by the default bindings, we should silently ignore that
1416 function key specification, rather than giving the user an error and
1417 refusing to run at all on such a terminal. */
1419 extern Lisp_Object
Fidentity ();
1420 term_get_fkeys_arg
= address
;
1421 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1429 char **address
= term_get_fkeys_arg
;
1431 /* This can happen if CANNOT_DUMP or with strange options. */
1433 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1435 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1437 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1439 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1440 Fmake_vector (make_number (1),
1441 intern (keys
[i
].name
)));
1444 /* The uses of the "k0" capability are inconsistent; sometimes it
1445 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1446 We will attempt to politely accommodate both systems by testing for
1447 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1450 char *k_semi
= tgetstr ("k;", address
);
1451 char *k0
= tgetstr ("k0", address
);
1452 char *k0_name
= "f10";
1457 /* Define f0 first, so that f10 takes precedence in case the
1458 key sequences happens to be the same. */
1459 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1460 Fmake_vector (make_number (1), intern ("f0")));
1461 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1462 Fmake_vector (make_number (1), intern ("f10")));
1465 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1466 Fmake_vector (make_number (1), intern (k0_name
)));
1469 /* Set up cookies for numbered function keys above f10. */
1471 char fcap
[3], fkey
[4];
1473 fcap
[0] = 'F'; fcap
[2] = '\0';
1474 for (i
= 11; i
< 64; i
++)
1477 fcap
[1] = '1' + i
- 11;
1479 fcap
[1] = 'A' + i
- 20;
1481 fcap
[1] = 'a' + i
- 46;
1484 char *sequence
= tgetstr (fcap
, address
);
1487 sprintf (fkey
, "f%d", i
);
1488 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1489 Fmake_vector (make_number (1),
1497 * Various mappings to try and get a better fit.
1500 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1501 if (!tgetstr (cap1, address)) \
1503 char *sequence = tgetstr (cap2, address); \
1505 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1506 Fmake_vector (make_number (1), \
1510 /* if there's no key_next keycap, map key_npage to `next' keysym */
1511 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1512 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1513 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1514 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1515 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1516 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1517 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1519 /* IBM has their own non-standard dialect of terminfo.
1520 If the standard name isn't found, try the IBM name. */
1521 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1522 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1523 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1524 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1525 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1526 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1527 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1528 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1529 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1530 #undef CONDITIONAL_REASSIGN
1537 /***********************************************************************
1538 Character Display Information
1539 ***********************************************************************/
1541 static void append_glyph
P_ ((struct it
*));
1544 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1545 terminal frames if IT->glyph_row != NULL. IT->c is the character
1546 for which to produce glyphs; IT->face_id contains the character's
1547 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1554 struct glyph
*glyph
, *end
;
1557 xassert (it
->glyph_row
);
1558 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1559 + it
->glyph_row
->used
[it
->area
]);
1560 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1563 i
< it
->pixel_width
&& glyph
< end
;
1566 glyph
->type
= CHAR_GLYPH
;
1567 glyph
->pixel_width
= 1;
1568 glyph
->u
.ch
= it
->c
;
1569 glyph
->face_id
= it
->face_id
;
1570 glyph
->padding_p
= i
> 0;
1571 glyph
->charpos
= CHARPOS (it
->position
);
1572 glyph
->object
= it
->object
;
1574 ++it
->glyph_row
->used
[it
->area
];
1580 /* Produce glyphs for the display element described by IT. *IT
1581 specifies what we want to produce a glyph for (character, image, ...),
1582 and where in the glyph matrix we currently are (glyph row and hpos).
1583 produce_glyphs fills in output fields of *IT with information such as the
1584 pixel width and height of a character, and maybe output actual glyphs at
1585 the same time if IT->glyph_row is non-null. See the explanation of
1586 struct display_iterator in dispextern.h for an overview.
1588 produce_glyphs also stores the result of glyph width, ascent
1589 etc. computations in *IT.
1591 IT->glyph_row may be null, in which case produce_glyphs does not
1592 actually fill in the glyphs. This is used in the move_* functions
1593 in xdisp.c for text width and height computations.
1595 Callers usually don't call produce_glyphs directly;
1596 instead they use the macro PRODUCE_GLYPHS. */
1602 /* If a hook is installed, let it do the work. */
1603 xassert (it
->what
== IT_CHARACTER
1604 || it
->what
== IT_COMPOSITION
1605 || it
->what
== IT_IMAGE
1606 || it
->what
== IT_STRETCH
);
1608 /* Nothing but characters are supported on terminal frames. For a
1609 composition sequence, it->c is the first character of the
1611 xassert (it
->what
== IT_CHARACTER
1612 || it
->what
== IT_COMPOSITION
);
1614 if (it
->c
>= 040 && it
->c
< 0177)
1616 it
->pixel_width
= it
->nglyphs
= 1;
1620 else if (it
->c
== '\n')
1621 it
->pixel_width
= it
->nglyphs
= 0;
1622 else if (it
->c
== '\t')
1624 int absolute_x
= (it
->current_x
1625 + it
->continuation_lines_width
);
1627 = (((1 + absolute_x
+ it
->tab_width
- 1)
1632 /* If part of the TAB has been displayed on the previous line
1633 which is continued now, continuation_lines_width will have
1634 been incremented already by the part that fitted on the
1635 continued line. So, we will get the right number of spaces
1637 nspaces
= next_tab_x
- absolute_x
;
1644 it
->pixel_width
= it
->len
= 1;
1652 it
->pixel_width
= nspaces
;
1653 it
->nglyphs
= nspaces
;
1655 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1657 /* Coming here means that it->c is from display table, thus we
1658 must send the code as is to the terminal. Although there's
1659 no way to know how many columns it occupies on a screen, it
1660 is a good assumption that a single byte code has 1-column
1662 it
->pixel_width
= it
->nglyphs
= 1;
1668 /* A multi-byte character. The display width is fixed for all
1669 characters of the set. Some of the glyphs may have to be
1670 ignored because they are already displayed in a continued
1672 int charset
= CHAR_CHARSET (it
->c
);
1674 it
->pixel_width
= CHARSET_WIDTH (charset
);
1675 it
->nglyphs
= it
->pixel_width
;
1681 /* Advance current_x by the pixel width as a convenience for
1683 if (it
->area
== TEXT_AREA
)
1684 it
->current_x
+= it
->pixel_width
;
1685 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1686 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1690 /* Get information about special display element WHAT in an
1691 environment described by IT. WHAT is one of IT_TRUNCATION or
1692 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1693 non-null glyph_row member. This function ensures that fields like
1694 face_id, c, len of IT are left untouched. */
1697 produce_special_glyphs (it
, what
)
1699 enum display_element_type what
;
1705 temp_it
.what
= IT_CHARACTER
;
1707 temp_it
.object
= make_number (0);
1708 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1710 if (what
== IT_CONTINUATION
)
1712 /* Continuation glyph. */
1714 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1715 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1717 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it
->dp
)));
1718 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1723 produce_glyphs (&temp_it
);
1724 it
->pixel_width
= temp_it
.pixel_width
;
1725 it
->nglyphs
= temp_it
.pixel_width
;
1727 else if (what
== IT_TRUNCATION
)
1729 /* Truncation glyph. */
1731 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1732 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1734 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it
->dp
)));
1735 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1740 produce_glyphs (&temp_it
);
1741 it
->pixel_width
= temp_it
.pixel_width
;
1742 it
->nglyphs
= temp_it
.pixel_width
;
1750 /***********************************************************************
1752 ***********************************************************************/
1754 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1755 one of the enumerators from enum no_color_bit, or a bit set built
1756 from them. Some display attributes may not be used together with
1757 color; the termcap capability `NC' specifies which ones. */
1759 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1760 (tty->TN_max_colors > 0 \
1761 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1764 /* Turn appearances of face FACE_ID on tty frame F on. */
1767 turn_on_face (f
, face_id
)
1771 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1772 long fg
= face
->foreground
;
1773 long bg
= face
->background
;
1774 struct tty_display_info
*tty
= FRAME_TTY (f
);
1776 /* Do this first because TS_end_standout_mode may be the same
1777 as TS_exit_attribute_mode, which turns all appearances off. */
1778 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1780 if (tty
->TN_max_colors
> 0)
1782 if (fg
>= 0 && bg
>= 0)
1784 /* If the terminal supports colors, we can set them
1785 below without using reverse video. The face's fg
1786 and bg colors are set as they should appear on
1787 the screen, i.e. they take the inverse-video'ness
1788 of the face already into account. */
1790 else if (inverse_video
)
1792 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1793 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1794 toggle_highlight (tty
);
1798 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1799 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1800 toggle_highlight (tty
);
1805 /* If we can't display colors, use reverse video
1806 if the face specifies that. */
1809 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1810 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1811 toggle_highlight (tty
);
1815 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1816 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1817 toggle_highlight (tty
);
1822 if (face
->tty_bold_p
)
1824 if (MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1825 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1827 else if (face
->tty_dim_p
)
1828 if (MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1829 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1831 /* Alternate charset and blinking not yet used. */
1832 if (face
->tty_alt_charset_p
1833 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1834 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1836 if (face
->tty_blinking_p
1837 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1838 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1840 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1841 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1843 if (tty
->TN_max_colors
> 0)
1847 if (fg
>= 0 && tty
->TS_set_foreground
)
1849 p
= tparam (tty
->TS_set_foreground
, NULL
, 0, (int) fg
);
1854 if (bg
>= 0 && tty
->TS_set_background
)
1856 p
= tparam (tty
->TS_set_background
, NULL
, 0, (int) bg
);
1864 /* Turn off appearances of face FACE_ID on tty frame F. */
1867 turn_off_face (f
, face_id
)
1871 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1872 struct tty_display_info
*tty
= FRAME_TTY (f
);
1874 xassert (face
!= NULL
);
1876 if (tty
->TS_exit_attribute_mode
)
1878 /* Capability "me" will turn off appearance modes double-bright,
1879 half-bright, reverse-video, standout, underline. It may or
1880 may not turn off alt-char-mode. */
1881 if (face
->tty_bold_p
1883 || face
->tty_reverse_p
1884 || face
->tty_alt_charset_p
1885 || face
->tty_blinking_p
1886 || face
->tty_underline_p
)
1888 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
1889 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
1890 tty
->standout_mode
= 0;
1893 if (face
->tty_alt_charset_p
)
1894 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1898 /* If we don't have "me" we can only have those appearances
1899 that have exit sequences defined. */
1900 if (face
->tty_alt_charset_p
)
1901 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1903 if (face
->tty_underline_p
)
1904 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
1907 /* Switch back to default colors. */
1908 if (tty
->TN_max_colors
> 0
1909 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
1910 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
1911 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
1912 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
1913 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
1917 /* Return non-zero if the terminal on frame F supports all of the
1918 capabilities in CAPS simultaneously, with foreground and background
1919 colors FG and BG. */
1922 tty_capable_p (tty
, caps
, fg
, bg
)
1923 struct tty_display_info
*tty
;
1925 unsigned long fg
, bg
;
1927 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
1928 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
1931 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
1932 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
1933 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
1934 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
1935 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
1936 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
1943 /* Return non-zero if the terminal is capable to display colors. */
1945 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
1947 doc
: /* Return non-nil if TTY can display colors on DISPLAY. */)
1949 Lisp_Object display
;
1951 struct tty_display_info
*tty
= FRAME_TTY (SELECTED_FRAME ());
1952 return tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
1955 /* Return the number of supported colors. */
1956 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
1957 Stty_display_color_cells
, 0, 1, 0,
1958 doc
: /* Return the number of colors supported by TTY on DISPLAY. */)
1960 Lisp_Object display
;
1962 struct tty_display_info
*tty
= FRAME_TTY (SELECTED_FRAME ());
1963 return make_number (tty
->TN_max_colors
);
1968 /* Save or restore the default color-related capabilities of this
1971 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
1974 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
1975 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
1979 if (default_orig_pair
)
1980 xfree (default_orig_pair
);
1981 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
1983 if (default_set_foreground
)
1984 xfree (default_set_foreground
);
1985 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
1988 if (default_set_background
)
1989 xfree (default_set_background
);
1990 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
1993 default_max_colors
= tty
->TN_max_colors
;
1994 default_max_pairs
= tty
->TN_max_pairs
;
1995 default_no_color_video
= tty
->TN_no_color_video
;
1999 tty
->TS_orig_pair
= default_orig_pair
;
2000 tty
->TS_set_foreground
= default_set_foreground
;
2001 tty
->TS_set_background
= default_set_background
;
2002 tty
->TN_max_colors
= default_max_colors
;
2003 tty
->TN_max_pairs
= default_max_pairs
;
2004 tty
->TN_no_color_video
= default_no_color_video
;
2008 /* Setup one of the standard tty color schemes according to MODE.
2009 MODE's value is generally the number of colors which we want to
2010 support; zero means set up for the default capabilities, the ones
2011 we saw at term_init time; -1 means turn off color support. */
2013 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2015 /* Canonicalize all negative values of MODE. */
2021 case -1: /* no colors at all */
2022 tty
->TN_max_colors
= 0;
2023 tty
->TN_max_pairs
= 0;
2024 tty
->TN_no_color_video
= 0;
2025 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2027 case 0: /* default colors, if any */
2029 tty_default_color_capabilities (tty
, 0);
2031 case 8: /* 8 standard ANSI colors */
2032 tty
->TS_orig_pair
= "\033[0m";
2034 tty
->TS_set_foreground
= "\033[3%p1%dm";
2035 tty
->TS_set_background
= "\033[4%p1%dm";
2037 tty
->TS_set_foreground
= "\033[3%dm";
2038 tty
->TS_set_background
= "\033[4%dm";
2040 tty
->TN_max_colors
= 8;
2041 tty
->TN_max_pairs
= 64;
2042 tty
->TN_no_color_video
= 0;
2048 set_tty_color_mode (f
, val
)
2052 Lisp_Object color_mode_spec
, current_mode_spec
;
2053 Lisp_Object color_mode
, current_mode
;
2055 extern Lisp_Object Qtty_color_mode
;
2056 Lisp_Object tty_color_mode_alist
;
2058 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2065 if (NILP (tty_color_mode_alist
))
2066 color_mode_spec
= Qnil
;
2068 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2070 if (CONSP (color_mode_spec
))
2071 color_mode
= XCDR (color_mode_spec
);
2076 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2078 if (CONSP (current_mode_spec
))
2079 current_mode
= XCDR (current_mode_spec
);
2081 current_mode
= Qnil
;
2082 if (INTEGERP (color_mode
))
2083 mode
= XINT (color_mode
);
2085 mode
= 0; /* meaning default */
2086 if (INTEGERP (current_mode
))
2087 old_mode
= XINT (current_mode
);
2091 if (mode
!= old_mode
)
2093 tty_setup_colors (FRAME_TTY (f
), mode
);
2094 /* This recomputes all the faces given the new color
2096 call0 (intern ("tty-set-up-initial-frame-faces"));
2101 #endif /* !WINDOWSNT */
2105 struct tty_display_info
*
2106 get_named_tty (name
)
2109 struct tty_display_info
*tty
= tty_list
;
2112 if ((tty
->name
== 0 && name
== 0)
2113 || (name
&& tty
->name
&& !strcmp (tty
->name
, name
)))
2123 DEFUN ("frame-tty-name", Fframe_tty_name
, Sframe_tty_name
, 0, 1, 0,
2124 doc
: /* Return the name of the TTY device that FRAME is displayed on. */)
2132 f
= XFRAME (selected_frame
);
2136 CHECK_LIVE_FRAME (frame
);
2140 if (f
->output_method
!= output_termcap
)
2141 wrong_type_argument (Qframe_tty_name
, frame
);
2143 if (FRAME_TTY (f
)->name
)
2144 return build_string (FRAME_TTY (f
)->name
);
2149 DEFUN ("frame-tty-type", Fframe_tty_type
, Sframe_tty_type
, 0, 1, 0,
2150 doc
: /* Return the type of the TTY device that FRAME is displayed on. */)
2158 f
= XFRAME (selected_frame
);
2162 CHECK_LIVE_FRAME (frame
);
2166 if (f
->output_method
!= output_termcap
)
2167 wrong_type_argument (Qframe_tty_type
, frame
);
2169 if (FRAME_TTY (f
)->type
)
2170 return build_string (FRAME_TTY (f
)->type
);
2176 /***********************************************************************
2178 ***********************************************************************/
2180 struct tty_display_info
*
2181 term_dummy_init (void)
2183 if (initialized
|| tty_list
)
2184 error ("tty already initialized");
2186 tty_list
= xmalloc (sizeof (struct tty_display_info
));
2187 bzero (tty_list
, sizeof (struct tty_display_info
));
2189 tty_list
->input
= stdin
;
2190 tty_list
->output
= stdout
;
2191 tty_list
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
2192 tty_list
->display_method
= (struct display_method
*) xmalloc (sizeof (struct display_method
));
2193 tty_list
->kboard
= initial_kboard
;
2198 struct tty_display_info
*
2199 term_init (Lisp_Object frame
, char *name
, char *terminal_type
)
2202 char **address
= &area
;
2203 char *buffer
= NULL
;
2204 int buffer_size
= 4096;
2207 struct frame
*f
= XFRAME (frame
);
2208 struct tty_display_info
*tty
;
2210 tty
= get_named_tty (name
);
2213 /* Return the previously initialized terminal, except if it is
2214 the dummy terminal created for the initial frame. */
2218 /* Free up temporary structures. */
2221 if (tty
->display_method
)
2222 xfree (tty
->display_method
);
2223 if (tty
->kboard
!= initial_kboard
)
2229 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
2230 bzero (tty
, sizeof (struct tty_display_info
));
2231 tty
->next
= tty_list
;
2235 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
2238 /* Each termcap frame has its own display method. */
2239 tty
->display_method
= (struct display_method
*) xmalloc (sizeof (struct display_method
));
2240 bzero (tty
->display_method
, sizeof (struct display_method
));
2242 /* Initialize the common members in the new display method with our
2243 predefined template. */
2244 *tty
->display_method
= tty_display_method_template
;
2245 f
->display_method
= tty
->display_method
;
2247 /* Make sure the frame is live; if an error happens, it must be
2249 f
->output_method
= output_termcap
;
2250 if (! f
->output_data
.tty
)
2252 f
->output_data
.tty
->display_info
= tty
;
2257 fd
= emacs_open (name
, O_RDWR
, 0);
2261 error ("Could not open file: %s", name
);
2263 file
= fdopen (fd
, "w+");
2264 tty
->name
= xstrdup (name
);
2272 tty
->output
= stdout
;
2275 tty
->type
= xstrdup (terminal_type
);
2277 add_keyboard_wait_descriptor (fileno (tty
->input
));
2280 initialize_w32_display ();
2284 area
= (char *) xmalloc (2044);
2286 FrameRows (tty
) = FRAME_LINES (f
);
2287 FrameCols (tty
) = FRAME_COLS (f
);
2288 tty
->specified_window
= FRAME_LINES (f
);
2290 tty
->display_method
->delete_in_insert_mode
= 1;
2293 FRAME_SCROLL_REGION_OK (f
) = 0;
2295 /* Seems to insert lines when it's not supposed to, messing
2296 up the display. In doing a trace, it didn't seem to be
2297 called much, so I don't think we're losing anything by
2299 FRAME_LINE_INS_DEL_OK (f
) = 0;
2300 FRAME_CHAR_INS_DEL_OK (f
) = 1;
2304 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
2305 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
2306 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2309 #else /* not WINDOWSNT */
2313 buffer
= (char *) xmalloc (buffer_size
);
2314 status
= tgetent (buffer
, terminal_type
);
2322 error ("Cannot open terminfo database file");
2325 fatal ("Cannot open terminfo database file");
2331 error ("Cannot open termcap database file");
2334 fatal ("Cannot open termcap database file");
2344 error ("Terminal type %s is not defined", terminal_type
);
2347 fatal ("Terminal type %s is not defined.\n\
2348 If that is not the actual type of terminal you have,\n\
2349 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2350 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2351 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2358 error ("Terminal type %s is not defined", terminal_type
);
2361 fatal ("Terminal type %s is not defined.\n\
2362 If that is not the actual type of terminal you have,\n\
2363 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2364 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2365 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2371 if (strlen (buffer
) >= buffer_size
)
2373 buffer_size
= strlen (buffer
);
2375 area
= (char *) xmalloc (buffer_size
);
2377 tty
->TS_ins_line
= tgetstr ("al", address
);
2378 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
2379 tty
->TS_bell
= tgetstr ("bl", address
);
2380 BackTab (tty
) = tgetstr ("bt", address
);
2381 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
2382 tty
->TS_clr_line
= tgetstr ("ce", address
);
2383 tty
->TS_clr_frame
= tgetstr ("cl", address
);
2384 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
2385 AbsPosition (tty
) = tgetstr ("cm", address
);
2386 CR (tty
) = tgetstr ("cr", address
);
2387 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
2388 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
2389 RowPosition (tty
) = tgetstr ("cv", address
);
2390 tty
->TS_del_char
= tgetstr ("dc", address
);
2391 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
2392 tty
->TS_del_line
= tgetstr ("dl", address
);
2393 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
2394 tty
->TS_delete_mode
= tgetstr ("dm", address
);
2395 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
2396 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
2397 Home (tty
) = tgetstr ("ho", address
);
2398 tty
->TS_ins_char
= tgetstr ("ic", address
);
2399 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
2400 tty
->TS_insert_mode
= tgetstr ("im", address
);
2401 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
2402 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
2403 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
2404 LastLine (tty
) = tgetstr ("ll", address
);
2405 Right (tty
) = tgetstr ("nd", address
);
2406 Down (tty
) = tgetstr ("do", address
);
2408 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
2410 /* VMS puts a carriage return before each linefeed,
2411 so it is not safe to use linefeeds. */
2412 if (Down (tty
) && Down (tty
)[0] == '\n' && Down (tty
)[1] == '\0')
2415 if (tgetflag ("bs"))
2416 Left (tty
) = "\b"; /* can't possibly be longer! */
2417 else /* (Actually, "bs" is obsolete...) */
2418 Left (tty
) = tgetstr ("le", address
);
2420 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
2421 tty
->TS_pad_char
= tgetstr ("pc", address
);
2422 tty
->TS_repeat
= tgetstr ("rp", address
);
2423 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
2424 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
2425 tty
->TS_standout_mode
= tgetstr ("so", address
);
2426 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
2427 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
2428 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
2429 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
2430 Up (tty
) = tgetstr ("up", address
);
2431 tty
->TS_visible_bell
= tgetstr ("vb", address
);
2432 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
2433 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
2434 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
2435 tty
->TS_set_window
= tgetstr ("wi", address
);
2437 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
2438 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
2439 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
2440 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
2441 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
2442 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
2443 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2444 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2445 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
2447 MultiUp (tty
) = tgetstr ("UP", address
);
2448 MultiDown (tty
) = tgetstr ("DO", address
);
2449 MultiLeft (tty
) = tgetstr ("LE", address
);
2450 MultiRight (tty
) = tgetstr ("RI", address
);
2452 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2453 color because we can't switch back to the default foreground and
2455 tty
->TS_orig_pair
= tgetstr ("op", address
);
2456 if (tty
->TS_orig_pair
)
2458 tty
->TS_set_foreground
= tgetstr ("AF", address
);
2459 tty
->TS_set_background
= tgetstr ("AB", address
);
2460 if (!tty
->TS_set_foreground
)
2463 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
2464 tty
->TS_set_background
= tgetstr ("Sb", address
);
2467 tty
->TN_max_colors
= tgetnum ("Co");
2468 tty
->TN_max_pairs
= tgetnum ("pa");
2470 tty
->TN_no_color_video
= tgetnum ("NC");
2471 if (tty
->TN_no_color_video
== -1)
2472 tty
->TN_no_color_video
= 0;
2475 tty_default_color_capabilities (tty
, 1);
2477 MagicWrap (tty
) = tgetflag ("xn");
2478 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2479 the former flag imply the latter. */
2480 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
2481 FRAME_MEMORY_BELOW_FRAME (f
) = tgetflag ("db");
2482 tty
->TF_hazeltine
= tgetflag ("hz");
2483 FRAME_MUST_WRITE_SPACES (f
) = tgetflag ("in");
2484 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
2485 tty
->TF_insmode_motion
= tgetflag ("mi");
2486 tty
->TF_standout_motion
= tgetflag ("ms");
2487 tty
->TF_underscore
= tgetflag ("ul");
2488 tty
->TF_teleray
= tgetflag ("xt");
2490 term_get_fkeys (address
);
2492 /* Get frame size from system, or else from termcap. */
2495 get_tty_size (fileno (TTY_INPUT (tty
)), &width
, &height
);
2496 FrameCols (tty
) = width
;
2497 FrameRows (tty
) = height
;
2500 if (FrameCols (tty
) <= 0)
2501 FrameCols (tty
) = tgetnum ("co");
2502 if (FrameRows (tty
) <= 0)
2503 FrameRows (tty
) = tgetnum ("li");
2505 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
2510 error ("Screen size %dx%d is too small",
2511 FrameCols (tty
), FrameRows (tty
));
2515 fatal ("Screen size %dx%d is too small",
2516 FrameCols (tty
), FrameRows (tty
));
2520 #if 0 /* This is not used anywhere. */
2521 tty
->display_method
->min_padding_speed
= tgetnum ("pb");
2524 TabWidth (tty
) = tgetnum ("tw");
2527 /* These capabilities commonly use ^J.
2528 I don't know why, but sending them on VMS does not work;
2529 it causes following spaces to be lost, sometimes.
2530 For now, the simplest fix is to avoid using these capabilities ever. */
2531 if (Down (tty
) && Down (tty
)[0] == '\n')
2536 tty
->TS_bell
= "\07";
2538 if (!tty
->TS_fwd_scroll
)
2539 tty
->TS_fwd_scroll
= Down (tty
);
2541 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
2543 if (TabWidth (tty
) < 0)
2546 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2547 and newer termcap doc does not seem to say there is a default.
2548 if (!tty->Wcm->cm_tab)
2549 tty->Wcm->cm_tab = "\t";
2552 /* We don't support standout modes that use `magic cookies', so
2553 turn off any that do. */
2554 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
2556 tty
->TS_standout_mode
= 0;
2557 tty
->TS_end_standout_mode
= 0;
2559 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
2561 tty
->TS_enter_underline_mode
= 0;
2562 tty
->TS_exit_underline_mode
= 0;
2565 /* If there's no standout mode, try to use underlining instead. */
2566 if (tty
->TS_standout_mode
== 0)
2568 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
2569 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
2572 /* If no `se' string, try using a `me' string instead.
2573 If that fails, we can't use standout mode at all. */
2574 if (tty
->TS_end_standout_mode
== 0)
2576 char *s
= tgetstr ("me", address
);
2578 tty
->TS_end_standout_mode
= s
;
2580 tty
->TS_standout_mode
= 0;
2583 if (tty
->TF_teleray
)
2585 tty
->Wcm
->cm_tab
= 0;
2586 /* We can't support standout mode, because it uses magic cookies. */
2587 tty
->TS_standout_mode
= 0;
2588 /* But that means we cannot rely on ^M to go to column zero! */
2590 /* LF can't be trusted either -- can alter hpos */
2591 /* if move at column 0 thru a line with TS_standout_mode */
2595 /* Special handling for certain terminal types known to need it */
2597 if (!strcmp (terminal_type
, "supdup"))
2599 FRAME_MEMORY_BELOW_FRAME (f
) = 1;
2600 tty
->Wcm
->cm_losewrap
= 1;
2602 if (!strncmp (terminal_type
, "c10", 3)
2603 || !strcmp (terminal_type
, "perq"))
2605 /* Supply a makeshift :wi string.
2606 This string is not valid in general since it works only
2607 for windows starting at the upper left corner;
2608 but that is all Emacs uses.
2610 This string works only if the frame is using
2611 the top of the video memory, because addressing is memory-relative.
2612 So first check the :ti string to see if that is true.
2614 It would be simpler if the :wi string could go in the termcap
2615 entry, but it can't because it is not fully valid.
2616 If it were in the termcap entry, it would confuse other programs. */
2617 if (!tty
->TS_set_window
)
2619 p
= tty
->TS_termcap_modes
;
2620 while (*p
&& strcmp (p
, "\033v "))
2623 tty
->TS_set_window
= "\033v%C %C %C %C ";
2625 /* Termcap entry often fails to have :in: flag */
2626 FRAME_MUST_WRITE_SPACES (f
) = 1;
2627 /* :ti string typically fails to have \E^G! in it */
2628 /* This limits scope of insert-char to one line. */
2629 strcpy (area
, tty
->TS_termcap_modes
);
2630 strcat (area
, "\033\007!");
2631 tty
->TS_termcap_modes
= area
;
2632 area
+= strlen (area
) + 1;
2633 p
= AbsPosition (tty
);
2634 /* Change all %+ parameters to %C, to handle
2635 values above 96 correctly for the C100. */
2638 if (p
[0] == '%' && p
[1] == '+')
2644 tty
->specified_window
= FrameRows (tty
);
2646 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
2650 error ("Terminal type \"%s\" is not powerful enough to run Emacs",
2655 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2656 It lacks the ability to position the cursor.\n\
2657 If that is not the actual type of terminal you have, use either the\n\
2658 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2659 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2663 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2664 It lacks the ability to position the cursor.\n\
2665 If that is not the actual type of terminal you have,\n\
2666 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2667 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2668 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2670 # else /* TERMCAP */
2671 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2672 It lacks the ability to position the cursor.\n\
2673 If that is not the actual type of terminal you have,\n\
2674 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2675 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2676 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2678 # endif /* TERMINFO */
2682 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
2687 error ("The frame size has not been specified");
2690 fatal ("The frame size has not been specified");
2693 tty
->delete_in_insert_mode
2694 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
2695 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
2697 tty
->se_is_so
= (tty
->TS_standout_mode
2698 && tty
->TS_end_standout_mode
2699 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
2701 UseTabs (tty
) = tabs_safe_p (fileno (TTY_INPUT (tty
))) && TabWidth (tty
) == 8;
2703 FRAME_SCROLL_REGION_OK (f
)
2705 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
2707 FRAME_LINE_INS_DEL_OK (f
)
2708 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
2709 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
2710 || (FRAME_SCROLL_REGION_OK (f
)
2711 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
2713 FRAME_CHAR_INS_DEL_OK (f
)
2714 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
2715 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
2716 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
2718 FRAME_FAST_CLEAR_END_OF_LINE (f
) = tty
->TS_clr_line
!= 0;
2720 init_baud_rate (fileno (TTY_INPUT (tty
)));
2721 if (read_socket_hook
) /* Baudrate is somewhat
2722 meaningless in this case */
2725 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
2726 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
2729 /* The HFT system on AIX doesn't optimize for scrolling, so it's
2730 really ugly at times. */
2731 FRAME_LINE_INS_DEL_OK (f
) = 0;
2732 FRAME_CHAR_INS_DEL_OK (f
) = 0;
2736 tty
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
2737 init_kboard (tty
->kboard
);
2738 tty
->kboard
->next_kboard
= all_kboards
;
2739 all_kboards
= tty
->kboard
;
2740 /* Don't let the initial kboard remain current longer than necessary.
2741 That would cause problems if a file loaded on startup tries to
2742 prompt in the mini-buffer. */
2743 if (current_kboard
== initial_kboard
)
2744 current_kboard
= tty
->kboard
;
2745 tty
->kboard
->reference_count
++;
2748 /* Don't do this. I think termcap may still need the buffer. */
2749 /* xfree (buffer); */
2751 /* Set the top frame to the first frame on this display. */
2752 tty
->top_frame
= frame
;
2754 /* Init system terminal modes (RAW or CBREAK, etc.). */
2755 init_sys_modes (tty
);
2758 #endif /* not WINDOWSNT */
2763 fatal (str
, arg1
, arg2
)
2764 char *str
, *arg1
, *arg2
;
2766 fprintf (stderr
, "emacs: ");
2767 fprintf (stderr
, str
, arg1
, arg2
);
2768 fprintf (stderr
, "\n");
2775 DEFUN ("delete-tty", Fdelete_tty
, Sdelete_tty
, 0, 1, 0,
2776 doc
: /* Delete all frames on the terminal named TTY, and close the device.
2777 If omitted, TTY defaults to the controlling terminal.
2779 This function runs `delete-tty-after-functions' after closing the
2780 tty. The functions are run with one arg, the frame to be deleted. */)
2784 struct tty_display_info
*t
;
2789 if (SBYTES (tty
) > 0)
2791 name
= (char *) alloca (SBYTES (tty
) + 1);
2792 strncpy (name
, SDATA (tty
), SBYTES (tty
));
2793 name
[SBYTES (tty
)] = 0;
2796 t
= get_named_tty (name
);
2799 error ("No such tty device: %s", name
);
2804 static int deleting_tty
= 0;
2807 delete_tty (struct tty_display_info
*tty
)
2809 Lisp_Object tail
, frame
;
2813 /* We get a recursive call when we delete the last frame on this
2819 if (tty
== tty_list
)
2820 tty_list
= tty
->next
;
2823 struct tty_display_info
*p
;
2824 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
2828 /* This should not happen. */
2831 p
->next
= tty
->next
;
2835 FOR_EACH_FRAME (tail
, frame
)
2837 struct frame
*f
= XFRAME (frame
);
2838 if (FRAME_TERMCAP_P (f
) && FRAME_LIVE_P (f
) && FRAME_TTY (f
) == tty
)
2840 Fdelete_frame (frame
, Qt
);
2841 f
->output_data
.tty
= 0;
2845 reset_sys_modes (tty
);
2847 tty_name
= tty
->name
;
2853 delete_keyboard_wait_descriptor (fileno (tty
->input
));
2854 if (tty
->input
!= stdin
)
2855 fclose (tty
->input
);
2857 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
2858 fclose (tty
->output
);
2859 if (tty
->termscript
)
2860 fclose (tty
->termscript
);
2863 xfree (tty
->old_tty
);
2868 if (tty
->display_method
)
2869 xfree (tty
->display_method
);
2872 if (tty
->kboard
&& --tty
->kboard
->reference_count
> 0)
2875 delete_kboard (tty
->kboard
);
2878 bzero (tty
, sizeof (struct tty_display_info
));
2882 /* Run `delete-tty-after-functions'. */
2883 if (!NILP (Vrun_hooks
))
2885 Lisp_Object args
[2];
2886 args
[0] = intern ("delete-tty-after-functions");
2889 args
[1] = build_string (tty_name
);
2894 Frun_hook_with_args (2, args
);
2901 /* Mark the pointers in the tty_display_info objects.
2902 Called by the Fgarbage_collector. */
2906 struct tty_display_info
*tty
;
2908 for (tty
= tty_list
; tty
; tty
= tty
->next
)
2911 mark_object (tty
->top_frame
);
2920 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
2921 doc
: /* Non-nil means the system uses terminfo rather than termcap.
2922 This variable can be used by terminal emulator packages. */);
2924 system_uses_terminfo
= 1;
2926 system_uses_terminfo
= 0;
2929 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
2930 doc
: /* Non-nil means call this function to ring the bell.
2931 The function should accept no arguments. */);
2932 Vring_bell_function
= Qnil
;
2934 DEFVAR_LISP ("delete-tty-after-functions", &Vdelete_tty_after_functions
,
2935 doc
: /* Functions to be run after deleting a tty.
2936 The functions are run with one argument, the name of the tty to be deleted.
2937 See `delete-tty'. */);
2938 Vdelete_tty_after_functions
= Qnil
;
2940 Qframe_tty_name
= intern ("frame-tty-name");
2941 staticpro (&Qframe_tty_name
);
2943 Qframe_tty_type
= intern ("frame-tty-type");
2944 staticpro (&Qframe_tty_type
);
2946 defsubr (&Stty_display_color_p
);
2947 defsubr (&Stty_display_color_cells
);
2948 defsubr (&Sframe_tty_name
);
2949 defsubr (&Sframe_tty_type
);
2950 defsubr (&Sdelete_tty
);
2952 Fprovide (intern ("multi-tty"), Qnil
);
2954 /* Initialize the display method template. */
2956 /* Termcap-based displays don't support window-based redisplay. */
2957 tty_display_method_template
.rif
= 0;
2963 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
2964 (do not change this comment) */