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>. */
40 #include "termhooks.h"
41 #include "dispextern.h"
44 #include "blockinput.h"
45 #include "intervals.h"
47 /* For now, don't try to include termcap.h. On some systems,
48 configure finds a non-standard termcap.h that the main build
51 #if defined HAVE_TERMCAP_H && 0
54 extern void tputs
P_ ((const char *, int, int (*)(int)));
55 extern int tgetent
P_ ((char *, const char *));
56 extern int tgetflag
P_ ((char *id
));
57 extern int tgetnum
P_ ((char *id
));
68 static void turn_on_face
P_ ((struct frame
*, int face_id
));
69 static void turn_off_face
P_ ((struct frame
*, int face_id
));
70 static void tty_show_cursor
P_ ((void));
71 static void tty_hide_cursor
P_ ((void));
74 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) - curY), cmputc)
75 #define OUTPUT1(a) tputs (a, 1, cmputc)
76 #define OUTPUTL(a, lines) tputs (a, lines, cmputc)
78 #define OUTPUT_IF(a) \
81 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) \
85 #define OUTPUT1_IF(a) do { if (a) tputs (a, 1, cmputc); } while (0)
87 /* Display space properties */
89 extern Lisp_Object Qspace
, QCalign_to
, QCwidth
;
91 /* Function to use to ring the bell. */
93 Lisp_Object Vring_bell_function
;
95 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */
97 static int visible_cursor
;
99 /* Terminal characteristics that higher levels want to look at.
100 These are all extern'd in termchar.h */
102 int must_write_spaces
; /* Nonzero means spaces in the text
103 must actually be output; can't just skip
104 over some columns to leave them blank. */
105 int min_padding_speed
; /* Speed below which no padding necessary */
107 int line_ins_del_ok
; /* Terminal can insert and delete lines */
108 int char_ins_del_ok
; /* Terminal can insert and delete chars */
109 int scroll_region_ok
; /* Terminal supports setting the
111 int scroll_region_cost
; /* Cost of setting a scroll window,
112 measured in characters */
113 int memory_below_frame
; /* Terminal remembers lines
114 scrolled off bottom */
115 int fast_clear_end_of_line
; /* Terminal has a `ce' string */
117 /* Nonzero means no need to redraw the entire frame on resuming
118 a suspended Emacs. This is useful on terminals with multiple pages,
119 where one page is used for Emacs and another for all else. */
121 int no_redraw_on_reenter
;
123 /* Hook functions that you can set to snap out the functions in this file.
124 These are all extern'd in termhooks.h */
126 void (*cursor_to_hook
) P_ ((int, int));
127 void (*raw_cursor_to_hook
) P_ ((int, int));
128 void (*clear_to_end_hook
) P_ ((void));
129 void (*clear_frame_hook
) P_ ((void));
130 void (*clear_end_of_line_hook
) P_ ((int));
132 void (*ins_del_lines_hook
) P_ ((int, int));
134 void (*delete_glyphs_hook
) P_ ((int));
136 void (*ring_bell_hook
) P_ ((void));
138 void (*reset_terminal_modes_hook
) P_ ((void));
139 void (*set_terminal_modes_hook
) P_ ((void));
140 void (*update_begin_hook
) P_ ((struct frame
*));
141 void (*update_end_hook
) P_ ((struct frame
*));
142 void (*set_terminal_window_hook
) P_ ((int));
143 void (*insert_glyphs_hook
) P_ ((struct glyph
*, int));
144 void (*write_glyphs_hook
) P_ ((struct glyph
*, int));
145 void (*delete_glyphs_hook
) P_ ((int));
147 int (*read_socket_hook
) P_ ((int, int, struct input_event
*));
149 void (*frame_up_to_date_hook
) P_ ((struct frame
*));
151 void (*mouse_position_hook
) P_ ((FRAME_PTR
*f
, int insist
,
152 Lisp_Object
*bar_window
,
153 enum scroll_bar_part
*part
,
156 unsigned long *time
));
158 /* When reading from a minibuffer in a different frame, Emacs wants
159 to shift the highlight from the selected frame to the mini-buffer's
160 frame; under X, this means it lies about where the focus is.
161 This hook tells the window system code to re-decide where to put
164 void (*frame_rehighlight_hook
) P_ ((FRAME_PTR f
));
166 /* If we're displaying frames using a window system that can stack
167 frames on top of each other, this hook allows you to bring a frame
168 to the front, or bury it behind all the other windows. If this
169 hook is zero, that means the device we're displaying on doesn't
170 support overlapping frames, so there's no need to raise or lower
173 If RAISE is non-zero, F is brought to the front, before all other
174 windows. If RAISE is zero, F is sent to the back, behind all other
177 void (*frame_raise_lower_hook
) P_ ((FRAME_PTR f
, int raise
));
179 /* If the value of the frame parameter changed, whis hook is called.
180 For example, if going from fullscreen to not fullscreen this hook
181 may do something OS dependent, like extended window manager hints on X11. */
182 void (*fullscreen_hook
) P_ ((struct frame
*f
));
184 /* Set the vertical scroll bar for WINDOW to have its upper left corner
185 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
186 indicate that we are displaying PORTION characters out of a total
187 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
188 have a scroll bar, create one for it. */
190 void (*set_vertical_scroll_bar_hook
)
191 P_ ((struct window
*window
,
192 int portion
, int whole
, int position
));
195 /* The following three hooks are used when we're doing a thorough
196 redisplay of the frame. We don't explicitly know which scroll bars
197 are going to be deleted, because keeping track of when windows go
198 away is a real pain - can you say set-window-configuration?
199 Instead, we just assert at the beginning of redisplay that *all*
200 scroll bars are to be removed, and then save scroll bars from the
201 fiery pit when we actually redisplay their window. */
203 /* Arrange for all scroll bars on FRAME to be removed at the next call
204 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
205 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
207 This should be applied to each frame each time its window tree is
208 redisplayed, even if it is not displaying scroll bars at the moment;
209 if the HAS_SCROLL_BARS flag has just been turned off, only calling
210 this and the judge_scroll_bars_hook will get rid of them.
212 If non-zero, this hook should be safe to apply to any frame,
213 whether or not it can support scroll bars, and whether or not it is
214 currently displaying them. */
216 void (*condemn_scroll_bars_hook
) P_ ((FRAME_PTR frame
));
218 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
219 Note that it's okay to redeem a scroll bar that is not condemned. */
221 void (*redeem_scroll_bar_hook
) P_ ((struct window
*window
));
223 /* Remove all scroll bars on FRAME that haven't been saved since the
224 last call to `*condemn_scroll_bars_hook'.
226 This should be applied to each frame after each time its window
227 tree is redisplayed, even if it is not displaying scroll bars at the
228 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
229 calling this and condemn_scroll_bars_hook will get rid of them.
231 If non-zero, this hook should be safe to apply to any frame,
232 whether or not it can support scroll bars, and whether or not it is
233 currently displaying them. */
235 void (*judge_scroll_bars_hook
) P_ ((FRAME_PTR FRAME
));
237 /* Strings, numbers and flags taken from the termcap entry. */
239 char *TS_ins_line
; /* "al" */
240 char *TS_ins_multi_lines
; /* "AL" (one parameter, # lines to insert) */
241 char *TS_bell
; /* "bl" */
242 char *TS_clr_to_bottom
; /* "cd" */
243 char *TS_clr_line
; /* "ce", clear to end of line */
244 char *TS_clr_frame
; /* "cl" */
245 char *TS_set_scroll_region
; /* "cs" (2 params, first line and last line) */
246 char *TS_set_scroll_region_1
; /* "cS" (4 params: total lines,
247 lines above scroll region, lines below it,
248 total lines again) */
249 char *TS_del_char
; /* "dc" */
250 char *TS_del_multi_chars
; /* "DC" (one parameter, # chars to delete) */
251 char *TS_del_line
; /* "dl" */
252 char *TS_del_multi_lines
; /* "DL" (one parameter, # lines to delete) */
253 char *TS_delete_mode
; /* "dm", enter character-delete mode */
254 char *TS_end_delete_mode
; /* "ed", leave character-delete mode */
255 char *TS_end_insert_mode
; /* "ei", leave character-insert mode */
256 char *TS_ins_char
; /* "ic" */
257 char *TS_ins_multi_chars
; /* "IC" (one parameter, # chars to insert) */
258 char *TS_insert_mode
; /* "im", enter character-insert mode */
259 char *TS_pad_inserted_char
; /* "ip". Just padding, no commands. */
260 char *TS_end_keypad_mode
; /* "ke" */
261 char *TS_keypad_mode
; /* "ks" */
262 char *TS_pad_char
; /* "pc", char to use as padding */
263 char *TS_repeat
; /* "rp" (2 params, # times to repeat
264 and character to be repeated) */
265 char *TS_end_standout_mode
; /* "se" */
266 char *TS_fwd_scroll
; /* "sf" */
267 char *TS_standout_mode
; /* "so" */
268 char *TS_rev_scroll
; /* "sr" */
269 char *TS_end_termcap_modes
; /* "te" */
270 char *TS_termcap_modes
; /* "ti" */
271 char *TS_visible_bell
; /* "vb" */
272 char *TS_cursor_normal
; /* "ve" */
273 char *TS_cursor_visible
; /* "vs" */
274 char *TS_cursor_invisible
; /* "vi" */
275 char *TS_set_window
; /* "wi" (4 params, start and end of window,
276 each as vpos and hpos) */
278 /* Value of the "NC" (no_color_video) capability, or 0 if not
281 static int TN_no_color_video
;
283 /* Meaning of bits in no_color_video. Each bit set means that the
284 corresponding attribute cannot be combined with colors. */
288 NC_STANDOUT
= 1 << 0,
289 NC_UNDERLINE
= 1 << 1,
296 NC_ALT_CHARSET
= 1 << 8
299 /* "md" -- turn on bold (extra bright mode). */
301 char *TS_enter_bold_mode
;
303 /* "mh" -- turn on half-bright mode. */
305 char *TS_enter_dim_mode
;
307 /* "mb" -- enter blinking mode. */
309 char *TS_enter_blink_mode
;
311 /* "mr" -- enter reverse video mode. */
313 char *TS_enter_reverse_mode
;
315 /* "us"/"ue" -- start/end underlining. */
317 char *TS_exit_underline_mode
, *TS_enter_underline_mode
;
319 /* "as"/"ae" -- start/end alternate character set. Not really
322 char *TS_enter_alt_charset_mode
, *TS_exit_alt_charset_mode
;
324 /* "me" -- switch appearances off. */
326 char *TS_exit_attribute_mode
;
328 /* "Co" -- number of colors. */
332 /* "pa" -- max. number of color pairs on screen. Not handled yet.
333 Could be a problem if not equal to TN_max_colors * TN_max_colors. */
337 /* "op" -- SVr4 set default pair to its original value. */
341 /* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
342 1 param, the color index. */
344 char *TS_set_foreground
, *TS_set_background
;
346 int TF_hazeltine
; /* termcap hz flag. */
347 int TF_insmode_motion
; /* termcap mi flag: can move while in insert mode. */
348 int TF_standout_motion
; /* termcap mi flag: can move while in standout mode. */
349 int TF_underscore
; /* termcap ul flag: _ underlines if over-struck on
350 non-blank position. Must clear before writing _. */
351 int TF_teleray
; /* termcap xt flag: many weird consequences.
354 static int RPov
; /* # chars to start a TS_repeat */
356 static int delete_in_insert_mode
; /* delete mode == insert mode */
358 static int se_is_so
; /* 1 if same string both enters and leaves
363 /* The largest frame width in any call to calculate_costs. */
367 /* The largest frame height in any call to calculate_costs. */
371 static int costs_set
; /* Nonzero if costs have been calculated. */
373 int insert_mode
; /* Nonzero when in insert mode. */
374 int standout_mode
; /* Nonzero when in standout mode. */
376 /* Size of window specified by higher levels.
377 This is the number of lines, from the top of frame downwards,
378 which can participate in insert-line/delete-line operations.
380 Effectively it excludes the bottom frame_lines - specified_window_size
381 lines from those operations. */
383 int specified_window
;
385 /* Frame currently being redisplayed; 0 if not currently redisplaying.
386 (Direct output does not count). */
388 FRAME_PTR updating_frame
;
390 /* Provided for lisp packages. */
392 static int system_uses_terminfo
;
394 /* Flag used in tty_show/hide_cursor. */
396 static int tty_cursor_hidden
;
400 extern char *tgetstr ();
402 static void term_clear_mouse_face ();
403 static void term_mouse_highlight (struct frame
*f
, int x
, int y
);
407 /* We aren't X windows, but we aren't termcap either. This makes me
408 uncertain as to what value to use for frame.output_method. For
409 this file, we'll define FRAME_TERMCAP_P to be zero so that our
410 output hooks get called instead of the termcap functions. Probably
411 the best long-term solution is to define an output_windows_nt... */
413 #undef FRAME_TERMCAP_P
414 #define FRAME_TERMCAP_P(_f_) 0
415 #endif /* WINDOWSNT */
418 #include <sys/fcntl.h>
421 /* Nonzero means mouse is enabled on Linux console. */
424 /* These variables describe the range of text currently shown in its
425 mouse-face, together with the window they apply to. As long as
426 the mouse stays within this range, we need not redraw anything on
427 its account. Rows and columns are glyph matrix positions in
428 MOUSE_FACE_WINDOW. */
429 static int mouse_face_beg_row
, mouse_face_beg_col
;
430 static int mouse_face_end_row
, mouse_face_end_col
;
431 static int mouse_face_past_end
;
432 static Lisp_Object Qmouse_face_window
;
433 static int mouse_face_face_id
;
435 static int pos_x
, pos_y
;
436 static int last_mouse_x
, last_mouse_y
;
437 #endif /* HAVE_GPM */
442 if (!NILP (Vring_bell_function
))
444 Lisp_Object function
;
446 /* Temporarily set the global variable to nil
447 so that if we get an error, it stays nil
448 and we don't call it over and over.
450 We don't specbind it, because that would carefully
451 restore the bad value if there's an error
452 and make the loop of errors happen anyway. */
454 function
= Vring_bell_function
;
455 Vring_bell_function
= Qnil
;
459 Vring_bell_function
= function
;
461 else if (!FRAME_TERMCAP_P (XFRAME (selected_frame
)))
462 (*ring_bell_hook
) ();
464 OUTPUT (TS_visible_bell
&& visible_bell
? TS_visible_bell
: TS_bell
);
468 set_terminal_modes ()
470 if (FRAME_TERMCAP_P (XFRAME (selected_frame
)))
472 if (TS_termcap_modes
)
473 OUTPUT (TS_termcap_modes
);
476 /* Output enough newlines to scroll all the old screen contents
477 off the screen, so it won't be overwritten and lost. */
479 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
483 OUTPUT_IF (visible_cursor
? TS_cursor_visible
: TS_cursor_normal
);
484 OUTPUT_IF (TS_keypad_mode
);
488 (*set_terminal_modes_hook
) ();
492 reset_terminal_modes ()
494 if (FRAME_TERMCAP_P (XFRAME (selected_frame
)))
496 turn_off_highlight ();
498 OUTPUT_IF (TS_end_keypad_mode
);
499 OUTPUT_IF (TS_cursor_normal
);
500 OUTPUT_IF (TS_end_termcap_modes
);
501 OUTPUT_IF (TS_orig_pair
);
502 /* Output raw CR so kernel can track the cursor hpos. */
505 else if (reset_terminal_modes_hook
)
506 (*reset_terminal_modes_hook
) ();
514 if (!FRAME_TERMCAP_P (f
))
515 update_begin_hook (f
);
522 if (FRAME_TERMCAP_P (f
))
524 if (!XWINDOW (selected_window
)->cursor_off_p
)
527 background_highlight ();
532 updating_frame
= NULL
;
536 set_terminal_window (size
)
539 if (FRAME_TERMCAP_P (updating_frame
))
541 specified_window
= size
? size
: FRAME_LINES (updating_frame
);
542 if (scroll_region_ok
)
543 set_scroll_region (0, specified_window
);
546 set_terminal_window_hook (size
);
550 set_scroll_region (start
, stop
)
554 struct frame
*sf
= XFRAME (selected_frame
);
556 if (TS_set_scroll_region
)
557 buf
= tparam (TS_set_scroll_region
, 0, 0, start
, stop
- 1);
558 else if (TS_set_scroll_region_1
)
559 buf
= tparam (TS_set_scroll_region_1
, 0, 0,
560 FRAME_LINES (sf
), start
,
561 FRAME_LINES (sf
) - stop
,
564 buf
= tparam (TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (sf
));
576 OUTPUT (TS_insert_mode
);
584 OUTPUT (TS_end_insert_mode
);
588 /* Handle highlighting. */
591 turn_off_highlight ()
594 OUTPUT_IF (TS_end_standout_mode
);
602 OUTPUT_IF (TS_standout_mode
);
610 turn_off_highlight ();
612 turn_on_highlight ();
616 /* Make cursor invisible. */
621 if (tty_cursor_hidden
== 0)
623 tty_cursor_hidden
= 1;
624 OUTPUT_IF (TS_cursor_invisible
);
629 /* Ensure that cursor is visible. */
634 if (tty_cursor_hidden
)
636 tty_cursor_hidden
= 0;
637 OUTPUT_IF (TS_cursor_normal
);
639 OUTPUT_IF (TS_cursor_visible
);
644 /* Set standout mode to the state it should be in for
645 empty space inside windows. What this is,
646 depends on the user option inverse-video. */
649 background_highlight ()
652 turn_on_highlight ();
654 turn_off_highlight ();
657 /* Set standout mode to the mode specified for the text to be output. */
660 highlight_if_desired ()
663 turn_on_highlight ();
665 turn_off_highlight ();
669 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
670 frame-relative coordinates. */
673 cursor_to (vpos
, hpos
)
676 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
678 if (! FRAME_TERMCAP_P (f
) && cursor_to_hook
)
680 (*cursor_to_hook
) (vpos
, hpos
);
684 /* Detect the case where we are called from reset_sys_modes
685 and the costs have never been calculated. Do nothing. */
689 if (curY
== vpos
&& curX
== hpos
)
691 if (!TF_standout_motion
)
692 background_highlight ();
693 if (!TF_insmode_motion
)
698 /* Similar but don't take any account of the wasted characters. */
701 raw_cursor_to (row
, col
)
704 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
705 if (! FRAME_TERMCAP_P (f
))
707 (*raw_cursor_to_hook
) (row
, col
);
710 if (curY
== row
&& curX
== col
)
712 if (!TF_standout_motion
)
713 background_highlight ();
714 if (!TF_insmode_motion
)
719 /* Erase operations */
721 /* clear from cursor to end of frame */
727 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
729 (*clear_to_end_hook
) ();
732 if (TS_clr_to_bottom
)
734 background_highlight ();
735 OUTPUT (TS_clr_to_bottom
);
739 for (i
= curY
; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
742 clear_end_of_line (FRAME_COLS (XFRAME (selected_frame
)));
747 /* Clear entire frame */
752 struct frame
*sf
= XFRAME (selected_frame
);
755 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: sf
)))
757 (*clear_frame_hook
) ();
762 background_highlight ();
763 OUTPUT (TS_clr_frame
);
773 /* Clear from cursor to end of line.
774 Assume that the line is already clear starting at column first_unused_hpos.
776 Note that the cursor may be moved, on terminals lacking a `ce' string. */
779 clear_end_of_line (first_unused_hpos
)
780 int first_unused_hpos
;
784 if (clear_end_of_line_hook
785 && ! FRAME_TERMCAP_P ((updating_frame
787 : XFRAME (selected_frame
))))
789 (*clear_end_of_line_hook
) (first_unused_hpos
);
793 /* Detect the case where we are called from reset_sys_modes
794 and the costs have never been calculated. Do nothing. */
798 if (curX
>= first_unused_hpos
)
800 background_highlight ();
803 OUTPUT1 (TS_clr_line
);
806 { /* have to do it the hard way */
807 struct frame
*sf
= XFRAME (selected_frame
);
810 /* Do not write in last row last col with Auto-wrap on. */
811 if (AutoWrap
&& curY
== FRAME_LINES (sf
) - 1
812 && first_unused_hpos
== FRAME_COLS (sf
))
815 for (i
= curX
; i
< first_unused_hpos
; i
++)
818 fputc (' ', termscript
);
821 cmplus (first_unused_hpos
- curX
);
825 /* Buffer to store the source and result of code conversion for terminal. */
826 static unsigned char *encode_terminal_buf
;
827 /* Allocated size of the above buffer. */
828 static int encode_terminal_bufsize
;
830 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
831 Set CODING->produced to the byte-length of the resulting byte
832 sequence, and return a pointer to that byte sequence. */
835 encode_terminal_code (src
, src_len
, coding
)
838 struct coding_system
*coding
;
840 struct glyph
*src_end
= src
+ src_len
;
843 int nchars
, nbytes
, required
;
844 register int tlen
= GLYPH_TABLE_LENGTH
;
845 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
847 /* Allocate sufficient size of buffer to store all characters in
848 multibyte-form. But, it may be enlarged on demand if
849 Vglyph_table contains a string. */
850 required
= MAX_MULTIBYTE_LENGTH
* src_len
;
851 if (encode_terminal_bufsize
< required
)
853 if (encode_terminal_bufsize
== 0)
854 encode_terminal_buf
= xmalloc (required
);
856 encode_terminal_buf
= xrealloc (encode_terminal_buf
, required
);
857 encode_terminal_bufsize
= required
;
860 buf
= encode_terminal_buf
;
862 while (src
< src_end
)
864 /* We must skip glyphs to be padded for a wide character. */
865 if (! CHAR_GLYPH_PADDING_P (*src
))
867 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
869 if (g
< 0 || g
>= tlen
)
871 /* This glyph doesn't has an entry in Vglyph_table. */
872 if (CHAR_VALID_P (src
->u
.ch
, 0))
873 buf
+= CHAR_STRING (src
->u
.ch
, buf
);
880 /* This glyph has an entry in Vglyph_table,
881 so process any alias before testing for simpleness. */
882 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
884 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
886 int c
= FAST_GLYPH_CHAR (g
);
888 if (CHAR_VALID_P (c
, 0))
889 buf
+= CHAR_STRING (c
, buf
);
896 /* We have a string in Vglyph_table. */
900 if (! STRING_MULTIBYTE (string
))
901 string
= string_to_multibyte (string
);
902 nbytes
= buf
- encode_terminal_buf
;
903 if (encode_terminal_bufsize
< nbytes
+ SBYTES (string
))
905 encode_terminal_bufsize
= nbytes
+ SBYTES (string
);
906 encode_terminal_buf
= xrealloc (encode_terminal_buf
,
907 encode_terminal_bufsize
);
908 buf
= encode_terminal_buf
+ nbytes
;
910 bcopy (SDATA (string
), buf
, SBYTES (string
));
911 buf
+= SBYTES (string
);
912 nchars
+= SCHARS (string
);
919 nbytes
= buf
- encode_terminal_buf
;
920 coding
->src_multibyte
= 1;
921 coding
->dst_multibyte
= 0;
922 if (SYMBOLP (coding
->pre_write_conversion
)
923 && ! NILP (Ffboundp (coding
->pre_write_conversion
)))
925 run_pre_write_conversin_on_c_str (&encode_terminal_buf
,
926 &encode_terminal_bufsize
,
927 nchars
, nbytes
, coding
);
928 nchars
= coding
->produced_char
;
929 nbytes
= coding
->produced
;
931 required
= nbytes
+ encoding_buffer_size (coding
, nbytes
);
932 if (encode_terminal_bufsize
< required
)
934 encode_terminal_bufsize
= required
;
935 encode_terminal_buf
= xrealloc (encode_terminal_buf
, required
);
938 encode_coding (coding
, encode_terminal_buf
, encode_terminal_buf
+ nbytes
,
939 nbytes
, encode_terminal_bufsize
- nbytes
);
940 return encode_terminal_buf
+ nbytes
;
944 write_glyphs (string
, len
)
945 register struct glyph
*string
;
948 struct frame
*sf
= XFRAME (selected_frame
);
949 struct frame
*f
= updating_frame
? updating_frame
: sf
;
950 unsigned char *conversion_buffer
;
951 struct coding_system
*coding
;
953 if (write_glyphs_hook
954 && ! FRAME_TERMCAP_P (f
))
956 (*write_glyphs_hook
) (string
, len
);
963 /* Don't dare write in last column of bottom line, if Auto-Wrap,
964 since that would scroll the whole frame on some terminals. */
967 && curY
+ 1 == FRAME_LINES (sf
)
968 && (curX
+ len
) == FRAME_COLS (sf
))
975 /* If terminal_coding does any conversion, use it, otherwise use
976 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
977 because it always return 1 if the member src_multibyte is 1. */
978 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
979 ? &terminal_coding
: &safe_terminal_coding
);
980 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
982 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
986 /* Identify a run of glyphs with the same face. */
987 int face_id
= string
->face_id
;
990 for (n
= 1; n
< len
; ++n
)
991 if (string
[n
].face_id
!= face_id
)
994 /* Turn appearance modes of the face of the run on. */
995 highlight_if_desired ();
996 turn_on_face (f
, face_id
);
999 /* This is the last run. */
1000 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
1001 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
1002 if (coding
->produced
> 0)
1005 fwrite (conversion_buffer
, 1, coding
->produced
, stdout
);
1006 if (ferror (stdout
))
1009 fwrite (conversion_buffer
, 1, coding
->produced
, termscript
);
1015 /* Turn appearance modes off. */
1016 turn_off_face (f
, face_id
);
1017 turn_off_highlight ();
1024 write_glyphs_with_face (string
, len
, face_id
)
1025 register struct glyph
*string
;
1026 register int len
, face_id
;
1028 struct frame
*sf
= XFRAME (selected_frame
);
1029 struct frame
*f
= updating_frame
? updating_frame
: sf
;
1030 unsigned char *conversion_buffer
;
1031 struct coding_system
*coding
;
1036 /* Don't dare write in last column of bottom line, if Auto-Wrap,
1037 since that would scroll the whole frame on some terminals. */
1040 && curY
+ 1 == FRAME_LINES (sf
)
1041 && (curX
+ len
) == FRAME_COLS (sf
))
1048 /* If terminal_coding does any conversion, use it, otherwise use
1049 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
1050 because it always return 1 if the member src_multibyte is 1. */
1051 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
1052 ? &terminal_coding
: &safe_terminal_coding
);
1053 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1055 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
1058 /* Turn appearance modes of the face. */
1059 highlight_if_desired ();
1060 turn_on_face (f
, face_id
);
1062 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
1063 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
1064 if (coding
->produced
> 0)
1067 fwrite (conversion_buffer
, 1, coding
->produced
, stdout
);
1068 if (ferror (stdout
))
1071 fwrite (conversion_buffer
, 1, coding
->produced
, termscript
);
1075 /* Turn appearance modes off. */
1076 turn_off_face (f
, face_id
);
1077 turn_off_highlight ();
1082 /* If start is zero, insert blanks instead of a string at start */
1085 insert_glyphs (start
, len
)
1086 register struct glyph
*start
;
1090 struct glyph
*glyph
= NULL
;
1091 struct frame
*f
, *sf
;
1092 unsigned char *conversion_buffer
;
1093 unsigned char space
[1];
1094 struct coding_system
*coding
;
1099 if (insert_glyphs_hook
)
1101 (*insert_glyphs_hook
) (start
, len
);
1105 sf
= XFRAME (selected_frame
);
1106 f
= updating_frame
? updating_frame
: sf
;
1108 if (TS_ins_multi_chars
)
1110 buf
= tparam (TS_ins_multi_chars
, 0, 0, len
);
1114 write_glyphs (start
, len
);
1122 space
[0] = SPACEGLYPH
;
1124 /* If terminal_coding does any conversion, use it, otherwise use
1125 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
1126 because it always return 1 if the member src_multibyte is 1. */
1127 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
1128 ? &terminal_coding
: &safe_terminal_coding
);
1129 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1131 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
1135 OUTPUT1_IF (TS_ins_char
);
1138 conversion_buffer
= space
;
1139 coding
->produced
= 1;
1143 highlight_if_desired ();
1144 turn_on_face (f
, start
->face_id
);
1147 /* We must open sufficient space for a character which
1148 occupies more than one column. */
1149 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
1151 OUTPUT1_IF (TS_ins_char
);
1156 /* This is the last glyph. */
1157 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
1159 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
1162 if (coding
->produced
> 0)
1165 fwrite (conversion_buffer
, 1, coding
->produced
, stdout
);
1166 if (ferror (stdout
))
1169 fwrite (conversion_buffer
, 1, coding
->produced
, termscript
);
1173 OUTPUT1_IF (TS_pad_inserted_char
);
1176 turn_off_face (f
, glyph
->face_id
);
1177 turn_off_highlight ();
1191 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1193 (*delete_glyphs_hook
) (n
);
1197 if (delete_in_insert_mode
)
1204 OUTPUT_IF (TS_delete_mode
);
1207 if (TS_del_multi_chars
)
1209 buf
= tparam (TS_del_multi_chars
, 0, 0, n
);
1214 for (i
= 0; i
< n
; i
++)
1215 OUTPUT1 (TS_del_char
);
1216 if (!delete_in_insert_mode
)
1217 OUTPUT_IF (TS_end_delete_mode
);
1220 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1223 ins_del_lines (vpos
, n
)
1226 char *multi
= n
> 0 ? TS_ins_multi_lines
: TS_del_multi_lines
;
1227 char *single
= n
> 0 ? TS_ins_line
: TS_del_line
;
1228 char *scroll
= n
> 0 ? TS_rev_scroll
: TS_fwd_scroll
;
1231 register int i
= n
> 0 ? n
: -n
;
1234 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1236 (*ins_del_lines_hook
) (vpos
, n
);
1240 sf
= XFRAME (selected_frame
);
1242 /* If the lines below the insertion are being pushed
1243 into the end of the window, this is the same as clearing;
1244 and we know the lines are already clear, since the matching
1245 deletion has already been done. So can ignore this. */
1246 /* If the lines below the deletion are blank lines coming
1247 out of the end of the window, don't bother,
1248 as there will be a matching inslines later that will flush them. */
1249 if (scroll_region_ok
&& vpos
+ i
>= specified_window
)
1251 if (!memory_below_frame
&& vpos
+ i
>= FRAME_LINES (sf
))
1256 raw_cursor_to (vpos
, 0);
1257 background_highlight ();
1258 buf
= tparam (multi
, 0, 0, i
);
1264 raw_cursor_to (vpos
, 0);
1265 background_highlight ();
1273 set_scroll_region (vpos
, specified_window
);
1275 raw_cursor_to (specified_window
- 1, 0);
1277 raw_cursor_to (vpos
, 0);
1278 background_highlight ();
1280 OUTPUTL (scroll
, specified_window
- vpos
);
1281 set_scroll_region (0, specified_window
);
1284 if (!scroll_region_ok
&& memory_below_frame
&& n
< 0)
1286 cursor_to (FRAME_LINES (sf
) + n
, 0);
1291 /* Compute cost of sending "str", in characters,
1292 not counting any line-dependent padding. */
1300 tputs (str
, 0, evalcost
);
1304 /* Compute cost of sending "str", in characters,
1305 counting any line-dependent padding at one line. */
1308 string_cost_one_line (str
)
1313 tputs (str
, 1, evalcost
);
1317 /* Compute per line amount of line-dependent padding,
1318 in tenths of characters. */
1326 tputs (str
, 0, evalcost
);
1329 tputs (str
, 10, evalcost
);
1334 /* char_ins_del_cost[n] is cost of inserting N characters.
1335 char_ins_del_cost[-n] is cost of deleting N characters.
1336 The length of this vector is based on max_frame_cols. */
1338 int *char_ins_del_vector
;
1340 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1345 calculate_ins_del_char_costs (frame
)
1348 int ins_startup_cost
, del_startup_cost
;
1349 int ins_cost_per_char
, del_cost_per_char
;
1353 if (TS_ins_multi_chars
)
1355 ins_cost_per_char
= 0;
1356 ins_startup_cost
= string_cost_one_line (TS_ins_multi_chars
);
1358 else if (TS_ins_char
|| TS_pad_inserted_char
1359 || (TS_insert_mode
&& TS_end_insert_mode
))
1361 ins_startup_cost
= (30 * (string_cost (TS_insert_mode
)
1362 + string_cost (TS_end_insert_mode
))) / 100;
1363 ins_cost_per_char
= (string_cost_one_line (TS_ins_char
)
1364 + string_cost_one_line (TS_pad_inserted_char
));
1368 ins_startup_cost
= 9999;
1369 ins_cost_per_char
= 0;
1372 if (TS_del_multi_chars
)
1374 del_cost_per_char
= 0;
1375 del_startup_cost
= string_cost_one_line (TS_del_multi_chars
);
1377 else if (TS_del_char
)
1379 del_startup_cost
= (string_cost (TS_delete_mode
)
1380 + string_cost (TS_end_delete_mode
));
1381 if (delete_in_insert_mode
)
1382 del_startup_cost
/= 2;
1383 del_cost_per_char
= string_cost_one_line (TS_del_char
);
1387 del_startup_cost
= 9999;
1388 del_cost_per_char
= 0;
1391 /* Delete costs are at negative offsets */
1392 p
= &char_ins_del_cost (frame
)[0];
1393 for (i
= FRAME_COLS (frame
); --i
>= 0;)
1394 *--p
= (del_startup_cost
+= del_cost_per_char
);
1396 /* Doing nothing is free */
1397 p
= &char_ins_del_cost (frame
)[0];
1400 /* Insert costs are at positive offsets */
1401 for (i
= FRAME_COLS (frame
); --i
>= 0;)
1402 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1406 calculate_costs (frame
)
1409 register char *f
= (TS_set_scroll_region
1410 ? TS_set_scroll_region
1411 : TS_set_scroll_region_1
);
1413 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1415 scroll_region_cost
= string_cost (f
);
1417 /* These variables are only used for terminal stuff. They are allocated
1418 once for the terminal frame of X-windows emacs, but not used afterwards.
1420 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1421 X turns off char_ins_del_ok. */
1423 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1424 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1428 if (char_ins_del_vector
!= 0)
1430 = (int *) xrealloc (char_ins_del_vector
,
1432 + 2 * max_frame_cols
* sizeof (int)));
1435 = (int *) xmalloc (sizeof (int)
1436 + 2 * max_frame_cols
* sizeof (int));
1438 bzero (char_ins_del_vector
, (sizeof (int)
1439 + 2 * max_frame_cols
* sizeof (int)));
1441 if (f
&& (!TS_ins_line
&& !TS_del_line
))
1442 do_line_insertion_deletion_costs (frame
,
1443 TS_rev_scroll
, TS_ins_multi_lines
,
1444 TS_fwd_scroll
, TS_del_multi_lines
,
1447 do_line_insertion_deletion_costs (frame
,
1448 TS_ins_line
, TS_ins_multi_lines
,
1449 TS_del_line
, TS_del_multi_lines
,
1452 calculate_ins_del_char_costs (frame
);
1454 /* Don't use TS_repeat if its padding is worse than sending the chars */
1455 if (TS_repeat
&& per_line_cost (TS_repeat
) * baud_rate
< 9000)
1456 RPov
= string_cost (TS_repeat
);
1458 RPov
= FRAME_COLS (frame
) * 2;
1460 cmcostinit (); /* set up cursor motion costs */
1467 /* Termcap capability names that correspond directly to X keysyms.
1468 Some of these (marked "terminfo") aren't supplied by old-style
1469 (Berkeley) termcap entries. They're listed in X keysym order;
1470 except we put the keypad keys first, so that if they clash with
1471 other keys (as on the IBM PC keyboard) they get overridden.
1474 static struct fkey_table keys
[] =
1476 {"kh", "home"}, /* termcap */
1477 {"kl", "left"}, /* termcap */
1478 {"ku", "up"}, /* termcap */
1479 {"kr", "right"}, /* termcap */
1480 {"kd", "down"}, /* termcap */
1481 {"%8", "prior"}, /* terminfo */
1482 {"%5", "next"}, /* terminfo */
1483 {"@7", "end"}, /* terminfo */
1484 {"@1", "begin"}, /* terminfo */
1485 {"*6", "select"}, /* terminfo */
1486 {"%9", "print"}, /* terminfo */
1487 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1489 * "insert" --- see below
1491 {"&8", "undo"}, /* terminfo */
1492 {"%0", "redo"}, /* terminfo */
1493 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1494 {"@0", "find"}, /* terminfo */
1495 {"@2", "cancel"}, /* terminfo */
1496 {"%1", "help"}, /* terminfo */
1498 * "break" goes here, but can't be reliably intercepted with termcap
1500 {"&4", "reset"}, /* terminfo --- actually `restart' */
1502 * "system" and "user" --- no termcaps
1504 {"kE", "clearline"}, /* terminfo */
1505 {"kA", "insertline"}, /* terminfo */
1506 {"kL", "deleteline"}, /* terminfo */
1507 {"kI", "insertchar"}, /* terminfo */
1508 {"kD", "deletechar"}, /* terminfo */
1509 {"kB", "backtab"}, /* terminfo */
1511 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1513 {"@8", "kp-enter"}, /* terminfo */
1515 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1516 * "kp-multiply", "kp-add", "kp-separator",
1517 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1518 * --- no termcaps for any of these.
1520 {"K4", "kp-1"}, /* terminfo */
1522 * "kp-2" --- no termcap
1524 {"K5", "kp-3"}, /* terminfo */
1526 * "kp-4" --- no termcap
1528 {"K2", "kp-5"}, /* terminfo */
1530 * "kp-6" --- no termcap
1532 {"K1", "kp-7"}, /* terminfo */
1534 * "kp-8" --- no termcap
1536 {"K3", "kp-9"}, /* terminfo */
1538 * "kp-equal" --- no termcap
1550 {"&0", "S-cancel"}, /*shifted cancel key*/
1551 {"&9", "S-begin"}, /*shifted begin key*/
1552 {"*0", "S-find"}, /*shifted find key*/
1553 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1554 {"*4", "S-delete"}, /*shifted delete-character key*/
1555 {"*7", "S-end"}, /*shifted end key*/
1556 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1557 {"#1", "S-help"}, /*shifted help key*/
1558 {"#2", "S-home"}, /*shifted home key*/
1559 {"#3", "S-insert"}, /*shifted insert-character key*/
1560 {"#4", "S-left"}, /*shifted left-arrow key*/
1561 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1562 {"%c", "S-next"}, /*shifted next key*/
1563 {"%e", "S-prior"}, /*shifted previous key*/
1564 {"%f", "S-print"}, /*shifted print key*/
1565 {"%g", "S-redo"}, /*shifted redo key*/
1566 {"%i", "S-right"}, /*shifted right-arrow key*/
1567 {"!3", "S-undo"} /*shifted undo key*/
1570 static char **term_get_fkeys_arg
;
1571 static Lisp_Object
term_get_fkeys_1 ();
1573 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1574 This function scans the termcap function key sequence entries, and
1575 adds entries to Vfunction_key_map for each function key it finds. */
1578 term_get_fkeys (address
)
1581 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1582 errors during the call. The only errors should be from Fdefine_key
1583 when given a key sequence containing an invalid prefix key. If the
1584 termcap defines function keys which use a prefix that is already bound
1585 to a command by the default bindings, we should silently ignore that
1586 function key specification, rather than giving the user an error and
1587 refusing to run at all on such a terminal. */
1589 extern Lisp_Object
Fidentity ();
1590 term_get_fkeys_arg
= address
;
1591 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1599 char **address
= term_get_fkeys_arg
;
1601 /* This can happen if CANNOT_DUMP or with strange options. */
1603 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1605 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1607 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1609 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1610 Fmake_vector (make_number (1),
1611 intern (keys
[i
].name
)));
1614 /* The uses of the "k0" capability are inconsistent; sometimes it
1615 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1616 We will attempt to politely accommodate both systems by testing for
1617 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1620 char *k_semi
= tgetstr ("k;", address
);
1621 char *k0
= tgetstr ("k0", address
);
1622 char *k0_name
= "f10";
1627 /* Define f0 first, so that f10 takes precedence in case the
1628 key sequences happens to be the same. */
1629 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1630 Fmake_vector (make_number (1), intern ("f0")));
1631 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1632 Fmake_vector (make_number (1), intern ("f10")));
1635 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1636 Fmake_vector (make_number (1), intern (k0_name
)));
1639 /* Set up cookies for numbered function keys above f10. */
1641 char fcap
[3], fkey
[4];
1643 fcap
[0] = 'F'; fcap
[2] = '\0';
1644 for (i
= 11; i
< 64; i
++)
1647 fcap
[1] = '1' + i
- 11;
1649 fcap
[1] = 'A' + i
- 20;
1651 fcap
[1] = 'a' + i
- 46;
1654 char *sequence
= tgetstr (fcap
, address
);
1657 sprintf (fkey
, "f%d", i
);
1658 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1659 Fmake_vector (make_number (1),
1667 * Various mappings to try and get a better fit.
1670 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1671 if (!tgetstr (cap1, address)) \
1673 char *sequence = tgetstr (cap2, address); \
1675 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1676 Fmake_vector (make_number (1), \
1680 /* if there's no key_next keycap, map key_npage to `next' keysym */
1681 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1682 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1683 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1684 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1685 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1686 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1687 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1689 /* IBM has their own non-standard dialect of terminfo.
1690 If the standard name isn't found, try the IBM name. */
1691 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1692 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1693 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1694 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1695 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1696 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1697 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1698 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1699 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1700 #undef CONDITIONAL_REASSIGN
1707 /***********************************************************************
1708 Character Display Information
1709 ***********************************************************************/
1711 /* Avoid name clash with functions defined in xterm.c */
1713 #define append_glyph append_glyph_term
1714 #define produce_stretch_glyph produce_stretch_glyph_term
1717 static void append_glyph
P_ ((struct it
*));
1718 static void produce_stretch_glyph
P_ ((struct it
*));
1721 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1722 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1723 the character for which to produce glyphs; IT->face_id contains the
1724 character's face. Padding glyphs are appended if IT->c has a
1725 IT->pixel_width > 1. */
1731 struct glyph
*glyph
, *end
;
1734 xassert (it
->glyph_row
);
1735 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1736 + it
->glyph_row
->used
[it
->area
]);
1737 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1740 i
< it
->pixel_width
&& glyph
< end
;
1743 glyph
->type
= CHAR_GLYPH
;
1744 glyph
->pixel_width
= 1;
1745 glyph
->u
.ch
= it
->char_to_display
;
1746 glyph
->face_id
= it
->face_id
;
1747 glyph
->padding_p
= i
> 0;
1748 glyph
->charpos
= CHARPOS (it
->position
);
1749 glyph
->object
= it
->object
;
1751 ++it
->glyph_row
->used
[it
->area
];
1757 /* Produce glyphs for the display element described by IT. *IT
1758 specifies what we want to produce a glyph for (character, image, ...),
1759 and where in the glyph matrix we currently are (glyph row and hpos).
1760 produce_glyphs fills in output fields of *IT with information such as the
1761 pixel width and height of a character, and maybe output actual glyphs at
1762 the same time if IT->glyph_row is non-null. See the explanation of
1763 struct display_iterator in dispextern.h for an overview.
1765 produce_glyphs also stores the result of glyph width, ascent
1766 etc. computations in *IT.
1768 IT->glyph_row may be null, in which case produce_glyphs does not
1769 actually fill in the glyphs. This is used in the move_* functions
1770 in xdisp.c for text width and height computations.
1772 Callers usually don't call produce_glyphs directly;
1773 instead they use the macro PRODUCE_GLYPHS. */
1779 /* If a hook is installed, let it do the work. */
1780 xassert (it
->what
== IT_CHARACTER
1781 || it
->what
== IT_COMPOSITION
1782 || it
->what
== IT_STRETCH
);
1784 if (it
->what
== IT_STRETCH
)
1786 produce_stretch_glyph (it
);
1790 /* Nothing but characters are supported on terminal frames. For a
1791 composition sequence, it->c is the first character of the
1793 xassert (it
->what
== IT_CHARACTER
1794 || it
->what
== IT_COMPOSITION
);
1796 /* Maybe translate single-byte characters to multibyte. */
1797 it
->char_to_display
= it
->c
;
1799 if (it
->c
>= 040 && it
->c
< 0177)
1801 it
->pixel_width
= it
->nglyphs
= 1;
1805 else if (it
->c
== '\n')
1806 it
->pixel_width
= it
->nglyphs
= 0;
1807 else if (it
->c
== '\t')
1809 int absolute_x
= (it
->current_x
1810 + it
->continuation_lines_width
);
1812 = (((1 + absolute_x
+ it
->tab_width
- 1)
1817 /* If part of the TAB has been displayed on the previous line
1818 which is continued now, continuation_lines_width will have
1819 been incremented already by the part that fitted on the
1820 continued line. So, we will get the right number of spaces
1822 nspaces
= next_tab_x
- absolute_x
;
1828 it
->char_to_display
= ' ';
1829 it
->pixel_width
= it
->len
= 1;
1835 it
->pixel_width
= nspaces
;
1836 it
->nglyphs
= nspaces
;
1838 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1840 if (unibyte_display_via_language_environment
1842 || !NILP (Vnonascii_translation_table
)))
1846 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1847 charset
= CHAR_CHARSET (it
->char_to_display
);
1848 it
->pixel_width
= CHARSET_WIDTH (charset
);
1849 it
->nglyphs
= it
->pixel_width
;
1855 /* Coming here means that it->c is from display table, thus we
1856 must send the code as is to the terminal. Although there's
1857 no way to know how many columns it occupies on a screen, it
1858 is a good assumption that a single byte code has 1-column
1860 it
->pixel_width
= it
->nglyphs
= 1;
1867 /* A multi-byte character. The display width is fixed for all
1868 characters of the set. Some of the glyphs may have to be
1869 ignored because they are already displayed in a continued
1871 int charset
= CHAR_CHARSET (it
->c
);
1873 it
->pixel_width
= CHARSET_WIDTH (charset
);
1874 it
->nglyphs
= it
->pixel_width
;
1881 /* Advance current_x by the pixel width as a convenience for
1883 if (it
->area
== TEXT_AREA
)
1884 it
->current_x
+= it
->pixel_width
;
1885 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1886 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1890 /* Produce a stretch glyph for iterator IT. IT->object is the value
1891 of the glyph property displayed. The value must be a list
1892 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1895 1. `:width WIDTH' specifies that the space should be WIDTH *
1896 canonical char width wide. WIDTH may be an integer or floating
1899 2. `:align-to HPOS' specifies that the space should be wide enough
1900 to reach HPOS, a value in canonical character units. */
1903 produce_stretch_glyph (it
)
1906 /* (space :width WIDTH ...) */
1907 Lisp_Object prop
, plist
;
1908 int width
= 0, align_to
= -1;
1909 int zero_width_ok_p
= 0;
1912 /* List should start with `space'. */
1913 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1914 plist
= XCDR (it
->object
);
1916 /* Compute the width of the stretch. */
1917 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1918 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1920 /* Absolute width `:width WIDTH' specified and valid. */
1921 zero_width_ok_p
= 1;
1922 width
= (int)(tem
+ 0.5);
1924 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1925 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1927 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1928 align_to
= (align_to
< 0
1930 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1931 else if (align_to
< 0)
1932 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1933 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1934 zero_width_ok_p
= 1;
1937 /* Nothing specified -> width defaults to canonical char width. */
1938 width
= FRAME_COLUMN_WIDTH (it
->f
);
1940 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1943 if (width
> 0 && it
->glyph_row
)
1945 Lisp_Object o_object
= it
->object
;
1946 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1949 if (!STRINGP (object
))
1950 object
= it
->w
->buffer
;
1951 it
->object
= object
;
1952 it
->char_to_display
= ' ';
1953 it
->pixel_width
= it
->len
= 1;
1956 it
->object
= o_object
;
1958 it
->pixel_width
= width
;
1959 it
->nglyphs
= width
;
1963 /* Get information about special display element WHAT in an
1964 environment described by IT. WHAT is one of IT_TRUNCATION or
1965 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1966 non-null glyph_row member. This function ensures that fields like
1967 face_id, c, len of IT are left untouched. */
1970 produce_special_glyphs (it
, what
)
1972 enum display_element_type what
;
1979 temp_it
.what
= IT_CHARACTER
;
1981 temp_it
.object
= make_number (0);
1982 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1984 if (what
== IT_CONTINUATION
)
1986 /* Continuation glyph. */
1988 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1989 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1991 glyph
= XINT (DISP_CONTINUE_GLYPH (it
->dp
));
1992 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
1997 else if (what
== IT_TRUNCATION
)
1999 /* Truncation glyph. */
2001 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
2002 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
2004 glyph
= XINT (DISP_TRUNC_GLYPH (it
->dp
));
2005 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
2013 temp_it
.c
= FAST_GLYPH_CHAR (glyph
);
2014 temp_it
.face_id
= FAST_GLYPH_FACE (glyph
);
2015 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
2017 produce_glyphs (&temp_it
);
2018 it
->pixel_width
= temp_it
.pixel_width
;
2019 it
->nglyphs
= temp_it
.pixel_width
;
2024 /***********************************************************************
2026 ***********************************************************************/
2028 /* Value is non-zero if attribute ATTR may be used. ATTR should be
2029 one of the enumerators from enum no_color_bit, or a bit set built
2030 from them. Some display attributes may not be used together with
2031 color; the termcap capability `NC' specifies which ones. */
2033 #define MAY_USE_WITH_COLORS_P(ATTR) \
2034 (TN_max_colors > 0 \
2035 ? (TN_no_color_video & (ATTR)) == 0 \
2038 /* Turn appearances of face FACE_ID on tty frame F on.
2039 FACE_ID is a realized face ID number, in the face cache. */
2042 turn_on_face (f
, face_id
)
2046 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2047 long fg
= face
->foreground
;
2048 long bg
= face
->background
;
2050 /* Do this first because TS_end_standout_mode may be the same
2051 as TS_exit_attribute_mode, which turns all appearances off. */
2052 if (MAY_USE_WITH_COLORS_P (NC_REVERSE
))
2054 if (TN_max_colors
> 0)
2056 if (fg
>= 0 && bg
>= 0)
2058 /* If the terminal supports colors, we can set them
2059 below without using reverse video. The face's fg
2060 and bg colors are set as they should appear on
2061 the screen, i.e. they take the inverse-video'ness
2062 of the face already into account. */
2064 else if (inverse_video
)
2066 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
2067 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
2068 toggle_highlight ();
2072 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
2073 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
2074 toggle_highlight ();
2079 /* If we can't display colors, use reverse video
2080 if the face specifies that. */
2083 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
2084 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
2085 toggle_highlight ();
2089 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
2090 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
2091 toggle_highlight ();
2096 if (face
->tty_bold_p
)
2098 if (MAY_USE_WITH_COLORS_P (NC_BOLD
))
2099 OUTPUT1_IF (TS_enter_bold_mode
);
2101 else if (face
->tty_dim_p
)
2102 if (MAY_USE_WITH_COLORS_P (NC_DIM
))
2103 OUTPUT1_IF (TS_enter_dim_mode
);
2105 /* Alternate charset and blinking not yet used. */
2106 if (face
->tty_alt_charset_p
2107 && MAY_USE_WITH_COLORS_P (NC_ALT_CHARSET
))
2108 OUTPUT1_IF (TS_enter_alt_charset_mode
);
2110 if (face
->tty_blinking_p
2111 && MAY_USE_WITH_COLORS_P (NC_BLINK
))
2112 OUTPUT1_IF (TS_enter_blink_mode
);
2114 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (NC_UNDERLINE
))
2115 OUTPUT1_IF (TS_enter_underline_mode
);
2117 if (TN_max_colors
> 0)
2121 ts
= standout_mode
? TS_set_background
: TS_set_foreground
;
2124 p
= tparam (ts
, NULL
, 0, (int) fg
);
2129 ts
= standout_mode
? TS_set_foreground
: TS_set_background
;
2132 p
= tparam (ts
, NULL
, 0, (int) bg
);
2140 /* Turn off appearances of face FACE_ID on tty frame F. */
2143 turn_off_face (f
, face_id
)
2147 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2149 xassert (face
!= NULL
);
2151 if (TS_exit_attribute_mode
)
2153 /* Capability "me" will turn off appearance modes double-bright,
2154 half-bright, reverse-video, standout, underline. It may or
2155 may not turn off alt-char-mode. */
2156 if (face
->tty_bold_p
2158 || face
->tty_reverse_p
2159 || face
->tty_alt_charset_p
2160 || face
->tty_blinking_p
2161 || face
->tty_underline_p
)
2163 OUTPUT1_IF (TS_exit_attribute_mode
);
2164 if (strcmp (TS_exit_attribute_mode
, TS_end_standout_mode
) == 0)
2168 if (face
->tty_alt_charset_p
)
2169 OUTPUT_IF (TS_exit_alt_charset_mode
);
2173 /* If we don't have "me" we can only have those appearances
2174 that have exit sequences defined. */
2175 if (face
->tty_alt_charset_p
)
2176 OUTPUT_IF (TS_exit_alt_charset_mode
);
2178 if (face
->tty_underline_p
)
2179 OUTPUT_IF (TS_exit_underline_mode
);
2182 /* Switch back to default colors. */
2183 if (TN_max_colors
> 0
2184 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2185 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2186 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2187 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2188 OUTPUT1_IF (TS_orig_pair
);
2192 /* Return non-zero if the terminal on frame F supports all of the
2193 capabilities in CAPS simultaneously, with foreground and background
2194 colors FG and BG. */
2197 tty_capable_p (f
, caps
, fg
, bg
)
2200 unsigned long fg
, bg
;
2202 #define TTY_CAPABLE_P_TRY(cap, TS, NC_bit) \
2203 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(NC_bit))) \
2206 TTY_CAPABLE_P_TRY (TTY_CAP_INVERSE
, TS_standout_mode
, NC_REVERSE
);
2207 TTY_CAPABLE_P_TRY (TTY_CAP_UNDERLINE
, TS_enter_underline_mode
, NC_UNDERLINE
);
2208 TTY_CAPABLE_P_TRY (TTY_CAP_BOLD
, TS_enter_bold_mode
, NC_BOLD
);
2209 TTY_CAPABLE_P_TRY (TTY_CAP_DIM
, TS_enter_dim_mode
, NC_DIM
);
2210 TTY_CAPABLE_P_TRY (TTY_CAP_BLINK
, TS_enter_blink_mode
, NC_BLINK
);
2211 TTY_CAPABLE_P_TRY (TTY_CAP_ALT_CHARSET
, TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
2218 /* Return non-zero if the terminal is capable to display colors. */
2220 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2222 doc
: /* Return non-nil if TTY can display colors on DISPLAY. */)
2224 Lisp_Object display
;
2226 return TN_max_colors
> 0 ? Qt
: Qnil
;
2229 /* Return the number of supported colors. */
2230 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2231 Stty_display_color_cells
, 0, 1, 0,
2232 doc
: /* Return the number of colors supported by TTY on DISPLAY. */)
2234 Lisp_Object display
;
2236 return make_number (TN_max_colors
);
2241 /* Save or restore the default color-related capabilities of this
2244 tty_default_color_capabilities (save
)
2248 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
2249 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
2253 if (default_orig_pair
)
2254 xfree (default_orig_pair
);
2255 default_orig_pair
= TS_orig_pair
? xstrdup (TS_orig_pair
) : NULL
;
2257 if (default_set_foreground
)
2258 xfree (default_set_foreground
);
2259 default_set_foreground
= TS_set_foreground
? xstrdup (TS_set_foreground
)
2262 if (default_set_background
)
2263 xfree (default_set_background
);
2264 default_set_background
= TS_set_background
? xstrdup (TS_set_background
)
2267 default_max_colors
= TN_max_colors
;
2268 default_max_pairs
= TN_max_pairs
;
2269 default_no_color_video
= TN_no_color_video
;
2273 TS_orig_pair
= default_orig_pair
;
2274 TS_set_foreground
= default_set_foreground
;
2275 TS_set_background
= default_set_background
;
2276 TN_max_colors
= default_max_colors
;
2277 TN_max_pairs
= default_max_pairs
;
2278 TN_no_color_video
= default_no_color_video
;
2282 /* Setup one of the standard tty color schemes according to MODE.
2283 MODE's value is generally the number of colors which we want to
2284 support; zero means set up for the default capabilities, the ones
2285 we saw at term_init time; -1 means turn off color support. */
2287 tty_setup_colors (mode
)
2290 /* Canonicalize all negative values of MODE. */
2296 case -1: /* no colors at all */
2299 TN_no_color_video
= 0;
2300 TS_set_foreground
= TS_set_background
= TS_orig_pair
= NULL
;
2302 case 0: /* default colors, if any */
2304 tty_default_color_capabilities (0);
2306 case 8: /* 8 standard ANSI colors */
2307 TS_orig_pair
= "\033[0m";
2309 TS_set_foreground
= "\033[3%p1%dm";
2310 TS_set_background
= "\033[4%p1%dm";
2312 TS_set_foreground
= "\033[3%dm";
2313 TS_set_background
= "\033[4%dm";
2317 TN_no_color_video
= 0;
2323 set_tty_color_mode (f
, val
)
2327 Lisp_Object color_mode_spec
, current_mode_spec
;
2328 Lisp_Object color_mode
, current_mode
;
2330 extern Lisp_Object Qtty_color_mode
;
2331 Lisp_Object tty_color_mode_alist
;
2333 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2340 if (NILP (tty_color_mode_alist
))
2341 color_mode_spec
= Qnil
;
2343 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2345 if (CONSP (color_mode_spec
))
2346 color_mode
= XCDR (color_mode_spec
);
2351 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2353 if (CONSP (current_mode_spec
))
2354 current_mode
= XCDR (current_mode_spec
);
2356 current_mode
= Qnil
;
2357 if (INTEGERP (color_mode
))
2358 mode
= XINT (color_mode
);
2360 mode
= 0; /* meaning default */
2361 if (INTEGERP (current_mode
))
2362 old_mode
= XINT (current_mode
);
2366 if (mode
!= old_mode
)
2368 tty_setup_colors (mode
);
2369 /* This recomputes all the faces given the new color
2371 call0 (intern ("tty-set-up-initial-frame-faces"));
2376 #endif /* !WINDOWSNT */
2379 /***********************************************************************
2381 ***********************************************************************/
2385 term_mouse_moveto (int x
, int y
)
2387 /* TODO: how to set mouse position?
2390 name = (const char *) ttyname (0);
2391 fd = open (name, O_WRONLY);
2392 SOME_FUNCTION (x, y, fd);
2395 last_mouse_y = y; */
2399 term_show_mouse_face (enum draw_glyphs_face draw
)
2401 struct window
*w
= XWINDOW (Qmouse_face_window
);
2405 if (/* If window is in the process of being destroyed, don't bother
2407 w
->current_matrix
!= NULL
2408 /* Recognize when we are called to operate on rows that don't exist
2409 anymore. This can happen when a window is split. */
2410 && mouse_face_end_row
< w
->current_matrix
->nrows
)
2412 /* write_glyphs writes at cursor position, so we need to
2413 temporarily move cursor coordinates to the beginning of
2414 the highlight region. */
2416 /* Save current cursor co-ordinates */
2420 /* Note that mouse_face_beg_row etc. are window relative. */
2421 for (i
= mouse_face_beg_row
; i
<= mouse_face_end_row
; i
++)
2423 int start_hpos
, end_hpos
, nglyphs
;
2424 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
2426 /* Don't do anything if row doesn't have valid contents. */
2427 if (!row
->enabled_p
)
2430 /* For all but the first row, the highlight starts at column 0. */
2431 if (i
== mouse_face_beg_row
)
2432 start_hpos
= mouse_face_beg_col
;
2436 if (i
== mouse_face_end_row
)
2437 end_hpos
= mouse_face_end_col
;
2440 end_hpos
= row
->used
[TEXT_AREA
];
2441 if (draw
== DRAW_NORMAL_TEXT
)
2442 row
->fill_line_p
= 1; /* Clear to end of line */
2445 if (end_hpos
<= start_hpos
)
2447 /* Record that some glyphs of this row are displayed in
2449 row
->mouse_face_p
= draw
> 0;
2451 nglyphs
= end_hpos
- start_hpos
;
2453 if (end_hpos
>= row
->used
[TEXT_AREA
])
2454 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2456 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2457 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
2458 + WINDOW_LEFT_EDGE_X (w
);
2460 cursor_to (pos_y
, pos_x
);
2462 if (draw
== DRAW_MOUSE_FACE
)
2464 write_glyphs_with_face (row
->glyphs
[TEXT_AREA
] + start_hpos
,
2465 nglyphs
, mouse_face_face_id
);
2467 else /* draw == DRAW_NORMAL_TEXT */
2468 write_glyphs (row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2470 cursor_to (save_y
, save_x
);
2475 term_clear_mouse_face ()
2477 if (!NILP (Qmouse_face_window
))
2478 term_show_mouse_face (DRAW_NORMAL_TEXT
);
2480 mouse_face_beg_row
= mouse_face_beg_col
= -1;
2481 mouse_face_end_row
= mouse_face_end_col
= -1;
2482 Qmouse_face_window
= Qnil
;
2485 /* Find the glyph matrix position of buffer position POS in window W.
2486 *HPOS and *VPOS are set to the positions found. W's current glyphs
2487 must be up to date. If POS is above window start return (0, 0).
2488 If POS is after end of W, return end of last line in W.
2489 - taken from msdos.c */
2491 fast_find_position (struct window
*w
, int pos
, int *hpos
, int *vpos
)
2493 int i
, lastcol
, line_start_position
, maybe_next_line_p
= 0;
2494 int yb
= window_text_bottom_y (w
);
2495 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0), *best_row
= row
;
2499 if (row
->used
[TEXT_AREA
])
2500 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
2502 line_start_position
= 0;
2504 if (line_start_position
> pos
)
2506 /* If the position sought is the end of the buffer,
2507 don't include the blank lines at the bottom of the window. */
2508 else if (line_start_position
== pos
2509 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
2511 maybe_next_line_p
= 1;
2514 else if (line_start_position
> 0)
2517 /* Don't overstep the last matrix row, lest we get into the
2518 never-never land... */
2519 if (row
->y
+ 1 >= yb
)
2525 /* Find the right column within BEST_ROW. */
2528 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
2530 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + i
;
2533 charpos
= glyph
->charpos
;
2540 else if (charpos
> pos
)
2542 else if (charpos
> 0)
2546 /* If we're looking for the end of the buffer,
2547 and we didn't find it in the line we scanned,
2548 use the start of the following line. */
2549 if (maybe_next_line_p
)
2556 *hpos
= lastcol
+ 1;
2561 term_mouse_highlight (struct frame
*f
, int x
, int y
)
2563 enum window_part part
;
2568 if (NILP (Vmouse_highlight
)
2569 || !f
->glyphs_initialized_p
)
2572 /* Which window is that in? */
2573 window
= window_from_coordinates (f
, x
, y
, &part
, &x
, &y
, 0);
2575 /* Not on a window -> return. */
2576 if (!WINDOWP (window
))
2579 if (!EQ (window
, Qmouse_face_window
))
2580 term_clear_mouse_face ();
2582 w
= XWINDOW (window
);
2584 /* Are we in a window whose display is up to date?
2585 And verify the buffer's text has not changed. */
2586 b
= XBUFFER (w
->buffer
);
2588 && EQ (w
->window_end_valid
, w
->buffer
)
2589 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
2590 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
2592 int pos
, i
, nrows
= w
->current_matrix
->nrows
;
2593 struct glyph_row
*row
;
2594 struct glyph
*glyph
;
2596 /* Find the glyph under X/Y. */
2598 if (y
>= 0 && y
< nrows
)
2600 row
= MATRIX_ROW (w
->current_matrix
, y
);
2601 /* Give up if some row before the one we are looking for is
2603 for (i
= 0; i
<= y
; i
++)
2604 if (!MATRIX_ROW (w
->current_matrix
, i
)->enabled_p
)
2606 if (i
> y
/* all rows upto and including the one at Y are enabled */
2607 && row
->displays_text_p
2608 && x
< window_box_width (w
, TEXT_AREA
))
2610 glyph
= row
->glyphs
[TEXT_AREA
];
2611 if (x
>= row
->used
[TEXT_AREA
])
2616 if (!BUFFERP (glyph
->object
))
2622 /* Clear mouse face if X/Y not over text. */
2625 term_clear_mouse_face ();
2629 if (!BUFFERP (glyph
->object
))
2631 pos
= glyph
->charpos
;
2633 /* Check for mouse-face. */
2635 extern Lisp_Object Qmouse_face
;
2636 Lisp_Object mouse_face
, overlay
, position
, *overlay_vec
;
2637 int noverlays
, obegv
, ozv
;
2638 struct buffer
*obuf
;
2640 /* If we get an out-of-range value, return now; avoid an error. */
2641 if (pos
> BUF_Z (b
))
2644 /* Make the window's buffer temporarily current for
2645 overlays_at and compute_char_face. */
2646 obuf
= current_buffer
;
2653 /* Is this char mouse-active? */
2654 XSETINT (position
, pos
);
2656 /* Put all the overlays we want in a vector in overlay_vec. */
2657 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
2658 /* Sort overlays into increasing priority order. */
2659 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
2661 /* Check mouse-face highlighting. */
2662 if (!(EQ (window
, Qmouse_face_window
)
2663 && y
>= mouse_face_beg_row
2664 && y
<= mouse_face_end_row
2665 && (y
> mouse_face_beg_row
2666 || x
>= mouse_face_beg_col
)
2667 && (y
< mouse_face_end_row
2668 || x
< mouse_face_end_col
2669 || mouse_face_past_end
)))
2671 /* Clear the display of the old active region, if any. */
2672 term_clear_mouse_face ();
2674 /* Find the highest priority overlay that has a mouse-face
2677 for (i
= noverlays
- 1; i
>= 0; --i
)
2679 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
2680 if (!NILP (mouse_face
))
2682 overlay
= overlay_vec
[i
];
2687 /* If no overlay applies, get a text property. */
2689 mouse_face
= Fget_text_property (position
, Qmouse_face
,
2692 /* Handle the overlay case. */
2693 if (!NILP (overlay
))
2695 /* Find the range of text around this char that
2696 should be active. */
2697 Lisp_Object before
, after
;
2701 before
= Foverlay_start (overlay
);
2702 after
= Foverlay_end (overlay
);
2703 /* Record this as the current active region. */
2704 fast_find_position (w
, XFASTINT (before
),
2705 &mouse_face_beg_col
,
2706 &mouse_face_beg_row
);
2709 = !fast_find_position (w
, XFASTINT (after
),
2710 &mouse_face_end_col
,
2711 &mouse_face_end_row
);
2712 Qmouse_face_window
= window
;
2715 = face_at_buffer_position (w
, pos
, 0, 0,
2716 &ignore
, pos
+ 1, 1);
2718 /* Display it as active. */
2719 term_show_mouse_face (DRAW_MOUSE_FACE
);
2721 /* Handle the text property case. */
2722 else if (!NILP (mouse_face
))
2724 /* Find the range of text around this char that
2725 should be active. */
2726 Lisp_Object before
, after
, beginning
, end
;
2729 beginning
= Fmarker_position (w
->start
);
2730 XSETINT (end
, (BUF_Z (b
) - XFASTINT (w
->window_end_pos
)));
2732 = Fprevious_single_property_change (make_number (pos
+ 1),
2734 w
->buffer
, beginning
);
2736 = Fnext_single_property_change (position
, Qmouse_face
,
2739 /* Record this as the current active region. */
2740 fast_find_position (w
, XFASTINT (before
),
2741 &mouse_face_beg_col
,
2742 &mouse_face_beg_row
);
2744 = !fast_find_position (w
, XFASTINT (after
),
2745 &mouse_face_end_col
,
2746 &mouse_face_end_row
);
2747 Qmouse_face_window
= window
;
2750 = face_at_buffer_position (w
, pos
, 0, 0,
2751 &ignore
, pos
+ 1, 1);
2753 /* Display it as active. */
2754 term_show_mouse_face (DRAW_MOUSE_FACE
);
2758 /* Look for a `help-echo' property. */
2761 extern Lisp_Object Qhelp_echo
;
2763 /* Check overlays first. */
2765 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
2767 overlay
= overlay_vec
[i
];
2768 help
= Foverlay_get (overlay
, Qhelp_echo
);
2773 help_echo_string
= help
;
2774 help_echo_window
= window
;
2775 help_echo_object
= overlay
;
2776 help_echo_pos
= pos
;
2778 /* Try text properties. */
2779 else if (NILP (help
)
2780 && ((STRINGP (glyph
->object
)
2781 && glyph
->charpos
>= 0
2782 && glyph
->charpos
< SCHARS (glyph
->object
))
2783 || (BUFFERP (glyph
->object
)
2784 && glyph
->charpos
>= BEGV
2785 && glyph
->charpos
< ZV
)))
2787 help
= Fget_text_property (make_number (glyph
->charpos
),
2788 Qhelp_echo
, glyph
->object
);
2791 help_echo_string
= help
;
2792 help_echo_window
= window
;
2793 help_echo_object
= glyph
->object
;
2794 help_echo_pos
= glyph
->charpos
;
2801 current_buffer
= obuf
;
2807 term_mouse_movement (FRAME_PTR frame
, Gpm_Event
*event
)
2809 /* Has the mouse moved off the glyph it was on at the last sighting? */
2810 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2812 frame
->mouse_moved
= 1;
2813 term_mouse_highlight (frame
, event
->x
, event
->y
);
2814 /* Remember which glyph we're now on. */
2815 last_mouse_x
= event
->x
;
2816 last_mouse_y
= event
->y
;
2822 /* Return the current position of the mouse.
2824 Set *f to the frame the mouse is in, or zero if the mouse is in no
2825 Emacs frame. If it is set to zero, all the other arguments are
2828 Set *bar_window to Qnil, and *x and *y to the column and
2829 row of the character cell the mouse is over.
2831 Set *time to the time the mouse was at the returned position.
2833 This clears mouse_moved until the next motion
2836 term_mouse_position (FRAME_PTR
*fp
, int insist
, Lisp_Object
*bar_window
,
2837 enum scroll_bar_part
*part
, Lisp_Object
*x
,
2838 Lisp_Object
*y
, unsigned long *time
)
2842 *fp
= SELECTED_FRAME ();
2843 (*fp
)->mouse_moved
= 0;
2848 XSETINT (*x
, last_mouse_x
);
2849 XSETINT (*y
, last_mouse_y
);
2850 gettimeofday(&now
, 0);
2851 *time
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2854 /* Prepare a mouse-event in *RESULT for placement in the input queue.
2856 If the event is a button press, then note that we have grabbed
2860 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
2866 result
->kind
= GPM_CLICK_EVENT
;
2867 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
2869 if (event
->buttons
& j
) {
2870 result
->code
= i
; /* button number */
2874 gettimeofday(&now
, 0);
2875 result
->timestamp
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2877 if (event
->type
& GPM_UP
)
2878 result
->modifiers
= up_modifier
;
2879 else if (event
->type
& GPM_DOWN
)
2880 result
->modifiers
= down_modifier
;
2882 result
->modifiers
= 0;
2884 if (event
->type
& GPM_SINGLE
)
2885 result
->modifiers
|= click_modifier
;
2887 if (event
->type
& GPM_DOUBLE
)
2888 result
->modifiers
|= double_modifier
;
2890 if (event
->type
& GPM_TRIPLE
)
2891 result
->modifiers
|= triple_modifier
;
2893 if (event
->type
& GPM_DRAG
)
2894 result
->modifiers
|= drag_modifier
;
2896 if (!(event
->type
& (GPM_MOVE
| GPM_DRAG
))) {
2899 if (event
->modifiers
& (1 << 0))
2900 result
->modifiers
|= shift_modifier
;
2903 if (event
->modifiers
& (1 << 2))
2904 result
->modifiers
|= ctrl_modifier
;
2906 /* 1 << KG_ALT || KG_ALTGR */
2907 if (event
->modifiers
& (1 << 3)
2908 || event
->modifiers
& (1 << 1))
2909 result
->modifiers
|= meta_modifier
;
2912 XSETINT (result
->x
, event
->x
);
2913 XSETINT (result
->y
, event
->y
);
2914 XSETFRAME (result
->frame_or_window
, f
);
2920 handle_one_term_event (Gpm_Event
*event
, struct input_event
* hold_quit
)
2922 struct frame
*f
= SELECTED_FRAME ();
2924 struct input_event ie
;
2932 if (event
->type
& (GPM_MOVE
| GPM_DRAG
)) {
2933 unsigned char buf
[6 * sizeof (short)];
2934 unsigned short *arg
= (unsigned short *) buf
+ 1;
2937 previous_help_echo_string
= help_echo_string
;
2938 help_echo_string
= Qnil
;
2940 /* Display mouse pointer */
2941 buf
[sizeof(short) - 1] = 2; /* set selection */
2943 arg
[0] = arg
[2] = (unsigned short) event
->x
+ gpm_zerobased
;
2944 arg
[1] = arg
[3] = (unsigned short) event
->y
+ gpm_zerobased
;
2945 arg
[4] = (unsigned short) 3;
2948 fd
= open (name
, O_WRONLY
);
2949 ioctl (fd
, TIOCLINUX
, buf
+ sizeof (short) - 1);
2952 if (!term_mouse_movement (f
, event
))
2953 help_echo_string
= previous_help_echo_string
;
2955 /* If the contents of the global variable help_echo_string
2956 has changed, generate a HELP_EVENT. */
2957 if (!NILP (help_echo_string
)
2958 || !NILP (previous_help_echo_string
))
2965 term_mouse_click (&ie
, event
, f
);
2969 if (ie
.kind
!= NO_EVENT
)
2971 kbd_buffer_store_event_hold (&ie
, hold_quit
);
2976 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
2981 XSETFRAME (frame
, f
);
2985 gen_help_event (help_echo_string
, frame
, help_echo_window
,
2986 help_echo_object
, help_echo_pos
);
2993 DEFUN ("term-open-connection", Fterm_open_connection
, Sterm_open_connection
,
2995 doc
: /* Open a connection to Gpm. */)
2998 Gpm_Connect connection
;
3000 connection
.eventMask
= ~0;
3001 connection
.defaultMask
= ~GPM_HARD
;
3002 connection
.maxMod
= ~0;
3003 connection
.minMod
= 0;
3006 if (Gpm_Open (&connection
, 0) < 0)
3013 add_gpm_wait_descriptor (gpm_fd
);
3018 DEFUN ("term-close-connection", Fterm_close_connection
, Sterm_close_connection
,
3020 doc
: /* Close a connection to Gpm. */)
3023 delete_gpm_wait_descriptor (gpm_fd
);
3024 while (Gpm_Close()); /* close all the stack */
3028 #endif /* HAVE_GPM */
3031 /***********************************************************************
3033 ***********************************************************************/
3036 term_init (terminal_type
)
3037 char *terminal_type
;
3040 char **address
= &area
;
3041 char *buffer
= NULL
;
3042 int buffer_size
= 4096;
3045 struct frame
*sf
= XFRAME (selected_frame
);
3047 encode_terminal_bufsize
= 0;
3050 mouse_position_hook
= term_mouse_position
;
3051 Qmouse_face_window
= Qnil
;
3055 initialize_w32_display ();
3059 area
= (char *) xmalloc (2044);
3061 FrameRows
= FRAME_LINES (sf
);
3062 FrameCols
= FRAME_COLS (sf
);
3063 specified_window
= FRAME_LINES (sf
);
3065 delete_in_insert_mode
= 1;
3068 scroll_region_ok
= 0;
3070 /* Seems to insert lines when it's not supposed to, messing
3071 up the display. In doing a trace, it didn't seem to be
3072 called much, so I don't think we're losing anything by
3075 line_ins_del_ok
= 0;
3076 char_ins_del_ok
= 1;
3080 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
3081 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
3082 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
3085 #else /* not WINDOWSNT */
3089 buffer
= (char *) xmalloc (buffer_size
);
3090 status
= tgetent (buffer
, terminal_type
);
3094 fatal ("Cannot open terminfo database file");
3096 fatal ("Cannot open termcap database file");
3102 fatal ("Terminal type %s is not defined.\n\
3103 If that is not the actual type of terminal you have,\n\
3104 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3105 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3106 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3109 fatal ("Terminal type %s is not defined.\n\
3110 If that is not the actual type of terminal you have,\n\
3111 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3112 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3113 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3119 if (strlen (buffer
) >= buffer_size
)
3121 buffer_size
= strlen (buffer
);
3123 area
= (char *) xmalloc (buffer_size
);
3125 TS_ins_line
= tgetstr ("al", address
);
3126 TS_ins_multi_lines
= tgetstr ("AL", address
);
3127 TS_bell
= tgetstr ("bl", address
);
3128 BackTab
= tgetstr ("bt", address
);
3129 TS_clr_to_bottom
= tgetstr ("cd", address
);
3130 TS_clr_line
= tgetstr ("ce", address
);
3131 TS_clr_frame
= tgetstr ("cl", address
);
3132 ColPosition
= NULL
; /* tgetstr ("ch", address); */
3133 AbsPosition
= tgetstr ("cm", address
);
3134 CR
= tgetstr ("cr", address
);
3135 TS_set_scroll_region
= tgetstr ("cs", address
);
3136 TS_set_scroll_region_1
= tgetstr ("cS", address
);
3137 RowPosition
= tgetstr ("cv", address
);
3138 TS_del_char
= tgetstr ("dc", address
);
3139 TS_del_multi_chars
= tgetstr ("DC", address
);
3140 TS_del_line
= tgetstr ("dl", address
);
3141 TS_del_multi_lines
= tgetstr ("DL", address
);
3142 TS_delete_mode
= tgetstr ("dm", address
);
3143 TS_end_delete_mode
= tgetstr ("ed", address
);
3144 TS_end_insert_mode
= tgetstr ("ei", address
);
3145 Home
= tgetstr ("ho", address
);
3146 TS_ins_char
= tgetstr ("ic", address
);
3147 TS_ins_multi_chars
= tgetstr ("IC", address
);
3148 TS_insert_mode
= tgetstr ("im", address
);
3149 TS_pad_inserted_char
= tgetstr ("ip", address
);
3150 TS_end_keypad_mode
= tgetstr ("ke", address
);
3151 TS_keypad_mode
= tgetstr ("ks", address
);
3152 LastLine
= tgetstr ("ll", address
);
3153 Right
= tgetstr ("nd", address
);
3154 Down
= tgetstr ("do", address
);
3156 Down
= tgetstr ("nl", address
); /* Obsolete name for "do" */
3158 /* VMS puts a carriage return before each linefeed,
3159 so it is not safe to use linefeeds. */
3160 if (Down
&& Down
[0] == '\n' && Down
[1] == '\0')
3163 if (tgetflag ("bs"))
3164 Left
= "\b"; /* can't possibly be longer! */
3165 else /* (Actually, "bs" is obsolete...) */
3166 Left
= tgetstr ("le", address
);
3168 Left
= tgetstr ("bc", address
); /* Obsolete name for "le" */
3169 TS_pad_char
= tgetstr ("pc", address
);
3170 TS_repeat
= tgetstr ("rp", address
);
3171 TS_end_standout_mode
= tgetstr ("se", address
);
3172 TS_fwd_scroll
= tgetstr ("sf", address
);
3173 TS_standout_mode
= tgetstr ("so", address
);
3174 TS_rev_scroll
= tgetstr ("sr", address
);
3175 Wcm
.cm_tab
= tgetstr ("ta", address
);
3176 TS_end_termcap_modes
= tgetstr ("te", address
);
3177 TS_termcap_modes
= tgetstr ("ti", address
);
3178 Up
= tgetstr ("up", address
);
3179 TS_visible_bell
= tgetstr ("vb", address
);
3180 TS_cursor_normal
= tgetstr ("ve", address
);
3181 TS_cursor_visible
= tgetstr ("vs", address
);
3182 TS_cursor_invisible
= tgetstr ("vi", address
);
3183 TS_set_window
= tgetstr ("wi", address
);
3185 TS_enter_underline_mode
= tgetstr ("us", address
);
3186 TS_exit_underline_mode
= tgetstr ("ue", address
);
3187 TS_enter_bold_mode
= tgetstr ("md", address
);
3188 TS_enter_dim_mode
= tgetstr ("mh", address
);
3189 TS_enter_blink_mode
= tgetstr ("mb", address
);
3190 TS_enter_reverse_mode
= tgetstr ("mr", address
);
3191 TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3192 TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3193 TS_exit_attribute_mode
= tgetstr ("me", address
);
3195 MultiUp
= tgetstr ("UP", address
);
3196 MultiDown
= tgetstr ("DO", address
);
3197 MultiLeft
= tgetstr ("LE", address
);
3198 MultiRight
= tgetstr ("RI", address
);
3200 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
3201 color because we can't switch back to the default foreground and
3203 TS_orig_pair
= tgetstr ("op", address
);
3206 TS_set_foreground
= tgetstr ("AF", address
);
3207 TS_set_background
= tgetstr ("AB", address
);
3208 if (!TS_set_foreground
)
3211 TS_set_foreground
= tgetstr ("Sf", address
);
3212 TS_set_background
= tgetstr ("Sb", address
);
3215 TN_max_colors
= tgetnum ("Co");
3216 TN_max_pairs
= tgetnum ("pa");
3218 TN_no_color_video
= tgetnum ("NC");
3219 if (TN_no_color_video
== -1)
3220 TN_no_color_video
= 0;
3223 tty_default_color_capabilities (1);
3225 MagicWrap
= tgetflag ("xn");
3226 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3227 the former flag imply the latter. */
3228 AutoWrap
= MagicWrap
|| tgetflag ("am");
3229 memory_below_frame
= tgetflag ("db");
3230 TF_hazeltine
= tgetflag ("hz");
3231 must_write_spaces
= tgetflag ("in");
3232 meta_key
= tgetflag ("km") || tgetflag ("MT");
3233 TF_insmode_motion
= tgetflag ("mi");
3234 TF_standout_motion
= tgetflag ("ms");
3235 TF_underscore
= tgetflag ("ul");
3236 TF_teleray
= tgetflag ("xt");
3238 term_get_fkeys (address
);
3240 /* Get frame size from system, or else from termcap. */
3243 get_frame_size (&width
, &height
);
3244 FRAME_COLS (sf
) = width
;
3245 FRAME_LINES (sf
) = height
;
3248 if (FRAME_COLS (sf
) <= 0)
3249 SET_FRAME_COLS (sf
, tgetnum ("co"));
3251 /* Keep width and external_width consistent */
3252 SET_FRAME_COLS (sf
, FRAME_COLS (sf
));
3253 if (FRAME_LINES (sf
) <= 0)
3254 FRAME_LINES (sf
) = tgetnum ("li");
3256 if (FRAME_LINES (sf
) < 3 || FRAME_COLS (sf
) < 3)
3257 fatal ("Screen size %dx%d is too small",
3258 FRAME_LINES (sf
), FRAME_COLS (sf
));
3260 min_padding_speed
= tgetnum ("pb");
3261 TabWidth
= tgetnum ("tw");
3264 /* These capabilities commonly use ^J.
3265 I don't know why, but sending them on VMS does not work;
3266 it causes following spaces to be lost, sometimes.
3267 For now, the simplest fix is to avoid using these capabilities ever. */
3268 if (Down
&& Down
[0] == '\n')
3276 TS_fwd_scroll
= Down
;
3278 PC
= TS_pad_char
? *TS_pad_char
: 0;
3283 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3284 and newer termcap doc does not seem to say there is a default.
3289 /* We don't support standout modes that use `magic cookies', so
3290 turn off any that do. */
3291 if (TS_standout_mode
&& tgetnum ("sg") >= 0)
3293 TS_standout_mode
= 0;
3294 TS_end_standout_mode
= 0;
3296 if (TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3298 TS_enter_underline_mode
= 0;
3299 TS_exit_underline_mode
= 0;
3302 /* If there's no standout mode, try to use underlining instead. */
3303 if (TS_standout_mode
== 0)
3305 TS_standout_mode
= TS_enter_underline_mode
;
3306 TS_end_standout_mode
= TS_exit_underline_mode
;
3309 /* If no `se' string, try using a `me' string instead.
3310 If that fails, we can't use standout mode at all. */
3311 if (TS_end_standout_mode
== 0)
3313 char *s
= tgetstr ("me", address
);
3315 TS_end_standout_mode
= s
;
3317 TS_standout_mode
= 0;
3323 /* We can't support standout mode, because it uses magic cookies. */
3324 TS_standout_mode
= 0;
3325 /* But that means we cannot rely on ^M to go to column zero! */
3327 /* LF can't be trusted either -- can alter hpos */
3328 /* if move at column 0 thru a line with TS_standout_mode */
3332 /* Special handling for certain terminal types known to need it */
3334 if (!strcmp (terminal_type
, "supdup"))
3336 memory_below_frame
= 1;
3337 Wcm
.cm_losewrap
= 1;
3339 if (!strncmp (terminal_type
, "c10", 3)
3340 || !strcmp (terminal_type
, "perq"))
3342 /* Supply a makeshift :wi string.
3343 This string is not valid in general since it works only
3344 for windows starting at the upper left corner;
3345 but that is all Emacs uses.
3347 This string works only if the frame is using
3348 the top of the video memory, because addressing is memory-relative.
3349 So first check the :ti string to see if that is true.
3351 It would be simpler if the :wi string could go in the termcap
3352 entry, but it can't because it is not fully valid.
3353 If it were in the termcap entry, it would confuse other programs. */
3356 p
= TS_termcap_modes
;
3357 while (*p
&& strcmp (p
, "\033v "))
3360 TS_set_window
= "\033v%C %C %C %C ";
3362 /* Termcap entry often fails to have :in: flag */
3363 must_write_spaces
= 1;
3364 /* :ti string typically fails to have \E^G! in it */
3365 /* This limits scope of insert-char to one line. */
3366 strcpy (area
, TS_termcap_modes
);
3367 strcat (area
, "\033\007!");
3368 TS_termcap_modes
= area
;
3369 area
+= strlen (area
) + 1;
3371 /* Change all %+ parameters to %C, to handle
3372 values above 96 correctly for the C100. */
3375 if (p
[0] == '%' && p
[1] == '+')
3381 FrameRows
= FRAME_LINES (sf
);
3382 FrameCols
= FRAME_COLS (sf
);
3383 specified_window
= FRAME_LINES (sf
);
3385 if (Wcm_init () == -1) /* can't do cursor motion */
3387 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3388 It lacks the ability to position the cursor.\n\
3389 If that is not the actual type of terminal you have, use either the\n\
3390 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
3391 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
3395 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3396 It lacks the ability to position the cursor.\n\
3397 If that is not the actual type of terminal you have,\n\
3398 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3399 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3400 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3402 # else /* TERMCAP */
3403 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3404 It lacks the ability to position the cursor.\n\
3405 If that is not the actual type of terminal you have,\n\
3406 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3407 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3408 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3410 # endif /* TERMINFO */
3412 if (FRAME_LINES (sf
) <= 0
3413 || FRAME_COLS (sf
) <= 0)
3414 fatal ("The frame size has not been specified");
3416 delete_in_insert_mode
3417 = TS_delete_mode
&& TS_insert_mode
3418 && !strcmp (TS_delete_mode
, TS_insert_mode
);
3420 se_is_so
= (TS_standout_mode
3421 && TS_end_standout_mode
3422 && !strcmp (TS_standout_mode
, TS_end_standout_mode
));
3424 UseTabs
= tabs_safe_p () && TabWidth
== 8;
3428 && (TS_set_window
|| TS_set_scroll_region
|| TS_set_scroll_region_1
));
3430 line_ins_del_ok
= (((TS_ins_line
|| TS_ins_multi_lines
)
3431 && (TS_del_line
|| TS_del_multi_lines
))
3432 || (scroll_region_ok
&& TS_fwd_scroll
&& TS_rev_scroll
));
3434 char_ins_del_ok
= ((TS_ins_char
|| TS_insert_mode
3435 || TS_pad_inserted_char
|| TS_ins_multi_chars
)
3436 && (TS_del_char
|| TS_del_multi_chars
));
3438 fast_clear_end_of_line
= TS_clr_line
!= 0;
3441 if (read_socket_hook
) /* Baudrate is somewhat */
3442 /* meaningless in this case */
3445 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
3446 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
3447 #endif /* WINDOWSNT */
3454 fatal (str
, arg1
, arg2
)
3455 char *str
, *arg1
, *arg2
;
3457 fprintf (stderr
, "emacs: ");
3458 fprintf (stderr
, str
, arg1
, arg2
);
3459 fprintf (stderr
, "\n");
3464 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 0, 0,
3465 doc
: /* Declare that this terminal does not handle underlining.
3466 This is used to override the terminfo data, for certain terminals that
3467 do not really do underlining, but say that they do. */)
3470 TS_enter_underline_mode
= 0;
3477 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
3478 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3479 This variable can be used by terminal emulator packages. */);
3481 system_uses_terminfo
= 1;
3483 system_uses_terminfo
= 0;
3486 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
3487 doc
: /* Non-nil means call this function to ring the bell.
3488 The function should accept no arguments. */);
3489 Vring_bell_function
= Qnil
;
3491 DEFVAR_BOOL ("visible-cursor", &visible_cursor
,
3492 doc
: /* Non-nil means to make the cursor very visible.
3493 This only has an effect when running in a text terminal.
3494 What means \"very visible\" is up to your terminal. It may make the cursor
3495 bigger, or it may make it blink, or it may do nothing at all. */);
3498 defsubr (&Stty_display_color_p
);
3499 defsubr (&Stty_display_color_cells
);
3500 defsubr (&Stty_no_underline
);
3502 defsubr (&Sterm_open_connection
);
3503 defsubr (&Sterm_close_connection
);
3505 staticpro (&Qmouse_face_window
);
3506 #endif /* HAVE_GPM */
3508 fullscreen_hook
= NULL
;
3511 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
3512 (do not change this comment) */