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"
43 /* For now, don't try to include termcap.h. On some systems,
44 configure finds a non-standard termcap.h that the main build
47 #if defined HAVE_TERMCAP_H && 0
50 extern void tputs
P_ ((const char *, int, int (*)(int)));
51 extern int tgetent
P_ ((char *, const char *));
52 extern int tgetflag
P_ ((char *id
));
53 extern int tgetnum
P_ ((char *id
));
64 static void turn_on_face
P_ ((struct frame
*, int face_id
));
65 static void turn_off_face
P_ ((struct frame
*, int face_id
));
66 static void tty_show_cursor
P_ ((void));
67 static void tty_hide_cursor
P_ ((void));
70 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) - curY), cmputc)
71 #define OUTPUT1(a) tputs (a, 1, cmputc)
72 #define OUTPUTL(a, lines) tputs (a, lines, cmputc)
74 #define OUTPUT_IF(a) \
77 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) \
81 #define OUTPUT1_IF(a) do { if (a) tputs (a, 1, cmputc); } while (0)
83 /* Display space properties */
85 extern Lisp_Object Qspace
, QCalign_to
, QCwidth
;
87 /* Function to use to ring the bell. */
89 Lisp_Object Vring_bell_function
;
91 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */
93 static int visible_cursor
;
95 /* Terminal characteristics that higher levels want to look at.
96 These are all extern'd in termchar.h */
98 int must_write_spaces
; /* Nonzero means spaces in the text
99 must actually be output; can't just skip
100 over some columns to leave them blank. */
101 int min_padding_speed
; /* Speed below which no padding necessary */
103 int line_ins_del_ok
; /* Terminal can insert and delete lines */
104 int char_ins_del_ok
; /* Terminal can insert and delete chars */
105 int scroll_region_ok
; /* Terminal supports setting the
107 int scroll_region_cost
; /* Cost of setting a scroll window,
108 measured in characters */
109 int memory_below_frame
; /* Terminal remembers lines
110 scrolled off bottom */
111 int fast_clear_end_of_line
; /* Terminal has a `ce' string */
113 /* Nonzero means no need to redraw the entire frame on resuming
114 a suspended Emacs. This is useful on terminals with multiple pages,
115 where one page is used for Emacs and another for all else. */
117 int no_redraw_on_reenter
;
119 /* Hook functions that you can set to snap out the functions in this file.
120 These are all extern'd in termhooks.h */
122 void (*cursor_to_hook
) P_ ((int, int));
123 void (*raw_cursor_to_hook
) P_ ((int, int));
124 void (*clear_to_end_hook
) P_ ((void));
125 void (*clear_frame_hook
) P_ ((void));
126 void (*clear_end_of_line_hook
) P_ ((int));
128 void (*ins_del_lines_hook
) P_ ((int, int));
130 void (*delete_glyphs_hook
) P_ ((int));
132 void (*ring_bell_hook
) P_ ((void));
134 void (*reset_terminal_modes_hook
) P_ ((void));
135 void (*set_terminal_modes_hook
) P_ ((void));
136 void (*update_begin_hook
) P_ ((struct frame
*));
137 void (*update_end_hook
) P_ ((struct frame
*));
138 void (*set_terminal_window_hook
) P_ ((int));
139 void (*insert_glyphs_hook
) P_ ((struct glyph
*, int));
140 void (*write_glyphs_hook
) P_ ((struct glyph
*, int));
141 void (*delete_glyphs_hook
) P_ ((int));
143 int (*read_socket_hook
) P_ ((int, int, struct input_event
*));
145 void (*frame_up_to_date_hook
) P_ ((struct frame
*));
147 void (*mouse_position_hook
) P_ ((FRAME_PTR
*f
, int insist
,
148 Lisp_Object
*bar_window
,
149 enum scroll_bar_part
*part
,
152 unsigned long *time
));
154 /* When reading from a minibuffer in a different frame, Emacs wants
155 to shift the highlight from the selected frame to the mini-buffer's
156 frame; under X, this means it lies about where the focus is.
157 This hook tells the window system code to re-decide where to put
160 void (*frame_rehighlight_hook
) P_ ((FRAME_PTR f
));
162 /* If we're displaying frames using a window system that can stack
163 frames on top of each other, this hook allows you to bring a frame
164 to the front, or bury it behind all the other windows. If this
165 hook is zero, that means the device we're displaying on doesn't
166 support overlapping frames, so there's no need to raise or lower
169 If RAISE is non-zero, F is brought to the front, before all other
170 windows. If RAISE is zero, F is sent to the back, behind all other
173 void (*frame_raise_lower_hook
) P_ ((FRAME_PTR f
, int raise
));
175 /* If the value of the frame parameter changed, whis hook is called.
176 For example, if going from fullscreen to not fullscreen this hook
177 may do something OS dependent, like extended window manager hints on X11. */
178 void (*fullscreen_hook
) P_ ((struct frame
*f
));
180 /* Set the vertical scroll bar for WINDOW to have its upper left corner
181 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
182 indicate that we are displaying PORTION characters out of a total
183 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
184 have a scroll bar, create one for it. */
186 void (*set_vertical_scroll_bar_hook
)
187 P_ ((struct window
*window
,
188 int portion
, int whole
, int position
));
191 /* The following three hooks are used when we're doing a thorough
192 redisplay of the frame. We don't explicitly know which scroll bars
193 are going to be deleted, because keeping track of when windows go
194 away is a real pain - can you say set-window-configuration?
195 Instead, we just assert at the beginning of redisplay that *all*
196 scroll bars are to be removed, and then save scroll bars from the
197 fiery pit when we actually redisplay their window. */
199 /* Arrange for all scroll bars on FRAME to be removed at the next call
200 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
201 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
203 This should be applied to each frame each time its window tree is
204 redisplayed, even if it is not displaying scroll bars at the moment;
205 if the HAS_SCROLL_BARS flag has just been turned off, only calling
206 this and the judge_scroll_bars_hook will get rid of them.
208 If non-zero, this hook should be safe to apply to any frame,
209 whether or not it can support scroll bars, and whether or not it is
210 currently displaying them. */
212 void (*condemn_scroll_bars_hook
) P_ ((FRAME_PTR frame
));
214 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
215 Note that it's okay to redeem a scroll bar that is not condemned. */
217 void (*redeem_scroll_bar_hook
) P_ ((struct window
*window
));
219 /* Remove all scroll bars on FRAME that haven't been saved since the
220 last call to `*condemn_scroll_bars_hook'.
222 This should be applied to each frame after each time its window
223 tree is redisplayed, even if it is not displaying scroll bars at the
224 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
225 calling this and condemn_scroll_bars_hook will get rid of them.
227 If non-zero, this hook should be safe to apply to any frame,
228 whether or not it can support scroll bars, and whether or not it is
229 currently displaying them. */
231 void (*judge_scroll_bars_hook
) P_ ((FRAME_PTR FRAME
));
233 /* Strings, numbers and flags taken from the termcap entry. */
235 char *TS_ins_line
; /* "al" */
236 char *TS_ins_multi_lines
; /* "AL" (one parameter, # lines to insert) */
237 char *TS_bell
; /* "bl" */
238 char *TS_clr_to_bottom
; /* "cd" */
239 char *TS_clr_line
; /* "ce", clear to end of line */
240 char *TS_clr_frame
; /* "cl" */
241 char *TS_set_scroll_region
; /* "cs" (2 params, first line and last line) */
242 char *TS_set_scroll_region_1
; /* "cS" (4 params: total lines,
243 lines above scroll region, lines below it,
244 total lines again) */
245 char *TS_del_char
; /* "dc" */
246 char *TS_del_multi_chars
; /* "DC" (one parameter, # chars to delete) */
247 char *TS_del_line
; /* "dl" */
248 char *TS_del_multi_lines
; /* "DL" (one parameter, # lines to delete) */
249 char *TS_delete_mode
; /* "dm", enter character-delete mode */
250 char *TS_end_delete_mode
; /* "ed", leave character-delete mode */
251 char *TS_end_insert_mode
; /* "ei", leave character-insert mode */
252 char *TS_ins_char
; /* "ic" */
253 char *TS_ins_multi_chars
; /* "IC" (one parameter, # chars to insert) */
254 char *TS_insert_mode
; /* "im", enter character-insert mode */
255 char *TS_pad_inserted_char
; /* "ip". Just padding, no commands. */
256 char *TS_end_keypad_mode
; /* "ke" */
257 char *TS_keypad_mode
; /* "ks" */
258 char *TS_pad_char
; /* "pc", char to use as padding */
259 char *TS_repeat
; /* "rp" (2 params, # times to repeat
260 and character to be repeated) */
261 char *TS_end_standout_mode
; /* "se" */
262 char *TS_fwd_scroll
; /* "sf" */
263 char *TS_standout_mode
; /* "so" */
264 char *TS_rev_scroll
; /* "sr" */
265 char *TS_end_termcap_modes
; /* "te" */
266 char *TS_termcap_modes
; /* "ti" */
267 char *TS_visible_bell
; /* "vb" */
268 char *TS_cursor_normal
; /* "ve" */
269 char *TS_cursor_visible
; /* "vs" */
270 char *TS_cursor_invisible
; /* "vi" */
271 char *TS_set_window
; /* "wi" (4 params, start and end of window,
272 each as vpos and hpos) */
274 /* Value of the "NC" (no_color_video) capability, or 0 if not
277 static int TN_no_color_video
;
279 /* Meaning of bits in no_color_video. Each bit set means that the
280 corresponding attribute cannot be combined with colors. */
284 NC_STANDOUT
= 1 << 0,
285 NC_UNDERLINE
= 1 << 1,
292 NC_ALT_CHARSET
= 1 << 8
295 /* "md" -- turn on bold (extra bright mode). */
297 char *TS_enter_bold_mode
;
299 /* "mh" -- turn on half-bright mode. */
301 char *TS_enter_dim_mode
;
303 /* "mb" -- enter blinking mode. */
305 char *TS_enter_blink_mode
;
307 /* "mr" -- enter reverse video mode. */
309 char *TS_enter_reverse_mode
;
311 /* "us"/"ue" -- start/end underlining. */
313 char *TS_exit_underline_mode
, *TS_enter_underline_mode
;
315 /* "as"/"ae" -- start/end alternate character set. Not really
318 char *TS_enter_alt_charset_mode
, *TS_exit_alt_charset_mode
;
320 /* "me" -- switch appearances off. */
322 char *TS_exit_attribute_mode
;
324 /* "Co" -- number of colors. */
328 /* "pa" -- max. number of color pairs on screen. Not handled yet.
329 Could be a problem if not equal to TN_max_colors * TN_max_colors. */
333 /* "op" -- SVr4 set default pair to its original value. */
337 /* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
338 1 param, the color index. */
340 char *TS_set_foreground
, *TS_set_background
;
342 int TF_hazeltine
; /* termcap hz flag. */
343 int TF_insmode_motion
; /* termcap mi flag: can move while in insert mode. */
344 int TF_standout_motion
; /* termcap mi flag: can move while in standout mode. */
345 int TF_underscore
; /* termcap ul flag: _ underlines if over-struck on
346 non-blank position. Must clear before writing _. */
347 int TF_teleray
; /* termcap xt flag: many weird consequences.
350 static int RPov
; /* # chars to start a TS_repeat */
352 static int delete_in_insert_mode
; /* delete mode == insert mode */
354 static int se_is_so
; /* 1 if same string both enters and leaves
359 /* The largest frame width in any call to calculate_costs. */
363 /* The largest frame height in any call to calculate_costs. */
367 static int costs_set
; /* Nonzero if costs have been calculated. */
369 int insert_mode
; /* Nonzero when in insert mode. */
370 int standout_mode
; /* Nonzero when in standout mode. */
372 /* Size of window specified by higher levels.
373 This is the number of lines, from the top of frame downwards,
374 which can participate in insert-line/delete-line operations.
376 Effectively it excludes the bottom frame_lines - specified_window_size
377 lines from those operations. */
379 int specified_window
;
381 /* Frame currently being redisplayed; 0 if not currently redisplaying.
382 (Direct output does not count). */
384 FRAME_PTR updating_frame
;
386 /* Provided for lisp packages. */
388 static int system_uses_terminfo
;
390 /* Flag used in tty_show/hide_cursor. */
392 static int tty_cursor_hidden
;
396 extern char *tgetstr ();
398 static void term_clear_mouse_face ();
399 static void term_mouse_highlight (struct frame
*f
, int x
, int y
);
403 /* We aren't X windows, but we aren't termcap either. This makes me
404 uncertain as to what value to use for frame.output_method. For
405 this file, we'll define FRAME_TERMCAP_P to be zero so that our
406 output hooks get called instead of the termcap functions. Probably
407 the best long-term solution is to define an output_windows_nt... */
409 #undef FRAME_TERMCAP_P
410 #define FRAME_TERMCAP_P(_f_) 0
411 #endif /* WINDOWSNT */
414 #include <sys/fcntl.h>
417 /* Nonzero means mouse is enabled on Linux console. */
420 /* These variables describe the range of text currently shown in its
421 mouse-face, together with the window they apply to. As long as
422 the mouse stays within this range, we need not redraw anything on
423 its account. Rows and columns are glyph matrix positions in
424 MOUSE_FACE_WINDOW. */
425 static int mouse_face_beg_row
, mouse_face_beg_col
;
426 static int mouse_face_end_row
, mouse_face_end_col
;
427 static int mouse_face_past_end
;
428 static Lisp_Object Qmouse_face_window
;
429 static int mouse_face_face_id
;
431 /* FRAME and X, Y position of mouse when last checked for
432 highlighting. X and Y can be negative or out of range for the frame. */
433 struct frame
*mouse_face_mouse_frame
;
434 int mouse_face_mouse_x
, mouse_face_mouse_y
;
436 static int pos_x
, pos_y
;
437 static int last_mouse_x
, last_mouse_y
;
438 #endif /* HAVE_GPM */
443 if (!NILP (Vring_bell_function
))
445 Lisp_Object function
;
447 /* Temporarily set the global variable to nil
448 so that if we get an error, it stays nil
449 and we don't call it over and over.
451 We don't specbind it, because that would carefully
452 restore the bad value if there's an error
453 and make the loop of errors happen anyway. */
455 function
= Vring_bell_function
;
456 Vring_bell_function
= Qnil
;
460 Vring_bell_function
= function
;
462 else if (!FRAME_TERMCAP_P (XFRAME (selected_frame
)))
463 (*ring_bell_hook
) ();
465 OUTPUT (TS_visible_bell
&& visible_bell
? TS_visible_bell
: TS_bell
);
469 set_terminal_modes ()
471 if (FRAME_TERMCAP_P (XFRAME (selected_frame
)))
473 if (TS_termcap_modes
)
474 OUTPUT (TS_termcap_modes
);
477 /* Output enough newlines to scroll all the old screen contents
478 off the screen, so it won't be overwritten and lost. */
480 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
484 OUTPUT_IF (visible_cursor
? TS_cursor_visible
: TS_cursor_normal
);
485 OUTPUT_IF (TS_keypad_mode
);
489 (*set_terminal_modes_hook
) ();
493 reset_terminal_modes ()
495 if (FRAME_TERMCAP_P (XFRAME (selected_frame
)))
497 turn_off_highlight ();
499 OUTPUT_IF (TS_end_keypad_mode
);
500 OUTPUT_IF (TS_cursor_normal
);
501 OUTPUT_IF (TS_end_termcap_modes
);
502 OUTPUT_IF (TS_orig_pair
);
503 /* Output raw CR so kernel can track the cursor hpos. */
506 else if (reset_terminal_modes_hook
)
507 (*reset_terminal_modes_hook
) ();
515 if (!FRAME_TERMCAP_P (f
))
516 update_begin_hook (f
);
523 if (FRAME_TERMCAP_P (f
))
525 if (!XWINDOW (selected_window
)->cursor_off_p
)
528 background_highlight ();
533 updating_frame
= NULL
;
537 set_terminal_window (size
)
540 if (FRAME_TERMCAP_P (updating_frame
))
542 specified_window
= size
? size
: FRAME_LINES (updating_frame
);
543 if (scroll_region_ok
)
544 set_scroll_region (0, specified_window
);
547 set_terminal_window_hook (size
);
551 set_scroll_region (start
, stop
)
555 struct frame
*sf
= XFRAME (selected_frame
);
557 if (TS_set_scroll_region
)
558 buf
= tparam (TS_set_scroll_region
, 0, 0, start
, stop
- 1);
559 else if (TS_set_scroll_region_1
)
560 buf
= tparam (TS_set_scroll_region_1
, 0, 0,
561 FRAME_LINES (sf
), start
,
562 FRAME_LINES (sf
) - stop
,
565 buf
= tparam (TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (sf
));
577 OUTPUT (TS_insert_mode
);
585 OUTPUT (TS_end_insert_mode
);
589 /* Handle highlighting. */
592 turn_off_highlight ()
595 OUTPUT_IF (TS_end_standout_mode
);
603 OUTPUT_IF (TS_standout_mode
);
611 turn_off_highlight ();
613 turn_on_highlight ();
617 /* Make cursor invisible. */
622 if (tty_cursor_hidden
== 0)
624 tty_cursor_hidden
= 1;
625 OUTPUT_IF (TS_cursor_invisible
);
630 /* Ensure that cursor is visible. */
635 if (tty_cursor_hidden
)
637 tty_cursor_hidden
= 0;
638 OUTPUT_IF (TS_cursor_normal
);
640 OUTPUT_IF (TS_cursor_visible
);
645 /* Set standout mode to the state it should be in for
646 empty space inside windows. What this is,
647 depends on the user option inverse-video. */
650 background_highlight ()
653 turn_on_highlight ();
655 turn_off_highlight ();
658 /* Set standout mode to the mode specified for the text to be output. */
661 highlight_if_desired ()
664 turn_on_highlight ();
666 turn_off_highlight ();
670 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
671 frame-relative coordinates. */
674 cursor_to (vpos
, hpos
)
677 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
679 if (! FRAME_TERMCAP_P (f
) && cursor_to_hook
)
681 (*cursor_to_hook
) (vpos
, hpos
);
685 /* Detect the case where we are called from reset_sys_modes
686 and the costs have never been calculated. Do nothing. */
690 if (curY
== vpos
&& curX
== hpos
)
692 if (!TF_standout_motion
)
693 background_highlight ();
694 if (!TF_insmode_motion
)
699 /* Similar but don't take any account of the wasted characters. */
702 raw_cursor_to (row
, col
)
705 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
706 if (! FRAME_TERMCAP_P (f
))
708 (*raw_cursor_to_hook
) (row
, col
);
711 if (curY
== row
&& curX
== col
)
713 if (!TF_standout_motion
)
714 background_highlight ();
715 if (!TF_insmode_motion
)
720 /* Erase operations */
722 /* clear from cursor to end of frame */
728 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
730 (*clear_to_end_hook
) ();
733 if (TS_clr_to_bottom
)
735 background_highlight ();
736 OUTPUT (TS_clr_to_bottom
);
740 for (i
= curY
; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
743 clear_end_of_line (FRAME_COLS (XFRAME (selected_frame
)));
748 /* Clear entire frame */
753 struct frame
*sf
= XFRAME (selected_frame
);
756 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: sf
)))
758 (*clear_frame_hook
) ();
763 background_highlight ();
764 OUTPUT (TS_clr_frame
);
774 /* Clear from cursor to end of line.
775 Assume that the line is already clear starting at column first_unused_hpos.
777 Note that the cursor may be moved, on terminals lacking a `ce' string. */
780 clear_end_of_line (first_unused_hpos
)
781 int first_unused_hpos
;
785 if (clear_end_of_line_hook
786 && ! FRAME_TERMCAP_P ((updating_frame
788 : XFRAME (selected_frame
))))
790 (*clear_end_of_line_hook
) (first_unused_hpos
);
794 /* Detect the case where we are called from reset_sys_modes
795 and the costs have never been calculated. Do nothing. */
799 if (curX
>= first_unused_hpos
)
801 background_highlight ();
804 OUTPUT1 (TS_clr_line
);
807 { /* have to do it the hard way */
808 struct frame
*sf
= XFRAME (selected_frame
);
811 /* Do not write in last row last col with Auto-wrap on. */
812 if (AutoWrap
&& curY
== FRAME_LINES (sf
) - 1
813 && first_unused_hpos
== FRAME_COLS (sf
))
816 for (i
= curX
; i
< first_unused_hpos
; i
++)
819 fputc (' ', termscript
);
822 cmplus (first_unused_hpos
- curX
);
826 /* Buffer to store the source and result of code conversion for terminal. */
827 static unsigned char *encode_terminal_buf
;
828 /* Allocated size of the above buffer. */
829 static int encode_terminal_bufsize
;
831 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
832 Set CODING->produced to the byte-length of the resulting byte
833 sequence, and return a pointer to that byte sequence. */
836 encode_terminal_code (src
, src_len
, coding
)
839 struct coding_system
*coding
;
841 struct glyph
*src_end
= src
+ src_len
;
844 int nchars
, nbytes
, required
;
845 register int tlen
= GLYPH_TABLE_LENGTH
;
846 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
848 /* Allocate sufficient size of buffer to store all characters in
849 multibyte-form. But, it may be enlarged on demand if
850 Vglyph_table contains a string. */
851 required
= MAX_MULTIBYTE_LENGTH
* src_len
;
852 if (encode_terminal_bufsize
< required
)
854 if (encode_terminal_bufsize
== 0)
855 encode_terminal_buf
= xmalloc (required
);
857 encode_terminal_buf
= xrealloc (encode_terminal_buf
, required
);
858 encode_terminal_bufsize
= required
;
861 buf
= encode_terminal_buf
;
863 while (src
< src_end
)
865 /* We must skip glyphs to be padded for a wide character. */
866 if (! CHAR_GLYPH_PADDING_P (*src
))
868 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
870 if (g
< 0 || g
>= tlen
)
872 /* This glyph doesn't has an entry in Vglyph_table. */
873 if (CHAR_VALID_P (src
->u
.ch
, 0))
874 buf
+= CHAR_STRING (src
->u
.ch
, buf
);
881 /* This glyph has an entry in Vglyph_table,
882 so process any alias before testing for simpleness. */
883 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
885 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
887 int c
= FAST_GLYPH_CHAR (g
);
889 if (CHAR_VALID_P (c
, 0))
890 buf
+= CHAR_STRING (c
, buf
);
897 /* We have a string in Vglyph_table. */
901 if (! STRING_MULTIBYTE (string
))
902 string
= string_to_multibyte (string
);
903 nbytes
= buf
- encode_terminal_buf
;
904 if (encode_terminal_bufsize
< nbytes
+ SBYTES (string
))
906 encode_terminal_bufsize
= nbytes
+ SBYTES (string
);
907 encode_terminal_buf
= xrealloc (encode_terminal_buf
,
908 encode_terminal_bufsize
);
909 buf
= encode_terminal_buf
+ nbytes
;
911 bcopy (SDATA (string
), buf
, SBYTES (string
));
912 buf
+= SBYTES (string
);
913 nchars
+= SCHARS (string
);
920 nbytes
= buf
- encode_terminal_buf
;
921 coding
->src_multibyte
= 1;
922 coding
->dst_multibyte
= 0;
923 if (SYMBOLP (coding
->pre_write_conversion
)
924 && ! NILP (Ffboundp (coding
->pre_write_conversion
)))
926 run_pre_write_conversin_on_c_str (&encode_terminal_buf
,
927 &encode_terminal_bufsize
,
928 nchars
, nbytes
, coding
);
929 nchars
= coding
->produced_char
;
930 nbytes
= coding
->produced
;
932 required
= nbytes
+ encoding_buffer_size (coding
, nbytes
);
933 if (encode_terminal_bufsize
< required
)
935 encode_terminal_bufsize
= required
;
936 encode_terminal_buf
= xrealloc (encode_terminal_buf
, required
);
939 encode_coding (coding
, encode_terminal_buf
, encode_terminal_buf
+ nbytes
,
940 nbytes
, encode_terminal_bufsize
- nbytes
);
941 return encode_terminal_buf
+ nbytes
;
945 write_glyphs (string
, len
)
946 register struct glyph
*string
;
949 struct frame
*sf
= XFRAME (selected_frame
);
950 struct frame
*f
= updating_frame
? updating_frame
: sf
;
951 unsigned char *conversion_buffer
;
952 struct coding_system
*coding
;
954 if (write_glyphs_hook
955 && ! FRAME_TERMCAP_P (f
))
957 (*write_glyphs_hook
) (string
, len
);
964 /* Don't dare write in last column of bottom line, if Auto-Wrap,
965 since that would scroll the whole frame on some terminals. */
968 && curY
+ 1 == FRAME_LINES (sf
)
969 && (curX
+ len
) == FRAME_COLS (sf
))
976 /* If terminal_coding does any conversion, use it, otherwise use
977 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
978 because it always return 1 if the member src_multibyte is 1. */
979 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
980 ? &terminal_coding
: &safe_terminal_coding
);
981 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
983 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
987 /* Identify a run of glyphs with the same face. */
988 int face_id
= string
->face_id
;
991 for (n
= 1; n
< len
; ++n
)
992 if (string
[n
].face_id
!= face_id
)
995 /* Turn appearance modes of the face of the run on. */
996 highlight_if_desired ();
997 turn_on_face (f
, face_id
);
1000 /* This is the last run. */
1001 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
1002 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
1003 if (coding
->produced
> 0)
1006 fwrite (conversion_buffer
, 1, coding
->produced
, stdout
);
1007 if (ferror (stdout
))
1010 fwrite (conversion_buffer
, 1, coding
->produced
, termscript
);
1016 /* Turn appearance modes off. */
1017 turn_off_face (f
, face_id
);
1018 turn_off_highlight ();
1025 write_glyphs_with_face (string
, len
, face_id
)
1026 register struct glyph
*string
;
1027 register int len
, face_id
;
1029 struct frame
*sf
= XFRAME (selected_frame
);
1030 struct frame
*f
= updating_frame
? updating_frame
: sf
;
1031 unsigned char *conversion_buffer
;
1032 struct coding_system
*coding
;
1037 /* Don't dare write in last column of bottom line, if Auto-Wrap,
1038 since that would scroll the whole frame on some terminals. */
1041 && curY
+ 1 == FRAME_LINES (sf
)
1042 && (curX
+ len
) == FRAME_COLS (sf
))
1049 /* If terminal_coding does any conversion, use it, otherwise use
1050 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
1051 because it always return 1 if the member src_multibyte is 1. */
1052 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
1053 ? &terminal_coding
: &safe_terminal_coding
);
1054 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1056 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
1059 /* Turn appearance modes of the face. */
1060 highlight_if_desired ();
1061 turn_on_face (f
, face_id
);
1063 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
1064 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
1065 if (coding
->produced
> 0)
1068 fwrite (conversion_buffer
, 1, coding
->produced
, stdout
);
1069 if (ferror (stdout
))
1072 fwrite (conversion_buffer
, 1, coding
->produced
, termscript
);
1076 /* Turn appearance modes off. */
1077 turn_off_face (f
, face_id
);
1078 turn_off_highlight ();
1083 /* If start is zero, insert blanks instead of a string at start */
1086 insert_glyphs (start
, len
)
1087 register struct glyph
*start
;
1091 struct glyph
*glyph
= NULL
;
1092 struct frame
*f
, *sf
;
1093 unsigned char *conversion_buffer
;
1094 unsigned char space
[1];
1095 struct coding_system
*coding
;
1100 if (insert_glyphs_hook
)
1102 (*insert_glyphs_hook
) (start
, len
);
1106 sf
= XFRAME (selected_frame
);
1107 f
= updating_frame
? updating_frame
: sf
;
1109 if (TS_ins_multi_chars
)
1111 buf
= tparam (TS_ins_multi_chars
, 0, 0, len
);
1115 write_glyphs (start
, len
);
1123 space
[0] = SPACEGLYPH
;
1125 /* If terminal_coding does any conversion, use it, otherwise use
1126 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
1127 because it always return 1 if the member src_multibyte is 1. */
1128 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
1129 ? &terminal_coding
: &safe_terminal_coding
);
1130 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1132 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
1136 OUTPUT1_IF (TS_ins_char
);
1139 conversion_buffer
= space
;
1140 coding
->produced
= 1;
1144 highlight_if_desired ();
1145 turn_on_face (f
, start
->face_id
);
1148 /* We must open sufficient space for a character which
1149 occupies more than one column. */
1150 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
1152 OUTPUT1_IF (TS_ins_char
);
1157 /* This is the last glyph. */
1158 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
1160 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
1163 if (coding
->produced
> 0)
1166 fwrite (conversion_buffer
, 1, coding
->produced
, stdout
);
1167 if (ferror (stdout
))
1170 fwrite (conversion_buffer
, 1, coding
->produced
, termscript
);
1174 OUTPUT1_IF (TS_pad_inserted_char
);
1177 turn_off_face (f
, glyph
->face_id
);
1178 turn_off_highlight ();
1192 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1194 (*delete_glyphs_hook
) (n
);
1198 if (delete_in_insert_mode
)
1205 OUTPUT_IF (TS_delete_mode
);
1208 if (TS_del_multi_chars
)
1210 buf
= tparam (TS_del_multi_chars
, 0, 0, n
);
1215 for (i
= 0; i
< n
; i
++)
1216 OUTPUT1 (TS_del_char
);
1217 if (!delete_in_insert_mode
)
1218 OUTPUT_IF (TS_end_delete_mode
);
1221 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1224 ins_del_lines (vpos
, n
)
1227 char *multi
= n
> 0 ? TS_ins_multi_lines
: TS_del_multi_lines
;
1228 char *single
= n
> 0 ? TS_ins_line
: TS_del_line
;
1229 char *scroll
= n
> 0 ? TS_rev_scroll
: TS_fwd_scroll
;
1232 register int i
= n
> 0 ? n
: -n
;
1235 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1237 (*ins_del_lines_hook
) (vpos
, n
);
1241 sf
= XFRAME (selected_frame
);
1243 /* If the lines below the insertion are being pushed
1244 into the end of the window, this is the same as clearing;
1245 and we know the lines are already clear, since the matching
1246 deletion has already been done. So can ignore this. */
1247 /* If the lines below the deletion are blank lines coming
1248 out of the end of the window, don't bother,
1249 as there will be a matching inslines later that will flush them. */
1250 if (scroll_region_ok
&& vpos
+ i
>= specified_window
)
1252 if (!memory_below_frame
&& vpos
+ i
>= FRAME_LINES (sf
))
1257 raw_cursor_to (vpos
, 0);
1258 background_highlight ();
1259 buf
= tparam (multi
, 0, 0, i
);
1265 raw_cursor_to (vpos
, 0);
1266 background_highlight ();
1274 set_scroll_region (vpos
, specified_window
);
1276 raw_cursor_to (specified_window
- 1, 0);
1278 raw_cursor_to (vpos
, 0);
1279 background_highlight ();
1281 OUTPUTL (scroll
, specified_window
- vpos
);
1282 set_scroll_region (0, specified_window
);
1285 if (!scroll_region_ok
&& memory_below_frame
&& n
< 0)
1287 cursor_to (FRAME_LINES (sf
) + n
, 0);
1292 /* Compute cost of sending "str", in characters,
1293 not counting any line-dependent padding. */
1301 tputs (str
, 0, evalcost
);
1305 /* Compute cost of sending "str", in characters,
1306 counting any line-dependent padding at one line. */
1309 string_cost_one_line (str
)
1314 tputs (str
, 1, evalcost
);
1318 /* Compute per line amount of line-dependent padding,
1319 in tenths of characters. */
1327 tputs (str
, 0, evalcost
);
1330 tputs (str
, 10, evalcost
);
1335 /* char_ins_del_cost[n] is cost of inserting N characters.
1336 char_ins_del_cost[-n] is cost of deleting N characters.
1337 The length of this vector is based on max_frame_cols. */
1339 int *char_ins_del_vector
;
1341 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1346 calculate_ins_del_char_costs (frame
)
1349 int ins_startup_cost
, del_startup_cost
;
1350 int ins_cost_per_char
, del_cost_per_char
;
1354 if (TS_ins_multi_chars
)
1356 ins_cost_per_char
= 0;
1357 ins_startup_cost
= string_cost_one_line (TS_ins_multi_chars
);
1359 else if (TS_ins_char
|| TS_pad_inserted_char
1360 || (TS_insert_mode
&& TS_end_insert_mode
))
1362 ins_startup_cost
= (30 * (string_cost (TS_insert_mode
)
1363 + string_cost (TS_end_insert_mode
))) / 100;
1364 ins_cost_per_char
= (string_cost_one_line (TS_ins_char
)
1365 + string_cost_one_line (TS_pad_inserted_char
));
1369 ins_startup_cost
= 9999;
1370 ins_cost_per_char
= 0;
1373 if (TS_del_multi_chars
)
1375 del_cost_per_char
= 0;
1376 del_startup_cost
= string_cost_one_line (TS_del_multi_chars
);
1378 else if (TS_del_char
)
1380 del_startup_cost
= (string_cost (TS_delete_mode
)
1381 + string_cost (TS_end_delete_mode
));
1382 if (delete_in_insert_mode
)
1383 del_startup_cost
/= 2;
1384 del_cost_per_char
= string_cost_one_line (TS_del_char
);
1388 del_startup_cost
= 9999;
1389 del_cost_per_char
= 0;
1392 /* Delete costs are at negative offsets */
1393 p
= &char_ins_del_cost (frame
)[0];
1394 for (i
= FRAME_COLS (frame
); --i
>= 0;)
1395 *--p
= (del_startup_cost
+= del_cost_per_char
);
1397 /* Doing nothing is free */
1398 p
= &char_ins_del_cost (frame
)[0];
1401 /* Insert costs are at positive offsets */
1402 for (i
= FRAME_COLS (frame
); --i
>= 0;)
1403 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1407 calculate_costs (frame
)
1410 register char *f
= (TS_set_scroll_region
1411 ? TS_set_scroll_region
1412 : TS_set_scroll_region_1
);
1414 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1416 scroll_region_cost
= string_cost (f
);
1418 /* These variables are only used for terminal stuff. They are allocated
1419 once for the terminal frame of X-windows emacs, but not used afterwards.
1421 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1422 X turns off char_ins_del_ok. */
1424 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1425 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1429 if (char_ins_del_vector
!= 0)
1431 = (int *) xrealloc (char_ins_del_vector
,
1433 + 2 * max_frame_cols
* sizeof (int)));
1436 = (int *) xmalloc (sizeof (int)
1437 + 2 * max_frame_cols
* sizeof (int));
1439 bzero (char_ins_del_vector
, (sizeof (int)
1440 + 2 * max_frame_cols
* sizeof (int)));
1442 if (f
&& (!TS_ins_line
&& !TS_del_line
))
1443 do_line_insertion_deletion_costs (frame
,
1444 TS_rev_scroll
, TS_ins_multi_lines
,
1445 TS_fwd_scroll
, TS_del_multi_lines
,
1448 do_line_insertion_deletion_costs (frame
,
1449 TS_ins_line
, TS_ins_multi_lines
,
1450 TS_del_line
, TS_del_multi_lines
,
1453 calculate_ins_del_char_costs (frame
);
1455 /* Don't use TS_repeat if its padding is worse than sending the chars */
1456 if (TS_repeat
&& per_line_cost (TS_repeat
) * baud_rate
< 9000)
1457 RPov
= string_cost (TS_repeat
);
1459 RPov
= FRAME_COLS (frame
) * 2;
1461 cmcostinit (); /* set up cursor motion costs */
1468 /* Termcap capability names that correspond directly to X keysyms.
1469 Some of these (marked "terminfo") aren't supplied by old-style
1470 (Berkeley) termcap entries. They're listed in X keysym order;
1471 except we put the keypad keys first, so that if they clash with
1472 other keys (as on the IBM PC keyboard) they get overridden.
1475 static struct fkey_table keys
[] =
1477 {"kh", "home"}, /* termcap */
1478 {"kl", "left"}, /* termcap */
1479 {"ku", "up"}, /* termcap */
1480 {"kr", "right"}, /* termcap */
1481 {"kd", "down"}, /* termcap */
1482 {"%8", "prior"}, /* terminfo */
1483 {"%5", "next"}, /* terminfo */
1484 {"@7", "end"}, /* terminfo */
1485 {"@1", "begin"}, /* terminfo */
1486 {"*6", "select"}, /* terminfo */
1487 {"%9", "print"}, /* terminfo */
1488 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1490 * "insert" --- see below
1492 {"&8", "undo"}, /* terminfo */
1493 {"%0", "redo"}, /* terminfo */
1494 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1495 {"@0", "find"}, /* terminfo */
1496 {"@2", "cancel"}, /* terminfo */
1497 {"%1", "help"}, /* terminfo */
1499 * "break" goes here, but can't be reliably intercepted with termcap
1501 {"&4", "reset"}, /* terminfo --- actually `restart' */
1503 * "system" and "user" --- no termcaps
1505 {"kE", "clearline"}, /* terminfo */
1506 {"kA", "insertline"}, /* terminfo */
1507 {"kL", "deleteline"}, /* terminfo */
1508 {"kI", "insertchar"}, /* terminfo */
1509 {"kD", "deletechar"}, /* terminfo */
1510 {"kB", "backtab"}, /* terminfo */
1512 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1514 {"@8", "kp-enter"}, /* terminfo */
1516 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1517 * "kp-multiply", "kp-add", "kp-separator",
1518 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1519 * --- no termcaps for any of these.
1521 {"K4", "kp-1"}, /* terminfo */
1523 * "kp-2" --- no termcap
1525 {"K5", "kp-3"}, /* terminfo */
1527 * "kp-4" --- no termcap
1529 {"K2", "kp-5"}, /* terminfo */
1531 * "kp-6" --- no termcap
1533 {"K1", "kp-7"}, /* terminfo */
1535 * "kp-8" --- no termcap
1537 {"K3", "kp-9"}, /* terminfo */
1539 * "kp-equal" --- no termcap
1551 {"&0", "S-cancel"}, /*shifted cancel key*/
1552 {"&9", "S-begin"}, /*shifted begin key*/
1553 {"*0", "S-find"}, /*shifted find key*/
1554 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1555 {"*4", "S-delete"}, /*shifted delete-character key*/
1556 {"*7", "S-end"}, /*shifted end key*/
1557 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1558 {"#1", "S-help"}, /*shifted help key*/
1559 {"#2", "S-home"}, /*shifted home key*/
1560 {"#3", "S-insert"}, /*shifted insert-character key*/
1561 {"#4", "S-left"}, /*shifted left-arrow key*/
1562 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1563 {"%c", "S-next"}, /*shifted next key*/
1564 {"%e", "S-prior"}, /*shifted previous key*/
1565 {"%f", "S-print"}, /*shifted print key*/
1566 {"%g", "S-redo"}, /*shifted redo key*/
1567 {"%i", "S-right"}, /*shifted right-arrow key*/
1568 {"!3", "S-undo"} /*shifted undo key*/
1571 static char **term_get_fkeys_arg
;
1572 static Lisp_Object
term_get_fkeys_1 ();
1574 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1575 This function scans the termcap function key sequence entries, and
1576 adds entries to Vfunction_key_map for each function key it finds. */
1579 term_get_fkeys (address
)
1582 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1583 errors during the call. The only errors should be from Fdefine_key
1584 when given a key sequence containing an invalid prefix key. If the
1585 termcap defines function keys which use a prefix that is already bound
1586 to a command by the default bindings, we should silently ignore that
1587 function key specification, rather than giving the user an error and
1588 refusing to run at all on such a terminal. */
1590 extern Lisp_Object
Fidentity ();
1591 term_get_fkeys_arg
= address
;
1592 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1600 char **address
= term_get_fkeys_arg
;
1602 /* This can happen if CANNOT_DUMP or with strange options. */
1604 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1606 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1608 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1610 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1611 Fmake_vector (make_number (1),
1612 intern (keys
[i
].name
)));
1615 /* The uses of the "k0" capability are inconsistent; sometimes it
1616 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1617 We will attempt to politely accommodate both systems by testing for
1618 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1621 char *k_semi
= tgetstr ("k;", address
);
1622 char *k0
= tgetstr ("k0", address
);
1623 char *k0_name
= "f10";
1628 /* Define f0 first, so that f10 takes precedence in case the
1629 key sequences happens to be the same. */
1630 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1631 Fmake_vector (make_number (1), intern ("f0")));
1632 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1633 Fmake_vector (make_number (1), intern ("f10")));
1636 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1637 Fmake_vector (make_number (1), intern (k0_name
)));
1640 /* Set up cookies for numbered function keys above f10. */
1642 char fcap
[3], fkey
[4];
1644 fcap
[0] = 'F'; fcap
[2] = '\0';
1645 for (i
= 11; i
< 64; i
++)
1648 fcap
[1] = '1' + i
- 11;
1650 fcap
[1] = 'A' + i
- 20;
1652 fcap
[1] = 'a' + i
- 46;
1655 char *sequence
= tgetstr (fcap
, address
);
1658 sprintf (fkey
, "f%d", i
);
1659 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1660 Fmake_vector (make_number (1),
1668 * Various mappings to try and get a better fit.
1671 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1672 if (!tgetstr (cap1, address)) \
1674 char *sequence = tgetstr (cap2, address); \
1676 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1677 Fmake_vector (make_number (1), \
1681 /* if there's no key_next keycap, map key_npage to `next' keysym */
1682 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1683 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1684 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1685 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1686 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1687 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1688 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1690 /* IBM has their own non-standard dialect of terminfo.
1691 If the standard name isn't found, try the IBM name. */
1692 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1693 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1694 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1695 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1696 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1697 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1698 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1699 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1700 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1701 #undef CONDITIONAL_REASSIGN
1708 /***********************************************************************
1709 Character Display Information
1710 ***********************************************************************/
1712 /* Avoid name clash with functions defined in xterm.c */
1714 #define append_glyph append_glyph_term
1715 #define produce_stretch_glyph produce_stretch_glyph_term
1718 static void append_glyph
P_ ((struct it
*));
1719 static void produce_stretch_glyph
P_ ((struct it
*));
1722 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1723 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1724 the character for which to produce glyphs; IT->face_id contains the
1725 character's face. Padding glyphs are appended if IT->c has a
1726 IT->pixel_width > 1. */
1732 struct glyph
*glyph
, *end
;
1735 xassert (it
->glyph_row
);
1736 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1737 + it
->glyph_row
->used
[it
->area
]);
1738 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1741 i
< it
->pixel_width
&& glyph
< end
;
1744 glyph
->type
= CHAR_GLYPH
;
1745 glyph
->pixel_width
= 1;
1746 glyph
->u
.ch
= it
->char_to_display
;
1747 glyph
->face_id
= it
->face_id
;
1748 glyph
->padding_p
= i
> 0;
1749 glyph
->charpos
= CHARPOS (it
->position
);
1750 glyph
->object
= it
->object
;
1752 ++it
->glyph_row
->used
[it
->area
];
1758 /* Produce glyphs for the display element described by IT. *IT
1759 specifies what we want to produce a glyph for (character, image, ...),
1760 and where in the glyph matrix we currently are (glyph row and hpos).
1761 produce_glyphs fills in output fields of *IT with information such as the
1762 pixel width and height of a character, and maybe output actual glyphs at
1763 the same time if IT->glyph_row is non-null. See the explanation of
1764 struct display_iterator in dispextern.h for an overview.
1766 produce_glyphs also stores the result of glyph width, ascent
1767 etc. computations in *IT.
1769 IT->glyph_row may be null, in which case produce_glyphs does not
1770 actually fill in the glyphs. This is used in the move_* functions
1771 in xdisp.c for text width and height computations.
1773 Callers usually don't call produce_glyphs directly;
1774 instead they use the macro PRODUCE_GLYPHS. */
1780 /* If a hook is installed, let it do the work. */
1781 xassert (it
->what
== IT_CHARACTER
1782 || it
->what
== IT_COMPOSITION
1783 || it
->what
== IT_STRETCH
);
1785 if (it
->what
== IT_STRETCH
)
1787 produce_stretch_glyph (it
);
1791 /* Nothing but characters are supported on terminal frames. For a
1792 composition sequence, it->c is the first character of the
1794 xassert (it
->what
== IT_CHARACTER
1795 || it
->what
== IT_COMPOSITION
);
1797 /* Maybe translate single-byte characters to multibyte. */
1798 it
->char_to_display
= it
->c
;
1800 if (it
->c
>= 040 && it
->c
< 0177)
1802 it
->pixel_width
= it
->nglyphs
= 1;
1806 else if (it
->c
== '\n')
1807 it
->pixel_width
= it
->nglyphs
= 0;
1808 else if (it
->c
== '\t')
1810 int absolute_x
= (it
->current_x
1811 + it
->continuation_lines_width
);
1813 = (((1 + absolute_x
+ it
->tab_width
- 1)
1818 /* If part of the TAB has been displayed on the previous line
1819 which is continued now, continuation_lines_width will have
1820 been incremented already by the part that fitted on the
1821 continued line. So, we will get the right number of spaces
1823 nspaces
= next_tab_x
- absolute_x
;
1829 it
->char_to_display
= ' ';
1830 it
->pixel_width
= it
->len
= 1;
1836 it
->pixel_width
= nspaces
;
1837 it
->nglyphs
= nspaces
;
1839 else if (SINGLE_BYTE_CHAR_P (it
->c
))
1841 if (unibyte_display_via_language_environment
1843 || !NILP (Vnonascii_translation_table
)))
1847 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1848 charset
= CHAR_CHARSET (it
->char_to_display
);
1849 it
->pixel_width
= CHARSET_WIDTH (charset
);
1850 it
->nglyphs
= it
->pixel_width
;
1856 /* Coming here means that it->c is from display table, thus we
1857 must send the code as is to the terminal. Although there's
1858 no way to know how many columns it occupies on a screen, it
1859 is a good assumption that a single byte code has 1-column
1861 it
->pixel_width
= it
->nglyphs
= 1;
1868 /* A multi-byte character. The display width is fixed for all
1869 characters of the set. Some of the glyphs may have to be
1870 ignored because they are already displayed in a continued
1872 int charset
= CHAR_CHARSET (it
->c
);
1874 it
->pixel_width
= CHARSET_WIDTH (charset
);
1875 it
->nglyphs
= it
->pixel_width
;
1882 /* Advance current_x by the pixel width as a convenience for
1884 if (it
->area
== TEXT_AREA
)
1885 it
->current_x
+= it
->pixel_width
;
1886 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1887 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1891 /* Produce a stretch glyph for iterator IT. IT->object is the value
1892 of the glyph property displayed. The value must be a list
1893 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1896 1. `:width WIDTH' specifies that the space should be WIDTH *
1897 canonical char width wide. WIDTH may be an integer or floating
1900 2. `:align-to HPOS' specifies that the space should be wide enough
1901 to reach HPOS, a value in canonical character units. */
1904 produce_stretch_glyph (it
)
1907 /* (space :width WIDTH ...) */
1908 Lisp_Object prop
, plist
;
1909 int width
= 0, align_to
= -1;
1910 int zero_width_ok_p
= 0;
1913 /* List should start with `space'. */
1914 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1915 plist
= XCDR (it
->object
);
1917 /* Compute the width of the stretch. */
1918 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1919 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1921 /* Absolute width `:width WIDTH' specified and valid. */
1922 zero_width_ok_p
= 1;
1923 width
= (int)(tem
+ 0.5);
1925 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1926 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1928 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1929 align_to
= (align_to
< 0
1931 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1932 else if (align_to
< 0)
1933 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1934 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1935 zero_width_ok_p
= 1;
1938 /* Nothing specified -> width defaults to canonical char width. */
1939 width
= FRAME_COLUMN_WIDTH (it
->f
);
1941 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
1944 if (width
> 0 && it
->glyph_row
)
1946 Lisp_Object o_object
= it
->object
;
1947 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1950 if (!STRINGP (object
))
1951 object
= it
->w
->buffer
;
1952 it
->object
= object
;
1953 it
->char_to_display
= ' ';
1954 it
->pixel_width
= it
->len
= 1;
1957 it
->object
= o_object
;
1959 it
->pixel_width
= width
;
1960 it
->nglyphs
= width
;
1964 /* Get information about special display element WHAT in an
1965 environment described by IT. WHAT is one of IT_TRUNCATION or
1966 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
1967 non-null glyph_row member. This function ensures that fields like
1968 face_id, c, len of IT are left untouched. */
1971 produce_special_glyphs (it
, what
)
1973 enum display_element_type what
;
1980 temp_it
.what
= IT_CHARACTER
;
1982 temp_it
.object
= make_number (0);
1983 bzero (&temp_it
.current
, sizeof temp_it
.current
);
1985 if (what
== IT_CONTINUATION
)
1987 /* Continuation glyph. */
1989 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
1990 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
1992 glyph
= XINT (DISP_CONTINUE_GLYPH (it
->dp
));
1993 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
1998 else if (what
== IT_TRUNCATION
)
2000 /* Truncation glyph. */
2002 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
2003 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
2005 glyph
= XINT (DISP_TRUNC_GLYPH (it
->dp
));
2006 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
2014 temp_it
.c
= FAST_GLYPH_CHAR (glyph
);
2015 temp_it
.face_id
= FAST_GLYPH_FACE (glyph
);
2016 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
2018 produce_glyphs (&temp_it
);
2019 it
->pixel_width
= temp_it
.pixel_width
;
2020 it
->nglyphs
= temp_it
.pixel_width
;
2025 /***********************************************************************
2027 ***********************************************************************/
2029 /* Value is non-zero if attribute ATTR may be used. ATTR should be
2030 one of the enumerators from enum no_color_bit, or a bit set built
2031 from them. Some display attributes may not be used together with
2032 color; the termcap capability `NC' specifies which ones. */
2034 #define MAY_USE_WITH_COLORS_P(ATTR) \
2035 (TN_max_colors > 0 \
2036 ? (TN_no_color_video & (ATTR)) == 0 \
2039 /* Turn appearances of face FACE_ID on tty frame F on.
2040 FACE_ID is a realized face ID number, in the face cache. */
2043 turn_on_face (f
, face_id
)
2047 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2048 long fg
= face
->foreground
;
2049 long bg
= face
->background
;
2051 /* Do this first because TS_end_standout_mode may be the same
2052 as TS_exit_attribute_mode, which turns all appearances off. */
2053 if (MAY_USE_WITH_COLORS_P (NC_REVERSE
))
2055 if (TN_max_colors
> 0)
2057 if (fg
>= 0 && bg
>= 0)
2059 /* If the terminal supports colors, we can set them
2060 below without using reverse video. The face's fg
2061 and bg colors are set as they should appear on
2062 the screen, i.e. they take the inverse-video'ness
2063 of the face already into account. */
2065 else if (inverse_video
)
2067 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
2068 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
2069 toggle_highlight ();
2073 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
2074 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
2075 toggle_highlight ();
2080 /* If we can't display colors, use reverse video
2081 if the face specifies that. */
2084 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
2085 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
2086 toggle_highlight ();
2090 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
2091 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
2092 toggle_highlight ();
2097 if (face
->tty_bold_p
)
2099 if (MAY_USE_WITH_COLORS_P (NC_BOLD
))
2100 OUTPUT1_IF (TS_enter_bold_mode
);
2102 else if (face
->tty_dim_p
)
2103 if (MAY_USE_WITH_COLORS_P (NC_DIM
))
2104 OUTPUT1_IF (TS_enter_dim_mode
);
2106 /* Alternate charset and blinking not yet used. */
2107 if (face
->tty_alt_charset_p
2108 && MAY_USE_WITH_COLORS_P (NC_ALT_CHARSET
))
2109 OUTPUT1_IF (TS_enter_alt_charset_mode
);
2111 if (face
->tty_blinking_p
2112 && MAY_USE_WITH_COLORS_P (NC_BLINK
))
2113 OUTPUT1_IF (TS_enter_blink_mode
);
2115 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (NC_UNDERLINE
))
2116 OUTPUT1_IF (TS_enter_underline_mode
);
2118 if (TN_max_colors
> 0)
2122 ts
= standout_mode
? TS_set_background
: TS_set_foreground
;
2125 p
= tparam (ts
, NULL
, 0, (int) fg
);
2130 ts
= standout_mode
? TS_set_foreground
: TS_set_background
;
2133 p
= tparam (ts
, NULL
, 0, (int) bg
);
2141 /* Turn off appearances of face FACE_ID on tty frame F. */
2144 turn_off_face (f
, face_id
)
2148 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2150 xassert (face
!= NULL
);
2152 if (TS_exit_attribute_mode
)
2154 /* Capability "me" will turn off appearance modes double-bright,
2155 half-bright, reverse-video, standout, underline. It may or
2156 may not turn off alt-char-mode. */
2157 if (face
->tty_bold_p
2159 || face
->tty_reverse_p
2160 || face
->tty_alt_charset_p
2161 || face
->tty_blinking_p
2162 || face
->tty_underline_p
)
2164 OUTPUT1_IF (TS_exit_attribute_mode
);
2165 if (strcmp (TS_exit_attribute_mode
, TS_end_standout_mode
) == 0)
2169 if (face
->tty_alt_charset_p
)
2170 OUTPUT_IF (TS_exit_alt_charset_mode
);
2174 /* If we don't have "me" we can only have those appearances
2175 that have exit sequences defined. */
2176 if (face
->tty_alt_charset_p
)
2177 OUTPUT_IF (TS_exit_alt_charset_mode
);
2179 if (face
->tty_underline_p
)
2180 OUTPUT_IF (TS_exit_underline_mode
);
2183 /* Switch back to default colors. */
2184 if (TN_max_colors
> 0
2185 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2186 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2187 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2188 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2189 OUTPUT1_IF (TS_orig_pair
);
2193 /* Return non-zero if the terminal on frame F supports all of the
2194 capabilities in CAPS simultaneously, with foreground and background
2195 colors FG and BG. */
2198 tty_capable_p (f
, caps
, fg
, bg
)
2201 unsigned long fg
, bg
;
2203 #define TTY_CAPABLE_P_TRY(cap, TS, NC_bit) \
2204 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(NC_bit))) \
2207 TTY_CAPABLE_P_TRY (TTY_CAP_INVERSE
, TS_standout_mode
, NC_REVERSE
);
2208 TTY_CAPABLE_P_TRY (TTY_CAP_UNDERLINE
, TS_enter_underline_mode
, NC_UNDERLINE
);
2209 TTY_CAPABLE_P_TRY (TTY_CAP_BOLD
, TS_enter_bold_mode
, NC_BOLD
);
2210 TTY_CAPABLE_P_TRY (TTY_CAP_DIM
, TS_enter_dim_mode
, NC_DIM
);
2211 TTY_CAPABLE_P_TRY (TTY_CAP_BLINK
, TS_enter_blink_mode
, NC_BLINK
);
2212 TTY_CAPABLE_P_TRY (TTY_CAP_ALT_CHARSET
, TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
2219 /* Return non-zero if the terminal is capable to display colors. */
2221 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2223 doc
: /* Return non-nil if TTY can display colors on DISPLAY. */)
2225 Lisp_Object display
;
2227 return TN_max_colors
> 0 ? Qt
: Qnil
;
2230 /* Return the number of supported colors. */
2231 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2232 Stty_display_color_cells
, 0, 1, 0,
2233 doc
: /* Return the number of colors supported by TTY on DISPLAY. */)
2235 Lisp_Object display
;
2237 return make_number (TN_max_colors
);
2242 /* Save or restore the default color-related capabilities of this
2245 tty_default_color_capabilities (save
)
2249 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
2250 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
2254 if (default_orig_pair
)
2255 xfree (default_orig_pair
);
2256 default_orig_pair
= TS_orig_pair
? xstrdup (TS_orig_pair
) : NULL
;
2258 if (default_set_foreground
)
2259 xfree (default_set_foreground
);
2260 default_set_foreground
= TS_set_foreground
? xstrdup (TS_set_foreground
)
2263 if (default_set_background
)
2264 xfree (default_set_background
);
2265 default_set_background
= TS_set_background
? xstrdup (TS_set_background
)
2268 default_max_colors
= TN_max_colors
;
2269 default_max_pairs
= TN_max_pairs
;
2270 default_no_color_video
= TN_no_color_video
;
2274 TS_orig_pair
= default_orig_pair
;
2275 TS_set_foreground
= default_set_foreground
;
2276 TS_set_background
= default_set_background
;
2277 TN_max_colors
= default_max_colors
;
2278 TN_max_pairs
= default_max_pairs
;
2279 TN_no_color_video
= default_no_color_video
;
2283 /* Setup one of the standard tty color schemes according to MODE.
2284 MODE's value is generally the number of colors which we want to
2285 support; zero means set up for the default capabilities, the ones
2286 we saw at term_init time; -1 means turn off color support. */
2288 tty_setup_colors (mode
)
2291 /* Canonicalize all negative values of MODE. */
2297 case -1: /* no colors at all */
2300 TN_no_color_video
= 0;
2301 TS_set_foreground
= TS_set_background
= TS_orig_pair
= NULL
;
2303 case 0: /* default colors, if any */
2305 tty_default_color_capabilities (0);
2307 case 8: /* 8 standard ANSI colors */
2308 TS_orig_pair
= "\033[0m";
2310 TS_set_foreground
= "\033[3%p1%dm";
2311 TS_set_background
= "\033[4%p1%dm";
2313 TS_set_foreground
= "\033[3%dm";
2314 TS_set_background
= "\033[4%dm";
2318 TN_no_color_video
= 0;
2324 set_tty_color_mode (f
, val
)
2328 Lisp_Object color_mode_spec
, current_mode_spec
;
2329 Lisp_Object color_mode
, current_mode
;
2331 extern Lisp_Object Qtty_color_mode
;
2332 Lisp_Object tty_color_mode_alist
;
2334 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2341 if (NILP (tty_color_mode_alist
))
2342 color_mode_spec
= Qnil
;
2344 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2346 if (CONSP (color_mode_spec
))
2347 color_mode
= XCDR (color_mode_spec
);
2352 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2354 if (CONSP (current_mode_spec
))
2355 current_mode
= XCDR (current_mode_spec
);
2357 current_mode
= Qnil
;
2358 if (INTEGERP (color_mode
))
2359 mode
= XINT (color_mode
);
2361 mode
= 0; /* meaning default */
2362 if (INTEGERP (current_mode
))
2363 old_mode
= XINT (current_mode
);
2367 if (mode
!= old_mode
)
2369 tty_setup_colors (mode
);
2370 /* This recomputes all the faces given the new color
2372 call0 (intern ("tty-set-up-initial-frame-faces"));
2377 #endif /* !WINDOWSNT */
2380 /***********************************************************************
2382 ***********************************************************************/
2386 term_mouse_moveto (int x
, int y
)
2390 name
= (const char *) ttyname (0);
2391 fd
= open (name
, O_WRONLY
);
2392 /* TODO: how to set mouse position?
2393 SOME_FUNCTION (x, y, fd); */
2400 term_show_mouse_face (enum draw_glyphs_face draw
)
2402 struct window
*w
= XWINDOW (Qmouse_face_window
);
2406 if (/* If window is in the process of being destroyed, don't bother
2408 w
->current_matrix
!= NULL
2409 /* Recognize when we are called to operate on rows that don't exist
2410 anymore. This can happen when a window is split. */
2411 && mouse_face_end_row
< w
->current_matrix
->nrows
)
2413 /* write_glyphs writes at cursor position, so we need to
2414 temporarily move cursor coordinates to the beginning of
2415 the highlight region. */
2417 /* Save current cursor co-ordinates */
2421 /* Note that mouse_face_beg_row etc. are window relative. */
2422 for (i
= mouse_face_beg_row
; i
<= mouse_face_end_row
; i
++)
2424 int start_hpos
, end_hpos
, nglyphs
;
2425 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
2427 /* Don't do anything if row doesn't have valid contents. */
2428 if (!row
->enabled_p
)
2431 /* For all but the first row, the highlight starts at column 0. */
2432 if (i
== mouse_face_beg_row
)
2433 start_hpos
= mouse_face_beg_col
;
2437 if (i
== mouse_face_end_row
)
2438 end_hpos
= mouse_face_end_col
;
2441 end_hpos
= row
->used
[TEXT_AREA
];
2442 if (draw
== DRAW_NORMAL_TEXT
)
2443 row
->fill_line_p
= 1; /* Clear to end of line */
2446 if (end_hpos
<= start_hpos
)
2448 /* Record that some glyphs of this row are displayed in
2450 row
->mouse_face_p
= draw
> 0;
2452 nglyphs
= end_hpos
- start_hpos
;
2454 if (end_hpos
>= row
->used
[TEXT_AREA
])
2455 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2457 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2458 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
2459 + WINDOW_LEFT_EDGE_X (w
);
2461 cursor_to (pos_y
, pos_x
);
2463 if (draw
== DRAW_MOUSE_FACE
)
2465 write_glyphs_with_face (row
->glyphs
[TEXT_AREA
] + start_hpos
,
2466 nglyphs
, mouse_face_face_id
);
2468 else /* draw == DRAW_NORMAL_TEXT */
2469 write_glyphs (row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2471 cursor_to (save_y
, save_x
);
2476 term_clear_mouse_face ()
2478 if (!NILP (Qmouse_face_window
))
2479 term_show_mouse_face (DRAW_NORMAL_TEXT
);
2481 mouse_face_beg_row
= mouse_face_beg_col
= -1;
2482 mouse_face_end_row
= mouse_face_end_col
= -1;
2483 Qmouse_face_window
= Qnil
;
2486 /* Find the glyph matrix position of buffer position POS in window W.
2487 *HPOS and *VPOS are set to the positions found. W's current glyphs
2488 must be up to date. If POS is above window start return (0, 0).
2489 If POS is after end of W, return end of last line in W.
2490 - taken from msdos.c */
2492 fast_find_position (struct window
*w
, int pos
, int *hpos
, int *vpos
)
2494 int i
, lastcol
, line_start_position
, maybe_next_line_p
= 0;
2495 int yb
= window_text_bottom_y (w
);
2496 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0), *best_row
= row
;
2500 if (row
->used
[TEXT_AREA
])
2501 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
2503 line_start_position
= 0;
2505 if (line_start_position
> pos
)
2507 /* If the position sought is the end of the buffer,
2508 don't include the blank lines at the bottom of the window. */
2509 else if (line_start_position
== pos
2510 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
2512 maybe_next_line_p
= 1;
2515 else if (line_start_position
> 0)
2518 /* Don't overstep the last matrix row, lest we get into the
2519 never-never land... */
2520 if (row
->y
+ 1 >= yb
)
2526 /* Find the right column within BEST_ROW. */
2529 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
2531 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + i
;
2534 charpos
= glyph
->charpos
;
2541 else if (charpos
> pos
)
2543 else if (charpos
> 0)
2547 /* If we're looking for the end of the buffer,
2548 and we didn't find it in the line we scanned,
2549 use the start of the following line. */
2550 if (maybe_next_line_p
)
2557 *hpos
= lastcol
+ 1;
2562 term_mouse_highlight (struct frame
*f
, int x
, int y
)
2564 enum window_part part
;
2569 if (NILP (Vmouse_highlight
)
2570 || !f
->glyphs_initialized_p
)
2573 mouse_face_mouse_x
= x
;
2574 mouse_face_mouse_y
= y
;
2575 mouse_face_mouse_frame
= f
;
2577 /* Which window is that in? */
2578 window
= window_from_coordinates (f
, x
, y
, &part
, &x
, &y
, 0);
2580 /* Not on a window -> return. */
2581 if (!WINDOWP (window
))
2584 if (!EQ (window
, Qmouse_face_window
))
2585 term_clear_mouse_face ();
2587 w
= XWINDOW (window
);
2589 /* Are we in a window whose display is up to date?
2590 And verify the buffer's text has not changed. */
2591 b
= XBUFFER (w
->buffer
);
2593 && EQ (w
->window_end_valid
, w
->buffer
)
2594 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
2595 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
2597 int pos
, i
, nrows
= w
->current_matrix
->nrows
;
2598 struct glyph_row
*row
;
2599 struct glyph
*glyph
;
2601 /* Find the glyph under X/Y. */
2603 if (y
>= 0 && y
< nrows
)
2605 row
= MATRIX_ROW (w
->current_matrix
, y
);
2606 /* Give up if some row before the one we are looking for is
2608 for (i
= 0; i
<= y
; i
++)
2609 if (!MATRIX_ROW (w
->current_matrix
, i
)->enabled_p
)
2611 if (i
> y
/* all rows upto and including the one at Y are enabled */
2612 && row
->displays_text_p
2613 && x
< window_box_width (w
, TEXT_AREA
))
2615 glyph
= row
->glyphs
[TEXT_AREA
];
2616 if (x
>= row
->used
[TEXT_AREA
])
2621 if (!BUFFERP (glyph
->object
))
2627 /* Clear mouse face if X/Y not over text. */
2630 term_clear_mouse_face ();
2634 if (!BUFFERP (glyph
->object
))
2636 pos
= glyph
->charpos
;
2638 /* Check for mouse-face. */
2640 extern Lisp_Object Qmouse_face
;
2641 Lisp_Object mouse_face
, overlay
, position
, *overlay_vec
;
2642 int noverlays
, obegv
, ozv
;
2643 struct buffer
*obuf
;
2645 /* If we get an out-of-range value, return now; avoid an error. */
2646 if (pos
> BUF_Z (b
))
2649 /* Make the window's buffer temporarily current for
2650 overlays_at and compute_char_face. */
2651 obuf
= current_buffer
;
2658 /* Is this char mouse-active? */
2659 XSETINT (position
, pos
);
2661 /* Put all the overlays we want in a vector in overlay_vec. */
2662 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
2663 /* Sort overlays into increasing priority order. */
2664 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
2666 /* Check mouse-face highlighting. */
2667 if (!(EQ (window
, Qmouse_face_window
)
2668 && y
>= mouse_face_beg_row
2669 && y
<= mouse_face_end_row
2670 && (y
> mouse_face_beg_row
2671 || x
>= mouse_face_beg_col
)
2672 && (y
< mouse_face_end_row
2673 || x
< mouse_face_end_col
2674 || mouse_face_past_end
)))
2676 /* Clear the display of the old active region, if any. */
2677 term_clear_mouse_face ();
2679 /* Find the highest priority overlay that has a mouse-face
2682 for (i
= noverlays
- 1; i
>= 0; --i
)
2684 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
2685 if (!NILP (mouse_face
))
2687 overlay
= overlay_vec
[i
];
2692 /* If no overlay applies, get a text property. */
2694 mouse_face
= Fget_text_property (position
, Qmouse_face
,
2697 /* Handle the overlay case. */
2698 if (!NILP (overlay
))
2700 /* Find the range of text around this char that
2701 should be active. */
2702 Lisp_Object before
, after
;
2706 before
= Foverlay_start (overlay
);
2707 after
= Foverlay_end (overlay
);
2708 /* Record this as the current active region. */
2709 fast_find_position (w
, XFASTINT (before
),
2710 &mouse_face_beg_col
,
2711 &mouse_face_beg_row
);
2714 = !fast_find_position (w
, XFASTINT (after
),
2715 &mouse_face_end_col
,
2716 &mouse_face_end_row
);
2717 Qmouse_face_window
= window
;
2720 = face_at_buffer_position (w
, pos
, 0, 0,
2721 &ignore
, pos
+ 1, 1);
2723 /* Display it as active. */
2724 term_show_mouse_face (DRAW_MOUSE_FACE
);
2726 /* Handle the text property case. */
2727 else if (!NILP (mouse_face
))
2729 /* Find the range of text around this char that
2730 should be active. */
2731 Lisp_Object before
, after
, beginning
, end
;
2734 beginning
= Fmarker_position (w
->start
);
2735 XSETINT (end
, (BUF_Z (b
) - XFASTINT (w
->window_end_pos
)));
2737 = Fprevious_single_property_change (make_number (pos
+ 1),
2739 w
->buffer
, beginning
);
2741 = Fnext_single_property_change (position
, Qmouse_face
,
2744 /* Record this as the current active region. */
2745 fast_find_position (w
, XFASTINT (before
),
2746 &mouse_face_beg_col
,
2747 &mouse_face_beg_row
);
2749 = !fast_find_position (w
, XFASTINT (after
),
2750 &mouse_face_end_col
,
2751 &mouse_face_end_row
);
2752 Qmouse_face_window
= window
;
2755 = face_at_buffer_position (w
, pos
, 0, 0,
2756 &ignore
, pos
+ 1, 1);
2758 /* Display it as active. */
2759 term_show_mouse_face (DRAW_MOUSE_FACE
);
2763 /* Look for a `help-echo' property. */
2766 extern Lisp_Object Qhelp_echo
;
2768 /* Check overlays first. */
2770 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
2772 overlay
= overlay_vec
[i
];
2773 help
= Foverlay_get (overlay
, Qhelp_echo
);
2778 help_echo_string
= help
;
2779 help_echo_window
= window
;
2780 help_echo_object
= overlay
;
2781 help_echo_pos
= pos
;
2783 /* Try text properties. */
2784 else if (NILP (help
)
2785 && ((STRINGP (glyph
->object
)
2786 && glyph
->charpos
>= 0
2787 && glyph
->charpos
< SCHARS (glyph
->object
))
2788 || (BUFFERP (glyph
->object
)
2789 && glyph
->charpos
>= BEGV
2790 && glyph
->charpos
< ZV
)))
2792 help
= Fget_text_property (make_number (glyph
->charpos
),
2793 Qhelp_echo
, glyph
->object
);
2796 help_echo_string
= help
;
2797 help_echo_window
= window
;
2798 help_echo_object
= glyph
->object
;
2799 help_echo_pos
= glyph
->charpos
;
2806 current_buffer
= obuf
;
2812 term_mouse_movement (FRAME_PTR frame
, Gpm_Event
*event
)
2814 /* Has the mouse moved off the glyph it was on at the last sighting? */
2815 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2817 frame
->mouse_moved
= 1;
2818 term_mouse_highlight (frame
, event
->x
- 1, event
->y
- 1);
2819 /* Remember which glyph we're now on. */
2820 last_mouse_x
= event
->x
;
2821 last_mouse_y
= event
->y
;
2827 /* Return the current position of the mouse.
2829 Set *f to the frame the mouse is in, or zero if the mouse is in no
2830 Emacs frame. If it is set to zero, all the other arguments are
2833 Set *bar_window to Qnil, and *x and *y to the column and
2834 row of the character cell the mouse is over.
2836 Set *time to the time the mouse was at the returned position.
2838 This should clear mouse_moved until the next motion
2841 term_mouse_position (FRAME_PTR
*fp
, int insist
, Lisp_Object
*bar_window
,
2842 enum scroll_bar_part
*part
, Lisp_Object
*x
,
2843 Lisp_Object
*y
, unsigned long *time
)
2846 Lisp_Object frame
, window
;
2849 *fp
= SELECTED_FRAME ();
2850 (*fp
)->mouse_moved
= 0;
2855 XSETINT (*x
, last_mouse_x
);
2856 XSETINT (*y
, last_mouse_y
);
2857 XSETFRAME (frame
, *fp
);
2858 window
= Fwindow_at (*x
, *y
, frame
);
2860 XSETINT (*x
, last_mouse_x
- WINDOW_LEFT_EDGE_COL (XWINDOW (window
)));
2861 XSETINT (*y
, last_mouse_y
- WINDOW_TOP_EDGE_LINE (XWINDOW (window
)));
2862 gettimeofday(&now
, 0);
2863 *time
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2866 /* Prepare a mouse-event in *RESULT for placement in the input queue.
2868 If the event is a button press, then note that we have grabbed
2872 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
2878 result
->kind
= GPM_CLICK_EVENT
;
2879 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
2881 if (event
->buttons
& j
) {
2882 result
->code
= i
; /* button number */
2886 gettimeofday(&now
, 0);
2887 result
->timestamp
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2889 if (event
->type
& GPM_UP
)
2890 result
->modifiers
= up_modifier
;
2891 else if (event
->type
& GPM_DOWN
)
2892 result
->modifiers
= down_modifier
;
2894 result
->modifiers
= 0;
2896 if (event
->type
& GPM_SINGLE
)
2897 result
->modifiers
|= click_modifier
;
2899 if (event
->type
& GPM_DOUBLE
)
2900 result
->modifiers
|= double_modifier
;
2902 if (event
->type
& GPM_TRIPLE
)
2903 result
->modifiers
|= triple_modifier
;
2905 if (event
->type
& GPM_DRAG
)
2906 result
->modifiers
|= drag_modifier
;
2908 if (!(event
->type
& (GPM_MOVE
|GPM_DRAG
))) {
2911 if (event
->modifiers
& (1 << 0))
2912 result
->modifiers
|= shift_modifier
;
2915 if (event
->modifiers
& (1 << 2))
2916 result
->modifiers
|= ctrl_modifier
;
2918 /* 1 << KG_ALT || KG_ALTGR */
2919 if (event
->modifiers
& (1 << 3)
2920 || event
->modifiers
& (1 << 1))
2921 result
->modifiers
|= meta_modifier
;
2924 XSETINT (result
->x
, event
->x
- 1);
2925 XSETINT (result
->y
, event
->y
- 1);
2926 XSETFRAME (result
->frame_or_window
, f
);
2932 handle_one_term_event (Gpm_Event
*event
, struct input_event
* hold_quit
)
2934 struct frame
*f
= SELECTED_FRAME ();
2936 struct input_event ie
;
2944 if (event
->type
& GPM_MOVE
) {
2945 unsigned char buf
[6 * sizeof (short)];
2946 unsigned short *arg
= (unsigned short *) buf
+ 1;
2949 previous_help_echo_string
= help_echo_string
;
2950 help_echo_string
= Qnil
;
2952 /* Display mouse pointer */
2953 buf
[sizeof(short) - 1] = 2; /* set selection */
2955 arg
[0] = arg
[2] = (unsigned short) event
->x
;
2956 arg
[1] = arg
[3] = (unsigned short) event
->y
;
2957 arg
[4] = (unsigned short) 3;
2959 name
= (const char *) ttyname (0);
2960 fd
= open (name
, O_WRONLY
);
2961 ioctl (fd
, TIOCLINUX
, buf
+ sizeof (short) - 1);
2964 term_mouse_movement (f
, event
);
2966 /* If the contents of the global variable help_echo_string
2967 has changed, generate a HELP_EVENT. */
2968 if (!NILP (help_echo_string
)
2969 || !NILP (previous_help_echo_string
))
2976 term_mouse_click (&ie
, event
, f
);
2980 if (ie
.kind
!= NO_EVENT
)
2982 kbd_buffer_store_event_hold (&ie
, hold_quit
);
2987 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
2992 XSETFRAME (frame
, f
);
2996 gen_help_event (help_echo_string
, frame
, help_echo_window
,
2997 help_echo_object
, help_echo_pos
);
3004 DEFUN ("term-open-connection", Fterm_open_connection
, Sterm_open_connection
,
3006 doc
: /* Open a connection to Gpm. */)
3009 Gpm_Connect connection
;
3011 connection
.eventMask
= ~0;
3012 connection
.defaultMask
= ~GPM_HARD
;
3013 connection
.maxMod
= ~0;
3014 connection
.minMod
= 0;
3016 if (Gpm_Open (&connection
, 0) < 0)
3023 add_gpm_wait_descriptor (gpm_fd
);
3028 DEFUN ("term-close-connection", Fterm_close_connection
, Sterm_close_connection
,
3030 doc
: /* Close a connection to Gpm. */)
3033 delete_gpm_wait_descriptor (gpm_fd
);
3034 while (Gpm_Close()); /* close all the stack */
3038 #endif /* HAVE_GPM */
3041 /***********************************************************************
3043 ***********************************************************************/
3046 term_init (terminal_type
)
3047 char *terminal_type
;
3050 char **address
= &area
;
3051 char *buffer
= NULL
;
3052 int buffer_size
= 4096;
3055 struct frame
*sf
= XFRAME (selected_frame
);
3057 encode_terminal_bufsize
= 0;
3060 mouse_position_hook
= term_mouse_position
;
3061 Qmouse_face_window
= Qnil
;
3065 initialize_w32_display ();
3069 area
= (char *) xmalloc (2044);
3071 FrameRows
= FRAME_LINES (sf
);
3072 FrameCols
= FRAME_COLS (sf
);
3073 specified_window
= FRAME_LINES (sf
);
3075 delete_in_insert_mode
= 1;
3078 scroll_region_ok
= 0;
3080 /* Seems to insert lines when it's not supposed to, messing
3081 up the display. In doing a trace, it didn't seem to be
3082 called much, so I don't think we're losing anything by
3085 line_ins_del_ok
= 0;
3086 char_ins_del_ok
= 1;
3090 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
3091 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
3092 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
3095 #else /* not WINDOWSNT */
3099 buffer
= (char *) xmalloc (buffer_size
);
3100 status
= tgetent (buffer
, terminal_type
);
3104 fatal ("Cannot open terminfo database file");
3106 fatal ("Cannot open termcap database file");
3112 fatal ("Terminal type %s is not defined.\n\
3113 If that is not the actual type of terminal you have,\n\
3114 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3115 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3116 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3119 fatal ("Terminal type %s is not defined.\n\
3120 If that is not the actual type of terminal you have,\n\
3121 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3122 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3123 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3129 if (strlen (buffer
) >= buffer_size
)
3131 buffer_size
= strlen (buffer
);
3133 area
= (char *) xmalloc (buffer_size
);
3135 TS_ins_line
= tgetstr ("al", address
);
3136 TS_ins_multi_lines
= tgetstr ("AL", address
);
3137 TS_bell
= tgetstr ("bl", address
);
3138 BackTab
= tgetstr ("bt", address
);
3139 TS_clr_to_bottom
= tgetstr ("cd", address
);
3140 TS_clr_line
= tgetstr ("ce", address
);
3141 TS_clr_frame
= tgetstr ("cl", address
);
3142 ColPosition
= NULL
; /* tgetstr ("ch", address); */
3143 AbsPosition
= tgetstr ("cm", address
);
3144 CR
= tgetstr ("cr", address
);
3145 TS_set_scroll_region
= tgetstr ("cs", address
);
3146 TS_set_scroll_region_1
= tgetstr ("cS", address
);
3147 RowPosition
= tgetstr ("cv", address
);
3148 TS_del_char
= tgetstr ("dc", address
);
3149 TS_del_multi_chars
= tgetstr ("DC", address
);
3150 TS_del_line
= tgetstr ("dl", address
);
3151 TS_del_multi_lines
= tgetstr ("DL", address
);
3152 TS_delete_mode
= tgetstr ("dm", address
);
3153 TS_end_delete_mode
= tgetstr ("ed", address
);
3154 TS_end_insert_mode
= tgetstr ("ei", address
);
3155 Home
= tgetstr ("ho", address
);
3156 TS_ins_char
= tgetstr ("ic", address
);
3157 TS_ins_multi_chars
= tgetstr ("IC", address
);
3158 TS_insert_mode
= tgetstr ("im", address
);
3159 TS_pad_inserted_char
= tgetstr ("ip", address
);
3160 TS_end_keypad_mode
= tgetstr ("ke", address
);
3161 TS_keypad_mode
= tgetstr ("ks", address
);
3162 LastLine
= tgetstr ("ll", address
);
3163 Right
= tgetstr ("nd", address
);
3164 Down
= tgetstr ("do", address
);
3166 Down
= tgetstr ("nl", address
); /* Obsolete name for "do" */
3168 /* VMS puts a carriage return before each linefeed,
3169 so it is not safe to use linefeeds. */
3170 if (Down
&& Down
[0] == '\n' && Down
[1] == '\0')
3173 if (tgetflag ("bs"))
3174 Left
= "\b"; /* can't possibly be longer! */
3175 else /* (Actually, "bs" is obsolete...) */
3176 Left
= tgetstr ("le", address
);
3178 Left
= tgetstr ("bc", address
); /* Obsolete name for "le" */
3179 TS_pad_char
= tgetstr ("pc", address
);
3180 TS_repeat
= tgetstr ("rp", address
);
3181 TS_end_standout_mode
= tgetstr ("se", address
);
3182 TS_fwd_scroll
= tgetstr ("sf", address
);
3183 TS_standout_mode
= tgetstr ("so", address
);
3184 TS_rev_scroll
= tgetstr ("sr", address
);
3185 Wcm
.cm_tab
= tgetstr ("ta", address
);
3186 TS_end_termcap_modes
= tgetstr ("te", address
);
3187 TS_termcap_modes
= tgetstr ("ti", address
);
3188 Up
= tgetstr ("up", address
);
3189 TS_visible_bell
= tgetstr ("vb", address
);
3190 TS_cursor_normal
= tgetstr ("ve", address
);
3191 TS_cursor_visible
= tgetstr ("vs", address
);
3192 TS_cursor_invisible
= tgetstr ("vi", address
);
3193 TS_set_window
= tgetstr ("wi", address
);
3195 TS_enter_underline_mode
= tgetstr ("us", address
);
3196 TS_exit_underline_mode
= tgetstr ("ue", address
);
3197 TS_enter_bold_mode
= tgetstr ("md", address
);
3198 TS_enter_dim_mode
= tgetstr ("mh", address
);
3199 TS_enter_blink_mode
= tgetstr ("mb", address
);
3200 TS_enter_reverse_mode
= tgetstr ("mr", address
);
3201 TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3202 TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3203 TS_exit_attribute_mode
= tgetstr ("me", address
);
3205 MultiUp
= tgetstr ("UP", address
);
3206 MultiDown
= tgetstr ("DO", address
);
3207 MultiLeft
= tgetstr ("LE", address
);
3208 MultiRight
= tgetstr ("RI", address
);
3210 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
3211 color because we can't switch back to the default foreground and
3213 TS_orig_pair
= tgetstr ("op", address
);
3216 TS_set_foreground
= tgetstr ("AF", address
);
3217 TS_set_background
= tgetstr ("AB", address
);
3218 if (!TS_set_foreground
)
3221 TS_set_foreground
= tgetstr ("Sf", address
);
3222 TS_set_background
= tgetstr ("Sb", address
);
3225 TN_max_colors
= tgetnum ("Co");
3226 TN_max_pairs
= tgetnum ("pa");
3228 TN_no_color_video
= tgetnum ("NC");
3229 if (TN_no_color_video
== -1)
3230 TN_no_color_video
= 0;
3233 tty_default_color_capabilities (1);
3235 MagicWrap
= tgetflag ("xn");
3236 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3237 the former flag imply the latter. */
3238 AutoWrap
= MagicWrap
|| tgetflag ("am");
3239 memory_below_frame
= tgetflag ("db");
3240 TF_hazeltine
= tgetflag ("hz");
3241 must_write_spaces
= tgetflag ("in");
3242 meta_key
= tgetflag ("km") || tgetflag ("MT");
3243 TF_insmode_motion
= tgetflag ("mi");
3244 TF_standout_motion
= tgetflag ("ms");
3245 TF_underscore
= tgetflag ("ul");
3246 TF_teleray
= tgetflag ("xt");
3248 term_get_fkeys (address
);
3250 /* Get frame size from system, or else from termcap. */
3253 get_frame_size (&width
, &height
);
3254 FRAME_COLS (sf
) = width
;
3255 FRAME_LINES (sf
) = height
;
3258 if (FRAME_COLS (sf
) <= 0)
3259 SET_FRAME_COLS (sf
, tgetnum ("co"));
3261 /* Keep width and external_width consistent */
3262 SET_FRAME_COLS (sf
, FRAME_COLS (sf
));
3263 if (FRAME_LINES (sf
) <= 0)
3264 FRAME_LINES (sf
) = tgetnum ("li");
3266 if (FRAME_LINES (sf
) < 3 || FRAME_COLS (sf
) < 3)
3267 fatal ("Screen size %dx%d is too small",
3268 FRAME_LINES (sf
), FRAME_COLS (sf
));
3270 min_padding_speed
= tgetnum ("pb");
3271 TabWidth
= tgetnum ("tw");
3274 /* These capabilities commonly use ^J.
3275 I don't know why, but sending them on VMS does not work;
3276 it causes following spaces to be lost, sometimes.
3277 For now, the simplest fix is to avoid using these capabilities ever. */
3278 if (Down
&& Down
[0] == '\n')
3286 TS_fwd_scroll
= Down
;
3288 PC
= TS_pad_char
? *TS_pad_char
: 0;
3293 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3294 and newer termcap doc does not seem to say there is a default.
3299 /* We don't support standout modes that use `magic cookies', so
3300 turn off any that do. */
3301 if (TS_standout_mode
&& tgetnum ("sg") >= 0)
3303 TS_standout_mode
= 0;
3304 TS_end_standout_mode
= 0;
3306 if (TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3308 TS_enter_underline_mode
= 0;
3309 TS_exit_underline_mode
= 0;
3312 /* If there's no standout mode, try to use underlining instead. */
3313 if (TS_standout_mode
== 0)
3315 TS_standout_mode
= TS_enter_underline_mode
;
3316 TS_end_standout_mode
= TS_exit_underline_mode
;
3319 /* If no `se' string, try using a `me' string instead.
3320 If that fails, we can't use standout mode at all. */
3321 if (TS_end_standout_mode
== 0)
3323 char *s
= tgetstr ("me", address
);
3325 TS_end_standout_mode
= s
;
3327 TS_standout_mode
= 0;
3333 /* We can't support standout mode, because it uses magic cookies. */
3334 TS_standout_mode
= 0;
3335 /* But that means we cannot rely on ^M to go to column zero! */
3337 /* LF can't be trusted either -- can alter hpos */
3338 /* if move at column 0 thru a line with TS_standout_mode */
3342 /* Special handling for certain terminal types known to need it */
3344 if (!strcmp (terminal_type
, "supdup"))
3346 memory_below_frame
= 1;
3347 Wcm
.cm_losewrap
= 1;
3349 if (!strncmp (terminal_type
, "c10", 3)
3350 || !strcmp (terminal_type
, "perq"))
3352 /* Supply a makeshift :wi string.
3353 This string is not valid in general since it works only
3354 for windows starting at the upper left corner;
3355 but that is all Emacs uses.
3357 This string works only if the frame is using
3358 the top of the video memory, because addressing is memory-relative.
3359 So first check the :ti string to see if that is true.
3361 It would be simpler if the :wi string could go in the termcap
3362 entry, but it can't because it is not fully valid.
3363 If it were in the termcap entry, it would confuse other programs. */
3366 p
= TS_termcap_modes
;
3367 while (*p
&& strcmp (p
, "\033v "))
3370 TS_set_window
= "\033v%C %C %C %C ";
3372 /* Termcap entry often fails to have :in: flag */
3373 must_write_spaces
= 1;
3374 /* :ti string typically fails to have \E^G! in it */
3375 /* This limits scope of insert-char to one line. */
3376 strcpy (area
, TS_termcap_modes
);
3377 strcat (area
, "\033\007!");
3378 TS_termcap_modes
= area
;
3379 area
+= strlen (area
) + 1;
3381 /* Change all %+ parameters to %C, to handle
3382 values above 96 correctly for the C100. */
3385 if (p
[0] == '%' && p
[1] == '+')
3391 FrameRows
= FRAME_LINES (sf
);
3392 FrameCols
= FRAME_COLS (sf
);
3393 specified_window
= FRAME_LINES (sf
);
3395 if (Wcm_init () == -1) /* can't do cursor motion */
3397 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3398 It lacks the ability to position the cursor.\n\
3399 If that is not the actual type of terminal you have, use either the\n\
3400 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
3401 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
3405 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3406 It lacks the ability to position the cursor.\n\
3407 If that is not the actual type of terminal you have,\n\
3408 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3409 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3410 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3412 # else /* TERMCAP */
3413 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3414 It lacks the ability to position the cursor.\n\
3415 If that is not the actual type of terminal you have,\n\
3416 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3417 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3418 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3420 # endif /* TERMINFO */
3422 if (FRAME_LINES (sf
) <= 0
3423 || FRAME_COLS (sf
) <= 0)
3424 fatal ("The frame size has not been specified");
3426 delete_in_insert_mode
3427 = TS_delete_mode
&& TS_insert_mode
3428 && !strcmp (TS_delete_mode
, TS_insert_mode
);
3430 se_is_so
= (TS_standout_mode
3431 && TS_end_standout_mode
3432 && !strcmp (TS_standout_mode
, TS_end_standout_mode
));
3434 UseTabs
= tabs_safe_p () && TabWidth
== 8;
3438 && (TS_set_window
|| TS_set_scroll_region
|| TS_set_scroll_region_1
));
3440 line_ins_del_ok
= (((TS_ins_line
|| TS_ins_multi_lines
)
3441 && (TS_del_line
|| TS_del_multi_lines
))
3442 || (scroll_region_ok
&& TS_fwd_scroll
&& TS_rev_scroll
));
3444 char_ins_del_ok
= ((TS_ins_char
|| TS_insert_mode
3445 || TS_pad_inserted_char
|| TS_ins_multi_chars
)
3446 && (TS_del_char
|| TS_del_multi_chars
));
3448 fast_clear_end_of_line
= TS_clr_line
!= 0;
3451 if (read_socket_hook
) /* Baudrate is somewhat */
3452 /* meaningless in this case */
3455 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
3456 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
3457 #endif /* WINDOWSNT */
3464 fatal (str
, arg1
, arg2
)
3465 char *str
, *arg1
, *arg2
;
3467 fprintf (stderr
, "emacs: ");
3468 fprintf (stderr
, str
, arg1
, arg2
);
3469 fprintf (stderr
, "\n");
3474 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 0, 0,
3475 doc
: /* Declare that this terminal does not handle underlining.
3476 This is used to override the terminfo data, for certain terminals that
3477 do not really do underlining, but say that they do. */)
3480 TS_enter_underline_mode
= 0;
3487 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
3488 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3489 This variable can be used by terminal emulator packages. */);
3491 system_uses_terminfo
= 1;
3493 system_uses_terminfo
= 0;
3496 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
3497 doc
: /* Non-nil means call this function to ring the bell.
3498 The function should accept no arguments. */);
3499 Vring_bell_function
= Qnil
;
3501 DEFVAR_BOOL ("visible-cursor", &visible_cursor
,
3502 doc
: /* Non-nil means to make the cursor very visible.
3503 This only has an effect when running in a text terminal.
3504 What means \"very visible\" is up to your terminal. It may make the cursor
3505 bigger, or it may make it blink, or it may do nothing at all. */);
3508 defsubr (&Stty_display_color_p
);
3509 defsubr (&Stty_display_color_cells
);
3510 defsubr (&Stty_no_underline
);
3512 defsubr (&Sterm_open_connection
);
3513 defsubr (&Sterm_close_connection
);
3515 staticpro (&Qmouse_face_window
);
3516 #endif /* HAVE_GPM */
3518 fullscreen_hook
= NULL
;
3521 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
3522 (do not change this comment) */