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 /* A template for tty display methods, with common values
272 static struct display_method tty_display_method_template
;
274 /* Frame currently being redisplayed; 0 if not currently redisplaying.
275 (Direct output does not count). */
277 FRAME_PTR updating_frame
;
279 /* Provided for lisp packages. */
281 static int system_uses_terminfo
;
285 extern char *tgetstr ();
289 /* We aren't X windows, but we aren't termcap either. This makes me
290 uncertain as to what value to use for frame.output_method. For
291 this file, we'll define FRAME_TERMCAP_P to be zero so that our
292 output hooks get called instead of the termcap functions. Probably
293 the best long-term solution is to define an output_windows_nt... */
295 #undef FRAME_TERMCAP_P
296 #define FRAME_TERMCAP_P(_f_) 0
297 #endif /* WINDOWSNT */
302 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
304 if (!NILP (Vring_bell_function
))
306 Lisp_Object function
;
308 /* Temporarily set the global variable to nil
309 so that if we get an error, it stays nil
310 and we don't call it over and over.
312 We don't specbind it, because that would carefully
313 restore the bad value if there's an error
314 and make the loop of errors happen anyway. */
316 function
= Vring_bell_function
;
317 Vring_bell_function
= Qnil
;
321 Vring_bell_function
= function
;
323 else if (!FRAME_TERMCAP_P (f
))
324 (*ring_bell_hook
) ();
326 struct tty_display_info
*tty
= FRAME_TTY (f
);
327 OUTPUT (tty
, tty
->TS_visible_bell
&& visible_bell
? tty
->TS_visible_bell
: tty
->TS_bell
);
331 void tty_set_terminal_modes (struct tty_display_info
*tty
)
333 OUTPUT_IF (tty
, tty
->TS_termcap_modes
);
334 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
335 OUTPUT_IF (tty
, tty
->TS_keypad_mode
);
340 set_terminal_modes ()
342 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
343 if (FRAME_TERMCAP_P (f
))
344 tty_set_terminal_modes (FRAME_TTY (f
));
346 (*set_terminal_modes_hook
) ();
349 void tty_reset_terminal_modes (struct tty_display_info
*tty
)
351 turn_off_highlight (tty
);
352 turn_off_insert (tty
);
353 OUTPUT_IF (tty
, tty
->TS_end_keypad_mode
);
354 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
355 OUTPUT_IF (tty
, tty
->TS_end_termcap_modes
);
356 OUTPUT_IF (tty
, tty
->TS_orig_pair
);
357 /* Output raw CR so kernel can track the cursor hpos. */
363 reset_terminal_modes ()
365 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
366 if (FRAME_TERMCAP_P (f
))
367 tty_reset_terminal_modes (FRAME_TTY (f
));
368 else if (reset_terminal_modes_hook
)
369 (*reset_terminal_modes_hook
) ();
378 rif
= f
->display_method
->rif
;
379 if (!FRAME_TERMCAP_P (f
))
380 update_begin_hook (f
);
387 if (FRAME_TERMCAP_P (f
))
389 struct tty_display_info
*tty
= FRAME_TTY (f
);
390 if (!XWINDOW (selected_window
)->cursor_off_p
)
391 tty_show_cursor (tty
);
392 turn_off_insert (tty
);
393 background_highlight (tty
);
398 updating_frame
= NULL
;
402 set_terminal_window (size
)
405 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
406 if (FRAME_TERMCAP_P (f
))
408 struct tty_display_info
*tty
= FRAME_TTY (f
);
409 tty
->specified_window
= size
? size
: FRAME_LINES (f
);
410 if (FRAME_SCROLL_REGION_OK (f
))
411 set_scroll_region (0, tty
->specified_window
);
414 set_terminal_window_hook (size
);
418 set_scroll_region (start
, stop
)
422 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
423 struct tty_display_info
*tty
= FRAME_TTY (f
);
425 if (tty
->TS_set_scroll_region
)
426 buf
= tparam (tty
->TS_set_scroll_region
, 0, 0, start
, stop
- 1);
427 else if (tty
->TS_set_scroll_region_1
)
428 buf
= tparam (tty
->TS_set_scroll_region_1
, 0, 0,
429 FRAME_LINES (f
), start
,
430 FRAME_LINES (f
) - stop
,
433 buf
= tparam (tty
->TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (f
));
442 turn_on_insert (struct tty_display_info
*tty
)
444 if (!tty
->insert_mode
)
445 OUTPUT (tty
, tty
->TS_insert_mode
);
446 tty
->insert_mode
= 1;
450 turn_off_insert (struct tty_display_info
*tty
)
452 if (tty
->insert_mode
)
453 OUTPUT (tty
, tty
->TS_end_insert_mode
);
454 tty
->insert_mode
= 0;
457 /* Handle highlighting. */
460 turn_off_highlight (struct tty_display_info
*tty
)
462 if (tty
->standout_mode
)
463 OUTPUT_IF (tty
, tty
->TS_end_standout_mode
);
464 tty
->standout_mode
= 0;
468 turn_on_highlight (struct tty_display_info
*tty
)
470 if (!tty
->standout_mode
)
471 OUTPUT_IF (tty
, tty
->TS_standout_mode
);
472 tty
->standout_mode
= 1;
476 toggle_highlight (struct tty_display_info
*tty
)
478 if (tty
->standout_mode
)
479 turn_off_highlight (tty
);
481 turn_on_highlight (tty
);
485 /* Make cursor invisible. */
488 tty_hide_cursor (struct tty_display_info
*tty
)
490 if (tty
->cursor_hidden
== 0)
492 tty
->cursor_hidden
= 1;
493 OUTPUT_IF (tty
, tty
->TS_cursor_invisible
);
498 /* Ensure that cursor is visible. */
501 tty_show_cursor (struct tty_display_info
*tty
)
503 if (tty
->cursor_hidden
)
505 tty
->cursor_hidden
= 0;
506 OUTPUT_IF (tty
, tty
->TS_cursor_normal
);
507 OUTPUT_IF (tty
, tty
->TS_cursor_visible
);
512 /* Set standout mode to the state it should be in for
513 empty space inside windows. What this is,
514 depends on the user option inverse-video. */
517 background_highlight (struct tty_display_info
*tty
)
520 turn_on_highlight (tty
);
522 turn_off_highlight (tty
);
525 /* Set standout mode to the mode specified for the text to be output. */
528 highlight_if_desired (struct tty_display_info
*tty
)
531 turn_on_highlight (tty
);
533 turn_off_highlight (tty
);
537 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
538 frame-relative coordinates. */
541 cursor_to (vpos
, hpos
)
544 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
545 struct tty_display_info
*tty
;
547 if (! FRAME_TERMCAP_P (f
) && cursor_to_hook
)
549 (*cursor_to_hook
) (vpos
, hpos
);
555 /* Detect the case where we are called from reset_sys_modes
556 and the costs have never been calculated. Do nothing. */
557 if (! tty
->costs_set
)
560 if (curY (tty
) == vpos
561 && curX (tty
) == hpos
)
563 if (!tty
->TF_standout_motion
)
564 background_highlight (tty
);
565 if (!tty
->TF_insmode_motion
)
566 turn_off_insert (tty
);
567 cmgoto (tty
, vpos
, hpos
);
570 /* Similar but don't take any account of the wasted characters. */
573 raw_cursor_to (row
, col
)
576 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
577 struct tty_display_info
*tty
;
578 if (! FRAME_TERMCAP_P (f
))
580 (*raw_cursor_to_hook
) (row
, col
);
584 if (curY (tty
) == row
585 && curX (tty
) == col
)
587 if (!tty
->TF_standout_motion
)
588 background_highlight (tty
);
589 if (!tty
->TF_insmode_motion
)
590 turn_off_insert (tty
);
591 cmgoto (tty
, row
, col
);
594 /* Erase operations */
596 /* clear from cursor to end of frame */
602 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
603 struct tty_display_info
*tty
;
605 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (f
))
607 (*clear_to_end_hook
) ();
611 if (tty
->TS_clr_to_bottom
)
613 background_highlight (tty
);
614 OUTPUT (tty
, tty
->TS_clr_to_bottom
);
618 for (i
= curY (tty
); i
< FRAME_LINES (f
); i
++)
621 clear_end_of_line (FRAME_COLS (f
));
626 /* Clear entire frame */
631 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
632 struct tty_display_info
*tty
;
634 if (clear_frame_hook
&& ! FRAME_TERMCAP_P (f
))
636 (*clear_frame_hook
) ();
640 if (tty
->TS_clr_frame
)
642 background_highlight (tty
);
643 OUTPUT (tty
, tty
->TS_clr_frame
);
653 /* Clear from cursor to end of line.
654 Assume that the line is already clear starting at column first_unused_hpos.
656 Note that the cursor may be moved, on terminals lacking a `ce' string. */
659 clear_end_of_line (first_unused_hpos
)
660 int first_unused_hpos
;
662 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
663 struct tty_display_info
*tty
;
665 if (clear_end_of_line_hook
&& ! FRAME_TERMCAP_P (f
))
667 (*clear_end_of_line_hook
) (first_unused_hpos
);
671 tty_clear_end_of_line (FRAME_TTY (f
), first_unused_hpos
);
675 tty_clear_end_of_line (struct tty_display_info
*tty
, int first_unused_hpos
)
678 /* Detect the case where we are called from reset_sys_modes
679 and the costs have never been calculated. Do nothing. */
680 if (! tty
->costs_set
)
683 if (curX (tty
) >= first_unused_hpos
)
685 background_highlight (tty
);
686 if (tty
->TS_clr_line
)
688 OUTPUT1 (tty
, tty
->TS_clr_line
);
691 { /* have to do it the hard way */
692 turn_off_insert (tty
);
694 /* Do not write in last row last col with Auto-wrap on. */
696 && curY (tty
) == FrameRows (tty
) - 1
697 && first_unused_hpos
== FrameCols (tty
))
700 for (i
= curX (tty
); i
< first_unused_hpos
; i
++)
702 if (TTY_TERMSCRIPT (tty
))
703 fputc (' ', TTY_TERMSCRIPT (tty
));
704 fputc (' ', TTY_OUTPUT (tty
));
706 cmplus (tty
, first_unused_hpos
- curX (tty
));
710 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
711 store them at DST. Do not write more than DST_LEN bytes. That may
712 require stopping before all SRC_LEN input glyphs have been
715 We store the number of glyphs actually converted in *CONSUMED. The
716 return value is the number of bytes store in DST. */
719 encode_terminal_code (src
, dst
, src_len
, dst_len
, consumed
)
723 int dst_len
, *consumed
;
725 struct glyph
*src_start
= src
, *src_end
= src
+ src_len
;
726 unsigned char *dst_start
= dst
, *dst_end
= dst
+ dst_len
;
728 unsigned char workbuf
[MAX_MULTIBYTE_LENGTH
];
729 const unsigned char *buf
;
731 register int tlen
= GLYPH_TABLE_LENGTH
;
732 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
734 struct coding_system
*coding
;
736 /* If terminal_coding does any conversion, use it, otherwise use
737 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
738 because it always return 1 if the member src_multibyte is 1. */
739 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
741 : &safe_terminal_coding
);
743 while (src
< src_end
)
745 /* We must skip glyphs to be padded for a wide character. */
746 if (! CHAR_GLYPH_PADDING_P (*src
))
748 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
750 if (g
< 0 || g
>= tlen
)
752 /* This glyph doesn't has an entry in Vglyph_table. */
753 if (! CHAR_VALID_P (src
->u
.ch
, 0))
757 coding
->src_multibyte
= 0;
761 len
= CHAR_STRING (src
->u
.ch
, workbuf
);
763 coding
->src_multibyte
= 1;
768 /* This glyph has an entry in Vglyph_table,
769 so process any alias before testing for simpleness. */
770 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
772 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
774 /* We set the multi-byte form of a character in G
775 (that should be an ASCII character) at
777 workbuf
[0] = FAST_GLYPH_CHAR (g
);
780 coding
->src_multibyte
= 0;
784 /* We have a string in Vglyph_table. */
785 len
= GLYPH_LENGTH (tbase
, g
);
786 buf
= GLYPH_STRING (tbase
, g
);
787 coding
->src_multibyte
= STRING_MULTIBYTE (tbase
[g
]);
791 result
= encode_coding (coding
, buf
, dst
, len
, dst_end
- dst
);
792 len
-= coding
->consumed
;
793 dst
+= coding
->produced
;
794 if (result
== CODING_FINISH_INSUFFICIENT_DST
795 || (result
== CODING_FINISH_INSUFFICIENT_SRC
796 && len
> dst_end
- dst
))
797 /* The remaining output buffer is too short. We must
798 break the loop here without increasing SRC so that the
799 next call of this function starts from the same glyph. */
804 /* This is the case that a code of the range 0200..0237
805 exists in buf. We must just write out such a code. */
806 buf
+= coding
->consumed
;
814 *consumed
= src
- src_start
;
815 return (dst
- dst_start
);
820 write_glyphs (string
, len
)
821 register struct glyph
*string
;
824 int produced
, consumed
;
825 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
826 struct tty_display_info
*tty
;
827 unsigned char conversion_buffer
[1024];
828 int conversion_buffer_size
= sizeof conversion_buffer
;
830 if (write_glyphs_hook
&& ! FRAME_TERMCAP_P (f
))
832 (*write_glyphs_hook
) (string
, len
);
838 turn_off_insert (tty
);
839 tty_hide_cursor (tty
);
841 /* Don't dare write in last column of bottom line, if Auto-Wrap,
842 since that would scroll the whole frame on some terminals. */
845 && curY (tty
) + 1 == FRAME_LINES (f
)
846 && (curX (tty
) + len
) == FRAME_COLS (f
))
853 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
855 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
859 /* Identify a run of glyphs with the same face. */
860 int face_id
= string
->face_id
;
863 for (n
= 1; n
< len
; ++n
)
864 if (string
[n
].face_id
!= face_id
)
867 /* Turn appearance modes of the face of the run on. */
868 highlight_if_desired (tty
);
869 turn_on_face (f
, face_id
);
873 /* We use a fixed size (1024 bytes) of conversion buffer.
874 Usually it is sufficient, but if not, we just repeat the
876 produced
= encode_terminal_code (string
, conversion_buffer
,
877 n
, conversion_buffer_size
,
881 fwrite (conversion_buffer
, 1, produced
,
883 if (ferror (TTY_OUTPUT (tty
)))
884 clearerr (TTY_OUTPUT (tty
));
885 if (TTY_TERMSCRIPT (tty
))
886 fwrite (conversion_buffer
, 1, produced
,
887 TTY_TERMSCRIPT (tty
));
894 /* Turn appearance modes off. */
895 turn_off_face (f
, face_id
);
896 turn_off_highlight (tty
);
899 /* We may have to output some codes to terminate the writing. */
900 if (CODING_REQUIRE_FLUSHING (&terminal_coding
))
902 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
903 encode_coding (&terminal_coding
, "", conversion_buffer
,
904 0, conversion_buffer_size
);
905 if (terminal_coding
.produced
> 0)
907 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
909 if (ferror (TTY_OUTPUT (tty
)))
910 clearerr (TTY_OUTPUT (tty
));
911 if (TTY_TERMSCRIPT (tty
))
912 fwrite (conversion_buffer
, 1, terminal_coding
.produced
,
913 TTY_TERMSCRIPT (tty
));
920 /* If start is zero, insert blanks instead of a string at start */
923 insert_glyphs (start
, len
)
924 register struct glyph
*start
;
928 struct glyph
*glyph
= NULL
;
930 struct tty_display_info
*tty
;
935 f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
937 if (insert_glyphs_hook
&& ! FRAME_TERMCAP_P (f
))
939 (*insert_glyphs_hook
) (start
, len
);
945 if (tty
->TS_ins_multi_chars
)
947 buf
= tparam (tty
->TS_ins_multi_chars
, 0, 0, len
);
951 write_glyphs (start
, len
);
955 turn_on_insert (tty
);
957 /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
958 terminal_coding
.mode
&= ~CODING_MODE_LAST_BLOCK
;
961 int produced
, consumed
;
962 unsigned char conversion_buffer
[1024];
963 int conversion_buffer_size
= sizeof conversion_buffer
;
965 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
968 conversion_buffer
[0] = SPACEGLYPH
;
973 highlight_if_desired (tty
);
974 turn_on_face (f
, start
->face_id
);
977 /* We must open sufficient space for a character which
978 occupies more than one column. */
979 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
981 OUTPUT1_IF (tty
, tty
->TS_ins_char
);
986 /* This is the last glyph. */
987 terminal_coding
.mode
|= CODING_MODE_LAST_BLOCK
;
989 /* The size of conversion buffer (1024 bytes) is surely
990 sufficient for just one glyph. */
991 produced
= encode_terminal_code (glyph
, conversion_buffer
, 1,
992 conversion_buffer_size
, &consumed
);
997 fwrite (conversion_buffer
, 1, produced
,
999 if (ferror (TTY_OUTPUT (tty
)))
1000 clearerr (TTY_OUTPUT (tty
));
1001 if (TTY_TERMSCRIPT (tty
))
1002 fwrite (conversion_buffer
, 1, produced
,
1003 TTY_TERMSCRIPT (tty
));
1006 OUTPUT1_IF (tty
, tty
->TS_pad_inserted_char
);
1009 turn_off_face (f
, glyph
->face_id
);
1010 turn_off_highlight (tty
);
1023 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
1024 struct tty_display_info
*tty
= FRAME_TTY (f
);
1026 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (f
))
1028 (*delete_glyphs_hook
) (n
);
1033 if (tty
->delete_in_insert_mode
)
1035 turn_on_insert (tty
);
1039 turn_off_insert (tty
);
1040 OUTPUT_IF (tty
, tty
->TS_delete_mode
);
1043 if (tty
->TS_del_multi_chars
)
1045 buf
= tparam (tty
->TS_del_multi_chars
, 0, 0, n
);
1050 for (i
= 0; i
< n
; i
++)
1051 OUTPUT1 (tty
, tty
->TS_del_char
);
1052 if (!tty
->delete_in_insert_mode
)
1053 OUTPUT_IF (tty
, tty
->TS_end_delete_mode
);
1056 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1059 ins_del_lines (vpos
, n
)
1062 struct frame
*f
= (updating_frame
? updating_frame
: XFRAME (selected_frame
));
1063 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (f
))
1065 (*ins_del_lines_hook
) (vpos
, n
);
1070 struct tty_display_info
*tty
= FRAME_TTY (f
);
1071 char *multi
= n
> 0 ? tty
->TS_ins_multi_lines
: tty
->TS_del_multi_lines
;
1072 char *single
= n
> 0 ? tty
->TS_ins_line
: tty
->TS_del_line
;
1073 char *scroll
= n
> 0 ? tty
->TS_rev_scroll
: tty
->TS_fwd_scroll
;
1075 register int i
= n
> 0 ? n
: -n
;
1078 /* If the lines below the insertion are being pushed
1079 into the end of the window, this is the same as clearing;
1080 and we know the lines are already clear, since the matching
1081 deletion has already been done. So can ignore this. */
1082 /* If the lines below the deletion are blank lines coming
1083 out of the end of the window, don't bother,
1084 as there will be a matching inslines later that will flush them. */
1085 if (FRAME_SCROLL_REGION_OK (f
)
1086 && vpos
+ i
>= tty
->specified_window
)
1088 if (!FRAME_MEMORY_BELOW_FRAME (f
)
1089 && vpos
+ i
>= FRAME_LINES (f
))
1094 raw_cursor_to (vpos
, 0);
1095 background_highlight (tty
);
1096 buf
= tparam (multi
, 0, 0, i
);
1102 raw_cursor_to (vpos
, 0);
1103 background_highlight (tty
);
1105 OUTPUT (tty
, single
);
1106 if (tty
->TF_teleray
)
1111 set_scroll_region (vpos
, tty
->specified_window
);
1113 raw_cursor_to (tty
->specified_window
- 1, 0);
1115 raw_cursor_to (vpos
, 0);
1116 background_highlight (tty
);
1118 OUTPUTL (tty
, scroll
, tty
->specified_window
- vpos
);
1119 set_scroll_region (0, tty
->specified_window
);
1122 if (!FRAME_SCROLL_REGION_OK (f
)
1123 && FRAME_MEMORY_BELOW_FRAME (f
)
1126 cursor_to (FRAME_LINES (f
) + n
, 0);
1132 /* Compute cost of sending "str", in characters,
1133 not counting any line-dependent padding. */
1141 tputs (str
, 0, evalcost
);
1145 /* Compute cost of sending "str", in characters,
1146 counting any line-dependent padding at one line. */
1149 string_cost_one_line (str
)
1154 tputs (str
, 1, evalcost
);
1158 /* Compute per line amount of line-dependent padding,
1159 in tenths of characters. */
1167 tputs (str
, 0, evalcost
);
1170 tputs (str
, 10, evalcost
);
1175 /* char_ins_del_cost[n] is cost of inserting N characters.
1176 char_ins_del_cost[-n] is cost of deleting N characters.
1177 The length of this vector is based on max_frame_cols. */
1179 int *char_ins_del_vector
;
1181 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1186 calculate_ins_del_char_costs (f
)
1189 struct tty_display_info
*tty
= FRAME_TTY (f
);
1190 int ins_startup_cost
, del_startup_cost
;
1191 int ins_cost_per_char
, del_cost_per_char
;
1195 if (tty
->TS_ins_multi_chars
)
1197 ins_cost_per_char
= 0;
1198 ins_startup_cost
= string_cost_one_line (tty
->TS_ins_multi_chars
);
1200 else if (tty
->TS_ins_char
|| tty
->TS_pad_inserted_char
1201 || (tty
->TS_insert_mode
&& tty
->TS_end_insert_mode
))
1203 ins_startup_cost
= (30 * (string_cost (tty
->TS_insert_mode
)
1204 + string_cost (tty
->TS_end_insert_mode
))) / 100;
1205 ins_cost_per_char
= (string_cost_one_line (tty
->TS_ins_char
)
1206 + string_cost_one_line (tty
->TS_pad_inserted_char
));
1210 ins_startup_cost
= 9999;
1211 ins_cost_per_char
= 0;
1214 if (tty
->TS_del_multi_chars
)
1216 del_cost_per_char
= 0;
1217 del_startup_cost
= string_cost_one_line (tty
->TS_del_multi_chars
);
1219 else if (tty
->TS_del_char
)
1221 del_startup_cost
= (string_cost (tty
->TS_delete_mode
)
1222 + string_cost (tty
->TS_end_delete_mode
));
1223 if (tty
->delete_in_insert_mode
)
1224 del_startup_cost
/= 2;
1225 del_cost_per_char
= string_cost_one_line (tty
->TS_del_char
);
1229 del_startup_cost
= 9999;
1230 del_cost_per_char
= 0;
1233 /* Delete costs are at negative offsets */
1234 p
= &char_ins_del_cost (f
)[0];
1235 for (i
= FRAME_COLS (f
); --i
>= 0;)
1236 *--p
= (del_startup_cost
+= del_cost_per_char
);
1238 /* Doing nothing is free */
1239 p
= &char_ins_del_cost (f
)[0];
1242 /* Insert costs are at positive offsets */
1243 for (i
= FRAME_COLS (f
); --i
>= 0;)
1244 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1248 calculate_costs (frame
)
1251 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1253 if (FRAME_TERMCAP_P (frame
))
1255 struct tty_display_info
*tty
= FRAME_TTY (frame
);
1256 register char *f
= (tty
->TS_set_scroll_region
1257 ? tty
->TS_set_scroll_region
1258 : tty
->TS_set_scroll_region_1
);
1260 FRAME_SCROLL_REGION_COST (frame
) = string_cost (f
);
1264 /* These variables are only used for terminal stuff. They are
1265 allocated once for the terminal frame of X-windows emacs, but not
1268 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1269 X turns off char_ins_del_ok. */
1271 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1272 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1274 if (char_ins_del_vector
!= 0)
1276 = (int *) xrealloc (char_ins_del_vector
,
1278 + 2 * max_frame_cols
* sizeof (int)));
1281 = (int *) xmalloc (sizeof (int)
1282 + 2 * max_frame_cols
* sizeof (int));
1284 bzero (char_ins_del_vector
, (sizeof (int)
1285 + 2 * max_frame_cols
* sizeof (int)));
1288 if (f
&& (!tty
->TS_ins_line
&& !tty
->TS_del_line
))
1289 do_line_insertion_deletion_costs (frame
,
1290 tty
->TS_rev_scroll
, tty
->TS_ins_multi_lines
,
1291 tty
->TS_fwd_scroll
, tty
->TS_del_multi_lines
,
1294 do_line_insertion_deletion_costs (frame
,
1295 tty
->TS_ins_line
, tty
->TS_ins_multi_lines
,
1296 tty
->TS_del_line
, tty
->TS_del_multi_lines
,
1299 calculate_ins_del_char_costs (frame
);
1301 /* Don't use TS_repeat if its padding is worse than sending the chars */
1302 if (tty
->TS_repeat
&& per_line_cost (tty
->TS_repeat
) * baud_rate
< 9000)
1303 tty
->RPov
= string_cost (tty
->TS_repeat
);
1305 tty
->RPov
= FRAME_COLS (frame
) * 2;
1307 cmcostinit (FRAME_TTY (frame
)); /* set up cursor motion costs */
1315 /* Termcap capability names that correspond directly to X keysyms.
1316 Some of these (marked "terminfo") aren't supplied by old-style
1317 (Berkeley) termcap entries. They're listed in X keysym order;
1318 except we put the keypad keys first, so that if they clash with
1319 other keys (as on the IBM PC keyboard) they get overridden.
1322 static struct fkey_table keys
[] =
1324 {"kh", "home"}, /* termcap */
1325 {"kl", "left"}, /* termcap */
1326 {"ku", "up"}, /* termcap */
1327 {"kr", "right"}, /* termcap */
1328 {"kd", "down"}, /* termcap */
1329 {"%8", "prior"}, /* terminfo */
1330 {"%5", "next"}, /* terminfo */
1331 {"@7", "end"}, /* terminfo */
1332 {"@1", "begin"}, /* terminfo */
1333 {"*6", "select"}, /* terminfo */
1334 {"%9", "print"}, /* terminfo */
1335 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1337 * "insert" --- see below
1339 {"&8", "undo"}, /* terminfo */
1340 {"%0", "redo"}, /* terminfo */
1341 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1342 {"@0", "find"}, /* terminfo */
1343 {"@2", "cancel"}, /* terminfo */
1344 {"%1", "help"}, /* terminfo */
1346 * "break" goes here, but can't be reliably intercepted with termcap
1348 {"&4", "reset"}, /* terminfo --- actually `restart' */
1350 * "system" and "user" --- no termcaps
1352 {"kE", "clearline"}, /* terminfo */
1353 {"kA", "insertline"}, /* terminfo */
1354 {"kL", "deleteline"}, /* terminfo */
1355 {"kI", "insertchar"}, /* terminfo */
1356 {"kD", "deletechar"}, /* terminfo */
1357 {"kB", "backtab"}, /* terminfo */
1359 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1361 {"@8", "kp-enter"}, /* terminfo */
1363 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1364 * "kp-multiply", "kp-add", "kp-separator",
1365 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1366 * --- no termcaps for any of these.
1368 {"K4", "kp-1"}, /* terminfo */
1370 * "kp-2" --- no termcap
1372 {"K5", "kp-3"}, /* terminfo */
1374 * "kp-4" --- no termcap
1376 {"K2", "kp-5"}, /* terminfo */
1378 * "kp-6" --- no termcap
1380 {"K1", "kp-7"}, /* terminfo */
1382 * "kp-8" --- no termcap
1384 {"K3", "kp-9"}, /* terminfo */
1386 * "kp-equal" --- no termcap
1399 static char **term_get_fkeys_arg
;
1400 static Lisp_Object
term_get_fkeys_1 ();
1402 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1403 This function scans the termcap function key sequence entries, and
1404 adds entries to Vfunction_key_map for each function key it finds. */
1407 term_get_fkeys (address
)
1410 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1411 errors during the call. The only errors should be from Fdefine_key
1412 when given a key sequence containing an invalid prefix key. If the
1413 termcap defines function keys which use a prefix that is already bound
1414 to a command by the default bindings, we should silently ignore that
1415 function key specification, rather than giving the user an error and
1416 refusing to run at all on such a terminal. */
1418 extern Lisp_Object
Fidentity ();
1419 term_get_fkeys_arg
= address
;
1420 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1428 char **address
= term_get_fkeys_arg
;
1430 /* This can happen if CANNOT_DUMP or with strange options. */
1432 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1434 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1436 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1438 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1439 Fmake_vector (make_number (1),
1440 intern (keys
[i
].name
)));
1443 /* The uses of the "k0" capability are inconsistent; sometimes it
1444 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1445 We will attempt to politely accommodate both systems by testing for
1446 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1449 char *k_semi
= tgetstr ("k;", address
);
1450 char *k0
= tgetstr ("k0", address
);
1451 char *k0_name
= "f10";
1456 /* Define f0 first, so that f10 takes precedence in case the
1457 key sequences happens to be the same. */
1458 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1459 Fmake_vector (make_number (1), intern ("f0")));
1460 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1461 Fmake_vector (make_number (1), intern ("f10")));
1464 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1465 Fmake_vector (make_number (1), intern (k0_name
)));
1468 /* Set up cookies for numbered function keys above f10. */
1470 char fcap
[3], fkey
[4];
1472 fcap
[0] = 'F'; fcap
[2] = '\0';
1473 for (i
= 11; i
< 64; i
++)
1476 fcap
[1] = '1' + i
- 11;
1478 fcap
[1] = 'A' + i
- 20;
1480 fcap
[1] = 'a' + i
- 46;
1483 char *sequence
= tgetstr (fcap
, address
);
1486 sprintf (fkey
, "f%d", i
);
1487 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1488 Fmake_vector (make_number (1),
1496 * Various mappings to try and get a better fit.
1499 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1500 if (!tgetstr (cap1, address)) \
1502 char *sequence = tgetstr (cap2, address); \
1504 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1505 Fmake_vector (make_number (1), \
1509 /* if there's no key_next keycap, map key_npage to `next' keysym */
1510 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1511 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1512 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1513 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1514 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1515 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1516 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1518 /* IBM has their own non-standard dialect of terminfo.
1519 If the standard name isn't found, try the IBM name. */
1520 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1521 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1522 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1523 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1524 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1525 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1526 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1527 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1528 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1529 #undef CONDITIONAL_REASSIGN
1536 /***********************************************************************
1537 Character Display Information
1538 ***********************************************************************/
1540 static void append_glyph
P_ ((struct it
*));
1543 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1544 terminal frames if IT->glyph_row != NULL. IT->c is the character
1545 for which to produce glyphs; IT->face_id contains the character's
1546 face. Padding glyphs are appended if IT->c has a IT->pixel_width >
1553 struct glyph
*glyph
, *end
;
1556 xassert (it
->glyph_row
);
1557 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1558 + it
->glyph_row
->used
[it
->area
]);
1559 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1562 i
< it
->pixel_width
&& glyph
< end
;
1565 glyph
->type
= CHAR_GLYPH
;
1566 glyph
->pixel_width
= 1;
1567 glyph
->u
.ch
= it
->c
;
1568 glyph
->face_id
= it
->face_id
;
1569 glyph
->padding_p
= i
> 0;
1570 glyph
->charpos
= CHARPOS (it
->position
);
1571 glyph
->object
= it
->object
;
1573 ++it
->glyph_row
->used
[it
->area
];
1579 /* Produce glyphs for the display element described by IT. *IT
1580 specifies what we want to produce a glyph for (character, image, ...),
1581 and where in the glyph matrix we currently are (glyph row and hpos).
1582 produce_glyphs fills in output fields of *IT with information such as the
1583 pixel width and height of a character, and maybe output actual glyphs at
1584 the same time if IT->glyph_row is non-null. See the explanation of
1585 struct display_iterator in dispextern.h for an overview.
1587 produce_glyphs also stores the result of glyph width, ascent
1588 etc. computations in *IT.
1590 IT->glyph_row may be null, in which case produce_glyphs does not
1591 actually fill in the glyphs. This is used in the move_* functions
1592 in xdisp.c for text width and height computations.
1594 Callers usually don't call produce_glyphs directly;
1595 instead they use the macro PRODUCE_GLYPHS. */
1601 /* If a hook is installed, let it do the work. */
1602 xassert (it
->what
== IT_CHARACTER
1603 || it
->what
== IT_COMPOSITION
1604 || it
->what
== IT_IMAGE
1605 || it
->what
== IT_STRETCH
);
1607 /* Nothing but characters are supported on terminal frames. For a
1608 composition sequence, it->c is the first character of the
1610 xassert (it
->what
== IT_CHARACTER
1611 || it
->what
== IT_COMPOSITION
);
1613 if (it
->c
>= 040 && it
->c
< 0177)
1615 it
->pixel_width
= it
->nglyphs
= 1;
1619 else if (it
->c
== '\n')
1620 it
->pixel_width
= it
->nglyphs
= 0;
1621 else if (it
->c
== '\t')
1623 int absolute_x
= (it
->current_x
1624 + it
->continuation_lines_width
);
1626 = (((1 + absolute_x
+ it
->tab_width
- 1)
1631 /* If part of the TAB has been displayed on the previous line
1632 which is continued now, continuation_lines_width will have
1633 been incremented already by the part that fitted on the
1634 continued line. So, we will get the right number of spaces
1636 nspaces
= next_tab_x
- absolute_x
;
1643 it
->pixel_width
= it
->len
= 1;
1651 it
->pixel_width
= nspaces
;
1652 it
->nglyphs
= nspaces
;
1654 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1656 /* Coming here means that it->c is from display table, thus we
1657 must send the code as is to the terminal. Although there's
1658 no way to know how many columns it occupies on a screen, it
1659 is a good assumption that a single byte code has 1-column
1661 it
->pixel_width
= it
->nglyphs
= 1;
1667 /* A multi-byte character. The display width is fixed for all
1668 characters of the set. Some of the glyphs may have to be
1669 ignored because they are already displayed in a continued
1671 int charset
= CHAR_CHARSET (it
->c
);
1673 it
->pixel_width
= CHARSET_WIDTH (charset
);
1674 it
->nglyphs
= it
->pixel_width
;
1680 /* Advance current_x by the pixel width as a convenience for
1682 if (it
->area
== TEXT_AREA
)
1683 it
->current_x
+= it
->pixel_width
;
1684 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1685 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1689 /* Get information about special display element WHAT in an
1690 environment described by IT. WHAT is one of IT_TRUNCATION or
1691 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1692 non-null glyph_row member. This function ensures that fields like
1693 face_id, c, len of IT are left untouched. */
1696 produce_special_glyphs (it
, what
)
1698 enum display_element_type what
;
1704 temp_it
.what
= IT_CHARACTER
;
1706 temp_it
.object
= make_number (0);
1707 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1709 if (what
== IT_CONTINUATION
)
1711 /* Continuation glyph. */
1713 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1714 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1716 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it
->dp
)));
1717 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1722 produce_glyphs (&temp_it
);
1723 it
->pixel_width
= temp_it
.pixel_width
;
1724 it
->nglyphs
= temp_it
.pixel_width
;
1726 else if (what
== IT_TRUNCATION
)
1728 /* Truncation glyph. */
1730 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1731 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
1733 temp_it
.c
= FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it
->dp
)));
1734 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
1739 produce_glyphs (&temp_it
);
1740 it
->pixel_width
= temp_it
.pixel_width
;
1741 it
->nglyphs
= temp_it
.pixel_width
;
1749 /***********************************************************************
1751 ***********************************************************************/
1753 /* Value is non-zero if attribute ATTR may be used. ATTR should be
1754 one of the enumerators from enum no_color_bit, or a bit set built
1755 from them. Some display attributes may not be used together with
1756 color; the termcap capability `NC' specifies which ones. */
1758 #define MAY_USE_WITH_COLORS_P(tty, ATTR) \
1759 (tty->TN_max_colors > 0 \
1760 ? (tty->TN_no_color_video & (ATTR)) == 0 \
1763 /* Turn appearances of face FACE_ID on tty frame F on. */
1766 turn_on_face (f
, face_id
)
1770 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1771 long fg
= face
->foreground
;
1772 long bg
= face
->background
;
1773 struct tty_display_info
*tty
= FRAME_TTY (f
);
1775 /* Do this first because TS_end_standout_mode may be the same
1776 as TS_exit_attribute_mode, which turns all appearances off. */
1777 if (MAY_USE_WITH_COLORS_P (tty
, NC_REVERSE
))
1779 if (tty
->TN_max_colors
> 0)
1781 if (fg
>= 0 && bg
>= 0)
1783 /* If the terminal supports colors, we can set them
1784 below without using reverse video. The face's fg
1785 and bg colors are set as they should appear on
1786 the screen, i.e. they take the inverse-video'ness
1787 of the face already into account. */
1789 else if (inverse_video
)
1791 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1792 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1793 toggle_highlight (tty
);
1797 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1798 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1799 toggle_highlight (tty
);
1804 /* If we can't display colors, use reverse video
1805 if the face specifies that. */
1808 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
1809 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
1810 toggle_highlight (tty
);
1814 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
1815 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
1816 toggle_highlight (tty
);
1821 if (face
->tty_bold_p
)
1823 if (MAY_USE_WITH_COLORS_P (tty
, NC_BOLD
))
1824 OUTPUT1_IF (tty
, tty
->TS_enter_bold_mode
);
1826 else if (face
->tty_dim_p
)
1827 if (MAY_USE_WITH_COLORS_P (tty
, NC_DIM
))
1828 OUTPUT1_IF (tty
, tty
->TS_enter_dim_mode
);
1830 /* Alternate charset and blinking not yet used. */
1831 if (face
->tty_alt_charset_p
1832 && MAY_USE_WITH_COLORS_P (tty
, NC_ALT_CHARSET
))
1833 OUTPUT1_IF (tty
, tty
->TS_enter_alt_charset_mode
);
1835 if (face
->tty_blinking_p
1836 && MAY_USE_WITH_COLORS_P (tty
, NC_BLINK
))
1837 OUTPUT1_IF (tty
, tty
->TS_enter_blink_mode
);
1839 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (tty
, NC_UNDERLINE
))
1840 OUTPUT1_IF (tty
, tty
->TS_enter_underline_mode
);
1842 if (tty
->TN_max_colors
> 0)
1846 if (fg
>= 0 && tty
->TS_set_foreground
)
1848 p
= tparam (tty
->TS_set_foreground
, NULL
, 0, (int) fg
);
1853 if (bg
>= 0 && tty
->TS_set_background
)
1855 p
= tparam (tty
->TS_set_background
, NULL
, 0, (int) bg
);
1863 /* Turn off appearances of face FACE_ID on tty frame F. */
1866 turn_off_face (f
, face_id
)
1870 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1871 struct tty_display_info
*tty
= FRAME_TTY (f
);
1873 xassert (face
!= NULL
);
1875 if (tty
->TS_exit_attribute_mode
)
1877 /* Capability "me" will turn off appearance modes double-bright,
1878 half-bright, reverse-video, standout, underline. It may or
1879 may not turn off alt-char-mode. */
1880 if (face
->tty_bold_p
1882 || face
->tty_reverse_p
1883 || face
->tty_alt_charset_p
1884 || face
->tty_blinking_p
1885 || face
->tty_underline_p
)
1887 OUTPUT1_IF (tty
, tty
->TS_exit_attribute_mode
);
1888 if (strcmp (tty
->TS_exit_attribute_mode
, tty
->TS_end_standout_mode
) == 0)
1889 tty
->standout_mode
= 0;
1892 if (face
->tty_alt_charset_p
)
1893 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1897 /* If we don't have "me" we can only have those appearances
1898 that have exit sequences defined. */
1899 if (face
->tty_alt_charset_p
)
1900 OUTPUT_IF (tty
, tty
->TS_exit_alt_charset_mode
);
1902 if (face
->tty_underline_p
)
1903 OUTPUT_IF (tty
, tty
->TS_exit_underline_mode
);
1906 /* Switch back to default colors. */
1907 if (tty
->TN_max_colors
> 0
1908 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
1909 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
1910 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
1911 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
1912 OUTPUT1_IF (tty
, tty
->TS_orig_pair
);
1916 /* Return non-zero if the terminal on frame F supports all of the
1917 capabilities in CAPS simultaneously, with foreground and background
1918 colors FG and BG. */
1921 tty_capable_p (tty
, caps
, fg
, bg
)
1922 struct tty_display_info
*tty
;
1924 unsigned long fg
, bg
;
1926 #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
1927 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
1930 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_INVERSE
, tty
->TS_standout_mode
, NC_REVERSE
);
1931 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_UNDERLINE
, tty
->TS_enter_underline_mode
, NC_UNDERLINE
);
1932 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BOLD
, tty
->TS_enter_bold_mode
, NC_BOLD
);
1933 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_DIM
, tty
->TS_enter_dim_mode
, NC_DIM
);
1934 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_BLINK
, tty
->TS_enter_blink_mode
, NC_BLINK
);
1935 TTY_CAPABLE_P_TRY (tty
, TTY_CAP_ALT_CHARSET
, tty
->TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
1942 /* Return non-zero if the terminal is capable to display colors. */
1944 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
1946 doc
: /* Return non-nil if TTY can display colors on DISPLAY. */)
1948 Lisp_Object display
;
1950 struct tty_display_info
*tty
= FRAME_TTY (SELECTED_FRAME ());
1951 return tty
->TN_max_colors
> 0 ? Qt
: Qnil
;
1954 /* Return the number of supported colors. */
1955 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
1956 Stty_display_color_cells
, 0, 1, 0,
1957 doc
: /* Return the number of colors supported by TTY on DISPLAY. */)
1959 Lisp_Object display
;
1961 struct tty_display_info
*tty
= FRAME_TTY (SELECTED_FRAME ());
1962 return make_number (tty
->TN_max_colors
);
1967 /* Save or restore the default color-related capabilities of this
1970 tty_default_color_capabilities (struct tty_display_info
*tty
, int save
)
1973 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
1974 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
1978 if (default_orig_pair
)
1979 xfree (default_orig_pair
);
1980 default_orig_pair
= tty
->TS_orig_pair
? xstrdup (tty
->TS_orig_pair
) : NULL
;
1982 if (default_set_foreground
)
1983 xfree (default_set_foreground
);
1984 default_set_foreground
= tty
->TS_set_foreground
? xstrdup (tty
->TS_set_foreground
)
1987 if (default_set_background
)
1988 xfree (default_set_background
);
1989 default_set_background
= tty
->TS_set_background
? xstrdup (tty
->TS_set_background
)
1992 default_max_colors
= tty
->TN_max_colors
;
1993 default_max_pairs
= tty
->TN_max_pairs
;
1994 default_no_color_video
= tty
->TN_no_color_video
;
1998 tty
->TS_orig_pair
= default_orig_pair
;
1999 tty
->TS_set_foreground
= default_set_foreground
;
2000 tty
->TS_set_background
= default_set_background
;
2001 tty
->TN_max_colors
= default_max_colors
;
2002 tty
->TN_max_pairs
= default_max_pairs
;
2003 tty
->TN_no_color_video
= default_no_color_video
;
2007 /* Setup one of the standard tty color schemes according to MODE.
2008 MODE's value is generally the number of colors which we want to
2009 support; zero means set up for the default capabilities, the ones
2010 we saw at term_init time; -1 means turn off color support. */
2012 tty_setup_colors (struct tty_display_info
*tty
, int mode
)
2014 /* Canonicalize all negative values of MODE. */
2020 case -1: /* no colors at all */
2021 tty
->TN_max_colors
= 0;
2022 tty
->TN_max_pairs
= 0;
2023 tty
->TN_no_color_video
= 0;
2024 tty
->TS_set_foreground
= tty
->TS_set_background
= tty
->TS_orig_pair
= NULL
;
2026 case 0: /* default colors, if any */
2028 tty_default_color_capabilities (tty
, 0);
2030 case 8: /* 8 standard ANSI colors */
2031 tty
->TS_orig_pair
= "\033[0m";
2033 tty
->TS_set_foreground
= "\033[3%p1%dm";
2034 tty
->TS_set_background
= "\033[4%p1%dm";
2036 tty
->TS_set_foreground
= "\033[3%dm";
2037 tty
->TS_set_background
= "\033[4%dm";
2039 tty
->TN_max_colors
= 8;
2040 tty
->TN_max_pairs
= 64;
2041 tty
->TN_no_color_video
= 0;
2047 set_tty_color_mode (f
, val
)
2051 Lisp_Object color_mode_spec
, current_mode_spec
;
2052 Lisp_Object color_mode
, current_mode
;
2054 extern Lisp_Object Qtty_color_mode
;
2055 Lisp_Object tty_color_mode_alist
;
2057 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2064 if (NILP (tty_color_mode_alist
))
2065 color_mode_spec
= Qnil
;
2067 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2069 if (CONSP (color_mode_spec
))
2070 color_mode
= XCDR (color_mode_spec
);
2075 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2077 if (CONSP (current_mode_spec
))
2078 current_mode
= XCDR (current_mode_spec
);
2080 current_mode
= Qnil
;
2081 if (INTEGERP (color_mode
))
2082 mode
= XINT (color_mode
);
2084 mode
= 0; /* meaning default */
2085 if (INTEGERP (current_mode
))
2086 old_mode
= XINT (current_mode
);
2090 if (mode
!= old_mode
)
2092 tty_setup_colors (FRAME_TTY (f
), mode
);
2093 /* This recomputes all the faces given the new color
2095 call0 (intern ("tty-set-up-initial-frame-faces"));
2100 #endif /* !WINDOWSNT */
2104 struct tty_display_info
*
2105 get_named_tty (name
)
2108 struct tty_display_info
*tty
= tty_list
;
2111 if ((tty
->name
== 0 && name
== 0)
2112 || (name
&& tty
->name
&& !strcmp (tty
->name
, name
)))
2122 DEFUN ("frame-tty-name", Fframe_tty_name
, Sframe_tty_name
, 0, 1, 0,
2123 doc
: /* Return the name of the TTY device that FRAME is displayed on. */)
2131 f
= XFRAME (selected_frame
);
2135 CHECK_LIVE_FRAME (frame
);
2139 if (f
->output_method
!= output_termcap
)
2140 wrong_type_argument (Qframe_tty_name
, frame
);
2142 if (FRAME_TTY (f
)->name
)
2143 return build_string (FRAME_TTY (f
)->name
);
2148 DEFUN ("frame-tty-type", Fframe_tty_type
, Sframe_tty_type
, 0, 1, 0,
2149 doc
: /* Return the type of the TTY device that FRAME is displayed on. */)
2157 f
= XFRAME (selected_frame
);
2161 CHECK_LIVE_FRAME (frame
);
2165 if (f
->output_method
!= output_termcap
)
2166 wrong_type_argument (Qframe_tty_type
, frame
);
2168 if (FRAME_TTY (f
)->type
)
2169 return build_string (FRAME_TTY (f
)->type
);
2175 /***********************************************************************
2177 ***********************************************************************/
2179 struct tty_display_info
*
2180 term_dummy_init (void)
2182 if (initialized
|| tty_list
)
2183 error ("tty already initialized");
2185 tty_list
= xmalloc (sizeof (struct tty_display_info
));
2186 bzero (tty_list
, sizeof (struct tty_display_info
));
2188 tty_list
->input
= stdin
;
2189 tty_list
->output
= stdout
;
2190 tty_list
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
2191 tty_list
->display_method
= (struct display_method
*) xmalloc (sizeof (struct display_method
));
2196 struct tty_display_info
*
2197 term_init (Lisp_Object frame
, char *name
, char *terminal_type
)
2200 char **address
= &area
;
2201 char *buffer
= NULL
;
2202 int buffer_size
= 4096;
2205 struct frame
*f
= XFRAME (frame
);
2206 struct tty_display_info
*tty
;
2208 tty
= get_named_tty (name
);
2211 /* Return the previously initialized terminal, except if it is
2212 the dummy terminal created for the initial frame. */
2218 tty
= (struct tty_display_info
*) xmalloc (sizeof (struct tty_display_info
));
2219 bzero (tty
, sizeof (struct tty_display_info
));
2220 tty
->next
= tty_list
;
2225 tty
->Wcm
= (struct cm
*) xmalloc (sizeof (struct cm
));
2227 if (! tty
->display_method
)
2228 tty
->display_method
= (struct display_method
*) xmalloc (sizeof (struct display_method
));
2230 /* Initialize the common members in the new display method with our
2231 predefined template. */
2232 *tty
->display_method
= tty_display_method_template
;
2233 f
->display_method
= tty
->display_method
;
2235 /* Termcap-based displays don't support window-based redisplay. */
2236 f
->display_method
->rif
= 0;
2238 /* Make sure the frame is live; if an error happens, it must be
2240 f
->output_method
= output_termcap
;
2241 if (! f
->output_data
.tty
)
2243 f
->output_data
.tty
->display_info
= tty
;
2248 fd
= emacs_open (name
, O_RDWR
, 0);
2252 error ("Could not open file: %s", name
);
2254 file
= fdopen (fd
, "w+");
2255 tty
->name
= xstrdup (name
);
2263 tty
->output
= stdout
;
2266 tty
->type
= xstrdup (terminal_type
);
2268 add_keyboard_wait_descriptor (fileno (tty
->input
));
2271 initialize_w32_display ();
2275 area
= (char *) xmalloc (2044);
2277 FrameRows (tty
) = FRAME_LINES (f
);
2278 FrameCols (tty
) = FRAME_COLS (f
);
2279 tty
->specified_window
= FRAME_LINES (f
);
2281 f
->display_method
->delete_in_insert_mode
= 1;
2284 FRAME_SCROLL_REGION_OK (f
) = 0;
2286 /* Seems to insert lines when it's not supposed to, messing
2287 up the display. In doing a trace, it didn't seem to be
2288 called much, so I don't think we're losing anything by
2290 FRAME_LINE_INS_DEL_OK (f
) = 0;
2291 FRAME_CHAR_INS_DEL_OK (f
) = 1;
2295 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
2296 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
2297 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
2300 #else /* not WINDOWSNT */
2304 buffer
= (char *) xmalloc (buffer_size
);
2305 status
= tgetent (buffer
, terminal_type
);
2313 error ("Cannot open terminfo database file");
2316 fatal ("Cannot open terminfo database file");
2322 error ("Cannot open termcap database file");
2325 fatal ("Cannot open termcap database file");
2335 error ("Terminal type %s is not defined", terminal_type
);
2338 fatal ("Terminal type %s is not defined.\n\
2339 If that is not the actual type of terminal you have,\n\
2340 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2341 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2342 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2349 error ("Terminal type %s is not defined", terminal_type
);
2352 fatal ("Terminal type %s is not defined.\n\
2353 If that is not the actual type of terminal you have,\n\
2354 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2355 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2356 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2362 if (strlen (buffer
) >= buffer_size
)
2364 buffer_size
= strlen (buffer
);
2366 area
= (char *) xmalloc (buffer_size
);
2368 tty
->TS_ins_line
= tgetstr ("al", address
);
2369 tty
->TS_ins_multi_lines
= tgetstr ("AL", address
);
2370 tty
->TS_bell
= tgetstr ("bl", address
);
2371 BackTab (tty
) = tgetstr ("bt", address
);
2372 tty
->TS_clr_to_bottom
= tgetstr ("cd", address
);
2373 tty
->TS_clr_line
= tgetstr ("ce", address
);
2374 tty
->TS_clr_frame
= tgetstr ("cl", address
);
2375 ColPosition (tty
) = NULL
; /* tgetstr ("ch", address); */
2376 AbsPosition (tty
) = tgetstr ("cm", address
);
2377 CR (tty
) = tgetstr ("cr", address
);
2378 tty
->TS_set_scroll_region
= tgetstr ("cs", address
);
2379 tty
->TS_set_scroll_region_1
= tgetstr ("cS", address
);
2380 RowPosition (tty
) = tgetstr ("cv", address
);
2381 tty
->TS_del_char
= tgetstr ("dc", address
);
2382 tty
->TS_del_multi_chars
= tgetstr ("DC", address
);
2383 tty
->TS_del_line
= tgetstr ("dl", address
);
2384 tty
->TS_del_multi_lines
= tgetstr ("DL", address
);
2385 tty
->TS_delete_mode
= tgetstr ("dm", address
);
2386 tty
->TS_end_delete_mode
= tgetstr ("ed", address
);
2387 tty
->TS_end_insert_mode
= tgetstr ("ei", address
);
2388 Home (tty
) = tgetstr ("ho", address
);
2389 tty
->TS_ins_char
= tgetstr ("ic", address
);
2390 tty
->TS_ins_multi_chars
= tgetstr ("IC", address
);
2391 tty
->TS_insert_mode
= tgetstr ("im", address
);
2392 tty
->TS_pad_inserted_char
= tgetstr ("ip", address
);
2393 tty
->TS_end_keypad_mode
= tgetstr ("ke", address
);
2394 tty
->TS_keypad_mode
= tgetstr ("ks", address
);
2395 LastLine (tty
) = tgetstr ("ll", address
);
2396 Right (tty
) = tgetstr ("nd", address
);
2397 Down (tty
) = tgetstr ("do", address
);
2399 Down (tty
) = tgetstr ("nl", address
); /* Obsolete name for "do" */
2401 /* VMS puts a carriage return before each linefeed,
2402 so it is not safe to use linefeeds. */
2403 if (Down (tty
) && Down (tty
)[0] == '\n' && Down (tty
)[1] == '\0')
2406 if (tgetflag ("bs"))
2407 Left (tty
) = "\b"; /* can't possibly be longer! */
2408 else /* (Actually, "bs" is obsolete...) */
2409 Left (tty
) = tgetstr ("le", address
);
2411 Left (tty
) = tgetstr ("bc", address
); /* Obsolete name for "le" */
2412 tty
->TS_pad_char
= tgetstr ("pc", address
);
2413 tty
->TS_repeat
= tgetstr ("rp", address
);
2414 tty
->TS_end_standout_mode
= tgetstr ("se", address
);
2415 tty
->TS_fwd_scroll
= tgetstr ("sf", address
);
2416 tty
->TS_standout_mode
= tgetstr ("so", address
);
2417 tty
->TS_rev_scroll
= tgetstr ("sr", address
);
2418 tty
->Wcm
->cm_tab
= tgetstr ("ta", address
);
2419 tty
->TS_end_termcap_modes
= tgetstr ("te", address
);
2420 tty
->TS_termcap_modes
= tgetstr ("ti", address
);
2421 Up (tty
) = tgetstr ("up", address
);
2422 tty
->TS_visible_bell
= tgetstr ("vb", address
);
2423 tty
->TS_cursor_normal
= tgetstr ("ve", address
);
2424 tty
->TS_cursor_visible
= tgetstr ("vs", address
);
2425 tty
->TS_cursor_invisible
= tgetstr ("vi", address
);
2426 tty
->TS_set_window
= tgetstr ("wi", address
);
2428 tty
->TS_enter_underline_mode
= tgetstr ("us", address
);
2429 tty
->TS_exit_underline_mode
= tgetstr ("ue", address
);
2430 tty
->TS_enter_bold_mode
= tgetstr ("md", address
);
2431 tty
->TS_enter_dim_mode
= tgetstr ("mh", address
);
2432 tty
->TS_enter_blink_mode
= tgetstr ("mb", address
);
2433 tty
->TS_enter_reverse_mode
= tgetstr ("mr", address
);
2434 tty
->TS_enter_alt_charset_mode
= tgetstr ("as", address
);
2435 tty
->TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
2436 tty
->TS_exit_attribute_mode
= tgetstr ("me", address
);
2438 MultiUp (tty
) = tgetstr ("UP", address
);
2439 MultiDown (tty
) = tgetstr ("DO", address
);
2440 MultiLeft (tty
) = tgetstr ("LE", address
);
2441 MultiRight (tty
) = tgetstr ("RI", address
);
2443 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
2444 color because we can't switch back to the default foreground and
2446 tty
->TS_orig_pair
= tgetstr ("op", address
);
2447 if (tty
->TS_orig_pair
)
2449 tty
->TS_set_foreground
= tgetstr ("AF", address
);
2450 tty
->TS_set_background
= tgetstr ("AB", address
);
2451 if (!tty
->TS_set_foreground
)
2454 tty
->TS_set_foreground
= tgetstr ("Sf", address
);
2455 tty
->TS_set_background
= tgetstr ("Sb", address
);
2458 tty
->TN_max_colors
= tgetnum ("Co");
2459 tty
->TN_max_pairs
= tgetnum ("pa");
2461 tty
->TN_no_color_video
= tgetnum ("NC");
2462 if (tty
->TN_no_color_video
== -1)
2463 tty
->TN_no_color_video
= 0;
2466 tty_default_color_capabilities (tty
, 1);
2468 MagicWrap (tty
) = tgetflag ("xn");
2469 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
2470 the former flag imply the latter. */
2471 AutoWrap (tty
) = MagicWrap (tty
) || tgetflag ("am");
2472 FRAME_MEMORY_BELOW_FRAME (f
) = tgetflag ("db");
2473 tty
->TF_hazeltine
= tgetflag ("hz");
2474 FRAME_MUST_WRITE_SPACES (f
) = tgetflag ("in");
2475 tty
->meta_key
= tgetflag ("km") || tgetflag ("MT");
2476 tty
->TF_insmode_motion
= tgetflag ("mi");
2477 tty
->TF_standout_motion
= tgetflag ("ms");
2478 tty
->TF_underscore
= tgetflag ("ul");
2479 tty
->TF_teleray
= tgetflag ("xt");
2481 term_get_fkeys (address
);
2483 /* Get frame size from system, or else from termcap. */
2486 get_tty_size (fileno (TTY_INPUT (tty
)), &width
, &height
);
2487 FrameCols (tty
) = width
;
2488 FrameRows (tty
) = height
;
2491 if (FrameCols (tty
) <= 0)
2492 FrameCols (tty
) = tgetnum ("co");
2493 if (FrameRows (tty
) <= 0)
2494 FrameRows (tty
) = tgetnum ("li");
2496 if (FrameRows (tty
) < 3 || FrameCols (tty
) < 3)
2501 error ("Screen size %dx%d is too small",
2502 FrameCols (tty
), FrameRows (tty
));
2506 fatal ("Screen size %dx%d is too small",
2507 FrameCols (tty
), FrameRows (tty
));
2511 #if 0 /* This is not used anywhere. */
2512 f
->display_method
->min_padding_speed
= tgetnum ("pb");
2515 TabWidth (tty
) = tgetnum ("tw");
2518 /* These capabilities commonly use ^J.
2519 I don't know why, but sending them on VMS does not work;
2520 it causes following spaces to be lost, sometimes.
2521 For now, the simplest fix is to avoid using these capabilities ever. */
2522 if (Down (tty
) && Down (tty
)[0] == '\n')
2527 tty
->TS_bell
= "\07";
2529 if (!tty
->TS_fwd_scroll
)
2530 tty
->TS_fwd_scroll
= Down (tty
);
2532 PC
= tty
->TS_pad_char
? *tty
->TS_pad_char
: 0;
2534 if (TabWidth (tty
) < 0)
2537 /* Turned off since /etc/termcap seems to have :ta= for most terminals
2538 and newer termcap doc does not seem to say there is a default.
2539 if (!tty->Wcm->cm_tab)
2540 tty->Wcm->cm_tab = "\t";
2543 /* We don't support standout modes that use `magic cookies', so
2544 turn off any that do. */
2545 if (tty
->TS_standout_mode
&& tgetnum ("sg") >= 0)
2547 tty
->TS_standout_mode
= 0;
2548 tty
->TS_end_standout_mode
= 0;
2550 if (tty
->TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
2552 tty
->TS_enter_underline_mode
= 0;
2553 tty
->TS_exit_underline_mode
= 0;
2556 /* If there's no standout mode, try to use underlining instead. */
2557 if (tty
->TS_standout_mode
== 0)
2559 tty
->TS_standout_mode
= tty
->TS_enter_underline_mode
;
2560 tty
->TS_end_standout_mode
= tty
->TS_exit_underline_mode
;
2563 /* If no `se' string, try using a `me' string instead.
2564 If that fails, we can't use standout mode at all. */
2565 if (tty
->TS_end_standout_mode
== 0)
2567 char *s
= tgetstr ("me", address
);
2569 tty
->TS_end_standout_mode
= s
;
2571 tty
->TS_standout_mode
= 0;
2574 if (tty
->TF_teleray
)
2576 tty
->Wcm
->cm_tab
= 0;
2577 /* We can't support standout mode, because it uses magic cookies. */
2578 tty
->TS_standout_mode
= 0;
2579 /* But that means we cannot rely on ^M to go to column zero! */
2581 /* LF can't be trusted either -- can alter hpos */
2582 /* if move at column 0 thru a line with TS_standout_mode */
2586 /* Special handling for certain terminal types known to need it */
2588 if (!strcmp (terminal_type
, "supdup"))
2590 FRAME_MEMORY_BELOW_FRAME (f
) = 1;
2591 tty
->Wcm
->cm_losewrap
= 1;
2593 if (!strncmp (terminal_type
, "c10", 3)
2594 || !strcmp (terminal_type
, "perq"))
2596 /* Supply a makeshift :wi string.
2597 This string is not valid in general since it works only
2598 for windows starting at the upper left corner;
2599 but that is all Emacs uses.
2601 This string works only if the frame is using
2602 the top of the video memory, because addressing is memory-relative.
2603 So first check the :ti string to see if that is true.
2605 It would be simpler if the :wi string could go in the termcap
2606 entry, but it can't because it is not fully valid.
2607 If it were in the termcap entry, it would confuse other programs. */
2608 if (!tty
->TS_set_window
)
2610 p
= tty
->TS_termcap_modes
;
2611 while (*p
&& strcmp (p
, "\033v "))
2614 tty
->TS_set_window
= "\033v%C %C %C %C ";
2616 /* Termcap entry often fails to have :in: flag */
2617 FRAME_MUST_WRITE_SPACES (f
) = 1;
2618 /* :ti string typically fails to have \E^G! in it */
2619 /* This limits scope of insert-char to one line. */
2620 strcpy (area
, tty
->TS_termcap_modes
);
2621 strcat (area
, "\033\007!");
2622 tty
->TS_termcap_modes
= area
;
2623 area
+= strlen (area
) + 1;
2624 p
= AbsPosition (tty
);
2625 /* Change all %+ parameters to %C, to handle
2626 values above 96 correctly for the C100. */
2629 if (p
[0] == '%' && p
[1] == '+')
2635 tty
->specified_window
= FrameRows (tty
);
2637 if (Wcm_init (tty
) == -1) /* can't do cursor motion */
2641 error ("Terminal type \"%s\" is not powerful enough to run Emacs",
2646 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2647 It lacks the ability to position the cursor.\n\
2648 If that is not the actual type of terminal you have, use either the\n\
2649 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
2650 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
2654 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2655 It lacks the ability to position the cursor.\n\
2656 If that is not the actual type of terminal you have,\n\
2657 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2658 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2659 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
2661 # else /* TERMCAP */
2662 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
2663 It lacks the ability to position the cursor.\n\
2664 If that is not the actual type of terminal you have,\n\
2665 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
2666 `setenv TERM ...') to specify the correct type. It may be necessary\n\
2667 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2669 # endif /* TERMINFO */
2673 if (FrameRows (tty
) <= 0 || FrameCols (tty
) <= 0)
2678 error ("The frame size has not been specified");
2681 fatal ("The frame size has not been specified");
2684 tty
->delete_in_insert_mode
2685 = tty
->TS_delete_mode
&& tty
->TS_insert_mode
2686 && !strcmp (tty
->TS_delete_mode
, tty
->TS_insert_mode
);
2688 tty
->se_is_so
= (tty
->TS_standout_mode
2689 && tty
->TS_end_standout_mode
2690 && !strcmp (tty
->TS_standout_mode
, tty
->TS_end_standout_mode
));
2692 UseTabs (tty
) = tabs_safe_p (fileno (TTY_INPUT (tty
))) && TabWidth (tty
) == 8;
2694 FRAME_SCROLL_REGION_OK (f
)
2696 && (tty
->TS_set_window
|| tty
->TS_set_scroll_region
|| tty
->TS_set_scroll_region_1
));
2698 FRAME_LINE_INS_DEL_OK (f
)
2699 = (((tty
->TS_ins_line
|| tty
->TS_ins_multi_lines
)
2700 && (tty
->TS_del_line
|| tty
->TS_del_multi_lines
))
2701 || (FRAME_SCROLL_REGION_OK (f
)
2702 && tty
->TS_fwd_scroll
&& tty
->TS_rev_scroll
));
2704 FRAME_CHAR_INS_DEL_OK (f
)
2705 = ((tty
->TS_ins_char
|| tty
->TS_insert_mode
2706 || tty
->TS_pad_inserted_char
|| tty
->TS_ins_multi_chars
)
2707 && (tty
->TS_del_char
|| tty
->TS_del_multi_chars
));
2709 FRAME_FAST_CLEAR_END_OF_LINE (f
) = tty
->TS_clr_line
!= 0;
2711 init_baud_rate (fileno (TTY_INPUT (tty
)));
2712 if (read_socket_hook
) /* Baudrate is somewhat
2713 meaningless in this case */
2716 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 0;
2717 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_none
;
2720 /* The HFT system on AIX doesn't optimize for scrolling, so it's
2721 really ugly at times. */
2722 FRAME_LINE_INS_DEL_OK (f
) = 0;
2723 FRAME_CHAR_INS_DEL_OK (f
) = 0;
2726 /* Don't do this. I think termcap may still need the buffer. */
2727 /* xfree (buffer); */
2729 /* Set the top frame to the first frame on this display. */
2730 tty
->top_frame
= frame
;
2732 /* Init system terminal modes (RAW or CBREAK, etc.). */
2733 init_sys_modes (tty
);
2735 tty_set_terminal_modes (tty
);
2738 #endif /* WINDOWSNT */
2743 fatal (str
, arg1
, arg2
)
2744 char *str
, *arg1
, *arg2
;
2746 fprintf (stderr
, "emacs: ");
2747 fprintf (stderr
, str
, arg1
, arg2
);
2748 fprintf (stderr
, "\n");
2755 DEFUN ("delete-tty", Fdelete_tty
, Sdelete_tty
, 0, 1, 0,
2756 doc
: /* Delete all frames on the terminal named TTY, and close the device. */)
2760 struct tty_display_info
*t
;
2765 if (SBYTES (tty
) > 0)
2767 name
= (char *) alloca (SBYTES (tty
) + 1);
2768 strncpy (name
, SDATA (tty
), SBYTES (tty
));
2769 name
[SBYTES (tty
)] = 0;
2772 t
= get_named_tty (name
);
2775 error ("No such tty device: %s", name
);
2780 static int deleting_tty
= 0;
2783 delete_tty (struct tty_display_info
*tty
)
2785 Lisp_Object tail
, frame
;
2788 /* We get a recursive call when we delete the last frame on this
2794 if (tty
== tty_list
)
2795 tty_list
= tty
->next
;
2798 struct tty_display_info
*p
;
2799 for (p
= tty_list
; p
&& p
->next
!= tty
; p
= p
->next
)
2803 /* This should not happen. */
2806 p
->next
= tty
->next
;
2810 FOR_EACH_FRAME (tail
, frame
)
2812 struct frame
*f
= XFRAME (frame
);
2813 if (FRAME_TERMCAP_P (f
) && FRAME_LIVE_P (f
) && FRAME_TTY (f
) == tty
)
2815 Fdelete_frame (frame
, Qt
);
2816 f
->output_data
.tty
= 0;
2820 reset_sys_modes (tty
);
2829 delete_keyboard_wait_descriptor (fileno (tty
->input
));
2830 if (tty
->input
!= stdin
)
2831 fclose (tty
->input
);
2833 if (tty
->output
&& tty
->output
!= stdout
&& tty
->output
!= tty
->input
)
2834 fclose (tty
->output
);
2835 if (tty
->termscript
)
2836 fclose (tty
->termscript
);
2839 xfree (tty
->old_tty
);
2844 if (tty
->display_method
)
2845 xfree (tty
->display_method
);
2847 bzero (tty
, sizeof (struct tty_display_info
));
2855 /* Mark the pointers in the tty_display_info objects.
2856 Called by the Fgarbage_collector. */
2860 struct tty_display_info
*tty
;
2862 for (tty
= tty_list
; tty
; tty
= tty
->next
)
2865 mark_object (tty
->top_frame
);
2874 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
2875 doc
: /* Non-nil means the system uses terminfo rather than termcap.
2876 This variable can be used by terminal emulator packages. */);
2878 system_uses_terminfo
= 1;
2880 system_uses_terminfo
= 0;
2883 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
2884 doc
: /* Non-nil means call this function to ring the bell.
2885 The function should accept no arguments. */);
2886 Vring_bell_function
= Qnil
;
2888 Qframe_tty_name
= intern ("frame-tty-name");
2889 staticpro (&Qframe_tty_name
);
2891 Qframe_tty_type
= intern ("frame-tty-type");
2892 staticpro (&Qframe_tty_type
);
2894 defsubr (&Stty_display_color_p
);
2895 defsubr (&Stty_display_color_cells
);
2896 defsubr (&Sframe_tty_name
);
2897 defsubr (&Sframe_tty_type
);
2898 defsubr (&Sdelete_tty
);
2900 /* XXX tty_display_method_template initialization will go here. */
2902 Fprovide (intern ("multi-tty"), Qnil
);
2907 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
2908 (do not change this comment) */