1 /* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 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., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
37 #include "termhooks.h"
38 #include "dispextern.h"
41 #include "blockinput.h"
42 #include "intervals.h"
44 /* For now, don't try to include termcap.h. On some systems,
45 configure finds a non-standard termcap.h that the main build
48 #if defined HAVE_TERMCAP_H && 0
51 extern void tputs
P_ ((const char *, int, int (*)(int)));
52 extern int tgetent
P_ ((char *, const char *));
53 extern int tgetflag
P_ ((char *id
));
54 extern int tgetnum
P_ ((char *id
));
65 static void turn_on_face
P_ ((struct frame
*, int face_id
));
66 static void turn_off_face
P_ ((struct frame
*, int face_id
));
67 static void tty_show_cursor
P_ ((void));
68 static void tty_hide_cursor
P_ ((void));
71 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) - curY), cmputc)
72 #define OUTPUT1(a) tputs (a, 1, cmputc)
73 #define OUTPUTL(a, lines) tputs (a, lines, cmputc)
75 #define OUTPUT_IF(a) \
78 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) \
82 #define OUTPUT1_IF(a) do { if (a) tputs (a, 1, cmputc); } while (0)
84 /* Display space properties */
86 extern Lisp_Object Qspace
, QCalign_to
, QCwidth
;
88 /* Function to use to ring the bell. */
90 Lisp_Object Vring_bell_function
;
92 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */
94 static int visible_cursor
;
96 /* Terminal characteristics that higher levels want to look at.
97 These are all extern'd in termchar.h */
99 int must_write_spaces
; /* Nonzero means spaces in the text
100 must actually be output; can't just skip
101 over some columns to leave them blank. */
102 int min_padding_speed
; /* Speed below which no padding necessary */
104 int line_ins_del_ok
; /* Terminal can insert and delete lines */
105 int char_ins_del_ok
; /* Terminal can insert and delete chars */
106 int scroll_region_ok
; /* Terminal supports setting the
108 int scroll_region_cost
; /* Cost of setting a scroll window,
109 measured in characters */
110 int memory_below_frame
; /* Terminal remembers lines
111 scrolled off bottom */
112 int fast_clear_end_of_line
; /* Terminal has a `ce' string */
114 /* Nonzero means no need to redraw the entire frame on resuming
115 a suspended Emacs. This is useful on terminals with multiple pages,
116 where one page is used for Emacs and another for all else. */
118 int no_redraw_on_reenter
;
120 /* Hook functions that you can set to snap out the functions in this file.
121 These are all extern'd in termhooks.h */
123 void (*cursor_to_hook
) P_ ((int, int));
124 void (*raw_cursor_to_hook
) P_ ((int, int));
125 void (*clear_to_end_hook
) P_ ((void));
126 void (*clear_frame_hook
) P_ ((void));
127 void (*clear_end_of_line_hook
) P_ ((int));
129 void (*ins_del_lines_hook
) P_ ((int, int));
131 void (*delete_glyphs_hook
) P_ ((int));
133 void (*ring_bell_hook
) P_ ((void));
135 void (*reset_terminal_modes_hook
) P_ ((void));
136 void (*set_terminal_modes_hook
) P_ ((void));
137 void (*update_begin_hook
) P_ ((struct frame
*));
138 void (*update_end_hook
) P_ ((struct frame
*));
139 void (*set_terminal_window_hook
) P_ ((int));
140 void (*insert_glyphs_hook
) P_ ((struct glyph
*, int));
141 void (*write_glyphs_hook
) P_ ((struct glyph
*, int));
142 void (*delete_glyphs_hook
) P_ ((int));
144 int (*read_socket_hook
) P_ ((int, int, struct input_event
*));
146 void (*frame_up_to_date_hook
) P_ ((struct frame
*));
148 void (*mouse_position_hook
) P_ ((FRAME_PTR
*f
, int insist
,
149 Lisp_Object
*bar_window
,
150 enum scroll_bar_part
*part
,
153 unsigned long *time
));
155 /* When reading from a minibuffer in a different frame, Emacs wants
156 to shift the highlight from the selected frame to the mini-buffer's
157 frame; under X, this means it lies about where the focus is.
158 This hook tells the window system code to re-decide where to put
161 void (*frame_rehighlight_hook
) P_ ((FRAME_PTR f
));
163 /* If we're displaying frames using a window system that can stack
164 frames on top of each other, this hook allows you to bring a frame
165 to the front, or bury it behind all the other windows. If this
166 hook is zero, that means the device we're displaying on doesn't
167 support overlapping frames, so there's no need to raise or lower
170 If RAISE is non-zero, F is brought to the front, before all other
171 windows. If RAISE is zero, F is sent to the back, behind all other
174 void (*frame_raise_lower_hook
) P_ ((FRAME_PTR f
, int raise
));
176 /* If the value of the frame parameter changed, whis hook is called.
177 For example, if going from fullscreen to not fullscreen this hook
178 may do something OS dependent, like extended window manager hints on X11. */
179 void (*fullscreen_hook
) P_ ((struct frame
*f
));
181 /* Set the vertical scroll bar for WINDOW to have its upper left corner
182 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
183 indicate that we are displaying PORTION characters out of a total
184 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
185 have a scroll bar, create one for it. */
187 void (*set_vertical_scroll_bar_hook
)
188 P_ ((struct window
*window
,
189 int portion
, int whole
, int position
));
192 /* The following three hooks are used when we're doing a thorough
193 redisplay of the frame. We don't explicitly know which scroll bars
194 are going to be deleted, because keeping track of when windows go
195 away is a real pain - can you say set-window-configuration?
196 Instead, we just assert at the beginning of redisplay that *all*
197 scroll bars are to be removed, and then save scroll bars from the
198 fiery pit when we actually redisplay their window. */
200 /* Arrange for all scroll bars on FRAME to be removed at the next call
201 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
202 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
204 This should be applied to each frame each time its window tree is
205 redisplayed, even if it is not displaying scroll bars at the moment;
206 if the HAS_SCROLL_BARS flag has just been turned off, only calling
207 this and the judge_scroll_bars_hook will get rid of them.
209 If non-zero, this hook should be safe to apply to any frame,
210 whether or not it can support scroll bars, and whether or not it is
211 currently displaying them. */
213 void (*condemn_scroll_bars_hook
) P_ ((FRAME_PTR frame
));
215 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
216 Note that it's okay to redeem a scroll bar that is not condemned. */
218 void (*redeem_scroll_bar_hook
) P_ ((struct window
*window
));
220 /* Remove all scroll bars on FRAME that haven't been saved since the
221 last call to `*condemn_scroll_bars_hook'.
223 This should be applied to each frame after each time its window
224 tree is redisplayed, even if it is not displaying scroll bars at the
225 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
226 calling this and condemn_scroll_bars_hook will get rid of them.
228 If non-zero, this hook should be safe to apply to any frame,
229 whether or not it can support scroll bars, and whether or not it is
230 currently displaying them. */
232 void (*judge_scroll_bars_hook
) P_ ((FRAME_PTR FRAME
));
234 /* Strings, numbers and flags taken from the termcap entry. */
236 char *TS_ins_line
; /* "al" */
237 char *TS_ins_multi_lines
; /* "AL" (one parameter, # lines to insert) */
238 char *TS_bell
; /* "bl" */
239 char *TS_clr_to_bottom
; /* "cd" */
240 char *TS_clr_line
; /* "ce", clear to end of line */
241 char *TS_clr_frame
; /* "cl" */
242 char *TS_set_scroll_region
; /* "cs" (2 params, first line and last line) */
243 char *TS_set_scroll_region_1
; /* "cS" (4 params: total lines,
244 lines above scroll region, lines below it,
245 total lines again) */
246 char *TS_del_char
; /* "dc" */
247 char *TS_del_multi_chars
; /* "DC" (one parameter, # chars to delete) */
248 char *TS_del_line
; /* "dl" */
249 char *TS_del_multi_lines
; /* "DL" (one parameter, # lines to delete) */
250 char *TS_delete_mode
; /* "dm", enter character-delete mode */
251 char *TS_end_delete_mode
; /* "ed", leave character-delete mode */
252 char *TS_end_insert_mode
; /* "ei", leave character-insert mode */
253 char *TS_ins_char
; /* "ic" */
254 char *TS_ins_multi_chars
; /* "IC" (one parameter, # chars to insert) */
255 char *TS_insert_mode
; /* "im", enter character-insert mode */
256 char *TS_pad_inserted_char
; /* "ip". Just padding, no commands. */
257 char *TS_end_keypad_mode
; /* "ke" */
258 char *TS_keypad_mode
; /* "ks" */
259 char *TS_pad_char
; /* "pc", char to use as padding */
260 char *TS_repeat
; /* "rp" (2 params, # times to repeat
261 and character to be repeated) */
262 char *TS_end_standout_mode
; /* "se" */
263 char *TS_fwd_scroll
; /* "sf" */
264 char *TS_standout_mode
; /* "so" */
265 char *TS_rev_scroll
; /* "sr" */
266 char *TS_end_termcap_modes
; /* "te" */
267 char *TS_termcap_modes
; /* "ti" */
268 char *TS_visible_bell
; /* "vb" */
269 char *TS_cursor_normal
; /* "ve" */
270 char *TS_cursor_visible
; /* "vs" */
271 char *TS_cursor_invisible
; /* "vi" */
272 char *TS_set_window
; /* "wi" (4 params, start and end of window,
273 each as vpos and hpos) */
275 /* Value of the "NC" (no_color_video) capability, or 0 if not
278 static int TN_no_color_video
;
280 /* Meaning of bits in no_color_video. Each bit set means that the
281 corresponding attribute cannot be combined with colors. */
285 NC_STANDOUT
= 1 << 0,
286 NC_UNDERLINE
= 1 << 1,
293 NC_ALT_CHARSET
= 1 << 8
296 /* "md" -- turn on bold (extra bright mode). */
298 char *TS_enter_bold_mode
;
300 /* "mh" -- turn on half-bright mode. */
302 char *TS_enter_dim_mode
;
304 /* "mb" -- enter blinking mode. */
306 char *TS_enter_blink_mode
;
308 /* "mr" -- enter reverse video mode. */
310 char *TS_enter_reverse_mode
;
312 /* "us"/"ue" -- start/end underlining. */
314 char *TS_exit_underline_mode
, *TS_enter_underline_mode
;
316 /* "as"/"ae" -- start/end alternate character set. Not really
319 char *TS_enter_alt_charset_mode
, *TS_exit_alt_charset_mode
;
321 /* "me" -- switch appearances off. */
323 char *TS_exit_attribute_mode
;
325 /* "Co" -- number of colors. */
329 /* "pa" -- max. number of color pairs on screen. Not handled yet.
330 Could be a problem if not equal to TN_max_colors * TN_max_colors. */
334 /* "op" -- SVr4 set default pair to its original value. */
338 /* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
339 1 param, the color index. */
341 char *TS_set_foreground
, *TS_set_background
;
343 int TF_hazeltine
; /* termcap hz flag. */
344 int TF_insmode_motion
; /* termcap mi flag: can move while in insert mode. */
345 int TF_standout_motion
; /* termcap mi flag: can move while in standout mode. */
346 int TF_underscore
; /* termcap ul flag: _ underlines if over-struck on
347 non-blank position. Must clear before writing _. */
348 int TF_teleray
; /* termcap xt flag: many weird consequences.
351 static int RPov
; /* # chars to start a TS_repeat */
353 static int delete_in_insert_mode
; /* delete mode == insert mode */
355 static int se_is_so
; /* 1 if same string both enters and leaves
360 /* The largest frame width in any call to calculate_costs. */
364 /* The largest frame height in any call to calculate_costs. */
368 static int costs_set
; /* Nonzero if costs have been calculated. */
370 int insert_mode
; /* Nonzero when in insert mode. */
371 int standout_mode
; /* Nonzero when in standout mode. */
373 /* Size of window specified by higher levels.
374 This is the number of lines, from the top of frame downwards,
375 which can participate in insert-line/delete-line operations.
377 Effectively it excludes the bottom frame_lines - specified_window_size
378 lines from those operations. */
380 int specified_window
;
382 /* Frame currently being redisplayed; 0 if not currently redisplaying.
383 (Direct output does not count). */
385 FRAME_PTR updating_frame
;
387 /* Provided for lisp packages. */
389 static int system_uses_terminfo
;
391 /* Flag used in tty_show/hide_cursor. */
393 static int tty_cursor_hidden
;
397 extern char *tgetstr ();
399 static void term_clear_mouse_face ();
400 static void term_mouse_highlight (struct frame
*f
, int x
, int y
);
404 /* We aren't X windows, but we aren't termcap either. This makes me
405 uncertain as to what value to use for frame.output_method. For
406 this file, we'll define FRAME_TERMCAP_P to be zero so that our
407 output hooks get called instead of the termcap functions. Probably
408 the best long-term solution is to define an output_windows_nt... */
410 #undef FRAME_TERMCAP_P
411 #define FRAME_TERMCAP_P(_f_) 0
412 #endif /* WINDOWSNT */
415 #include <sys/fcntl.h>
418 /* Nonzero means mouse is enabled on Linux console. */
421 /* These variables describe the range of text currently shown in its
422 mouse-face, together with the window they apply to. As long as
423 the mouse stays within this range, we need not redraw anything on
424 its account. Rows and columns are glyph matrix positions in
425 MOUSE_FACE_WINDOW. */
426 static int mouse_face_beg_row
, mouse_face_beg_col
;
427 static int mouse_face_end_row
, mouse_face_end_col
;
428 static int mouse_face_past_end
;
429 static Lisp_Object Qmouse_face_window
;
430 static int mouse_face_face_id
;
432 static int pos_x
, pos_y
;
433 static int last_mouse_x
, last_mouse_y
;
434 #endif /* HAVE_GPM */
439 if (!NILP (Vring_bell_function
))
441 Lisp_Object function
;
443 /* Temporarily set the global variable to nil
444 so that if we get an error, it stays nil
445 and we don't call it over and over.
447 We don't specbind it, because that would carefully
448 restore the bad value if there's an error
449 and make the loop of errors happen anyway. */
451 function
= Vring_bell_function
;
452 Vring_bell_function
= Qnil
;
456 Vring_bell_function
= function
;
458 else if (!FRAME_TERMCAP_P (XFRAME (selected_frame
)))
459 (*ring_bell_hook
) ();
461 OUTPUT (TS_visible_bell
&& visible_bell
? TS_visible_bell
: TS_bell
);
465 set_terminal_modes ()
467 if (FRAME_TERMCAP_P (XFRAME (selected_frame
)))
469 if (TS_termcap_modes
)
470 OUTPUT (TS_termcap_modes
);
473 /* Output enough newlines to scroll all the old screen contents
474 off the screen, so it won't be overwritten and lost. */
476 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
480 OUTPUT_IF (visible_cursor
? TS_cursor_visible
: TS_cursor_normal
);
481 OUTPUT_IF (TS_keypad_mode
);
485 (*set_terminal_modes_hook
) ();
489 reset_terminal_modes ()
491 if (FRAME_TERMCAP_P (XFRAME (selected_frame
)))
493 turn_off_highlight ();
495 OUTPUT_IF (TS_end_keypad_mode
);
496 OUTPUT_IF (TS_cursor_normal
);
497 OUTPUT_IF (TS_end_termcap_modes
);
498 OUTPUT_IF (TS_orig_pair
);
499 /* Output raw CR so kernel can track the cursor hpos. */
502 else if (reset_terminal_modes_hook
)
503 (*reset_terminal_modes_hook
) ();
511 if (!FRAME_TERMCAP_P (f
))
512 update_begin_hook (f
);
519 if (FRAME_TERMCAP_P (f
))
521 if (!XWINDOW (selected_window
)->cursor_off_p
)
524 background_highlight ();
529 updating_frame
= NULL
;
533 set_terminal_window (size
)
536 if (FRAME_TERMCAP_P (updating_frame
))
538 specified_window
= size
? size
: FRAME_LINES (updating_frame
);
539 if (scroll_region_ok
)
540 set_scroll_region (0, specified_window
);
543 set_terminal_window_hook (size
);
547 set_scroll_region (start
, stop
)
551 struct frame
*sf
= XFRAME (selected_frame
);
553 if (TS_set_scroll_region
)
554 buf
= tparam (TS_set_scroll_region
, 0, 0, start
, stop
- 1);
555 else if (TS_set_scroll_region_1
)
556 buf
= tparam (TS_set_scroll_region_1
, 0, 0,
557 FRAME_LINES (sf
), start
,
558 FRAME_LINES (sf
) - stop
,
561 buf
= tparam (TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (sf
));
573 OUTPUT (TS_insert_mode
);
581 OUTPUT (TS_end_insert_mode
);
585 /* Handle highlighting. */
588 turn_off_highlight ()
591 OUTPUT_IF (TS_end_standout_mode
);
599 OUTPUT_IF (TS_standout_mode
);
607 turn_off_highlight ();
609 turn_on_highlight ();
613 /* Make cursor invisible. */
618 if (tty_cursor_hidden
== 0)
620 tty_cursor_hidden
= 1;
621 OUTPUT_IF (TS_cursor_invisible
);
626 /* Ensure that cursor is visible. */
631 if (tty_cursor_hidden
)
633 tty_cursor_hidden
= 0;
634 OUTPUT_IF (TS_cursor_normal
);
636 OUTPUT_IF (TS_cursor_visible
);
641 /* Set standout mode to the state it should be in for
642 empty space inside windows. What this is,
643 depends on the user option inverse-video. */
646 background_highlight ()
649 turn_on_highlight ();
651 turn_off_highlight ();
654 /* Set standout mode to the mode specified for the text to be output. */
657 highlight_if_desired ()
660 turn_on_highlight ();
662 turn_off_highlight ();
666 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
667 frame-relative coordinates. */
670 cursor_to (vpos
, hpos
)
673 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
675 if (! FRAME_TERMCAP_P (f
) && cursor_to_hook
)
677 (*cursor_to_hook
) (vpos
, hpos
);
681 /* Detect the case where we are called from reset_sys_modes
682 and the costs have never been calculated. Do nothing. */
686 if (curY
== vpos
&& curX
== hpos
)
688 if (!TF_standout_motion
)
689 background_highlight ();
690 if (!TF_insmode_motion
)
695 /* Similar but don't take any account of the wasted characters. */
698 raw_cursor_to (row
, col
)
701 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
702 if (! FRAME_TERMCAP_P (f
))
704 (*raw_cursor_to_hook
) (row
, col
);
707 if (curY
== row
&& curX
== col
)
709 if (!TF_standout_motion
)
710 background_highlight ();
711 if (!TF_insmode_motion
)
716 /* Erase operations */
718 /* clear from cursor to end of frame */
724 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
726 (*clear_to_end_hook
) ();
729 if (TS_clr_to_bottom
)
731 background_highlight ();
732 OUTPUT (TS_clr_to_bottom
);
736 for (i
= curY
; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
739 clear_end_of_line (FRAME_COLS (XFRAME (selected_frame
)));
744 /* Clear entire frame */
749 struct frame
*sf
= XFRAME (selected_frame
);
752 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: sf
)))
754 (*clear_frame_hook
) ();
759 background_highlight ();
760 OUTPUT (TS_clr_frame
);
770 /* Clear from cursor to end of line.
771 Assume that the line is already clear starting at column first_unused_hpos.
773 Note that the cursor may be moved, on terminals lacking a `ce' string. */
776 clear_end_of_line (first_unused_hpos
)
777 int first_unused_hpos
;
781 if (clear_end_of_line_hook
782 && ! FRAME_TERMCAP_P ((updating_frame
784 : XFRAME (selected_frame
))))
786 (*clear_end_of_line_hook
) (first_unused_hpos
);
790 /* Detect the case where we are called from reset_sys_modes
791 and the costs have never been calculated. Do nothing. */
795 if (curX
>= first_unused_hpos
)
797 background_highlight ();
800 OUTPUT1 (TS_clr_line
);
803 { /* have to do it the hard way */
804 struct frame
*sf
= XFRAME (selected_frame
);
807 /* Do not write in last row last col with Auto-wrap on. */
808 if (AutoWrap
&& curY
== FRAME_LINES (sf
) - 1
809 && first_unused_hpos
== FRAME_COLS (sf
))
812 for (i
= curX
; i
< first_unused_hpos
; i
++)
815 fputc (' ', termscript
);
818 cmplus (first_unused_hpos
- curX
);
822 /* Buffer to store the source and result of code conversion for terminal. */
823 static unsigned char *encode_terminal_buf
;
824 /* Allocated size of the above buffer. */
825 static int encode_terminal_bufsize
;
827 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
828 Set CODING->produced to the byte-length of the resulting byte
829 sequence, and return a pointer to that byte sequence. */
832 encode_terminal_code (src
, src_len
, coding
)
835 struct coding_system
*coding
;
837 struct glyph
*src_end
= src
+ src_len
;
840 int nchars
, nbytes
, required
;
841 register int tlen
= GLYPH_TABLE_LENGTH
;
842 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
844 /* Allocate sufficient size of buffer to store all characters in
845 multibyte-form. But, it may be enlarged on demand if
846 Vglyph_table contains a string. */
847 required
= MAX_MULTIBYTE_LENGTH
* src_len
;
848 if (encode_terminal_bufsize
< required
)
850 if (encode_terminal_bufsize
== 0)
851 encode_terminal_buf
= xmalloc (required
);
853 encode_terminal_buf
= xrealloc (encode_terminal_buf
, required
);
854 encode_terminal_bufsize
= required
;
857 buf
= encode_terminal_buf
;
859 while (src
< src_end
)
861 /* We must skip glyphs to be padded for a wide character. */
862 if (! CHAR_GLYPH_PADDING_P (*src
))
864 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
866 if (g
< 0 || g
>= tlen
)
868 /* This glyph doesn't has an entry in Vglyph_table. */
869 if (CHAR_VALID_P (src
->u
.ch
, 0))
870 buf
+= CHAR_STRING (src
->u
.ch
, buf
);
877 /* This glyph has an entry in Vglyph_table,
878 so process any alias before testing for simpleness. */
879 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
881 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
883 int c
= FAST_GLYPH_CHAR (g
);
885 if (CHAR_VALID_P (c
, 0))
886 buf
+= CHAR_STRING (c
, buf
);
893 /* We have a string in Vglyph_table. */
897 if (! STRING_MULTIBYTE (string
))
898 string
= string_to_multibyte (string
);
899 nbytes
= buf
- encode_terminal_buf
;
900 if (encode_terminal_bufsize
< nbytes
+ SBYTES (string
))
902 encode_terminal_bufsize
= nbytes
+ SBYTES (string
);
903 encode_terminal_buf
= xrealloc (encode_terminal_buf
,
904 encode_terminal_bufsize
);
905 buf
= encode_terminal_buf
+ nbytes
;
907 bcopy (SDATA (string
), buf
, SBYTES (string
));
908 buf
+= SBYTES (string
);
909 nchars
+= SCHARS (string
);
916 nbytes
= buf
- encode_terminal_buf
;
917 coding
->src_multibyte
= 1;
918 coding
->dst_multibyte
= 0;
919 if (SYMBOLP (coding
->pre_write_conversion
)
920 && ! NILP (Ffboundp (coding
->pre_write_conversion
)))
922 run_pre_write_conversin_on_c_str (&encode_terminal_buf
,
923 &encode_terminal_bufsize
,
924 nchars
, nbytes
, coding
);
925 nchars
= coding
->produced_char
;
926 nbytes
= coding
->produced
;
928 required
= nbytes
+ encoding_buffer_size (coding
, nbytes
);
929 if (encode_terminal_bufsize
< required
)
931 encode_terminal_bufsize
= required
;
932 encode_terminal_buf
= xrealloc (encode_terminal_buf
, required
);
935 encode_coding (coding
, encode_terminal_buf
, encode_terminal_buf
+ nbytes
,
936 nbytes
, encode_terminal_bufsize
- nbytes
);
937 return encode_terminal_buf
+ nbytes
;
941 write_glyphs (string
, len
)
942 register struct glyph
*string
;
945 struct frame
*sf
= XFRAME (selected_frame
);
946 struct frame
*f
= updating_frame
? updating_frame
: sf
;
947 unsigned char *conversion_buffer
;
948 struct coding_system
*coding
;
950 if (write_glyphs_hook
951 && ! FRAME_TERMCAP_P (f
))
953 (*write_glyphs_hook
) (string
, len
);
960 /* Don't dare write in last column of bottom line, if Auto-Wrap,
961 since that would scroll the whole frame on some terminals. */
964 && curY
+ 1 == FRAME_LINES (sf
)
965 && (curX
+ len
) == FRAME_COLS (sf
))
972 /* If terminal_coding does any conversion, use it, otherwise use
973 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
974 because it always return 1 if the member src_multibyte is 1. */
975 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
976 ? &terminal_coding
: &safe_terminal_coding
);
977 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
979 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
983 /* Identify a run of glyphs with the same face. */
984 int face_id
= string
->face_id
;
987 for (n
= 1; n
< len
; ++n
)
988 if (string
[n
].face_id
!= face_id
)
991 /* Turn appearance modes of the face of the run on. */
992 highlight_if_desired ();
993 turn_on_face (f
, face_id
);
996 /* This is the last run. */
997 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
998 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
999 if (coding
->produced
> 0)
1002 fwrite (conversion_buffer
, 1, coding
->produced
, stdout
);
1003 if (ferror (stdout
))
1006 fwrite (conversion_buffer
, 1, coding
->produced
, termscript
);
1012 /* Turn appearance modes off. */
1013 turn_off_face (f
, face_id
);
1014 turn_off_highlight ();
1021 write_glyphs_with_face (string
, len
, face_id
)
1022 register struct glyph
*string
;
1023 register int len
, face_id
;
1025 struct frame
*sf
= XFRAME (selected_frame
);
1026 struct frame
*f
= updating_frame
? updating_frame
: sf
;
1027 unsigned char *conversion_buffer
;
1028 struct coding_system
*coding
;
1033 /* Don't dare write in last column of bottom line, if Auto-Wrap,
1034 since that would scroll the whole frame on some terminals. */
1037 && curY
+ 1 == FRAME_LINES (sf
)
1038 && (curX
+ len
) == FRAME_COLS (sf
))
1045 /* If terminal_coding does any conversion, use it, otherwise use
1046 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
1047 because it always return 1 if the member src_multibyte is 1. */
1048 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
1049 ? &terminal_coding
: &safe_terminal_coding
);
1050 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1052 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
1055 /* Turn appearance modes of the face. */
1056 highlight_if_desired ();
1057 turn_on_face (f
, face_id
);
1059 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
1060 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
1061 if (coding
->produced
> 0)
1064 fwrite (conversion_buffer
, 1, coding
->produced
, stdout
);
1065 if (ferror (stdout
))
1068 fwrite (conversion_buffer
, 1, coding
->produced
, termscript
);
1072 /* Turn appearance modes off. */
1073 turn_off_face (f
, face_id
);
1074 turn_off_highlight ();
1079 /* If start is zero, insert blanks instead of a string at start */
1082 insert_glyphs (start
, len
)
1083 register struct glyph
*start
;
1087 struct glyph
*glyph
= NULL
;
1088 struct frame
*f
, *sf
;
1089 unsigned char *conversion_buffer
;
1090 unsigned char space
[1];
1091 struct coding_system
*coding
;
1096 if (insert_glyphs_hook
)
1098 (*insert_glyphs_hook
) (start
, len
);
1102 sf
= XFRAME (selected_frame
);
1103 f
= updating_frame
? updating_frame
: sf
;
1105 if (TS_ins_multi_chars
)
1107 buf
= tparam (TS_ins_multi_chars
, 0, 0, len
);
1111 write_glyphs (start
, len
);
1119 space
[0] = SPACEGLYPH
;
1121 /* If terminal_coding does any conversion, use it, otherwise use
1122 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
1123 because it always return 1 if the member src_multibyte is 1. */
1124 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
1125 ? &terminal_coding
: &safe_terminal_coding
);
1126 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1128 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
1132 OUTPUT1_IF (TS_ins_char
);
1135 conversion_buffer
= space
;
1136 coding
->produced
= 1;
1140 highlight_if_desired ();
1141 turn_on_face (f
, start
->face_id
);
1144 /* We must open sufficient space for a character which
1145 occupies more than one column. */
1146 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
1148 OUTPUT1_IF (TS_ins_char
);
1153 /* This is the last glyph. */
1154 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
1156 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
1159 if (coding
->produced
> 0)
1162 fwrite (conversion_buffer
, 1, coding
->produced
, stdout
);
1163 if (ferror (stdout
))
1166 fwrite (conversion_buffer
, 1, coding
->produced
, termscript
);
1170 OUTPUT1_IF (TS_pad_inserted_char
);
1173 turn_off_face (f
, glyph
->face_id
);
1174 turn_off_highlight ();
1188 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1190 (*delete_glyphs_hook
) (n
);
1194 if (delete_in_insert_mode
)
1201 OUTPUT_IF (TS_delete_mode
);
1204 if (TS_del_multi_chars
)
1206 buf
= tparam (TS_del_multi_chars
, 0, 0, n
);
1211 for (i
= 0; i
< n
; i
++)
1212 OUTPUT1 (TS_del_char
);
1213 if (!delete_in_insert_mode
)
1214 OUTPUT_IF (TS_end_delete_mode
);
1217 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1220 ins_del_lines (vpos
, n
)
1223 char *multi
= n
> 0 ? TS_ins_multi_lines
: TS_del_multi_lines
;
1224 char *single
= n
> 0 ? TS_ins_line
: TS_del_line
;
1225 char *scroll
= n
> 0 ? TS_rev_scroll
: TS_fwd_scroll
;
1228 register int i
= n
> 0 ? n
: -n
;
1231 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1233 (*ins_del_lines_hook
) (vpos
, n
);
1237 sf
= XFRAME (selected_frame
);
1239 /* If the lines below the insertion are being pushed
1240 into the end of the window, this is the same as clearing;
1241 and we know the lines are already clear, since the matching
1242 deletion has already been done. So can ignore this. */
1243 /* If the lines below the deletion are blank lines coming
1244 out of the end of the window, don't bother,
1245 as there will be a matching inslines later that will flush them. */
1246 if (scroll_region_ok
&& vpos
+ i
>= specified_window
)
1248 if (!memory_below_frame
&& vpos
+ i
>= FRAME_LINES (sf
))
1253 raw_cursor_to (vpos
, 0);
1254 background_highlight ();
1255 buf
= tparam (multi
, 0, 0, i
);
1261 raw_cursor_to (vpos
, 0);
1262 background_highlight ();
1270 set_scroll_region (vpos
, specified_window
);
1272 raw_cursor_to (specified_window
- 1, 0);
1274 raw_cursor_to (vpos
, 0);
1275 background_highlight ();
1277 OUTPUTL (scroll
, specified_window
- vpos
);
1278 set_scroll_region (0, specified_window
);
1281 if (!scroll_region_ok
&& memory_below_frame
&& n
< 0)
1283 cursor_to (FRAME_LINES (sf
) + n
, 0);
1288 /* Compute cost of sending "str", in characters,
1289 not counting any line-dependent padding. */
1297 tputs (str
, 0, evalcost
);
1301 /* Compute cost of sending "str", in characters,
1302 counting any line-dependent padding at one line. */
1305 string_cost_one_line (str
)
1310 tputs (str
, 1, evalcost
);
1314 /* Compute per line amount of line-dependent padding,
1315 in tenths of characters. */
1323 tputs (str
, 0, evalcost
);
1326 tputs (str
, 10, evalcost
);
1331 /* char_ins_del_cost[n] is cost of inserting N characters.
1332 char_ins_del_cost[-n] is cost of deleting N characters.
1333 The length of this vector is based on max_frame_cols. */
1335 int *char_ins_del_vector
;
1337 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1342 calculate_ins_del_char_costs (frame
)
1345 int ins_startup_cost
, del_startup_cost
;
1346 int ins_cost_per_char
, del_cost_per_char
;
1350 if (TS_ins_multi_chars
)
1352 ins_cost_per_char
= 0;
1353 ins_startup_cost
= string_cost_one_line (TS_ins_multi_chars
);
1355 else if (TS_ins_char
|| TS_pad_inserted_char
1356 || (TS_insert_mode
&& TS_end_insert_mode
))
1358 ins_startup_cost
= (30 * (string_cost (TS_insert_mode
)
1359 + string_cost (TS_end_insert_mode
))) / 100;
1360 ins_cost_per_char
= (string_cost_one_line (TS_ins_char
)
1361 + string_cost_one_line (TS_pad_inserted_char
));
1365 ins_startup_cost
= 9999;
1366 ins_cost_per_char
= 0;
1369 if (TS_del_multi_chars
)
1371 del_cost_per_char
= 0;
1372 del_startup_cost
= string_cost_one_line (TS_del_multi_chars
);
1374 else if (TS_del_char
)
1376 del_startup_cost
= (string_cost (TS_delete_mode
)
1377 + string_cost (TS_end_delete_mode
));
1378 if (delete_in_insert_mode
)
1379 del_startup_cost
/= 2;
1380 del_cost_per_char
= string_cost_one_line (TS_del_char
);
1384 del_startup_cost
= 9999;
1385 del_cost_per_char
= 0;
1388 /* Delete costs are at negative offsets */
1389 p
= &char_ins_del_cost (frame
)[0];
1390 for (i
= FRAME_COLS (frame
); --i
>= 0;)
1391 *--p
= (del_startup_cost
+= del_cost_per_char
);
1393 /* Doing nothing is free */
1394 p
= &char_ins_del_cost (frame
)[0];
1397 /* Insert costs are at positive offsets */
1398 for (i
= FRAME_COLS (frame
); --i
>= 0;)
1399 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1403 calculate_costs (frame
)
1406 register char *f
= (TS_set_scroll_region
1407 ? TS_set_scroll_region
1408 : TS_set_scroll_region_1
);
1410 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1412 scroll_region_cost
= string_cost (f
);
1414 /* These variables are only used for terminal stuff. They are allocated
1415 once for the terminal frame of X-windows emacs, but not used afterwards.
1417 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1418 X turns off char_ins_del_ok. */
1420 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1421 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1425 if (char_ins_del_vector
!= 0)
1427 = (int *) xrealloc (char_ins_del_vector
,
1429 + 2 * max_frame_cols
* sizeof (int)));
1432 = (int *) xmalloc (sizeof (int)
1433 + 2 * max_frame_cols
* sizeof (int));
1435 bzero (char_ins_del_vector
, (sizeof (int)
1436 + 2 * max_frame_cols
* sizeof (int)));
1438 if (f
&& (!TS_ins_line
&& !TS_del_line
))
1439 do_line_insertion_deletion_costs (frame
,
1440 TS_rev_scroll
, TS_ins_multi_lines
,
1441 TS_fwd_scroll
, TS_del_multi_lines
,
1444 do_line_insertion_deletion_costs (frame
,
1445 TS_ins_line
, TS_ins_multi_lines
,
1446 TS_del_line
, TS_del_multi_lines
,
1449 calculate_ins_del_char_costs (frame
);
1451 /* Don't use TS_repeat if its padding is worse than sending the chars */
1452 if (TS_repeat
&& per_line_cost (TS_repeat
) * baud_rate
< 9000)
1453 RPov
= string_cost (TS_repeat
);
1455 RPov
= FRAME_COLS (frame
) * 2;
1457 cmcostinit (); /* set up cursor motion costs */
1464 /* Termcap capability names that correspond directly to X keysyms.
1465 Some of these (marked "terminfo") aren't supplied by old-style
1466 (Berkeley) termcap entries. They're listed in X keysym order;
1467 except we put the keypad keys first, so that if they clash with
1468 other keys (as on the IBM PC keyboard) they get overridden.
1471 static struct fkey_table keys
[] =
1473 {"kh", "home"}, /* termcap */
1474 {"kl", "left"}, /* termcap */
1475 {"ku", "up"}, /* termcap */
1476 {"kr", "right"}, /* termcap */
1477 {"kd", "down"}, /* termcap */
1478 {"%8", "prior"}, /* terminfo */
1479 {"%5", "next"}, /* terminfo */
1480 {"@7", "end"}, /* terminfo */
1481 {"@1", "begin"}, /* terminfo */
1482 {"*6", "select"}, /* terminfo */
1483 {"%9", "print"}, /* terminfo */
1484 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1486 * "insert" --- see below
1488 {"&8", "undo"}, /* terminfo */
1489 {"%0", "redo"}, /* terminfo */
1490 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1491 {"@0", "find"}, /* terminfo */
1492 {"@2", "cancel"}, /* terminfo */
1493 {"%1", "help"}, /* terminfo */
1495 * "break" goes here, but can't be reliably intercepted with termcap
1497 {"&4", "reset"}, /* terminfo --- actually `restart' */
1499 * "system" and "user" --- no termcaps
1501 {"kE", "clearline"}, /* terminfo */
1502 {"kA", "insertline"}, /* terminfo */
1503 {"kL", "deleteline"}, /* terminfo */
1504 {"kI", "insertchar"}, /* terminfo */
1505 {"kD", "deletechar"}, /* terminfo */
1506 {"kB", "backtab"}, /* terminfo */
1508 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1510 {"@8", "kp-enter"}, /* terminfo */
1512 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1513 * "kp-multiply", "kp-add", "kp-separator",
1514 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1515 * --- no termcaps for any of these.
1517 {"K4", "kp-1"}, /* terminfo */
1519 * "kp-2" --- no termcap
1521 {"K5", "kp-3"}, /* terminfo */
1523 * "kp-4" --- no termcap
1525 {"K2", "kp-5"}, /* terminfo */
1527 * "kp-6" --- no termcap
1529 {"K1", "kp-7"}, /* terminfo */
1531 * "kp-8" --- no termcap
1533 {"K3", "kp-9"}, /* terminfo */
1535 * "kp-equal" --- no termcap
1547 {"&0", "S-cancel"}, /*shifted cancel key*/
1548 {"&9", "S-begin"}, /*shifted begin key*/
1549 {"*0", "S-find"}, /*shifted find key*/
1550 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1551 {"*4", "S-delete"}, /*shifted delete-character key*/
1552 {"*7", "S-end"}, /*shifted end key*/
1553 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1554 {"#1", "S-help"}, /*shifted help key*/
1555 {"#2", "S-home"}, /*shifted home key*/
1556 {"#3", "S-insert"}, /*shifted insert-character key*/
1557 {"#4", "S-left"}, /*shifted left-arrow key*/
1558 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1559 {"%c", "S-next"}, /*shifted next key*/
1560 {"%e", "S-prior"}, /*shifted previous key*/
1561 {"%f", "S-print"}, /*shifted print key*/
1562 {"%g", "S-redo"}, /*shifted redo key*/
1563 {"%i", "S-right"}, /*shifted right-arrow key*/
1564 {"!3", "S-undo"} /*shifted undo key*/
1567 static char **term_get_fkeys_arg
;
1568 static Lisp_Object
term_get_fkeys_1 ();
1570 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1571 This function scans the termcap function key sequence entries, and
1572 adds entries to Vfunction_key_map for each function key it finds. */
1575 term_get_fkeys (address
)
1578 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1579 errors during the call. The only errors should be from Fdefine_key
1580 when given a key sequence containing an invalid prefix key. If the
1581 termcap defines function keys which use a prefix that is already bound
1582 to a command by the default bindings, we should silently ignore that
1583 function key specification, rather than giving the user an error and
1584 refusing to run at all on such a terminal. */
1586 extern Lisp_Object
Fidentity ();
1587 term_get_fkeys_arg
= address
;
1588 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1596 char **address
= term_get_fkeys_arg
;
1598 /* This can happen if CANNOT_DUMP or with strange options. */
1600 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1602 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1604 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1606 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1607 Fmake_vector (make_number (1),
1608 intern (keys
[i
].name
)));
1611 /* The uses of the "k0" capability are inconsistent; sometimes it
1612 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1613 We will attempt to politely accommodate both systems by testing for
1614 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1617 char *k_semi
= tgetstr ("k;", address
);
1618 char *k0
= tgetstr ("k0", address
);
1619 char *k0_name
= "f10";
1624 /* Define f0 first, so that f10 takes precedence in case the
1625 key sequences happens to be the same. */
1626 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1627 Fmake_vector (make_number (1), intern ("f0")));
1628 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1629 Fmake_vector (make_number (1), intern ("f10")));
1632 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1633 Fmake_vector (make_number (1), intern (k0_name
)));
1636 /* Set up cookies for numbered function keys above f10. */
1638 char fcap
[3], fkey
[4];
1640 fcap
[0] = 'F'; fcap
[2] = '\0';
1641 for (i
= 11; i
< 64; i
++)
1644 fcap
[1] = '1' + i
- 11;
1646 fcap
[1] = 'A' + i
- 20;
1648 fcap
[1] = 'a' + i
- 46;
1651 char *sequence
= tgetstr (fcap
, address
);
1654 sprintf (fkey
, "f%d", i
);
1655 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1656 Fmake_vector (make_number (1),
1664 * Various mappings to try and get a better fit.
1667 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1668 if (!tgetstr (cap1, address)) \
1670 char *sequence = tgetstr (cap2, address); \
1672 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1673 Fmake_vector (make_number (1), \
1677 /* if there's no key_next keycap, map key_npage to `next' keysym */
1678 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1679 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1680 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1681 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1682 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1683 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1684 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1686 /* IBM has their own non-standard dialect of terminfo.
1687 If the standard name isn't found, try the IBM name. */
1688 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1689 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1690 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1691 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1692 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1693 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1694 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1695 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1696 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1697 #undef CONDITIONAL_REASSIGN
1704 /***********************************************************************
1705 Character Display Information
1706 ***********************************************************************/
1708 /* Avoid name clash with functions defined in xterm.c */
1710 #define append_glyph append_glyph_term
1711 #define produce_stretch_glyph produce_stretch_glyph_term
1714 static void append_glyph
P_ ((struct it
*));
1715 static void produce_stretch_glyph
P_ ((struct it
*));
1718 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1719 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1720 the character for which to produce glyphs; IT->face_id contains the
1721 character's face. Padding glyphs are appended if IT->c has a
1722 IT->pixel_width > 1. */
1728 struct glyph
*glyph
, *end
;
1731 xassert (it
->glyph_row
);
1732 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1733 + it
->glyph_row
->used
[it
->area
]);
1734 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1737 i
< it
->pixel_width
&& glyph
< end
;
1740 glyph
->type
= CHAR_GLYPH
;
1741 glyph
->pixel_width
= 1;
1742 glyph
->u
.ch
= it
->char_to_display
;
1743 glyph
->face_id
= it
->face_id
;
1744 glyph
->padding_p
= i
> 0;
1745 glyph
->charpos
= CHARPOS (it
->position
);
1746 glyph
->object
= it
->object
;
1748 ++it
->glyph_row
->used
[it
->area
];
1754 /* Produce glyphs for the display element described by IT. *IT
1755 specifies what we want to produce a glyph for (character, image, ...),
1756 and where in the glyph matrix we currently are (glyph row and hpos).
1757 produce_glyphs fills in output fields of *IT with information such as the
1758 pixel width and height of a character, and maybe output actual glyphs at
1759 the same time if IT->glyph_row is non-null. See the explanation of
1760 struct display_iterator in dispextern.h for an overview.
1762 produce_glyphs also stores the result of glyph width, ascent
1763 etc. computations in *IT.
1765 IT->glyph_row may be null, in which case produce_glyphs does not
1766 actually fill in the glyphs. This is used in the move_* functions
1767 in xdisp.c for text width and height computations.
1769 Callers usually don't call produce_glyphs directly;
1770 instead they use the macro PRODUCE_GLYPHS. */
1776 /* If a hook is installed, let it do the work. */
1777 xassert (it
->what
== IT_CHARACTER
1778 || it
->what
== IT_COMPOSITION
1779 || it
->what
== IT_STRETCH
);
1781 if (it
->what
== IT_STRETCH
)
1783 produce_stretch_glyph (it
);
1787 /* Nothing but characters are supported on terminal frames. For a
1788 composition sequence, it->c is the first character of the
1790 xassert (it
->what
== IT_CHARACTER
1791 || it
->what
== IT_COMPOSITION
);
1793 /* Maybe translate single-byte characters to multibyte. */
1794 it
->char_to_display
= it
->c
;
1796 if (it
->c
>= 040 && it
->c
< 0177)
1798 it
->pixel_width
= it
->nglyphs
= 1;
1802 else if (it
->c
== '\n')
1803 it
->pixel_width
= it
->nglyphs
= 0;
1804 else if (it
->c
== '\t')
1806 int absolute_x
= (it
->current_x
1807 + it
->continuation_lines_width
);
1809 = (((1 + absolute_x
+ it
->tab_width
- 1)
1814 /* If part of the TAB has been displayed on the previous line
1815 which is continued now, continuation_lines_width will have
1816 been incremented already by the part that fitted on the
1817 continued line. So, we will get the right number of spaces
1819 nspaces
= next_tab_x
- absolute_x
;
1825 it
->char_to_display
= ' ';
1826 it
->pixel_width
= it
->len
= 1;
1832 it
->pixel_width
= nspaces
;
1833 it
->nglyphs
= nspaces
;
1835 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1837 if (unibyte_display_via_language_environment
1839 || !NILP (Vnonascii_translation_table
)))
1843 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1844 charset
= CHAR_CHARSET (it
->char_to_display
);
1845 it
->pixel_width
= CHARSET_WIDTH (charset
);
1846 it
->nglyphs
= it
->pixel_width
;
1852 /* Coming here means that it->c is from display table, thus we
1853 must send the code as is to the terminal. Although there's
1854 no way to know how many columns it occupies on a screen, it
1855 is a good assumption that a single byte code has 1-column
1857 it
->pixel_width
= it
->nglyphs
= 1;
1864 /* A multi-byte character. The display width is fixed for all
1865 characters of the set. Some of the glyphs may have to be
1866 ignored because they are already displayed in a continued
1868 int charset
= CHAR_CHARSET (it
->c
);
1870 it
->pixel_width
= CHARSET_WIDTH (charset
);
1871 it
->nglyphs
= it
->pixel_width
;
1878 /* Advance current_x by the pixel width as a convenience for
1880 if (it
->area
== TEXT_AREA
)
1881 it
->current_x
+= it
->pixel_width
;
1882 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1883 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1887 /* Produce a stretch glyph for iterator IT. IT->object is the value
1888 of the glyph property displayed. The value must be a list
1889 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1892 1. `:width WIDTH' specifies that the space should be WIDTH *
1893 canonical char width wide. WIDTH may be an integer or floating
1896 2. `:align-to HPOS' specifies that the space should be wide enough
1897 to reach HPOS, a value in canonical character units. */
1900 produce_stretch_glyph (it
)
1903 /* (space :width WIDTH ...) */
1904 Lisp_Object prop
, plist
;
1905 int width
= 0, align_to
= -1;
1906 int zero_width_ok_p
= 0;
1909 /* List should start with `space'. */
1910 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1911 plist
= XCDR (it
->object
);
1913 /* Compute the width of the stretch. */
1914 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1915 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1917 /* Absolute width `:width WIDTH' specified and valid. */
1918 zero_width_ok_p
= 1;
1919 width
= (int)(tem
+ 0.5);
1921 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1922 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1924 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1925 align_to
= (align_to
< 0
1927 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1928 else if (align_to
< 0)
1929 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1930 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1931 zero_width_ok_p
= 1;
1934 /* Nothing specified -> width defaults to canonical char width. */
1935 width
= FRAME_COLUMN_WIDTH (it
->f
);
1937 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1940 if (width
> 0 && it
->glyph_row
)
1942 Lisp_Object o_object
= it
->object
;
1943 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1946 if (!STRINGP (object
))
1947 object
= it
->w
->buffer
;
1948 it
->object
= object
;
1949 it
->char_to_display
= ' ';
1950 it
->pixel_width
= it
->len
= 1;
1953 it
->object
= o_object
;
1955 it
->pixel_width
= width
;
1956 it
->nglyphs
= width
;
1960 /* Get information about special display element WHAT in an
1961 environment described by IT. WHAT is one of IT_TRUNCATION or
1962 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1963 non-null glyph_row member. This function ensures that fields like
1964 face_id, c, len of IT are left untouched. */
1967 produce_special_glyphs (it
, what
)
1969 enum display_element_type what
;
1976 temp_it
.what
= IT_CHARACTER
;
1978 temp_it
.object
= make_number (0);
1979 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1981 if (what
== IT_CONTINUATION
)
1983 /* Continuation glyph. */
1985 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1986 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1988 glyph
= XINT (DISP_CONTINUE_GLYPH (it
->dp
));
1989 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
1994 else if (what
== IT_TRUNCATION
)
1996 /* Truncation glyph. */
1998 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
1999 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
2001 glyph
= XINT (DISP_TRUNC_GLYPH (it
->dp
));
2002 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
2010 temp_it
.c
= FAST_GLYPH_CHAR (glyph
);
2011 temp_it
.face_id
= FAST_GLYPH_FACE (glyph
);
2012 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
2014 produce_glyphs (&temp_it
);
2015 it
->pixel_width
= temp_it
.pixel_width
;
2016 it
->nglyphs
= temp_it
.pixel_width
;
2021 /***********************************************************************
2023 ***********************************************************************/
2025 /* Value is non-zero if attribute ATTR may be used. ATTR should be
2026 one of the enumerators from enum no_color_bit, or a bit set built
2027 from them. Some display attributes may not be used together with
2028 color; the termcap capability `NC' specifies which ones. */
2030 #define MAY_USE_WITH_COLORS_P(ATTR) \
2031 (TN_max_colors > 0 \
2032 ? (TN_no_color_video & (ATTR)) == 0 \
2035 /* Turn appearances of face FACE_ID on tty frame F on.
2036 FACE_ID is a realized face ID number, in the face cache. */
2039 turn_on_face (f
, face_id
)
2043 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2044 long fg
= face
->foreground
;
2045 long bg
= face
->background
;
2047 /* Do this first because TS_end_standout_mode may be the same
2048 as TS_exit_attribute_mode, which turns all appearances off. */
2049 if (MAY_USE_WITH_COLORS_P (NC_REVERSE
))
2051 if (TN_max_colors
> 0)
2053 if (fg
>= 0 && bg
>= 0)
2055 /* If the terminal supports colors, we can set them
2056 below without using reverse video. The face's fg
2057 and bg colors are set as they should appear on
2058 the screen, i.e. they take the inverse-video'ness
2059 of the face already into account. */
2061 else if (inverse_video
)
2063 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
2064 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
2065 toggle_highlight ();
2069 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
2070 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
2071 toggle_highlight ();
2076 /* If we can't display colors, use reverse video
2077 if the face specifies that. */
2080 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
2081 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
2082 toggle_highlight ();
2086 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
2087 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
2088 toggle_highlight ();
2093 if (face
->tty_bold_p
)
2095 if (MAY_USE_WITH_COLORS_P (NC_BOLD
))
2096 OUTPUT1_IF (TS_enter_bold_mode
);
2098 else if (face
->tty_dim_p
)
2099 if (MAY_USE_WITH_COLORS_P (NC_DIM
))
2100 OUTPUT1_IF (TS_enter_dim_mode
);
2102 /* Alternate charset and blinking not yet used. */
2103 if (face
->tty_alt_charset_p
2104 && MAY_USE_WITH_COLORS_P (NC_ALT_CHARSET
))
2105 OUTPUT1_IF (TS_enter_alt_charset_mode
);
2107 if (face
->tty_blinking_p
2108 && MAY_USE_WITH_COLORS_P (NC_BLINK
))
2109 OUTPUT1_IF (TS_enter_blink_mode
);
2111 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (NC_UNDERLINE
))
2112 OUTPUT1_IF (TS_enter_underline_mode
);
2114 if (TN_max_colors
> 0)
2118 ts
= standout_mode
? TS_set_background
: TS_set_foreground
;
2121 p
= tparam (ts
, NULL
, 0, (int) fg
);
2126 ts
= standout_mode
? TS_set_foreground
: TS_set_background
;
2129 p
= tparam (ts
, NULL
, 0, (int) bg
);
2137 /* Turn off appearances of face FACE_ID on tty frame F. */
2140 turn_off_face (f
, face_id
)
2144 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2146 xassert (face
!= NULL
);
2148 if (TS_exit_attribute_mode
)
2150 /* Capability "me" will turn off appearance modes double-bright,
2151 half-bright, reverse-video, standout, underline. It may or
2152 may not turn off alt-char-mode. */
2153 if (face
->tty_bold_p
2155 || face
->tty_reverse_p
2156 || face
->tty_alt_charset_p
2157 || face
->tty_blinking_p
2158 || face
->tty_underline_p
)
2160 OUTPUT1_IF (TS_exit_attribute_mode
);
2161 if (strcmp (TS_exit_attribute_mode
, TS_end_standout_mode
) == 0)
2165 if (face
->tty_alt_charset_p
)
2166 OUTPUT_IF (TS_exit_alt_charset_mode
);
2170 /* If we don't have "me" we can only have those appearances
2171 that have exit sequences defined. */
2172 if (face
->tty_alt_charset_p
)
2173 OUTPUT_IF (TS_exit_alt_charset_mode
);
2175 if (face
->tty_underline_p
)
2176 OUTPUT_IF (TS_exit_underline_mode
);
2179 /* Switch back to default colors. */
2180 if (TN_max_colors
> 0
2181 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2182 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2183 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2184 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2185 OUTPUT1_IF (TS_orig_pair
);
2189 /* Return non-zero if the terminal on frame F supports all of the
2190 capabilities in CAPS simultaneously, with foreground and background
2191 colors FG and BG. */
2194 tty_capable_p (f
, caps
, fg
, bg
)
2197 unsigned long fg
, bg
;
2199 #define TTY_CAPABLE_P_TRY(cap, TS, NC_bit) \
2200 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(NC_bit))) \
2203 TTY_CAPABLE_P_TRY (TTY_CAP_INVERSE
, TS_standout_mode
, NC_REVERSE
);
2204 TTY_CAPABLE_P_TRY (TTY_CAP_UNDERLINE
, TS_enter_underline_mode
, NC_UNDERLINE
);
2205 TTY_CAPABLE_P_TRY (TTY_CAP_BOLD
, TS_enter_bold_mode
, NC_BOLD
);
2206 TTY_CAPABLE_P_TRY (TTY_CAP_DIM
, TS_enter_dim_mode
, NC_DIM
);
2207 TTY_CAPABLE_P_TRY (TTY_CAP_BLINK
, TS_enter_blink_mode
, NC_BLINK
);
2208 TTY_CAPABLE_P_TRY (TTY_CAP_ALT_CHARSET
, TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
2215 /* Return non-zero if the terminal is capable to display colors. */
2217 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2219 doc
: /* Return non-nil if TTY can display colors on DISPLAY. */)
2221 Lisp_Object display
;
2223 return TN_max_colors
> 0 ? Qt
: Qnil
;
2226 /* Return the number of supported colors. */
2227 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2228 Stty_display_color_cells
, 0, 1, 0,
2229 doc
: /* Return the number of colors supported by TTY on DISPLAY. */)
2231 Lisp_Object display
;
2233 return make_number (TN_max_colors
);
2238 /* Save or restore the default color-related capabilities of this
2241 tty_default_color_capabilities (save
)
2245 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
2246 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
2250 if (default_orig_pair
)
2251 xfree (default_orig_pair
);
2252 default_orig_pair
= TS_orig_pair
? xstrdup (TS_orig_pair
) : NULL
;
2254 if (default_set_foreground
)
2255 xfree (default_set_foreground
);
2256 default_set_foreground
= TS_set_foreground
? xstrdup (TS_set_foreground
)
2259 if (default_set_background
)
2260 xfree (default_set_background
);
2261 default_set_background
= TS_set_background
? xstrdup (TS_set_background
)
2264 default_max_colors
= TN_max_colors
;
2265 default_max_pairs
= TN_max_pairs
;
2266 default_no_color_video
= TN_no_color_video
;
2270 TS_orig_pair
= default_orig_pair
;
2271 TS_set_foreground
= default_set_foreground
;
2272 TS_set_background
= default_set_background
;
2273 TN_max_colors
= default_max_colors
;
2274 TN_max_pairs
= default_max_pairs
;
2275 TN_no_color_video
= default_no_color_video
;
2279 /* Setup one of the standard tty color schemes according to MODE.
2280 MODE's value is generally the number of colors which we want to
2281 support; zero means set up for the default capabilities, the ones
2282 we saw at term_init time; -1 means turn off color support. */
2284 tty_setup_colors (mode
)
2287 /* Canonicalize all negative values of MODE. */
2293 case -1: /* no colors at all */
2296 TN_no_color_video
= 0;
2297 TS_set_foreground
= TS_set_background
= TS_orig_pair
= NULL
;
2299 case 0: /* default colors, if any */
2301 tty_default_color_capabilities (0);
2303 case 8: /* 8 standard ANSI colors */
2304 TS_orig_pair
= "\033[0m";
2306 TS_set_foreground
= "\033[3%p1%dm";
2307 TS_set_background
= "\033[4%p1%dm";
2309 TS_set_foreground
= "\033[3%dm";
2310 TS_set_background
= "\033[4%dm";
2314 TN_no_color_video
= 0;
2320 set_tty_color_mode (f
, val
)
2324 Lisp_Object color_mode_spec
, current_mode_spec
;
2325 Lisp_Object color_mode
, current_mode
;
2327 extern Lisp_Object Qtty_color_mode
;
2328 Lisp_Object tty_color_mode_alist
;
2330 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2337 if (NILP (tty_color_mode_alist
))
2338 color_mode_spec
= Qnil
;
2340 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2342 if (CONSP (color_mode_spec
))
2343 color_mode
= XCDR (color_mode_spec
);
2348 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2350 if (CONSP (current_mode_spec
))
2351 current_mode
= XCDR (current_mode_spec
);
2353 current_mode
= Qnil
;
2354 if (INTEGERP (color_mode
))
2355 mode
= XINT (color_mode
);
2357 mode
= 0; /* meaning default */
2358 if (INTEGERP (current_mode
))
2359 old_mode
= XINT (current_mode
);
2363 if (mode
!= old_mode
)
2365 tty_setup_colors (mode
);
2366 /* This recomputes all the faces given the new color
2368 call0 (intern ("tty-set-up-initial-frame-faces"));
2373 #endif /* !WINDOWSNT */
2376 /***********************************************************************
2378 ***********************************************************************/
2382 term_mouse_moveto (int x
, int y
)
2386 /* TODO: how to set mouse position?
2387 name = (const char *) ttyname (0);
2388 fd = open (name, O_WRONLY);
2389 SOME_FUNCTION (x, y, fd);
2392 last_mouse_y = y; */
2396 term_show_mouse_face (enum draw_glyphs_face draw
)
2398 struct window
*w
= XWINDOW (Qmouse_face_window
);
2402 if (/* If window is in the process of being destroyed, don't bother
2404 w
->current_matrix
!= NULL
2405 /* Recognize when we are called to operate on rows that don't exist
2406 anymore. This can happen when a window is split. */
2407 && mouse_face_end_row
< w
->current_matrix
->nrows
)
2409 /* write_glyphs writes at cursor position, so we need to
2410 temporarily move cursor coordinates to the beginning of
2411 the highlight region. */
2413 /* Save current cursor co-ordinates */
2417 /* Note that mouse_face_beg_row etc. are window relative. */
2418 for (i
= mouse_face_beg_row
; i
<= mouse_face_end_row
; i
++)
2420 int start_hpos
, end_hpos
, nglyphs
;
2421 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
2423 /* Don't do anything if row doesn't have valid contents. */
2424 if (!row
->enabled_p
)
2427 /* For all but the first row, the highlight starts at column 0. */
2428 if (i
== mouse_face_beg_row
)
2429 start_hpos
= mouse_face_beg_col
;
2433 if (i
== mouse_face_end_row
)
2434 end_hpos
= mouse_face_end_col
;
2437 end_hpos
= row
->used
[TEXT_AREA
];
2438 if (draw
== DRAW_NORMAL_TEXT
)
2439 row
->fill_line_p
= 1; /* Clear to end of line */
2442 if (end_hpos
<= start_hpos
)
2444 /* Record that some glyphs of this row are displayed in
2446 row
->mouse_face_p
= draw
> 0;
2448 nglyphs
= end_hpos
- start_hpos
;
2450 if (end_hpos
>= row
->used
[TEXT_AREA
])
2451 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2453 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2454 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
2455 + WINDOW_LEFT_EDGE_X (w
);
2457 cursor_to (pos_y
, pos_x
);
2459 if (draw
== DRAW_MOUSE_FACE
)
2461 write_glyphs_with_face (row
->glyphs
[TEXT_AREA
] + start_hpos
,
2462 nglyphs
, mouse_face_face_id
);
2464 else /* draw == DRAW_NORMAL_TEXT */
2465 write_glyphs (row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2467 cursor_to (save_y
, save_x
);
2472 term_clear_mouse_face ()
2474 if (!NILP (Qmouse_face_window
))
2475 term_show_mouse_face (DRAW_NORMAL_TEXT
);
2477 mouse_face_beg_row
= mouse_face_beg_col
= -1;
2478 mouse_face_end_row
= mouse_face_end_col
= -1;
2479 Qmouse_face_window
= Qnil
;
2482 /* Find the glyph matrix position of buffer position POS in window W.
2483 *HPOS and *VPOS are set to the positions found. W's current glyphs
2484 must be up to date. If POS is above window start return (0, 0).
2485 If POS is after end of W, return end of last line in W.
2486 - taken from msdos.c */
2488 fast_find_position (struct window
*w
, int pos
, int *hpos
, int *vpos
)
2490 int i
, lastcol
, line_start_position
, maybe_next_line_p
= 0;
2491 int yb
= window_text_bottom_y (w
);
2492 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0), *best_row
= row
;
2496 if (row
->used
[TEXT_AREA
])
2497 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
2499 line_start_position
= 0;
2501 if (line_start_position
> pos
)
2503 /* If the position sought is the end of the buffer,
2504 don't include the blank lines at the bottom of the window. */
2505 else if (line_start_position
== pos
2506 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
2508 maybe_next_line_p
= 1;
2511 else if (line_start_position
> 0)
2514 /* Don't overstep the last matrix row, lest we get into the
2515 never-never land... */
2516 if (row
->y
+ 1 >= yb
)
2522 /* Find the right column within BEST_ROW. */
2525 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
2527 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + i
;
2530 charpos
= glyph
->charpos
;
2537 else if (charpos
> pos
)
2539 else if (charpos
> 0)
2543 /* If we're looking for the end of the buffer,
2544 and we didn't find it in the line we scanned,
2545 use the start of the following line. */
2546 if (maybe_next_line_p
)
2553 *hpos
= lastcol
+ 1;
2558 term_mouse_highlight (struct frame
*f
, int x
, int y
)
2560 enum window_part part
;
2565 if (NILP (Vmouse_highlight
)
2566 || !f
->glyphs_initialized_p
)
2569 /* Which window is that in? */
2570 window
= window_from_coordinates (f
, x
, y
, &part
, &x
, &y
, 0);
2572 /* Not on a window -> return. */
2573 if (!WINDOWP (window
))
2576 if (!EQ (window
, Qmouse_face_window
))
2577 term_clear_mouse_face ();
2579 w
= XWINDOW (window
);
2581 /* Are we in a window whose display is up to date?
2582 And verify the buffer's text has not changed. */
2583 b
= XBUFFER (w
->buffer
);
2585 && EQ (w
->window_end_valid
, w
->buffer
)
2586 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
2587 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
2589 int pos
, i
, nrows
= w
->current_matrix
->nrows
;
2590 struct glyph_row
*row
;
2591 struct glyph
*glyph
;
2593 /* Find the glyph under X/Y. */
2595 if (y
>= 0 && y
< nrows
)
2597 row
= MATRIX_ROW (w
->current_matrix
, y
);
2598 /* Give up if some row before the one we are looking for is
2600 for (i
= 0; i
<= y
; i
++)
2601 if (!MATRIX_ROW (w
->current_matrix
, i
)->enabled_p
)
2603 if (i
> y
/* all rows upto and including the one at Y are enabled */
2604 && row
->displays_text_p
2605 && x
< window_box_width (w
, TEXT_AREA
))
2607 glyph
= row
->glyphs
[TEXT_AREA
];
2608 if (x
>= row
->used
[TEXT_AREA
])
2613 if (!BUFFERP (glyph
->object
))
2619 /* Clear mouse face if X/Y not over text. */
2622 term_clear_mouse_face ();
2626 if (!BUFFERP (glyph
->object
))
2628 pos
= glyph
->charpos
;
2630 /* Check for mouse-face. */
2632 extern Lisp_Object Qmouse_face
;
2633 Lisp_Object mouse_face
, overlay
, position
, *overlay_vec
;
2634 int noverlays
, obegv
, ozv
;
2635 struct buffer
*obuf
;
2637 /* If we get an out-of-range value, return now; avoid an error. */
2638 if (pos
> BUF_Z (b
))
2641 /* Make the window's buffer temporarily current for
2642 overlays_at and compute_char_face. */
2643 obuf
= current_buffer
;
2650 /* Is this char mouse-active? */
2651 XSETINT (position
, pos
);
2653 /* Put all the overlays we want in a vector in overlay_vec. */
2654 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
2655 /* Sort overlays into increasing priority order. */
2656 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
2658 /* Check mouse-face highlighting. */
2659 if (!(EQ (window
, Qmouse_face_window
)
2660 && y
>= mouse_face_beg_row
2661 && y
<= mouse_face_end_row
2662 && (y
> mouse_face_beg_row
2663 || x
>= mouse_face_beg_col
)
2664 && (y
< mouse_face_end_row
2665 || x
< mouse_face_end_col
2666 || mouse_face_past_end
)))
2668 /* Clear the display of the old active region, if any. */
2669 term_clear_mouse_face ();
2671 /* Find the highest priority overlay that has a mouse-face
2674 for (i
= noverlays
- 1; i
>= 0; --i
)
2676 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
2677 if (!NILP (mouse_face
))
2679 overlay
= overlay_vec
[i
];
2684 /* If no overlay applies, get a text property. */
2686 mouse_face
= Fget_text_property (position
, Qmouse_face
,
2689 /* Handle the overlay case. */
2690 if (!NILP (overlay
))
2692 /* Find the range of text around this char that
2693 should be active. */
2694 Lisp_Object before
, after
;
2698 before
= Foverlay_start (overlay
);
2699 after
= Foverlay_end (overlay
);
2700 /* Record this as the current active region. */
2701 fast_find_position (w
, XFASTINT (before
),
2702 &mouse_face_beg_col
,
2703 &mouse_face_beg_row
);
2706 = !fast_find_position (w
, XFASTINT (after
),
2707 &mouse_face_end_col
,
2708 &mouse_face_end_row
);
2709 Qmouse_face_window
= window
;
2712 = face_at_buffer_position (w
, pos
, 0, 0,
2713 &ignore
, pos
+ 1, 1);
2715 /* Display it as active. */
2716 term_show_mouse_face (DRAW_MOUSE_FACE
);
2718 /* Handle the text property case. */
2719 else if (!NILP (mouse_face
))
2721 /* Find the range of text around this char that
2722 should be active. */
2723 Lisp_Object before
, after
, beginning
, end
;
2726 beginning
= Fmarker_position (w
->start
);
2727 XSETINT (end
, (BUF_Z (b
) - XFASTINT (w
->window_end_pos
)));
2729 = Fprevious_single_property_change (make_number (pos
+ 1),
2731 w
->buffer
, beginning
);
2733 = Fnext_single_property_change (position
, Qmouse_face
,
2736 /* Record this as the current active region. */
2737 fast_find_position (w
, XFASTINT (before
),
2738 &mouse_face_beg_col
,
2739 &mouse_face_beg_row
);
2741 = !fast_find_position (w
, XFASTINT (after
),
2742 &mouse_face_end_col
,
2743 &mouse_face_end_row
);
2744 Qmouse_face_window
= window
;
2747 = face_at_buffer_position (w
, pos
, 0, 0,
2748 &ignore
, pos
+ 1, 1);
2750 /* Display it as active. */
2751 term_show_mouse_face (DRAW_MOUSE_FACE
);
2755 /* Look for a `help-echo' property. */
2758 extern Lisp_Object Qhelp_echo
;
2760 /* Check overlays first. */
2762 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
2764 overlay
= overlay_vec
[i
];
2765 help
= Foverlay_get (overlay
, Qhelp_echo
);
2770 help_echo_string
= help
;
2771 help_echo_window
= window
;
2772 help_echo_object
= overlay
;
2773 help_echo_pos
= pos
;
2775 /* Try text properties. */
2776 else if (NILP (help
)
2777 && ((STRINGP (glyph
->object
)
2778 && glyph
->charpos
>= 0
2779 && glyph
->charpos
< SCHARS (glyph
->object
))
2780 || (BUFFERP (glyph
->object
)
2781 && glyph
->charpos
>= BEGV
2782 && glyph
->charpos
< ZV
)))
2784 help
= Fget_text_property (make_number (glyph
->charpos
),
2785 Qhelp_echo
, glyph
->object
);
2788 help_echo_string
= help
;
2789 help_echo_window
= window
;
2790 help_echo_object
= glyph
->object
;
2791 help_echo_pos
= glyph
->charpos
;
2798 current_buffer
= obuf
;
2804 term_mouse_movement (FRAME_PTR frame
, Gpm_Event
*event
)
2806 /* Has the mouse moved off the glyph it was on at the last sighting? */
2807 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2809 frame
->mouse_moved
= 1;
2810 term_mouse_highlight (frame
, event
->x
, event
->y
);
2811 /* Remember which glyph we're now on. */
2812 last_mouse_x
= event
->x
;
2813 last_mouse_y
= event
->y
;
2819 /* Return the current position of the mouse.
2821 Set *f to the frame the mouse is in, or zero if the mouse is in no
2822 Emacs frame. If it is set to zero, all the other arguments are
2825 Set *bar_window to Qnil, and *x and *y to the column and
2826 row of the character cell the mouse is over.
2828 Set *time to the time the mouse was at the returned position.
2830 This clears mouse_moved until the next motion
2833 term_mouse_position (FRAME_PTR
*fp
, int insist
, Lisp_Object
*bar_window
,
2834 enum scroll_bar_part
*part
, Lisp_Object
*x
,
2835 Lisp_Object
*y
, unsigned long *time
)
2839 *fp
= SELECTED_FRAME ();
2840 (*fp
)->mouse_moved
= 0;
2845 XSETINT (*x
, last_mouse_x
);
2846 XSETINT (*y
, last_mouse_y
);
2847 gettimeofday(&now
, 0);
2848 *time
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2851 /* Prepare a mouse-event in *RESULT for placement in the input queue.
2853 If the event is a button press, then note that we have grabbed
2857 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
2863 result
->kind
= GPM_CLICK_EVENT
;
2864 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
2866 if (event
->buttons
& j
) {
2867 result
->code
= i
; /* button number */
2871 gettimeofday(&now
, 0);
2872 result
->timestamp
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2874 if (event
->type
& GPM_UP
)
2875 result
->modifiers
= up_modifier
;
2876 else if (event
->type
& GPM_DOWN
)
2877 result
->modifiers
= down_modifier
;
2879 result
->modifiers
= 0;
2881 if (event
->type
& GPM_SINGLE
)
2882 result
->modifiers
|= click_modifier
;
2884 if (event
->type
& GPM_DOUBLE
)
2885 result
->modifiers
|= double_modifier
;
2887 if (event
->type
& GPM_TRIPLE
)
2888 result
->modifiers
|= triple_modifier
;
2890 if (event
->type
& GPM_DRAG
)
2891 result
->modifiers
|= drag_modifier
;
2893 if (!(event
->type
& (GPM_MOVE
| GPM_DRAG
))) {
2896 if (event
->modifiers
& (1 << 0))
2897 result
->modifiers
|= shift_modifier
;
2900 if (event
->modifiers
& (1 << 2))
2901 result
->modifiers
|= ctrl_modifier
;
2903 /* 1 << KG_ALT || KG_ALTGR */
2904 if (event
->modifiers
& (1 << 3)
2905 || event
->modifiers
& (1 << 1))
2906 result
->modifiers
|= meta_modifier
;
2909 XSETINT (result
->x
, event
->x
);
2910 XSETINT (result
->y
, event
->y
);
2911 XSETFRAME (result
->frame_or_window
, f
);
2917 handle_one_term_event (Gpm_Event
*event
, struct input_event
* hold_quit
)
2919 struct frame
*f
= SELECTED_FRAME ();
2921 struct input_event ie
;
2929 if (event
->type
& (GPM_MOVE
| GPM_DRAG
)) {
2930 unsigned char buf
[6 * sizeof (short)];
2931 unsigned short *arg
= (unsigned short *) buf
+ 1;
2934 previous_help_echo_string
= help_echo_string
;
2935 help_echo_string
= Qnil
;
2937 /* Display mouse pointer */
2938 buf
[sizeof(short) - 1] = 2; /* set selection */
2940 arg
[0] = arg
[2] = (unsigned short) event
->x
+ gpm_zerobased
;
2941 arg
[1] = arg
[3] = (unsigned short) event
->y
+ gpm_zerobased
;
2942 arg
[4] = (unsigned short) 3;
2944 name
= (const char *) ttyname (0);
2945 fd
= open (name
, O_WRONLY
);
2946 ioctl (fd
, TIOCLINUX
, buf
+ sizeof (short) - 1);
2949 if (!term_mouse_movement (f
, event
))
2950 help_echo_string
= previous_help_echo_string
;
2952 /* If the contents of the global variable help_echo_string
2953 has changed, generate a HELP_EVENT. */
2954 if (!NILP (help_echo_string
)
2955 || !NILP (previous_help_echo_string
))
2962 term_mouse_click (&ie
, event
, f
);
2966 if (ie
.kind
!= NO_EVENT
)
2968 kbd_buffer_store_event_hold (&ie
, hold_quit
);
2973 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
2978 XSETFRAME (frame
, f
);
2982 gen_help_event (help_echo_string
, frame
, help_echo_window
,
2983 help_echo_object
, help_echo_pos
);
2990 DEFUN ("term-open-connection", Fterm_open_connection
, Sterm_open_connection
,
2992 doc
: /* Open a connection to Gpm. */)
2995 Gpm_Connect connection
;
2997 connection
.eventMask
= ~0;
2998 connection
.defaultMask
= ~GPM_HARD
;
2999 connection
.maxMod
= ~0;
3000 connection
.minMod
= 0;
3003 if (Gpm_Open (&connection
, 0) < 0)
3010 add_gpm_wait_descriptor (gpm_fd
);
3015 DEFUN ("term-close-connection", Fterm_close_connection
, Sterm_close_connection
,
3017 doc
: /* Close a connection to Gpm. */)
3020 delete_gpm_wait_descriptor (gpm_fd
);
3021 while (Gpm_Close()); /* close all the stack */
3025 #endif /* HAVE_GPM */
3028 /***********************************************************************
3030 ***********************************************************************/
3033 term_init (terminal_type
)
3034 char *terminal_type
;
3037 char **address
= &area
;
3038 char *buffer
= NULL
;
3039 int buffer_size
= 4096;
3042 struct frame
*sf
= XFRAME (selected_frame
);
3044 encode_terminal_bufsize
= 0;
3047 mouse_position_hook
= term_mouse_position
;
3048 Qmouse_face_window
= Qnil
;
3052 initialize_w32_display ();
3056 area
= (char *) xmalloc (2044);
3058 FrameRows
= FRAME_LINES (sf
);
3059 FrameCols
= FRAME_COLS (sf
);
3060 specified_window
= FRAME_LINES (sf
);
3062 delete_in_insert_mode
= 1;
3065 scroll_region_ok
= 0;
3067 /* Seems to insert lines when it's not supposed to, messing
3068 up the display. In doing a trace, it didn't seem to be
3069 called much, so I don't think we're losing anything by
3072 line_ins_del_ok
= 0;
3073 char_ins_del_ok
= 1;
3077 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
3078 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
3079 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
3082 #else /* not WINDOWSNT */
3086 buffer
= (char *) xmalloc (buffer_size
);
3087 status
= tgetent (buffer
, terminal_type
);
3091 fatal ("Cannot open terminfo database file");
3093 fatal ("Cannot open termcap database file");
3099 fatal ("Terminal type %s is not defined.\n\
3100 If that is not the actual type of terminal you have,\n\
3101 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3102 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3103 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3106 fatal ("Terminal type %s is not defined.\n\
3107 If that is not the actual type of terminal you have,\n\
3108 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3109 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3110 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3116 if (strlen (buffer
) >= buffer_size
)
3118 buffer_size
= strlen (buffer
);
3120 area
= (char *) xmalloc (buffer_size
);
3122 TS_ins_line
= tgetstr ("al", address
);
3123 TS_ins_multi_lines
= tgetstr ("AL", address
);
3124 TS_bell
= tgetstr ("bl", address
);
3125 BackTab
= tgetstr ("bt", address
);
3126 TS_clr_to_bottom
= tgetstr ("cd", address
);
3127 TS_clr_line
= tgetstr ("ce", address
);
3128 TS_clr_frame
= tgetstr ("cl", address
);
3129 ColPosition
= NULL
; /* tgetstr ("ch", address); */
3130 AbsPosition
= tgetstr ("cm", address
);
3131 CR
= tgetstr ("cr", address
);
3132 TS_set_scroll_region
= tgetstr ("cs", address
);
3133 TS_set_scroll_region_1
= tgetstr ("cS", address
);
3134 RowPosition
= tgetstr ("cv", address
);
3135 TS_del_char
= tgetstr ("dc", address
);
3136 TS_del_multi_chars
= tgetstr ("DC", address
);
3137 TS_del_line
= tgetstr ("dl", address
);
3138 TS_del_multi_lines
= tgetstr ("DL", address
);
3139 TS_delete_mode
= tgetstr ("dm", address
);
3140 TS_end_delete_mode
= tgetstr ("ed", address
);
3141 TS_end_insert_mode
= tgetstr ("ei", address
);
3142 Home
= tgetstr ("ho", address
);
3143 TS_ins_char
= tgetstr ("ic", address
);
3144 TS_ins_multi_chars
= tgetstr ("IC", address
);
3145 TS_insert_mode
= tgetstr ("im", address
);
3146 TS_pad_inserted_char
= tgetstr ("ip", address
);
3147 TS_end_keypad_mode
= tgetstr ("ke", address
);
3148 TS_keypad_mode
= tgetstr ("ks", address
);
3149 LastLine
= tgetstr ("ll", address
);
3150 Right
= tgetstr ("nd", address
);
3151 Down
= tgetstr ("do", address
);
3153 Down
= tgetstr ("nl", address
); /* Obsolete name for "do" */
3155 /* VMS puts a carriage return before each linefeed,
3156 so it is not safe to use linefeeds. */
3157 if (Down
&& Down
[0] == '\n' && Down
[1] == '\0')
3160 if (tgetflag ("bs"))
3161 Left
= "\b"; /* can't possibly be longer! */
3162 else /* (Actually, "bs" is obsolete...) */
3163 Left
= tgetstr ("le", address
);
3165 Left
= tgetstr ("bc", address
); /* Obsolete name for "le" */
3166 TS_pad_char
= tgetstr ("pc", address
);
3167 TS_repeat
= tgetstr ("rp", address
);
3168 TS_end_standout_mode
= tgetstr ("se", address
);
3169 TS_fwd_scroll
= tgetstr ("sf", address
);
3170 TS_standout_mode
= tgetstr ("so", address
);
3171 TS_rev_scroll
= tgetstr ("sr", address
);
3172 Wcm
.cm_tab
= tgetstr ("ta", address
);
3173 TS_end_termcap_modes
= tgetstr ("te", address
);
3174 TS_termcap_modes
= tgetstr ("ti", address
);
3175 Up
= tgetstr ("up", address
);
3176 TS_visible_bell
= tgetstr ("vb", address
);
3177 TS_cursor_normal
= tgetstr ("ve", address
);
3178 TS_cursor_visible
= tgetstr ("vs", address
);
3179 TS_cursor_invisible
= tgetstr ("vi", address
);
3180 TS_set_window
= tgetstr ("wi", address
);
3182 TS_enter_underline_mode
= tgetstr ("us", address
);
3183 TS_exit_underline_mode
= tgetstr ("ue", address
);
3184 TS_enter_bold_mode
= tgetstr ("md", address
);
3185 TS_enter_dim_mode
= tgetstr ("mh", address
);
3186 TS_enter_blink_mode
= tgetstr ("mb", address
);
3187 TS_enter_reverse_mode
= tgetstr ("mr", address
);
3188 TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3189 TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3190 TS_exit_attribute_mode
= tgetstr ("me", address
);
3192 MultiUp
= tgetstr ("UP", address
);
3193 MultiDown
= tgetstr ("DO", address
);
3194 MultiLeft
= tgetstr ("LE", address
);
3195 MultiRight
= tgetstr ("RI", address
);
3197 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
3198 color because we can't switch back to the default foreground and
3200 TS_orig_pair
= tgetstr ("op", address
);
3203 TS_set_foreground
= tgetstr ("AF", address
);
3204 TS_set_background
= tgetstr ("AB", address
);
3205 if (!TS_set_foreground
)
3208 TS_set_foreground
= tgetstr ("Sf", address
);
3209 TS_set_background
= tgetstr ("Sb", address
);
3212 TN_max_colors
= tgetnum ("Co");
3213 TN_max_pairs
= tgetnum ("pa");
3215 TN_no_color_video
= tgetnum ("NC");
3216 if (TN_no_color_video
== -1)
3217 TN_no_color_video
= 0;
3220 tty_default_color_capabilities (1);
3222 MagicWrap
= tgetflag ("xn");
3223 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3224 the former flag imply the latter. */
3225 AutoWrap
= MagicWrap
|| tgetflag ("am");
3226 memory_below_frame
= tgetflag ("db");
3227 TF_hazeltine
= tgetflag ("hz");
3228 must_write_spaces
= tgetflag ("in");
3229 meta_key
= tgetflag ("km") || tgetflag ("MT");
3230 TF_insmode_motion
= tgetflag ("mi");
3231 TF_standout_motion
= tgetflag ("ms");
3232 TF_underscore
= tgetflag ("ul");
3233 TF_teleray
= tgetflag ("xt");
3235 term_get_fkeys (address
);
3237 /* Get frame size from system, or else from termcap. */
3240 get_frame_size (&width
, &height
);
3241 FRAME_COLS (sf
) = width
;
3242 FRAME_LINES (sf
) = height
;
3245 if (FRAME_COLS (sf
) <= 0)
3246 SET_FRAME_COLS (sf
, tgetnum ("co"));
3248 /* Keep width and external_width consistent */
3249 SET_FRAME_COLS (sf
, FRAME_COLS (sf
));
3250 if (FRAME_LINES (sf
) <= 0)
3251 FRAME_LINES (sf
) = tgetnum ("li");
3253 if (FRAME_LINES (sf
) < 3 || FRAME_COLS (sf
) < 3)
3254 fatal ("Screen size %dx%d is too small",
3255 FRAME_LINES (sf
), FRAME_COLS (sf
));
3257 min_padding_speed
= tgetnum ("pb");
3258 TabWidth
= tgetnum ("tw");
3261 /* These capabilities commonly use ^J.
3262 I don't know why, but sending them on VMS does not work;
3263 it causes following spaces to be lost, sometimes.
3264 For now, the simplest fix is to avoid using these capabilities ever. */
3265 if (Down
&& Down
[0] == '\n')
3273 TS_fwd_scroll
= Down
;
3275 PC
= TS_pad_char
? *TS_pad_char
: 0;
3280 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3281 and newer termcap doc does not seem to say there is a default.
3286 /* We don't support standout modes that use `magic cookies', so
3287 turn off any that do. */
3288 if (TS_standout_mode
&& tgetnum ("sg") >= 0)
3290 TS_standout_mode
= 0;
3291 TS_end_standout_mode
= 0;
3293 if (TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3295 TS_enter_underline_mode
= 0;
3296 TS_exit_underline_mode
= 0;
3299 /* If there's no standout mode, try to use underlining instead. */
3300 if (TS_standout_mode
== 0)
3302 TS_standout_mode
= TS_enter_underline_mode
;
3303 TS_end_standout_mode
= TS_exit_underline_mode
;
3306 /* If no `se' string, try using a `me' string instead.
3307 If that fails, we can't use standout mode at all. */
3308 if (TS_end_standout_mode
== 0)
3310 char *s
= tgetstr ("me", address
);
3312 TS_end_standout_mode
= s
;
3314 TS_standout_mode
= 0;
3320 /* We can't support standout mode, because it uses magic cookies. */
3321 TS_standout_mode
= 0;
3322 /* But that means we cannot rely on ^M to go to column zero! */
3324 /* LF can't be trusted either -- can alter hpos */
3325 /* if move at column 0 thru a line with TS_standout_mode */
3329 /* Special handling for certain terminal types known to need it */
3331 if (!strcmp (terminal_type
, "supdup"))
3333 memory_below_frame
= 1;
3334 Wcm
.cm_losewrap
= 1;
3336 if (!strncmp (terminal_type
, "c10", 3)
3337 || !strcmp (terminal_type
, "perq"))
3339 /* Supply a makeshift :wi string.
3340 This string is not valid in general since it works only
3341 for windows starting at the upper left corner;
3342 but that is all Emacs uses.
3344 This string works only if the frame is using
3345 the top of the video memory, because addressing is memory-relative.
3346 So first check the :ti string to see if that is true.
3348 It would be simpler if the :wi string could go in the termcap
3349 entry, but it can't because it is not fully valid.
3350 If it were in the termcap entry, it would confuse other programs. */
3353 p
= TS_termcap_modes
;
3354 while (*p
&& strcmp (p
, "\033v "))
3357 TS_set_window
= "\033v%C %C %C %C ";
3359 /* Termcap entry often fails to have :in: flag */
3360 must_write_spaces
= 1;
3361 /* :ti string typically fails to have \E^G! in it */
3362 /* This limits scope of insert-char to one line. */
3363 strcpy (area
, TS_termcap_modes
);
3364 strcat (area
, "\033\007!");
3365 TS_termcap_modes
= area
;
3366 area
+= strlen (area
) + 1;
3368 /* Change all %+ parameters to %C, to handle
3369 values above 96 correctly for the C100. */
3372 if (p
[0] == '%' && p
[1] == '+')
3378 FrameRows
= FRAME_LINES (sf
);
3379 FrameCols
= FRAME_COLS (sf
);
3380 specified_window
= FRAME_LINES (sf
);
3382 if (Wcm_init () == -1) /* can't do cursor motion */
3384 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3385 It lacks the ability to position the cursor.\n\
3386 If that is not the actual type of terminal you have, use either the\n\
3387 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
3388 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
3392 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3393 It lacks the ability to position the cursor.\n\
3394 If that is not the actual type of terminal you have,\n\
3395 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3396 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3397 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3399 # else /* TERMCAP */
3400 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3401 It lacks the ability to position the cursor.\n\
3402 If that is not the actual type of terminal you have,\n\
3403 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3404 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3405 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3407 # endif /* TERMINFO */
3409 if (FRAME_LINES (sf
) <= 0
3410 || FRAME_COLS (sf
) <= 0)
3411 fatal ("The frame size has not been specified");
3413 delete_in_insert_mode
3414 = TS_delete_mode
&& TS_insert_mode
3415 && !strcmp (TS_delete_mode
, TS_insert_mode
);
3417 se_is_so
= (TS_standout_mode
3418 && TS_end_standout_mode
3419 && !strcmp (TS_standout_mode
, TS_end_standout_mode
));
3421 UseTabs
= tabs_safe_p () && TabWidth
== 8;
3425 && (TS_set_window
|| TS_set_scroll_region
|| TS_set_scroll_region_1
));
3427 line_ins_del_ok
= (((TS_ins_line
|| TS_ins_multi_lines
)
3428 && (TS_del_line
|| TS_del_multi_lines
))
3429 || (scroll_region_ok
&& TS_fwd_scroll
&& TS_rev_scroll
));
3431 char_ins_del_ok
= ((TS_ins_char
|| TS_insert_mode
3432 || TS_pad_inserted_char
|| TS_ins_multi_chars
)
3433 && (TS_del_char
|| TS_del_multi_chars
));
3435 fast_clear_end_of_line
= TS_clr_line
!= 0;
3438 if (read_socket_hook
) /* Baudrate is somewhat */
3439 /* meaningless in this case */
3442 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
3443 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
3444 #endif /* WINDOWSNT */
3451 fatal (str
, arg1
, arg2
)
3452 char *str
, *arg1
, *arg2
;
3454 fprintf (stderr
, "emacs: ");
3455 fprintf (stderr
, str
, arg1
, arg2
);
3456 fprintf (stderr
, "\n");
3461 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 0, 0,
3462 doc
: /* Declare that this terminal does not handle underlining.
3463 This is used to override the terminfo data, for certain terminals that
3464 do not really do underlining, but say that they do. */)
3467 TS_enter_underline_mode
= 0;
3474 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
3475 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3476 This variable can be used by terminal emulator packages. */);
3478 system_uses_terminfo
= 1;
3480 system_uses_terminfo
= 0;
3483 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
3484 doc
: /* Non-nil means call this function to ring the bell.
3485 The function should accept no arguments. */);
3486 Vring_bell_function
= Qnil
;
3488 DEFVAR_BOOL ("visible-cursor", &visible_cursor
,
3489 doc
: /* Non-nil means to make the cursor very visible.
3490 This only has an effect when running in a text terminal.
3491 What means \"very visible\" is up to your terminal. It may make the cursor
3492 bigger, or it may make it blink, or it may do nothing at all. */);
3495 defsubr (&Stty_display_color_p
);
3496 defsubr (&Stty_display_color_cells
);
3497 defsubr (&Stty_no_underline
);
3499 defsubr (&Sterm_open_connection
);
3500 defsubr (&Sterm_close_connection
);
3502 staticpro (&Qmouse_face_window
);
3503 #endif /* HAVE_GPM */
3505 fullscreen_hook
= NULL
;
3508 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
3509 (do not change this comment) */