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>. */
36 #include "character.h"
39 #include "composite.h"
43 #include "termhooks.h"
44 #include "dispextern.h"
47 #include "blockinput.h"
48 #include "intervals.h"
50 /* For now, don't try to include termcap.h. On some systems,
51 configure finds a non-standard termcap.h that the main build
54 #if defined HAVE_TERMCAP_H && 0
57 extern void tputs
P_ ((const char *, int, int (*)(int)));
58 extern int tgetent
P_ ((char *, const char *));
59 extern int tgetflag
P_ ((char *id
));
60 extern int tgetnum
P_ ((char *id
));
71 static void turn_on_face
P_ ((struct frame
*, int face_id
));
72 static void turn_off_face
P_ ((struct frame
*, int face_id
));
73 static void tty_show_cursor
P_ ((void));
74 static void tty_hide_cursor
P_ ((void));
77 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) - curY), cmputc)
78 #define OUTPUT1(a) tputs (a, 1, cmputc)
79 #define OUTPUTL(a, lines) tputs (a, lines, cmputc)
81 #define OUTPUT_IF(a) \
84 tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) \
88 #define OUTPUT1_IF(a) do { if (a) tputs (a, 1, cmputc); } while (0)
90 /* Display space properties */
92 extern Lisp_Object Qspace
, QCalign_to
, QCwidth
;
94 /* Function to use to ring the bell. */
96 Lisp_Object Vring_bell_function
;
98 /* If true, use "vs", otherwise use "ve" to make the cursor visible. */
100 static int visible_cursor
;
102 /* Terminal characteristics that higher levels want to look at.
103 These are all extern'd in termchar.h */
105 int must_write_spaces
; /* Nonzero means spaces in the text
106 must actually be output; can't just skip
107 over some columns to leave them blank. */
108 int min_padding_speed
; /* Speed below which no padding necessary */
110 int line_ins_del_ok
; /* Terminal can insert and delete lines */
111 int char_ins_del_ok
; /* Terminal can insert and delete chars */
112 int scroll_region_ok
; /* Terminal supports setting the
114 int scroll_region_cost
; /* Cost of setting a scroll window,
115 measured in characters */
116 int memory_below_frame
; /* Terminal remembers lines
117 scrolled off bottom */
118 int fast_clear_end_of_line
; /* Terminal has a `ce' string */
120 /* Nonzero means no need to redraw the entire frame on resuming
121 a suspended Emacs. This is useful on terminals with multiple pages,
122 where one page is used for Emacs and another for all else. */
124 int no_redraw_on_reenter
;
126 /* Hook functions that you can set to snap out the functions in this file.
127 These are all extern'd in termhooks.h */
129 void (*cursor_to_hook
) P_ ((int, int));
130 void (*raw_cursor_to_hook
) P_ ((int, int));
131 void (*clear_to_end_hook
) P_ ((void));
132 void (*clear_frame_hook
) P_ ((void));
133 void (*clear_end_of_line_hook
) P_ ((int));
135 void (*ins_del_lines_hook
) P_ ((int, int));
137 void (*delete_glyphs_hook
) P_ ((int));
139 void (*ring_bell_hook
) P_ ((void));
141 void (*reset_terminal_modes_hook
) P_ ((void));
142 void (*set_terminal_modes_hook
) P_ ((void));
143 void (*update_begin_hook
) P_ ((struct frame
*));
144 void (*update_end_hook
) P_ ((struct frame
*));
145 void (*set_terminal_window_hook
) P_ ((int));
146 void (*insert_glyphs_hook
) P_ ((struct glyph
*, int));
147 void (*write_glyphs_hook
) P_ ((struct glyph
*, int));
148 void (*delete_glyphs_hook
) P_ ((int));
150 int (*read_socket_hook
) P_ ((int, int, struct input_event
*));
152 void (*frame_up_to_date_hook
) P_ ((struct frame
*));
154 void (*mouse_position_hook
) P_ ((FRAME_PTR
*f
, int insist
,
155 Lisp_Object
*bar_window
,
156 enum scroll_bar_part
*part
,
159 unsigned long *time
));
161 /* When reading from a minibuffer in a different frame, Emacs wants
162 to shift the highlight from the selected frame to the mini-buffer's
163 frame; under X, this means it lies about where the focus is.
164 This hook tells the window system code to re-decide where to put
167 void (*frame_rehighlight_hook
) P_ ((FRAME_PTR f
));
169 /* If we're displaying frames using a window system that can stack
170 frames on top of each other, this hook allows you to bring a frame
171 to the front, or bury it behind all the other windows. If this
172 hook is zero, that means the device we're displaying on doesn't
173 support overlapping frames, so there's no need to raise or lower
176 If RAISE is non-zero, F is brought to the front, before all other
177 windows. If RAISE is zero, F is sent to the back, behind all other
180 void (*frame_raise_lower_hook
) P_ ((FRAME_PTR f
, int raise
));
182 /* If the value of the frame parameter changed, whis hook is called.
183 For example, if going from fullscreen to not fullscreen this hook
184 may do something OS dependent, like extended window manager hints on X11. */
185 void (*fullscreen_hook
) P_ ((struct frame
*f
));
187 /* Set the vertical scroll bar for WINDOW to have its upper left corner
188 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
189 indicate that we are displaying PORTION characters out of a total
190 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
191 have a scroll bar, create one for it. */
193 void (*set_vertical_scroll_bar_hook
)
194 P_ ((struct window
*window
,
195 int portion
, int whole
, int position
));
198 /* The following three hooks are used when we're doing a thorough
199 redisplay of the frame. We don't explicitly know which scroll bars
200 are going to be deleted, because keeping track of when windows go
201 away is a real pain - can you say set-window-configuration?
202 Instead, we just assert at the beginning of redisplay that *all*
203 scroll bars are to be removed, and then save scroll bars from the
204 fiery pit when we actually redisplay their window. */
206 /* Arrange for all scroll bars on FRAME to be removed at the next call
207 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
208 `*redeem_scroll_bar_hook' is applied to its window before the judgment.
210 This should be applied to each frame each time its window tree is
211 redisplayed, even if it is not displaying scroll bars at the moment;
212 if the HAS_SCROLL_BARS flag has just been turned off, only calling
213 this and the judge_scroll_bars_hook will get rid of them.
215 If non-zero, this hook should be safe to apply to any frame,
216 whether or not it can support scroll bars, and whether or not it is
217 currently displaying them. */
219 void (*condemn_scroll_bars_hook
) P_ ((FRAME_PTR frame
));
221 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
222 Note that it's okay to redeem a scroll bar that is not condemned. */
224 void (*redeem_scroll_bar_hook
) P_ ((struct window
*window
));
226 /* Remove all scroll bars on FRAME that haven't been saved since the
227 last call to `*condemn_scroll_bars_hook'.
229 This should be applied to each frame after each time its window
230 tree is redisplayed, even if it is not displaying scroll bars at the
231 moment; if the HAS_SCROLL_BARS flag has just been turned off, only
232 calling this and condemn_scroll_bars_hook will get rid of them.
234 If non-zero, this hook should be safe to apply to any frame,
235 whether or not it can support scroll bars, and whether or not it is
236 currently displaying them. */
238 void (*judge_scroll_bars_hook
) P_ ((FRAME_PTR FRAME
));
240 /* Strings, numbers and flags taken from the termcap entry. */
242 char *TS_ins_line
; /* "al" */
243 char *TS_ins_multi_lines
; /* "AL" (one parameter, # lines to insert) */
244 char *TS_bell
; /* "bl" */
245 char *TS_clr_to_bottom
; /* "cd" */
246 char *TS_clr_line
; /* "ce", clear to end of line */
247 char *TS_clr_frame
; /* "cl" */
248 char *TS_set_scroll_region
; /* "cs" (2 params, first line and last line) */
249 char *TS_set_scroll_region_1
; /* "cS" (4 params: total lines,
250 lines above scroll region, lines below it,
251 total lines again) */
252 char *TS_del_char
; /* "dc" */
253 char *TS_del_multi_chars
; /* "DC" (one parameter, # chars to delete) */
254 char *TS_del_line
; /* "dl" */
255 char *TS_del_multi_lines
; /* "DL" (one parameter, # lines to delete) */
256 char *TS_delete_mode
; /* "dm", enter character-delete mode */
257 char *TS_end_delete_mode
; /* "ed", leave character-delete mode */
258 char *TS_end_insert_mode
; /* "ei", leave character-insert mode */
259 char *TS_ins_char
; /* "ic" */
260 char *TS_ins_multi_chars
; /* "IC" (one parameter, # chars to insert) */
261 char *TS_insert_mode
; /* "im", enter character-insert mode */
262 char *TS_pad_inserted_char
; /* "ip". Just padding, no commands. */
263 char *TS_end_keypad_mode
; /* "ke" */
264 char *TS_keypad_mode
; /* "ks" */
265 char *TS_pad_char
; /* "pc", char to use as padding */
266 char *TS_repeat
; /* "rp" (2 params, # times to repeat
267 and character to be repeated) */
268 char *TS_end_standout_mode
; /* "se" */
269 char *TS_fwd_scroll
; /* "sf" */
270 char *TS_standout_mode
; /* "so" */
271 char *TS_rev_scroll
; /* "sr" */
272 char *TS_end_termcap_modes
; /* "te" */
273 char *TS_termcap_modes
; /* "ti" */
274 char *TS_visible_bell
; /* "vb" */
275 char *TS_cursor_normal
; /* "ve" */
276 char *TS_cursor_visible
; /* "vs" */
277 char *TS_cursor_invisible
; /* "vi" */
278 char *TS_set_window
; /* "wi" (4 params, start and end of window,
279 each as vpos and hpos) */
281 /* Value of the "NC" (no_color_video) capability, or 0 if not
284 static int TN_no_color_video
;
286 /* Meaning of bits in no_color_video. Each bit set means that the
287 corresponding attribute cannot be combined with colors. */
291 NC_STANDOUT
= 1 << 0,
292 NC_UNDERLINE
= 1 << 1,
299 NC_ALT_CHARSET
= 1 << 8
302 /* "md" -- turn on bold (extra bright mode). */
304 char *TS_enter_bold_mode
;
306 /* "mh" -- turn on half-bright mode. */
308 char *TS_enter_dim_mode
;
310 /* "mb" -- enter blinking mode. */
312 char *TS_enter_blink_mode
;
314 /* "mr" -- enter reverse video mode. */
316 char *TS_enter_reverse_mode
;
318 /* "us"/"ue" -- start/end underlining. */
320 char *TS_exit_underline_mode
, *TS_enter_underline_mode
;
322 /* "as"/"ae" -- start/end alternate character set. Not really
325 char *TS_enter_alt_charset_mode
, *TS_exit_alt_charset_mode
;
327 /* "me" -- switch appearances off. */
329 char *TS_exit_attribute_mode
;
331 /* "Co" -- number of colors. */
335 /* "pa" -- max. number of color pairs on screen. Not handled yet.
336 Could be a problem if not equal to TN_max_colors * TN_max_colors. */
340 /* "op" -- SVr4 set default pair to its original value. */
344 /* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
345 1 param, the color index. */
347 char *TS_set_foreground
, *TS_set_background
;
349 int TF_hazeltine
; /* termcap hz flag. */
350 int TF_insmode_motion
; /* termcap mi flag: can move while in insert mode. */
351 int TF_standout_motion
; /* termcap mi flag: can move while in standout mode. */
352 int TF_underscore
; /* termcap ul flag: _ underlines if over-struck on
353 non-blank position. Must clear before writing _. */
354 int TF_teleray
; /* termcap xt flag: many weird consequences.
357 static int RPov
; /* # chars to start a TS_repeat */
359 static int delete_in_insert_mode
; /* delete mode == insert mode */
361 static int se_is_so
; /* 1 if same string both enters and leaves
366 /* The largest frame width in any call to calculate_costs. */
370 /* The largest frame height in any call to calculate_costs. */
374 static int costs_set
; /* Nonzero if costs have been calculated. */
376 int insert_mode
; /* Nonzero when in insert mode. */
377 int standout_mode
; /* Nonzero when in standout mode. */
379 /* Size of window specified by higher levels.
380 This is the number of lines, from the top of frame downwards,
381 which can participate in insert-line/delete-line operations.
383 Effectively it excludes the bottom frame_lines - specified_window_size
384 lines from those operations. */
386 int specified_window
;
388 /* Frame currently being redisplayed; 0 if not currently redisplaying.
389 (Direct output does not count). */
391 FRAME_PTR updating_frame
;
393 /* Provided for lisp packages. */
395 static int system_uses_terminfo
;
397 /* Flag used in tty_show/hide_cursor. */
399 static int tty_cursor_hidden
;
403 extern char *tgetstr ();
405 static void term_clear_mouse_face ();
406 static void term_mouse_highlight (struct frame
*f
, int x
, int y
);
410 /* We aren't X windows, but we aren't termcap either. This makes me
411 uncertain as to what value to use for frame.output_method. For
412 this file, we'll define FRAME_TERMCAP_P to be zero so that our
413 output hooks get called instead of the termcap functions. Probably
414 the best long-term solution is to define an output_windows_nt... */
416 #undef FRAME_TERMCAP_P
417 #define FRAME_TERMCAP_P(_f_) 0
418 #endif /* WINDOWSNT */
421 #include <sys/fcntl.h>
423 /* Nonzero means mouse is enabled on Linux console. */
426 /* These variables describe the range of text currently shown in its
427 mouse-face, together with the window they apply to. As long as
428 the mouse stays within this range, we need not redraw anything on
429 its account. Rows and columns are glyph matrix positions in
430 MOUSE_FACE_WINDOW. */
431 static int mouse_face_beg_row
, mouse_face_beg_col
;
432 static int mouse_face_end_row
, mouse_face_end_col
;
433 static int mouse_face_past_end
;
434 static Lisp_Object Qmouse_face_window
;
435 static int mouse_face_face_id
;
437 static int pos_x
, pos_y
;
438 static int last_mouse_x
, last_mouse_y
;
439 #endif /* HAVE_GPM */
444 if (!NILP (Vring_bell_function
))
446 Lisp_Object function
;
448 /* Temporarily set the global variable to nil
449 so that if we get an error, it stays nil
450 and we don't call it over and over.
452 We don't specbind it, because that would carefully
453 restore the bad value if there's an error
454 and make the loop of errors happen anyway. */
456 function
= Vring_bell_function
;
457 Vring_bell_function
= Qnil
;
461 Vring_bell_function
= function
;
463 else if (!FRAME_TERMCAP_P (XFRAME (selected_frame
)))
464 (*ring_bell_hook
) ();
466 OUTPUT (TS_visible_bell
&& visible_bell
? TS_visible_bell
: TS_bell
);
470 set_terminal_modes ()
472 if (FRAME_TERMCAP_P (XFRAME (selected_frame
)))
474 if (TS_termcap_modes
)
475 OUTPUT (TS_termcap_modes
);
478 /* Output enough newlines to scroll all the old screen contents
479 off the screen, so it won't be overwritten and lost. */
481 for (i
= 0; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
485 OUTPUT_IF (visible_cursor
? TS_cursor_visible
: TS_cursor_normal
);
486 OUTPUT_IF (TS_keypad_mode
);
490 (*set_terminal_modes_hook
) ();
494 reset_terminal_modes ()
496 if (FRAME_TERMCAP_P (XFRAME (selected_frame
)))
498 turn_off_highlight ();
500 OUTPUT_IF (TS_end_keypad_mode
);
501 OUTPUT_IF (TS_cursor_normal
);
502 OUTPUT_IF (TS_end_termcap_modes
);
503 OUTPUT_IF (TS_orig_pair
);
504 /* Output raw CR so kernel can track the cursor hpos. */
507 else if (reset_terminal_modes_hook
)
508 (*reset_terminal_modes_hook
) ();
516 if (!FRAME_TERMCAP_P (f
))
517 update_begin_hook (f
);
524 if (FRAME_TERMCAP_P (f
))
526 if (!XWINDOW (selected_window
)->cursor_off_p
)
529 background_highlight ();
534 updating_frame
= NULL
;
538 set_terminal_window (size
)
541 if (FRAME_TERMCAP_P (updating_frame
))
543 specified_window
= size
? size
: FRAME_LINES (updating_frame
);
544 if (scroll_region_ok
)
545 set_scroll_region (0, specified_window
);
548 set_terminal_window_hook (size
);
552 set_scroll_region (start
, stop
)
556 struct frame
*sf
= XFRAME (selected_frame
);
558 if (TS_set_scroll_region
)
559 buf
= tparam (TS_set_scroll_region
, 0, 0, start
, stop
- 1);
560 else if (TS_set_scroll_region_1
)
561 buf
= tparam (TS_set_scroll_region_1
, 0, 0,
562 FRAME_LINES (sf
), start
,
563 FRAME_LINES (sf
) - stop
,
566 buf
= tparam (TS_set_window
, 0, 0, start
, 0, stop
, FRAME_COLS (sf
));
578 OUTPUT (TS_insert_mode
);
586 OUTPUT (TS_end_insert_mode
);
590 /* Handle highlighting. */
593 turn_off_highlight ()
596 OUTPUT_IF (TS_end_standout_mode
);
604 OUTPUT_IF (TS_standout_mode
);
612 turn_off_highlight ();
614 turn_on_highlight ();
618 /* Make cursor invisible. */
623 if (tty_cursor_hidden
== 0)
625 tty_cursor_hidden
= 1;
626 OUTPUT_IF (TS_cursor_invisible
);
631 /* Ensure that cursor is visible. */
636 if (tty_cursor_hidden
)
638 tty_cursor_hidden
= 0;
639 OUTPUT_IF (TS_cursor_normal
);
641 OUTPUT_IF (TS_cursor_visible
);
646 /* Set standout mode to the state it should be in for
647 empty space inside windows. What this is,
648 depends on the user option inverse-video. */
651 background_highlight ()
654 turn_on_highlight ();
656 turn_off_highlight ();
659 /* Set standout mode to the mode specified for the text to be output. */
662 highlight_if_desired ()
665 turn_on_highlight ();
667 turn_off_highlight ();
671 /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
672 frame-relative coordinates. */
675 cursor_to (vpos
, hpos
)
678 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
680 if (! FRAME_TERMCAP_P (f
) && cursor_to_hook
)
682 (*cursor_to_hook
) (vpos
, hpos
);
686 /* Detect the case where we are called from reset_sys_modes
687 and the costs have never been calculated. Do nothing. */
691 if (curY
== vpos
&& curX
== hpos
)
693 if (!TF_standout_motion
)
694 background_highlight ();
695 if (!TF_insmode_motion
)
700 /* Similar but don't take any account of the wasted characters. */
703 raw_cursor_to (row
, col
)
706 struct frame
*f
= updating_frame
? updating_frame
: XFRAME (selected_frame
);
707 if (! FRAME_TERMCAP_P (f
))
709 (*raw_cursor_to_hook
) (row
, col
);
712 if (curY
== row
&& curX
== col
)
714 if (!TF_standout_motion
)
715 background_highlight ();
716 if (!TF_insmode_motion
)
721 /* Erase operations */
723 /* clear from cursor to end of frame */
729 if (clear_to_end_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
731 (*clear_to_end_hook
) ();
734 if (TS_clr_to_bottom
)
736 background_highlight ();
737 OUTPUT (TS_clr_to_bottom
);
741 for (i
= curY
; i
< FRAME_LINES (XFRAME (selected_frame
)); i
++)
744 clear_end_of_line (FRAME_COLS (XFRAME (selected_frame
)));
749 /* Clear entire frame */
754 struct frame
*sf
= XFRAME (selected_frame
);
757 && ! FRAME_TERMCAP_P ((updating_frame
? updating_frame
: sf
)))
759 (*clear_frame_hook
) ();
764 background_highlight ();
765 OUTPUT (TS_clr_frame
);
775 /* Clear from cursor to end of line.
776 Assume that the line is already clear starting at column first_unused_hpos.
778 Note that the cursor may be moved, on terminals lacking a `ce' string. */
781 clear_end_of_line (first_unused_hpos
)
782 int first_unused_hpos
;
786 if (clear_end_of_line_hook
787 && ! FRAME_TERMCAP_P ((updating_frame
789 : XFRAME (selected_frame
))))
791 (*clear_end_of_line_hook
) (first_unused_hpos
);
795 /* Detect the case where we are called from reset_sys_modes
796 and the costs have never been calculated. Do nothing. */
800 if (curX
>= first_unused_hpos
)
802 background_highlight ();
805 OUTPUT1 (TS_clr_line
);
808 { /* have to do it the hard way */
809 struct frame
*sf
= XFRAME (selected_frame
);
812 /* Do not write in last row last col with Auto-wrap on. */
813 if (AutoWrap
&& curY
== FRAME_LINES (sf
) - 1
814 && first_unused_hpos
== FRAME_COLS (sf
))
817 for (i
= curX
; i
< first_unused_hpos
; i
++)
820 fputc (' ', termscript
);
823 cmplus (first_unused_hpos
- curX
);
827 /* Buffers to store the source and result of code conversion for terminal. */
828 static unsigned char *encode_terminal_src
;
829 static unsigned char *encode_terminal_dst
;
830 /* Allocated sizes of the above buffers. */
831 static int encode_terminal_src_size
;
832 static int encode_terminal_dst_size
;
834 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
835 Set CODING->produced to the byte-length of the resulting byte
836 sequence, and return a pointer to that byte sequence. */
839 encode_terminal_code (src
, src_len
, coding
)
842 struct coding_system
*coding
;
844 struct glyph
*src_end
= src
+ src_len
;
847 int nchars
, nbytes
, required
;
848 register int tlen
= GLYPH_TABLE_LENGTH
;
849 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
850 Lisp_Object charset_list
;
852 /* Allocate sufficient size of buffer to store all characters in
853 multibyte-form. But, it may be enlarged on demand if
854 Vglyph_table contains a string or a composite glyph is
856 required
= MAX_MULTIBYTE_LENGTH
* src_len
;
857 if (encode_terminal_src_size
< required
)
859 if (encode_terminal_src_size
== 0)
860 encode_terminal_src
= xmalloc (required
);
862 encode_terminal_src
= xrealloc (encode_terminal_src
, required
);
863 encode_terminal_src_size
= required
;
866 charset_list
= coding_charset_list (coding
);
868 buf
= encode_terminal_src
;
870 while (src
< src_end
)
872 if (src
->type
== COMPOSITE_GLYPH
)
874 struct composition
*cmp
= composition_table
[src
->u
.cmp_id
];
877 nbytes
= buf
- encode_terminal_src
;
878 required
= MAX_MULTIBYTE_LENGTH
* cmp
->glyph_len
;
880 if (encode_terminal_src_size
< nbytes
+ required
)
882 encode_terminal_src_size
= nbytes
+ required
;
883 encode_terminal_src
= xrealloc (encode_terminal_src
,
884 encode_terminal_src_size
);
885 buf
= encode_terminal_src
+ nbytes
;
888 for (i
= 0; i
< cmp
->glyph_len
; i
++)
890 int c
= COMPOSITION_GLYPH (cmp
, i
);
892 if (! char_charset (c
, charset_list
, NULL
))
894 buf
+= CHAR_STRING (c
, buf
);
899 /* The first character of the composition is not encodable. */
904 /* We must skip glyphs to be padded for a wide character. */
905 else if (! CHAR_GLYPH_PADDING_P (*src
))
911 g
= GLYPH_FROM_CHAR_GLYPH (src
[0]);
913 if (g
< 0 || g
>= tlen
)
915 /* This glyph doesn't has an entry in Vglyph_table. */
920 /* This glyph has an entry in Vglyph_table,
921 so process any alias before testing for simpleness. */
922 GLYPH_FOLLOW_ALIASES (tbase
, tlen
, g
);
924 if (GLYPH_SIMPLE_P (tbase
, tlen
, g
))
925 /* We set the multi-byte form of a character in G
926 (that should be an ASCII character) at WORKBUF. */
927 c
= FAST_GLYPH_CHAR (g
);
929 /* We have a string in Vglyph_table. */
935 nbytes
= buf
- encode_terminal_src
;
936 if (encode_terminal_src_size
< nbytes
+ MAX_MULTIBYTE_LENGTH
)
938 encode_terminal_src_size
= nbytes
+ MAX_MULTIBYTE_LENGTH
;
939 encode_terminal_src
= xrealloc (encode_terminal_src
,
940 encode_terminal_src_size
);
941 buf
= encode_terminal_src
+ nbytes
;
943 if (char_charset (c
, charset_list
, NULL
))
945 /* Store the multibyte form of C at BUF. */
946 buf
+= CHAR_STRING (c
, buf
);
951 /* C is not encodable. */
954 while (src
+ 1 < src_end
&& CHAR_GLYPH_PADDING_P (src
[1]))
964 unsigned char *p
= SDATA (string
), *pend
= p
+ SBYTES (string
);
966 if (! STRING_MULTIBYTE (string
))
967 string
= string_to_multibyte (string
);
968 nbytes
= buf
- encode_terminal_src
;
969 if (encode_terminal_src_size
< nbytes
+ SBYTES (string
))
971 encode_terminal_src_size
= nbytes
+ SBYTES (string
);
972 encode_terminal_src
= xrealloc (encode_terminal_src
,
973 encode_terminal_src_size
);
974 buf
= encode_terminal_src
+ nbytes
;
976 bcopy (SDATA (string
), buf
, SBYTES (string
));
977 buf
+= SBYTES (string
);
978 nchars
+= SCHARS (string
);
986 coding
->produced
= 0;
990 nbytes
= buf
- encode_terminal_src
;
991 coding
->source
= encode_terminal_src
;
992 if (encode_terminal_dst_size
== 0)
994 encode_terminal_dst_size
= encode_terminal_src_size
;
995 encode_terminal_dst
= xmalloc (encode_terminal_dst_size
);
997 coding
->destination
= encode_terminal_dst
;
998 coding
->dst_bytes
= encode_terminal_dst_size
;
999 encode_coding_object (coding
, Qnil
, 0, 0, nchars
, nbytes
, Qnil
);
1000 /* coding->destination may have been reallocated. */
1001 encode_terminal_dst
= coding
->destination
;
1002 encode_terminal_dst_size
= coding
->dst_bytes
;
1004 return (encode_terminal_dst
);
1009 write_glyphs (string
, len
)
1010 register struct glyph
*string
;
1013 int produced
, consumed
;
1014 struct frame
*sf
= XFRAME (selected_frame
);
1015 struct frame
*f
= updating_frame
? updating_frame
: sf
;
1016 unsigned char *conversion_buffer
;
1017 struct coding_system
*coding
;
1019 if (write_glyphs_hook
1020 && ! FRAME_TERMCAP_P (f
))
1022 (*write_glyphs_hook
) (string
, len
);
1029 /* Don't dare write in last column of bottom line, if Auto-Wrap,
1030 since that would scroll the whole frame on some terminals. */
1033 && curY
+ 1 == FRAME_LINES (sf
)
1034 && (curX
+ len
) == FRAME_COLS (sf
))
1041 /* If terminal_coding does any conversion, use it, otherwise use
1042 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
1043 because it always return 1 if the member src_multibyte is 1. */
1044 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
1045 ? &terminal_coding
: &safe_terminal_coding
);
1046 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1048 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
1052 /* Identify a run of glyphs with the same face. */
1053 int face_id
= string
->face_id
;
1056 for (n
= 1; n
< len
; ++n
)
1057 if (string
[n
].face_id
!= face_id
)
1060 /* Turn appearance modes of the face of the run on. */
1061 highlight_if_desired ();
1062 turn_on_face (f
, face_id
);
1065 /* This is the last run. */
1066 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
1067 conversion_buffer
= encode_terminal_code (string
, n
, coding
);
1068 if (coding
->produced
> 0)
1071 fwrite (conversion_buffer
, 1, coding
->produced
, stdout
);
1072 if (ferror (stdout
))
1075 fwrite (conversion_buffer
, 1, coding
->produced
, termscript
);
1081 /* Turn appearance modes off. */
1082 turn_off_face (f
, face_id
);
1083 turn_off_highlight ();
1090 write_glyphs_with_face (string
, len
, face_id
)
1091 register struct glyph
*string
;
1092 register int len
, face_id
;
1094 struct frame
*sf
= XFRAME (selected_frame
);
1095 struct frame
*f
= updating_frame
? updating_frame
: sf
;
1096 unsigned char *conversion_buffer
;
1097 struct coding_system
*coding
;
1102 /* Don't dare write in last column of bottom line, if Auto-Wrap,
1103 since that would scroll the whole frame on some terminals. */
1106 && curY
+ 1 == FRAME_LINES (sf
)
1107 && (curX
+ len
) == FRAME_COLS (sf
))
1114 /* If terminal_coding does any conversion, use it, otherwise use
1115 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
1116 because it always return 1 if the member src_multibyte is 1. */
1117 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
1118 ? &terminal_coding
: &safe_terminal_coding
);
1119 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1121 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
1124 /* Turn appearance modes of the face. */
1125 highlight_if_desired ();
1126 turn_on_face (f
, face_id
);
1128 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
1129 conversion_buffer
= encode_terminal_code (string
, len
, coding
);
1130 if (coding
->produced
> 0)
1133 fwrite (conversion_buffer
, 1, coding
->produced
, stdout
);
1134 if (ferror (stdout
))
1137 fwrite (conversion_buffer
, 1, coding
->produced
, termscript
);
1141 /* Turn appearance modes off. */
1142 turn_off_face (f
, face_id
);
1143 turn_off_highlight ();
1148 /* If start is zero, insert blanks instead of a string at start */
1151 insert_glyphs (start
, len
)
1152 register struct glyph
*start
;
1156 struct glyph
*glyph
= NULL
;
1157 struct frame
*f
, *sf
;
1158 unsigned char *conversion_buffer
;
1159 unsigned char space
[1];
1160 struct coding_system
*coding
;
1165 if (insert_glyphs_hook
)
1167 (*insert_glyphs_hook
) (start
, len
);
1171 sf
= XFRAME (selected_frame
);
1172 f
= updating_frame
? updating_frame
: sf
;
1174 if (TS_ins_multi_chars
)
1176 buf
= tparam (TS_ins_multi_chars
, 0, 0, len
);
1180 write_glyphs (start
, len
);
1188 space
[0] = SPACEGLYPH
;
1190 /* If terminal_coding does any conversion, use it, otherwise use
1191 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
1192 because it always return 1 if the member src_multibyte is 1. */
1193 coding
= (terminal_coding
.common_flags
& CODING_REQUIRE_ENCODING_MASK
1194 ? &terminal_coding
: &safe_terminal_coding
);
1195 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1197 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
1201 OUTPUT1_IF (TS_ins_char
);
1204 conversion_buffer
= space
;
1205 coding
->produced
= 1;
1209 highlight_if_desired ();
1210 turn_on_face (f
, start
->face_id
);
1213 /* We must open sufficient space for a character which
1214 occupies more than one column. */
1215 while (len
&& CHAR_GLYPH_PADDING_P (*start
))
1217 OUTPUT1_IF (TS_ins_char
);
1222 /* This is the last glyph. */
1223 coding
->mode
|= CODING_MODE_LAST_BLOCK
;
1225 conversion_buffer
= encode_terminal_code (glyph
, 1, coding
);
1228 if (coding
->produced
> 0)
1231 fwrite (conversion_buffer
, 1, coding
->produced
, stdout
);
1232 if (ferror (stdout
))
1235 fwrite (conversion_buffer
, 1, coding
->produced
, termscript
);
1239 OUTPUT1_IF (TS_pad_inserted_char
);
1242 turn_off_face (f
, glyph
->face_id
);
1243 turn_off_highlight ();
1257 if (delete_glyphs_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1259 (*delete_glyphs_hook
) (n
);
1263 if (delete_in_insert_mode
)
1270 OUTPUT_IF (TS_delete_mode
);
1273 if (TS_del_multi_chars
)
1275 buf
= tparam (TS_del_multi_chars
, 0, 0, n
);
1280 for (i
= 0; i
< n
; i
++)
1281 OUTPUT1 (TS_del_char
);
1282 if (!delete_in_insert_mode
)
1283 OUTPUT_IF (TS_end_delete_mode
);
1286 /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
1289 ins_del_lines (vpos
, n
)
1292 char *multi
= n
> 0 ? TS_ins_multi_lines
: TS_del_multi_lines
;
1293 char *single
= n
> 0 ? TS_ins_line
: TS_del_line
;
1294 char *scroll
= n
> 0 ? TS_rev_scroll
: TS_fwd_scroll
;
1297 register int i
= n
> 0 ? n
: -n
;
1300 if (ins_del_lines_hook
&& ! FRAME_TERMCAP_P (updating_frame
))
1302 (*ins_del_lines_hook
) (vpos
, n
);
1306 sf
= XFRAME (selected_frame
);
1308 /* If the lines below the insertion are being pushed
1309 into the end of the window, this is the same as clearing;
1310 and we know the lines are already clear, since the matching
1311 deletion has already been done. So can ignore this. */
1312 /* If the lines below the deletion are blank lines coming
1313 out of the end of the window, don't bother,
1314 as there will be a matching inslines later that will flush them. */
1315 if (scroll_region_ok
&& vpos
+ i
>= specified_window
)
1317 if (!memory_below_frame
&& vpos
+ i
>= FRAME_LINES (sf
))
1322 raw_cursor_to (vpos
, 0);
1323 background_highlight ();
1324 buf
= tparam (multi
, 0, 0, i
);
1330 raw_cursor_to (vpos
, 0);
1331 background_highlight ();
1339 set_scroll_region (vpos
, specified_window
);
1341 raw_cursor_to (specified_window
- 1, 0);
1343 raw_cursor_to (vpos
, 0);
1344 background_highlight ();
1346 OUTPUTL (scroll
, specified_window
- vpos
);
1347 set_scroll_region (0, specified_window
);
1350 if (!scroll_region_ok
&& memory_below_frame
&& n
< 0)
1352 cursor_to (FRAME_LINES (sf
) + n
, 0);
1357 /* Compute cost of sending "str", in characters,
1358 not counting any line-dependent padding. */
1366 tputs (str
, 0, evalcost
);
1370 /* Compute cost of sending "str", in characters,
1371 counting any line-dependent padding at one line. */
1374 string_cost_one_line (str
)
1379 tputs (str
, 1, evalcost
);
1383 /* Compute per line amount of line-dependent padding,
1384 in tenths of characters. */
1392 tputs (str
, 0, evalcost
);
1395 tputs (str
, 10, evalcost
);
1400 /* char_ins_del_cost[n] is cost of inserting N characters.
1401 char_ins_del_cost[-n] is cost of deleting N characters.
1402 The length of this vector is based on max_frame_cols. */
1404 int *char_ins_del_vector
;
1406 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))])
1411 calculate_ins_del_char_costs (frame
)
1414 int ins_startup_cost
, del_startup_cost
;
1415 int ins_cost_per_char
, del_cost_per_char
;
1419 if (TS_ins_multi_chars
)
1421 ins_cost_per_char
= 0;
1422 ins_startup_cost
= string_cost_one_line (TS_ins_multi_chars
);
1424 else if (TS_ins_char
|| TS_pad_inserted_char
1425 || (TS_insert_mode
&& TS_end_insert_mode
))
1427 ins_startup_cost
= (30 * (string_cost (TS_insert_mode
)
1428 + string_cost (TS_end_insert_mode
))) / 100;
1429 ins_cost_per_char
= (string_cost_one_line (TS_ins_char
)
1430 + string_cost_one_line (TS_pad_inserted_char
));
1434 ins_startup_cost
= 9999;
1435 ins_cost_per_char
= 0;
1438 if (TS_del_multi_chars
)
1440 del_cost_per_char
= 0;
1441 del_startup_cost
= string_cost_one_line (TS_del_multi_chars
);
1443 else if (TS_del_char
)
1445 del_startup_cost
= (string_cost (TS_delete_mode
)
1446 + string_cost (TS_end_delete_mode
));
1447 if (delete_in_insert_mode
)
1448 del_startup_cost
/= 2;
1449 del_cost_per_char
= string_cost_one_line (TS_del_char
);
1453 del_startup_cost
= 9999;
1454 del_cost_per_char
= 0;
1457 /* Delete costs are at negative offsets */
1458 p
= &char_ins_del_cost (frame
)[0];
1459 for (i
= FRAME_COLS (frame
); --i
>= 0;)
1460 *--p
= (del_startup_cost
+= del_cost_per_char
);
1462 /* Doing nothing is free */
1463 p
= &char_ins_del_cost (frame
)[0];
1466 /* Insert costs are at positive offsets */
1467 for (i
= FRAME_COLS (frame
); --i
>= 0;)
1468 *p
++ = (ins_startup_cost
+= ins_cost_per_char
);
1472 calculate_costs (frame
)
1475 register char *f
= (TS_set_scroll_region
1476 ? TS_set_scroll_region
1477 : TS_set_scroll_region_1
);
1479 FRAME_COST_BAUD_RATE (frame
) = baud_rate
;
1481 scroll_region_cost
= string_cost (f
);
1483 /* These variables are only used for terminal stuff. They are allocated
1484 once for the terminal frame of X-windows emacs, but not used afterwards.
1486 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1487 X turns off char_ins_del_ok. */
1489 max_frame_lines
= max (max_frame_lines
, FRAME_LINES (frame
));
1490 max_frame_cols
= max (max_frame_cols
, FRAME_COLS (frame
));
1494 if (char_ins_del_vector
!= 0)
1496 = (int *) xrealloc (char_ins_del_vector
,
1498 + 2 * max_frame_cols
* sizeof (int)));
1501 = (int *) xmalloc (sizeof (int)
1502 + 2 * max_frame_cols
* sizeof (int));
1504 bzero (char_ins_del_vector
, (sizeof (int)
1505 + 2 * max_frame_cols
* sizeof (int)));
1507 if (f
&& (!TS_ins_line
&& !TS_del_line
))
1508 do_line_insertion_deletion_costs (frame
,
1509 TS_rev_scroll
, TS_ins_multi_lines
,
1510 TS_fwd_scroll
, TS_del_multi_lines
,
1513 do_line_insertion_deletion_costs (frame
,
1514 TS_ins_line
, TS_ins_multi_lines
,
1515 TS_del_line
, TS_del_multi_lines
,
1518 calculate_ins_del_char_costs (frame
);
1520 /* Don't use TS_repeat if its padding is worse than sending the chars */
1521 if (TS_repeat
&& per_line_cost (TS_repeat
) * baud_rate
< 9000)
1522 RPov
= string_cost (TS_repeat
);
1524 RPov
= FRAME_COLS (frame
) * 2;
1526 cmcostinit (); /* set up cursor motion costs */
1533 /* Termcap capability names that correspond directly to X keysyms.
1534 Some of these (marked "terminfo") aren't supplied by old-style
1535 (Berkeley) termcap entries. They're listed in X keysym order;
1536 except we put the keypad keys first, so that if they clash with
1537 other keys (as on the IBM PC keyboard) they get overridden.
1540 static struct fkey_table keys
[] =
1542 {"kh", "home"}, /* termcap */
1543 {"kl", "left"}, /* termcap */
1544 {"ku", "up"}, /* termcap */
1545 {"kr", "right"}, /* termcap */
1546 {"kd", "down"}, /* termcap */
1547 {"%8", "prior"}, /* terminfo */
1548 {"%5", "next"}, /* terminfo */
1549 {"@7", "end"}, /* terminfo */
1550 {"@1", "begin"}, /* terminfo */
1551 {"*6", "select"}, /* terminfo */
1552 {"%9", "print"}, /* terminfo */
1553 {"@4", "execute"}, /* terminfo --- actually the `command' key */
1555 * "insert" --- see below
1557 {"&8", "undo"}, /* terminfo */
1558 {"%0", "redo"}, /* terminfo */
1559 {"%7", "menu"}, /* terminfo --- actually the `options' key */
1560 {"@0", "find"}, /* terminfo */
1561 {"@2", "cancel"}, /* terminfo */
1562 {"%1", "help"}, /* terminfo */
1564 * "break" goes here, but can't be reliably intercepted with termcap
1566 {"&4", "reset"}, /* terminfo --- actually `restart' */
1568 * "system" and "user" --- no termcaps
1570 {"kE", "clearline"}, /* terminfo */
1571 {"kA", "insertline"}, /* terminfo */
1572 {"kL", "deleteline"}, /* terminfo */
1573 {"kI", "insertchar"}, /* terminfo */
1574 {"kD", "deletechar"}, /* terminfo */
1575 {"kB", "backtab"}, /* terminfo */
1577 * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
1579 {"@8", "kp-enter"}, /* terminfo */
1581 * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
1582 * "kp-multiply", "kp-add", "kp-separator",
1583 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
1584 * --- no termcaps for any of these.
1586 {"K4", "kp-1"}, /* terminfo */
1588 * "kp-2" --- no termcap
1590 {"K5", "kp-3"}, /* terminfo */
1592 * "kp-4" --- no termcap
1594 {"K2", "kp-5"}, /* terminfo */
1596 * "kp-6" --- no termcap
1598 {"K1", "kp-7"}, /* terminfo */
1600 * "kp-8" --- no termcap
1602 {"K3", "kp-9"}, /* terminfo */
1604 * "kp-equal" --- no termcap
1616 {"&0", "S-cancel"}, /*shifted cancel key*/
1617 {"&9", "S-begin"}, /*shifted begin key*/
1618 {"*0", "S-find"}, /*shifted find key*/
1619 {"*1", "S-execute"}, /*shifted execute? actually shifted command key*/
1620 {"*4", "S-delete"}, /*shifted delete-character key*/
1621 {"*7", "S-end"}, /*shifted end key*/
1622 {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
1623 {"#1", "S-help"}, /*shifted help key*/
1624 {"#2", "S-home"}, /*shifted home key*/
1625 {"#3", "S-insert"}, /*shifted insert-character key*/
1626 {"#4", "S-left"}, /*shifted left-arrow key*/
1627 {"%d", "S-menu"}, /*shifted menu? actually shifted options key*/
1628 {"%c", "S-next"}, /*shifted next key*/
1629 {"%e", "S-prior"}, /*shifted previous key*/
1630 {"%f", "S-print"}, /*shifted print key*/
1631 {"%g", "S-redo"}, /*shifted redo key*/
1632 {"%i", "S-right"}, /*shifted right-arrow key*/
1633 {"!3", "S-undo"} /*shifted undo key*/
1636 static char **term_get_fkeys_arg
;
1637 static Lisp_Object
term_get_fkeys_1 ();
1639 /* Find the escape codes sent by the function keys for Vfunction_key_map.
1640 This function scans the termcap function key sequence entries, and
1641 adds entries to Vfunction_key_map for each function key it finds. */
1644 term_get_fkeys (address
)
1647 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
1648 errors during the call. The only errors should be from Fdefine_key
1649 when given a key sequence containing an invalid prefix key. If the
1650 termcap defines function keys which use a prefix that is already bound
1651 to a command by the default bindings, we should silently ignore that
1652 function key specification, rather than giving the user an error and
1653 refusing to run at all on such a terminal. */
1655 extern Lisp_Object
Fidentity ();
1656 term_get_fkeys_arg
= address
;
1657 internal_condition_case (term_get_fkeys_1
, Qerror
, Fidentity
);
1665 char **address
= term_get_fkeys_arg
;
1667 /* This can happen if CANNOT_DUMP or with strange options. */
1669 Vfunction_key_map
= Fmake_sparse_keymap (Qnil
);
1671 for (i
= 0; i
< (sizeof (keys
)/sizeof (keys
[0])); i
++)
1673 char *sequence
= tgetstr (keys
[i
].cap
, address
);
1675 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1676 Fmake_vector (make_number (1),
1677 intern (keys
[i
].name
)));
1680 /* The uses of the "k0" capability are inconsistent; sometimes it
1681 describes F10, whereas othertimes it describes F0 and "k;" describes F10.
1682 We will attempt to politely accommodate both systems by testing for
1683 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
1686 char *k_semi
= tgetstr ("k;", address
);
1687 char *k0
= tgetstr ("k0", address
);
1688 char *k0_name
= "f10";
1693 /* Define f0 first, so that f10 takes precedence in case the
1694 key sequences happens to be the same. */
1695 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1696 Fmake_vector (make_number (1), intern ("f0")));
1697 Fdefine_key (Vfunction_key_map
, build_string (k_semi
),
1698 Fmake_vector (make_number (1), intern ("f10")));
1701 Fdefine_key (Vfunction_key_map
, build_string (k0
),
1702 Fmake_vector (make_number (1), intern (k0_name
)));
1705 /* Set up cookies for numbered function keys above f10. */
1707 char fcap
[3], fkey
[4];
1709 fcap
[0] = 'F'; fcap
[2] = '\0';
1710 for (i
= 11; i
< 64; i
++)
1713 fcap
[1] = '1' + i
- 11;
1715 fcap
[1] = 'A' + i
- 20;
1717 fcap
[1] = 'a' + i
- 46;
1720 char *sequence
= tgetstr (fcap
, address
);
1723 sprintf (fkey
, "f%d", i
);
1724 Fdefine_key (Vfunction_key_map
, build_string (sequence
),
1725 Fmake_vector (make_number (1),
1733 * Various mappings to try and get a better fit.
1736 #define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
1737 if (!tgetstr (cap1, address)) \
1739 char *sequence = tgetstr (cap2, address); \
1741 Fdefine_key (Vfunction_key_map, build_string (sequence), \
1742 Fmake_vector (make_number (1), \
1746 /* if there's no key_next keycap, map key_npage to `next' keysym */
1747 CONDITIONAL_REASSIGN ("%5", "kN", "next");
1748 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
1749 CONDITIONAL_REASSIGN ("%8", "kP", "prior");
1750 /* if there's no key_dc keycap, map key_ic to `insert' keysym */
1751 CONDITIONAL_REASSIGN ("kD", "kI", "insert");
1752 /* if there's no key_end keycap, map key_ll to 'end' keysym */
1753 CONDITIONAL_REASSIGN ("@7", "kH", "end");
1755 /* IBM has their own non-standard dialect of terminfo.
1756 If the standard name isn't found, try the IBM name. */
1757 CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
1758 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
1759 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
1760 CONDITIONAL_REASSIGN ("%7", "ki", "menu");
1761 CONDITIONAL_REASSIGN ("@7", "kw", "end");
1762 CONDITIONAL_REASSIGN ("F1", "k<", "f11");
1763 CONDITIONAL_REASSIGN ("F2", "k>", "f12");
1764 CONDITIONAL_REASSIGN ("%1", "kq", "help");
1765 CONDITIONAL_REASSIGN ("*6", "kU", "select");
1766 #undef CONDITIONAL_REASSIGN
1773 /***********************************************************************
1774 Character Display Information
1775 ***********************************************************************/
1777 /* Avoid name clash with functions defined in xterm.c */
1779 #define append_glyph append_glyph_term
1780 #define produce_stretch_glyph produce_stretch_glyph_term
1781 #define append_composite_glyph append_composite_glyph_term
1782 #define produce_composite_glyph produce_composite_glyph_term
1785 static void append_glyph
P_ ((struct it
*));
1786 static void produce_stretch_glyph
P_ ((struct it
*));
1787 static void append_composite_glyph
P_ ((struct it
*));
1788 static void produce_composite_glyph
P_ ((struct it
*));
1790 /* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1791 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
1792 the character for which to produce glyphs; IT->face_id contains the
1793 character's face. Padding glyphs are appended if IT->c has a
1794 IT->pixel_width > 1. */
1800 struct glyph
*glyph
, *end
;
1803 xassert (it
->glyph_row
);
1804 glyph
= (it
->glyph_row
->glyphs
[it
->area
]
1805 + it
->glyph_row
->used
[it
->area
]);
1806 end
= it
->glyph_row
->glyphs
[1 + it
->area
];
1809 i
< it
->pixel_width
&& glyph
< end
;
1812 glyph
->type
= CHAR_GLYPH
;
1813 glyph
->pixel_width
= 1;
1814 glyph
->u
.ch
= it
->char_to_display
;
1815 glyph
->face_id
= it
->face_id
;
1816 glyph
->padding_p
= i
> 0;
1817 glyph
->charpos
= CHARPOS (it
->position
);
1818 glyph
->object
= it
->object
;
1820 ++it
->glyph_row
->used
[it
->area
];
1826 /* Produce glyphs for the display element described by IT. *IT
1827 specifies what we want to produce a glyph for (character, image, ...),
1828 and where in the glyph matrix we currently are (glyph row and hpos).
1829 produce_glyphs fills in output fields of *IT with information such as the
1830 pixel width and height of a character, and maybe output actual glyphs at
1831 the same time if IT->glyph_row is non-null. See the explanation of
1832 struct display_iterator in dispextern.h for an overview.
1834 produce_glyphs also stores the result of glyph width, ascent
1835 etc. computations in *IT.
1837 IT->glyph_row may be null, in which case produce_glyphs does not
1838 actually fill in the glyphs. This is used in the move_* functions
1839 in xdisp.c for text width and height computations.
1841 Callers usually don't call produce_glyphs directly;
1842 instead they use the macro PRODUCE_GLYPHS. */
1848 /* If a hook is installed, let it do the work. */
1850 /* Nothing but characters are supported on terminal frames. */
1851 xassert (it
->what
== IT_CHARACTER
1852 || it
->what
== IT_COMPOSITION
1853 || it
->what
== IT_STRETCH
);
1855 if (it
->what
== IT_STRETCH
)
1857 produce_stretch_glyph (it
);
1861 if (it
->what
== IT_COMPOSITION
)
1863 produce_composite_glyph (it
);
1867 /* Maybe translate single-byte characters to multibyte. */
1868 it
->char_to_display
= it
->c
;
1870 if (it
->c
>= 040 && it
->c
< 0177)
1872 it
->pixel_width
= it
->nglyphs
= 1;
1876 else if (it
->c
== '\n')
1877 it
->pixel_width
= it
->nglyphs
= 0;
1878 else if (it
->c
== '\t')
1880 int absolute_x
= (it
->current_x
1881 + it
->continuation_lines_width
);
1883 = (((1 + absolute_x
+ it
->tab_width
- 1)
1888 /* If part of the TAB has been displayed on the previous line
1889 which is continued now, continuation_lines_width will have
1890 been incremented already by the part that fitted on the
1891 continued line. So, we will get the right number of spaces
1893 nspaces
= next_tab_x
- absolute_x
;
1899 it
->char_to_display
= ' ';
1900 it
->pixel_width
= it
->len
= 1;
1906 it
->pixel_width
= nspaces
;
1907 it
->nglyphs
= nspaces
;
1909 else if (CHAR_BYTE8_P (it
->c
))
1911 if (unibyte_display_via_language_environment
1914 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1915 it
->pixel_width
= CHAR_WIDTH (it
->char_to_display
);
1916 it
->nglyphs
= it
->pixel_width
;
1922 /* Coming here means that it->c is from display table, thus
1923 we must send the raw 8-bit byte as is to the terminal.
1924 Although there's no way to know how many columns it
1925 occupies on a screen, it is a good assumption that a
1926 single byte code has 1-column width. */
1927 it
->pixel_width
= it
->nglyphs
= 1;
1934 it
->pixel_width
= CHAR_WIDTH (it
->c
);
1935 it
->nglyphs
= it
->pixel_width
;
1942 /* Advance current_x by the pixel width as a convenience for
1944 if (it
->area
== TEXT_AREA
)
1945 it
->current_x
+= it
->pixel_width
;
1946 it
->ascent
= it
->max_ascent
= it
->phys_ascent
= it
->max_phys_ascent
= 0;
1947 it
->descent
= it
->max_descent
= it
->phys_descent
= it
->max_phys_descent
= 1;
1951 /* Produce a stretch glyph for iterator IT. IT->object is the value
1952 of the glyph property displayed. The value must be a list
1953 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1956 1. `:width WIDTH' specifies that the space should be WIDTH *
1957 canonical char width wide. WIDTH may be an integer or floating
1960 2. `:align-to HPOS' specifies that the space should be wide enough
1961 to reach HPOS, a value in canonical character units. */
1964 produce_stretch_glyph (it
)
1967 /* (space :width WIDTH ...) */
1968 Lisp_Object prop
, plist
;
1969 int width
= 0, align_to
= -1;
1970 int zero_width_ok_p
= 0;
1973 /* List should start with `space'. */
1974 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1975 plist
= XCDR (it
->object
);
1977 /* Compute the width of the stretch. */
1978 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
1979 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, 0))
1981 /* Absolute width `:width WIDTH' specified and valid. */
1982 zero_width_ok_p
= 1;
1983 width
= (int)(tem
+ 0.5);
1985 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
1986 && calc_pixel_width_or_height (&tem
, it
, prop
, 0, 1, &align_to
))
1988 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
1989 align_to
= (align_to
< 0
1991 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
1992 else if (align_to
< 0)
1993 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
1994 width
= max (0, (int)(tem
+ 0.5) + align_to
- it
->current_x
);
1995 zero_width_ok_p
= 1;
1998 /* Nothing specified -> width defaults to canonical char width. */
1999 width
= FRAME_COLUMN_WIDTH (it
->f
);
2001 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
2004 if (width
> 0 && it
->glyph_row
)
2006 Lisp_Object o_object
= it
->object
;
2007 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
2010 if (!STRINGP (object
))
2011 object
= it
->w
->buffer
;
2012 it
->object
= object
;
2013 it
->char_to_display
= ' ';
2014 it
->pixel_width
= it
->len
= 1;
2017 it
->object
= o_object
;
2019 it
->pixel_width
= width
;
2020 it
->nglyphs
= width
;
2024 /* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
2025 Called from produce_composite_glyph for terminal frames if
2026 IT->glyph_row != NULL. IT->face_id contains the character's
2030 append_composite_glyph (it
)
2033 struct glyph
*glyph
;
2035 xassert (it
->glyph_row
);
2036 glyph
= it
->glyph_row
->glyphs
[it
->area
] + it
->glyph_row
->used
[it
->area
];
2037 if (glyph
< it
->glyph_row
->glyphs
[1 + it
->area
])
2039 glyph
->type
= COMPOSITE_GLYPH
;
2040 glyph
->pixel_width
= it
->pixel_width
;
2041 glyph
->u
.cmp_id
= it
->cmp_id
;
2042 glyph
->face_id
= it
->face_id
;
2043 glyph
->padding_p
= 0;
2044 glyph
->charpos
= CHARPOS (it
->position
);
2045 glyph
->object
= it
->object
;
2047 ++it
->glyph_row
->used
[it
->area
];
2053 /* Produce a composite glyph for iterator IT. IT->cmp_id is the ID of
2054 the composition. We simply produces components of the composition
2055 assuming that that the terminal has a capability to layout/render
2059 produce_composite_glyph (it
)
2062 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2065 xassert (cmp
->glyph_len
> 0);
2066 c
= COMPOSITION_GLYPH (cmp
, 0);
2067 it
->pixel_width
= CHAR_WIDTH (it
->c
);
2071 append_composite_glyph (it
);
2075 /* Get information about special display element WHAT in an
2076 environment described by IT. WHAT is one of IT_TRUNCATION or
2077 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
2078 non-null glyph_row member. This function ensures that fields like
2079 face_id, c, len of IT are left untouched. */
2082 produce_special_glyphs (it
, what
)
2084 enum display_element_type what
;
2091 temp_it
.what
= IT_CHARACTER
;
2093 temp_it
.object
= make_number (0);
2094 bzero (&temp_it
.current
, sizeof temp_it
.current
);
2096 if (what
== IT_CONTINUATION
)
2098 /* Continuation glyph. */
2100 && INTEGERP (DISP_CONTINUE_GLYPH (it
->dp
))
2101 && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it
->dp
))))
2103 glyph
= XINT (DISP_CONTINUE_GLYPH (it
->dp
));
2104 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
2109 else if (what
== IT_TRUNCATION
)
2111 /* Truncation glyph. */
2113 && INTEGERP (DISP_TRUNC_GLYPH (it
->dp
))
2114 && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it
->dp
))))
2116 glyph
= XINT (DISP_TRUNC_GLYPH (it
->dp
));
2117 glyph
= spec_glyph_lookup_face (XWINDOW (it
->window
), glyph
);
2125 temp_it
.c
= FAST_GLYPH_CHAR (glyph
);
2126 temp_it
.face_id
= FAST_GLYPH_FACE (glyph
);
2127 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
2129 produce_glyphs (&temp_it
);
2130 it
->pixel_width
= temp_it
.pixel_width
;
2131 it
->nglyphs
= temp_it
.pixel_width
;
2136 /***********************************************************************
2138 ***********************************************************************/
2140 /* Value is non-zero if attribute ATTR may be used. ATTR should be
2141 one of the enumerators from enum no_color_bit, or a bit set built
2142 from them. Some display attributes may not be used together with
2143 color; the termcap capability `NC' specifies which ones. */
2145 #define MAY_USE_WITH_COLORS_P(ATTR) \
2146 (TN_max_colors > 0 \
2147 ? (TN_no_color_video & (ATTR)) == 0 \
2150 /* Turn appearances of face FACE_ID on tty frame F on.
2151 FACE_ID is a realized face ID number, in the face cache. */
2154 turn_on_face (f
, face_id
)
2158 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2159 long fg
= face
->foreground
;
2160 long bg
= face
->background
;
2162 /* Do this first because TS_end_standout_mode may be the same
2163 as TS_exit_attribute_mode, which turns all appearances off. */
2164 if (MAY_USE_WITH_COLORS_P (NC_REVERSE
))
2166 if (TN_max_colors
> 0)
2168 if (fg
>= 0 && bg
>= 0)
2170 /* If the terminal supports colors, we can set them
2171 below without using reverse video. The face's fg
2172 and bg colors are set as they should appear on
2173 the screen, i.e. they take the inverse-video'ness
2174 of the face already into account. */
2176 else if (inverse_video
)
2178 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
2179 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
2180 toggle_highlight ();
2184 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
2185 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
2186 toggle_highlight ();
2191 /* If we can't display colors, use reverse video
2192 if the face specifies that. */
2195 if (fg
== FACE_TTY_DEFAULT_FG_COLOR
2196 || bg
== FACE_TTY_DEFAULT_BG_COLOR
)
2197 toggle_highlight ();
2201 if (fg
== FACE_TTY_DEFAULT_BG_COLOR
2202 || bg
== FACE_TTY_DEFAULT_FG_COLOR
)
2203 toggle_highlight ();
2208 if (face
->tty_bold_p
)
2210 if (MAY_USE_WITH_COLORS_P (NC_BOLD
))
2211 OUTPUT1_IF (TS_enter_bold_mode
);
2213 else if (face
->tty_dim_p
)
2214 if (MAY_USE_WITH_COLORS_P (NC_DIM
))
2215 OUTPUT1_IF (TS_enter_dim_mode
);
2217 /* Alternate charset and blinking not yet used. */
2218 if (face
->tty_alt_charset_p
2219 && MAY_USE_WITH_COLORS_P (NC_ALT_CHARSET
))
2220 OUTPUT1_IF (TS_enter_alt_charset_mode
);
2222 if (face
->tty_blinking_p
2223 && MAY_USE_WITH_COLORS_P (NC_BLINK
))
2224 OUTPUT1_IF (TS_enter_blink_mode
);
2226 if (face
->tty_underline_p
&& MAY_USE_WITH_COLORS_P (NC_UNDERLINE
))
2227 OUTPUT1_IF (TS_enter_underline_mode
);
2229 if (TN_max_colors
> 0)
2233 ts
= standout_mode
? TS_set_background
: TS_set_foreground
;
2236 p
= tparam (ts
, NULL
, 0, (int) fg
);
2241 ts
= standout_mode
? TS_set_foreground
: TS_set_background
;
2244 p
= tparam (ts
, NULL
, 0, (int) bg
);
2252 /* Turn off appearances of face FACE_ID on tty frame F. */
2255 turn_off_face (f
, face_id
)
2259 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2261 xassert (face
!= NULL
);
2263 if (TS_exit_attribute_mode
)
2265 /* Capability "me" will turn off appearance modes double-bright,
2266 half-bright, reverse-video, standout, underline. It may or
2267 may not turn off alt-char-mode. */
2268 if (face
->tty_bold_p
2270 || face
->tty_reverse_p
2271 || face
->tty_alt_charset_p
2272 || face
->tty_blinking_p
2273 || face
->tty_underline_p
)
2275 OUTPUT1_IF (TS_exit_attribute_mode
);
2276 if (strcmp (TS_exit_attribute_mode
, TS_end_standout_mode
) == 0)
2280 if (face
->tty_alt_charset_p
)
2281 OUTPUT_IF (TS_exit_alt_charset_mode
);
2285 /* If we don't have "me" we can only have those appearances
2286 that have exit sequences defined. */
2287 if (face
->tty_alt_charset_p
)
2288 OUTPUT_IF (TS_exit_alt_charset_mode
);
2290 if (face
->tty_underline_p
)
2291 OUTPUT_IF (TS_exit_underline_mode
);
2294 /* Switch back to default colors. */
2295 if (TN_max_colors
> 0
2296 && ((face
->foreground
!= FACE_TTY_DEFAULT_COLOR
2297 && face
->foreground
!= FACE_TTY_DEFAULT_FG_COLOR
)
2298 || (face
->background
!= FACE_TTY_DEFAULT_COLOR
2299 && face
->background
!= FACE_TTY_DEFAULT_BG_COLOR
)))
2300 OUTPUT1_IF (TS_orig_pair
);
2304 /* Return non-zero if the terminal on frame F supports all of the
2305 capabilities in CAPS simultaneously, with foreground and background
2306 colors FG and BG. */
2309 tty_capable_p (f
, caps
, fg
, bg
)
2312 unsigned long fg
, bg
;
2314 #define TTY_CAPABLE_P_TRY(cap, TS, NC_bit) \
2315 if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(NC_bit))) \
2318 TTY_CAPABLE_P_TRY (TTY_CAP_INVERSE
, TS_standout_mode
, NC_REVERSE
);
2319 TTY_CAPABLE_P_TRY (TTY_CAP_UNDERLINE
, TS_enter_underline_mode
, NC_UNDERLINE
);
2320 TTY_CAPABLE_P_TRY (TTY_CAP_BOLD
, TS_enter_bold_mode
, NC_BOLD
);
2321 TTY_CAPABLE_P_TRY (TTY_CAP_DIM
, TS_enter_dim_mode
, NC_DIM
);
2322 TTY_CAPABLE_P_TRY (TTY_CAP_BLINK
, TS_enter_blink_mode
, NC_BLINK
);
2323 TTY_CAPABLE_P_TRY (TTY_CAP_ALT_CHARSET
, TS_enter_alt_charset_mode
, NC_ALT_CHARSET
);
2330 /* Return non-zero if the terminal is capable to display colors. */
2332 DEFUN ("tty-display-color-p", Ftty_display_color_p
, Stty_display_color_p
,
2334 doc
: /* Return non-nil if TTY can display colors on DISPLAY. */)
2336 Lisp_Object display
;
2338 return TN_max_colors
> 0 ? Qt
: Qnil
;
2341 /* Return the number of supported colors. */
2342 DEFUN ("tty-display-color-cells", Ftty_display_color_cells
,
2343 Stty_display_color_cells
, 0, 1, 0,
2344 doc
: /* Return the number of colors supported by TTY on DISPLAY. */)
2346 Lisp_Object display
;
2348 return make_number (TN_max_colors
);
2353 /* Save or restore the default color-related capabilities of this
2356 tty_default_color_capabilities (save
)
2360 *default_orig_pair
, *default_set_foreground
, *default_set_background
;
2361 static int default_max_colors
, default_max_pairs
, default_no_color_video
;
2365 if (default_orig_pair
)
2366 xfree (default_orig_pair
);
2367 default_orig_pair
= TS_orig_pair
? xstrdup (TS_orig_pair
) : NULL
;
2369 if (default_set_foreground
)
2370 xfree (default_set_foreground
);
2371 default_set_foreground
= TS_set_foreground
? xstrdup (TS_set_foreground
)
2374 if (default_set_background
)
2375 xfree (default_set_background
);
2376 default_set_background
= TS_set_background
? xstrdup (TS_set_background
)
2379 default_max_colors
= TN_max_colors
;
2380 default_max_pairs
= TN_max_pairs
;
2381 default_no_color_video
= TN_no_color_video
;
2385 TS_orig_pair
= default_orig_pair
;
2386 TS_set_foreground
= default_set_foreground
;
2387 TS_set_background
= default_set_background
;
2388 TN_max_colors
= default_max_colors
;
2389 TN_max_pairs
= default_max_pairs
;
2390 TN_no_color_video
= default_no_color_video
;
2394 /* Setup one of the standard tty color schemes according to MODE.
2395 MODE's value is generally the number of colors which we want to
2396 support; zero means set up for the default capabilities, the ones
2397 we saw at term_init time; -1 means turn off color support. */
2399 tty_setup_colors (mode
)
2402 /* Canonicalize all negative values of MODE. */
2408 case -1: /* no colors at all */
2411 TN_no_color_video
= 0;
2412 TS_set_foreground
= TS_set_background
= TS_orig_pair
= NULL
;
2414 case 0: /* default colors, if any */
2416 tty_default_color_capabilities (0);
2418 case 8: /* 8 standard ANSI colors */
2419 TS_orig_pair
= "\033[0m";
2421 TS_set_foreground
= "\033[3%p1%dm";
2422 TS_set_background
= "\033[4%p1%dm";
2424 TS_set_foreground
= "\033[3%dm";
2425 TS_set_background
= "\033[4%dm";
2429 TN_no_color_video
= 0;
2435 set_tty_color_mode (f
, val
)
2439 Lisp_Object color_mode_spec
, current_mode_spec
;
2440 Lisp_Object color_mode
, current_mode
;
2442 extern Lisp_Object Qtty_color_mode
;
2443 Lisp_Object tty_color_mode_alist
;
2445 tty_color_mode_alist
= Fintern_soft (build_string ("tty-color-mode-alist"),
2452 if (NILP (tty_color_mode_alist
))
2453 color_mode_spec
= Qnil
;
2455 color_mode_spec
= Fassq (val
, XSYMBOL (tty_color_mode_alist
)->value
);
2457 if (CONSP (color_mode_spec
))
2458 color_mode
= XCDR (color_mode_spec
);
2463 current_mode_spec
= assq_no_quit (Qtty_color_mode
, f
->param_alist
);
2465 if (CONSP (current_mode_spec
))
2466 current_mode
= XCDR (current_mode_spec
);
2468 current_mode
= Qnil
;
2469 if (INTEGERP (color_mode
))
2470 mode
= XINT (color_mode
);
2472 mode
= 0; /* meaning default */
2473 if (INTEGERP (current_mode
))
2474 old_mode
= XINT (current_mode
);
2478 if (mode
!= old_mode
)
2480 tty_setup_colors (mode
);
2481 /* This recomputes all the faces given the new color
2483 call0 (intern ("tty-set-up-initial-frame-faces"));
2488 #endif /* !WINDOWSNT */
2491 /***********************************************************************
2493 ***********************************************************************/
2497 term_mouse_moveto (int x
, int y
)
2499 /* TODO: how to set mouse position?
2502 name = (const char *) ttyname (0);
2503 fd = open (name, O_WRONLY);
2504 SOME_FUNCTION (x, y, fd);
2507 last_mouse_y = y; */
2511 term_show_mouse_face (enum draw_glyphs_face draw
)
2513 struct window
*w
= XWINDOW (Qmouse_face_window
);
2517 if (/* If window is in the process of being destroyed, don't bother
2519 w
->current_matrix
!= NULL
2520 /* Recognize when we are called to operate on rows that don't exist
2521 anymore. This can happen when a window is split. */
2522 && mouse_face_end_row
< w
->current_matrix
->nrows
)
2524 /* write_glyphs writes at cursor position, so we need to
2525 temporarily move cursor coordinates to the beginning of
2526 the highlight region. */
2528 /* Save current cursor co-ordinates */
2532 /* Note that mouse_face_beg_row etc. are window relative. */
2533 for (i
= mouse_face_beg_row
; i
<= mouse_face_end_row
; i
++)
2535 int start_hpos
, end_hpos
, nglyphs
;
2536 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
2538 /* Don't do anything if row doesn't have valid contents. */
2539 if (!row
->enabled_p
)
2542 /* For all but the first row, the highlight starts at column 0. */
2543 if (i
== mouse_face_beg_row
)
2544 start_hpos
= mouse_face_beg_col
;
2548 if (i
== mouse_face_end_row
)
2549 end_hpos
= mouse_face_end_col
;
2552 end_hpos
= row
->used
[TEXT_AREA
];
2553 if (draw
== DRAW_NORMAL_TEXT
)
2554 row
->fill_line_p
= 1; /* Clear to end of line */
2557 if (end_hpos
<= start_hpos
)
2559 /* Record that some glyphs of this row are displayed in
2561 row
->mouse_face_p
= draw
> 0;
2563 nglyphs
= end_hpos
- start_hpos
;
2565 if (end_hpos
>= row
->used
[TEXT_AREA
])
2566 nglyphs
= row
->used
[TEXT_AREA
] - start_hpos
;
2568 pos_y
= row
->y
+ WINDOW_TOP_EDGE_Y (w
);
2569 pos_x
= row
->used
[LEFT_MARGIN_AREA
] + start_hpos
2570 + WINDOW_LEFT_EDGE_X (w
);
2572 cursor_to (pos_y
, pos_x
);
2574 if (draw
== DRAW_MOUSE_FACE
)
2576 write_glyphs_with_face (row
->glyphs
[TEXT_AREA
] + start_hpos
,
2577 nglyphs
, mouse_face_face_id
);
2579 else /* draw == DRAW_NORMAL_TEXT */
2580 write_glyphs (row
->glyphs
[TEXT_AREA
] + start_hpos
, nglyphs
);
2582 cursor_to (save_y
, save_x
);
2587 term_clear_mouse_face ()
2589 if (!NILP (Qmouse_face_window
))
2590 term_show_mouse_face (DRAW_NORMAL_TEXT
);
2592 mouse_face_beg_row
= mouse_face_beg_col
= -1;
2593 mouse_face_end_row
= mouse_face_end_col
= -1;
2594 Qmouse_face_window
= Qnil
;
2597 /* Find the glyph matrix position of buffer position POS in window W.
2598 *HPOS and *VPOS are set to the positions found. W's current glyphs
2599 must be up to date. If POS is above window start return (0, 0).
2600 If POS is after end of W, return end of last line in W.
2601 - taken from msdos.c */
2603 fast_find_position (struct window
*w
, int pos
, int *hpos
, int *vpos
)
2605 int i
, lastcol
, line_start_position
, maybe_next_line_p
= 0;
2606 int yb
= window_text_bottom_y (w
);
2607 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0), *best_row
= row
;
2611 if (row
->used
[TEXT_AREA
])
2612 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
2614 line_start_position
= 0;
2616 if (line_start_position
> pos
)
2618 /* If the position sought is the end of the buffer,
2619 don't include the blank lines at the bottom of the window. */
2620 else if (line_start_position
== pos
2621 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
2623 maybe_next_line_p
= 1;
2626 else if (line_start_position
> 0)
2629 /* Don't overstep the last matrix row, lest we get into the
2630 never-never land... */
2631 if (row
->y
+ 1 >= yb
)
2637 /* Find the right column within BEST_ROW. */
2640 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
2642 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + i
;
2645 charpos
= glyph
->charpos
;
2652 else if (charpos
> pos
)
2654 else if (charpos
> 0)
2658 /* If we're looking for the end of the buffer,
2659 and we didn't find it in the line we scanned,
2660 use the start of the following line. */
2661 if (maybe_next_line_p
)
2668 *hpos
= lastcol
+ 1;
2673 term_mouse_highlight (struct frame
*f
, int x
, int y
)
2675 enum window_part part
;
2680 if (NILP (Vmouse_highlight
)
2681 || !f
->glyphs_initialized_p
)
2684 /* Which window is that in? */
2685 window
= window_from_coordinates (f
, x
, y
, &part
, &x
, &y
, 0);
2687 /* Not on a window -> return. */
2688 if (!WINDOWP (window
))
2691 if (!EQ (window
, Qmouse_face_window
))
2692 term_clear_mouse_face ();
2694 w
= XWINDOW (window
);
2696 /* Are we in a window whose display is up to date?
2697 And verify the buffer's text has not changed. */
2698 b
= XBUFFER (w
->buffer
);
2700 && EQ (w
->window_end_valid
, w
->buffer
)
2701 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
2702 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
2704 int pos
, i
, nrows
= w
->current_matrix
->nrows
;
2705 struct glyph_row
*row
;
2706 struct glyph
*glyph
;
2708 /* Find the glyph under X/Y. */
2710 if (y
>= 0 && y
< nrows
)
2712 row
= MATRIX_ROW (w
->current_matrix
, y
);
2713 /* Give up if some row before the one we are looking for is
2715 for (i
= 0; i
<= y
; i
++)
2716 if (!MATRIX_ROW (w
->current_matrix
, i
)->enabled_p
)
2718 if (i
> y
/* all rows upto and including the one at Y are enabled */
2719 && row
->displays_text_p
2720 && x
< window_box_width (w
, TEXT_AREA
))
2722 glyph
= row
->glyphs
[TEXT_AREA
];
2723 if (x
>= row
->used
[TEXT_AREA
])
2728 if (!BUFFERP (glyph
->object
))
2734 /* Clear mouse face if X/Y not over text. */
2737 term_clear_mouse_face ();
2741 if (!BUFFERP (glyph
->object
))
2743 pos
= glyph
->charpos
;
2745 /* Check for mouse-face. */
2747 extern Lisp_Object Qmouse_face
;
2748 Lisp_Object mouse_face
, overlay
, position
, *overlay_vec
;
2749 int noverlays
, obegv
, ozv
;
2750 struct buffer
*obuf
;
2752 /* If we get an out-of-range value, return now; avoid an error. */
2753 if (pos
> BUF_Z (b
))
2756 /* Make the window's buffer temporarily current for
2757 overlays_at and compute_char_face. */
2758 obuf
= current_buffer
;
2765 /* Is this char mouse-active? */
2766 XSETINT (position
, pos
);
2768 /* Put all the overlays we want in a vector in overlay_vec. */
2769 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
2770 /* Sort overlays into increasing priority order. */
2771 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
2773 /* Check mouse-face highlighting. */
2774 if (!(EQ (window
, Qmouse_face_window
)
2775 && y
>= mouse_face_beg_row
2776 && y
<= mouse_face_end_row
2777 && (y
> mouse_face_beg_row
2778 || x
>= mouse_face_beg_col
)
2779 && (y
< mouse_face_end_row
2780 || x
< mouse_face_end_col
2781 || mouse_face_past_end
)))
2783 /* Clear the display of the old active region, if any. */
2784 term_clear_mouse_face ();
2786 /* Find the highest priority overlay that has a mouse-face
2789 for (i
= noverlays
- 1; i
>= 0; --i
)
2791 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
2792 if (!NILP (mouse_face
))
2794 overlay
= overlay_vec
[i
];
2799 /* If no overlay applies, get a text property. */
2801 mouse_face
= Fget_text_property (position
, Qmouse_face
,
2804 /* Handle the overlay case. */
2805 if (!NILP (overlay
))
2807 /* Find the range of text around this char that
2808 should be active. */
2809 Lisp_Object before
, after
;
2813 before
= Foverlay_start (overlay
);
2814 after
= Foverlay_end (overlay
);
2815 /* Record this as the current active region. */
2816 fast_find_position (w
, XFASTINT (before
),
2817 &mouse_face_beg_col
,
2818 &mouse_face_beg_row
);
2821 = !fast_find_position (w
, XFASTINT (after
),
2822 &mouse_face_end_col
,
2823 &mouse_face_end_row
);
2824 Qmouse_face_window
= window
;
2827 = face_at_buffer_position (w
, pos
, 0, 0,
2828 &ignore
, pos
+ 1, 1);
2830 /* Display it as active. */
2831 term_show_mouse_face (DRAW_MOUSE_FACE
);
2833 /* Handle the text property case. */
2834 else if (!NILP (mouse_face
))
2836 /* Find the range of text around this char that
2837 should be active. */
2838 Lisp_Object before
, after
, beginning
, end
;
2841 beginning
= Fmarker_position (w
->start
);
2842 XSETINT (end
, (BUF_Z (b
) - XFASTINT (w
->window_end_pos
)));
2844 = Fprevious_single_property_change (make_number (pos
+ 1),
2846 w
->buffer
, beginning
);
2848 = Fnext_single_property_change (position
, Qmouse_face
,
2851 /* Record this as the current active region. */
2852 fast_find_position (w
, XFASTINT (before
),
2853 &mouse_face_beg_col
,
2854 &mouse_face_beg_row
);
2856 = !fast_find_position (w
, XFASTINT (after
),
2857 &mouse_face_end_col
,
2858 &mouse_face_end_row
);
2859 Qmouse_face_window
= window
;
2862 = face_at_buffer_position (w
, pos
, 0, 0,
2863 &ignore
, pos
+ 1, 1);
2865 /* Display it as active. */
2866 term_show_mouse_face (DRAW_MOUSE_FACE
);
2870 /* Look for a `help-echo' property. */
2873 extern Lisp_Object Qhelp_echo
;
2875 /* Check overlays first. */
2877 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
2879 overlay
= overlay_vec
[i
];
2880 help
= Foverlay_get (overlay
, Qhelp_echo
);
2885 help_echo_string
= help
;
2886 help_echo_window
= window
;
2887 help_echo_object
= overlay
;
2888 help_echo_pos
= pos
;
2890 /* Try text properties. */
2891 else if (NILP (help
)
2892 && ((STRINGP (glyph
->object
)
2893 && glyph
->charpos
>= 0
2894 && glyph
->charpos
< SCHARS (glyph
->object
))
2895 || (BUFFERP (glyph
->object
)
2896 && glyph
->charpos
>= BEGV
2897 && glyph
->charpos
< ZV
)))
2899 help
= Fget_text_property (make_number (glyph
->charpos
),
2900 Qhelp_echo
, glyph
->object
);
2903 help_echo_string
= help
;
2904 help_echo_window
= window
;
2905 help_echo_object
= glyph
->object
;
2906 help_echo_pos
= glyph
->charpos
;
2913 current_buffer
= obuf
;
2919 term_mouse_movement (FRAME_PTR frame
, Gpm_Event
*event
)
2921 /* Has the mouse moved off the glyph it was on at the last sighting? */
2922 if (event
->x
!= last_mouse_x
|| event
->y
!= last_mouse_y
)
2924 frame
->mouse_moved
= 1;
2925 term_mouse_highlight (frame
, event
->x
, event
->y
);
2926 /* Remember which glyph we're now on. */
2927 last_mouse_x
= event
->x
;
2928 last_mouse_y
= event
->y
;
2934 /* Return the current position of the mouse.
2936 Set *f to the frame the mouse is in, or zero if the mouse is in no
2937 Emacs frame. If it is set to zero, all the other arguments are
2940 Set *bar_window to Qnil, and *x and *y to the column and
2941 row of the character cell the mouse is over.
2943 Set *time to the time the mouse was at the returned position.
2945 This clears mouse_moved until the next motion
2948 term_mouse_position (FRAME_PTR
*fp
, int insist
, Lisp_Object
*bar_window
,
2949 enum scroll_bar_part
*part
, Lisp_Object
*x
,
2950 Lisp_Object
*y
, unsigned long *time
)
2954 *fp
= SELECTED_FRAME ();
2955 (*fp
)->mouse_moved
= 0;
2960 XSETINT (*x
, last_mouse_x
);
2961 XSETINT (*y
, last_mouse_y
);
2962 gettimeofday(&now
, 0);
2963 *time
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2966 /* Prepare a mouse-event in *RESULT for placement in the input queue.
2968 If the event is a button press, then note that we have grabbed
2972 term_mouse_click (struct input_event
*result
, Gpm_Event
*event
,
2978 result
->kind
= GPM_CLICK_EVENT
;
2979 for (i
= 0, j
= GPM_B_LEFT
; i
< 3; i
++, j
>>= 1 )
2981 if (event
->buttons
& j
) {
2982 result
->code
= i
; /* button number */
2986 gettimeofday(&now
, 0);
2987 result
->timestamp
= (now
.tv_sec
* 1000) + (now
.tv_usec
/ 1000);
2989 if (event
->type
& GPM_UP
)
2990 result
->modifiers
= up_modifier
;
2991 else if (event
->type
& GPM_DOWN
)
2992 result
->modifiers
= down_modifier
;
2994 result
->modifiers
= 0;
2996 if (event
->type
& GPM_SINGLE
)
2997 result
->modifiers
|= click_modifier
;
2999 if (event
->type
& GPM_DOUBLE
)
3000 result
->modifiers
|= double_modifier
;
3002 if (event
->type
& GPM_TRIPLE
)
3003 result
->modifiers
|= triple_modifier
;
3005 if (event
->type
& GPM_DRAG
)
3006 result
->modifiers
|= drag_modifier
;
3008 if (!(event
->type
& (GPM_MOVE
| GPM_DRAG
))) {
3011 if (event
->modifiers
& (1 << 0))
3012 result
->modifiers
|= shift_modifier
;
3015 if (event
->modifiers
& (1 << 2))
3016 result
->modifiers
|= ctrl_modifier
;
3018 /* 1 << KG_ALT || KG_ALTGR */
3019 if (event
->modifiers
& (1 << 3)
3020 || event
->modifiers
& (1 << 1))
3021 result
->modifiers
|= meta_modifier
;
3024 XSETINT (result
->x
, event
->x
);
3025 XSETINT (result
->y
, event
->y
);
3026 XSETFRAME (result
->frame_or_window
, f
);
3032 handle_one_term_event (Gpm_Event
*event
, struct input_event
* hold_quit
)
3034 struct frame
*f
= SELECTED_FRAME ();
3036 struct input_event ie
;
3044 if (event
->type
& (GPM_MOVE
| GPM_DRAG
)) {
3045 unsigned char buf
[6 * sizeof (short)];
3046 unsigned short *arg
= (unsigned short *) buf
+ 1;
3049 previous_help_echo_string
= help_echo_string
;
3050 help_echo_string
= Qnil
;
3052 /* Display mouse pointer */
3053 buf
[sizeof(short) - 1] = 2; /* set selection */
3055 arg
[0] = arg
[2] = (unsigned short) event
->x
+ gpm_zerobased
;
3056 arg
[1] = arg
[3] = (unsigned short) event
->y
+ gpm_zerobased
;
3057 arg
[4] = (unsigned short) 3;
3060 fd
= open (name
, O_WRONLY
);
3061 ioctl (fd
, TIOCLINUX
, buf
+ sizeof (short) - 1);
3064 if (!term_mouse_movement (f
, event
))
3065 help_echo_string
= previous_help_echo_string
;
3067 /* If the contents of the global variable help_echo_string
3068 has changed, generate a HELP_EVENT. */
3069 if (!NILP (help_echo_string
)
3070 || !NILP (previous_help_echo_string
))
3077 term_mouse_click (&ie
, event
, f
);
3081 if (ie
.kind
!= NO_EVENT
)
3083 kbd_buffer_store_event_hold (&ie
, hold_quit
);
3088 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
3093 XSETFRAME (frame
, f
);
3097 gen_help_event (help_echo_string
, frame
, help_echo_window
,
3098 help_echo_object
, help_echo_pos
);
3105 DEFUN ("term-open-connection", Fterm_open_connection
, Sterm_open_connection
,
3107 doc
: /* Open a connection to Gpm. */)
3110 Gpm_Connect connection
;
3112 connection
.eventMask
= ~0;
3113 connection
.defaultMask
= ~GPM_HARD
;
3114 connection
.maxMod
= ~0;
3115 connection
.minMod
= 0;
3118 if (Gpm_Open (&connection
, 0) < 0)
3125 add_gpm_wait_descriptor (gpm_fd
);
3130 DEFUN ("term-close-connection", Fterm_close_connection
, Sterm_close_connection
,
3132 doc
: /* Close a connection to Gpm. */)
3135 delete_gpm_wait_descriptor (gpm_fd
);
3136 while (Gpm_Close()); /* close all the stack */
3140 #endif /* HAVE_GPM */
3143 /***********************************************************************
3145 ***********************************************************************/
3148 term_init (terminal_type
)
3149 char *terminal_type
;
3152 char **address
= &area
;
3153 char *buffer
= NULL
;
3154 int buffer_size
= 4096;
3157 struct frame
*sf
= XFRAME (selected_frame
);
3159 encode_terminal_src_size
= 0;
3160 encode_terminal_dst_size
= 0;
3163 mouse_position_hook
= term_mouse_position
;
3164 Qmouse_face_window
= Qnil
;
3168 initialize_w32_display ();
3172 area
= (char *) xmalloc (2044);
3174 FrameRows
= FRAME_LINES (sf
);
3175 FrameCols
= FRAME_COLS (sf
);
3176 specified_window
= FRAME_LINES (sf
);
3178 delete_in_insert_mode
= 1;
3181 scroll_region_ok
= 0;
3183 /* Seems to insert lines when it's not supposed to, messing
3184 up the display. In doing a trace, it didn't seem to be
3185 called much, so I don't think we're losing anything by
3188 line_ins_del_ok
= 0;
3189 char_ins_del_ok
= 1;
3193 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
3194 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
3195 TN_max_colors
= 16; /* Required to be non-zero for tty-display-color-p */
3198 #else /* not WINDOWSNT */
3202 buffer
= (char *) xmalloc (buffer_size
);
3203 status
= tgetent (buffer
, terminal_type
);
3207 fatal ("Cannot open terminfo database file");
3209 fatal ("Cannot open termcap database file");
3215 fatal ("Terminal type %s is not defined.\n\
3216 If that is not the actual type of terminal you have,\n\
3217 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3218 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3219 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3222 fatal ("Terminal type %s is not defined.\n\
3223 If that is not the actual type of terminal you have,\n\
3224 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3225 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3226 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3232 if (strlen (buffer
) >= buffer_size
)
3234 buffer_size
= strlen (buffer
);
3236 area
= (char *) xmalloc (buffer_size
);
3238 TS_ins_line
= tgetstr ("al", address
);
3239 TS_ins_multi_lines
= tgetstr ("AL", address
);
3240 TS_bell
= tgetstr ("bl", address
);
3241 BackTab
= tgetstr ("bt", address
);
3242 TS_clr_to_bottom
= tgetstr ("cd", address
);
3243 TS_clr_line
= tgetstr ("ce", address
);
3244 TS_clr_frame
= tgetstr ("cl", address
);
3245 ColPosition
= NULL
; /* tgetstr ("ch", address); */
3246 AbsPosition
= tgetstr ("cm", address
);
3247 CR
= tgetstr ("cr", address
);
3248 TS_set_scroll_region
= tgetstr ("cs", address
);
3249 TS_set_scroll_region_1
= tgetstr ("cS", address
);
3250 RowPosition
= tgetstr ("cv", address
);
3251 TS_del_char
= tgetstr ("dc", address
);
3252 TS_del_multi_chars
= tgetstr ("DC", address
);
3253 TS_del_line
= tgetstr ("dl", address
);
3254 TS_del_multi_lines
= tgetstr ("DL", address
);
3255 TS_delete_mode
= tgetstr ("dm", address
);
3256 TS_end_delete_mode
= tgetstr ("ed", address
);
3257 TS_end_insert_mode
= tgetstr ("ei", address
);
3258 Home
= tgetstr ("ho", address
);
3259 TS_ins_char
= tgetstr ("ic", address
);
3260 TS_ins_multi_chars
= tgetstr ("IC", address
);
3261 TS_insert_mode
= tgetstr ("im", address
);
3262 TS_pad_inserted_char
= tgetstr ("ip", address
);
3263 TS_end_keypad_mode
= tgetstr ("ke", address
);
3264 TS_keypad_mode
= tgetstr ("ks", address
);
3265 LastLine
= tgetstr ("ll", address
);
3266 Right
= tgetstr ("nd", address
);
3267 Down
= tgetstr ("do", address
);
3269 Down
= tgetstr ("nl", address
); /* Obsolete name for "do" */
3271 /* VMS puts a carriage return before each linefeed,
3272 so it is not safe to use linefeeds. */
3273 if (Down
&& Down
[0] == '\n' && Down
[1] == '\0')
3276 if (tgetflag ("bs"))
3277 Left
= "\b"; /* can't possibly be longer! */
3278 else /* (Actually, "bs" is obsolete...) */
3279 Left
= tgetstr ("le", address
);
3281 Left
= tgetstr ("bc", address
); /* Obsolete name for "le" */
3282 TS_pad_char
= tgetstr ("pc", address
);
3283 TS_repeat
= tgetstr ("rp", address
);
3284 TS_end_standout_mode
= tgetstr ("se", address
);
3285 TS_fwd_scroll
= tgetstr ("sf", address
);
3286 TS_standout_mode
= tgetstr ("so", address
);
3287 TS_rev_scroll
= tgetstr ("sr", address
);
3288 Wcm
.cm_tab
= tgetstr ("ta", address
);
3289 TS_end_termcap_modes
= tgetstr ("te", address
);
3290 TS_termcap_modes
= tgetstr ("ti", address
);
3291 Up
= tgetstr ("up", address
);
3292 TS_visible_bell
= tgetstr ("vb", address
);
3293 TS_cursor_normal
= tgetstr ("ve", address
);
3294 TS_cursor_visible
= tgetstr ("vs", address
);
3295 TS_cursor_invisible
= tgetstr ("vi", address
);
3296 TS_set_window
= tgetstr ("wi", address
);
3298 TS_enter_underline_mode
= tgetstr ("us", address
);
3299 TS_exit_underline_mode
= tgetstr ("ue", address
);
3300 TS_enter_bold_mode
= tgetstr ("md", address
);
3301 TS_enter_dim_mode
= tgetstr ("mh", address
);
3302 TS_enter_blink_mode
= tgetstr ("mb", address
);
3303 TS_enter_reverse_mode
= tgetstr ("mr", address
);
3304 TS_enter_alt_charset_mode
= tgetstr ("as", address
);
3305 TS_exit_alt_charset_mode
= tgetstr ("ae", address
);
3306 TS_exit_attribute_mode
= tgetstr ("me", address
);
3308 MultiUp
= tgetstr ("UP", address
);
3309 MultiDown
= tgetstr ("DO", address
);
3310 MultiLeft
= tgetstr ("LE", address
);
3311 MultiRight
= tgetstr ("RI", address
);
3313 /* SVr4/ANSI color suppert. If "op" isn't available, don't support
3314 color because we can't switch back to the default foreground and
3316 TS_orig_pair
= tgetstr ("op", address
);
3319 TS_set_foreground
= tgetstr ("AF", address
);
3320 TS_set_background
= tgetstr ("AB", address
);
3321 if (!TS_set_foreground
)
3324 TS_set_foreground
= tgetstr ("Sf", address
);
3325 TS_set_background
= tgetstr ("Sb", address
);
3328 TN_max_colors
= tgetnum ("Co");
3329 TN_max_pairs
= tgetnum ("pa");
3331 TN_no_color_video
= tgetnum ("NC");
3332 if (TN_no_color_video
== -1)
3333 TN_no_color_video
= 0;
3336 tty_default_color_capabilities (1);
3338 MagicWrap
= tgetflag ("xn");
3339 /* Since we make MagicWrap terminals look like AutoWrap, we need to have
3340 the former flag imply the latter. */
3341 AutoWrap
= MagicWrap
|| tgetflag ("am");
3342 memory_below_frame
= tgetflag ("db");
3343 TF_hazeltine
= tgetflag ("hz");
3344 must_write_spaces
= tgetflag ("in");
3345 meta_key
= tgetflag ("km") || tgetflag ("MT");
3346 TF_insmode_motion
= tgetflag ("mi");
3347 TF_standout_motion
= tgetflag ("ms");
3348 TF_underscore
= tgetflag ("ul");
3349 TF_teleray
= tgetflag ("xt");
3351 term_get_fkeys (address
);
3353 /* Get frame size from system, or else from termcap. */
3356 get_frame_size (&width
, &height
);
3357 FRAME_COLS (sf
) = width
;
3358 FRAME_LINES (sf
) = height
;
3361 if (FRAME_COLS (sf
) <= 0)
3362 SET_FRAME_COLS (sf
, tgetnum ("co"));
3364 /* Keep width and external_width consistent */
3365 SET_FRAME_COLS (sf
, FRAME_COLS (sf
));
3366 if (FRAME_LINES (sf
) <= 0)
3367 FRAME_LINES (sf
) = tgetnum ("li");
3369 if (FRAME_LINES (sf
) < 3 || FRAME_COLS (sf
) < 3)
3370 fatal ("Screen size %dx%d is too small",
3371 FRAME_LINES (sf
), FRAME_COLS (sf
));
3373 min_padding_speed
= tgetnum ("pb");
3374 TabWidth
= tgetnum ("tw");
3377 /* These capabilities commonly use ^J.
3378 I don't know why, but sending them on VMS does not work;
3379 it causes following spaces to be lost, sometimes.
3380 For now, the simplest fix is to avoid using these capabilities ever. */
3381 if (Down
&& Down
[0] == '\n')
3389 TS_fwd_scroll
= Down
;
3391 PC
= TS_pad_char
? *TS_pad_char
: 0;
3396 /* Turned off since /etc/termcap seems to have :ta= for most terminals
3397 and newer termcap doc does not seem to say there is a default.
3402 /* We don't support standout modes that use `magic cookies', so
3403 turn off any that do. */
3404 if (TS_standout_mode
&& tgetnum ("sg") >= 0)
3406 TS_standout_mode
= 0;
3407 TS_end_standout_mode
= 0;
3409 if (TS_enter_underline_mode
&& tgetnum ("ug") >= 0)
3411 TS_enter_underline_mode
= 0;
3412 TS_exit_underline_mode
= 0;
3415 /* If there's no standout mode, try to use underlining instead. */
3416 if (TS_standout_mode
== 0)
3418 TS_standout_mode
= TS_enter_underline_mode
;
3419 TS_end_standout_mode
= TS_exit_underline_mode
;
3422 /* If no `se' string, try using a `me' string instead.
3423 If that fails, we can't use standout mode at all. */
3424 if (TS_end_standout_mode
== 0)
3426 char *s
= tgetstr ("me", address
);
3428 TS_end_standout_mode
= s
;
3430 TS_standout_mode
= 0;
3436 /* We can't support standout mode, because it uses magic cookies. */
3437 TS_standout_mode
= 0;
3438 /* But that means we cannot rely on ^M to go to column zero! */
3440 /* LF can't be trusted either -- can alter hpos */
3441 /* if move at column 0 thru a line with TS_standout_mode */
3445 /* Special handling for certain terminal types known to need it */
3447 if (!strcmp (terminal_type
, "supdup"))
3449 memory_below_frame
= 1;
3450 Wcm
.cm_losewrap
= 1;
3452 if (!strncmp (terminal_type
, "c10", 3)
3453 || !strcmp (terminal_type
, "perq"))
3455 /* Supply a makeshift :wi string.
3456 This string is not valid in general since it works only
3457 for windows starting at the upper left corner;
3458 but that is all Emacs uses.
3460 This string works only if the frame is using
3461 the top of the video memory, because addressing is memory-relative.
3462 So first check the :ti string to see if that is true.
3464 It would be simpler if the :wi string could go in the termcap
3465 entry, but it can't because it is not fully valid.
3466 If it were in the termcap entry, it would confuse other programs. */
3469 p
= TS_termcap_modes
;
3470 while (*p
&& strcmp (p
, "\033v "))
3473 TS_set_window
= "\033v%C %C %C %C ";
3475 /* Termcap entry often fails to have :in: flag */
3476 must_write_spaces
= 1;
3477 /* :ti string typically fails to have \E^G! in it */
3478 /* This limits scope of insert-char to one line. */
3479 strcpy (area
, TS_termcap_modes
);
3480 strcat (area
, "\033\007!");
3481 TS_termcap_modes
= area
;
3482 area
+= strlen (area
) + 1;
3484 /* Change all %+ parameters to %C, to handle
3485 values above 96 correctly for the C100. */
3488 if (p
[0] == '%' && p
[1] == '+')
3494 FrameRows
= FRAME_LINES (sf
);
3495 FrameCols
= FRAME_COLS (sf
);
3496 specified_window
= FRAME_LINES (sf
);
3498 if (Wcm_init () == -1) /* can't do cursor motion */
3500 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3501 It lacks the ability to position the cursor.\n\
3502 If that is not the actual type of terminal you have, use either the\n\
3503 DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
3504 or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
3508 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3509 It lacks the ability to position the cursor.\n\
3510 If that is not the actual type of terminal you have,\n\
3511 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3512 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3513 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
3515 # else /* TERMCAP */
3516 fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
3517 It lacks the ability to position the cursor.\n\
3518 If that is not the actual type of terminal you have,\n\
3519 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3520 `setenv TERM ...') to specify the correct type. It may be necessary\n\
3521 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
3523 # endif /* TERMINFO */
3525 if (FRAME_LINES (sf
) <= 0
3526 || FRAME_COLS (sf
) <= 0)
3527 fatal ("The frame size has not been specified");
3529 delete_in_insert_mode
3530 = TS_delete_mode
&& TS_insert_mode
3531 && !strcmp (TS_delete_mode
, TS_insert_mode
);
3533 se_is_so
= (TS_standout_mode
3534 && TS_end_standout_mode
3535 && !strcmp (TS_standout_mode
, TS_end_standout_mode
));
3537 UseTabs
= tabs_safe_p () && TabWidth
== 8;
3541 && (TS_set_window
|| TS_set_scroll_region
|| TS_set_scroll_region_1
));
3543 line_ins_del_ok
= (((TS_ins_line
|| TS_ins_multi_lines
)
3544 && (TS_del_line
|| TS_del_multi_lines
))
3545 || (scroll_region_ok
&& TS_fwd_scroll
&& TS_rev_scroll
));
3547 char_ins_del_ok
= ((TS_ins_char
|| TS_insert_mode
3548 || TS_pad_inserted_char
|| TS_ins_multi_chars
)
3549 && (TS_del_char
|| TS_del_multi_chars
));
3551 fast_clear_end_of_line
= TS_clr_line
!= 0;
3554 if (read_socket_hook
) /* Baudrate is somewhat */
3555 /* meaningless in this case */
3558 FRAME_CAN_HAVE_SCROLL_BARS (sf
) = 0;
3559 FRAME_VERTICAL_SCROLL_BAR_TYPE (sf
) = vertical_scroll_bar_none
;
3560 #endif /* WINDOWSNT */
3567 fatal (str
, arg1
, arg2
)
3568 char *str
, *arg1
, *arg2
;
3570 fprintf (stderr
, "emacs: ");
3571 fprintf (stderr
, str
, arg1
, arg2
);
3572 fprintf (stderr
, "\n");
3577 DEFUN ("tty-no-underline", Ftty_no_underline
, Stty_no_underline
, 0, 0, 0,
3578 doc
: /* Declare that this terminal does not handle underlining.
3579 This is used to override the terminfo data, for certain terminals that
3580 do not really do underlining, but say that they do. */)
3583 TS_enter_underline_mode
= 0;
3590 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo
,
3591 doc
: /* Non-nil means the system uses terminfo rather than termcap.
3592 This variable can be used by terminal emulator packages. */);
3594 system_uses_terminfo
= 1;
3596 system_uses_terminfo
= 0;
3599 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function
,
3600 doc
: /* Non-nil means call this function to ring the bell.
3601 The function should accept no arguments. */);
3602 Vring_bell_function
= Qnil
;
3604 DEFVAR_BOOL ("visible-cursor", &visible_cursor
,
3605 doc
: /* Non-nil means to make the cursor very visible.
3606 This only has an effect when running in a text terminal.
3607 What means \"very visible\" is up to your terminal. It may make the cursor
3608 bigger, or it may make it blink, or it may do nothing at all. */);
3611 defsubr (&Stty_display_color_p
);
3612 defsubr (&Stty_display_color_cells
);
3613 defsubr (&Stty_no_underline
);
3615 defsubr (&Sterm_open_connection
);
3616 defsubr (&Sterm_close_connection
);
3618 staticpro (&Qmouse_face_window
);
3619 #endif /* HAVE_GPM */
3621 fullscreen_hook
= NULL
;
3624 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
3625 (do not change this comment) */